feat(ui): фильтр уровней логов в панели «Логи»

This commit is contained in:
ki.sagidullin
2026-08-21 21:35:37 +05:00
parent ee76f9d89f
commit a762a1df80
7 changed files with 509 additions and 45 deletions

View File

@@ -5,6 +5,14 @@ import (
"sync"
)
// Канонические уровни записей лога (фильтр панели «Логи», см. ui.LogLevels).
const (
LevelError = "error"
LevelWarning = "warning"
LevelInfo = "info"
LevelDebug = "debug"
)
// LogLine — строка лога для панели «Логи».
type LogLine struct {
Level string
@@ -13,6 +21,37 @@ type LogLine struct {
func (LogLine) _event() {}
// markers проверяет наличие любого из маркеров в уже приведённой к нижнему
// регистру строке.
func markers(s string, anyOf ...string) bool {
for _, m := range anyOf {
if strings.Contains(s, m) {
return true
}
}
return false
}
// ClassifyLevel определяет уровень строки лога по её тексту.
//
// Стандартный log.Printf не несёт уровня, поэтому применяются эвристики по
// маркерам в тексте (в приоритете debug → warning → error): "debug"/"trace" —
// отладка; "warn"/"предупреж" — предупреждение; "error"/"ошибк"/"failed"/
// "fatal"/"panic" — ошибка. Остальные строки — информационные.
func ClassifyLevel(line string) string {
s := strings.ToLower(line)
switch {
case markers(s, "debug", "trace"):
return LevelDebug
case markers(s, "warn", "предупреж"):
return LevelWarning
case markers(s, "error", "ошибк", "failed", "failure", "fatal", "panic"):
return LevelError
default:
return LevelInfo
}
}
// LogBus — тип-обёртка над *Bus для логов.
//
// Логи идут отдельной шиной, чтобы большие объёмы текста не блокировали
@@ -35,7 +74,8 @@ type LogWriter struct {
buf strings.Builder
}
// NewLogWriter создаёт LogWriter, публикующий в шину логов события LogLine{Level:"log"}.
// NewLogWriter создаёт LogWriter, публикующий строки лога как события
// LogLine; уровень каждой строки определяется эвристикой ClassifyLevel.
func NewLogWriter(bus *LogBus) *LogWriter {
return &LogWriter{bus: bus.Bus}
}
@@ -56,7 +96,7 @@ func (w *LogWriter) Write(p []byte) (int, error) {
line := strings.TrimSuffix(data[:idx], "\r")
data = data[idx+1:]
if line != "" {
w.bus.Publish(LogLine{Level: "log", Text: line})
w.bus.Publish(LogLine{Level: ClassifyLevel(line), Text: line})
}
}
w.buf.Reset()