G-02 Pipeline de télémétrie
Brique G de la plateforme Enterprise AI. Technologie : OpenTelemetry Collector (receivers OTLP ; processors
filter,attributes,redaction,tail_sampling; exporters vers Prometheus, OpenSearch, Jaeger, ClickHouse, Opik). Version anglaise : ../../en/bricks/G-02-telemetry-pipeline.md.
Rôle et responsabilités
- Recevoir, filtrer, enrichir, masquer, échantillonner et router toute la télémétrie.
- Imposer les labels de tenant et supprimer les attributs interdits (secrets, PII brutes) avant export.
Position et interactions
- Chemin d'exécution : flux d'événements.
- Agents et gateways exportent en OTLP vers le collecteur ; le Control Plane transmet les spans des SDK reçus sur /v1/telemetry/spans.
Part open source et part développée
- Open source réutilisé : Distribution contrib de l'OpenTelemetry Collector.
- Développé dans la plateforme : Configuration du collecteur en code (Helm), règles de masquage partagées avec les motifs DLP de la brique E.
Modèle de données
Tables du Control Plane (schéma eai) : eai.telemetry_spans.
Chaque table de tenant a tenant_id uuid NOT NULL et une politique de sécurité au niveau des lignes sur current_setting('app.tenant_id', true)::uuid. ClickHouse usage_events est la réplique analytique de eai.usage_events (ReplacingMergeTree par event_id).
Contrat : contracts/v1/usage-event.schema.json (schema_version 1.0). L'usage est toujours remonté avec contracts/v1/usage-event.schema.json, l'audit avec contracts/v1/audit-event.schema.json.
Endpoints d'API
| Méthode | Chemin |
|---|---|
| POST | /v1/telemetry/spans |
| GET | /v1/telemetry/overview |
POST /v1/telemetry/spans
Requête :
{
"spans": [
{
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"span_id": "00f067aa0ba902b7",
"name": "gen_ai.chat",
"kind": "client",
"start_time": "2026-10-29T10:00:00.120Z",
"end_time": "2026-10-29T10:00:01.940Z",
"attributes": {
"gen_ai.request.model": "gpt-4o-mini",
"gen_ai.usage.input_tokens": 812,
"eai.agent_id": "agt_ap",
"eai.run_id": "run_42"
}
}
]
}
Réponse :
{
"accepted": 1,
"rejected": 0
}
GET /v1/telemetry/overview
Réponse :
{
"window": "24h",
"requests": 18234,
"error_rate": 0.012,
"p95_latency_ms": 2140,
"tokens": {
"input": 9120044,
"output": 1203400
},
"top_models": [
{
"model_id": "gpt-4o-mini",
"share": 0.61
}
]
}
Exemples SDK
Python
from enterprise_ai import EnterpriseAI
client = EnterpriseAI(base_url="<control-plane-url>", api_key="eai_live_xxx", tenant="acme", locale="fr")
client.telemetry.ingest(spans=spans)
client.telemetry.overview(days=1)
TypeScript
import { EnterpriseAI } from "@enterprise-ai/sdk";
const client = new EnterpriseAI({ baseUrl: "<control-plane-url>", apiKey: process.env.EAI_API_KEY, tenant: "acme", locale: "fr" });
await client.telemetry.ingestSpans({ spans: spans });
await client.telemetry.overview({ days: 1 });
Java
EnterpriseAIClient client = EnterpriseAIClient.builder()
.baseUrl("<control-plane-url>")
.apiKey(System.getenv("EAI_API_KEY"))
.tenant("acme")
.locale(Locale.FRENCH)
.build();
client.telemetry().ingestSpans(Map.of("spans", spans));
client.telemetry().overview(Map.of("days", 1));
Go
client, err := eai.NewClient(eai.WithBaseURL("<control-plane-url>"), eai.WithAPIKey(os.Getenv("EAI_API_KEY")), eai.WithTenant("acme"), eai.WithLocale("fr"))
if err != nil { log.Fatal(err) }
ctx := context.Background()
_, err = client.Telemetry.IngestSpans(ctx, map[string]any{"spans": spans})
_, err = client.Telemetry.Overview(ctx, eai.WithQuery(map[string]string{"days": "1"}))
Configuration
Variables d'environnement : EAI_OTEL_EXPORTER_OTLP_ENDPOINT.
Clés de valeurs Helm (deploy/helm/enterprise-ai/values.yaml) : global.monitoring, otelCollector.config.processors.
Sécurité
- mTLS entre agents et collecteur ; le collecteur tourne dans le namespace observability avec des politiques Cilium.
- Tenant déduit de l'identifiant d'accès, jamais du corps ; sécurité au niveau des lignes PostgreSQL sur chaque table de tenant.
- Chaque mutation et décision de politique écrit un événement d'audit chaîné par hachage (G-11).
- Les erreurs utilisent l'enveloppe standard avec message_i18n en et fr.
Observabilité
- Alertes sur otelcol_exporter_send_failed_spans, taille de file, spans refusés.
- traceparent W3C propagé, X-Request-Id renvoyé, les spans portent eai.tenant_id, eai.project, eai.agent_id, eai.run_id.
Unités FinOps
- L'échantillonnage en queue garde 100 % des erreurs et traces lentes, le trafic normal au ratio configuré pour maîtriser le coût de stockage.
Modes de défaillance et résilience
- Backend d'export indisponible -> file persistante sur disque, reprise avec backoff.
Adoption autonome
Un client peut diriger son collecteur existant vers les exportateurs de la plateforme ou réutiliser seul le chart du collecteur.
Tests d'acceptation
- Un span portant un attribut e-mail est exporté avec la valeur masquée.
- Arrêter ClickHouse 5 minutes ne perd aucun span après reprise.