Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improvement: Check log level enabled before evaluating parameters #157

Merged
merged 11 commits into from
Sep 16, 2021
7 changes: 7 additions & 0 deletions changelog/@unreleased/pr-157.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type: improvement
improvement:
description: >
Update all leveled logger implementations to track level atomically and, when a logger implements wlog.LevelChecker,
quickly skip disabled levels before parameter evaluation.
links:
- https://github.com/palantir/witchcraft-go-logging/pull/157
32 changes: 19 additions & 13 deletions wlog-glog/internal/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,36 @@ import (
"github.com/palantir/witchcraft-go-logging/wlog"
)

type gLogger struct{}
type gLogger struct {
wlog.AtomicLogLevel
}

func (*gLogger) Log(params ...wlog.Param) {
glog.Info(createGLogMsg("", params))
}

func (*gLogger) Debug(msg string, params ...wlog.Param) {
glog.Info(createGLogMsg(msg, params))
}

func (*gLogger) Info(msg string, params ...wlog.Param) {
glog.Info(createGLogMsg(msg, params))
func (l *gLogger) Debug(msg string, params ...wlog.Param) {
if l.Enabled(wlog.DebugLevel) {
glog.Info(createGLogMsg(msg, params))
}
}

func (*gLogger) Warn(msg string, params ...wlog.Param) {
glog.Warning(createGLogMsg(msg, params))
func (l *gLogger) Info(msg string, params ...wlog.Param) {
if l.Enabled(wlog.InfoLevel) {
glog.Info(createGLogMsg(msg, params))
}
}

func (*gLogger) Error(msg string, params ...wlog.Param) {
glog.Error(createGLogMsg(msg, params))
func (l *gLogger) Warn(msg string, params ...wlog.Param) {
if l.Enabled(wlog.WarnLevel) {
glog.Warning(createGLogMsg(msg, params))
}
}

func (*gLogger) SetLevel(level wlog.LogLevel) {
// intentionally not implemented as glog uses the globally defined level
func (l *gLogger) Error(msg string, params ...wlog.Param) {
if l.Enabled(wlog.ErrorLevel) {
glog.Error(createGLogMsg(msg, params))
}
}

func createGLogMsg(msg string, params []wlog.Param) string {
Expand Down
4 changes: 2 additions & 2 deletions wlog-glog/internal/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ func LoggerProvider() wlog.LoggerProvider {
type loggerProvider struct{}

func (lp *loggerProvider) NewLogger(w io.Writer) wlog.Logger {
return &gLogger{}
return &gLogger{AtomicLogLevel: wlog.NewAtomicLogLevel(wlog.InfoLevel)}
}

func (lp *loggerProvider) NewLeveledLogger(w io.Writer, level wlog.LogLevel) wlog.LeveledLogger {
return &gLogger{}
return &gLogger{AtomicLogLevel: wlog.NewAtomicLogLevel(level)}
}
22 changes: 7 additions & 15 deletions wlog-tmpl/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import (
)

type tmplLogger struct {
w io.Writer
level wlog.LogLevel
cfg *Config
w io.Writer
cfg *Config
wlog.AtomicLogLevel

delegate wlog.LoggerCreator
bufferPool bytesbuffers.Pool
Expand All @@ -38,37 +38,29 @@ func (l *tmplLogger) Log(params ...wlog.Param) {
}

func (l *tmplLogger) Debug(msg string, params ...wlog.Param) {
switch l.level {
case wlog.DebugLevel:
if l.Enabled(wlog.DebugLevel) {
l.logOutput(append(params, wlog.StringParam("message", msg), wlog.StringParam("level", "DEBUG")))
}
}

func (l *tmplLogger) Info(msg string, params ...wlog.Param) {
switch l.level {
case wlog.DebugLevel, wlog.InfoLevel:
if l.Enabled(wlog.InfoLevel) {
l.logOutput(append(params, wlog.StringParam("message", msg), wlog.StringParam("level", "INFO")))
}
}

func (l *tmplLogger) Warn(msg string, params ...wlog.Param) {
switch l.level {
case wlog.DebugLevel, wlog.InfoLevel, wlog.WarnLevel:
if l.Enabled(wlog.WarnLevel) {
l.logOutput(append(params, wlog.StringParam("message", msg), wlog.StringParam("level", "WARN")))
}
}

func (l *tmplLogger) Error(msg string, params ...wlog.Param) {
switch l.level {
case wlog.DebugLevel, wlog.InfoLevel, wlog.WarnLevel, wlog.ErrorLevel:
if l.Enabled(wlog.ErrorLevel) {
l.logOutput(append(params, wlog.StringParam("message", msg), wlog.StringParam("level", "ERROR")))
}
}

func (l *tmplLogger) SetLevel(level wlog.LogLevel) {
l.level = level
}

func (l *tmplLogger) logOutput(params []wlog.Param) {
_, _ = fmt.Fprintln(l.w, l.formatOutput(params))
}
Expand Down
10 changes: 5 additions & 5 deletions wlog-tmpl/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ func (p *tmplLoggerProvider) NewLogger(w io.Writer) wlog.Logger {

func (p *tmplLoggerProvider) NewLeveledLogger(w io.Writer, level wlog.LogLevel) wlog.LeveledLogger {
return &tmplLogger{
w: w,
level: level,
cfg: p.cfg,
delegate: p.cfg.DelegateLogger.NewLogger,
bufferPool: bytesbuffers.NewSyncPool(128),
w: w,
cfg: p.cfg,
AtomicLogLevel: wlog.NewAtomicLogLevel(level),
delegate: p.cfg.DelegateLogger.NewLogger,
bufferPool: bytesbuffers.NewSyncPool(128),
}
}
22 changes: 13 additions & 9 deletions wlog-zap/internal/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,31 +113,35 @@ func (e *zapLogEntry) Fields() []zapcore.Field {

type zapLogger struct {
logger *zap.Logger
level *zap.AtomicLevel
wlog.AtomicLogLevel
}

func (l *zapLogger) Log(params ...wlog.Param) {
logOutput(l.logger.Info, "", params)
}

func (l *zapLogger) Debug(msg string, params ...wlog.Param) {
logOutput(l.logger.Debug, msg, params)
if l.Enabled(wlog.DebugLevel) {
logOutput(l.logger.Debug, msg, params)
}
}

func (l *zapLogger) Info(msg string, params ...wlog.Param) {
logOutput(l.logger.Info, msg, params)
if l.Enabled(wlog.InfoLevel) {
logOutput(l.logger.Info, msg, params)
}
}

func (l *zapLogger) Warn(msg string, params ...wlog.Param) {
logOutput(l.logger.Warn, msg, params)
if l.Enabled(wlog.WarnLevel) {
logOutput(l.logger.Warn, msg, params)
}
}

func (l *zapLogger) Error(msg string, params ...wlog.Param) {
logOutput(l.logger.Error, msg, params)
}

func (l *zapLogger) SetLevel(level wlog.LogLevel) {
l.level.SetLevel(toZapLevel(level))
if l.Enabled(wlog.ErrorLevel) {
logOutput(l.logger.Error, msg, params)
}
}

func logOutput(logFn func(string, ...zap.Field), msg string, params []wlog.Param) {
Expand Down
49 changes: 14 additions & 35 deletions wlog-zap/internal/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package zapimpl

import (
"fmt"
"io"
"time"

Expand All @@ -31,52 +30,32 @@ func LoggerProvider() wlog.LoggerProvider {
type loggerProvider struct{}

func (lp *loggerProvider) NewLogger(w io.Writer) wlog.Logger {
logger, atomicLevel := newZapLogger(w, wlog.InfoLevel, zapcore.EncoderConfig{
EncodeTime: rfc3339NanoTimeEncoder,
EncodeDuration: zapcore.NanosDurationEncoder,
})
return &zapLogger{
logger: logger,
level: atomicLevel,
logger: newZapLogger(w, zapcore.EncoderConfig{
EncodeTime: rfc3339NanoTimeEncoder,
EncodeDuration: zapcore.NanosDurationEncoder,
}),
}
}

func (lp *loggerProvider) NewLeveledLogger(w io.Writer, level wlog.LogLevel) wlog.LeveledLogger {
logger, atomicLevel := newZapLogger(w, level, zapcore.EncoderConfig{
EncodeTime: rfc3339NanoTimeEncoder,
EncodeDuration: zapcore.NanosDurationEncoder,
EncodeLevel: zapcore.CapitalLevelEncoder,
})
return &zapLogger{
logger: logger,
level: atomicLevel,
logger: newZapLogger(w, zapcore.EncoderConfig{
EncodeTime: rfc3339NanoTimeEncoder,
EncodeDuration: zapcore.NanosDurationEncoder,
EncodeLevel: zapcore.CapitalLevelEncoder,
}),
AtomicLogLevel: wlog.NewAtomicLogLevel(level),
}
}

func rfc3339NanoTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.In(time.UTC).Format(time.RFC3339Nano))
}

func newZapLogger(w io.Writer, logLevel wlog.LogLevel, encoderConfig zapcore.EncoderConfig) (*zap.Logger, *zap.AtomicLevel) {
level := zap.NewAtomicLevel()
level.SetLevel(toZapLevel(logLevel))
enc := zapcore.NewJSONEncoder(encoderConfig)
return zap.New(zapcore.NewCore(enc, zapcore.AddSync(w), level)), &level
}
func newZapLogger(w io.Writer, encoderConfig zapcore.EncoderConfig) *zap.Logger {
// We do our own enforcement in the level-specific methods; no need for zap to check again.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: for consistency, please avoid "I/we" in comments -- update to something like "wlog performs its own enforcement of leveled logging in level-specific methods..."

level := zap.LevelEnablerFunc(func(zapcore.Level) bool { return true })

func toZapLevel(lvl wlog.LogLevel) zapcore.Level {
switch lvl {
case wlog.DebugLevel:
return zapcore.DebugLevel
case wlog.LogLevel(""), wlog.InfoLevel:
return zapcore.InfoLevel
case wlog.WarnLevel:
return zapcore.WarnLevel
case wlog.ErrorLevel:
return zapcore.ErrorLevel
case wlog.FatalLevel:
return zapcore.FatalLevel
default:
panic(fmt.Errorf("Invalid log level %q", lvl))
}
return zap.New(zapcore.NewCore(zapcore.NewJSONEncoder(encoderConfig), zapcore.AddSync(w), level))
}
37 changes: 9 additions & 28 deletions wlog-zerolog/internal/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,54 +158,35 @@ func (e *zeroLogEntry) Evt() *zerolog.Event {

type zeroLogger struct {
logger zerolog.Logger
level zerolog.Level
}

func (l *zeroLogger) should(level zerolog.Level) bool {
if level < l.level {
return false
}
return true
wlog.AtomicLogLevel
}

func (l *zeroLogger) Log(params ...wlog.Param) {
if !l.should(zerolog.NoLevel) {
return
}
logOutput(l.logger.Log, "", params)
}

func (l *zeroLogger) Debug(msg string, params ...wlog.Param) {
if !l.should(zerolog.DebugLevel) {
return
if l.Enabled(wlog.DebugLevel) {
logOutput(l.logger.Log, msg, params)
}
logOutput(l.logger.Log, msg, params)
}

func (l *zeroLogger) Info(msg string, params ...wlog.Param) {
if !l.should(zerolog.InfoLevel) {
return
if l.Enabled(wlog.InfoLevel) {
logOutput(l.logger.Log, msg, params)
}
logOutput(l.logger.Log, msg, params)
}

func (l *zeroLogger) Warn(msg string, params ...wlog.Param) {
if !l.should(zerolog.WarnLevel) {
return
if l.Enabled(wlog.WarnLevel) {
logOutput(l.logger.Log, msg, params)
}
logOutput(l.logger.Log, msg, params)
}

func (l *zeroLogger) Error(msg string, params ...wlog.Param) {
if !l.should(zerolog.ErrorLevel) {
return
if l.Enabled(wlog.ErrorLevel) {
logOutput(l.logger.Log, msg, params)
}
logOutput(l.logger.Log, msg, params)
}

func (l *zeroLogger) SetLevel(level wlog.LogLevel) {
nmiyake marked this conversation as resolved.
Show resolved Hide resolved
l.level = toZeroLevel(level)
l.logger = l.logger.Level(toZeroLevel(level))
}

func reverseParams(params []wlog.Param) {
Expand Down
28 changes: 3 additions & 25 deletions wlog-zerolog/internal/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package zeroimpl

import (
"fmt"
"io"

"github.com/palantir/witchcraft-go-logging/wlog"
Expand All @@ -30,34 +29,13 @@ type loggerProvider struct{}

func (lp *loggerProvider) NewLogger(w io.Writer) wlog.Logger {
return &zeroLogger{
logger: newZeroLogger(w, wlog.InfoLevel),
logger: zerolog.New(w),
}
}

func (lp *loggerProvider) NewLeveledLogger(w io.Writer, level wlog.LogLevel) wlog.LeveledLogger {
return &zeroLogger{
logger: newZeroLogger(w, level),
level: toZeroLevel(level),
}
}

func newZeroLogger(w io.Writer, level wlog.LogLevel) zerolog.Logger {
return zerolog.New(w).Level(toZeroLevel(level))
}

func toZeroLevel(lvl wlog.LogLevel) zerolog.Level {
switch lvl {
case wlog.DebugLevel:
return zerolog.DebugLevel
case wlog.LogLevel(""), wlog.InfoLevel:
return zerolog.InfoLevel
case wlog.WarnLevel:
return zerolog.WarnLevel
case wlog.ErrorLevel:
return zerolog.ErrorLevel
case wlog.FatalLevel:
return zerolog.FatalLevel
default:
panic(fmt.Errorf("Invalid log level %q", lvl))
logger: zerolog.New(w),
AtomicLogLevel: wlog.NewAtomicLogLevel(level),
}
}
Loading