json logging support, uppercase level

This commit is contained in:
Pavel 2024-04-10 14:06:41 +03:00
parent aead3854e1
commit f6c319752e
10 changed files with 81 additions and 15 deletions

View File

@ -14,6 +14,7 @@ type Configuration interface {
GetVersion() string GetVersion() string
GetSentryDSN() string GetSentryDSN() string
GetLogLevel() logging.Level GetLogLevel() logging.Level
GetLogFormat() string
GetHTTPConfig() HTTPServerConfig GetHTTPConfig() HTTPServerConfig
GetZabbixConfig() ZabbixConfig GetZabbixConfig() ZabbixConfig
GetDBConfig() DatabaseConfig GetDBConfig() DatabaseConfig
@ -44,6 +45,7 @@ type Config struct {
Database DatabaseConfig `yaml:"database"` Database DatabaseConfig `yaml:"database"`
UpdateInterval int `yaml:"update_interval"` UpdateInterval int `yaml:"update_interval"`
LogLevel logging.Level `yaml:"log_level"` LogLevel logging.Level `yaml:"log_level"`
LogFormat string `yaml:"log_format"`
Debug bool `yaml:"debug"` Debug bool `yaml:"debug"`
} }
@ -153,6 +155,10 @@ func (c Config) GetLogLevel() logging.Level {
return c.LogLevel return c.LogLevel
} }
func (c Config) GetLogFormat() string {
return c.LogFormat
}
// GetTransportInfo transport basic data. // GetTransportInfo transport basic data.
func (c Config) GetTransportInfo() InfoInterface { func (c Config) GetTransportInfo() InfoInterface {
return c.TransportInfo return c.TransportInfo

View File

@ -38,6 +38,7 @@ transport_info:
sentry_dsn: dsn string sentry_dsn: dsn string
log_level: 5 log_level: 5
log_format: console
debug: true debug: true
update_interval: 24 update_interval: 24
@ -90,6 +91,10 @@ func (c *ConfigTest) Test_GetLogLevel() {
assert.Equal(c.T(), logging.Level(5), c.config.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() { func (c *ConfigTest) Test_IsDebug() {
assert.Equal(c.T(), true, c.config.IsDebug()) assert.Equal(c.T(), true, c.config.IsDebug())
} }

View File

@ -13,7 +13,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gorilla/securecookie" "github.com/gorilla/securecookie"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
"github.com/retailcrm/zabbix-metrics-collector" metrics "github.com/retailcrm/zabbix-metrics-collector"
"go.uber.org/zap" "go.uber.org/zap"
"golang.org/x/text/language" "golang.org/x/text/language"
@ -141,9 +141,14 @@ func (e *Engine) Prepare() *Engine {
e.Localizer.Preload(e.PreloadLanguages) e.Localizer.Preload(e.PreloadLanguages)
} }
logFormat := "json"
if format := e.Config.GetLogFormat(); format != "" {
logFormat = format
}
e.CreateDB(e.Config.GetDBConfig()) e.CreateDB(e.Config.GetDBConfig())
e.ResetUtils(e.Config.GetAWSConfig(), e.Config.IsDebug(), 0) 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.Sentry.Localizer = &e.Localizer
e.Utils.Logger = e.Logger() e.Utils.Logger = e.Logger()
e.Sentry.Logger = e.Logger() e.Sentry.Logger = e.Logger()

View File

@ -436,7 +436,7 @@ func (t *JobManagerTest) WaitForJob() bool {
func (t *JobManagerTest) Test_SetLogger() { func (t *JobManagerTest) Test_SetLogger() {
t.manager.logger = nil 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) assert.IsType(t.T(), &logger.Default{}, t.manager.logger)
t.manager.SetLogger(nil) t.manager.SetLogger(nil)

View File

@ -30,9 +30,9 @@ type Default struct {
*zap.Logger *zap.Logger
} }
func NewDefault(debug bool) Logger { func NewDefault(format string, debug bool) Logger {
return &Default{ return &Default{
Logger: NewZap(debug), Logger: NewZap(format, debug),
} }
} }

View File

@ -1,13 +1,25 @@
package logger package logger
import ( import (
"fmt"
"time" "time"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zapcore" "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 level := zapcore.InfoLevel
if debug { if debug {
level = zapcore.DebugLevel level = zapcore.DebugLevel
@ -16,7 +28,7 @@ func NewZap(debug bool) *zap.Logger {
Level: zap.NewAtomicLevelAt(level), Level: zap.NewAtomicLevelAt(level),
Development: debug, Development: debug,
Encoding: "console", Encoding: "console",
EncoderConfig: EncoderConfig(), EncoderConfig: EncoderConfigConsole(),
OutputPaths: []string{"stdout"}, OutputPaths: []string{"stdout"},
ErrorOutputPaths: []string{"stderr"}, ErrorOutputPaths: []string{"stderr"},
}.Build() }.Build()
@ -26,7 +38,7 @@ func NewZap(debug bool) *zap.Logger {
return log return log
} }
func EncoderConfig() zapcore.EncoderConfig { func EncoderConfigConsole() zapcore.EncoderConfig {
return zapcore.EncoderConfig{ return zapcore.EncoderConfig{
MessageKey: "message", MessageKey: "message",
LevelKey: "level", LevelKey: "level",
@ -37,7 +49,7 @@ func EncoderConfig() zapcore.EncoderConfig {
StacktraceKey: "", StacktraceKey: "",
LineEnding: "\n", LineEnding: "\n",
EncodeLevel: func(level zapcore.Level, encoder zapcore.PrimitiveArrayEncoder) { 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) { EncodeTime: func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
encoder.AppendString("time=" + t.Format(time.RFC3339)) encoder.AppendString("time=" + t.Format(time.RFC3339))
@ -50,3 +62,41 @@ func EncoderConfig() zapcore.EncoderConfig {
ConsoleSeparator: " ", 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: " ",
}
}

View File

@ -142,7 +142,7 @@ func (t *HTTPClientBuilderTest) Test_WithLogger() {
builder.WithLogger(nil) builder.WithLogger(nil)
assert.Nil(t.T(), builder.logger) assert.Nil(t.T(), builder.logger)
log := logger.NewDefault(true) log := logger.NewDefault("console", true)
builder.WithLogger(log) builder.WithLogger(log)
assert.NotNil(t.T(), builder.logger) assert.NotNil(t.T(), builder.logger)
} }

View File

@ -37,7 +37,7 @@ func NewBufferedLogger() BufferedLogger {
bl.Logger = zap.New( bl.Logger = zap.New(
zapcore.NewCore( zapcore.NewCore(
zapcore.NewConsoleEncoder( 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 return bl
} }

View File

@ -29,17 +29,17 @@ func (t *BufferLoggerTest) Test_Read() {
data, err := io.ReadAll(t.logger) data, err := io.ReadAll(t.logger)
t.Require().NoError(err) 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() { func (t *BufferLoggerTest) Test_Bytes() {
t.logger.Debug("test") 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() { func (t *BufferLoggerTest) Test_String() {
t.logger.Debug("test") 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() { func (t *BufferLoggerTest) TestRace() {

View File

@ -38,7 +38,7 @@ func mgClient() *v1.MgClient {
} }
func (u *UtilsTest) SetupSuite() { func (u *UtilsTest) SetupSuite() {
logger := logger.NewDefault(true) logger := logger.NewDefault("console", true)
awsConfig := config.AWS{ awsConfig := config.AWS{
AccessKeyID: "access key id (will be removed)", AccessKeyID: "access key id (will be removed)",
SecretAccessKey: "secret access key", SecretAccessKey: "secret access key",