Comment arrêter de réécrire du code pour les logs et les métriques
Imaginez ceci : vous avez une douzaine de microservices Java en production. À un moment donné, l'un d'eux commence à « ramer ». Vous ouvrez les logs, mais il n'y a rien — les messages standard ne suffisent pas pour comprendre à quelle étape exacte la requête se bloque. Histoire familière ? Habituellement, à ce stade, le développeur plonge dans le code, décore les méthodes d'annotations, ajoute des dépendances de tracing, recompile le projet et le redéploie. Et s'il y a des centaines de services écrits sur différents frameworks ?
Dans l'écosystème OpenTelemetry, il existe un projet qui résout ce problème de manière élégante et, ce qui est particulièrement appréciable, presque sans effort. Il s'agit de opentelemetry-java-instrumentation. C'est un agent Java spécial qui peut s'injecter dans votre application « à la volée » et collecter de la télémétrie sans une seule ligne de nouveau code.
Ce qu'est cet agent et pourquoi vous en avez besoin
En essence, c'est un fichier JAR que vous attachez au démarrage de la JVM. Il utilise l'injection dynamique de bytecode. Lorsque votre application charge des classes de bibliothèques populaires (par exemple, Spring, Hibernate, gRPC ou Kafka), l'agent injecte soigneusement de la logique pour créer des spans et collecter des métriques.
C'est une option idéale pour deux scénarios. Premièrement, lorsque vous devez ajouter rapidement de l'observabilité à un projet legacy dont on a peur de toucher. Deuxièmement, lorsque vous voulez standardiser la collecte de données dans toute l'entreprise sans obliger chaque équipe à configurer manuellement le SDK.
Trois fonctionnalités pratiques qui facilitent la vie
De la magie automatique prête à l'emploi
L'agent prend en charge un nombre considérable de bibliothèques. Si vous utilisez une stack standard comme Spring Boot avec PostgreSQL et Redis, vous n'avez rien à configurer du tout. Vous attachez simplement l'agent, et dans votre système de monitoring (par exemple, Jaeger ou Zipkin), vous obtenez un arbre d'appels : de la requête HTTP entrante jusqu'à la requête en base de données et la réponse du cache.
Propagation du contexte dans les logs (MDC)
L'une des choses les plus utiles au quotidien pour le débogage est l'insertion automatique du Trace ID dans les logs. L'agent peut trouver vos loggers (Logback, Log4j2) de lui-même et ajouter l'identifiant de la trace actuelle dans MDC. Maintenant, lorsque vous voyez une erreur dans les logs, vous pouvez simplement copier l'ID et trouver le chemin complet de cette requête à travers tous les services. Plus de devinettes pour savoir quel utilisateur a déclenché ce NullPointerException.
Configuration flexible sans recompilation
Tous les paramètres — où envoyer les données, la fréquence d'échantillonnage, les attributs à ajouter aux spans — sont passés via des variables d'environnement ou des propriétés système Java. Cela signifie que le même binaire de votre application peut envoyer des données vers la console en dev et vers un cluster OpenTelemetry Collector puissant en production.
Comment mettre tout cela en route
Le processus de configuration est étonnamment simple. Tout d'abord, téléchargez la dernière version de opentelemetry-javaagent.jar depuis la page des releases. Ensuite, ajoutez un seul flag à la commande de lancement de votre application :
java -javaagent:path/to/opentelemetry-javaagent.jar \
-Dotel.resource.attributes=service.name=my-cool-service \
-jar myapp.jar
Par défaut, l'agent s'attend à ce qu'un collecteur acceptant les données via le protocole OTLP soit en cours d'exécution quelque part à localhost:4318. Si vous voulez utiliser autre chose, par exemple Zipkin, vous le changez avec un seul flag : -Dotel.traces.exporter=zipkin.
Sous le capot et extensibilité
Il est intéressant de noter que le projet ne vous limite pas à la simple « automatisation ». Si les capacités intégrées ne suffisent pas, vous pouvez utiliser le mécanisme d'extensions. Vous pouvez écrire votre propre fichier JAR qui ajoutera des règles d'instrumentation personnalisées ou des attributs spécifiques à l'entreprise.
Pour ceux qui ne font pas du tout confiance à la magie des agents, le projet fournit également les mêmes bibliothèques d'instrumentation séparément. Vous pouvez les ajouter comme dépendances régulières et les configurer manuellement, mais vous devrez alors accepter la nécessité de modifier le code.
Cela vaut-il la peine de l'utiliser
Je rencontre souvent l'opinion que les agents Java sont une « boîte noire » qui peut ralentir une application. Il y a une part de vérité : l'agent consomme des ressources pour la transformation du bytecode au démarrage et ajoute une petite surcharge lors de l'exécution des requêtes. Cependant, dans 95 % des cas, cette surcharge est négligeable par rapport à l'avantage que vous obtenez lorsque vous chassez les bugs dans un système distribué.
À qui conviendra-t-il particulièrement bien :
- Les équipes qui passent aux microservices et qui s'étouffent sans le tracing.
- Le support qui a besoin de comprendre « hier » pourquoi le vieux monolithe est lent.
- Les architectes qui mettent en place une norme de monitoring unifiée.
Si vous n'avez pas encore essayé OpenTelemetry dans vos projets Java, cet agent est le moyen le plus rapide et le moins douloureux de commencer. Essayez simplement de l'exécuter localement et voyez combien de choses intéressantes vous apprendrez sur le comportement de votre code sous charge.
Projets similaires