Introduction à l'Instrumentation OpenTelemetry
L'instrumentation est le processus d'ajout de code à une application pour collecter des données de télémétrie (traces, métriques, logs). OpenTelemetry offre deux approches principales pour instrumenter vos applications : l'instrumentation automatique et l'instrumentation manuelle. Le choix entre ces deux méthodes dépend de vos besoins spécifiques, du niveau de contrôle souhaité et de la complexité de votre application.
1. Instrumentation Automatique (Auto-Instrumentation)
L'instrumentation automatique permet de collecter des données de télémétrie sans modifier le code source de votre application. Elle s'appuie généralement sur des agents ou des bibliothèques qui s'injectent dans le runtime de l'application et instrumentent automatiquement les bibliothèques et frameworks populaires.
1.1. Comment ça marche ?
Des agents spécifiques à chaque langage (par exemple, un agent Java, un hook Python) surveillent l'exécution de votre application. Lorsqu'ils détectent l'utilisation d'une bibliothèque supportée (comme un client HTTP, une base de données, un framework web), ils injectent automatiquement des points d'instrumentation pour générer des spans, des métriques ou des logs.
1.2. Avantages et Inconvénients
- Avantages :
- Facilité de mise en œuvre : Souvent une simple ligne de commande ou une variable d'environnement suffit.
- Gain de temps : Pas de modification du code source, déploiement rapide.
- Couverture large : Instrumente automatiquement de nombreuses bibliothèques et frameworks courants.
- Mises à jour faciles : L'agent peut être mis à jour indépendamment de l'application.
- Inconvénients :
- Moins de contrôle : Difficile d'instrumenter la logique métier spécifique ou de personnaliser finement les spans.
- Overhead potentiel : Peut introduire un léger overhead si l'agent instrumente trop de choses non pertinentes.
- Dépendance à l'agent : Nécessite de maintenir l'agent à jour et compatible avec votre environnement.
1.3. Exemples de Configuration
L'instrumentation automatique est généralement activée via des variables d'environnement ou des arguments de ligne de commande.
- Java Agent
Pour une application Java, vous téléchargez l'agent OpenTelemetry et le lancez avec votre JVM :
java -javaagent:/path/to/opentelemetry-javaagent.jar \n -jar my-application.jarVous pouvez configurer l'exportateur et d'autres paramètres via des variables d'environnement :
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317" export OTEL_SERVICE_NAME="my-java-app" java -javaagent:/path/to/opentelemetry-javaagent.jar -jar my-application.jar - Python Auto-Instrumentation
Pour Python, vous utilisez le script
opentelemetry-instrument:opentelemetry-instrument python my_app.pyOu en définissant des variables d'environnement pour l'exportateur :
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317" export OTEL_SERVICE_NAME="my-python-app" opentelemetry-instrument python my_app.py - Node.js Auto-Instrumentation
Pour une application Node.js, vous pouvez précharger le SDK OpenTelemetry en utilisant l'option
-r(ou--require) de Node :node -r @opentelemetry/sdk-node/register my-app.jsLa configuration se fait également via des variables d'environnement :
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317" export OTEL_SERVICE_NAME="my-nodejs-app" node -r @opentelemetry/sdk-node/register my-app.js - Go Auto-Instrumentation (via eBPF)
L'auto-instrumentation pour Go est moins courante en raison de sa nature compilée, mais elle est possible grâce à eBPF. Elle permet d'instrumenter des binaires Go sans aucune modification de code. C'est une technologie puissante mais encore en développement.
Une fois l'agent d'instrumentation Go installé, vous le lancez en pointant vers votre binaire applicatif :
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317" export OTEL_SERVICE_NAME="my-go-app" # L'agent Go prend en charge le binaire de votre application /path/to/opentelemetry-go-instrumentation-launcher --service_name my-go-app /path/to/your/app-binaryNote : Cette méthode est encore considérée comme expérimentale et peut ne pas couvrir toutes les bibliothèques. L'approche hybride (auto + manuelle) reste souvent la plus fiable pour Go.
2. Instrumentation Manuelle (SDK)
L'instrumentation manuelle implique l'ajout direct d'appels à l'API et au SDK OpenTelemetry dans le code source de votre application. Cela vous donne un contrôle total sur les données de télémétrie collectées.
2.1. Comment ça marche ?
Le développeur utilise les bibliothèques OpenTelemetry pour créer explicitement des spans, enregistrer des métriques, ajouter des attributs personnalisés et propager le contexte de trace à travers les limites de processus.
2.2. Avantages et Inconvénients
- Avantages :
- Contrôle total : Instrumentez précisément la logique métier, ajoutez des attributs spécifiques et définissez des relations de span complexes.
- Granularité : Capturez exactement les informations dont vous avez besoin pour le diagnostic.
- Flexibilité : Adaptez l'instrumentation à des cas d'usage très spécifiques non couverts par l'auto-instrumentation.
- Inconvénients :
- Modification du code : Nécessite des changements dans le code source de l'application.
- Effort de développement : Plus de travail initial et de maintenance.
- Risque d'erreurs : Une instrumentation incorrecte peut entraîner des traces incomplètes ou des problèmes de performance.
2.3. Exemples de Configuration
L'instrumentation manuelle nécessite l'initialisation du SDK OpenTelemetry dans votre application.
- Java SDK
Exemple d'initialisation du SDK et de création d'une span en Java :
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; public class ManualInstrumentationExample { private static OpenTelemetry openTelemetry; public static void initOpenTelemetry() { // Configure l'exportateur OTLP (gRPC par défaut) OtlpGrpcSpanExporter spanExporter = OtlpGrpcSpanExporter.builder() .setEndpoint("http://localhost:4317") .build(); // Configure le processeur de span pour envoyer les spans à l'exportateur SdkTracerProvider tracerProvider = SdkTracerProvider.builder() .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) .build(); // Initialise l'instance globale d'OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(tracerProvider) .buildAndRegisterGlobal(); // Assurez-vous de fermer le provider à l'arrêt de l'application Runtime.getRuntime().addShutdownHook(new Thread(tracerProvider::close)); } public static void main(String[] args) { initOpenTelemetry(); Tracer tracer = openTelemetry.getTracer("my-manual-instrumentation-library"); Span span = tracer.spanBuilder("myOperation").startSpan(); try (var scope = span.makeCurrent()) { span.setAttribute("my.custom.attribute", "value"); System.out.println("Executing my operation..."); // ... votre logique métier ... } finally { span.end(); } } } - Python SDK
Exemple d'initialisation du SDK et de création d'une span en Python :
from opentelemetry import trace from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OtlpSpanExporter # Configure le Resource pour le service resource = Resource.create({ "service.name": "my-python-manual-app", "service.version": "1.0.0" }) # Configure le TracerProvider provider = TracerProvider(resource=resource) # Configure l'exportateur OTLP otlp_exporter = OtlpSpanExporter(endpoint="http://localhost:4317") # Ajoute le processeur de span au provider provider.add_span_processor(BatchSpanProcessor(otlp_exporter)) # Définit le provider comme global trace.set_tracer_provider(provider) # Obtient un tracer tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("myOperation") as span: span.set_attribute("my.custom.attribute", "another_value") print("Executing my Python operation...") # ... votre logique métier ...
3. L'importance des Attributs de Ressource avec OTEL_RESOURCE_ATTRIBUTES
Les attributs de ressource décrivent l'entité qui produit les données de télémétrie (par exemple, le service, l'application, l'hôte, le conteneur, le cloud). Ils sont cruciaux pour corréler les données et fournir un contexte global à toutes les traces, métriques et logs émises par cette ressource.
3.1. Qu'est-ce que OTEL_RESOURCE_ATTRIBUTES ?
OTEL_RESOURCE_ATTRIBUTES est une variable d'environnement standardisée par OpenTelemetry qui permet de définir des attributs de ressource pour votre application. Ces attributs sont ajoutés à toutes les données de télémétrie générées par l'application, qu'elle soit instrumentée automatiquement ou manuellement.
Elle prend une liste de paires clé=valeur séparées par des virgules. Il est fortement recommandé d'utiliser les Conventions Sémantiques (SemConv) pour ces attributs.
3.2. Pourquoi l'utiliser ?
- Contexte global : Fournit des informations essentielles sur l'environnement d'exécution (nom du service, version, environnement de déploiement, identifiants de pod/conteneur, région cloud, etc.).
- Corrélation facilitée : Permet aux outils d'observabilité de regrouper et de filtrer les données par service, environnement ou infrastructure.
- Cohérence : Assure que toutes les données de télémétrie d'une même instance de service partagent le même contexte de ressource.
- Indépendance de l'instrumentation : Peut être configuré sans modifier le code de l'application, même avec l'instrumentation manuelle, pour ajouter des attributs de ressource génériques.
3.3. Exemple d'Utilisation
Définir cette variable d'environnement avant de lancer votre application :
export OTEL_RESOURCE_ATTRIBUTES="service.name=mon-service-web,service.version=1.2.3,deployment.environment=production,host.name=web-server-01"
# Pour une application Java avec auto-instrumentation
java -javaagent:/path/to/opentelemetry-javaagent.jar -jar my-application.jar
# Pour une application Python avec auto-instrumentation
opentelemetry-instrument python my_app.py
# Pour une application avec instrumentation manuelle (les attributs seront fusionnés avec ceux définis dans le code)
python my_manual_app.py
Notez que si des attributs de ressource sont définis à la fois via OTEL_RESOURCE_ATTRIBUTES et dans le code (SDK), ceux définis dans le code peuvent potentiellement écraser ou compléter ceux de la variable d'environnement, selon l'implémentation du SDK.
Conclusion : Quand choisir quelle approche ?
- Utilisez l'instrumentation automatique pour un démarrage rapide et une couverture de base des bibliothèques et frameworks standards. C'est excellent pour obtenir une visibilité rapide sans effort de développement.
- Adoptez l'instrumentation manuelle lorsque vous avez besoin d'une visibilité approfondie sur votre logique métier spécifique, des attributs personnalisés critiques ou des relations de span complexes.
- Dans la plupart des cas, une approche hybride est la plus efficace : utilisez l'auto-instrumentation pour la couverture de base et complétez-la avec de l'instrumentation manuelle pour les points critiques de votre application.
- Utilisez toujours
OTEL_RESOURCE_ATTRIBUTESpour fournir un contexte de ressource cohérent et essentiel à toutes vos données de télémétrie.