Cloudflare Workers
Debugging
Logs
Workers Tail
Observabilidade

Workers : débogage, journaux et Workers Tail – observabilité en périphérie sans serveur de journaux

Il n'y a pas de processus persistant, il n'y a pas de système de fichiers et console.log ne va nulle part sans une session de fin active - le débogage de Workers nécessite un modèle mental différent.

Workers : débogage, journaux et Workers Tail – observabilité en périphérie sans serveur de journaux

La première fois qu'un ingénieur met un console.log sur un Worker de production et ne voit rien apparaître nulle part, son instinct est de soupçonner un bug dans le déploiement. Le journal disparaît tout simplement. Il n'y a pas de serveur d'applications avec une sortie standard persistante, il n'y a pas de fichier journal sur le disque, il n'y a pas de processus qui accumule les résultats entre les invocations. Chaque exécution de Worker se produit dans un isolat V8 qui naît, traite la demande et disparaît, ne laissant aucune trace à moins que vous ne la capturiez activement. Comprendre ce modèle est la condition préalable à toute stratégie d’observabilité qui fonctionne véritablement en périphérie.

Wrangler Tail : qu'est-ce que c'est et ce que ce n'est pas

wrangler tail ouvre une connexion streaming à l'infrastructure Cloudflare et retransmet en temps réel les événements de vos invocations Workers : métadonnées de chaque requête (méthode, URL, statut de réponse, durée CPU, pays d'origine), l'intégralité de la sortie de console.log et console.error, les exceptions non capturées avec la trace de pile, et le résultat de waitUntil() une fois terminé.

Ce que wrangler tail ne fait pas : persister. Lorsque vous fermez la session, les événements qui ne sont pas encore arrivés sont perdus. Les événements survenus avant l’ouverture de la session n’existent pas non plus pour vous. wrangler tail est un outil d'investigation en direct, utile pour reproduire un problème tel que vous l'observez, inutile pour reconstituer ce qui s'est passé il y a une heure.

Vous pouvez filtrer la sortie avec --filter-status 500 pour voir uniquement les erreurs, ou --filter-sampling-rate 0.1 pour échantillonner 10 % du trafic et ne pas être inondé sous une charge élevée. Dans les services avec des centaines de requêtes par seconde, la queue non filtrée rend rapidement le terminal illisible.

Le piège des exceptions silencieuses

Il existe un comportement d'exécution qui surprend les ingénieurs expérimentés : un Worker peut fournir une réponse de 200 au client tout en ayant levé une exception - à condition que l'exception ait été levée après l'envoi du Response.

Le scénario concret : vous appelez ctx.waitUntil(minhaFuncaoAssincrona()) pour faire un travail de fond après la réponse. Si minhaFuncaoAssincrona est lancé, le client en a déjà reçu 200 et est content. L'exception apparaît dans wrangler tail comme un événement d'erreur associé à la requête, mais ne modifie pas l'état HTTP vu par le client. Sans la queue ouverte, l'erreur n'est jamais visible.

Il en va de même pour toute promesse que vous ne faites pas à l'intérieur du gestionnaire. Si vous lancez un fetch() sans attente et sans gestion des erreurs, et qu'il rejette, le rejet non capturé apparaît dans la queue mais n'affecte pas la réponse reçue par le client. Dans un environnement local avec wrangler dev, ce comportement peut être différent : les avertissements sont plus visibles. En production, c’est le silence total.

La défense est systématique : chaque gestionnaire doit avoir un try/catch au niveau le plus élevé qui capture, se connecte avec console.error et renvoie un HTTP 500 explicite. Chaque promesse transmise à waitUntil() doit avoir une gestion des erreurs interne. Non pas parce que le moteur d’exécution se souviendra de vous – ce ne sera pas le cas.

développeur wrangler local contre --remote

wrangler dev sans indicateurs exécute un serveur local utilisant Miniflare — une implémentation Node.js du runtime Workers. Pour la plupart des cas de développement, cela est suffisant : les liaisons KV, D1, R2 et Queue fonctionnent avec des implémentations locales en mémoire ou SQLite, et la boucle de rétroaction est immédiate sans impliquer le réseau Cloudflare.

