Após instrumentar sua aplicação com o Jaeger e relatar dados de rastreamento para o Managed Service for OpenTelemetry, o Managed Service for OpenTelemetry começa a monitorá-la. É possível visualizar diversos dados de monitoramento, como topologia da aplicação, traces, transações anômalas, transações lentas e análise de SQL. Este tópico descreve como configurar a instrumentação manual e a automática com componentes Spring Cloud e gRPC.
Para recursos avançados e capacidades de rastreamento, recomendamos conectar sua aplicação ao Managed Service for OpenTelemetry pelo protocolo OpenTelemetry.
Nossos guias detalhados de integração do OpenTelemetry e melhores práticas ajudam você a começar a usar o Managed Service for OpenTelemetry. Para mais informações, consulte Conectar uma aplicação.
Pré-requisitos
Informações básicas
O Jaeger é um sistema de rastreamento distribuído de código source aberto, compatível com a API OpenTracing e reconhecido como um projeto graduado da Cloud Native Computing Foundation (CNCF). Ele agrega dados de monitoramento em tempo real de diversos sistemas heterogêneos. A comunidade OpenTracing fornece vários componentes compatíveis com uma ampla variedade de frameworks Java. Alguns exemplos incluem:
Para relatar dados de aplicações Java no console do Managed Service for OpenTelemetry usando o Jaeger, é necessário instrumentar a aplicação previamente. Você pode optar pela instrumentação manual ou utilizar diversos plug-ins existentes para instrumentação automática. Este tópico aborda os três métodos de instrumentação a seguir.
Instrumentação manual
Instrumentação com componente Spring Cloud
Instrumentação com componente gRPC
Instrumentar uma aplicação Java
Antes de usar o Jaeger para enviar dados de uma aplicação Java ao Managed Service for OpenTelemetry, instrumente a aplicação. Neste exemplo, a instrumentação é feita manualmente.
Baixe o projeto de demonstração. Acesse o diretório manualDemo e execute o programa conforme as instruções no arquivo README.md.
-
Adicione a seguinte dependência para clientes Jaeger ao arquivo pom.xml:
<dependency> <groupId>io.jaegertracing</groupId> <artifactId>jaeger-client</artifactId> <version>0.31.0</version> </dependency> -
Configure os parâmetros de inicialização e crie um tracer.
Um tracer cria spans que registram o tempo de operações distribuídas, transmitem dados entre servidores em modo pass-through pelos métodos Extract ou Inject, ou definem o span atual. O tracer também contém dados como o endpoint usado para relato, endereço IP local, taxa de amostragem e nome do service. Ajuste a taxa de amostragem para reduzir a sobrecarga causada pelo envio de dados.
NotaSubstitua
<endpoint>pelo endpoint obtido na seção "Pré-requisitos" deste tópico.// 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()); -
Registre os dados da requisição.
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(); -
Opcional. Execute o código anterior para criar um span raiz e registrar a operação inicial de uma requisição. Para registrar as operações anteriores e subsequentes, especifique as informações de contexto.
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(); -
Opcional. Para solucionar problemas com eficiência, adicione tags personalizadas a um span. Por exemplo, inclua uma tag personalizada para verificar a ocorrência de erros ou registrar o valor retornado por uma requisição.
tracer.activeSpan().setTag("methodName", "testCall"); -
Em sistemas distribuídos, requisições de chamada de procedimento remoto (RPC) são enviadas junto com dados de rastreamento. Esses dados contêm os valores dos parâmetros TraceId, ParentSpanId, SpanId e Sampled. Chame o método Extract ou Inject para transmitir os dados de rastreamento nos cabeçalhos de requisição HTTP. A figura a seguir ilustra todo o processo.

-
Chame o método Inject no cliente para especificar as informações de contexto.
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()"); } }); } -
Chame o método Extract no servidor para extrair as informações de contexto.
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(); }
-
Instrumentar uma aplicação Java com Spring Cloud
Para relatar dados de aplicações Java no console do Managed Service for OpenTelemetry usando o Jaeger, instrumente a aplicação previamente. Este exemplo utiliza componentes Spring Cloud para a instrumentação. O Spring Cloud oferece instrumentação para os seguintes componentes:
@Async, @Scheduled, Executors
Feign, HystrixFeign
Hystrix
JDBC
JMS
Mongo
RabbitMQ
Redis
RxJava
Spring Messaging - Os traces são enviados por canais de mensagens.
Spring Web (RestControllers, RestTemplates, WebAsyncTask)
Standard Logging - Os logs são adicionados ao Span atual.
WebSocket STOMP
Zuul
Baixe o projeto de demonstração, acesse o diretório springMvcDemo/webmvc4-boot e execute o programa conforme descrito no arquivo README.
-
Abra o arquivo pom.xml e adicione as dependências 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> -
Adicione o bean OpenTracing Tracer.
NotaSubstitua
<endpoint>pelo endpoint obtido na seção "Pré-requisitos" deste tópico.@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(); }
Instrumentar uma aplicação Java com gRPC
Para enviar dados de aplicações Java ao console do Managed Service for OpenTelemetry usando o Jaeger, instrumente a aplicação previamente. Este exemplo utiliza o componente gRPC para a instrumentação.
Baixe o projeto de demonstração, acesse o diretório grpcDemo e execute o programa conforme descrito no arquivo README.
-
Abra o arquivo pom.xml e adicione a dependência JAR.
<dependency> <groupId>io.opentracing.contrib</groupId> <artifactId>opentracing-grpc</artifactId> <version>0.2.3</version> </dependency> -
No servidor, inicialize o objeto Tracer, crie um ServerTracingInterceptor e adicione-o como interceptor do servidor.
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(); } } -
No cliente, inicialize o objeto Tracer, crie um ClientTracingInterceptor e adicione-o como interceptor de canal do cliente.
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)); } }
Perguntas frequentes
P: Meu programa de demonstração executa sem erros, mas nenhum dado aparece no console. Qual pode ser o problema?
R: Depure o método io.jaegertracing.thrift.internal.senders.HttpSender.send(Process process, List<Span> spans) e verifique o valor retornado durante o envio dos dados. Se um erro 403 for reportado, isso indica que a configuração do endpoint está incorreta. Verifique e modifique-a.