Skip to content

Commit

Permalink
logger: mitigate slow logger change with zap.AtomicLevel
Browse files Browse the repository at this point in the history
zap provides possibility to change loglevel on the fly[1]. Use it to
change loglevel of existing logger before the new reconfigured is
taken in use.

[1] https://github.com/uber-go/zap/blob/384e78230aefc7e724a1c9f526b9ab529f390983/level.go#L62

Signed-off-by: Yauheni Kaliuta <[email protected]>
  • Loading branch information
ykaliuta committed Oct 4, 2024
1 parent 282e504 commit dd12452
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Re
logmode := instance.Spec.DevFlags.LogMode
if logmode != "" { // allow override with explicit values only
log.V(1).Info("Setting logger mode", "mode", logmode)
logger.SetBaseLogger(logger.NewLogger(logmode))
logger.NewBaseLogger(logmode)
}
}

Expand Down
4 changes: 1 addition & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,7 @@ func main() { //nolint:funlen,maintidx

flag.Parse()

l := logger.NewLogger(logmode)
ctrl.SetLogger(l)
logger.SetBaseLogger(l)
ctrl.SetLogger(logger.NewBaseLogger(logmode))

// root context
ctx := ctrl.SetupSignalHandler()
Expand Down
65 changes: 45 additions & 20 deletions pkg/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ import (
"sync/atomic"

"github.com/go-logr/logr"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
ctrlzap "sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)

var baseLogger atomic.Value
var (
baseLogger atomic.Value
level = zap.NewAtomicLevel()
stackTraceLevel = zap.NewAtomicLevel()
)

func NewLogConstructor(name string) func(req *reconcile.Request) logr.Logger {
return func(req *reconcile.Request) logr.Logger {
Expand All @@ -22,6 +27,13 @@ func NewLogConstructor(name string) func(req *reconcile.Request) logr.Logger {
}
}

func NewBaseLogger(mode string) logr.Logger {
l := NewLogger(mode)
SetLoggerLevel(mode)
SetBaseLogger(l)
return l
}

func SetBaseLogger(log logr.Logger) {
baseLogger.Store(log)
}
Expand All @@ -31,25 +43,36 @@ func GetBaseLogger() logr.Logger {
return l
}

func SetLoggerLevel(mode string) {
switch mode {
case "devel", "development":
level.SetLevel(zapcore.DebugLevel)
stackTraceLevel.SetLevel(zapcore.WarnLevel)
case "prod", "production":
level.SetLevel(zapcore.ErrorLevel)
stackTraceLevel.SetLevel(zapcore.ErrorLevel)
default:
level.SetLevel(zapcore.InfoLevel)
stackTraceLevel.SetLevel(zapcore.ErrorLevel)
}
}

// 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 {
var opts zap.Options
var opts ctrlzap.Options

switch mode {
case "devel", "development": // the most logging verbosity
opts = zap.Options{
Development: true,
StacktraceLevel: zapcore.WarnLevel,
Level: zapcore.DebugLevel,
DestWriter: os.Stdout,
opts = ctrlzap.Options{
Development: true,
DestWriter: os.Stdout,
}
case "prod", "production": // the least logging verbosity
opts = zap.Options{
Development: false,
StacktraceLevel: zapcore.ErrorLevel,
Level: zapcore.ErrorLevel,
DestWriter: os.Stdout,
EncoderConfigOptions: []zap.EncoderConfigOption{func(config *zapcore.EncoderConfig) {
opts = ctrlzap.Options{
Development: false,
DestWriter: os.Stdout,
EncoderConfigOptions: []ctrlzap.EncoderConfigOption{func(config *zapcore.EncoderConfig) {
config.EncodeTime = zapcore.ISO8601TimeEncoder // human readable not epoch
config.EncodeDuration = zapcore.SecondsDurationEncoder
config.LevelKey = "LogLevel"
Expand All @@ -61,12 +84,14 @@ func NewLogger(mode string) logr.Logger {
}},
}
default:
opts = zap.Options{
Development: false,
StacktraceLevel: zapcore.ErrorLevel,
Level: zapcore.InfoLevel,
DestWriter: os.Stdout,
opts = ctrlzap.Options{
Development: false,
DestWriter: os.Stdout,
}
}
return zap.New(zap.UseFlagOptions(&opts))

opts.Level = level
opts.StacktraceLevel = stackTraceLevel

return ctrlzap.New(ctrlzap.UseFlagOptions(&opts))
}

0 comments on commit dd12452

Please sign in to comment.