wrangler dev --remote est différent : il envoie le Worker vers la véritable infrastructure Cloudflare et achemine les demandes de développement via la périphérie réelle. Cela est nécessaire lorsque vous devez tester des comportements que Miniflare ne peut pas simuler fidèlement : des objets durables en production avec un état réel, des comportements de mise en cache CDN ou des fonctionnalités d'exécution que la version actuelle de Miniflare n'a pas encore implémentées.

Le compromis est évident : --remote nécessite une authentification [40, a une latence réseau et toutes les opérations d'écriture sur KV ou D1 vont vers les ressources réelles (sauf si vous configurez des espaces de noms/banques de transfert séparés, ce qui devrait être standard). L'utilisation de --remote sans isolation de l'environnement de préparation est le chemin le plus court pour corrompre les données de production pendant le développement.

Logpush : de la queue éphémère à la rétention réelle

Pour tout service qui doit reconstruire ce qui s'est passé après coup (audit, débogage post-mortem, analyse des modèles d'erreurs), wrangler tail est insuffisant. Logpush résout ce problème en exportant les événements Workers vers une destination de stockage configurée.

Les destinations prises en charge incluent R2 (le propre stockage de Cloudflare, à 0,05 $ par million de lignes exportées), S3, Datadog, Splunk et quelques autres. La configuration se fait via un tableau de bord ou une API : vous choisissez l'ensemble de données (workers-trace-events), la destination et les champs que vous souhaitez exporter — timestamp, event.request.url, event.response.status, event.exceptions, event.logs (qui inclut la sortie de console.log).

La chose importante à propos du champ event.logs : il capture ce que vous avez transmis à console.log, mais sous forme de texte sérialisé. Si vous avez enregistré un objet JavaScript complexe, ce qui arrive dans Logpush est la représentation sous forme de chaîne de cet objet, et non du JSON structuré. Pour les journaux qui doivent être analysés et filtrés à la destination (pour créer des alertes dans Datadog ou des requêtes dans Splunk), sérialisez explicitement en JSON avant la journalisation : console.log(JSON.stringify({ level: 'error', message, requestId, stack })). Logpush délivre la chaîne ; la cible analyse le JSON.

Ce qu'il faut surveiller en production — et ce que le runtime ne fournit pas

Les travailleurs n’émettent pas nativement d’étendues de traçage distribuées. Il n'y a pas d'intégration automatique avec OpenTelemetry, il n'y a pas de propagation de contexte de trace entre sous-requêtes sans implémentation manuelle. Si un travailleur appelle trois services via fetch() et que l'un d'eux prend 800 ms, wrangler tail affiche la durée totale mais ne détaille pas où le temps a été passé. Pour avoir cette visibilité, vous le chronométrez manuellement : const t0 = Date.now() avant le fetch, Date.now() - t0 après, et enregistrez le résultat structuré avec le nom du service.

Cloudflare a acquis Baselime et intègre ses capacités sous le nom de Cloudflare Observability : analyse des journaux et des métriques avec plus d'ergonomie que la queue manuelle, mais un véritable traçage distribué nécessite toujours une instrumentation dans le code ou un SDK qui propage traceparent à travers les sous-requêtes.

Les métriques les plus utiles pour détecter une dégradation avant que le client ne s'en aperçoive : répartition des centiles de durée du processeur (p50, p95, p99), taux d'erreur segmenté par itinéraire et nombre de sous-requêtes par appel. Aucun n'est gratuit depuis le runtime : ils doivent être construits, exportés via Logpush et transformés en alertes à destination. La différence entre un service que vous exploitez en toute confiance et un service que vous craignez de mettre en production réside presque toujours dans la qualité des instruments que vous avez construits avant le premier incident.

A lire aussi

-Cloudflare Workers en production : qu'est-ce qui change après hello world