🛰 TRANSIT Error Intelligence Center ORCH-T111
Questo è il cruscotto che intercetta quando e dove l'applicazione TRANSIT smette di fare quello che dovrebbe — eccezioni nei router Telegram, bug silenti sul flusso stateless, drop-off nei funnel di dispatch, salute del processo PYBOT. È pensato per darti dati oggettivi prima di intervenire: non patching al buio su segnalazione utente, ma un ranking di nodi critici che ti dice "parti da qui". La Phase 1 mostra il runtime del processo (già LIVE). La Phase 2 aggiunge il tracking strutturato delle eccezioni: quelle sezioni sono marcate in viola.
Le metriche runtime che PYBOT sta già emettendo dal pilota OTel (ORCH-T111 Phase 1). Sono indicatori di salute del processo: se il worker è vivo, quanta memoria sta usando, se l'event-loop è reattivo, se il pool di connessioni Supabase è saturo. Non raccontano ancora cosa sta sbagliando a livello applicativo — quello è il lavoro della Phase 2.
Flag attivi su PYBOT che cambiano il comportamento del codice TRANSIT. Osservarne l'error-rate relativo è cruciale per decidere rollback.
Tabella delle eccezioni più frequenti nelle ultime 24h, aggregate per classe Python (es. RPCValidationError, KeyError, asyncio.TimeoutError). Ogni riga avrà il conteggio, l'ultimo timestamp, l'handler in cui è stata catturata, e il link al trace diagnostico. Serve per capire quale tipo di bug sta pesando — un KeyError su photo_router significa che un field attendo non arriva più, un TimeoutError su SupabaseGateway significa che il direct endpoint è lento o saturo.
| Exception class | Count 24h | Ultima vista | Handler | Azione |
|---|---|---|---|---|
⏳ Phase 2 — Dati emessi da span.record_exception()
+ counter transit_handler_errors_total{handler, exception_class}.
Aggregazione via RPC telemetry_top_exceptions_24h().
|
||||
COMPASS è l'observatory di ecosistema (compass.macvspc.cloud). Oggi raccoglie eventi a posteriori: incidenti chiusi, workaround registrati, segnali calcolati dal T1 engine. Con Telemetry Phase 2 in piedi, alimenteremo COMPASS con segnali real-time oggettivi: error-rate di ogni handler, health del processo PYBOT, drop-off dei funnel TRANSIT. Il passaggio è da narrative by incident a observation continua con prediction.
I quattro signal nuovi che proporremo nel design ORCH-T112 per COMPASS: S_TRANSIT_ERROR_SPIKE (error rate > 3/min per 5min),
S_PYBOT_HEARTBEAT_MISS (nessuna metrica runtime per 3min), S_FLAG_DIVERGENCE (error rate branch stateless diverge
> 50% vs legacy), S_FUNNEL_DROPOFF (completamento flusso sotto 85%).
📖 Cos'è Telemetry e perché l'abbiamo costruita
Telemetry, detto in una riga, è l'insieme degli strumenti che intercettano cosa fa il codice in produzione, in tempo reale, senza fermarlo.
Non è un tool, è un livello dell'infrastruttura: una pipeline che parte dall'applicazione (PYBOT su VIPER),
passa da un collector (OTel Collector), atterra su un backend di storage (Supabase schema telemetry),
e viene visualizzata da strumenti come Grafana o questa pagina stessa.
Nel contesto GEKO l'abbiamo costruita con un obiettivo specifico: smettere di osservare TRANSIT solo quando qualcosa si è già rotto. Prima — e in parte ancora oggi — la conoscenza dei problemi arrivava "per incidente": un autista segnalava un comando che non rispondeva, tu aprivi i log del container in SSH, grep-pavi a mano, e nel 60% dei casi i log erano già stati ruotati. L'informazione dopo l'evento non basta più, perché TRANSIT è sul sentiero per diventare un prodotto verticale vendibile, e un prodotto vendibile deve avere osservabilità industriale, non artigianale.
🔍 Come si legge un errore con Telemetry Phase 2
La sequenza operativa che stiamo costruendo è questa. Un autista ti scrive "il briefing ZTL non è arrivato". Tu apri questa pagina.
Prima cosa: guardi il KPI Errori 24h — se è salito rispetto a ieri, c'è qualcosa di nuovo. Seconda cosa:
il tile Top Exception Classes: ti dice quale tipo di errore sta dominando. Terza cosa: Dove intervenire
ti ranka gli handler dal più rotto al più stabile. A quel punto sai già, con molta probabilità, su quale file di codice mettere le mani.
Se serve il dettaglio puntuale dell'evento specifico dell'autista, chiedi il trace_id (che la Phase 2 propagherà nei messaggi di
fallback) e con quello apri Grafana Explore → filtro su traces_raw WHERE trace_id = 'abc123' → vedi l'intera timeline della richiesta:
ingresso webhook, span del router, eccezione con stack trace, output finale. Quello che oggi richiede 20 minuti di grep su log di container
diventa 10 secondi di query.
🧬 Il vocabolario minimo
Metrica — un numero che aggreghi nel tempo. Esempi: worker_memory_mb=144, errors_total=37.
Basso costo, perfetto per dashboard e alerting, ma perde informazione: un counter di 37 errori non ti dice cosa sono.
Traccia (span) — il racconto di una singola richiesta attraverso il codice. Ingresso → funzioni chiamate → eccezioni → uscita.
Porta molto contesto (parametri, exception class, stack trace) ma costa di più: non la aggreghi, la peschi on-demand con il trace_id.
Log — evento narrativo strutturato con livello (ERROR/WARN/INFO) e messaggio. La Phase 2 li correla automaticamente al
trace_id della richiesta che li ha generati. Senza questo link, i log restano isola.
La regola d'oro del debug con Telemetry: parti dal counter (cosa sta aumentando?), scendi al trace (cosa è successo in quella richiesta?), leggi i log correlati (qual è il contesto narrativo?), quindi patcha il codice. Non al contrario.
🏷 Cardinalità — perché non basta "logga tutto"
Ogni label su una metrica moltiplica lo storage. Se metti user_id come label, con 50 autisti già moltiplichi per 50 ogni conteggio.
Se metti trace_id esplodi. Per questo il nostro design separa le label basso-cardinality (handler, exception_class, user_role)
che vanno sulle metriche aggregate, dalle dimensioni alto-cardinality (trace_id, message_id, driver_code) che vanno su traces e logs come
attributi per la ricerca puntuale. È una scelta architetturale: il costo di storage di Supabase cresce linearmente con le righe, e la tabella
metrics_raw oggi colleziona già ~119 campioni all'ora solo con le 4 metriche runtime.
Ecco i 6 pilastri che trasformano questa pagina da "skeleton didattico" a "cruscotto operativo pieno". Ordine di attacco proposto: logs prima (serve per diagnosi), exception wrapper (quick-win 1 giornata), poi alerting + COMPASS signals, poi dashboard actionable, poi documentazione vendible. Governance: TRIO-GATED (4/6 criteri Triage TRUE).
Logs pipeline — schema telemetry.logs_raw + ingest /v1/logs
Schema minimale (ts, service, level, message, exception_class, stack_trace, trace_id, span_id, labels). FastAPI endpoint. OTel LoggingHandler su PYBOT. Retention policy 7/14/30 giorni per INFO/WARN/ERROR. Effort ~2 giornate.
Exception wrapper — span.record_exception() sui router TRANSIT
Wrapper di 15 righe su webhook.py, handlers/slash_router.py, handlers/photo_router.py. Counter transit_handler_errors_total{handler, exception_class, user_role}. Deploy PYBOT via Codex CLI su VIPER. Quick-win indipendente dalla pipeline logs.
Alerting — 3 regole Grafana → Telegram topic 5
(a) Error rate > 3/min per 5min, (b) Missing heartbeat PYBOT > 3min, (c) Exception class critica singola (RPCValidationError, AssertionError) al primo hit. Webhook Grafana → bot admin.
COMPASS integration — 4 signal nuovi + advisory notes
S_TRANSIT_ERROR_SPIKE, S_PYBOT_HEARTBEAT_MISS, S_FLAG_DIVERGENCE, S_FUNNEL_DROPOFF. Advisory prompt template che legge il trend e produce narrative note leggibili.
Actionable dashboard — "Dove intervenire" real-time
RPC telemetry_critical_nodes_24h() SECURITY DEFINER che ritorna top-N handler per error-rate con suggestion basata su pattern. Popolazione automatica tile principale di questa pagina + link diretto al file sorgente sul workspace.
Vendible product docs — runbook, SLA, data model
Documentazione orientata a TRANSIT come prodotto: SLO/SLA proposte (error budget), schema dati pubblico, runbook per onboarding tenant, disclosure GDPR su traces/logs. Deliverable per il percorso "TRANSIT vendibile".