Pile d'observation
1) Pourquoi avez-vous besoin d'une pile d'observation
RCA rapide et diminution du MTTR : du symptôme à la cause en quelques minutes.
Gestion SLO : Mesure des erreurs/latence, alerte sur le budget erroné.
Contrôle des sorties : Canaries, auto-rollback par métriques.
Sécurité et audit : voies d'accès, anomalies, Legal Hold.
FinOps-transparence : coût de stockage/demandes, cost-per-SLO.
Méthodologies : Signaux d'or (latitude/trafic/erreurs/saturation), RED, USE.
2) L'architecture de base de la pile
Composants par couches
Collecte/agents : Exportateurs, Promtail/Fluent Bit, OTEL SDK/Auto-Instr, Blackbox-probes.
Шина/ingest: Prometheus remote_write → Mimir/Thanos, Loki distributors/ingesters, Tempo/Jaeger ingesters.
Stockages : S3/GCS/MinIO objet (froid prolongé), SSD (séries chaudes).
Requêtes/Visualisation : Grafana (panneaux, widgets SLO), Kibana (si ELK).
Gestion : Alertmanager/Grafana-alerta, service-annuaire, RBAC, gestionnaire secret.
Modèles de déploiement
Managed (Grafana Cloud/services cloud) - rapide et plus cher sur les volumes.
Self-hosted en K8s - contrôle total, besoin d'exploitation et FinOps.
3) Normes de données : un seul « schéma d'observabilité »
3. 1 Métriques (Prometheus/OpenMetrics)
Les labels obligatoires sont : « bou », « région », « cluster », « namespace », « service », « version », « tenant » (si multi-tenant), « endpoint ».
Nom : 'snake _ case', suffixes '_ total', '_ second', '_ bytes'.
Histogrammes : fixes 'buckets' (orientés SLO).
Cardinalité : Ne pas inclure 'user _ id', 'request _ id' dans les labels.
3. 2 Logs
Format : JSON ; les champs obligatoires "t'," level "," service "," bou "," trace _ id', "span _ id'," msg ".
PII : masquage sur agent (PAN, tokens, e-mail, etc.).
Labels loki : cardinalité faible seulement ('app', 'namespace', 'level', 'tenant').
3. 3 Pistes
OTel sémantique : 'service. name`, `deployment. environment`, `db. system`, `http.`.
Sampling : les chemins cibles p99 sont 'always _ on '/tail-sampling, le reste étant' parent/ratio '.
Incorporation d'ID : faites glisser 'trace _ id/span _ id' dans les logs et les métriques (labels/fields).
4) Corrélation M-L-T (Metrics/Logs/Traces)
À partir du graphe d'alerte (métrique), → les logs filtrés par 'trace _ id' → une piste spécifique.
À partir de la piste (span lent), vous → demander les métriques d'un backend particulier sur l'intervalle de span.
Boutons Drilldown dans les panneaux : « to logs » et « to tracks » avec substitution de variables ('$ bou', '$ service', '$ trace _ id').
5) OpenTelemetry Collector : Pipline de référence
yaml receivers:
otlp:
protocols: { http: {}, grpc: {} }
prometheus:
config:
scrape_configs:
- job_name: kube-nodes static_configs: [{ targets: ['kubelet:9100'] }]
processors:
batch: {}
memory_limiter: { check_interval: 1s, limit_mib: 512 }
attributes:
actions:
- key: deployment. environment value: ${ENV}
action: insert tail_sampling:
decision_wait: 5s policies:
- name: errors type: status_code status_code: { status_codes: [ERROR] }
- name: important-routes type: string_attribute string_attribute: { key: http. target, values: ["/payments","/login"] }
- name: probabilistic type: probabilistic probabilistic: { sampling_percentage: 10 }
exporters:
otlphttp/mimir: { endpoint: "https://mimir/api/v1/push" }
otlphttp/tempo: { endpoint: "https://tempo/api/traces" }
loki:
endpoint: https://loki/loki/api/v1/push labels:
attributes:
env: "deployment. environment"
service: "service. name"
service:
pipelines:
metrics: { receivers: [prometheus, otlp], processors: [memory_limiter, batch], exporters: [otlphttp/mimir] }
logs: { receivers: [otlp], processors: [batch], exporters: [loki] }
traces: { receivers: [otlp], processors: [memory_limiter, attributes, tail_sampling, batch], exporters: [otlphttp/tempo] }
6) Alerting : SLO et multi-burn
L'idée n'est pas alertable au niveau « CPU> 80 % », mais sur la consommation d'Error Budget.
BouQL templates :promql
5-minute error rate err_ratio_5m =
sum(rate(http_requests_total{status=~"5.."}[5m])) /
sum(rate(http_requests_total[5m]))
Quick burn (1m window)
(err_ratio_1m / (1 - SLO)) > 14. 4
Slow burn (30m)
(err_ratio_30m / (1 - SLO)) > 2
Latence (histogrammes) :
promql latency_p95 =
histogram_quantile(0. 95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))
7) Dashboards : structure des dossiers
00_Overview - plate-forme : SLO, p95, 5xx %, capacity, incidents actifs.
10_Services - par service : RPS, p95/p99, erreurs, versions (annotations).
20_Infra - K8s/Nodes/Storage/Network, etcd, contrôleurs.
30_DB/Queues — PostgreSQL/Redis/Kafka/RabbitMQ.
40_Edge/DNS/CDN/WAF - ingress, LB, règles WAF.
50_Synthetic - aptyme et scénarios headless.
60_Cost/FinOps - stockage, demandes, chaud/froid, prévisions.
Chaque panneau : description, unités, propriétaire, runbook-link, drilldown.
8) Logs : LogQL Atelier
logql
API errors
{app="api", level="error"} = "Exception"
Nginx 5xx in 5 minutes
{app="nginx"} json status=~"5.." count_over_time([5m])
Extract Fields
{app="payments"} json code!="" unwrap duration avg()
9) Pistes : TraceQL et focus
Trouvez les dormeurs les plus lents :
{ service. name = "api" } duration > 500ms
Sandwich « SQL lent dans une requête lente » :
{ name = "HTTP GET /order" } child. span. name = "SELECT" & child. duration > 50ms
10) Synthétique et aptame
Blackbox-exportateur : HTTP/TCP/TLS/échantillons DNS provenant de ≥3 régions/ASN.
Headless : login/deposit scripts programmés.
Quorum-alerts : déclenchement si les ≥2 régions voient une défaillance.
Page de statut : Apdates automatiques + commentaires manuels.
11) Stockage et rétention
Métriques : chaud 7-30 jours (séries rapides), downsampling/enregistrement rules, froid - stockage d'objets (mois).
Logs : Chaud 3-7 jours, puis - S3/GCS avec index (Loki chunk store/ELK ILM).
Pistes : 3-7 jours 'always _ on' + stockage à long terme pour les échantillons (tail-sampled/rejet).
- Rollover en taille et en temps ; budget des demandes (quotas/limites).
- Des politiques distinctes pour les données de prod/stage et de sécurité.
12) Multi-ténacité et accès
Divisez par 'tenant '/' namespace '/Spaces, index-patterns et permissions.
Taggez les ressources de facturation : 'tenant', 'service', 'team'.
Dashboards/alerts importés - dans les espaces de commandes spécifiques.
13) Sécurité et conformité
TLS/mTLS des agents aux beckands, HMAC pour la santé privée.
RBAC en lecture/écriture, vérification de toutes les demandes et alertes.
L'édition PII au bord ; l'interdiction des secrets dans les loges ; DSAR/Legal Hold.
Isolation : clusters/neumspaces distincts pour les domaines sensibles.
14) FinOps : coût de l'observabilité
Nous réduisons la cardinalité des labels et la logique dans ingest (pas dans les demandes).
Sampling Tracks + cible always-on pour les sentiers critiques.
Downsampling/recording rules pour les agrégations lourdes.
Archiver l'accès rare aux objets froids.
Метрики: `storage_cost_gb_day`, `query_cost_hour`, `cost_per_rps`, `cost_per_9`.
15) CI/CD et tests d'observabilité
Lynchage des métriques/logs dans le CI : interdiction de « l'explosion » de la cardinalité, vérification des histogrammes/unités.
Tests d'observabilité contract : métriques/champs de logs obligatoires, 'trace _ id'dans middleware.
Canary : annotations de sortie sur les graphiques, SLO-auto-rollback.
16) Exemples : Demandes rapides
Top endpoints sur les erreurs :promql topk(10, sum by (route) (rate(http_requests_total{status=~"5.."}[5m])))
CPU throttling:
promql sum by (namespace, pod) (rate(container_cpu_cfs_throttled_seconds_total[5m])) > 0
Kafka lag:
promql max by (topic, group) (kafka_consumergroup_lag)
Des loges aux pistes (Loki → Tempo) : passer 'trace _ id'comme un link sur Tempo UI/dashboard.
17) Qualité de la pile : chèque-feuille
- Schémas harmonisés de métriques/logs/pistes et unités.
- 'trace _ id'dans les logs et métriques, drilldown des panneaux.
- Multi-burn SLO-alerte sans flapping (quorum/multi-window).
- Downsampling, quotas de demandes, limites de pas/portée.
- Les classes de rétention et de stockage sont documentées et appliquées.
- RBAC/audit/PII-révision inclus.
- Dashboards : propriétaire, runbooks, ≤2 -3 écrans, réponse rapide.
- FinOps-dashboard (volumes, valeur, haut parleurs).
18) Plan de mise en oeuvre (3 itérations)
1. MVP (2 semaines) : Prometheus→Mimir, Loki, Tempo ; OTel Collector; les dashboards de base et les alertes SLO ; l'échantillon de blackbox.
2. Scale (3-4 semaines) : tail-sampling, downsampling, multi-région ingest, RBAC/Spaces, FinOps-dashboards.
3. Pro (4 + semaines) : Auto-rollback par SLO, headless synthétique des chemins clés, Legal Hold, SLO portfolio et reporting.
19) Anti-modèles
« Beaux graphiques sans SLO » - pas d'action → pas d'avantages.
Les labels à haute cardinalité ('user _ id', 'request _ id') sont une explosion de mémoire et de coût.
Les logs sans JSON et sans 'trace _ id' ne sont pas corrélés.
L'alerte des ressources au lieu des symptômes est le bruit et le burn-out.
L'absence de politique de rétention est une augmentation incontrôlée des coûts.
20) Mini-FAQ
Que choisir : Loki ou ELK ?
ELK pour la recherche complexe/facettes ; Loki - moins cher et plus rapide pour des scénarios de type grep. On utilise souvent un hybride.
Tout le monde a besoin de pistes ?
Oui, au moins sur les chemins clés (login, checkout, payments) avec tail-sampling - cela accélère considérablement RCA.
Comment recommencer à zéro ?
OTel Collector → Mimir/Loki/Tempo → les SLO de base et les échantillons blackbox → puis les dashboards et les burn-alerts.
Résultat
La pile d'observabilité n'est pas un ensemble d'outils disparates, mais un système cohérent : normes de données uniques → corrélation M-L-T → alerting SLO et synthétique → sécurité et FinOps. Fixez les schémas, la discipline des labels et des rétentions, connectez OTel, ajoutez drilldown et auto-rollback - et vous obtiendrez une fiabilité gérable avec un coût compréhensible.