Après avoir instrumenté votre application avec Jaeger et envoyé les données de trace à Managed Service for OpenTelemetry, Managed Service for OpenTelemetry commence à surveiller votre application. Vous pouvez consulter diverses données de surveillance, telles que la topologie des applications, les traces, les transactions anormales, les transactions lentes et l'analyse SQL. Cette rubrique décrit comment procéder à une instrumentation manuelle ainsi qu'à une instrumentation automatique à l'aide des composants Spring Cloud et gRPC.
Pour bénéficier des fonctionnalités avancées et des capacités de traçage, nous vous recommandons de connecter votre application à Managed Service for OpenTelemetry via le protocole OpenTelemetry.
Nos guides d'intégration OpenTelemetry détaillés et nos bonnes pratiques vous aident à démarrer avec Managed Service for OpenTelemetry. Pour plus d'informations, consultez la section Connecter une application.
Prérequis
Contexte
Jaeger est un système de traçage distribué open source compatible avec l'API OpenTracing et constitue un projet diplômé de la Cloud Native Computing Foundation (CNCF). Il agrège les données de surveillance en temps réel provenant de divers systèmes hétérogènes. La communauté OpenTracing propose de nombreux composants prenant en charge une variété de frameworks Java. En voici quelques exemples :
Pour envoyer les données de l'application Java à la console Managed Service for OpenTelemetry à l'aide de Jaeger, vous devez d'abord instrumenter l'application. Vous pouvez procéder à une instrumentation manuelle ou utiliser divers plug-ins existants pour une instrumentation automatique. Cette rubrique décrit les trois méthodes d'instrumentation suivantes.
Instrumentation manuelle
Instrumentation à l'aide d'un composant Spring Cloud
Instrumentation à l'aide d'un composant gRPC
Instrumenter une application Java
Avant de pouvoir utiliser Jaeger pour soumettre les données d'une application Java à Managed Service for OpenTelemetry, vous devez instrumenter l'application. Dans cet exemple, l'application est instrumentée manuellement.
Téléchargez le projet de démonstration. Accédez au répertoire manualDemo et exécutez le programme conformément aux instructions du fichier README.md.
-
Ajoutez la dépendance suivante pour les clients Jaeger au fichier pom.xml :
<dependency> <groupId>io.jaegertracing</groupId> <artifactId>jaeger-client</artifactId> <version>0.31.0</version> </dependency> -
Configurez les paramètres d'initialisation et créez un traceur.
Un traceur permet de créer des spans pour enregistrer la durée des opérations distribuées, de transmettre des données entre serveurs en mode pass-through à l'aide de la méthode Extract ou Inject, ou de spécifier la span actuelle. Le traceur contient également des données telles que le point de terminaison utilisé pour l'envoi des données, l'adresse IP locale, le taux d'échantillonnage et le nom du service. Vous pouvez ajuster le taux d'échantillonnage afin de réduire la surcharge liée à l'envoi des données.
RemarqueRemplacez
<endpoint>par le point de terminaison que vous avez obtenu dans la section « Prérequis » de cette rubrique.// Replace manualDemo with your application name. io.jaegertracing.Configuration config = new io.jaegertracing.Configuration("manualDemo"); io.jaegertracing.Configuration.SenderConfiguration sender = new io.jaegertracing.Configuration.SenderConfiguration(); // Replace <endpoint> with the endpoint that you obtained in the "Prerequisites" section of this topic. sender.withEndpoint("<endpoint>"); config.withSampler(new io.jaegertracing.Configuration.SamplerConfiguration().withType("const").withParam(1)); config.withReporter(new io.jaegertracing.Configuration.ReporterConfiguration().withSender(sender).withMaxQueueSize(10000)); // Set resource tags, such as the application version and deployment environment. Map<String, String> map = new HashMap<>(); map.put("service.version", "1.0.0"); map.put("deployment.environment", "test"); config.withTracerTags(map); GlobalTracer.register(config.getTracer()); -
Enregistrez les données de la requête.
Tracer tracer = GlobalTracer.get(); // Create a span. Span span = tracer.buildSpan("parentSpan").withTag("myTag", "spanFirst").start(); tracer.scopeManager().activate(span, false); tracer.activeSpan().setTag("methodName", "testTracing"); // The business logic. secondBiz(); span.finish(); -
Facultatif. Exécutez le code précédent pour créer une span racine afin d'enregistrer l'opération racine d'une requête. Si vous souhaitez enregistrer les opérations précédentes et suivantes d'une requête, spécifiez les informations de contexte.
Tracer tracer = GlobalTracer.get(); Span parentspan = tracer.activeSpan(); Tracer.SpanBuilder spanBuilder = tracer.buildSpan("childSpan").withTag("myTag", "spanSecond"); if (parentspan !=null) { spanBuilder.asChildOf(parentspan).start(); } Span childSpan = spanBuilder.start(); Scope scope = tracer.scopeManager().activate(childSpan); // The statement is executed once when the request starts. // The business logic. The buildSpan function can be executed multiple times. childSpan.finish(); tracer.activeSpan().setTag("methodName", "testCall"); // The statement is executed once when the request ends. scope.close(); -
Facultatif. Pour résoudre efficacement les problèmes, ajoutez des tags personnalisés à une span. Par exemple, ajoutez un tag personnalisé pour vérifier si une erreur s'est produite ou pour enregistrer la valeur renvoyée d'une requête.
tracer.activeSpan().setTag("methodName", "testCall"); -
Dans un système distribué, les requêtes d'appel de procédure distante (RPC) sont envoyées conjointement avec les données de trace. Les données de trace contiennent les valeurs des paramètres TraceId, ParentSpanId, SpanId et Sampled. Appelez la méthode Extract ou Inject pour transmettre les données de trace dans les en-têtes de requête HTTP. La figure suivante illustre l'ensemble du processus.

