o2o公共业务代码
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.

log.go 5.9 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. package zhios_o2o_business_logx
  2. import (
  3. "os"
  4. "strings"
  5. "time"
  6. "go.uber.org/zap"
  7. "go.uber.org/zap/zapcore"
  8. )
  9. type LogConfig struct {
  10. AppName string `yaml:"app_name" json:"app_name" toml:"app_name"`
  11. Level string `yaml:"level" json:"level" toml:"level"`
  12. StacktraceLevel string `yaml:"stacktrace_level" json:"stacktrace_level" toml:"stacktrace_level"`
  13. IsStdOut bool `yaml:"is_stdout" json:"is_stdout" toml:"is_stdout"`
  14. TimeFormat string `yaml:"time_format" json:"time_format" toml:"time_format"` // second, milli, nano, standard, iso,
  15. Encoding string `yaml:"encoding" json:"encoding" toml:"encoding"` // console, json
  16. Skip int `yaml:"skip" json:"skip" toml:"skip"`
  17. IsFileOut bool `yaml:"is_file_out" json:"is_file_out" toml:"is_file_out"`
  18. FileDir string `yaml:"file_dir" json:"file_dir" toml:"file_dir"`
  19. FileName string `yaml:"file_name" json:"file_name" toml:"file_name"`
  20. FileMaxSize int `yaml:"file_max_size" json:"file_max_size" toml:"file_max_size"`
  21. FileMaxAge int `yaml:"file_max_age" json:"file_max_age" toml:"file_max_age"`
  22. }
  23. var (
  24. l *LogX = defaultLogger()
  25. conf *LogConfig
  26. )
  27. // default logger setting
  28. func defaultLogger() *LogX {
  29. conf = &LogConfig{
  30. Level: "debug",
  31. StacktraceLevel: "error",
  32. IsStdOut: true,
  33. TimeFormat: "standard",
  34. Encoding: "console",
  35. Skip: 2,
  36. }
  37. writers := []zapcore.WriteSyncer{os.Stdout}
  38. lg, lv := newZapLogger(setLogLevel(conf.Level), setLogLevel(conf.StacktraceLevel), conf.Encoding, conf.TimeFormat, conf.Skip, zapcore.NewMultiWriteSyncer(writers...))
  39. zap.RedirectStdLog(lg)
  40. return &LogX{logger: lg, atomLevel: lv}
  41. }
  42. // create a new zaplog logger
  43. func newZapLogger(level, stacktrace zapcore.Level, encoding, timeType string, skip int, output zapcore.WriteSyncer) (*zap.Logger, *zap.AtomicLevel) {
  44. encCfg := zapcore.EncoderConfig{
  45. TimeKey: "T",
  46. LevelKey: "L",
  47. NameKey: "N",
  48. CallerKey: "C",
  49. MessageKey: "M",
  50. StacktraceKey: "S",
  51. LineEnding: zapcore.DefaultLineEnding,
  52. EncodeCaller: zapcore.ShortCallerEncoder,
  53. EncodeDuration: zapcore.NanosDurationEncoder,
  54. EncodeLevel: zapcore.LowercaseLevelEncoder,
  55. }
  56. setTimeFormat(timeType, &encCfg) // set time type
  57. atmLvl := zap.NewAtomicLevel() // set level
  58. atmLvl.SetLevel(level)
  59. encoder := zapcore.NewJSONEncoder(encCfg) // 确定encoder格式
  60. if encoding == "console" {
  61. encoder = zapcore.NewConsoleEncoder(encCfg)
  62. }
  63. return zap.New(zapcore.NewCore(encoder, output, atmLvl), zap.AddCaller(), zap.AddStacktrace(stacktrace), zap.AddCallerSkip(skip)), &atmLvl
  64. }
  65. // set log level
  66. func setLogLevel(lvl string) zapcore.Level {
  67. switch strings.ToLower(lvl) {
  68. case "panic":
  69. return zapcore.PanicLevel
  70. case "fatal":
  71. return zapcore.FatalLevel
  72. case "error":
  73. return zapcore.ErrorLevel
  74. case "warn", "warning":
  75. return zapcore.WarnLevel
  76. case "info":
  77. return zapcore.InfoLevel
  78. default:
  79. return zapcore.DebugLevel
  80. }
  81. }
  82. // set time format
  83. func setTimeFormat(timeType string, z *zapcore.EncoderConfig) {
  84. switch strings.ToLower(timeType) {
  85. case "iso": // iso8601 standard
  86. z.EncodeTime = zapcore.ISO8601TimeEncoder
  87. case "sec": // only for unix second, without millisecond
  88. z.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
  89. enc.AppendInt64(t.Unix())
  90. }
  91. case "second": // unix second, with millisecond
  92. z.EncodeTime = zapcore.EpochTimeEncoder
  93. case "milli", "millisecond": // millisecond
  94. z.EncodeTime = zapcore.EpochMillisTimeEncoder
  95. case "nano", "nanosecond": // nanosecond
  96. z.EncodeTime = zapcore.EpochNanosTimeEncoder
  97. default: // standard format
  98. z.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
  99. enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
  100. }
  101. }
  102. }
  103. func GetLevel() string {
  104. switch l.atomLevel.Level() {
  105. case zapcore.PanicLevel:
  106. return "panic"
  107. case zapcore.FatalLevel:
  108. return "fatal"
  109. case zapcore.ErrorLevel:
  110. return "error"
  111. case zapcore.WarnLevel:
  112. return "warn"
  113. case zapcore.InfoLevel:
  114. return "info"
  115. default:
  116. return "debug"
  117. }
  118. }
  119. func SetLevel(lvl string) {
  120. l.atomLevel.SetLevel(setLogLevel(lvl))
  121. }
  122. // temporary add call skip
  123. func AddCallerSkip(skip int) *LogX {
  124. l.logger.WithOptions(zap.AddCallerSkip(skip))
  125. return l
  126. }
  127. // permanent add call skip
  128. func AddDepth(skip int) *LogX {
  129. l.logger = l.logger.WithOptions(zap.AddCallerSkip(skip))
  130. return l
  131. }
  132. // permanent add options
  133. func AddOptions(opts ...zap.Option) *LogX {
  134. l.logger = l.logger.WithOptions(opts...)
  135. return l
  136. }
  137. func AddField(k string, v interface{}) {
  138. l.logger.With(zap.Any(k, v))
  139. }
  140. func AddFields(fields map[string]interface{}) *LogX {
  141. for k, v := range fields {
  142. l.logger.With(zap.Any(k, v))
  143. }
  144. return l
  145. }
  146. // Normal log
  147. func Debug(e interface{}, args ...interface{}) error {
  148. return l.Debug(e, args...)
  149. }
  150. func Info(e interface{}, args ...interface{}) error {
  151. return l.Info(e, args...)
  152. }
  153. func Warn(e interface{}, args ...interface{}) error {
  154. return l.Warn(e, args...)
  155. }
  156. func Error(e interface{}, args ...interface{}) error {
  157. return l.Error(e, args...)
  158. }
  159. func Panic(e interface{}, args ...interface{}) error {
  160. return l.Panic(e, args...)
  161. }
  162. func Fatal(e interface{}, args ...interface{}) error {
  163. return l.Fatal(e, args...)
  164. }
  165. // Format logs
  166. func Debugf(format string, args ...interface{}) error {
  167. return l.Debugf(format, args...)
  168. }
  169. func Infof(format string, args ...interface{}) error {
  170. return l.Infof(format, args...)
  171. }
  172. func Warnf(format string, args ...interface{}) error {
  173. return l.Warnf(format, args...)
  174. }
  175. func Errorf(format string, args ...interface{}) error {
  176. return l.Errorf(format, args...)
  177. }
  178. func Panicf(format string, args ...interface{}) error {
  179. return l.Panicf(format, args...)
  180. }
  181. func Fatalf(format string, args ...interface{}) error {
  182. return l.Fatalf(format, args...)
  183. }
  184. func formatFieldMap(m FieldMap) []Field {
  185. var res []Field
  186. for k, v := range m {
  187. res = append(res, zap.Any(k, v))
  188. }
  189. return res
  190. }