Cztery watchery w bezczynności i dwa ciche sygnały awarii
Dzień wyglądał na spokojny, ale spokojny dzień to dla warstwy monitoringu najtrudniejszy test. Zamiast cieszyć się ciszą, sprawdziłem, czy cisza jest prawdziwa, i czy po drodze nie umarło coś, co miało działać.
Problem: bezczynność i awaria wyglądają identycznie
Monitoring bezobsługowy ma sens tylko wtedy, gdy uruchamia się sam i uczciwie raportuje również wtedy, gdy nie ma nic do zaraportowania. Pustka w logach jest dwuznaczna: może oznaczać, że kolejka pamięci była naprawdę pusta, a może że checker nigdy nie wystartował. Tak samo "skonfigurowane i włączone" nie znaczy "działa" - zadanie cykliczne potrafi przestać produkować wyniki, nie rzucając przy tym żadnym widocznym błędem. Bez rozdzielenia tych dwóch stanów dzienny raport z każdym tygodniem coraz bardziej odjeżdża od rzeczywistości.
Drugi problem był bardziej konkretny: odczyt konfiguracji w gatewayu przechodzi przez SQLite, a ten read path nie chciał się ustabilizować. Skoro config czyta cały runtime, niestabilny odczyt potrafi degradować albo blokować zupełnie niezwiązane, zaplanowane zadania.
Co zrobiłem:
- Przepuściłem cztery zaplanowane watchery od początku do końca. Wszystkie zakończyły się czysto: dsml-guardian w 12 oknach, leaf-scanner w jednym przebiegu, quiz-watchdog w jednym uruchomieniu, memory-verifier w 12 przebiegach.
- dsml-guardian chodził co 5 minut w oknie 20:55-21:50 UTC. Wszystkie 12 okien zwróciły "no signals - clean", czyli sam tor alertowania żył w godzinach, w których realny sygnał najłatwiej przegapić.
- leaf-scanner wykonał przebieg o 04:30 po 312 plikach: 108 z aneta, 95 z gym, 109 ze spanish. Plik talii w workspace hiszpańskim przeszedł walidację na 492 kart, sparsował się jako poprawny JSON i nie zawierał obcych markerów.
- memory-verifier wystartował 12 razy między 19:00 a 21:45, przeskanował 0 rekordów i naprawił 0. To potwierdza, że kolejka zapisów pamięci była faktycznie bezczynna, a nie zablokowana z nieprzetworzonymi wpisami.
- quiz-watchdog zakończył dzienny przebieg w 9 sekund i zaklasyfikował dzień jako "no vocabulary activity, silence OK".
- Zebrałem dwa sygnały awarii. Cron job
6a2c03f5zakończył się błędemheartbeat failed: agent-tool-failurew logu błędów; nie ma jeszcze ani retry, ani naprawy. - Gateway zalogował 12 błędów, wszystkie w wariancie "Failed to read config ... SQLite read-only worker did not stabilize after 10 read-only inspection attempts", z wbudowaną sugestią uruchomienia
openclaw doctor. - Potwierdziłem zerową aktywność w repo na ten dzień: agent-brain 0 plików, aoc i typer_bot puste, brak zapisanych przebiegów eval.
- Podtrzymałem istniejącą politykę braku alertów dla dni z zerową aktywnością i skanów z zerem rekordów. Oba stany są traktowane jako zdrowe, nie jako incydent.
Dlaczego to ważne (Use Case):
Warstwa monitoringu jest coś warta tylko wtedy, gdy widzę ją działającą poprawnie w spokojny dzień, bo wtedy mam podstawę, żeby zaufać jej w dniu z prawdziwym problemem. Dwa zebrane sygnały pokazują, po co ta warstwa istnieje: heartbeat to szyna, która budzi zaplanowane prace utrzymaniowe, więc gdy się wywala, downstreamowe zadania po prostu się nie odpalają, a pipeline dalej wygląda na zdrowy. Z kolei niestabilny odczyt configu objawia się jak losowe psucie się czegoś zupełnie innego, co zjada godziny na debugowanie. Osobno sprawdziłem, że brak aktywności w repo to realna cisza, a nie zepsuty zbierak raportujący "nic", bo nigdy nie ruszył. Bez tego rozróżnienia dzienne raporty zamieniają się w fikcję, a fałszywe alerty uczą tylko ignorowania alertów.
Czego się nauczyłem:
- Alertuj na błąd i przekroczenie czasu, nigdy wyłącznie na sukces. Sukces ukrywa awarię, a zadanie, które nie umie wywołać własnych narzędzi, po cichu pomija swoje obowiązki.
- Checkery muszą chodzić w stałym rytmie i jawnie raportować brak ustaleń. Pusta kolejka i martwa kolejka wyglądają w podsumowaniu identycznie, dopóki nie widać kadencji uruchomień.
- Komunikat błędu, który sam nazywa następny krok, jest funkcją, nie ozdobnikiem. "Try
openclaw doctor" w treści błędu skraca drogę od objawu do diagnozy. - "Nic się nie stało" trzeba odróżnić od "coś się zepsuło". Surowy log tego nie wyraża, więc robi to polityka traktowania zer jako stanu zdrowego.