-
Appelez la méthode Inject sur le client pour spécifier les informations de contexte.
private void attachTraceInfo(Tracer tracer, Span span, final Request request) { tracer.inject(span.context(), Format.Builtin.TEXT_MAP, new TextMap() { @Override public void put(String key, String value) { request.setHeader(key, value); } @Override public Iterator<Map.Entry<String, String>> iterator() { throw new UnsupportedOperationException("TextMapInjectAdapter should only be used with Tracer.inject()"); } }); } -
Appelez la méthode Extract sur le serveur pour extraire les informations de contexte.
protected Span extractTraceInfo(Request request, Tracer tracer) { Tracer.SpanBuilder spanBuilder = tracer.buildSpan("/api/xtrace/test03"); try { SpanContext spanContext = tracer.extract(Format.Builtin.TEXT_MAP, new TextMapExtractAdapter(request.getAttachments())); if (spanContext !=null) { spanBuilder.asChildOf(spanContext); } } catch (Exception e) { spanBuilder.withTag("Error", "extract from request fail, error msg:" + e.getMessage()); } return spanBuilder.start(); }
-
Instrumenter une application Java avec Spring Cloud
Pour envoyer les données de l'application Java à la console Managed Service for OpenTelemetry à l'aide de Jaeger, vous devez d'abord procéder à l'instrumentation. Cet exemple utilise des composants Spring Cloud pour l'instrumentation. Spring Cloud fournit l'instrumentation pour les composants suivants :
@Async, @Scheduled, Executors
Feign, HystrixFeign
Hystrix
JDBC
JMS
Mongo
RabbitMQ
Redis
RxJava
Spring Messaging - Les traces sont envoyées via les canaux de messages.
Spring Web (RestControllers, RestTemplates, WebAsyncTask)
Standard Logging - Les journaux sont ajoutés à la Span actuelle.
WebSocket STOMP
Zuul
Téléchargez le projet de démonstration, accédez au répertoire springMvcDemo/webmvc4-boot et exécutez le programme comme décrit dans le fichier README.
-
Ouvrez le fichier pom.xml et ajoutez les dépendances JAR.
<dependency> <groupId>io.opentracing.contrib</groupId> <artifactId>opentracing-spring-cloud-starter</artifactId> <version>0.5.8</version> </dependency> <dependency> <groupId>io.jaegertracing</groupId> <artifactId>jaeger-client</artifactId> <version>1.4.0</version> </dependency> -
Ajoutez le bean OpenTracing Tracer.
RemarqueRemplacez
<endpoint>par le point de terminaison que vous avez obtenu dans la section « Prérequis » de cette rubrique.@Bean public io.opentracing.Tracer tracer() { io.jaegertracing.Configuration config = new io.jaegertracing.Configuration("springFrontend"); io.jaegertracing.Configuration.SenderConfiguration sender = new io.jaegertracing.Configuration.SenderConfiguration(); sender.withEndpoint("<endpoint>"); config.withSampler(new io.jaegertracing.Configuration.SamplerConfiguration().withType("const").withParam(1)); config.withReporter(new io.jaegertracing.Configuration.ReporterConfiguration().withSender(sender).withMaxQueueSize(10000)); return config.getTracer(); }
Instrumenter une application Java avec gRPC
Pour envoyer les données de l'application Java à la console Managed Service for OpenTelemetry à l'aide de Jaeger, vous devez d'abord instrumenter votre application. Cet exemple utilise le composant gRPC pour l'instrumentation.
Téléchargez le projet de démonstration, accédez au répertoire grpcDemo et exécutez le programme comme décrit dans le fichier README.
-
Ouvrez le fichier pom.xml et ajoutez la dépendance JAR.
<dependency> <groupId>io.opentracing.contrib</groupId> <artifactId>opentracing-grpc</artifactId> <version>0.2.3</version> </dependency> -
Sur le serveur, initialisez l'objet Tracer, créez un ServerTracingInterceptor et ajoutez-le en tant qu'intercepteur de serveur.
import io.opentracing.Tracer; public class YourServer { private int port; private Server server; private final Tracer tracer; private void start() throws IOException { ServerTracingInterceptor tracingInterceptor = new ServerTracingInterceptor(this.tracer); // If GlobalTracer is used: // ServerTracingInterceptor tracingInterceptor = new ServerTracingInterceptor(); server = ServerBuilder.forPort(port) .addService(tracingInterceptor.intercept(someServiceDef)) .build() .start(); } } -
Sur le client, initialisez l'objet Tracer, créez un ClientTracingInterceptor et ajoutez-le en tant qu'intercepteur de canal client.
import io.opentracing.Tracer; public class YourClient { private final ManagedChannel channel; private final GreeterGrpc.GreeterBlockingStub blockingStub; private final Tracer tracer; public YourClient(String host, int port) { channel = ManagedChannelBuilder.forAddress(host, port) .usePlaintext(true) .build(); ClientTracingInterceptor tracingInterceptor = new ClientTracingInterceptor(this.tracer); // If GlobalTracer is used: // ClientTracingInterceptor tracingInterceptor = new ClientTracingInterceptor(); blockingStub = GreeterGrpc.newBlockingStub(tracingInterceptor.intercept(channel)); } }
FAQ
Q : Mon programme de démonstration s'exécute sans erreur, mais aucune donnée n'apparaît dans la console. Quel pourrait être le problème ?
R : Déboguez la méthode io.jaegertracing.thrift.internal.senders.HttpSender.send(Process process, List<Span> spans) et vérifiez la valeur de retour lors de l'envoi des données. Si une erreur 403 est signalée, cela indique que la configuration du point de terminaison est incorrecte. Veuillez la vérifier et la modifier.