- 支持按日期划分日志文件
- 支持清除30天前旧日志
- 按需结合io.MultiWriter()实现多输出端显示
package main
import (
"fmt"
"io"
"os"
"path/filepath"
"sync"
"time"
)
type MyLog struct {
mu sync.Mutex
F *os.File
Name string
Path string
CutByDay bool
date string
}
func (m *MyLog) Write(c []byte) (int, error) {
m.mu.Lock()
defer m.mu.Unlock()
if m.date != time.Now().Format("2006-01-02") {
if m.F != nil {
m.F.Close()
m.F = nil
}
}
if m.F == nil {
f, err := os.OpenFile(m.GetLogPath(), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
return 0, err
}
m.F = f
}
return m.F.Write(c)
}
func (m *MyLog) Close() {
if m.F != nil {
m.F.Close()
}
}
func (m *MyLog) GetLogPath() string {
path := m.Path + "/" + m.Name
if m.CutByDay {
path += "_" + time.Now().Format("2006-01-02")
}
return path + ".log"
}
func (m *MyLog) SetName(n string) {
m.mu.Lock()
defer m.mu.Unlock()
m.Name = n
}
func (m *MyLog) ClearOldLog() {
m.mu.Lock()
defer m.mu.Unlock()
p := m.Path + "/" + m.Name + "*.log"
matchFiles, err := filepath.Glob(p)
if err != nil {
return
}
for _, v := range matchFiles {
nFile := m.Path + "/" + v
fd, err := os.Stat(nFile)
if err != nil {
continue
}
fmt.Println(nFile)
if fd.ModTime().Before(time.Now().AddDate(0, 0, -30)) {
os.Remove(nFile)
}
}
}
func main() {
m := MyLog{
Path: ".",
Name: "warn",
CutByDay: false,
}
defer m.Close()
mw := io.MultiWriter(&m, os.Stdout)
mw.Write([]byte("hello\n"))
mw.Write([]byte("the world is very beat\n"))
m.ClearOldLog()
}