164 lines
3.6 KiB
Go
164 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
"time"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
prefixed "github.com/x-cray/logrus-prefixed-formatter"
|
|
)
|
|
|
|
var Log *log.Logger
|
|
var logFile *os.File
|
|
var logWriter *syncWriter
|
|
var logCtx context.Context
|
|
var logCancel context.CancelFunc
|
|
|
|
// syncWriter écrit de manière synchrone (pas de buffer)
|
|
type syncWriter struct {
|
|
file *os.File
|
|
mutex sync.Mutex
|
|
}
|
|
|
|
func (w *syncWriter) Write(p []byte) (n int, err error) {
|
|
w.mutex.Lock()
|
|
defer w.mutex.Unlock()
|
|
|
|
n, err = w.file.Write(p)
|
|
if err == nil {
|
|
w.file.Sync() // Force l'écriture immédiate sur disque
|
|
}
|
|
return n, err
|
|
}
|
|
|
|
func NewLog() *log.Logger {
|
|
|
|
// ✅ Vérifier que Cfg existe
|
|
if Cfg == nil {
|
|
panic("Config not initialized! Call NewConfig() before NewLog()")
|
|
}
|
|
|
|
// ✅ Chemin du log à côté de l'exe
|
|
exe, _ := os.Executable()
|
|
exePath := filepath.Dir(exe)
|
|
logPath := filepath.Join(exePath, "flexradio.log")
|
|
|
|
if Cfg.General.DeleteLogFileAtStart {
|
|
if _, err := os.Stat(logPath); err == nil {
|
|
os.Remove(logPath)
|
|
}
|
|
}
|
|
|
|
logCtx, logCancel = context.WithCancel(context.Background())
|
|
|
|
var w io.Writer
|
|
|
|
if Cfg.General.LogToFile {
|
|
f, err := os.OpenFile(logPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("Cannot open log file %s: %v", logPath, err))
|
|
}
|
|
|
|
logFile = f
|
|
logWriter = &syncWriter{file: f}
|
|
|
|
// ✅ IMPORTANT: Vérifier si Stdout est disponible (mode console vs GUI)
|
|
if isConsoleAvailable() {
|
|
// Mode console : log vers fichier ET console
|
|
w = io.MultiWriter(os.Stdout, logWriter)
|
|
} else {
|
|
// Mode GUI (windowsgui) : log SEULEMENT vers fichier
|
|
w = logWriter
|
|
}
|
|
} else {
|
|
// Log uniquement vers console (si disponible)
|
|
if isConsoleAvailable() {
|
|
w = os.Stdout
|
|
} else {
|
|
// Pas de console, pas de log fichier -> log vers null
|
|
w = io.Discard
|
|
}
|
|
}
|
|
|
|
Log = &log.Logger{
|
|
Out: w,
|
|
Formatter: &prefixed.TextFormatter{
|
|
DisableColors: !isConsoleAvailable(),
|
|
TimestampFormat: "02-01-2006 15:04:05",
|
|
FullTimestamp: true,
|
|
ForceFormatting: true,
|
|
DisableSorting: true, // ✅ Ajoute
|
|
QuoteEmptyFields: true, // ✅ Ajoute
|
|
SpacePadding: 0, // ✅ Ajoute (pas d'espace)
|
|
},
|
|
Hooks: make(log.LevelHooks),
|
|
}
|
|
|
|
if Cfg.General.LogLevel == "DEBUG" {
|
|
Log.Level = log.DebugLevel
|
|
} else if Cfg.General.LogLevel == "INFO" {
|
|
Log.Level = log.InfoLevel
|
|
} else if Cfg.General.LogLevel == "WARN" {
|
|
Log.Level = log.WarnLevel
|
|
} else {
|
|
Log.Level = log.InfoLevel
|
|
}
|
|
|
|
logBuffer = NewLogBuffer(500) // Garde les 500 derniers logs
|
|
// Log.AddHook(&LogHook{buffer: logBuffer})
|
|
|
|
// ✅ Premier vrai log
|
|
Log.Infof("Logger initialized - Level: %s, ToFile: %v, LogPath: %s",
|
|
Cfg.General.LogLevel, Cfg.General.LogToFile, logPath)
|
|
|
|
return Log
|
|
}
|
|
|
|
func InitLogHook() {
|
|
if logBuffer == nil {
|
|
logBuffer = NewLogBuffer(500)
|
|
}
|
|
|
|
Log.AddHook(&LogHook{buffer: logBuffer})
|
|
Log.Info("Log hook initialized and broadcasting enabled")
|
|
}
|
|
|
|
// ✅ Détecter si on a une console (fonctionne sur Windows)
|
|
func isConsoleAvailable() bool {
|
|
// Si Stdout est nil ou invalide, on n'a pas de console
|
|
stat, err := os.Stdout.Stat()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
// Si c'est un char device, on a une console
|
|
return (stat.Mode() & os.ModeCharDevice) != 0
|
|
}
|
|
|
|
// ✅ Fonction pour fermer proprement le log
|
|
func CloseLog() {
|
|
if Log != nil {
|
|
Log.Info("Closing log file...")
|
|
}
|
|
|
|
if logCancel != nil {
|
|
logCancel()
|
|
}
|
|
|
|
time.Sleep(200 * time.Millisecond) // Donne le temps d'écrire
|
|
|
|
if logWriter != nil {
|
|
logWriter.mutex.Lock()
|
|
if logFile != nil {
|
|
logFile.Sync()
|
|
logFile.Close()
|
|
logFile = nil
|
|
}
|
|
logWriter.mutex.Unlock()
|
|
}
|
|
}
|