blob: 71686a7894d97e87a753ee0f5296424c27032aaa [file] [log] [blame]
iomodoc6abf5b2021-02-19 14:48:03 +04001package log
2
3import (
4 "os"
5
6 "go.uber.org/zap"
7 "go.uber.org/zap/zapcore"
8 "gopkg.in/natefinch/lumberjack.v2"
9)
10
11const (
12 // LevelDebug represents very verbose messages for debugging specific issues
13 LevelDebug = "debug"
14 // LevelInfo represents default log level, informational
15 LevelInfo = "info"
16 // LevelWarn represents messages about possible issues
17 LevelWarn = "warn"
18 // LevelError represents messages about things we know are problems
19 LevelError = "error"
20)
21
22// Type and function aliases from zap to limit the libraries scope into our code
23type Field = zapcore.Field
24
25var Int = zap.Int
26var String = zap.String
27var Any = zap.Any
28var Err = zap.Error
29var Time = zap.Time
30var Duration = zap.Duration
31
32// Logger logs messages
33type Logger struct {
34 zap *zap.Logger
35 consoleLevel zap.AtomicLevel
36 fileLevel zap.AtomicLevel
37}
38
39// LoggerConfiguration represents configuration of the logger
40type LoggerConfiguration struct {
41 EnableConsole bool
42 ConsoleJSON bool
43 ConsoleLevel string
44 EnableFile bool
45 FileJSON bool
46 FileLevel string
47 FileLocation string
48}
49
50// NewLogger creates new logger
51func NewLogger(config *LoggerConfiguration) *Logger {
52 cores := []zapcore.Core{}
iomodod32f9ee2021-02-21 21:28:50 +040053 consoleLevel := zap.NewAtomicLevelAt(getZapLevel(config.ConsoleLevel))
54 fileLevel := zap.NewAtomicLevelAt(getZapLevel(config.FileLevel))
iomodoc6abf5b2021-02-19 14:48:03 +040055
56 if config.EnableConsole {
57 writer := zapcore.Lock(os.Stderr)
iomodod32f9ee2021-02-21 21:28:50 +040058 core := zapcore.NewCore(makeEncoder(config.ConsoleJSON), writer, consoleLevel)
iomodoc6abf5b2021-02-19 14:48:03 +040059 cores = append(cores, core)
60 }
61
62 if config.EnableFile {
63 writer := zapcore.AddSync(&lumberjack.Logger{
64 Filename: config.FileLocation,
65 MaxSize: 100,
66 Compress: true,
67 })
iomodod32f9ee2021-02-21 21:28:50 +040068 core := zapcore.NewCore(makeEncoder(config.FileJSON), writer, fileLevel)
iomodoc6abf5b2021-02-19 14:48:03 +040069 cores = append(cores, core)
70 }
71
72 combinedCore := zapcore.NewTee(cores...)
73
iomodod32f9ee2021-02-21 21:28:50 +040074 zap := zap.New(combinedCore,
iomodoc6abf5b2021-02-19 14:48:03 +040075 zap.AddCaller(),
76 )
77
iomodod32f9ee2021-02-21 21:28:50 +040078 return &Logger{
79 consoleLevel: consoleLevel,
80 fileLevel: fileLevel,
81 zap: zap,
82 }
iomodoc6abf5b2021-02-19 14:48:03 +040083}
84
85func (l *Logger) Debug(message string, fields ...Field) {
86 l.zap.Debug(message, fields...)
87}
88
89func (l *Logger) Info(message string, fields ...Field) {
90 l.zap.Info(message, fields...)
91}
92
93func (l *Logger) Warn(message string, fields ...Field) {
94 l.zap.Warn(message, fields...)
95}
96
97func (l *Logger) Error(message string, fields ...Field) {
98 l.zap.Error(message, fields...)
99}
100
101func getZapLevel(level string) zapcore.Level {
102 switch level {
103 case LevelInfo:
104 return zapcore.InfoLevel
105 case LevelWarn:
106 return zapcore.WarnLevel
107 case LevelDebug:
108 return zapcore.DebugLevel
109 case LevelError:
110 return zapcore.ErrorLevel
111 default:
112 return zapcore.InfoLevel
113 }
114}
115
116func makeEncoder(json bool) zapcore.Encoder {
117 encoderConfig := zap.NewProductionEncoderConfig()
118 if json {
119 return zapcore.NewJSONEncoder(encoderConfig)
120 }
121
122 encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
123 return zapcore.NewConsoleEncoder(encoderConfig)
124}