This commit fixes data race using atomics. We switch type of level from uint8 to uint32 but due memory alignment on most platforms it will not result in any additional memory.

This commit is contained in:
DmitriyMV 2017-03-23 19:13:19 +03:00
parent 10f801ebc3
commit 3bcb09397d
4 changed files with 51 additions and 42 deletions

View File

@ -126,7 +126,7 @@ func (entry Entry) log(level Level, msg string) {
} }
func (entry *Entry) Debug(args ...interface{}) { func (entry *Entry) Debug(args ...interface{}) {
if entry.Logger.Level >= DebugLevel { if entry.Logger.level() >= DebugLevel {
entry.log(DebugLevel, fmt.Sprint(args...)) entry.log(DebugLevel, fmt.Sprint(args...))
} }
} }
@ -136,13 +136,13 @@ func (entry *Entry) Print(args ...interface{}) {
} }
func (entry *Entry) Info(args ...interface{}) { func (entry *Entry) Info(args ...interface{}) {
if entry.Logger.Level >= InfoLevel { if entry.Logger.level() >= InfoLevel {
entry.log(InfoLevel, fmt.Sprint(args...)) entry.log(InfoLevel, fmt.Sprint(args...))
} }
} }
func (entry *Entry) Warn(args ...interface{}) { func (entry *Entry) Warn(args ...interface{}) {
if entry.Logger.Level >= WarnLevel { if entry.Logger.level() >= WarnLevel {
entry.log(WarnLevel, fmt.Sprint(args...)) entry.log(WarnLevel, fmt.Sprint(args...))
} }
} }
@ -152,20 +152,20 @@ func (entry *Entry) Warning(args ...interface{}) {
} }
func (entry *Entry) Error(args ...interface{}) { func (entry *Entry) Error(args ...interface{}) {
if entry.Logger.Level >= ErrorLevel { if entry.Logger.level() >= ErrorLevel {
entry.log(ErrorLevel, fmt.Sprint(args...)) entry.log(ErrorLevel, fmt.Sprint(args...))
} }
} }
func (entry *Entry) Fatal(args ...interface{}) { func (entry *Entry) Fatal(args ...interface{}) {
if entry.Logger.Level >= FatalLevel { if entry.Logger.level() >= FatalLevel {
entry.log(FatalLevel, fmt.Sprint(args...)) entry.log(FatalLevel, fmt.Sprint(args...))
} }
Exit(1) Exit(1)
} }
func (entry *Entry) Panic(args ...interface{}) { func (entry *Entry) Panic(args ...interface{}) {
if entry.Logger.Level >= PanicLevel { if entry.Logger.level() >= PanicLevel {
entry.log(PanicLevel, fmt.Sprint(args...)) entry.log(PanicLevel, fmt.Sprint(args...))
} }
panic(fmt.Sprint(args...)) panic(fmt.Sprint(args...))
@ -174,13 +174,13 @@ func (entry *Entry) Panic(args ...interface{}) {
// Entry Printf family functions // Entry Printf family functions
func (entry *Entry) Debugf(format string, args ...interface{}) { func (entry *Entry) Debugf(format string, args ...interface{}) {
if entry.Logger.Level >= DebugLevel { if entry.Logger.level() >= DebugLevel {
entry.Debug(fmt.Sprintf(format, args...)) entry.Debug(fmt.Sprintf(format, args...))
} }
} }
func (entry *Entry) Infof(format string, args ...interface{}) { func (entry *Entry) Infof(format string, args ...interface{}) {
if entry.Logger.Level >= InfoLevel { if entry.Logger.level() >= InfoLevel {
entry.Info(fmt.Sprintf(format, args...)) entry.Info(fmt.Sprintf(format, args...))
} }
} }
@ -190,7 +190,7 @@ func (entry *Entry) Printf(format string, args ...interface{}) {
} }
func (entry *Entry) Warnf(format string, args ...interface{}) { func (entry *Entry) Warnf(format string, args ...interface{}) {
if entry.Logger.Level >= WarnLevel { if entry.Logger.level() >= WarnLevel {
entry.Warn(fmt.Sprintf(format, args...)) entry.Warn(fmt.Sprintf(format, args...))
} }
} }
@ -200,20 +200,20 @@ func (entry *Entry) Warningf(format string, args ...interface{}) {
} }
func (entry *Entry) Errorf(format string, args ...interface{}) { func (entry *Entry) Errorf(format string, args ...interface{}) {
if entry.Logger.Level >= ErrorLevel { if entry.Logger.level() >= ErrorLevel {
entry.Error(fmt.Sprintf(format, args...)) entry.Error(fmt.Sprintf(format, args...))
} }
} }
func (entry *Entry) Fatalf(format string, args ...interface{}) { func (entry *Entry) Fatalf(format string, args ...interface{}) {
if entry.Logger.Level >= FatalLevel { if entry.Logger.level() >= FatalLevel {
entry.Fatal(fmt.Sprintf(format, args...)) entry.Fatal(fmt.Sprintf(format, args...))
} }
Exit(1) Exit(1)
} }
func (entry *Entry) Panicf(format string, args ...interface{}) { func (entry *Entry) Panicf(format string, args ...interface{}) {
if entry.Logger.Level >= PanicLevel { if entry.Logger.level() >= PanicLevel {
entry.Panic(fmt.Sprintf(format, args...)) entry.Panic(fmt.Sprintf(format, args...))
} }
} }
@ -221,13 +221,13 @@ func (entry *Entry) Panicf(format string, args ...interface{}) {
// Entry Println family functions // Entry Println family functions
func (entry *Entry) Debugln(args ...interface{}) { func (entry *Entry) Debugln(args ...interface{}) {
if entry.Logger.Level >= DebugLevel { if entry.Logger.level() >= DebugLevel {
entry.Debug(entry.sprintlnn(args...)) entry.Debug(entry.sprintlnn(args...))
} }
} }
func (entry *Entry) Infoln(args ...interface{}) { func (entry *Entry) Infoln(args ...interface{}) {
if entry.Logger.Level >= InfoLevel { if entry.Logger.level() >= InfoLevel {
entry.Info(entry.sprintlnn(args...)) entry.Info(entry.sprintlnn(args...))
} }
} }
@ -237,7 +237,7 @@ func (entry *Entry) Println(args ...interface{}) {
} }
func (entry *Entry) Warnln(args ...interface{}) { func (entry *Entry) Warnln(args ...interface{}) {
if entry.Logger.Level >= WarnLevel { if entry.Logger.level() >= WarnLevel {
entry.Warn(entry.sprintlnn(args...)) entry.Warn(entry.sprintlnn(args...))
} }
} }
@ -247,20 +247,20 @@ func (entry *Entry) Warningln(args ...interface{}) {
} }
func (entry *Entry) Errorln(args ...interface{}) { func (entry *Entry) Errorln(args ...interface{}) {
if entry.Logger.Level >= ErrorLevel { if entry.Logger.level() >= ErrorLevel {
entry.Error(entry.sprintlnn(args...)) entry.Error(entry.sprintlnn(args...))
} }
} }
func (entry *Entry) Fatalln(args ...interface{}) { func (entry *Entry) Fatalln(args ...interface{}) {
if entry.Logger.Level >= FatalLevel { if entry.Logger.level() >= FatalLevel {
entry.Fatal(entry.sprintlnn(args...)) entry.Fatal(entry.sprintlnn(args...))
} }
Exit(1) Exit(1)
} }
func (entry *Entry) Panicln(args ...interface{}) { func (entry *Entry) Panicln(args ...interface{}) {
if entry.Logger.Level >= PanicLevel { if entry.Logger.level() >= PanicLevel {
entry.Panic(entry.sprintlnn(args...)) entry.Panic(entry.sprintlnn(args...))
} }
} }

