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.

186 lines
4.3 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. package log
  2. import (
  3. "fmt"
  4. "strings"
  5. "time"
  6. "github.com/hermeznetwork/tracerr"
  7. "go.uber.org/zap"
  8. "go.uber.org/zap/zapcore"
  9. )
  10. var log *zap.SugaredLogger
  11. func init() {
  12. // default level: debug
  13. Init("debug", "")
  14. }
  15. // Init the logger with defined level. errorsPath defines the file where to store the errors, if set to "" will not store errors.
  16. func Init(levelStr, logPath string) {
  17. var level zap.AtomicLevel
  18. err := level.UnmarshalText([]byte(levelStr))
  19. if err != nil {
  20. panic(fmt.Errorf("Error on setting log level: %s", err))
  21. }
  22. outputPaths := []string{"stdout"}
  23. if logPath != "" {
  24. log.Infof("log file: %s", logPath)
  25. outputPaths = append(outputPaths, logPath)
  26. }
  27. cfg := zap.Config{
  28. Level: level,
  29. Encoding: "console",
  30. OutputPaths: outputPaths,
  31. ErrorOutputPaths: []string{"stderr"},
  32. EncoderConfig: zapcore.EncoderConfig{
  33. MessageKey: "message",
  34. LevelKey: "level",
  35. EncodeLevel: zapcore.CapitalColorLevelEncoder,
  36. TimeKey: "timestamp",
  37. EncodeTime: func(ts time.Time, encoder zapcore.PrimitiveArrayEncoder) {
  38. encoder.AppendString(ts.Local().Format(time.RFC3339))
  39. },
  40. EncodeDuration: zapcore.SecondsDurationEncoder,
  41. CallerKey: "caller",
  42. EncodeCaller: zapcore.ShortCallerEncoder,
  43. // StacktraceKey: "stacktrace",
  44. StacktraceKey: "",
  45. LineEnding: zapcore.DefaultLineEnding,
  46. },
  47. }
  48. logger, err := cfg.Build()
  49. if err != nil {
  50. panic(err)
  51. }
  52. //nolint:errcheck
  53. defer logger.Sync()
  54. withOptions := logger.WithOptions(zap.AddCallerSkip(1))
  55. log = withOptions.Sugar()
  56. log.Infof("log level: %s", level)
  57. }
  58. func sprintStackTrace(st []tracerr.Frame) string {
  59. builder := strings.Builder{}
  60. for _, f := range st {
  61. builder.WriteString(fmt.Sprintf("\n%s:%d %s()", f.Path, f.Line, f.Func))
  62. }
  63. builder.WriteString("\n")
  64. return builder.String()
  65. }
  66. // appendStackTraceMaybeArgs will append the stacktrace to the args if one of them
  67. // is a tracerr.Error
  68. func appendStackTraceMaybeArgs(args []interface{}) []interface{} {
  69. for i := range args {
  70. if err, ok := args[i].(tracerr.Error); ok {
  71. st := err.StackTrace()
  72. return append(args, sprintStackTrace(st))
  73. }
  74. }
  75. return args
  76. }
  77. // Debug calls log.Debug
  78. func Debug(args ...interface{}) {
  79. log.Debug(args...)
  80. }
  81. // Info calls log.Info
  82. func Info(args ...interface{}) {
  83. log.Info(args...)
  84. }
  85. // Warn calls log.Warn
  86. func Warn(args ...interface{}) {
  87. args = appendStackTraceMaybeArgs(args)
  88. log.Warn(args...)
  89. }
  90. // Error calls log.Error
  91. func Error(args ...interface{}) {
  92. args = appendStackTraceMaybeArgs(args)
  93. log.Error(args...)
  94. }
  95. // Fatal calls log.Fatal
  96. func Fatal(args ...interface{}) {
  97. args = appendStackTraceMaybeArgs(args)
  98. log.Fatal(args...)
  99. }
  100. // Debugf calls log.Debugf
  101. func Debugf(template string, args ...interface{}) {
  102. log.Debugf(template, args...)
  103. }
  104. // Infof calls log.Infof
  105. func Infof(template string, args ...interface{}) {
  106. log.Infof(template, args...)
  107. }
  108. // Warnf calls log.Warnf
  109. func Warnf(template string, args ...interface{}) {
  110. log.Warnf(template, args...)
  111. }
  112. // Fatalf calls log.Warnf
  113. func Fatalf(template string, args ...interface{}) {
  114. log.Fatalf(template, args...)
  115. }
  116. // Errorf calls log.Errorf and stores the error message into the ErrorFile
  117. func Errorf(template string, args ...interface{}) {
  118. log.Errorf(template, args...)
  119. }
  120. // appendStackTraceMaybeKV will append the stacktrace to the KV if one of them
  121. // is a tracerr.Error
  122. func appendStackTraceMaybeKV(msg string, kv []interface{}) string {
  123. for i := range kv {
  124. if i%2 == 0 {
  125. continue
  126. }
  127. if err, ok := kv[i].(tracerr.Error); ok {
  128. st := err.StackTrace()
  129. return fmt.Sprintf("%v: %v%v\n", msg, err, sprintStackTrace(st))
  130. }
  131. }
  132. return msg
  133. }
  134. // Debugw calls log.Debugw
  135. func Debugw(template string, kv ...interface{}) {
  136. log.Debugw(template, kv...)
  137. }
  138. // Infow calls log.Infow
  139. func Infow(template string, kv ...interface{}) {
  140. log.Infow(template, kv...)
  141. }
  142. // Warnw calls log.Warnw
  143. func Warnw(template string, kv ...interface{}) {
  144. template = appendStackTraceMaybeKV(template, kv)
  145. log.Warnw(template, kv...)
  146. }
  147. // Errorw calls log.Errorw
  148. func Errorw(template string, kv ...interface{}) {
  149. template = appendStackTraceMaybeKV(template, kv)
  150. log.Errorw(template, kv...)
  151. }
  152. // Fatalw calls log.Fatalw
  153. func Fatalw(template string, kv ...interface{}) {
  154. template = appendStackTraceMaybeKV(template, kv)
  155. log.Fatalw(template, kv...)
  156. }