zlog.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package zlog
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "sync"
  7. "github.com/rotisserie/eris"
  8. "go.uber.org/zap"
  9. "go.uber.org/zap/zapcore"
  10. )
  11. var (
  12. l *Logger
  13. once = sync.Once{}
  14. )
  15. type Logger struct {
  16. log *zap.Logger
  17. ctx context.Context
  18. }
  19. func NewLogger(writer Writer) *Logger {
  20. // 限制日志输出级别, >= DebugLevel 会打印所有级别的日志
  21. // 生产环境中一般使用 >= ErrorLevel
  22. lowPriority := zap.LevelEnablerFunc(func(lv zapcore.Level) bool {
  23. return lv >= zapcore.DebugLevel
  24. })
  25. // 控制台展示方便调试,使用 TEXT 的方式
  26. consoleEncoderConfig := zap.NewDevelopmentEncoderConfig()
  27. consoleEncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
  28. consoleEncoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05")
  29. consoleEncoder := zapcore.NewConsoleEncoder(consoleEncoderConfig)
  30. stdCore := zapcore.NewCore(consoleEncoder, zapcore.Lock(os.Stdout), lowPriority)
  31. // 日志格式化
  32. productionEncoderConfig := zap.NewProductionEncoderConfig()
  33. productionEncoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05")
  34. jsonEnc := zapcore.NewJSONEncoder(productionEncoderConfig)
  35. // 使用 JSON 格式日志
  36. var core zapcore.Core
  37. if writer.GetEnv() != notPushEnvironment {
  38. syncer := zapcore.AddSync(writer)
  39. esCore := zapcore.NewCore(jsonEnc, syncer, lowPriority).With([]zap.Field{zap.String("env", writer.GetEnv())})
  40. core = zapcore.NewTee(stdCore, esCore)
  41. } else {
  42. core = stdCore
  43. }
  44. // logger 输出到 console 且标识调用代码行
  45. l := zap.New(core).WithOptions(zap.AddCallerSkip(1), zap.AddCaller())
  46. return &Logger{log: l}
  47. }
  48. func NewLoggerWithZapCode(l *zap.Logger) *Logger {
  49. return &Logger{log: l}
  50. }
  51. func WithZapLogger(log *Logger) {
  52. once.Do(func() {
  53. l = log
  54. })
  55. }
  56. // Debug logs a message at info level.
  57. func Debug(args ...any) {
  58. l.log.Debug(fmt.Sprint(args...))
  59. }
  60. // Debugf logs a message at info level.
  61. func Debugf(msg string, args ...any) {
  62. l.log.Debug(fmt.Sprintf(msg, args...))
  63. }
  64. // Debugv logs a message at info level.
  65. func Debugv(arg any) {
  66. l.log.Debug(fmt.Sprint(arg))
  67. }
  68. // Debugw logs a message at info level.
  69. func Debugw(msg string, fields ...zap.Field) {
  70. l.log.Debug(fmt.Sprintf(msg, toValues(fields)...))
  71. }
  72. // Error logs a message at error level.
  73. func Error(args ...any) {
  74. l.log.Error(fmt.Sprint(args...))
  75. }
  76. func ErrorStack(err error) {
  77. format := eris.NewDefaultStringFormat(eris.FormatOptions{
  78. InvertOutput: true,
  79. WithTrace: true,
  80. InvertTrace: true,
  81. })
  82. formattedStr := eris.ToCustomString(err, format)
  83. l.log.Error(formattedStr)
  84. }
  85. // Errorf logs a message at error level.
  86. func Errorf(msg string, args ...any) {
  87. l.log.Error(fmt.Sprintf(msg, args...))
  88. }
  89. // Errorv logs a message at error level.
  90. func Errorv(arg any) {
  91. l.log.Error(fmt.Sprint(arg))
  92. }
  93. // Errorw logs a message at error level.
  94. func Errorw(msg string, fields ...zap.Field) {
  95. l.log.Error(fmt.Sprintf(msg, toValues(fields)...))
  96. }
  97. // Info logs a message at info level.
  98. func Info(args ...any) {
  99. l.log.Info(fmt.Sprint(args...))
  100. }
  101. // Infof logs a message at info level.
  102. func Infof(msg string, args ...any) {
  103. l.log.Info(fmt.Sprintf(msg, args...))
  104. }
  105. // Infov logs a message at info level.
  106. func Infov(arg any) {
  107. l.log.Info(fmt.Sprint(arg))
  108. }
  109. // Infow logs a message at info level.
  110. func Infow(msg string, fields ...zap.Field) {
  111. l.log.Info(fmt.Sprintf(msg, toValues(fields)...))
  112. }
  113. func addLineBreakSymbol(msg string) string {
  114. return fmt.Sprintln(msg)
  115. }
  116. func toValues(fields []zap.Field) []any {
  117. var str []any = make([]any, len(fields))
  118. for i, field := range fields {
  119. str[i] = field.String
  120. }
  121. return str
  122. }