Spaces:
Running
Running
File size: 6,466 Bytes
d0a3fab | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | # 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`](runbook.md).
> Pour le déploiement, voir [`deployment-institutional.md`](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 :
```python
# /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 :
```bash
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`](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)
```json
{
"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 :
```json
{
"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`](../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 :
```python
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. **Concurrence** — `picarones_jobs_running` actuel, comparé à
`PICARONES_MAX_CONCURRENT_JOBS`.
5. **Workspace size** — `du -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) |
|