logger.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Pacage logger provides a simple wrapper around zap logger
  2. package logger
  3. import (
  4. "fmt"
  5. "os"
  6. "strings"
  7. "time"
  8. "github.com/runningwater/gohub/pkg/app"
  9. "go.uber.org/zap"
  10. "go.uber.org/zap/zapcore"
  11. "gopkg.in/natefinch/lumberjack.v2"
  12. )
  13. // Logger 全局日志对象
  14. var Logger *zap.Logger
  15. // Init 初始化日志
  16. func Init(filename string, maxSize, maxBackup, maxAge int, compress bool, logType, level string) {
  17. // 获取日志写入介质
  18. writeSyncer := getLogWriter(filename, maxSize, maxBackup, maxAge, compress, logType)
  19. // 设置日志等级, 具体见 config/log.go
  20. logLevel := new(zap.AtomicLevel)
  21. if err := logLevel.UnmarshalText([]byte(level)); err != nil {
  22. fmt.Println("日志初始化错误,日志级别设置有误。请修改 config/log.go 中的 log.level")
  23. }
  24. // 初始化 core
  25. core := zapcore.NewCore(getEncoder(), writeSyncer, logLevel)
  26. // 初始化 logger
  27. Logger = zap.New(core,
  28. zap.AddCaller(), // 调用文件和行号,内部使用 runtime.Caller
  29. zap.AddCallerSkip(1), // 调用文件和行号,内部使用 runtime.Caller
  30. zap.Development(), // 开发模式,堆栈跟踪
  31. zap.AddStacktrace(zapcore.ErrorLevel), // 记录错误级别以上的堆栈信息
  32. )
  33. // 设置全局 logger
  34. // 将自定义的 logger 替换 zap 的全局 logger
  35. zap.ReplaceGlobals(Logger)
  36. }
  37. // getEncoder 获取编码器(如何写入日志), 输出: 日志格式
  38. func getEncoder() zapcore.Encoder {
  39. // 日志模式规则
  40. encoderConfig := zapcore.EncoderConfig{
  41. TimeKey: "time", // 时间字段名
  42. LevelKey: "level", // 日志级别字段名
  43. NameKey: "logger", // 日志名称字段名
  44. CallerKey: "caller", // 调用者字段名
  45. FunctionKey: zapcore.OmitKey, // 函数名字段名,不显示
  46. MessageKey: "msg", // 消息字段名
  47. StacktraceKey: "stacktrace", // 堆栈跟踪字段名
  48. LineEnding: zapcore.DefaultLineEnding, // 每行日志的结尾添加换行符
  49. EncodeLevel: zapcore.CapitalLevelEncoder, // 大写编码器
  50. EncodeTime: customTimeEncoder, // 自定义时间编码器
  51. EncodeDuration: zapcore.SecondsDurationEncoder, // 以秒为单位显示持续时间
  52. EncodeCaller: zapcore.ShortCallerEncoder, // 短路径编码器
  53. }
  54. if app.IsLocal() {
  55. encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder // 彩色编码器
  56. // 如果是本地环境,使用 console 编码器
  57. return zapcore.NewConsoleEncoder(encoderConfig)
  58. }
  59. // 如果不是本地环境,使用 JSON 编码器
  60. return zapcore.NewJSONEncoder(encoderConfig)
  61. }
  62. func customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
  63. // 自定义时间格式
  64. enc.AppendString(t.Format("2006-01-02 15:04:05"))
  65. }
  66. // getLogWriter 获取日志写入介质
  67. // os.Stdout: 标准输出
  68. // 文件输出
  69. func getLogWriter(filename string, maxSize, maxBackup, maxAge int, compress bool, logType string) zapcore.WriteSyncer {
  70. // 如果配置了按日期记录日志,则使用按日期记录日志
  71. if logType == "daily" {
  72. logname := time.Now().Format("2006-01-02") + ".log"
  73. filename = strings.Replace(filename, "logs.log", logname, 1)
  74. }
  75. // 滚动日志,详见 config/log.go
  76. lumberJackLogger := &lumberjack.Logger{
  77. Filename: filename, // 日志文件名
  78. MaxSize: maxSize, // 每个日志文件保存的最大尺寸 单位:MB
  79. MaxBackups: maxBackup, // 日志文件最多保存多少个备份
  80. MaxAge: maxAge, // 文件最多保存多少天
  81. Compress: compress, // 是否压缩
  82. }
  83. if app.IsLocal() {
  84. // 如果是本地环境,使用标准输出和文件输出
  85. return zapcore.NewMultiWriteSyncer(
  86. zapcore.AddSync(os.Stdout),
  87. zapcore.AddSync(lumberJackLogger),
  88. )
  89. } else {
  90. // 生产环境只记录文件
  91. return zapcore.AddSync(lumberJackLogger)
  92. }
  93. }