arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
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}