[#20] Add log sampling configuration

Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
Denis Kirillov 2024-09-23 16:27:27 +03:00
parent fce631be59
commit 5ffed0b96f
5 changed files with 59 additions and 30 deletions

View file

@ -21,29 +21,19 @@ type Logger struct {
}
func pickLogger(v *viper.Viper) *Logger {
lvl, err := getLogLevel(v.GetString(cfgLoggerLevel))
if err != nil {
panic(err)
switch dest := v.GetString(cfgLoggerDestination); dest {
case destinationStdout:
return newStdoutLogger(v)
case destinationJournald:
return newJournaldLogger(v)
default:
panic(fmt.Sprintf("wrong destination for logger: %s", dest))
}
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)
func newStdoutLogger(v *viper.Viper) *Logger {
c := newZapLogConfig(v)
c.Encoding = "console"
c.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
l, err := c.Build(
zap.AddStacktrace(zap.NewAtomicLevelAt(zap.FatalLevel)),
@ -55,10 +45,8 @@ func newStdoutLogger(lvl zapcore.Level) *Logger {
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)
func newJournaldLogger(v *viper.Viper) *Logger {
c := newZapLogConfig(v)
// We can use NewJSONEncoder instead if, say, frontend
// would like to access journald logs and parse them easily.
@ -74,6 +62,28 @@ func newJournaldLogger(lvl zapcore.Level) *Logger {
return &Logger{logger: l, lvl: c.Level}
}
func newZapLogConfig(v *viper.Viper) zap.Config {
lvl, err := getLogLevel(v.GetString(cfgLoggerLevel))
if err != nil {
panic(err)
}
c := zap.NewProductionConfig()
c.Level = zap.NewAtomicLevelAt(lvl)
c.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
if v.GetBool(cfgLoggerSamplingEnabled) {
c.Sampling = &zap.SamplingConfig{
Initial: v.GetInt(cfgLoggerSamplingInitial),
Thereafter: v.GetInt(cfgLoggerSamplingThereafter),
}
} else {
c.Sampling = nil
}
return c
}
func getLogLevel(lvlStr string) (zapcore.Level, error) {
var lvl zapcore.Level
err := lvl.UnmarshalText([]byte(lvlStr))

View file

@ -36,8 +36,11 @@ const (
cfgPprofAddress = "pprof.address"
// Logger.
cfgLoggerLevel = "logger.level"
cfgLoggerDestination = "logger.destination"
cfgLoggerLevel = "logger.level"
cfgLoggerDestination = "logger.destination"
cfgLoggerSamplingEnabled = "logger.sampling.enabled"
cfgLoggerSamplingInitial = "logger.sampling.initial"
cfgLoggerSamplingThereafter = "logger.sampling.thereafter"
// Morph.
cfgMorphRPCEndpointPrefixTmpl = "morph.rpc_endpoint.%d."
@ -125,6 +128,8 @@ func settings() *viper.Viper {
// logger:
v.SetDefault(cfgLoggerLevel, "info")
v.SetDefault(cfgLoggerDestination, "stdout")
v.SetDefault(cfgLoggerSamplingThereafter, 100)
v.SetDefault(cfgLoggerSamplingInitial, 100)
// services:
v.SetDefault(cfgPrometheusEnabled, false)

View file

@ -9,6 +9,9 @@ S3_LIFECYCLER_WALLET_PASSPHRASE=pwd
# Logger
S3_LIFECYCLER_LOGGER_LEVEL=debug
S3_LIFECYCLER_LOGGER_DESTINATION=stdout
S3_LIFECYCLER_LOGGER_SAMPLING_ENABLED=false
S3_LIFECYCLER_LOGGER_SAMPLING_INITIAL=100
S3_LIFECYCLER_LOGGER_SAMPLING_THEREAFTER=100
# Metrics
S3_LIFECYCLER_PPROF_ENABLED=false

View file

@ -7,6 +7,10 @@ wallet:
logger:
level: info # Log level.
destination: stdout # Logging destination.
sampling:
enabled: false
initial: 100
thereafter: 100
pprof:
enabled: false

View file

@ -47,14 +47,21 @@ wallet:
```yaml
logger:
level: debug
level: info
destination: stdout
sampling:
enabled: false
initial: 100
thereafter: 100
```
| Parameter | Type | SIGHUP reload | Default value | Description |
|---------------|----------|---------------|---------------|--------------------------------------------------------------------------------------|
| `level` | `string` | yes | `info` | Logging level. Possible values: `debug`, `info`, `warn`, `dpanic`, `panic`, `fatal`. |
| `destination` | `string` | no | `stdout` | Destination for logger: `stdout` or `journald` |
| Parameter | Type | SIGHUP reload | Default value | Description |
|-----------------------|----------|---------------|---------------|--------------------------------------------------------------------------------------------------|
| `level` | `string` | yes | `info` | Logging level. Possible values: `debug`, `info`, `warn`, `dpanic`, `panic`, `fatal`. |
| `destination` | `string` | no | `stdout` | Destination for logger: `stdout` or `journald` |
| `sampling.enabled` | `bool` | no | `false` | Enable sampling. |
| `sampling.initial` | `int` | no | `100` | Logs firth N of the same (level and message) log entries each second. |
| `sampling.thereafter` | `int` | no | `100` | Logs every Mth of the same (level and message) log entries after first N entries in that second. |
# `pprof` section