Quelle que soit la plateforme que vous utilisez, la journalisation est souvent indispensable au traitement des mégadonnées, aux statistiques, aux audits, aux rapports clients et aux transactions, ainsi qu’au débogage des communications client-serveur et des éventuels problèmes.
Dans cet article, nous abordons le rôle de la journalisation dans le débogage, où elle constitue l’outil par excellence pour identifier les différents problèmes si fréquents dans les communications sur Internet.

La journalisation des communications entre le client et le serveur web facilite grandement le diagnostic des problèmes potentiels liés à la version du navigateur, au réseau du client et aux fichiers consultés. Mais cela ne s’arrête pas là. Les possibilités de journalisation sont infinies et dépendent entièrement de votre plateforme et de vos besoins.
Architecture de journalisation de NGINX
Lorsque vous utilisez un proxy inverse, un répartiteur de charge ou un réseau de diffusion de contenu (CDN), vous ajoutez un nœud supplémentaire au flux de communication entre le client et le serveur. Un serveur intermédiaire qui manipule les données, tel qu’un proxy inverse, entraîne souvent des problèmes inattendus.
En tant que proxy inverse, NGINX transforme la connexion entre le client et le serveur web (ou un autre serveur d’applications) en deux connexions distinctes : il met fin à la connexion provenant du client et en crée une nouvelle vers le serveur. Cette « séparation » en deux connexions crée également deux contextes distincts pour la journalisation, que NGINX prend en charge de manière quelque peu différente.
- Pour le trafic entre le client et le proxy inverse, NGINX fournit à la fois un journal des erreurs et un journal des accès, qui consigne les événements de traitement et les actions qui ne sont pas des erreurs. Vous activez le journal des erreurs à l’aide de la directive
error_log, et pouvez définir le niveau de gravité des erreurs à consigner. Vous activez le journal des accès à l’aide de la directiveaccess_log. La directivelog_formatassociée vous permet de personnaliser le type d’informations incluses dans les journaux ainsi que le format des entrées. Vous pouvez écrire les journaux dans un fichier, les envoyer à syslog, ou faire les deux. - Pour le trafic entre le proxy inverse et le serveur web ou applicatif (que NGINX appelle un « serveur en amont »), NGINX prend en charge le journal des erreurs. En revanche, il ne prend pas en charge la journalisation des accès pour ce trafic. Le seul moyen de consulter les événements autres que les erreurs entre le serveur proxy et un serveur en amont consiste à définir le niveau de gravité du journal des erreurs sur
debug. L’inconvénient de ce réglage est qu’il entraîne la journalisation d’énormes quantités de données. Cela ralentit le traitement des requêtes et génère des fichiers très volumineux qui peuvent rapidement saturer l’espace de stockage. (Notez que vous devez également recompiler NGINX avec l’argument--with-debugde la commandeconfigure, car la prise en charge du débogage n’est pas activée par défaut.)
Notre solution de journalisation des serveurs en amont
En tant que fournisseur de CDN, nous rencontrons souvent des serveurs en amont qui ne communiquent pas correctement avec nos serveurs proxy inverses et nos clients. Les messages de niveau debug du journal d’erreurs ne fournissent pas toujours les informations dont nous avons besoin pour résoudre un problème lié au serveur en amont.
La solution s’est rapidement imposée : générer un journal d’accès aux serveurs en amont en ajoutant une fonction qui recueille uniquement les informations essentielles issues des échanges entre le proxy inverse et les serveurs en amont.

