mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-10 10:00:49 +09:00
132 lines
2.9 KiB
Go
132 lines
2.9 KiB
Go
package logger
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/gobwas/glob"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
var (
|
|
mu sync.Mutex
|
|
logger *zap.Logger
|
|
loggerConfig zap.Config
|
|
namedLevels = make(map[string]zap.AtomicLevel)
|
|
namedGlobs = make(map[string]glob.Glob)
|
|
namedLoggers = make(map[string]CtxLogger)
|
|
namedSugarLoggers = make(map[string]*zap.SugaredLogger)
|
|
)
|
|
|
|
func init() {
|
|
loggerConfig = zap.NewDevelopmentConfig()
|
|
logger, _ = loggerConfig.Build()
|
|
}
|
|
|
|
// SetDefault replaces the default logger
|
|
// you need to call SetNamedLevels after in case you have named loggers,
|
|
// otherwise they will use the old logger
|
|
func SetDefault(l *zap.Logger) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
*logger = *l
|
|
}
|
|
|
|
// SetNamedLevels sets the namedLevels for named loggers
|
|
// it also supports glob patterns for names, like "app*"
|
|
// can be racy in case there are existing named loggers
|
|
// so consider to call only once at the beginning
|
|
func SetNamedLevels(l map[string]zap.AtomicLevel) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
namedLevels = l
|
|
|
|
var minLevel = logger.Level()
|
|
for k, l := range namedLevels {
|
|
g, err := glob.Compile(k)
|
|
if err == nil {
|
|
namedGlobs[k] = g
|
|
}
|
|
namedLevels[k] = l
|
|
if l.Level() < minLevel {
|
|
minLevel = l.Level()
|
|
}
|
|
}
|
|
|
|
if minLevel < logger.Level() {
|
|
// recreate logger if the min level is lower than the current min one
|
|
loggerConfig.Level = zap.NewAtomicLevelAt(minLevel)
|
|
logger, _ = loggerConfig.Build()
|
|
}
|
|
|
|
for name, nl := range namedLoggers {
|
|
level := getLevel(name)
|
|
newCore := zap.New(logger.Core()).Named(name).WithOptions(
|
|
zap.IncreaseLevel(level),
|
|
)
|
|
*(nl.Logger) = *newCore
|
|
}
|
|
|
|
for name, nl := range namedSugarLoggers {
|
|
level := getLevel(name)
|
|
newCore := zap.New(logger.Core()).Named(name).WithOptions(
|
|
zap.IncreaseLevel(level),
|
|
).Sugar()
|
|
*(nl) = *newCore
|
|
}
|
|
}
|
|
|
|
func Default() *zap.Logger {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
return logger
|
|
}
|
|
|
|
func getLevel(name string) zap.AtomicLevel {
|
|
level, ok := namedLevels[name]
|
|
if !ok {
|
|
var found bool
|
|
for globName, glob := range namedGlobs {
|
|
if glob.Match(name) {
|
|
found = true
|
|
level, _ = namedLevels[globName]
|
|
// no need to check ok, because we know that globName exists
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
level = loggerConfig.Level
|
|
}
|
|
}
|
|
return level
|
|
}
|
|
|
|
func NewNamed(name string, fields ...zap.Field) CtxLogger {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
if l, nameExists := namedLoggers[name]; nameExists {
|
|
return l
|
|
}
|
|
|
|
level := getLevel(name)
|
|
l := zap.New(logger.Core()).Named(name).WithOptions(zap.IncreaseLevel(level),
|
|
zap.Fields(fields...))
|
|
|
|
ctxL := CtxLogger{Logger: l, name: name}
|
|
namedLoggers[name] = ctxL
|
|
return ctxL
|
|
}
|
|
|
|
func NewNamedSugared(name string) *zap.SugaredLogger {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
if l, nameExists := namedSugarLoggers[name]; nameExists {
|
|
return l
|
|
}
|
|
|
|
level := getLevel(name)
|
|
l := zap.New(logger.Core()).Named(name).Sugar().WithOptions(zap.IncreaseLevel(level))
|
|
namedSugarLoggers[name] = l
|
|
return l
|
|
}
|