View File

@ -31,14 +31,14 @@ func SetFormatter(formatter Formatter) {
func SetLevel(level Level) { func SetLevel(level Level) {
std.mu.Lock() std.mu.Lock()
defer std.mu.Unlock() defer std.mu.Unlock()
std.Level = level std.setLevel(level)
} }
// GetLevel returns the standard logger level. // GetLevel returns the standard logger level.
func GetLevel() Level { func GetLevel() Level {
std.mu.Lock() std.mu.Lock()
defer std.mu.Unlock() defer std.mu.Unlock()
return std.Level return std.level()
} }
// AddHook adds a hook to the standard logger hooks. // AddHook adds a hook to the standard logger hooks.

View File

@ -4,6 +4,7 @@ import (
"io" "io"
"os" "os"
"sync" "sync"
"sync/atomic"
) )
type Logger struct { type Logger struct {
@ -112,7 +113,7 @@ func (logger *Logger) WithError(err error) *Entry {
} }
func (logger *Logger) Debugf(format string, args ...interface{}) { func (logger *Logger) Debugf(format string, args ...interface{}) {
if logger.Level >= DebugLevel { if logger.level() >= DebugLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Debugf(format, args...) entry.Debugf(format, args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -120,7 +121,7 @@ func (logger *Logger) Debugf(format string, args ...interface{}) {
} }
func (logger *Logger) Infof(format string, args ...interface{}) { func (logger *Logger) Infof(format string, args ...interface{}) {
if logger.Level >= InfoLevel { if logger.level() >= InfoLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Infof(format, args...) entry.Infof(format, args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -134,7 +135,7 @@ func (logger *Logger) Printf(format string, args ...interface{}) {
} }
func (logger *Logger) Warnf(format string, args ...interface{}) { func (logger *Logger) Warnf(format string, args ...interface{}) {
if logger.Level >= WarnLevel { if logger.level() >= WarnLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Warnf(format, args...) entry.Warnf(format, args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -142,7 +143,7 @@ func (logger *Logger) Warnf(format string, args ...interface{}) {
} }
func (logger *Logger) Warningf(format string, args ...interface{}) { func (logger *Logger) Warningf(format string, args ...interface{}) {
if logger.Level >= WarnLevel { if logger.level() >= WarnLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Warnf(format, args...) entry.Warnf(format, args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -150,7 +151,7 @@ func (logger *Logger) Warningf(format string, args ...interface{}) {
} }
func (logger *Logger) Errorf(format string, args ...interface{}) { func (logger *Logger) Errorf(format string, args ...interface{}) {
if logger.Level >= ErrorLevel { if logger.level() >= ErrorLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Errorf(format, args...) entry.Errorf(format, args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -158,7 +159,7 @@ func (logger *Logger) Errorf(format string, args ...interface{}) {
} }
func (logger *Logger) Fatalf(format string, args ...interface{}) { func (logger *Logger) Fatalf(format string, args ...interface{}) {
if logger.Level >= FatalLevel { if logger.level() >= FatalLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Fatalf(format, args...) entry.Fatalf(format, args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -167,7 +168,7 @@ func (logger *Logger) Fatalf(format string, args ...interface{}) {
} }
func (logger *Logger) Panicf(format string, args ...interface{}) { func (logger *Logger) Panicf(format string, args ...interface{}) {
if logger.Level >= PanicLevel { if logger.level() >= PanicLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Panicf(format, args...) entry.Panicf(format, args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -175,7 +176,7 @@ func (logger *Logger) Panicf(format string, args ...interface{}) {
} }
func (logger *Logger) Debug(args ...interface{}) { func (logger *Logger) Debug(args ...interface{}) {
if logger.Level >= DebugLevel { if logger.level() >= DebugLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Debug(args...) entry.Debug(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -183,7 +184,7 @@ func (logger *Logger) Debug(args ...interface{}) {
} }
func (logger *Logger) Info(args ...interface{}) { func (logger *Logger) Info(args ...interface{}) {
if logger.Level >= InfoLevel { if logger.level() >= InfoLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Info(args...) entry.Info(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -197,7 +198,7 @@ func (logger *Logger) Print(args ...interface{}) {
} }
func (logger *Logger) Warn(args ...interface{}) { func (logger *Logger) Warn(args ...interface{}) {
if logger.Level >= WarnLevel { if logger.level() >= WarnLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Warn(args...) entry.Warn(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -205,7 +206,7 @@ func (logger *Logger) Warn(args ...interface{}) {
} }
func (logger *Logger) Warning(args ...interface{}) { func (logger *Logger) Warning(args ...interface{}) {
if logger.Level >= WarnLevel { if logger.level() >= WarnLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Warn(args...) entry.Warn(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -213,7 +214,7 @@ func (logger *Logger) Warning(args ...interface{}) {
} }
func (logger *Logger) Error(args ...interface{}) { func (logger *Logger) Error(args ...interface{}) {
if logger.Level >= ErrorLevel { if logger.level() >= ErrorLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Error(args...) entry.Error(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -221,7 +222,7 @@ func (logger *Logger) Error(args ...interface{}) {
} }
func (logger *Logger) Fatal(args ...interface{}) { func (logger *Logger) Fatal(args ...interface{}) {
if logger.Level >= FatalLevel { if logger.level() >= FatalLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Fatal(args...) entry.Fatal(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -230,7 +231,7 @@ func (logger *Logger) Fatal(args ...interface{}) {
} }
func (logger *Logger) Panic(args ...interface{}) { func (logger *Logger) Panic(args ...interface{}) {
if logger.Level >= PanicLevel { if logger.level() >= PanicLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Panic(args...) entry.Panic(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -238,7 +239,7 @@ func (logger *Logger) Panic(args ...interface{}) {
} }
func (logger *Logger) Debugln(args ...interface{}) { func (logger *Logger) Debugln(args ...interface{}) {
if logger.Level >= DebugLevel { if logger.level() >= DebugLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Debugln(args...) entry.Debugln(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -246,7 +247,7 @@ func (logger *Logger) Debugln(args ...interface{}) {
} }
func (logger *Logger) Infoln(args ...interface{}) { func (logger *Logger) Infoln(args ...interface{}) {
if logger.Level >= InfoLevel { if logger.level() >= InfoLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Infoln(args...) entry.Infoln(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -260,7 +261,7 @@ func (logger *Logger) Println(args ...interface{}) {
} }
func (logger *Logger) Warnln(args ...interface{}) { func (logger *Logger) Warnln(args ...interface{}) {
if logger.Level >= WarnLevel { if logger.level() >= WarnLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Warnln(args...) entry.Warnln(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -268,7 +269,7 @@ func (logger *Logger) Warnln(args ...interface{}) {
} }
func (logger *Logger) Warningln(args ...interface{}) { func (logger *Logger) Warningln(args ...interface{}) {
if logger.Level >= WarnLevel { if logger.level() >= WarnLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Warnln(args...) entry.Warnln(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -276,7 +277,7 @@ func (logger *Logger) Warningln(args ...interface{}) {
} }
func (logger *Logger) Errorln(args ...interface{}) { func (logger *Logger) Errorln(args ...interface{}) {
if logger.Level >= ErrorLevel { if logger.level() >= ErrorLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Errorln(args...) entry.Errorln(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -284,7 +285,7 @@ func (logger *Logger) Errorln(args ...interface{}) {
} }
func (logger *Logger) Fatalln(args ...interface{}) { func (logger *Logger) Fatalln(args ...interface{}) {
if logger.Level >= FatalLevel { if logger.level() >= FatalLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Fatalln(args...) entry.Fatalln(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -293,7 +294,7 @@ func (logger *Logger) Fatalln(args ...interface{}) {
} }
func (logger *Logger) Panicln(args ...interface{}) { func (logger *Logger) Panicln(args ...interface{}) {
if logger.Level >= PanicLevel { if logger.level() >= PanicLevel {
entry := logger.newEntry() entry := logger.newEntry()
entry.Panicln(args...) entry.Panicln(args...)
logger.releaseEntry(entry) logger.releaseEntry(entry)
@ -306,3 +307,11 @@ func (logger *Logger) Panicln(args ...interface{}) {
func (logger *Logger) SetNoLock() { func (logger *Logger) SetNoLock() {
logger.mu.Disable() logger.mu.Disable()
} }
func (logger *Logger) level() Level {
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
}
func (logger *Logger) setLevel(level Level) {
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
}

View File

@ -10,7 +10,7 @@ import (
type Fields map[string]interface{} type Fields map[string]interface{}
// Level type // Level type
type Level uint8 type Level uint32
// Convert the Level to a string. E.g. PanicLevel becomes "panic". // Convert the Level to a string. E.g. PanicLevel becomes "panic".
func (level Level) String() string { func (level Level) String() string {