diff --git a/.gitignore b/.gitignore index 0a141d2..771e94f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ __debug* .idea/ build +*.out +coraza-caddy.test diff --git a/logger.go b/logger.go index 2f1b3dd..5ab589a 100644 --- a/logger.go +++ b/logger.go @@ -26,7 +26,24 @@ func newLogger(l *zap.Logger) debuglog.Logger { } } +func isZapNop(l *zap.Logger) bool { + // As per zap documentation when a logger is created with NewNop() it will have + // an invalid level + return l.Level() == zapcore.InvalidLevel +} + func (l *logger) WithOutput(w io.Writer) debuglog.Logger { + if w == io.Discard { + return &logger{ + Logger: zap.NewNop(), + level: l.level, + } + } + + if isZapNop(l.Logger) { + return l + } + return &logger{ Logger: l.Logger.WithOptions( zap.WrapCore(func(c zapcore.Core) zapcore.Core { @@ -42,11 +59,17 @@ func (l *logger) WithOutput(w io.Writer) debuglog.Logger { } func (l *logger) WithLevel(level debuglog.Level) debuglog.Logger { + if level == debuglog.LevelNoLog { + return &logger{ + Logger: zap.NewNop(), + level: level, + } + } return &logger{l.Logger, level} } func (l *logger) With(fields ...debuglog.ContextField) debuglog.Logger { - if len(fields) == 0 { + if len(fields) == 0 || isZapNop(l.Logger) { return l } diff --git a/logger_test.go b/logger_test.go new file mode 100644 index 0000000..65db1ef --- /dev/null +++ b/logger_test.go @@ -0,0 +1,41 @@ +// Copyright 2024 The OWASP Coraza contributors +// SPDX-License-Identifier: Apache-2.0 + +package coraza + +import ( + "os" + "testing" + + "github.com/corazawaf/coraza/v3/debuglog" + "github.com/stretchr/testify/require" + "go.uber.org/zap" +) + +func BenchmarkLogger(b *testing.B) { + f, err := os.CreateTemp(b.TempDir(), "test.log") + require.NoError(b, err) + + cfg := zap.NewProductionConfig() + cfg.OutputPaths = []string{f.Name()} + + l, err := cfg.Build() + require.NoError(b, err) + + var ( + l1, l2, l3 debuglog.Logger + debugLogger = newLogger(l) + ) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + l1 = debugLogger.With(debuglog.Str("key1", "value1")) + l1.Info().Msg("message1") + + l2 = debugLogger.With(debuglog.Str("key2", "value2"), debuglog.Str("key3", "value3")) + l2.Info().Msg("message2&3") + + l3 = debugLogger.With(debuglog.Str("key4", "value4")) + l3.Info().Msg("message4") + } +}