Monitoring audit 2026-07-31 — nálezy, backlog úklidu, návrh vlastního agenta
Stav: otevřené, práce pozastavena na Liborův pokyn („vrátíme se k tomu"). Kontext vzniku: vzešlo z dotazu na telegram hlášky „? Unknown error" a na to, jestli je
https://sentinel.studio60.cz/status/realita. Není to plánovaný audit, je to řetěz nálezů. Vše níž je změřené, ne odhadnuté — u každého bodu je uvedeno čím.
1. Proč to vzniklo: monitoring nikdo dlouhodobě nehlídá
Společný jmenovatel všech nálezů z 30.–31. 7.:
| Nález | Jak dlouho nepovšimnuto | Kdo to našel |
|---|---|---|
Cert bi.studio60.cz expirovaný 31. 5. 2026 |
~2 měsíce | sentinel 31. 7. |
Cert docs.s60dev.cz vydaný na jiný hostname (be.s60dev.cz) |
neznámo | sentinel 31. 7. |
GlitchTip healthcheck volal neexistující wget → falešně unhealthy |
3 měsíce (failing streak 301218) | sentinel 30. 7. |
SENTRY_DSN s pomlčkami → 3 služby neposílaly do GlitchTipu nic |
měsíce | sentinel 30. 7. |
| 13 Kuma monitorů, které nikdy nebyly UP | od 31. 3. | sentinel 31. 7. |
| 5 pauznutých monitorů zobrazených na status page se 6 týdnů starými daty | od 15. 6. | sentinel 31. 7. |
Nic z toho nebylo těžké najít. Chybí pravidelná revize — sentinel je reaktivní (přijde release → nasadím → ověřím), monitoring potřebuje někoho, kdo se na něj dívá i když se nic neděje.
2. Status page https://sentinel.studio60.cz/status/
Mechanismus je reálný a živý (ověřeno 31. 7.):
- HTML je JS aplikace, data tahá z
KUMA_API='/status/api'aMETRICS_API='/metrics/api' /status/api/status-page/studio60→ 83 monitorů v 6 skupinách (Produkce, Produkce — Deep Health, Infrastruktura, Hub (staging), Hub — Deep Health, Auto-discovered)/metrics/api/metrics/current→ metriky hostů sage ≈ 39 s= živé- heartbeaty čerstvé v řádu sekund
Obsah je ale zaneřáděný: z 83 svítí 17 červeně a ani jedna z nich není skutečný výpadek.
⚠️ Důsledek: stránka dnes nedokáže říct, že se něco rozbilo — trvale červené položky splývají s případnou reálnou.
3. Rozpad těch 17 červených
3a. Aktivní, ale NIKDY nebyly UP (12) — chyba konfigurace, ne služby
| ID | Monitor | Hláška | Diagnóza |
|---|---|---|---|
| 20 | api.studio60.cz (prod-alfa) |
404 | hlídá kořen https://api.studio60.cz, ale routy jsou pod /api → /api/health vrací 200 (ověřeno curl) — ✅ OPRAVENO 2026-08-01 |
| 25 | api.s60hub.cz (hub-alfa) |
404 | totéž — ✅ OPRAVENO 2026-08-01 |
| 34 | api.s60dev.cz (cerebro) |
404 | totéž — ✅ OPRAVENO 2026-08-01 |
| 23 | pdf.studio60.cz (prod-alfa) |
403 | chráněné |
| 26 | pdf.s60hub.cz (hub-alfa) |
403 | chráněné |
| 39 | cerebro.studio60.cz (cerebro) |
403 | chráněné |
| 44 | fess.studio60.cz (cerebro) |
403 | chráněné |
| 45 | kb.studio60.cz (cerebro) |
404 | chráněné/neexistuje |
| 60 | zoe.studio60.cz (cerebro) |
403 | chráněné |
| 93 | domains.studio60.cz (forge) |
404 | vhost je záměrně neprůrazný (location / { return 404; }) — ✅ OPRAVENO 2026-08-01, forge přidal /health |
| 41 | bi.studio60.cz (cerebro) |
certificate has expired | REÁLNÁ VADA — cert platil do 31. 5. 2026 (ověřeno openssl s_client) |
| 42 | docs.s60dev.cz (cerebro) |
Hostname/IP does not match certificate | REÁLNÁ VADA — cert má CN = be.s60dev.cz, platnost do 22. 9. (ověřeno openssl) |
| 58 | wash.studio60.cz (cerebro) | 403 | chráněné — doplněno 2026-08-01, v původní tabulce chybělo (88 380 beatů od 31. 3., nikdy UP) |
⚠️ Oprava původního závěru (2026-08-01). V první verzi tu stálo, že api.* je nejnebezpečnější kategorie, protože „skutečný výpadek produkčního API by zanikl v šumu". To bylo přehnané. Produkční i hub API byly celou dobu korektně hlídané jinými monitory, které byly zelené:
| ID | Monitor | URL |
|---|---|---|
| 12 | BadWolf Deep |
https://api.studio60.cz/api/health |
| 72 | BadWolf |
https://api.studio60.cz/api/health |
| 68 | Hub: BadWolf |
https://api.s60hub.cz/api/health |
Reálná díra byla jen u dev (api.s60dev.cz), který žádný /api/health monitor neměl. Monitory 20/25/34 byly primárně šum, ne slepé místo. Původní počet „13 nikdy UP" byl navíc podhodnocený — s wash (58) jich bylo 14.
3b. PAUZNUTÉ, ale pořád na status page (5) — stará data se tváří jako stav
| ID | Monitor | Poslední heartbeat |
|---|---|---|
| 28 | be.s60hub.cz (hub-alfa) |
2026-06-15 |
| 31 | be.s60dev.cz (cerebro) |
2026-06-15 |
| 36 | hive.studio60.cz (cerebro) |
2026-06-15 |
| 38 | fess.s60dev.cz (cerebro) |
2026-06-15 |
| 74 | dl.s60dev.cz (cerebro) |
2026-06-15 (getaddrinfo ENOTFOUND) |
Nekontrolují se, ale stránka je zobrazuje červeně podle šest týdnů starého záznamu.
3c. Zdravá část
66 monitorů UP s čerstvými heartbeaty, 0 monitorů, které bývaly UP a spadly → 31. 7. neprobíhal žádný výpadek.
4. Kaylee — vyřešeno jen částečně
kaylee.studio60.cz (cerebro), monitor id 50, přidán 31. 3.- 87 637 heartbeatů, všechny
403, ani jeden UP za 4 měsíce - Libor: kaylee běžet nemá → monitor hlídá pozůstatek po mrtvé službě
- Sentinel 31. 7. přidal
403mezi přijímané kódy (["200-299","301","302","403"]) + restart Kumy → monitor poprvé UP - ⚠️ Tahle změna stála na chybném předpokladu, že služba má běžet. Když běžet nemá, je trvale zelený monitor horší než červený.
- Rollback:
UPDATE monitor SET accepted_statuscodes_json='["200-299","301","302"]', active=0 WHERE id=50; - Otevřené: kaylee není v katalogu služeb ani v routing tabulce — nikdo neví, co to bylo
5. Telegram boti — tři různí
⚠️ PŘEMĚŘENO 2026-08-01 — tabulka níž měla DVĚ chyby. Kuma neposílá přes „Wash"; notifikace id=1 se jmenuje
Sentinel Telegrama používá@s60_sentinel_bot. A@wash_s60_botse nenašel nikde — ten údaj byl nepodložený. Aktuální inventura níž.
Úplná inventura botů (2026-08-01, ověřeno getMe u každého tokenu)
| Bot | Kde token žije |
|---|---|
@s60_sentinel_bot |
sentinel /root/secrets/telegram/.env + Kuma notifikace id=1 |
@cerebro_s60_bot |
cerebro (.env, s60-tools/telegram-pm.sh, běžící dev procesy) + n8n prod credential „Telegram Bot" |
@cortex_s60_bot |
cortex /opt/s60-cs/.env + cerebro s60-cs/.env |
@zoe_s60_bot |
cerebro (nexus, kontejner s60-nexus-zoe) |
@Fess84bot |
cerebro (nexus, openclaw, fess agent) |
@s60monitor_bot |
cerebro s60-infra/tools/attack-watch.sh |
@s60_badwolf_bot |
sentinel secrets + hub/prod /opt/badwolf/.env (přidán 2026-08-01) |
Prohledáno: soubory na sentinel / cerebro / hub / prod / cortex / pg-alfa, env běžících kontejnerů
(hub, prod, cerebro), /proc/*/environ běžících procesů na cerebru, Kuma SQLite a rozšifrované
n8n credentials (n8n export:credentials --decrypted).
@kaylee_s60_bot NENÍ ani na jednom z nich. Zbývající místa mimo dosah sentinelu:
forge (SSH host key nepřijat — řeší Libor sám), merlin (port 22 timeout), Liborův Mac Mini,
externí SaaS.
Postup pro dohledání kdekoli jinde:
grep -rhoE '[0-9]{8,10}:[A-Za-z0-9_-]{35}' /root /opt /etc 2>/dev/null | sort -u
# každý nález pak: curl -s "https://api.telegram.org/bot<TOKEN>/getMe"
Původní (chybná) tabulka z 31. 7.
| Bot | `getMe` | Kde je token | Co posílá | |---|---|---|---| | Cerebro | `@cerebro_s60_bot` | `/root/secrets/telegram/.env` | relay agent ↔ Libor | | Wash | `@wash_s60_bot` | **uvnitř Kuma DB**, notifikace id=1 `My Telegram Alert` | Kuma alerty | | „kaylee" | ? | **na sentinelu NENÍ** (prohledány secrets, skripty, compose) | ? |Chat ID je u Kumy i relay stejné (8532871856 = Libor).
Rozdělení potvrzené Liborem 2026-07-31:
- Wash = Kuma monitoring alerty ✅ (sedí s konfigurací notifikace id=1)
- kaylee = dostává dál ty „? Unknown error" hlášky — NENÍ to Kuma
⚠️ Historie oprav (ať se to nemotá): sentinel nejdřív správně určil „nechodí to z Kumy". Pak to podle Liborova průběžného pozorování („po tvých změnách chodí smysluplnější zprávy") mylně odvolal. Libor to 31. 7. upřesnil: ty smysluplné zprávy chodí přes Wash, kaylee dál dostává ten samý šum. Platí tedy původní závěr: zdroj „? Unknown error" NENÍ Kuma a NENÍ na sentinelu.
Jak to dohledat (nejlevnější první):
- Libor v Telegramu klikne na jméno bota → zobrazí se
@username⇒ jednoznačná identifikace, kterého bota to je - s tím
@usernamepak kaizen/infra grepnou cerebro na odpovídající token ([0-9]{8,10}:[A-Za-z0-9_-]{35}) a najdou proces, který ho volá - hypotéza k ověření: druhá instance Uptime Kumy nebo jiný monitoring na cerebru — „? Unknown error" je formátem podobné notifikaci, jen s nevyplněnou zprávou
6. Proč se po restartu spustila záplava notifikací
resendInterval = 0 → Kuma posílá jen při změně stavu (important=1). Restart 31. 7. resetoval stav v paměti, takže všech 13 trvale rozbitých monitorů vygenerovalo přechod → 10 notifikací v 04:46–04:47. Není to výpadek, je to dávka dlouho neviditelných pravd.
7. Backlog úklidu (nic z toho zatím neuděláno)
| # | Úkol | Kdo | Pozn. |
|---|---|---|---|
| 1 | ~~Opravit URL u api.studio60.cz, api.s60hub.cz, api.s60dev.cz → /api/health~~ |
sentinel | ✅ HOTOVO 2026-08-01 (+ domains.studio60.cz → /health), viz §9 |
| 2 | Rozhodnout o 8 „403/404 chráněných" monitorech: akceptovat kód, nebo smazat | Libor rozhodne | u kaylee Libor už řekl, že běžet nemá |
| 3 | Vrátit kaylee změnu + monitor deaktivovat | sentinel | rollback SQL viz §4 |
| 4 | Odstranit 5 pauznutých monitorů ze status page | sentinel | jinak zobrazují stav z 15. 6. |
| 5 | Nahlásit 2 certifikáty na cerebru (bi.studio60.cz expirovaný, docs.s60dev.cz špatný CN) |
infra / kaizen | sentinel nemá SSH na cerebro |
| 6 | Zvážit sjednocení Telegram botů (Kuma jede přes Wash, relay přes Cerebro) | Libor | dnes nevadí, ale mate |
| 7 | Dohledat, co posílá „kaylee" hlášky | kaizen / infra | token není na sentinelu → běží to jinde |
| 8 | Zavést hlídání expirace certifikátů napříč doménami | sentinel / nový agent | dnes to nedělá nikdo — proto §1 |
8. Návrh: samostatný agent na sentinelu — backup & monitoring
Liborův nápad (31. 7.), rozšířený týž den: agent na sentinelu, jehož zodpovědností je backup A monitoring, a který to pravidelně hlídá.
Doména — monitoring: Kuma (monitory, status page), GlitchTip (projekty, DSN, retence), sledování expirace certifikátů, pravidelná revize „co je trvale červené a proč", routing nálezů na správného agenta.
Doména — backup: pokrytí zálohovací rotace (které DB/volumes v ní nejsou), kontrola že zálohy reálně vznikají a nejsou prázdné, retence, sync na storagebox, periodické ověření obnovitelnosti (dump, který nikdo nikdy nezkusil restorovat, není záloha).
Proč to patří k sobě: obojí je „nikdo se na to nedívá, dokud to nebolí". Backup díra z 31. 7. je učebnicová — s60_kb (375 MB, jediný domov KB) nebyla v rotaci a odhalilo se to jen proto, že se agent kb sám náhodou zeptal. Kontrola po tom nálezu ukázala dalších 9 databází mimo zálohy: s60_auth_staging, s60_keycloak_test, bazarai, kiwi, s60_n8n_staging, s60_badwolf_staging, hive_scrapper, s60_cs_kb, fess_context. Systémová příčina: seznam DATABASES v /usr/local/bin/s60-backup.sh je statický, takže nová databáze se do záloh nikdy nedostane sama — přesně jako monitor, který nikdo nezkontroluje, jestli byl někdy zelený.
Co mu NEDÁVAT: deploy práva a SSH zápis na hub/prod. Jinak vzniknou dva agenti sahající na produkci a padá pravidlo [[feedback_only_sentinel_deploys]]. Model: on diagnostikuje, sentinel/infra zasahuje.
Podmínka pořadí (sentinelův názor): nejdřív úklid §7, teprve pak předání. Agent, který zdědí 17 trvale červených položek, se naučí ignorovat červenou stejně jako my.
Stav: nezaloženo, čeká na Liborovo rozhodnutí.
9. Provedená oprava 2026-08-01 (backlog #1)
Schváleno Liborem („oprav 93 i api trojici najednou"). Spouštěčem byl forge, který zjistil, že
domains.studio60.cz má vhost záměrně neprůrazný (location / { return 404; }) a přidal /health,
takže monitor stačilo přesměrovat.
| ID | Bylo | Je | Výsledek |
|---|---|---|---|
| 20 | https://api.studio60.cz |
https://api.studio60.cz/api/health |
200 - OK |
| 25 | https://api.s60hub.cz |
https://api.s60hub.cz/api/health |
200 - OK |
| 34 | https://api.s60dev.cz |
https://api.s60dev.cz/api/health |
200 - OK |
| 93 | https://domains.studio60.cz |
https://domains.studio60.cz/health |
200 - OK |
Monitor 93 byl poprvé UP za celou svou existenci — 23 332 heartbeatů od založení, do 1. 8. ani jeden úspěšný.
Postup: docker stop s60-uptime-kuma → UPDATE v transakci přes jednorázový kontejner
(docker run --rm -i -v /opt/uptime-kuma/data:/data --entrypoint sqlite3 louislam/uptime-kuma:1) → docker start.
Plná kopie DB se nedělala (1,5 GB souboru kvůli 4 stringům při 78 % zaplnění disku); místo toho přesný
rollback skript: ../runbooks/rollback-kuma-monitors-20260801.sql.
Stav po opravě: 79 aktivních monitorů → 70 UP, 9 nikoli (23, 26, 39, 41, 42, 44, 45, 58, 60).
⚠️ Past při měření: Kuma používá status 0=DOWN, 1=UP, 2=PENDING, 3=MAINTENANCE. Po restartu jdou
rozbité monitory nejdřív do PENDING (dobíhají maxretries), takže dotaz WHERE status=0 hlásí falešnou nulu.
Vždy počítat status <> 1.
Ověřovací příkazy (pro návrat k tématu)
# POZOR: sqlite3 v kontejneru JE (/usr/bin/sqlite3) — dřívější poznámka „chybí" byla mylná:
# docker exec s60-uptime-kuma sqlite3 /app/data/kuma.db "..."
# Alternativa read-only z hostu (host sqlite3 nainstalovaný nemá):
python3 -c "
import sqlite3
c=sqlite3.connect('file:/opt/uptime-kuma/data/kuma.db?mode=ro',uri=True)
for mid,nm in c.execute('SELECT id,name FROM monitor WHERE active=1'):
up=c.execute('SELECT 1 FROM heartbeat WHERE monitor_id=? AND status=1 LIMIT 1',(mid,)).fetchone()
if not up: print('NIKDY UP:', mid, nm)"
# živá data status page
curl -s https://sentinel.studio60.cz/status/api/status-page/studio60
curl -s https://sentinel.studio60.cz/metrics/api/metrics/current
# expirace certu
echo | openssl s_client -servername bi.studio60.cz -connect bi.studio60.cz:443 2>/dev/null | openssl x509 -noout -dates
Související
monitoring.md— přehled stacku../services/glitchtip/INDEX.md— hex DSN, healthcheck fix../services/telegram/INDEX.md— relay bot../runbooks/uptime-kuma.md— operační runbook Kumy
✅ VYŘEŠENO 2026-08-12 — 7 pauznutých monitorů sundáno ze status page
Liborův pokyn („monitoring vsech sedmi muzes vypnout"). Monitoring byl přitom vypnutý už
od 2026-06-15 — všech sedm mělo active=0. Jediné, co zbývalo, bylo, že pořád visely
na status page, tedy se tvářily jako sledované, aniž by se cokoli měřilo.
| monitor | poslední měření | stav tehdy | stav 2026-08-12 |
|---|---|---|---|
19 be.studio60.cz (prod-alfa) |
2026-06-15 | — | |
28 be.s60hub.cz (hub-alfa) |
2026-06-15 | — | |
31 be.s60dev.cz (cerebro) |
2026-06-15 | — | |
33 be.studio60.cz (cerebro) |
2026-06-15 | — | |
36 hive.studio60.cz (cerebro) |
2026-06-15 | 502 | pořád 502 (DNS → cerebro 178.63.52.57; vhost stojí, backend pryč — Hive Scrapper běží na Liborově Mac Mini) |
38 fess.s60dev.cz (cerebro) |
2026-06-15 | — | |
74 dl.s60dev.cz (cerebro) |
2026-06-15 | ENOTFOUND |
DNS záznam neexistuje |
Shodné datum u všech sedmi ⇒ nešlo o sedm rozhodnutí, ale o jedno hromadné vypnutí
(nejspíš aby přestaly řvát). Čtyři z nich jsou be.*, tedy starý backend na merlinu.
Co se provedlo: DELETE FROM monitor_group WHERE monitor_id IN (… active=0) — odebrána
jen vazba na status page. Definice monitorů ani historie se nemazaly.
Ověřeno: skupina „Auto-discovered" 53 → 46; 7 monitorů dál existuje s active=0;
379 579 heartbeatů zachováno; aktivní monitoring běží dál (79 monitorů, 180 měření za
3 min po restartu). Kontrola provedena i na veřejném API status page
(/api/status-page/studio60), ne jen v DB — žádný ze šesti hostnames se v odpovědi
nevyskytuje.
Rollback: runbooks/rollback-kuma-statuspage-20260812.sql
(7 INSERTů + restart kontejneru).
⚠️ Změna přes SQLite vyžaduje restart s60-uptime-kuma — Kuma drží stav v paměti.