L’idée générale est de faire en sorte que NGINX appelle notre fonction chaque fois qu’une requête est envoyée à un serveur en amont. Cela nous permet de programmer toute la logique liée à la journalisation des échanges avec le serveur en amont directement dans la fonction.
Le module standard « ngx_http_upstream_module » gère les requêtes adressées aux serveurs en amont, et nous avons besoin qu’il appelle la fonction pour nous. Comme le module ne prend actuellement pas en charge cette fonctionnalité, nous l’avons modifié afin d’activer le rappel lorsque cela est nécessaire.
La journalisation elle-même est gérée dans un module distinct que nous avons développé et qui utilise la fonctionnalité de rappel de journalisation que nous avons ajoutée au module upstream modifié. Le nouveau module définit une nouvelle directive upstream_log permettant de configurer la fonctionnalité de journalisation. Cette directive utilise le même analyseur syntaxique que la directive access_log ; les données peuvent donc être écrites dans un fichier ou envoyées à un serveur syslog via un socket.
Lorsque NGINX lit la directive « upstream_log » dans le fichier nginx.conf au démarrage, deux fonctions sont appelées :
ngx_http_upstream_log_set_log, qui analyse la directive et prépare la structure du journal elle-même (ngx_log_t) en utilisantngx_log_set_logen internengx_http_upstream_log_init(lors d’une étape de post-configuration), qui enregistre notre fonction principale de journalisation auprès du module upstream
Ainsi, lorsqu’une requête doit être transmise à un serveur en amont, tout est prêt. Le module upstream établit une connexion avec le serveur en amont, et notre correctif veille à ce que la fonction de journalisation soit appelée afin de consigner les détails de la requête.
Le format des journaux est codé en dur dans le module upstream. Nous pouvons toujours ajouter la prise en charge de la configuration à l’aide de la directive log_format, mais ce n’est pas nécessaire dans notre cas d’utilisation.
Valeurs consignées provenant du serveur en amont
La fonction de journalisation est appelée juste après la fermeture de la connexion au serveur en amont. Son argument est un pointeur vers une requête en cours de traitement (la structure « ngx_http_ request_t »), ce qui permet à la fonction d’accéder à toutes les données de la structure et de les consigner. Le champ « upstream » (pointeur vers ngx_http_upstream_t) présente un intérêt particulier, car il contient des données sur la requête envoyée au serveur en amont. Nous nous intéressons tout particulièrement aux éléments suivants :
- Le code d’état de la réponse du serveur d’origine
- La durée de la requête
- La valeur d’un en-tête HTTP dans la réponse ou de l’en-tête Host
L’accès à l’intégralité de la structure de la requête confère au module sa flexibilité, car il permet de journaliser une grande variété d’informations.
Problèmes rencontrés
Nous avons initialement implémenté cette fonctionnalité dans ngx_http_core_module. Cela convenait pour un prototype, mais ce n’était pas une solution très propre, car elle risquait de compliquer les futures mises à jour et modifications. Nous avons finalement isolé la fonction de journalisation des serveurs en amont dans un module autonome, comme décrit dans Notre solution de journalisation des serveurs en amont.
Bien sûr, la mise en œuvre a posé quelques problèmes. En particulier, nous avons parfois mal manipulé les chaînes ngx_str_t, par exemple en utilisant la fonction sprintf de la bibliothèque C au lieu de ngx_snprintf. Cela peut entraîner l’écriture de données indéfinies dans le journal des serveurs en amont, voire une erreur de segmentation dans le thread de travail. Ces problèmes ont été résolus après des opérations approfondies de débogage et de test à l’aide d’outils tels que Valgrind et AddressSanitizer.
Fonctionnalités de NGINX utilisées dans CDN77
La principale raison pour laquelle CDN77 utilise NGINX réside dans ses capacités de mise en cache. Le serveur CDN est un nœud placé entre le client et le serveur web (serveur en amont) : il transmet les requêtes du client et demande les fichiers appropriés au serveur en amont. Une fois le fichier mis en cache, il est transmis aux autres utilisateurs qui demandent le même fichier depuis le même emplacement.
La « diffusion locale de fichiers » est l’une des fonctionnalités que nous utilisons pour permettre à NGINX de fournir un fichier depuis le disque du serveur lorsqu’il reçoit une requête.
Certaines fonctionnalités et configurations supplémentaires sont nécessaires pour sécuriser la mise en cache. Nous utilisons le protocole SSL (TLS 1.3 avec 0‑RTT) ou des jetons sécurisés pouvant être générés pour une adresse IP spécifique afin de protéger correctement le contenu.
Parmi les autres fonctionnalités que nous utilisons figurent des pages d’erreur personnalisées pour nos clients, l’implémentation par défaut de l’agrafage OCSP de NGINX et FastCGI pour PHP, afin de réduire le nombre de processus PHP nécessaires.
Conclusion
La journalisation des serveurs en amont nous a non seulement aidés, et continue de nous aider, à déboguer divers problèmes, mais elle nous a également offert une excellente occasion d’approfondir notre compréhension des fonctionnalités essentielles de NGINX et a simplifié de nombreux autres projets que nous avons entrepris.
À propos de CDN77
CDN77 améliore et simplifie la diffusion de contenu dans le monde entier. Grâce à plus de 30 centres de données, nous sommes en mesure de mettre efficacement en cache et de diffuser du contenu partout dans le monde. Cela comprend le contenu statique de votre site web, la distribution de logiciels, la vidéo à la demande (VoD) et la diffusion en direct via différents protocoles, tels que HLS ou MPEG‑DASH, à l’aide d’un moteur de streaming dédié.
La prise en main de CDN77 est très simple, rapide et intuitive. Inscrivez-vous pour bénéficier d’un essai gratuit, créez une ressource CDN, puis utilisez l’URL CDN générée ou un enregistrement CNAME personnalisé pour l’intégrer à votre site web ou à votre solution de streaming. Grâce à l’ensemble de ses fonctionnalités, paramètres et solutions personnalisées possibles, CDN77 répond à vos besoins.
À propos de l’auteur
Articles de blog associés

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA
Découvrez les principaux enseignements tirés des réponses à l’enquête annuelle F5 NGINX sur les dernières tendances en matière de technologies cloud natives, de sécurité, d’ingénierie de plateforme et d’IA.
Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?
Lorsque de nouvelles CVE sont signalées, il est facile de ne plus savoir si elles concernent un outil de contrôleur Ingress NGINX particulier, car il existe plusieurs projets. Cet article présente les CVE et explique comment distinguer les différents projets de contrôleurs Ingress afin de dissiper toute confusion.
Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX
Votre API répond-elle aux requêtes en moins de 30 ms ? Si ce n’est pas le cas, il ne s’agit pas d’une API en temps réel offrant la faible latence exigée par la grande majorité des organisations. Mesurez la latence de votre API avec l’outil rtapi de NGINX et découvrez comment NGINX peut l’aider à offrir une réactivité en temps réel.

Un testeur d’expressions régulières pour NGINX et NGINX Plus
Le testeur d’expressions régulières (regex) pour NGINX et NGINX Plus vous évite de tâtonner en vous indiquant si une expression régulière utilisée dans un bloc location ou map correspond aux valeurs comme prévu. Il génère la configuration appropriée et affiche les valeurs des groupes de capture.
Caches partagés avec les clusters de cache NGINX Plus, partie 1
Optimisez la capacité de votre cache web en le répartissant entre plusieurs serveurs de cache web NGINX ou NGINX Plus. Découvrez comment procéder dans cet article.
Introduction aux microservices
Les microservices suscitent actuellement beaucoup d’intérêt. Cet article de blog est le premier d’une série de sept consacrée à la conception, au développement et au déploiement de microservices.