Picarones / docs /operations /observability.md
Claude
docs: refonte Diataxis + 8 documents institutionnels (S60)
d0a3fab unverified

Observabilité — Picarones

Audience : opérateur (DSI institutionnelle, SRE). Décrit comment instrumenter Picarones pour qu'il soit observable depuis Prometheus, Grafana, Loki, Datadog, etc.

Pour la réponse aux incidents, voir runbook.md. Pour le déploiement, voir deployment-institutional.md.

Principes

Picarones expose trois types de signaux :

  1. Logs structurés (stdlib logging). Tous les modules utilisent logger = logging.getLogger(__name__). Niveaux conventionnels : DEBUG, INFO, WARNING, ERROR. Aucun print en production.
  2. Audit trail spécifique : [audit] <event> <key=value> (par convention). Émis par les endpoints sensibles (POST/DELETE /api/jobs).
  3. Endpoints de santé : GET /health, GET /version.

L'export vers une plateforme observabilité (Prometheus, Datadog, ELK) est laissé au déploiement institutionnel — Picarones ne pousse rien de lui-même.

Logs structurés

Format recommandé

Configurer le root logger en JSON pour l'ingestion automatique :

# /etc/picarones/logging.yaml
version: 1
disable_existing_loggers: false
formatters:
  json:
    format: '{"ts":"%(asctime)s","lvl":"%(levelname)s","logger":"%(name)s","msg":"%(message)s"}'
handlers:
  stdout:
    class: logging.StreamHandler
    stream: ext://sys.stdout
    formatter: json
loggers:
  picarones:
    level: INFO
    handlers: [stdout]
    propagate: false
root:
  level: WARNING
  handlers: [stdout]

Activer au démarrage :

PICARONES_LOG_CONFIG=/etc/picarones/logging.yaml \
  uvicorn picarones.interfaces.web:create_app --factory ...

Niveaux par module

Module Niveau prod recommandé
picarones.adapters.* INFO
picarones.app.services.* INFO
picarones.interfaces.web.* INFO
picarones.pipeline.* INFO (DEBUG si chasse à un bug d'orchestration)
picarones.evaluation.* WARNING (très verbeux en INFO)
picarones.adapters._retry WARNING (déjà bavard sur les retries)

Exemples de lignes utiles à monitorer

Pattern Signification Alerte
[adapter] erreur retryable.* Cloud API instable > 10/min sur 5 min → page
OCRAdapterError Échec définitif d'OCR > 5/min → warning
[job_runner] job .* en échec Job s'est terminé en error track per-IP
[audit] job_submitted Soumission de job tracker pour audit RGPD
[audit] job_cancelled Annulation de job tracker pour audit RGPD
WinError 87 Filename Windows invalide DEVRAIT être 0 (corrigé S59) — sinon régression
database is locked SQLite contention > 1/min → page

Audit trail

Les opérations sensibles produisent un log INFO normalisé :

INFO [audit] job_submitted job_id=abc123 corpus=bnf_xviii from=10.0.0.42
INFO [audit] job_cancelled job_id=abc123 from=10.0.0.42

Ces lignes sont destinées à être conservées selon la politique RGPD de l'institution (cf. data-retention-rgpd.md). Stockage minimum recommandé : 90 jours (audit interne) ; 5 ans si soumis aux Archives nationales.

Pour ingestion SIEM :

filter '[audit] '
extract job_id, corpus, from
forward to siem.bnf.fr:514 (syslog)

Endpoints de santé

GET /health

Réponse 200 OK si le process est en mesure de servir. Vérifie :

  • JobStore accessible (lecture)
  • WorkspaceManager accessible (écriture sandbox)
  • Pas de check sur les API cloud (un cloud down ne doit pas planter les health probes locales)
{
  "status": "ok",
  "version": "1.3.0-dev",
  "job_store": "ok",
  "workspace": "ok"
}

À utiliser comme liveness probe (Kubernetes) ou healthcheck (Docker). Recommandation : every 30s, fail after 3 consecutive.

GET /version

Réponse :

{
  "version": "1.3.0-dev",
  "code_version": "git-sha-abc1234",
  "python": "3.11.15"
}

Utile pour déterminer la version déployée sans accès au filesystem.

Métriques (à venir)

Picarones n'expose pas encore d'endpoint Prometheus /metrics. Recommandation immédiate : monitorer les logs.

Backlog (cf. /docs/roadmap/backlog.md) :

  • Compteur picarones_jobs_total{status="complete|error|cancelled"}
  • Histogramme picarones_job_duration_seconds
  • Compteur picarones_adapter_calls_total{adapter, status}
  • Histogramme picarones_adapter_latency_seconds{adapter}
  • Gauge picarones_jobs_running (instantané)

Implémentation visée : prometheus_client middleware FastAPI optionnel.

Tracing distribué

Pour les institutions qui orchestrent Picarones avec d'autres services (ETL, cataloguing), le tracing OpenTelemetry est recommandé.

État actuel : pas d'instrumentation native. Une instrumentation opportuniste via opentelemetry-instrumentation-fastapi peut être activée par le déploiement sans modifier Picarones :

from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from picarones.interfaces.web import create_app

app = create_app(state=...)
FastAPIInstrumentor.instrument_app(app)

Dashboards Grafana — squelette

Les panels recommandés pour un dashboard Picarones :

  1. Jobs throughput — courbes par status (complete/error/cancelled), stack area, 24 h.
  2. Adapter latency p50/p95/p99 par adapter (Tesseract, Pero, Mistral OCR, Google Vision, Azure DI, OpenAI, Anthropic, Mistral chat, Ollama).
  3. Error rate par adapter — % d'erreurs sur la dernière heure.
  4. Concurrencepicarones_jobs_running actuel, comparé à PICARONES_MAX_CONCURRENT_JOBS.
  5. Workspace sizedu -sh /var/lib/picarones/workspaces via exporter node.
  6. Heap RSS du process Picarones (via node_exporter ou process_exporter).

SLOs suggérés

Pour un déploiement institutionnel ouvert aux chercheurs :

Métrique SLO 30j Action si dépassé
Disponibilité /health 99.5 % Investiguer infra
Job completion rate > 95 % Examiner taux d'erreurs adapter
API p95 latency (CRUD jobs) < 500 ms Profiler le JobStore
Cloud adapter retry rate < 5 % Demander quota plus haut

Révisions

Version Date Changements
1.0 2026-05 Création initiale (S60)