From b3994bbb45c57d75daef27cba441a170b8558bc9 Mon Sep 17 00:00:00 2001 From: Yauheni Kaliuta Date: Mon, 7 Oct 2024 21:35:46 +0300 Subject: [PATCH] logger: add zap command line switches Allow to tune preconfigured by --log-mode zap backend with standard zap command line switches from controller-runtime (zap-devel, zap-encoder, zap-log-level, zap-stacktrace-level, zap-time-encoding)[1]. This brings flexibility in logger setup for development environments first of all. The patch does not change default logger setup and does not change DSCI override functionality. [1] https://sdk.operatorframework.io/docs/building-operators/golang/references/logging Signed-off-by: Yauheni Kaliuta --- main.go | 6 ++++- pkg/logger/logger.go | 52 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/main.go b/main.go index 62c31edec0b..7d33d59a997 100644 --- a/main.go +++ b/main.go @@ -51,6 +51,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/config" "sigs.k8s.io/controller-runtime/pkg/healthz" logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/manager" ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics/server" ctrlwebhook "sigs.k8s.io/controller-runtime/pkg/webhook" @@ -140,9 +141,12 @@ func main() { //nolint:funlen,maintidx flag.StringVar(&operatorName, "operator-name", "opendatahub", "The name of the operator") flag.StringVar(&logmode, "log-mode", "", "Log mode ('', prod, devel), default to ''") + opts := zap.Options{} + opts.BindFlags(flag.CommandLine) + flag.Parse() - ctrl.SetLogger(logger.NewLogger(logmode)) + ctrl.SetLogger(logger.NewLoggerWithOptions(logmode, &opts)) // root context ctx := ctrl.SetupSignalHandler() diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 149ed5f1dac..04ea52224a0 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -1,6 +1,7 @@ package logger import ( + "flag" "os" "strings" @@ -35,26 +36,40 @@ func LogWithLevel(logger logr.Logger, level string) logr.Logger { return logger.V(verbosityLevel) } +func NewLoggerWithOptions(mode string, override *zap.Options) logr.Logger { + opts := newOptions(mode) + overrideOptions(opts, override) + return newLogger(opts) +} + // in DSC component, to use different mode for logging, e.g. development, production // when not set mode it falls to "default" which is used by startup main.go. func NewLogger(mode string) logr.Logger { + return newLogger(newOptions(mode)) +} + +func newLogger(opts *zap.Options) logr.Logger { + return zap.New(zap.UseFlagOptions(opts)) +} + +func newOptions(mode string) *zap.Options { var opts zap.Options switch mode { - case "devel", "development": // the most logging verbosity + case "devel", "development": opts = zap.Options{ Development: true, StacktraceLevel: zapcore.WarnLevel, Level: zapcore.InfoLevel, DestWriter: os.Stdout, } - case "prod", "production": // the least logging verbosity + case "prod", "production": opts = zap.Options{ Development: false, StacktraceLevel: zapcore.ErrorLevel, Level: zapcore.InfoLevel, DestWriter: os.Stdout, EncoderConfigOptions: []zap.EncoderConfigOption{func(config *zapcore.EncoderConfig) { - config.EncodeTime = zapcore.ISO8601TimeEncoder // human readable not epoch + config.EncodeTime = zapcore.ISO8601TimeEncoder config.EncodeDuration = zapcore.SecondsDurationEncoder config.LevelKey = "LogLevel" config.NameKey = "Log" @@ -72,5 +87,34 @@ func NewLogger(mode string) logr.Logger { DestWriter: os.Stdout, } } - return zap.New(zap.UseFlagOptions(&opts)) + return &opts +} + +func overrideOptions(orig, override *zap.Options) { + // Development is boolean, cannot check for nil, so check if it was set + isDevelopmentSet := false + flag.Visit(func(f *flag.Flag) { + if f.Name == "zap-devel" { + isDevelopmentSet = true + } + }) + if isDevelopmentSet { + orig.Development = override.Development + } + + if override.StacktraceLevel != nil { + orig.StacktraceLevel = override.StacktraceLevel + } + + if override.Level != nil { + orig.Level = override.Level + } + + if override.DestWriter != nil { + orig.DestWriter = override.DestWriter + } + + if override.EncoderConfigOptions != nil { + orig.EncoderConfigOptions = append(orig.EncoderConfigOptions, override.EncoderConfigOptions...) + } }