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 = `