93 lines
2.3 KiB
Go
93 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"git.frostfs.info/TrueCloudLab/zapjournald"
|
|
"github.com/spf13/viper"
|
|
"github.com/ssgreg/journald"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
)
|
|
|
|
const (
|
|
destinationStdout string = "stdout"
|
|
destinationJournald string = "journald"
|
|
)
|
|
|
|
type Logger struct {
|
|
logger *zap.Logger
|
|
lvl zap.AtomicLevel
|
|
}
|
|
|
|
func pickLogger(v *viper.Viper) *Logger {
|
|
lvl, err := getLogLevel(v.GetString(cfgLoggerLevel))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
dest := v.GetString(cfgLoggerDestination)
|
|
|
|
if dest == destinationStdout {
|
|
return newStdoutLogger(lvl)
|
|
}
|
|
|
|
if dest == destinationJournald {
|
|
return newJournaldLogger(lvl)
|
|
}
|
|
|
|
panic(fmt.Sprintf("wrong destination for logger: %s", dest))
|
|
}
|
|
|
|
func newStdoutLogger(lvl zapcore.Level) *Logger {
|
|
c := zap.NewProductionConfig()
|
|
c.Level = zap.NewAtomicLevelAt(lvl)
|
|
c.Encoding = "console"
|
|
c.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
|
|
|
l, err := c.Build(
|
|
zap.AddStacktrace(zap.NewAtomicLevelAt(zap.FatalLevel)),
|
|
)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("build zap logger instance: %v", err))
|
|
}
|
|
|
|
return &Logger{logger: l, lvl: c.Level}
|
|
}
|
|
|
|
func newJournaldLogger(lvl zapcore.Level) *Logger {
|
|
c := zap.NewProductionConfig()
|
|
c.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
|
c.Level = zap.NewAtomicLevelAt(lvl)
|
|
|
|
// We can use NewJSONEncoder instead if, say, frontend
|
|
// would like to access journald logs and parse them easily.
|
|
encoder := zapjournald.NewPartialEncoder(zapcore.NewConsoleEncoder(c.EncoderConfig), zapjournald.SyslogFields)
|
|
|
|
core := zapjournald.NewCore(c.Level, encoder, &journald.Journal{}, zapjournald.SyslogFields)
|
|
coreWithContext := core.With([]zapcore.Field{
|
|
zapjournald.SyslogFacility(zapjournald.LogDaemon),
|
|
zapjournald.SyslogIdentifier(),
|
|
zapjournald.SyslogPid(),
|
|
})
|
|
l := zap.New(coreWithContext, zap.AddStacktrace(zap.NewAtomicLevelAt(zap.FatalLevel)))
|
|
return &Logger{logger: l, lvl: c.Level}
|
|
}
|
|
|
|
func getLogLevel(lvlStr string) (zapcore.Level, error) {
|
|
var lvl zapcore.Level
|
|
err := lvl.UnmarshalText([]byte(lvlStr))
|
|
if err != nil {
|
|
return lvl, fmt.Errorf("incorrect logger level configuration %s (%v), "+
|
|
"value should be one of %v", lvlStr, err, [...]zapcore.Level{
|
|
zapcore.DebugLevel,
|
|
zapcore.InfoLevel,
|
|
zapcore.WarnLevel,
|
|
zapcore.ErrorLevel,
|
|
zapcore.DPanicLevel,
|
|
zapcore.PanicLevel,
|
|
zapcore.FatalLevel,
|
|
})
|
|
}
|
|
return lvl, nil
|
|
}
|