基于 `zap` 包封装。除了实现 `Go` 日志包的基本功能外,还实现了很多高级功能 本包基于`github.com/tkestack/tke/pkg/util/log`裁剪
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
4.7 KiB

2 years ago
  1. package log
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/spf13/pflag"
  6. "go.uber.org/zap"
  7. "go.uber.org/zap/zapcore"
  8. "strings"
  9. )
  10. const (
  11. flagLevel = "log.level"
  12. flagDisableCaller = "log.disable-caller"
  13. flagDisableStacktrace = "log.disable-stacktrace"
  14. flagFormat = "log.format"
  15. flagEnableColor = "log.enable-color"
  16. flagOutputPaths = "log.output-paths"
  17. flagErrorOutputPaths = "log.error-output-paths"
  18. flagDevelopment = "log.development"
  19. flagName = "log.name"
  20. ConsoleFormat = "console"
  21. JsonFormat = "json"
  22. )
  23. // Options 日志有关的配置. 设置参考zap的配置
  24. type Options struct {
  25. OutputPaths []string `json:"output-paths" mapstructure:"output-paths"`
  26. ErrorOutputPaths []string `json:"error-output-paths" mapstructure:"error-output-paths"`
  27. Level string `json:"level" mapstructure:"level"`
  28. Format string `json:"format" mapstructure:"format"`
  29. DisableCaller bool `json:"disable-caller" mapstructure:"disable-caller"`
  30. DisableStacktrace bool `json:"disable-stacktrace" mapstructure:"disable-stacktrace"`
  31. EnableColor bool `json:"enable-color" mapstructure:"enable-color"`
  32. Development bool `json:"development" mapstructure:"development"`
  33. Name string `json:"name" mapstructure:"name"`
  34. }
  35. // NewOptions 新建带默认参数的日志配置
  36. func NewOptions() *Options {
  37. return &Options{
  38. Level: zapcore.InfoLevel.String(),
  39. DisableCaller: false,
  40. DisableStacktrace: false,
  41. Format: ConsoleFormat,
  42. EnableColor: false,
  43. Development: false,
  44. OutputPaths: []string{"stdout"},
  45. ErrorOutputPaths: []string{"stderr"},
  46. }
  47. }
  48. // Validate 验证日志配置.
  49. func (o *Options) Validate() []error {
  50. var errs []error
  51. var zapLevel zapcore.Level
  52. if err := zapLevel.UnmarshalText([]byte(o.Level)); err != nil {
  53. errs = append(errs, err)
  54. }
  55. format := strings.ToLower(o.Format)
  56. if format != ConsoleFormat && format != JsonFormat {
  57. errs = append(errs, fmt.Errorf("not a valid log format: %q", o.Format))
  58. }
  59. return errs
  60. }
  61. // AddFlags 读取命令行参数设置日志配置
  62. func (o *Options) AddFlags(fs *pflag.FlagSet) {
  63. fs.StringVar(&o.Level, flagLevel, o.Level, "Minimum log output `LEVEL`.")
  64. fs.BoolVar(&o.DisableCaller, flagDisableCaller, o.DisableCaller, "Disable output of caller information in the log.")
  65. fs.BoolVar(&o.DisableStacktrace, flagDisableStacktrace,
  66. o.DisableStacktrace, "Disable the log to record a stack trace for all messages at or above panic level.")
  67. fs.StringVar(&o.Format, flagFormat, o.Format, "Log output `FORMAT`, support plain or json format.")
  68. fs.BoolVar(&o.EnableColor, flagEnableColor, o.EnableColor, "Enable output ansi colors in plain format logs.")
  69. fs.StringSliceVar(&o.OutputPaths, flagOutputPaths, o.OutputPaths, "Output paths of log.")
  70. fs.StringSliceVar(&o.ErrorOutputPaths, flagErrorOutputPaths, o.ErrorOutputPaths, "Error output paths of log.")
  71. fs.BoolVar(
  72. &o.Development,
  73. flagDevelopment,
  74. o.Development,
  75. "Development puts the logger in development mode, which changes "+
  76. "the behavior of DPanicLevel and takes stacktraces more liberally.",
  77. )
  78. fs.StringVar(&o.Name, flagName, o.Name, "The name of the logger.")
  79. }
  80. func (o *Options) String() string {
  81. data, _ := json.Marshal(o)
  82. return string(data)
  83. }
  84. // Build 将设置安装到全局zap logger
  85. func (o *Options) Build() error {
  86. var zapLevel zapcore.Level
  87. if err := zapLevel.UnmarshalText([]byte(o.Level)); err != nil {
  88. zapLevel = zapcore.InfoLevel
  89. }
  90. encodeLevel := zapcore.CapitalLevelEncoder
  91. if o.Format == ConsoleFormat && o.EnableColor {
  92. encodeLevel = zapcore.CapitalColorLevelEncoder
  93. }
  94. zc := &zap.Config{
  95. Level: zap.NewAtomicLevelAt(zapLevel),
  96. Development: o.Development,
  97. DisableCaller: o.DisableCaller,
  98. DisableStacktrace: o.DisableStacktrace,
  99. Sampling: &zap.SamplingConfig{
  100. Initial: 100,
  101. Thereafter: 100,
  102. },
  103. Encoding: o.Format,
  104. EncoderConfig: zapcore.EncoderConfig{
  105. MessageKey: "message",
  106. LevelKey: "level",
  107. TimeKey: "timestamp",
  108. NameKey: "logger",
  109. CallerKey: "caller",
  110. StacktraceKey: "stacktrace",
  111. LineEnding: zapcore.DefaultLineEnding,
  112. EncodeLevel: encodeLevel,
  113. EncodeTime: timeEncoder,
  114. EncodeDuration: autoDurationEncoder,
  115. EncodeCaller: zapcore.ShortCallerEncoder,
  116. EncodeName: zapcore.FullNameEncoder,
  117. },
  118. OutputPaths: o.OutputPaths,
  119. ErrorOutputPaths: o.ErrorOutputPaths,
  120. }
  121. logger, err := zc.Build(zap.AddStacktrace(zapcore.PanicLevel))
  122. if err != nil {
  123. return err
  124. }
  125. zap.RedirectStdLog(logger.Named(o.Name))
  126. zap.ReplaceGlobals(logger)
  127. return nil
  128. }