Skip to content

Observabilite et logging

Le service produit un document JSON par ligne sur stdout. Ce format est le contrat d'ingestion du flux OpenObserve service_base = 'tvcast-intercopartnerapi'.

Champs communs

ChampDescription
timestampHorodatage ISO 8601 UTC
levelfatal, error, warn, info, debug ou trace
severity_numberNiveau Pino numerique
serviceNom runtime du service
service_baseIdentifiant stable OpenObserve
service_versionVersion de l'application
deployment_environmentEnvironnement d'execution
log_schema_versionVersion du contrat de log
eventNom stable et requetable de l'evenement
request_idIdentifiant de correlation HTTP
componentComposant non vide obligatoire, present exactement une fois a la racine de tout evenement
error_codeCode stable et requetable de l'echec ; ne pas utiliser msg comme identifiant
http_routePatron de route Fastify, par exemple /v1/areas/:areaExternalId/
http_pathChemin concret appele, sans query string, par exemple /v1/areas/area-123/
client_addressAdresse cliente resolue depuis la chaine de proxies de confiance
client_address_chainAdresses validees, de la plus proche a la plus distante
client_socket_addressAdresse du pair TCP direct, generalement Traefik dans Dokploy

Les query strings ne sont jamais incluses dans http_path, car elles peuvent contenir des secrets. Les secrets connus sont remplaces par [Redacted]. Une erreur est stockee dans l'objet err; sa stack reste dans le document JSON et ne cree jamais de lignes brutes supplementaires.

Contrat des evenements

Les noms suivent domaine.action.resultat, en minuscules et separes par des points, par exemple partner.auth.failed. Le niveau decrit l'impact :

NiveauUsage
debugDiagnostic detaille, normalement filtre en production
infoCycle normal du service ou requete reussie
warnEchec attendu ou recuperable, notamment une reponse HTTP 4xx
errorDefaillance technique, appel downstream en echec ou reponse HTTP 5xx
fatalLe service ne peut pas demarrer ou continuer

Les evenements de frontiere HTTP contiennent le contexte reseau complet. Les evenements metier lies a une requete conservent request_id, event, component, error_code et les identifiants metier utiles ; leur correlation avec http.request.completed se fait par request_id, sans recopier les adresses IP. Les evenements globaux, tels que server.started, ne portent que le contexte du service. Les evenements http.request.* utilisent le composant httpLifecycle, les evenements server.* utilisent server, et les rares logs sans contexte plus precis utilisent le fallback application.

Lorsqu'un payload structure ou un message entierement constitue d'un objet JSON contient un component, le logger le promeut au niveau racine sans modifier msg. Un component racine explicite reste toujours prioritaire.

error_code constitue l'identifiant stable utilise dans les requetes et alertes. msg reste une description lisible et err contient l'exception serialisee. Les messages d'erreur variables et le champ historique reason ne doivent pas servir de contrat.

Les headers d'authentification, cookies, tokens, query strings et payloads bruts ne doivent jamais etre journalises. Les diagnostics doivent exposer uniquement des champs explicitement choisis, des identifiants externes non secrets et, si necessaire, des nombres d'elements.

Evenements principaux

EvenementNiveauUsage
http.request.receivedinfoDebut d'une requete HTTP
http.request.completedinfo, warn ou errorFin, statut et duree d'une requete
http.request.failederrorException non geree par une route
facility.lookup.failedwarn ou errorEchec de resolution d'une facility
facility.list.failederrorEchec technique de lecture des facilities accessibles
partner.auth.failederrorDefaillance technique de validation du partenaire
cms.request.starteddebugDiagnostic d'un appel CMS sans URL, filtre ou payload
remote.request.failederrorEchec d'un appel au service de controle distant
server.startedinfoService pret a recevoir du trafic
server.start.failedfatalEchec du demarrage

facility.lookup.failed expose error_code, facility_external_id et downstream_service. Une facility inconnue porte error_code = 'FACILITY_NOT_FOUND'.

Les appels historiques non encore migres conservent temporairement legacy.console.*. Ils restent au niveau debug pour console.log et sont migres par domaine vers des evenements nommes. Aucun nouveau console.* direct n'est autorise hors de l'adaptateur createLegacyConsoleLogger.

Health check des orchestrateurs

Le service expose GET /health sans authentification. Cette route operationnelle est non versionnee : elle reste donc /health, quelle que soit la valeur de APIVER, et n'appartient ni a l'API v0 ni a l'API v1.

Une reponse 200 avec le corps JSON exact {"status":"ok"} indique que Fastify a termine son initialisation et peut traiter des requetes. Ce controle est destine aux orchestrateurs, notamment Dokploy/Docker Swarm, ainsi qu'aux load balancers. Il ne contacte ni Directus, ni le CMS, ni l'API distante, et ne garantit donc pas la disponibilite de ces services externes.

Les appels a /health sont exclus des evenements HTTP ordinaires http.request.received et http.request.completed afin que les sondes periodiques ne polluent pas les logs de production au niveau info. Les autres routes restent journalisees normalement.

La route operationnelle est volontairement exclue des documents OpenAPI partenaires versionnes /docs/openapi-v0.json et /docs/openapi-v1.json.

IP cliente derriere Dokploy

Fastify ignore X-Forwarded-For par defaut. Configurer TRUST_PROXY avec le CIDR du reseau par lequel Traefik joint le conteneur :

env
TRUST_PROXY=10.0.0.0/24

La valeur accepte aussi une liste separee par des virgules ou un nombre de sauts. TRUST_PROXY=true fait confiance a toute la chaine et ne doit etre utilise que si le port applicatif est strictement inaccessible sans passer par Traefik et si chaque proxy remplace les headers X-Forwarded-* recus. Un CIDR ou un nombre de sauts borne evite de faire confiance a une adresse ajoutee par le client. Ces adresses sont destinees a l'observabilite et ne doivent pas servir a une decision d'autorisation.

Requetes OpenObserve

Facilities inconnues :

sql
SELECT timestamp, request_id, facility_external_id, http_route
FROM "default"
WHERE service_base = 'tvcast-intercopartnerapi'
  AND event = 'facility.lookup.failed'
  AND error_code = 'FACILITY_NOT_FOUND'
ORDER BY timestamp DESC;

Erreurs HTTP sur les quinze dernieres minutes :

sql
SELECT timestamp, request_id, http_method, http_route, http_path, client_address,
       http_status_code, duration_ms
FROM "default"
WHERE service_base = 'tvcast-intercopartnerapi'
  AND event = 'http.request.completed'
  AND http_status_code >= 500
ORDER BY timestamp DESC;

Remplacer "default" par le nom du stream configure dans OpenObserve.