关于日志
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, "\r", "#", -1)
s = strings.Replace(s, "\n", "#", -1)
return ths.bw.WriteString(s + "\r\n")
}
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()
}


浙公网安备 33010602011771号