Golang项目中,需要增加循环日志功能,但是从网上资料看,Go本身log包,功能比较简单,只提供了基本的日志输出,
并且没有日志级别控制,日志文件分割和回滚,以及日志分发等功能。
查阅几篇网络资料,决定引入logrus软件包,它完全兼容golang标准库日志模块:拥有六种日志级别:debug、info、
warn、error、fatal和panic,这是golang标准库日志模块的API的超集。其他特性,可以参考文末的网络链接中的内容。
Go软件包
需要引入的软件包如下:
"github.com/sirupsen/logrus"
"github.com/lestrrat-go/file-rotatelogs"
"github.com/rifflock/lfshook"
其中 logrus 是基本的软件包,可以提供多种级别日志接口,可以通过其hook机制,将日志进行分发,定制文件输出格式等。
通过file-rotatelogs包,可以对本地日志文件进行分割,可以按照时间,也可以按照文件大小来实现。lfshook是专门为logrus
定制的本地文件系统钩子,帮助开发者直接把日志写入到本地文件系统的文件中。
另外,还需要几个辅助包,否则编译不通过。
"github.com/lestrrat-go/strftime"
"github.com/pkg/errors"
"golang.org/x/sys"
循环日志示例代码:
package main import ( "fmt" "path" "os" "bufio" "time" rotatelogs "github.com/lestrrat-go/file-rotatelogs" /* 引入日志回滚功能 */ "github.com/rifflock/lfshook" /* logrus本地文件系统钩子 */ "github.com/sirupsen/logrus" /* logrus日志包 */ )
/* 定义日志级别 */ const LOG_TRACE = 0 const LOG_DEBUG = 1 const LOG_INFO = 2 const LOG_WARN = 3 const LOG_ERROR = 4 const LOG_FATAL = 5 const LOG_PANIC = 6
/* 创建logrus日志实例 */ var Logger = logrus.New()
/* 使用闭包特性,初始化带回滚功能的logrus日志环境 */ func LoggerToFile() func(int, ...interface{}){
/* 日志路径和名称 */ logFilePath := "/home/goproject/log" logFileName := "helloworld" partFileName := path.Join(logFilePath, logFileName) /* 禁止日志打印到标准输出stdout */ devnull, err := os.OpenFile(os.DevNull, os.O_APPEND|os.O_WRONLY, os.ModeAppend) if err != nil { fmt.Printf("LoggerToFile open os.DevNull failed: ", err) } writernull := bufio.NewWriter(devnull) Logger.SetOutput(writernull)
/* 设置默认日志级别为 INFO */ Logger.SetLevel(logrus.InfoLevel)
/* 创建日志回滚实例,日志名称格式,日志回滚模式(日志每20M回滚,保留10各日志文件) */ logWriter, err := rotatelogs.New( partFileName+".%Y%m%d.log", rotatelogs.WithLinkName(logFileName+".log"), /* 链接文件,链接到当前实际的日志文件 */ rotatelogs.WithRotationSize(20*1024*1024), rotatelogs.WithRotationCount(10), )
/* 日志输出到本地文件系统,不同级别都输出到相同的日志中 */ writeMap := lfshook.WriterMap{ logrus.InfoLevel: logWriter, logrus.FatalLevel: logWriter, logrus.DebugLevel: logWriter, logrus.WarnLevel: logWriter, logrus.ErrorLevel: logWriter, logrus.PanicLevel: logWriter, }
/* 创建新的lfs钩子 */ lfHook := lfshook.NewHook(writeMap, &logrus.JSONFormatter{ TimestampFormat:"2006-01-02 15:04:05", }) /* logrus实例添加lfshook钩子 */ Logger.AddHook(lfHook)
/* 返回日志函数实例,这里可以根据level参数,实现不同级别的日志输出控制 */ return func(level int, args ...interface{}) { loginfo := fmt.Sprintf("%v", args) Logger.WithFields(logrus.Fields{ "module": "helloworld", }).Info(loginfo) } }
/* 创建一个日志函数实例(闭包) */ var TestLog = LoggerToFile() func main() { TestLog(LOG_DEBUG, "Hello, World!") fmt.Println("Hello, World!") count := 0 for { TestLog(LOG_INFO, "No.", count, "sleep 2s......") fmt.Println("No.", count, "sleep 20s......") count++ time.Sleep(2*time.Second) } }
日志文件:
实际日志输出到/home/goproject/log目录下,日志文件名为helloworld.YYYYMMDD.log形式;helloworld.log为当前日志文件的链接
日志内容:
参考资料:
https://studygolang.com/articles/18494
https://studygolang.com/articles/26516
https://studygolang.com/articles/30220
【4】golang使用日志分割
https://studygolang.com/articles/31475
【5】Local Filesystem Hook for Logrus
https://github.com/rifflock/lfshook
【6】Go语言闭包(Closure)——引用了外部变量的匿名函数