From 62613c9c7858b38f60f38a48ae705e4a8c6a366d Mon Sep 17 00:00:00 2001 From: Eric Coissac Date: Sun, 7 Sep 2025 08:07:25 +0200 Subject: [PATCH] derniere version deepseek --- pmolog/webloger.go | 57 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/pmolog/webloger.go b/pmolog/webloger.go index edccc5b5..9da89120 100644 --- a/pmolog/webloger.go +++ b/pmolog/webloger.go @@ -1,6 +1,7 @@ package pmolog import ( + "container/ring" "fmt" "net/http" "sync" @@ -14,6 +15,12 @@ type SSEBroker struct { mutex sync.Mutex } +// Buffer circulaire pour stocker les 1000 derniers messages +var ( + logBuffer = ring.New(1000) + bufferMutex sync.Mutex +) + // Initialiser le broker SSE var broker = &SSEBroker{ clients: make(map[chan string]bool), @@ -30,6 +37,12 @@ func (hook *SSELogHook) Fire(entry *logrus.Entry) error { // Formater le log avec le niveau et le message logLine := fmt.Sprintf("[%s] %s", entry.Level.String(), entry.Message) + // Ajouter le message au buffer circulaire + bufferMutex.Lock() + logBuffer.Value = logLine + logBuffer = logBuffer.Next() + bufferMutex.Unlock() + // Envoyer le log à tous les clients connectés broker.mutex.Lock() for client := range broker.clients { @@ -60,9 +73,32 @@ func sseHandler(w http.ResponseWriter, r *http.Request) { broker.clients[messageChan] = true broker.mutex.Unlock() - // Envoyer un message de bienvenue - fmt.Fprintf(w, "event: message\ndata: %s\n\n", "{\"content\": \"Connexion établie. Attente des logs...\", \"level\": \"info\"}") + // Envoyer d'abord les 1000 derniers messages stockés + bufferMutex.Lock() + logBuffer.Do(func(value interface{}) { + if value != nil { + if msg, ok := value.(string); ok { + // Déterminer le niveau de log pour le style CSS + level := "info" + if len(msg) > 7 { + switch msg[1:6] { + case "ERROR": + level = "error" + case "WARNI": + level = "warning" + case "DEBUG": + level = "debug" + } + } + + // Formater le message en JSON pour inclure le niveau + jsonMsg := fmt.Sprintf("{\"content\": \"%s\", \"level\": \"%s\"}", escapeJSONString(msg), level) + fmt.Fprintf(w, "event: message\ndata: %s\n\n", jsonMsg) + } + } + }) w.(http.Flusher).Flush() + bufferMutex.Unlock() // Envoyer les logs au client au fur et à mesure for { @@ -218,7 +254,7 @@ var indexHTML = `
-

📝 Logs en temps réel

+

📝 Logs en temps réel (1000 derniers messages)

@@ -235,8 +271,8 @@ var indexHTML = ` } }); - eventSource.addEventListener('message', function(event) { - const data = JSON.parse(event.data); + // Fonction pour ajouter un message aux logs + function addLogMessage(data) { const logLine = document.createElement('div'); logLine.className = 'log-line ' + data.level; @@ -257,6 +293,11 @@ var indexHTML = ` // Défilement automatique logsContainer.scrollTop = logsContainer.scrollHeight; + } + + eventSource.addEventListener('message', function(event) { + const data = JSON.parse(event.data); + addLogMessage(data); }); eventSource.onerror = function(error) { @@ -274,15 +315,15 @@ func indexHandler(w http.ResponseWriter, r *http.Request) { } func LoggerWeb(mux *http.ServeMux) { - // Ajouter le hook SSE à Logrus - logrus.AddHook(&SSELogHook{}) - // Configurer Logrus pour le développement logrus.SetFormatter(&logrus.TextFormatter{ ForceColors: true, FullTimestamp: true, }) + // Ajouter le hook SSE à Logrus + logrus.AddHook(&SSELogHook{}) + mux.HandleFunc("/log", indexHandler) mux.HandleFunc("/log-sse", sseHandler)