Доработка. Парсинг в логах

This commit is contained in:
Maxim
2026-06-09 11:19:32 +03:00
parent 354156e557
commit 676a674794
3 changed files with 151 additions and 33 deletions

View File

@@ -16,7 +16,11 @@ type PipeReader struct {
humanLogger *logger.HumanLogger
monitor *logger.Monitor
eventLog *logger.EventLogger
lastAlert map[byte]time.Time // для предотвращения спама алертов
// Для дедупликации логов
lastData logger.GPIOData
lastLogTime time.Time
lastAlertTime map[byte]time.Time
}
func NewPipeReader(
@@ -27,12 +31,12 @@ func NewPipeReader(
eventLog *logger.EventLogger,
) *PipeReader {
return &PipeReader{
buf: buf,
dataLogger: dataLogger,
humanLogger: humanLogger,
monitor: monitor,
eventLog: eventLog,
lastAlert: make(map[byte]time.Time),
buf: buf,
dataLogger: dataLogger,
humanLogger: humanLogger,
monitor: monitor,
eventLog: eventLog,
lastAlertTime: make(map[byte]time.Time),
}
}
@@ -47,7 +51,6 @@ func (pr *PipeReader) Start(ctx context.Context, pipePath string) {
default:
}
// Проверяем существует ли pipe
if _, err := os.Stat(pipePath); os.IsNotExist(err) {
if pr.eventLog != nil {
pr.eventLog.Event("PIPE_НЕ_НАЙДЕН")
@@ -79,33 +82,58 @@ func (pr *PipeReader) Start(ctx context.Context, pipePath string) {
break
}
// Обрабатываем каждый байт
for i := 0; i < n; i++ {
b := buffer[i]
rawByte := buffer[i]
now := time.Now()
// 1. В RAM для UI
pr.buf.Write(b)
// Парсим данные
data := logger.ParseGPIO(rawByte)
// 1. В RAM для UI (сырое значение)
pr.buf.Write(rawByte)
// 2. На диск для архива (бинарный)
if pr.dataLogger != nil {
pr.dataLogger.Write(logger.Sample{
Timestamp: now.UnixMicro(),
Value: b,
Value: rawByte,
})
}
// 3. Human-readable лог (только когда есть данные)
// 3. Human-readable лог (при изменении состояния или раз в 5 секунд)
if pr.humanLogger != nil {
humanLine := fmt.Sprintf("[%s] Значение GPIO: %d (0x%02X)\n",
now.Format("2006-01-02 15:04:05.000"),
b, b)
pr.humanLogger.Write(humanLine)
shouldLog := false
// Логируем если изменилось количество или сила
if data.Count != pr.lastData.Count || data.Strength != pr.lastData.Strength {
shouldLog = true
}
// Или если прошло больше 5 секунд с последнего лога
if now.Sub(pr.lastLogTime) >= 5*time.Second {
shouldLog = true
}
if shouldLog {
strengthName := logger.GetStrengthName(data.Strength)
humanLine := fmt.Sprintf(
"[%s] Обнаружение: %d объектов | Сила: %s (уровень %d) | Сырое: 0x%02X (%d)\n",
now.Format("2006-01-02 15:04:05.000"),
data.Count,
strengthName,
data.Strength,
rawByte,
rawByte,
)
pr.humanLogger.Write(humanLine)
pr.lastData = data
pr.lastLogTime = now
}
}
// 4. Алерт если значение > 10
if b > 10 {
pr.handleAlert(b, now)
// 4. Алерт если количество обнаружений > 10
if data.IsHighCount {
pr.handleAlert(data, now)
}
// 5. Обновляем watchdog
@@ -115,32 +143,37 @@ func (pr *PipeReader) Start(ctx context.Context, pipePath string) {
}
}
// Пауза перед переподключением
time.Sleep(1 * time.Second)
}
}()
}
func (pr *PipeReader) handleAlert(value byte, timestamp time.Time) {
// Anti-spam: не чаще 1 алерта в секунду для одного значения
if last, exists := pr.lastAlert[value]; exists {
if timestamp.Sub(last) < 1*time.Second {
func (pr *PipeReader) handleAlert(data logger.GPIOData, timestamp time.Time) {
// Anti-spam: не чаще 1 алерта в 10 секунд для одинакового количества
key := data.Count
if last, exists := pr.lastAlertTime[key]; exists {
if timestamp.Sub(last) < 10*time.Second {
return
}
}
pr.lastAlert[value] = timestamp
pr.lastAlertTime[key] = timestamp
strengthName := logger.GetStrengthName(data.Strength)
// 1. В event log (JSON)
if pr.eventLog != nil {
pr.eventLog.Event(fmt.Sprintf("ВЫСОКОЕ_ЗНАЧЕНИЕ_%d", value))
pr.eventLog.Event(fmt.Sprintf("ОБНАРУЖЕНО_%d_ОБЪЕКТОВ_СИЛА_%d", data.Count, data.Strength))
}
// 2. В human-readable лог с предупреждением (только на русском)
// 2. В human-readable лог с предупреждением
if pr.humanLogger != nil {
alertLine := fmt.Sprintf("[%s] ВНИМАНИЕ: Обнаружено высокое значение! GPIO = %d (>10)\n",
timestamp.Format("2006-01-02 15:04:05.000"), value)
alertLine := fmt.Sprintf(
"[%s] ВНИМАНИЕ: Обнаружено превышение! %d объектов | Сила: %s (уровень %d)\n",
timestamp.Format("2006-01-02 15:04:05.000"),
data.Count,
strengthName,
data.Strength,
)
pr.humanLogger.Write(alertLine)
}
// 3. В консоль больше НЕ пишем (всё уже в логах)
}