1package log
2
3import (
4	"os"
5
6	"go.uber.org/zap"
7	"go.uber.org/zap/zapcore"
8	"golang.org/x/xerrors"
9)
10
11var (
12	Logger      *zap.SugaredLogger
13	debugOption bool
14)
15
16func InitLogger(debug, disable bool) (err error) {
17	debugOption = debug
18	Logger, err = NewLogger(debug, disable)
19	if err != nil {
20		return xerrors.Errorf("error in new logger: %w", err)
21	}
22	return nil
23
24}
25
26func NewLogger(debug, disable bool) (*zap.SugaredLogger, error) {
27	// First, define our level-handling logic.
28	errorPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
29		return lvl >= zapcore.ErrorLevel
30	})
31	logPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
32		if debug {
33			return lvl < zapcore.ErrorLevel
34		}
35		// Not enable debug level
36		return zapcore.DebugLevel < lvl && lvl < zapcore.ErrorLevel
37	})
38
39	encoderConfig := zapcore.EncoderConfig{
40		TimeKey:        "Time",
41		LevelKey:       "Level",
42		NameKey:        "Name",
43		CallerKey:      "Caller",
44		MessageKey:     "Msg",
45		StacktraceKey:  "St",
46		EncodeLevel:    zapcore.CapitalColorLevelEncoder,
47		EncodeTime:     zapcore.ISO8601TimeEncoder,
48		EncodeDuration: zapcore.StringDurationEncoder,
49		EncodeCaller:   zapcore.ShortCallerEncoder,
50	}
51
52	consoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
53
54	// High-priority output should also go to standard error, and low-priority
55	// output should also go to standard out.
56	consoleLogs := zapcore.Lock(os.Stdout)
57	consoleErrors := zapcore.Lock(os.Stderr)
58	if disable {
59		devNull, err := os.Create(os.DevNull)
60		if err != nil {
61			return nil, err
62		}
63		// Discard low-priority output
64		consoleLogs = zapcore.Lock(devNull)
65	}
66
67	core := zapcore.NewTee(
68		zapcore.NewCore(consoleEncoder, consoleErrors, errorPriority),
69		zapcore.NewCore(consoleEncoder, consoleLogs, logPriority),
70	)
71
72	opts := []zap.Option{zap.ErrorOutput(zapcore.Lock(os.Stderr))}
73	if debug {
74		opts = append(opts, zap.Development())
75	}
76	logger := zap.New(core, opts...)
77
78	return logger.Sugar(), nil
79}
80
81func Fatal(err error) {
82	if debugOption {
83		Logger.Fatalf("%+v", err)
84	}
85	Logger.Fatal(err)
86}
87