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

fix the logger data race #170

Merged
merged 1 commit into from
Jan 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions common/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"io"
"os"
"path/filepath"
"sync"
"time"

rotatelogs "github.com/lestrrat/go-file-rotatelogs"
Expand All @@ -29,7 +30,8 @@ import (
)

var (
logger Logger
logger Logger
logLock sync.RWMutex
)

var levelMap = map[string]zapcore.Level{
Expand Down Expand Up @@ -79,20 +81,28 @@ func init() {
}
zapLoggerConfig.EncoderConfig = zapLoggerEncoderConfig
zapLogger, _ := zapLoggerConfig.Build(zap.AddCallerSkip(1))
logger = &NacosLogger{zapLogger.Sugar()}
SetLogger(&NacosLogger{zapLogger.Sugar()})
}

// InitLogger is init global logger for nacos
func InitLogger(config Config) (err error) {
logLock.Lock()
defer logLock.Unlock()
logger, err = InitNacosLogger(config)
return
}

// InitNacosLogger is init nacos default logger
func InitNacosLogger(config Config) (Logger, error) {
logLevel := getLogLevel(config.Level)
encoder := getEncoder()
writer, err := getWriter(config.OutputPath, config.RotationTime, config.MaxAge)
if err != nil {
return
return nil, err
}
core := zapcore.NewCore(zapcore.NewConsoleEncoder(encoder), zapcore.AddSync(writer), logLevel)
zaplogger := zap.New(core, zap.AddCallerSkip(1))
logger = &NacosLogger{zaplogger.Sugar()}
return
return &NacosLogger{zaplogger.Sugar()}, nil
}

func getLogLevel(level string) zapcore.Level {
Expand Down Expand Up @@ -132,9 +142,13 @@ func getWriter(outputPath string, rotateTime string, maxAge int64) (writer io.Wr

//SetLogger sets logger for sdk
func SetLogger(log Logger) {
binbin0325 marked this conversation as resolved.
Show resolved Hide resolved
logLock.Lock()
defer logLock.Unlock()
logger = log
}

func GetLogger() Logger {
logLock.RLock()
defer logLock.RUnlock()
return logger
}
114 changes: 114 additions & 0 deletions common/logger/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,16 @@
package logger

import (
"sync"
"testing"

"github.com/stretchr/testify/assert"
)

func reset() {
SetLogger(nil)
}

func TestInitLogger(t *testing.T) {
config := Config{
Level: "degug",
Expand All @@ -31,4 +36,113 @@ func TestInitLogger(t *testing.T) {
}
err := InitLogger(config)
assert.NoError(t, err)
reset()
}

func TestGetLogger(t *testing.T) {
// not yet init get default log
log := GetLogger()
config := Config{
Level: "degug",
OutputPath: "/tmp/nacos",
RotationTime: "1h",
MaxAge: 2,
}
_ = InitLogger(config)
// after init logger
log2 := GetLogger()
assert.NotEqual(t, log, log2)

// the secend init logger
config.Level = "info"
_ = InitLogger(config)
log3 := GetLogger()
assert.NotEqual(t, log2, log3)
reset()
}

func TestSetLogger(t *testing.T) {
// not yet init get default log
log := GetLogger()
log1 := &mockLogger{}
SetLogger(log1)

// after set logger
log2 := GetLogger()
assert.NotEqual(t, log, log2)
assert.Equal(t, log1, log2)

config := Config{
Level: "degug",
OutputPath: "/tmp/nacos",
RotationTime: "1h",
MaxAge: 2,
}
_ = InitLogger(config)
// after init logger
log3 := GetLogger()
assert.NotEqual(t, log2, log3)
reset()
}

func TestRaceLogger(t *testing.T) {
wg := sync.WaitGroup{}
for i := 0; i < 100; i++ {
wg.Add(3)
go func() {
defer wg.Done()
SetLogger(&mockLogger{})
}()
go func() {
defer wg.Done()
_ = GetLogger()
}()
go func() {
defer wg.Done()
config := Config{
Level: "degug",
OutputPath: "/tmp/nacos",
RotationTime: "1h",
MaxAge: 2,
}
_ = InitLogger(config)
}()
}
wg.Wait()
reset()
}

type mockLogger struct {
}

func (m mockLogger) Info(args ...interface{}) {
panic("implement me")
}

func (m mockLogger) Warn(args ...interface{}) {
panic("implement me")
}

func (m mockLogger) Error(args ...interface{}) {
panic("implement me")
}

func (m mockLogger) Debug(args ...interface{}) {
panic("implement me")
}

func (m mockLogger) Infof(fmt string, args ...interface{}) {
panic("implement me")
}

func (m mockLogger) Warnf(fmt string, args ...interface{}) {
panic("implement me")
}

func (m mockLogger) Errorf(fmt string, args ...interface{}) {
panic("implement me")
}

func (m mockLogger) Debugf(fmt string, args ...interface{}) {
panic("implement me")
}
16 changes: 8 additions & 8 deletions common/logger/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,40 @@ package logger

// Info is info level
func Info(args ...interface{}) {
logger.Info(args...)
GetLogger().Info(args...)
}

// Warn is warning level
func Warn(args ...interface{}) {
logger.Warn(args...)
GetLogger().Warn(args...)
}

// Error is error level
func Error(args ...interface{}) {
logger.Error(args...)
GetLogger().Error(args...)
}

// Debug is debug level
func Debug(args ...interface{}) {
logger.Debug(args...)
GetLogger().Debug(args...)
}

// Infof is format info level
func Infof(fmt string, args ...interface{}) {
logger.Infof(fmt, args...)
GetLogger().Infof(fmt, args...)
}

// Warnf is format warning level
func Warnf(fmt string, args ...interface{}) {
logger.Warnf(fmt, args...)
GetLogger().Warnf(fmt, args...)
}

// Errorf is format error level
func Errorf(fmt string, args ...interface{}) {
logger.Errorf(fmt, args...)
GetLogger().Errorf(fmt, args...)
}

// Debugf is format debug level
func Debugf(fmt string, args ...interface{}) {
logger.Debugf(fmt, args...)
GetLogger().Debugf(fmt, args...)
}