| iomodo | c6abf5b | 2021-02-19 14:48:03 +0400 | [diff] [blame] | 1 | package log |
| 2 | |
| 3 | import ( |
| 4 | "os" |
| 5 | |
| 6 | "go.uber.org/zap" |
| 7 | "go.uber.org/zap/zapcore" |
| 8 | "gopkg.in/natefinch/lumberjack.v2" |
| 9 | ) |
| 10 | |
| 11 | const ( |
| 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 |
| 23 | type Field = zapcore.Field |
| 24 | |
| 25 | var Int = zap.Int |
| 26 | var String = zap.String |
| 27 | var Any = zap.Any |
| 28 | var Err = zap.Error |
| 29 | var Time = zap.Time |
| 30 | var Duration = zap.Duration |
| 31 | |
| 32 | // Logger logs messages |
| 33 | type Logger struct { |
| 34 | zap *zap.Logger |
| 35 | consoleLevel zap.AtomicLevel |
| 36 | fileLevel zap.AtomicLevel |
| 37 | } |
| 38 | |
| 39 | // LoggerConfiguration represents configuration of the logger |
| 40 | type 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 |
| 51 | func NewLogger(config *LoggerConfiguration) *Logger { |
| 52 | cores := []zapcore.Core{} |
| iomodo | d32f9ee | 2021-02-21 21:28:50 +0400 | [diff] [blame] | 53 | consoleLevel := zap.NewAtomicLevelAt(getZapLevel(config.ConsoleLevel)) |
| 54 | fileLevel := zap.NewAtomicLevelAt(getZapLevel(config.FileLevel)) |
| iomodo | c6abf5b | 2021-02-19 14:48:03 +0400 | [diff] [blame] | 55 | |
| 56 | if config.EnableConsole { |
| 57 | writer := zapcore.Lock(os.Stderr) |
| iomodo | d32f9ee | 2021-02-21 21:28:50 +0400 | [diff] [blame] | 58 | core := zapcore.NewCore(makeEncoder(config.ConsoleJSON), writer, consoleLevel) |
| iomodo | c6abf5b | 2021-02-19 14:48:03 +0400 | [diff] [blame] | 59 | 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 | }) |
| iomodo | d32f9ee | 2021-02-21 21:28:50 +0400 | [diff] [blame] | 68 | core := zapcore.NewCore(makeEncoder(config.FileJSON), writer, fileLevel) |
| iomodo | c6abf5b | 2021-02-19 14:48:03 +0400 | [diff] [blame] | 69 | cores = append(cores, core) |
| 70 | } |
| 71 | |
| 72 | combinedCore := zapcore.NewTee(cores...) |
| 73 | |
| iomodo | d32f9ee | 2021-02-21 21:28:50 +0400 | [diff] [blame] | 74 | zap := zap.New(combinedCore, |
| iomodo | c6abf5b | 2021-02-19 14:48:03 +0400 | [diff] [blame] | 75 | zap.AddCaller(), |
| 76 | ) |
| 77 | |
| iomodo | d32f9ee | 2021-02-21 21:28:50 +0400 | [diff] [blame] | 78 | return &Logger{ |
| 79 | consoleLevel: consoleLevel, |
| 80 | fileLevel: fileLevel, |
| 81 | zap: zap, |
| 82 | } |
| iomodo | c6abf5b | 2021-02-19 14:48:03 +0400 | [diff] [blame] | 83 | } |
| 84 | |
| 85 | func (l *Logger) Debug(message string, fields ...Field) { |
| 86 | l.zap.Debug(message, fields...) |
| 87 | } |
| 88 | |
| 89 | func (l *Logger) Info(message string, fields ...Field) { |
| 90 | l.zap.Info(message, fields...) |
| 91 | } |
| 92 | |
| 93 | func (l *Logger) Warn(message string, fields ...Field) { |
| 94 | l.zap.Warn(message, fields...) |
| 95 | } |
| 96 | |
| 97 | func (l *Logger) Error(message string, fields ...Field) { |
| 98 | l.zap.Error(message, fields...) |
| 99 | } |
| 100 | |
| 101 | func 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 | |
| 116 | func 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 | } |