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