fix: renforcer corrélation A/B et sorties stdout/fichier
Co-authored-by: aider (openrouter/openai/gpt-5.3-codex) <aider@aider.chat>
This commit is contained in:
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
@ -52,10 +53,10 @@ func (l LogLevel) String() string {
|
||||
|
||||
// Logger provides structured logging.
|
||||
type Logger struct {
|
||||
mu sync.Mutex
|
||||
logger *log.Logger
|
||||
prefix string
|
||||
fields map[string]any
|
||||
mu sync.RWMutex
|
||||
logger *log.Logger
|
||||
prefix string
|
||||
fields map[string]any
|
||||
minLevel LogLevel
|
||||
}
|
||||
|
||||
@ -88,30 +89,32 @@ func (l *Logger) SetLevel(level string) {
|
||||
|
||||
// ShouldLog returns true if the given level should be logged.
|
||||
func (l *Logger) ShouldLog(level LogLevel) bool {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.mu.RLock()
|
||||
defer l.mu.RUnlock()
|
||||
return level >= l.minLevel
|
||||
}
|
||||
|
||||
// WithFields returns a new logger with additional fields.
|
||||
func (l *Logger) WithFields(fields map[string]any) *Logger {
|
||||
l.mu.Lock()
|
||||
l.mu.RLock()
|
||||
minLevel := l.minLevel
|
||||
l.mu.Unlock()
|
||||
|
||||
newLogger := &Logger{
|
||||
prefix := l.prefix
|
||||
existing := make(map[string]any, len(l.fields))
|
||||
for k, v := range l.fields {
|
||||
existing[k] = v
|
||||
}
|
||||
l.mu.RUnlock()
|
||||
|
||||
for k, v := range fields {
|
||||
existing[k] = v
|
||||
}
|
||||
|
||||
return &Logger{
|
||||
logger: l.logger,
|
||||
prefix: l.prefix,
|
||||
fields: make(map[string]any),
|
||||
prefix: prefix,
|
||||
fields: existing,
|
||||
minLevel: minLevel,
|
||||
}
|
||||
for k, v := range l.fields {
|
||||
newLogger.fields[k] = v
|
||||
}
|
||||
for k, v := range fields {
|
||||
newLogger.fields[k] = v
|
||||
}
|
||||
return newLogger
|
||||
}
|
||||
|
||||
// Info logs an info message.
|
||||
@ -119,8 +122,6 @@ func (l *Logger) Info(msg string) {
|
||||
if !l.ShouldLog(INFO) {
|
||||
return
|
||||
}
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.log("INFO", msg)
|
||||
}
|
||||
|
||||
@ -129,8 +130,6 @@ func (l *Logger) Warn(msg string) {
|
||||
if !l.ShouldLog(WARN) {
|
||||
return
|
||||
}
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.log("WARN", msg)
|
||||
}
|
||||
|
||||
@ -139,8 +138,6 @@ func (l *Logger) Error(msg string, err error) {
|
||||
if !l.ShouldLog(ERROR) {
|
||||
return
|
||||
}
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
if err != nil {
|
||||
l.log("ERROR", msg+" "+err.Error())
|
||||
} else {
|
||||
@ -153,8 +150,6 @@ func (l *Logger) Debug(msg string) {
|
||||
if !l.ShouldLog(DEBUG) {
|
||||
return
|
||||
}
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.log("DEBUG", msg)
|
||||
}
|
||||
|
||||
@ -163,8 +158,6 @@ func (l *Logger) Debugf(msg string, args ...any) {
|
||||
if !l.ShouldLog(DEBUG) {
|
||||
return
|
||||
}
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.log("DEBUG", fmt.Sprintf(msg, args...))
|
||||
}
|
||||
|
||||
@ -173,8 +166,6 @@ func (l *Logger) Warnf(msg string, args ...any) {
|
||||
if !l.ShouldLog(WARN) {
|
||||
return
|
||||
}
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.log("WARN", fmt.Sprintf(msg, args...))
|
||||
}
|
||||
|
||||
@ -183,27 +174,42 @@ func (l *Logger) Infof(msg string, args ...any) {
|
||||
if !l.ShouldLog(INFO) {
|
||||
return
|
||||
}
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.log("INFO", fmt.Sprintf(msg, args...))
|
||||
}
|
||||
|
||||
func (l *Logger) log(level, msg string) {
|
||||
l.mu.RLock()
|
||||
prefix := l.prefix
|
||||
fields := make(map[string]any, len(l.fields))
|
||||
for k, v := range l.fields {
|
||||
fields[k] = v
|
||||
}
|
||||
l.mu.RUnlock()
|
||||
|
||||
var b strings.Builder
|
||||
if prefix != "" {
|
||||
prefix = "[" + prefix + "] "
|
||||
b.WriteString("[")
|
||||
b.WriteString(prefix)
|
||||
b.WriteString("] ")
|
||||
}
|
||||
b.WriteString(level)
|
||||
b.WriteString(" ")
|
||||
b.WriteString(msg)
|
||||
|
||||
if len(fields) > 0 {
|
||||
keys := make([]string, 0, len(fields))
|
||||
for k := range fields {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, k := range keys {
|
||||
b.WriteString(" ")
|
||||
b.WriteString(k)
|
||||
b.WriteString("=")
|
||||
b.WriteString(fmt.Sprintf("%v", fields[k]))
|
||||
}
|
||||
}
|
||||
|
||||
l.logger.SetPrefix(prefix + level + " ")
|
||||
|
||||
var args []any
|
||||
for k, v := range l.fields {
|
||||
args = append(args, k, v)
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
l.logger.Printf(msg+" %+v", args...)
|
||||
} else {
|
||||
l.logger.Print(msg)
|
||||
}
|
||||
l.logger.Print(b.String())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user