1 使用go自带的log函数存储日志
参考资料:https://golang.org/pkg/log/
package main import ( "io" "log" "os" ) func setLogFile(filename string) error { f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return err } log.SetOutput(io.MultiWriter(os.Stdout, f)) return nil } func main() { err := setLogFile("./a.log") if err != nil { panic(err) } log.Println(1234) log.Println(map[string]string{ "a": "asdf", }) }
2.使用第三方的插件库存储日志
地址:https://github.com/donnie4w/go-logger
func setLog(err error) error{ logger.SetRollingDaily(`./logs`, "dataerror.log") //备份日志以日期切割 logger.SetLevel(logger.INFO) //日志级别 //存放日志 var lg = logger.GetLogger() lg.SetLevelFile(logger.ERROR, `./logs/`, "error.log") lg.Error(err) return nil }
3.自定义的日志
package nlog import ( "bufio" "errors" "fmt" "os" "path/filepath" "strings" "sync" "time" ) const BUFFIO_SIZE = 4096 const AUTO_RESET_TIME = 2 * time.Second var CST = time.FixedZone("CST", 28800) type ErrorCB func(err error) type LogFile struct { mu sync.Mutex f *os.File bw *bufio.Writer isClosed bool filename string filenameFormat string errorCB ErrorCB } /* const filenameFormat = "./logs/error/2006-01-02_15_04.error.log" log, err := nlog.NewLogFile(filenameFormat, func(err error) { // 处理在后台自动写数据和生成新文件时的错误 fmt.Println("err:", err) }) panicif(err) log.Println('a', true, time.Now()) */ func NewLogFile(filenameFormat string, errorCB ErrorCB) (*LogFile, error) { var o = &LogFile{ filenameFormat: filenameFormat, errorCB: errorCB, } var err = o.reset() if err != nil { return nil, err } o.autoReset() return o, nil } func (ths *LogFile) autoReset() { go func() { var ticker = time.NewTicker(AUTO_RESET_TIME) defer ticker.Stop() for { <-ticker.C if !ths.isClosed { var err = ths.reset() if ths.errorCB != nil && err != nil { ths.errorCB(err) } } } }() } func (ths *LogFile) reset() error { ths.mu.Lock() defer ths.mu.Unlock() var t = time.Now().In(CST) var filename = t.Format(ths.filenameFormat) _, err := os.Stat(filename) if os.IsNotExist(err) { // 如果文件被删除,重新生成文件 ths.filename = "" } // 判断是否需要重新生成文件 if ths.f == nil || ths.filename != filename { if ths.f != nil { if err := ths.close(); err != nil { return err } } var err = os.MkdirAll(filepath.Dir(filename), 0777) if err != nil { return err } f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return err } ths.isClosed = false ths.filename = filename ths.f = f ths.bw = bufio.NewWriterSize(f, BUFFIO_SIZE) } else { if err := ths.bw.Flush(); err != nil { return err } } return nil } func (ths *LogFile) Printfln(format string, v ...interface{}) (n int, err error) { ths.mu.Lock() defer ths.mu.Unlock() return ths.write(fmt.Sprintf(format, v...)) } func (ths *LogFile) Println(v ...interface{}) (n int, err error) { ths.mu.Lock() defer ths.mu.Unlock() return ths.write(fmt.Sprint(v...)) } func (ths *LogFile) write(s string) (n int, err error) { if ths.isClosed { return 0, errors.New("LogFile is closed: " + ths.filename) } s = strings.Replace(s, " ", "#", -1) s = strings.Replace(s, " ", "#", -1) return ths.bw.WriteString(s + " ") } func (ths *LogFile) Close() error { ths.mu.Lock() defer ths.mu.Unlock() return ths.close() } func (ths *LogFile) close() error { if ths.isClosed { return nil } ths.isClosed = true if err := ths.bw.Flush(); err != nil { ths.f.Close() return err } return ths.f.Close() }