From d5ac690634bcb335fdb8e5fcfb654dcfff0f497d Mon Sep 17 00:00:00 2001 From: kvii <13721952202@163.com> Date: Thu, 12 Sep 2024 23:23:46 +0800 Subject: [PATCH 1/2] fix(log): GetLogger doesn't returns the same logger that was set before. --- log/global.go | 64 ++++++++++++++++++++-------------------------- log/global_test.go | 54 ++++++++++++++++++++++++-------------- 2 files changed, 63 insertions(+), 55 deletions(-) diff --git a/log/global.go b/log/global.go index f1984fc3f9b..b254b8e094b 100644 --- a/log/global.go +++ b/log/global.go @@ -4,124 +4,116 @@ import ( "context" "fmt" "os" - "sync" + "sync/atomic" ) -// globalLogger is designed as a global logger in current process. -var global = &loggerAppliance{} +// global is a place to store global logger. +var global atomic.Value -// loggerAppliance is the proxy of `Logger` to -// make logger change will affect all sub-logger. +// loggerAppliance is a wrapper to make sure logger can be stored. type loggerAppliance struct { - lock sync.Mutex - Logger + logger Logger } func init() { - global.SetLogger(DefaultLogger) + SetLogger(DefaultLogger) } -func (a *loggerAppliance) SetLogger(in Logger) { - a.lock.Lock() - defer a.lock.Unlock() - a.Logger = in -} - -// SetLogger should be called before any other log call. -// And it is NOT THREAD SAFE. +// SetLogger sets the global logger. This function should be called +// before any other log call. func SetLogger(logger Logger) { - global.SetLogger(logger) + global.Store(loggerAppliance{logger: logger}) } -// GetLogger returns global logger appliance as logger in current process. +// GetLogger returns global logger. func GetLogger() Logger { - return global + return global.Load().(loggerAppliance).logger } // Log Print log by level and keyvals. func Log(level Level, keyvals ...interface{}) { - _ = global.Log(level, keyvals...) + _ = GetLogger().Log(level, keyvals...) } // Context with context logger. func Context(ctx context.Context) *Helper { - return NewHelper(WithContext(ctx, global.Logger)) + return NewHelper(WithContext(ctx, GetLogger())) } // Debug logs a message at debug level. func Debug(a ...interface{}) { - _ = global.Log(LevelDebug, DefaultMessageKey, fmt.Sprint(a...)) + _ = GetLogger().Log(LevelDebug, DefaultMessageKey, fmt.Sprint(a...)) } // Debugf logs a message at debug level. func Debugf(format string, a ...interface{}) { - _ = global.Log(LevelDebug, DefaultMessageKey, fmt.Sprintf(format, a...)) + _ = GetLogger().Log(LevelDebug, DefaultMessageKey, fmt.Sprintf(format, a...)) } // Debugw logs a message at debug level. func Debugw(keyvals ...interface{}) { - _ = global.Log(LevelDebug, keyvals...) + _ = GetLogger().Log(LevelDebug, keyvals...) } // Info logs a message at info level. func Info(a ...interface{}) { - _ = global.Log(LevelInfo, DefaultMessageKey, fmt.Sprint(a...)) + _ = GetLogger().Log(LevelInfo, DefaultMessageKey, fmt.Sprint(a...)) } // Infof logs a message at info level. func Infof(format string, a ...interface{}) { - _ = global.Log(LevelInfo, DefaultMessageKey, fmt.Sprintf(format, a...)) + _ = GetLogger().Log(LevelInfo, DefaultMessageKey, fmt.Sprintf(format, a...)) } // Infow logs a message at info level. func Infow(keyvals ...interface{}) { - _ = global.Log(LevelInfo, keyvals...) + _ = GetLogger().Log(LevelInfo, keyvals...) } // Warn logs a message at warn level. func Warn(a ...interface{}) { - _ = global.Log(LevelWarn, DefaultMessageKey, fmt.Sprint(a...)) + _ = GetLogger().Log(LevelWarn, DefaultMessageKey, fmt.Sprint(a...)) } // Warnf logs a message at warnf level. func Warnf(format string, a ...interface{}) { - _ = global.Log(LevelWarn, DefaultMessageKey, fmt.Sprintf(format, a...)) + _ = GetLogger().Log(LevelWarn, DefaultMessageKey, fmt.Sprintf(format, a...)) } // Warnw logs a message at warnf level. func Warnw(keyvals ...interface{}) { - _ = global.Log(LevelWarn, keyvals...) + _ = GetLogger().Log(LevelWarn, keyvals...) } // Error logs a message at error level. func Error(a ...interface{}) { - _ = global.Log(LevelError, DefaultMessageKey, fmt.Sprint(a...)) + _ = GetLogger().Log(LevelError, DefaultMessageKey, fmt.Sprint(a...)) } // Errorf logs a message at error level. func Errorf(format string, a ...interface{}) { - _ = global.Log(LevelError, DefaultMessageKey, fmt.Sprintf(format, a...)) + _ = GetLogger().Log(LevelError, DefaultMessageKey, fmt.Sprintf(format, a...)) } // Errorw logs a message at error level. func Errorw(keyvals ...interface{}) { - _ = global.Log(LevelError, keyvals...) + _ = GetLogger().Log(LevelError, keyvals...) } // Fatal logs a message at fatal level. func Fatal(a ...interface{}) { - _ = global.Log(LevelFatal, DefaultMessageKey, fmt.Sprint(a...)) + _ = GetLogger().Log(LevelFatal, DefaultMessageKey, fmt.Sprint(a...)) os.Exit(1) } // Fatalf logs a message at fatal level. func Fatalf(format string, a ...interface{}) { - _ = global.Log(LevelFatal, DefaultMessageKey, fmt.Sprintf(format, a...)) + _ = GetLogger().Log(LevelFatal, DefaultMessageKey, fmt.Sprintf(format, a...)) os.Exit(1) } // Fatalw logs a message at fatal level. func Fatalw(keyvals ...interface{}) { - _ = global.Log(LevelFatal, keyvals...) + _ = GetLogger().Log(LevelFatal, keyvals...) os.Exit(1) } diff --git a/log/global_test.go b/log/global_test.go index 8ee157052d7..d03dd73d3be 100644 --- a/log/global_test.go +++ b/log/global_test.go @@ -4,17 +4,19 @@ import ( "bytes" "context" "fmt" - "os" "strings" "testing" ) func TestGlobalLog(t *testing.T) { + defaultLogger := GetLogger() + t.Cleanup(func() { SetLogger(defaultLogger) }) + buffer := &bytes.Buffer{} logger := NewStdLogger(buffer) SetLogger(logger) - if global.Logger != logger { + if GetLogger() != logger { t.Error("GetLogger() is not equal to logger") } @@ -93,27 +95,41 @@ func TestGlobalLog(t *testing.T) { } } -func TestGlobalLogUpdate(t *testing.T) { - l := &loggerAppliance{} - l.SetLogger(NewStdLogger(os.Stdout)) - LOG := NewHelper(l) - LOG.Info("Log to stdout") - - buffer := &bytes.Buffer{} - l.SetLogger(NewStdLogger(buffer)) - LOG.Info("Log to buffer") - - expected := "INFO msg=Log to buffer\n" - if buffer.String() != expected { - t.Errorf("Expected: %s, got: %s", expected, buffer.String()) - } -} - func TestGlobalContext(t *testing.T) { + defaultLogger := GetLogger() + t.Cleanup(func() { SetLogger(defaultLogger) }) + buffer := &bytes.Buffer{} SetLogger(NewStdLogger(buffer)) - Context(context.Background()).Infof("111") + Context(context.Background()).Info("111") if buffer.String() != "INFO msg=111\n" { t.Errorf("Expected:%s, got:%s", "INFO msg=111", buffer.String()) } } + +type traceIdKey struct{} + +func TestValuerUnderGlobalValue(t *testing.T) { + defaultLogger := GetLogger() + t.Cleanup(func() { SetLogger(defaultLogger) }) + + var traceIdValuer Valuer = func(ctx context.Context) any { + return ctx.Value(traceIdKey{}) + } + + var buf bytes.Buffer + l1 := NewStdLogger(&buf) + l2 := With(l1, "traceId", traceIdValuer) + + SetLogger(l2) + l3 := GetLogger() + + ctx := context.WithValue(context.Background(), traceIdKey{}, "123") + l4 := WithContext(ctx, l3) + l4.Log(LevelInfo, "msg", "m") + + want := "INFO traceId=123 msg=m\n" + if got := buf.String(); got != want { + t.Errorf("Expected:%q, got:%q", want, got) + } +} From 7e54d3e02ab76b80072e1c9f6cba724ef4cdbb53 Mon Sep 17 00:00:00 2001 From: kvii <13721952202@163.com> Date: Fri, 13 Sep 2024 10:28:47 +0800 Subject: [PATCH 2/2] lint: fix lint issue --- log/global_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/log/global_test.go b/log/global_test.go index d03dd73d3be..445ab9c344a 100644 --- a/log/global_test.go +++ b/log/global_test.go @@ -107,26 +107,26 @@ func TestGlobalContext(t *testing.T) { } } -type traceIdKey struct{} +type tidKey struct{} func TestValuerUnderGlobalValue(t *testing.T) { defaultLogger := GetLogger() t.Cleanup(func() { SetLogger(defaultLogger) }) - var traceIdValuer Valuer = func(ctx context.Context) any { - return ctx.Value(traceIdKey{}) + var tidValuer Valuer = func(ctx context.Context) any { + return ctx.Value(tidKey{}) } var buf bytes.Buffer l1 := NewStdLogger(&buf) - l2 := With(l1, "traceId", traceIdValuer) + l2 := With(l1, "traceId", tidValuer) SetLogger(l2) l3 := GetLogger() - ctx := context.WithValue(context.Background(), traceIdKey{}, "123") + ctx := context.WithValue(context.Background(), tidKey{}, "123") l4 := WithContext(ctx, l3) - l4.Log(LevelInfo, "msg", "m") + _ = l4.Log(LevelInfo, "msg", "m") want := "INFO traceId=123 msg=m\n" if got := buf.String(); got != want {