程序日志不论在开发中还是实际生产环境下都扮演者极其重要的角色。配置好全流程日志,可以在程序异常时定位问题所在或者进行运行时数据对比起到关键的作用。在Java中,日志框架可选择非常多,如最常用的Log4j、SLF4J、Logback等。
同样,在golang中也有类似的日志框架供我们选择:
- logrus (推荐): logrus 是一个非常流行的Go日志库,支持结构化日志输出。通过结合使用logrus和第三方包如logrus-hook-rotatelogs或自定义Hook,您可以实现按日期滚动日志文件的功能。
- logrotate:虽然不是直接的库调用,但在生产环境中,可以通过系统级别的工具如logrotate来配置日志文件的自动滚动和压缩。这种方式适用于任何日志输出程序,不局限于Go语言。
- lumberjack:这是一个简单的库,可以方便地用于日志文件的自动滚动和清理。它通常作为其他日志库(如logrus)的日志文件处理插件使用。
- zap:zap 是Uber开源的一个高性能日志库,支持高级功能如结构化日志记录。它也有相应的文件滚动功能,可以通过配置实现按时间或其他条件滚动日志文件
本文则使用logrus来进行配置和使用。
1、创建和配置logrus
首选,我有如下的一个项目结构:
project/ ├── cmd/ │ └── main.go ├── config/ │ └── logger.go └── go.mod
在一般的Go项目工程中,日志配置通常会放在 config 或者 utils 包中,以便于管理和复用。如上面目录结构中 /config/logger.go文件。
安装logrus go get github.com/sirupsen/logrus
创建logger.go文件并添加如下内容:
package config
import (
"io"
"log"
"os"
"path/filepath"
"time"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"github.com/sirupsen/logrus"
)
func SetupLogger() error {
// 创建一个 Hook 处理器,用于按日期滚动日志文件
hook, err := rotatelogs.New(
filepath.Join("logs", "logfile.%Y%m%d%H%M%S.log"), // 日志文件名格式
rotatelogs.WithLinkName(filepath.Join("logs", "syslog.log")), // 符号链接名称
rotatelogs.WithRotationTime(time.Hour), // 每小时滚动一次
rotatelogs.WithMaxAge(7*24*time.Hour), // 最大保留7天
)
if err != nil {
return err
}
// 创建标准输出处理器
stdoutHook := os.Stdout
// 设置日志输出为 Hook 处理器和标准输出处理器
multiWriter := io.MultiWriter(hook, stdoutHook)
logrus.SetOutput(multiWriter)
// 设置日志级别
logrus.SetLevel(logrus.DebugLevel)
// 设置日志格式
logrus.SetFormatter(&logrus.TextFormatter{
TimestampFormat: "2006-01-02 15:04:05",
})
// 启用堆栈跟踪
logrus.SetReportCaller(true)
// 检查是否设置了环境变量 LOG_LEVEL
logLevelStr := os.Getenv("LOG_LEVEL")
if logLevelStr != "" {
level, err := logrus.ParseLevel(logLevelStr)
if err != nil {
log.Println("Invalid log level:", logLevelStr)
} else {
logrus.SetLevel(level)
}
}
return nil
}
2、使用logrus
package main
import (
"github.com/sirupsen/logrus"
"log"
"lzyz.fun/project/config"
)
func main() {
if err := config.SetupLogger(); err != nil {
log.Fatalf("启动log失败: %v", err)
}
logrus.Info("This is an info message")
logrus.Warn("This is a warning message")
logrus.Error("This is an error message")
//logrus.Fatal("ERROR quit!") // 取消注释后,程序会异常退出,不会向下执行
// 其他业务...
}
同样在其他包中也可以通过引用"github.com/sirupsen/logrus"
从而获取到日志句柄,进行相应的日志输出。 同时在项目根目录下,可以发现自动生成了/logs文件夹,里面则是日志文件。