Référence ingestion
Format du payload OTLP/JSON, codes d'erreur HTTP, comportement de retry attendu et limites de l'endpoint POST /v1/logs.
Cette page documente le contrat HTTP de https://api.monitoring.crahe-arthur.com/v1/logs en détail.
Pour un guide pas-à-pas avec exemples par stack, voir
Premiers pas.
Endpoint
POST https://api.monitoring.crahe-arthur.com/v1/logs — authentification par clé d'API
(header Authorization: Bearer lyn_live_xxx, scope write:logs).
L'OTel Collector et la plupart des transports/appenders SDK pointent vers la
racine https://api.lyncea.io et ajoutent eux-mêmes /v1/logs. Quand
vous configurez un SDK OTel à la main (OTLPLogExporter côté Node ou Python
par exemple), écrivez le chemin complet https://api.lyncea.io/v1/logs —
ces exporters n'ajoutent pas le suffixe.
Format du payload
Deux content-types acceptés :
| Content-Type | Usage |
|---|---|
application/x-protobuf | Format binaire ExportLogsServiceRequest. Par défaut pour les SDK OTel et Collector. |
application/json | Version JSON du même schéma. Pratique pour les scripts et les bridges sans protobuf. |
Content-Encoding: gzip et deflate sont décodés automatiquement. La limite
de 16 MiB s'applique après décompression — un ratio extrême déclenche un
413 plutôt qu'une consommation mémoire incontrôlée.
Exemple minimal valide (JSON)
{
"resourceLogs": [
{
"resource": {
"attributes": [
{ "key": "service.name", "value": { "stringValue": "checkout-api" } },
{ "key": "deployment.environment", "value": { "stringValue": "prod" } }
]
},
"scopeLogs": [
{
"scope": { "name": "lyncea-quickstart" },
"logRecords": [
{
"timeUnixNano": "1717171717000000000",
"severityNumber": 9,
"severityText": "INFO",
"body": { "stringValue": "user logged in" },
"attributes": [
{ "key": "user.id", "value": { "stringValue": "42" } }
]
}
]
}
]
}
]
}Contraintes :
resourceLogs[]ne peut pas être vide (400sinon).timeUnixNanoest une chaîne de 19 chiffres (nanosecondes Unix) — ne pas l'envoyer en number, JavaScript perd la précision au-delà de2^53.- Tout le reste est optionnel mais recommandé pour exploiter pleinement la recherche de logs.
Sévérité
OTel utilise severityNumber (entier 1–24). Mapping habituel à connaître si
vous écrivez le payload à la main — les bridges officiels font ce mapping
pour vous :
| Niveau | severityNumber | severityText |
|---|---|---|
| TRACE | 1 | TRACE |
| DEBUG | 5 | DEBUG |
| INFO | 9 | INFO |
| WARN | 13 | WARN |
| ERROR | 17 | ERROR |
| FATAL | 21 | FATAL |
Les valeurs intermédiaires (DEBUG2 = 6, INFO3 = 11, etc.) sont autorisées
par la spec et passent sans transformation.
Attributs OTel exploités
Lyncea lit un seul attribut côté ingestion : deployment.environment
(resource), pour appliquer l'allowlist du projet — voir
Environnements de projet.
Tous les autres attributs (service.name, service.version, trace_id,
attributs de logRecord custom…) sont conservés tels quels dans le
payload et indexables côté recherche via GET /api/v1/logs.
Aucun attribut n'est silencieusement supprimé.
Réponses HTTP
| Statut | Quand | Body | Retry-After |
|---|---|---|---|
200 OK | Lot accepté à l'edge | ExportLogsServiceResponse (vide en v1) | — |
400 Bad Request | JSON malformé, resourceLogs vide, Content-Type non géré | Status { code: 3, message } | — |
401 Unauthorized | Clé d'API absente ou invalide | Status { code: 16, message } | — |
403 Forbidden | Scope write:logs manquant, ou tenant suspendu | Status { code: 7, message } | — |
413 Payload Too Large | Body brut > 4 MiB ou décompressé > 16 MiB | Status { code: 3, message } | — |
429 Too Many Requests | Quota EPS dépassé (par clé ou par tenant — voir Plans) | Status { code: 8, message } | secondes |
503 Service Unavailable | Pipeline Lyncea momentanément indisponible (incident côté ingestion) | Status { code: 14, message } | 5 |
Le body d'erreur est toujours le proto gRPC Status { code, message },
encodé dans le même content-type que la requête (JSON ou protobuf).
Retry & backoff
Côté client, appliquer la convention OTel standard :
- Retry exponentiel sur
429et503uniquement, en respectantRetry-Afterquand il est présent. - Pas de retry sur les autres
4xx— ils signalent une erreur de configuration (clé invalide, scope manquant, payload trop gros, JSON malformé) qu'un retry ne corrigera pas. - Buffer en mémoire côté client pour absorber les coupures brèves.
Les SDK OTel officiels et l'OTel Collector implémentent ce comportement
nativement (queue interne + retry + circuit breaker) — vous n'avez rien à
coder. Si vous écrivez votre propre client, partez d'un backoff
exponentiel 1s → 2s → 4s → 8s → 16s avec jitter et un cap raisonnable.
200 OK signifie « accepté pour traitement », pas « consultable dans
l'interface ». La pipeline est asynchrone (Kafka → ClickHouse) — comptez
quelques secondes en régime nominal avant qu'un log apparaisse dans
GET /api/v1/logs ou dans le
live tail.
Limites
| Paramètre | Valeur par défaut |
|---|---|
| Body brut maximum | 4 MiB |
| Body après décompression maximum | 16 MiB |
| Quota d'événements par seconde (EPS) | dépend du plan — voir Plans |
| Granularité du rate-limit | par clé d'API et par tenant agrégé |
Le rate-limit est un token-bucket dont la capacité et la vitesse de refill suivent l'EPS du plan. Une rafale peut consommer jusqu'à la capacité complète avant de rate-limiter.
Voir aussi
- Premiers pas — créer un projet, générer une clé et envoyer son premier log.
- Environnements de projet — allowlist
deployment.environmentet préfixes de clé. - Plans — quotas EPS et rétention par offre.