1
0
mirror of https://gitea.com/gitea/log synced 2025-10-05 16:32:46 +02:00

Fix race problem

This commit is contained in:
Andrew Thornton
2019-05-24 18:32:40 +01:00
parent c3c12d820f
commit ba81296631
3 changed files with 73 additions and 16 deletions

31
log.go
View File

@@ -13,7 +13,7 @@ var (
// DEFAULT is the name of the default logger
DEFAULT = "default"
// NamedLoggers map of named loggers
NamedLoggers = make(map[string]*Logger)
NamedLoggers = &LoggerMap{}
prefix string
hasDefaultLogger = false
)
@@ -29,16 +29,17 @@ func NewLogger(bufLen int64, name, provider, config string) *Logger {
CriticalWithSkip(1, "Unable to create default logger: %v", err)
panic(err)
}
return NamedLoggers[DEFAULT]
logger, _ := NamedLoggers.Load(DEFAULT)
return logger
}
// NewNamedLogger creates a new named logger for a given configuration
func NewNamedLogger(name string, bufLen int64, subname, provider, config string) error {
logger, ok := NamedLoggers[name]
logger, ok := NamedLoggers.Load(name)
if !ok {
logger = newLogger(name, bufLen)
NamedLoggers[name] = logger
NamedLoggers.Store(name, logger)
}
return logger.SetLogger(subname, provider, config)
@@ -46,16 +47,16 @@ func NewNamedLogger(name string, bufLen int64, subname, provider, config string)
// DelNamedLogger closes and deletes the named logger
func DelNamedLogger(name string) {
l, ok := NamedLoggers[name]
l, ok := NamedLoggers.Load(name)
if ok {
delete(NamedLoggers, name)
NamedLoggers.Delete(name)
l.Close()
}
}
// DelLogger removes the named sublogger from the default logger
func DelLogger(name string) error {
logger := NamedLoggers[DEFAULT]
logger, _ := NamedLoggers.Load(DEFAULT)
found, err := logger.DelLogger(name)
if !found {
Trace("Log %s not found, no need to delete", name)
@@ -65,21 +66,21 @@ func DelLogger(name string) error {
// GetLogger returns either a named logger or the default logger
func GetLogger(name string) *Logger {
logger, ok := NamedLoggers[name]
logger, ok := NamedLoggers.Load(name)
if ok {
return logger
}
return NamedLoggers[DEFAULT]
return NamedLoggers.LoadOnly(DEFAULT)
}
// GetLevel returns the minimum logger level
func GetLevel() Level {
return NamedLoggers[DEFAULT].GetLevel()
return NamedLoggers.LoadOnly(DEFAULT).GetLevel()
}
// GetStacktraceLevel returns the minimum logger level
func GetStacktraceLevel() Level {
return NamedLoggers[DEFAULT].GetStacktraceLevel()
return NamedLoggers.LoadOnly(DEFAULT).GetStacktraceLevel()
}
// Trace records trace log
@@ -173,18 +174,18 @@ func IsFatal() bool {
// Close closes all the loggers
func Close() {
l, ok := NamedLoggers[DEFAULT]
l, ok := NamedLoggers.Load(DEFAULT)
if !ok {
return
}
delete(NamedLoggers, DEFAULT)
NamedLoggers.Delete(DEFAULT)
l.Close()
}
// Log a message with defined skip and at logging level
// A skip of 0 refers to the caller of this command
func Log(skip int, level Level, format string, v ...interface{}) {
l, ok := NamedLoggers[DEFAULT]
l, ok := NamedLoggers.Load(DEFAULT)
if ok {
l.Log(skip+1, level, format, v...)
}
@@ -199,7 +200,7 @@ type LoggerAsWriter struct {
// NewLoggerAsWriter creates a Writer representation of the logger with setable log level
func NewLoggerAsWriter(level string, ourLoggers ...*Logger) *LoggerAsWriter {
if len(ourLoggers) == 0 {
ourLoggers = []*Logger{NamedLoggers[DEFAULT]}
ourLoggers = []*Logger{NamedLoggers.LoadOnly(DEFAULT)}
}
l := &LoggerAsWriter{
ourLoggers: ourLoggers,

56
log_map.go Normal file
View File

@@ -0,0 +1,56 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package log
import (
"sync"
)
// LoggerMap is sync.Map specialised to return loggers
type LoggerMap struct {
internal sync.Map
}
// Delete a logger from the map
func (m *LoggerMap) Delete(key string) {
m.internal.Delete(key)
}
// Load returns the logger for the key
func (m *LoggerMap) Load(key string) (*Logger, bool) {
i, ok := m.internal.Load(key)
if !ok {
return nil, ok
}
logger := i.(*Logger)
return logger, ok
}
// LoadOnly returns the logger for the key or nil
func (m *LoggerMap) LoadOnly(key string) *Logger {
logger, _ := m.Load(key)
return logger
}
// LoadOrStore returns the existing logger for the key or stores and returns the value
func (m *LoggerMap) LoadOrStore(key string, logger *Logger) (*Logger, bool) {
i, ok := m.internal.LoadOrStore(key, logger)
returnable := i.(*Logger)
return returnable, ok
}
// Store stores the provided logger at the provided key
func (m *LoggerMap) Store(key string, logger *Logger) {
m.internal.Store(key, logger)
}
// Range calls the provided function for each key and logger in the map
func (m *LoggerMap) Range(f func(string, *Logger) bool) {
m.internal.Range(func(iKey interface{}, iValue interface{}) bool {
key := iKey.(string)
logger := iValue.(*Logger)
return f(key, logger)
})
}

View File

@@ -143,7 +143,7 @@ func TestNewNamedLogger(t *testing.T) {
level := INFO
err := NewNamedLogger("test", 0, "console", "console", fmt.Sprintf(`{"level":"%s"}`, level.String()))
assert.NoError(t, err)
logger := NamedLoggers["test"]
logger := NamedLoggers.LoadOnly("test")
assert.Equal(t, level, logger.GetLevel())
written, closed := baseConsoleTest(t, logger)