package pkg import ( "context" "os" "strconv" "github.com/mattn/go-colorable" "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" ) type LoggerConfig struct { Level zapcore.Level Filename string MaxSize int MaxAge int MaxBackups int Compress bool ConsoleEncoding bool // true for Console output, false for JSON } var loggerInstance *zap.Logger // GetLogger returns a singleton logger instance func GetLogger(ctx context.Context, config LoggerConfig) *zap.Logger { if loggerInstance == nil { createOrUpdateInstance(config) } return loggerInstance } func createOrUpdateInstance(config LoggerConfig) *zap.Logger { core := zapcore.NewTee( createFileCore(config), createStdoutCore(config), ) loggerInstance = zap.New(core).WithOptions( zap.IncreaseLevel(config.Level), ) return loggerInstance } // createFileCore creates the file logging core func createFileCore(config LoggerConfig) zapcore.Core { fileEncoderConfig := zap.NewProductionEncoderConfig() fileEncoder := zapcore.NewJSONEncoder(fileEncoderConfig) fileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ Filename: config.Filename, MaxSize: config.MaxSize, MaxAge: config.MaxAge, MaxBackups: config.MaxBackups, Compress: config.Compress, }) return zapcore.NewCore(fileEncoder, fileWriteSyncer, zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { return lvl >= zapcore.ErrorLevel })) } // createStdoutCore creates the stdout logging core based on config.ConsoleEncoding func createStdoutCore(config LoggerConfig) zapcore.Core { var encoder zapcore.Encoder encoderConfig := zap.NewDevelopmentEncoderConfig() encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder encoderConfig.TimeKey = "" if config.ConsoleEncoding { encoder = zapcore.NewConsoleEncoder(encoderConfig) } else { encoder = zapcore.NewJSONEncoder(encoderConfig) } stdoutWriteSyncer := zapcore.AddSync(colorable.NewColorableStdout()) return zapcore.NewCore(encoder, stdoutWriteSyncer, zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { return true })) } func OverrideLoggerConfig(config LoggerConfig) { Logger = createOrUpdateInstance(config) } var level, err = strconv.Atoi(os.Getenv("LOG_LEVEL")) var Logger = GetLogger(context.Background(), LoggerConfig{ Level: zapcore.Level(level), Filename: "./tmp/error.log", MaxSize: 100, MaxAge: 90, MaxBackups: 30, Compress: true, ConsoleEncoding: true, })