fix: renforcer corrélation A/B et sorties stdout/fichier
Some checks failed
Build and Test / test (push) Has been cancelled
Build and Test / build (push) Has been cancelled
Build and Test / docker (push) Has been cancelled

Co-authored-by: aider (openrouter/openai/gpt-5.3-codex) <aider@aider.chat>
This commit is contained in:
Jacquin Antoine
2026-03-01 12:10:17 +01:00
parent d3436f6245
commit 27c7659397
13 changed files with 441 additions and 259 deletions

View File

@ -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())
}