From f6c319752eb115992e5b2f0a0153ebbe42fbd627 Mon Sep 17 00:00:00 2001 From: Neur0toxine Date: Wed, 10 Apr 2024 14:06:41 +0300 Subject: [PATCH] json logging support, uppercase level --- core/config/config.go | 6 ++ core/config/config_test.go | 5 ++ core/engine.go | 9 ++- core/job_manager_test.go | 2 +- core/logger/default.go | 4 +- core/logger/zap.go | 58 +++++++++++++++++-- .../util/httputil/http_client_builder_test.go | 2 +- core/util/testutil/buffer_logger.go | 2 +- core/util/testutil/buffer_logger_test.go | 6 +- core/util/utils_test.go | 2 +- 10 files changed, 81 insertions(+), 15 deletions(-) diff --git a/core/config/config.go b/core/config/config.go index e49edcc..ea3ee72 100644 --- a/core/config/config.go +++ b/core/config/config.go @@ -14,6 +14,7 @@ type Configuration interface { GetVersion() string GetSentryDSN() string GetLogLevel() logging.Level + GetLogFormat() string GetHTTPConfig() HTTPServerConfig GetZabbixConfig() ZabbixConfig GetDBConfig() DatabaseConfig @@ -44,6 +45,7 @@ type Config struct { Database DatabaseConfig `yaml:"database"` UpdateInterval int `yaml:"update_interval"` LogLevel logging.Level `yaml:"log_level"` + LogFormat string `yaml:"log_format"` Debug bool `yaml:"debug"` } @@ -153,6 +155,10 @@ func (c Config) GetLogLevel() logging.Level { return c.LogLevel } +func (c Config) GetLogFormat() string { + return c.LogFormat +} + // GetTransportInfo transport basic data. func (c Config) GetTransportInfo() InfoInterface { return c.TransportInfo diff --git a/core/config/config_test.go b/core/config/config_test.go index 0b143d4..2fa569c 100644 --- a/core/config/config_test.go +++ b/core/config/config_test.go @@ -38,6 +38,7 @@ transport_info: sentry_dsn: dsn string log_level: 5 +log_format: console debug: true update_interval: 24 @@ -90,6 +91,10 @@ func (c *ConfigTest) Test_GetLogLevel() { assert.Equal(c.T(), logging.Level(5), c.config.GetLogLevel()) } +func (c *ConfigTest) Test_GetLogFormat() { + assert.Equal(c.T(), "console", c.config.GetLogFormat()) +} + func (c *ConfigTest) Test_IsDebug() { assert.Equal(c.T(), true, c.config.IsDebug()) } diff --git a/core/engine.go b/core/engine.go index 8c318b0..6887ad4 100644 --- a/core/engine.go +++ b/core/engine.go @@ -13,7 +13,7 @@ import ( "github.com/gin-gonic/gin" "github.com/gorilla/securecookie" "github.com/gorilla/sessions" - "github.com/retailcrm/zabbix-metrics-collector" + metrics "github.com/retailcrm/zabbix-metrics-collector" "go.uber.org/zap" "golang.org/x/text/language" @@ -141,9 +141,14 @@ func (e *Engine) Prepare() *Engine { e.Localizer.Preload(e.PreloadLanguages) } + logFormat := "json" + if format := e.Config.GetLogFormat(); format != "" { + logFormat = format + } + e.CreateDB(e.Config.GetDBConfig()) e.ResetUtils(e.Config.GetAWSConfig(), e.Config.IsDebug(), 0) - e.SetLogger(logger.NewDefault(e.Config.IsDebug())) + e.SetLogger(logger.NewDefault(logFormat, e.Config.IsDebug())) e.Sentry.Localizer = &e.Localizer e.Utils.Logger = e.Logger() e.Sentry.Logger = e.Logger() diff --git a/core/job_manager_test.go b/core/job_manager_test.go index ae3fd82..b6cce5a 100644 --- a/core/job_manager_test.go +++ b/core/job_manager_test.go @@ -436,7 +436,7 @@ func (t *JobManagerTest) WaitForJob() bool { func (t *JobManagerTest) Test_SetLogger() { t.manager.logger = nil - t.manager.SetLogger(logger.NewDefault(true)) + t.manager.SetLogger(logger.NewDefault("console", true)) assert.IsType(t.T(), &logger.Default{}, t.manager.logger) t.manager.SetLogger(nil) diff --git a/core/logger/default.go b/core/logger/default.go index b79f104..8b1bb1f 100644 --- a/core/logger/default.go +++ b/core/logger/default.go @@ -30,9 +30,9 @@ type Default struct { *zap.Logger } -func NewDefault(debug bool) Logger { +func NewDefault(format string, debug bool) Logger { return &Default{ - Logger: NewZap(debug), + Logger: NewZap(format, debug), } } diff --git a/core/logger/zap.go b/core/logger/zap.go index 69db51e..52618a1 100644 --- a/core/logger/zap.go +++ b/core/logger/zap.go @@ -1,13 +1,25 @@ package logger import ( + "fmt" "time" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) -func NewZap(debug bool) *zap.Logger { +func NewZap(format string, debug bool) *zap.Logger { + switch format { + case "json": + return NewZapJSON(debug) + case "console": + return NewZapConsole(debug) + default: + panic(fmt.Sprintf("unknown logger format: %s", format)) + } +} + +func NewZapConsole(debug bool) *zap.Logger { level := zapcore.InfoLevel if debug { level = zapcore.DebugLevel @@ -16,7 +28,7 @@ func NewZap(debug bool) *zap.Logger { Level: zap.NewAtomicLevelAt(level), Development: debug, Encoding: "console", - EncoderConfig: EncoderConfig(), + EncoderConfig: EncoderConfigConsole(), OutputPaths: []string{"stdout"}, ErrorOutputPaths: []string{"stderr"}, }.Build() @@ -26,7 +38,7 @@ func NewZap(debug bool) *zap.Logger { return log } -func EncoderConfig() zapcore.EncoderConfig { +func EncoderConfigConsole() zapcore.EncoderConfig { return zapcore.EncoderConfig{ MessageKey: "message", LevelKey: "level", @@ -37,7 +49,7 @@ func EncoderConfig() zapcore.EncoderConfig { StacktraceKey: "", LineEnding: "\n", EncodeLevel: func(level zapcore.Level, encoder zapcore.PrimitiveArrayEncoder) { - encoder.AppendString("level=" + level.String()) + encoder.AppendString("level=" + level.CapitalString()) }, EncodeTime: func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) { encoder.AppendString("time=" + t.Format(time.RFC3339)) @@ -50,3 +62,41 @@ func EncoderConfig() zapcore.EncoderConfig { ConsoleSeparator: " ", } } + +func NewZapJSON(debug bool) *zap.Logger { + level := zapcore.InfoLevel + if debug { + level = zapcore.DebugLevel + } + log, err := zap.Config{ + Level: zap.NewAtomicLevelAt(level), + Development: debug, + Encoding: "json", + EncoderConfig: EncoderConfigJSON(), + OutputPaths: []string{"stdout"}, + ErrorOutputPaths: []string{"stderr"}, + }.Build() + if err != nil { + panic(err) + } + return log +} + +func EncoderConfigJSON() zapcore.EncoderConfig { + return zapcore.EncoderConfig{ + MessageKey: "message", + LevelKey: "level", + TimeKey: "timestamp", + NameKey: "logger", + CallerKey: "caller", + FunctionKey: zapcore.OmitKey, + StacktraceKey: "", + LineEnding: "\n", + EncodeLevel: zapcore.CapitalLevelEncoder, + EncodeTime: zapcore.RFC3339TimeEncoder, + EncodeDuration: zapcore.StringDurationEncoder, + EncodeCaller: zapcore.ShortCallerEncoder, + EncodeName: zapcore.FullNameEncoder, + ConsoleSeparator: " ", + } +} diff --git a/core/util/httputil/http_client_builder_test.go b/core/util/httputil/http_client_builder_test.go index f2e9356..36d5931 100644 --- a/core/util/httputil/http_client_builder_test.go +++ b/core/util/httputil/http_client_builder_test.go @@ -142,7 +142,7 @@ func (t *HTTPClientBuilderTest) Test_WithLogger() { builder.WithLogger(nil) assert.Nil(t.T(), builder.logger) - log := logger.NewDefault(true) + log := logger.NewDefault("console", true) builder.WithLogger(log) assert.NotNil(t.T(), builder.logger) } diff --git a/core/util/testutil/buffer_logger.go b/core/util/testutil/buffer_logger.go index 08e887b..ff8ddf8 100644 --- a/core/util/testutil/buffer_logger.go +++ b/core/util/testutil/buffer_logger.go @@ -37,7 +37,7 @@ func NewBufferedLogger() BufferedLogger { bl.Logger = zap.New( zapcore.NewCore( zapcore.NewConsoleEncoder( - logger.EncoderConfig()), zap.CombineWriteSyncers(os.Stdout, os.Stderr, &bl.buf), zapcore.DebugLevel)) + logger.EncoderConfigConsole()), zap.CombineWriteSyncers(os.Stdout, os.Stderr, &bl.buf), zapcore.DebugLevel)) return bl } diff --git a/core/util/testutil/buffer_logger_test.go b/core/util/testutil/buffer_logger_test.go index dd4865c..f144082 100644 --- a/core/util/testutil/buffer_logger_test.go +++ b/core/util/testutil/buffer_logger_test.go @@ -29,17 +29,17 @@ func (t *BufferLoggerTest) Test_Read() { data, err := io.ReadAll(t.logger) t.Require().NoError(err) - t.Assert().Contains(string(data), "level=debug test") + t.Assert().Contains(string(data), "level=DEBUG test") } func (t *BufferLoggerTest) Test_Bytes() { t.logger.Debug("test") - t.Assert().Contains(string(t.logger.Bytes()), "level=debug test") + t.Assert().Contains(string(t.logger.Bytes()), "level=DEBUG test") } func (t *BufferLoggerTest) Test_String() { t.logger.Debug("test") - t.Assert().Contains(t.logger.String(), "level=debug test") + t.Assert().Contains(t.logger.String(), "level=DEBUG test") } func (t *BufferLoggerTest) TestRace() { diff --git a/core/util/utils_test.go b/core/util/utils_test.go index ffa2374..c1d577c 100644 --- a/core/util/utils_test.go +++ b/core/util/utils_test.go @@ -38,7 +38,7 @@ func mgClient() *v1.MgClient { } func (u *UtilsTest) SetupSuite() { - logger := logger.NewDefault(true) + logger := logger.NewDefault("console", true) awsConfig := config.AWS{ AccessKeyID: "access key id (will be removed)", SecretAccessKey: "secret access key",