core/backend/internal/logbuffer/buffer.go
enzo 88831e3967 feat: nettoyage menu + suppression modules inexistants + log viewer
- Sidebar : retrait des liens files, logs, services (non implémentés)
- Migration 001 : suppression des inserts files/logs/services
- Migration 002 : DELETE des modules inexistants en DB existante
- logbuffer : ring buffer mémoire branché sur log.SetOutput
- GET /api/settings/logs : retourne les 300 dernières lignes de log
- Settings : onglet Logs avec auto-refresh (5s/10s/30s/60s/désactivé, défaut 10s)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 23:57:07 +01:00

53 lines
1.2 KiB
Go

// Package logbuffer maintient un tampon circulaire en mémoire des lignes de log.
// Il implémente io.Writer pour être branché sur log.SetOutput via io.MultiWriter.
package logbuffer
import (
"bytes"
"sync"
)
const maxLines = 500
// Buffer est un tampon circulaire thread-safe de lignes de log.
type Buffer struct {
mu sync.RWMutex
lines []string
}
// Write implémente io.Writer. Découpe p en lignes et les ajoute au tampon.
func (b *Buffer) Write(p []byte) (int, error) {
b.mu.Lock()
defer b.mu.Unlock()
for _, line := range bytes.Split(p, []byte("\n")) {
s := string(bytes.TrimRight(line, "\r"))
if s == "" {
continue
}
b.lines = append(b.lines, s)
if len(b.lines) > maxLines {
b.lines = b.lines[len(b.lines)-maxLines:]
}
}
return len(p), nil
}
// Lines retourne les n dernières lignes (ou toutes si n <= 0 ou n > taille).
func (b *Buffer) Lines(n int) []string {
b.mu.RLock()
defer b.mu.RUnlock()
total := len(b.lines)
if n <= 0 || n >= total {
result := make([]string, total)
copy(result, b.lines)
return result
}
result := make([]string, n)
copy(result, b.lines[total-n:])
return result
}
// Global est l'instance partagée utilisée par main.go et les handlers.
var Global = &Buffer{}