Você está na página 1de 11

INSTRUMENTAÇÃO

PERSONALIZADA
DO JAVA COM A
BIBLIOTECA
DATADOG
ABRIL 2023

Versão do Documento: 01

INSTRUMENTAÇÃO PERSONALIZADA DO JAVA COM A


BIBLIOTECA
D O C U MDATADOG
ENTO CONFIDENCIAL
MARÇO 2023
CONFIDENCIALERRO! USE A GUIA PÁGINA INICIAL PARA
APLICAR TITLE OF THE DOCUMENT AO TEXTO QUE DEVERÁ
APARECER AQUI.TITLE OF THE DOCUMENT
1. Instrumentação Personalizada do Java
com a Biblioteca Datadog

Adicionando tags
Adicione tags personalizadas aos seus spans para personalizar sua observabilidade dentro
do Datadog. As tags de spans são aplicadas aos seus traces de entrada, permitindo que
você correlacione o comportamento observado com informações de nível de código, como o
nível do comerciante, o valor do checkout ou o ID do usuário.

 Adicionando tags personalizadas


Adicione tags personalizadas aos seus spans correspondentes a qualquer valor dinâmico
dentro do seu código de aplicativo, como customer.id.

import org.apache.cxf.transport.servlet.AbstractHTTPServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import io.opentracing.Tracer;
import io.opentracing.util.GlobalTracer;

@WebServlet
class ShoppingCartServlet extends AbstractHttpServlet {
@Override
void doGet(HttpServletRequest req, HttpServletResponse resp) {
// Get the active span
final Span span = GlobalTracer.get().activeSpan();
if (span != null) {
// customer_id -> 254889
// customer_tier -> platinum
// cart_value -> 867
span.setTag("customer.id", customer_id);
span.setTag("customer.tier", customer_tier);
span.setTag("cart.value", cart_value);
}
// [...]
}

 Adicionando tags globalmente à todos os spans

INSTRUMENTAÇÃO PERSONALIZADA DO JAVA COM A


BIBLIOTECA DATADOG
ABRIL 2023
CONFIDENCIALERRO! USE A GUIA PÁGINA INICIAL PARA
APLICAR TITLE OF THE DOCUMENT AO TEXTO QUE DEVERÁ
APARECER AQUI.TITLE OF THE DOCUMENTERRO! USE A GUIA
PÁGINA INICIAL PARA APLICAR TITLE OF THE DOCUMENT AO
TEXTO QUE DEVERÁ APARECER AQUI.TITLE OF THE DOCUMENT
A propriedade dd.tags permite definir tags em todas as spans geradas para uma aplicação.
Isso pode ser útil para agrupar estatísticas para suas aplicações, datacenters ou quaisquer
outras tags que você gostaria de ver dentro da interface do Datadog.
java -javaagent:<DD-JAVA-AGENT-PATH>.jar \
-Ddd.tags=datacenter:njc,<TAG_KEY>:<TAG_VALUE> \
-jar <YOUR_APPLICATION_PATH>.jar

 Configurando erros em um span


Para personalizar um erro associado à um de seus spans, defina a tag de erro na span e
use Span.log() para definir um "evento de erro". O evento de erro é um Map<String, Object>
que contém uma entrada Fields.ERROR_OBJECT -> Throwable, uma entrada
Fields.MESSAGE -> String ou ambos.
import io.opentracing.Span;
import io.opentracing.tag.Tags;
import io.opentracing.util.GlobalTracer;
import io.opentracing.log.Fields;
...
// Get active span if not available in current method
final Span span = GlobalTracer.get().activeSpan();
if (span != null) {
span.setTag(Tags.ERROR, true);
span.log(Collections.singletonMap(Fields.ERROR_OBJECT, ex));
}

Observação: Span.log() é um mecanismo genérico do OpenTracing para associar eventos


ao timestamp atual. O Java Tracer suporta apenas o registro de eventos de erro.
Alternativamente, você pode definir tags de erro diretamente na span sem o log():
import io.opentracing.Span;
import io.opentracing.tag.Tags;
import io.opentracing.util.GlobalTracer;
import datadog.trace.api.DDTags;
import java.io.PrintWriter;
import java.io.StringWriter;

...
final Span span = GlobalTracer.get().activeSpan();
if (span != null) {
span.setTag(Tags.ERROR, true);
span.setTag(DDTags.ERROR_MSG, ex.getMessage());
span.setTag(DDTags.ERROR_TYPE, ex.getClass().getName());

INSTRUMENTAÇÃO PERSONALIZADA DO JAVA COM A


BIBLIOTECA DATADOG
ABRIL 2023
CONFIDENCIALERRO! USE A GUIA PÁGINA INICIAL PARA
APLICAR TITLE OF THE DOCUMENT AO TEXTO QUE DEVERÁ
APARECER AQUI.TITLE OF THE DOCUMENTERRO! USE A GUIA
PÁGINA INICIAL PARA APLICAR TITLE OF THE DOCUMENT AO
TEXTO QUE DEVERÁ APARECER AQUI.TITLE OF THE DOCUMENT
final StringWriter errorString = new StringWriter();
ex.printStackTrace(new PrintWriter(errorString));
span.setTag(DDTags.ERROR_STACK, errorString.toString());
}
Observação: Você pode adicionar quaisquer metadados de erro relevantes listados na
documentação da visualização de traces. Se o span atual não for o root span, marque-o
como um erro usando a biblioteca dd-trace-api para pegar o root span com MutableSpan e,
em seguida, usar setError(true).

 Definir tags e erros em um root span à partir de um Child Span


Quando um evento ou condição acontece no fluxo descendente, pode ser necessário refletir
esse comportamento ou valor como uma tag no nível superior ou root span. Isso pode ser
útil para contar um erro ou medir o desempenho, ou definir uma tag dinâmica para
observabilidade.
import io.opentracing.Span;
import io.opentracing.Scope;
import datadog.trace.api.interceptor.MutableSpan;
import io.opentracing.log.Fields;
import io.opentracing.util.GlobalTracer;
import io.opentracing.util.Tracer;

Tracer tracer = GlobalTracer.get();


final Span span = tracer.buildSpan("<OPERATION_NAME>").start();
// Note: The scope in the try with resource block below
// will be automatically closed at the end of the code block.
// If you do not use a try with resource statement, you need
// to call scope.close().
try (final Scope scope = tracer.activateSpan(span)) {
// exception thrown here
} catch (final Exception e) {
// Set error tag on span as normal
span.log(Collections.singletonMap(Fields.ERROR_OBJECT, e));

// Set error on root span


if (span instanceof MutableSpan) {
MutableSpan localRootSpan = ((MutableSpan) span).getLocalRootSpan();
INSTRUMENTAÇÃO PERSONALIZADA DO JAVA COM A
BIBLIOTECA DATADOG
ABRIL 2023
CONFIDENCIALERRO! USE A GUIA PÁGINA INICIAL PARA
APLICAR TITLE OF THE DOCUMENT AO TEXTO QUE DEVERÁ
APARECER AQUI.TITLE OF THE DOCUMENTERRO! USE A GUIA
PÁGINA INICIAL PARA APLICAR TITLE OF THE DOCUMENT AO
TEXTO QUE DEVERÁ APARECER AQUI.TITLE OF THE DOCUMENT
localRootSpan.setError(true);
localRootSpan.setTag("some.other.tag", "value");
}
} finally {
// Close span in a finally block
span.finish();
}

Se você não estiver criando manualmente um span, ainda poderá acessar o root span por
meio do GlobalTracer:
import io.opentracing.Span;
import io.opentracing.util.GlobalTracer;
import datadog.trace.api.interceptor.MutableSpan;

...

final Span span = GlobalTracer.get().activeSpan();


if (span != null && (span instanceof MutableSpan)) {
MutableSpan localRootSpan = ((MutableSpan) span).getLocalRootSpan();
// do stuff with root span
}
Observação: Embora MutableSpan e Span compartilhem muitos métodos semelhantes, eles
são tipos distintos. MutableSpan é específico do Datadog e não faz parte da API do
OpenTracing.

Adicionando spans
Se você não estiver usando uma instrumentação de framework suportada, ou se desejar
uma profundidade adicional nas traces de sua aplicação, poderá adicionar instrumentação
personalizada ao seu código para obter gráficos de chamas completos ou para medir os
tempos de execução de trechos de código.
Se a modificação do código da aplicação não for possível, use a variável de ambiente
dd.trace.methods para detalhar esses métodos.
Se você tiver anotações @Trace existentes ou semelhantes, ou preferir usar anotações para
completar quaisquer traces incompletas dentro do Datadog, use Anotações de Trace.

INSTRUMENTAÇÃO PERSONALIZADA DO JAVA COM A


BIBLIOTECA DATADOG
ABRIL 2023
CONFIDENCIALERRO! USE A GUIA PÁGINA INICIAL PARA
APLICAR TITLE OF THE DOCUMENT AO TEXTO QUE DEVERÁ
APARECER AQUI.TITLE OF THE DOCUMENTERRO! USE A GUIA
PÁGINA INICIAL PARA APLICAR TITLE OF THE DOCUMENT AO
TEXTO QUE DEVERÁ APARECER AQUI.TITLE OF THE DOCUMENT
 Métodos de trace do Datadog
Usando a propriedade do sistema dd.trace.methods, você pode obter visibilidade em
frameworks não suportados sem alterar o código da aplicação.
java -javaagent:/path/to/dd-java-agent.jar -Ddd.env=prod -Ddd.service.name=db-app -
Ddd.trace.methods=store.db.SessionManager[saveSession] -jar path/to/application.jar
A única diferença entre esta abordagem e o uso de anotações @Trace são as opções de
personalização para os nomes de operação e recurso. Com os Métodos de Trace do DD,
operationName é trace.annotation e o resourceName é SessionManager.saveSession.

 Anotações de trace
Adicione @Trace a métodos para que sejam rastreados quando executados com dd-java-
agent.jar. Se o agente não estiver anexado, esta anotação não terá efeito na sua aplicação.
A anotação de Trace do Datadog é fornecida pela dependência dd-trace-api.
As anotações @Trace têm o nome de operação padrão trace.annotation e o nome de
recurso do método rastreado. Estes podem ser definidos como argumentos da anotação
@Trace para refletir melhor o que está sendo instrumentado. Estes são os únicos
argumentos possíveis que podem ser definidos para a anotação @Trace.
import datadog.trace.api.Trace;

public class SessionManager {

@Trace(operationName = "database.persist", resourceName =


"SessionManager.saveSession")
public static void saveSession() {
// your method implementation here
}
}
Observe que, através da propriedade do sistema dd.trace.annotations, outras anotações de
método de rastreamento podem ser reconhecidas pelo Datadog como @Trace. Você pode
encontrar uma lista aqui se já tiver decorado seu código.

 Criando manualmente um novo span


Além da instrumentação automática, da anotação @Trace e das configurações
dd.trace.methods, você pode personalizar sua observabilidade criando programaticamente
spans em torno de qualquer bloco de código. Os spans criados dessa maneira se integram
automaticamente a outros mecanismos de rastreamento. Em outras palavras, se um trace já
foi iniciado, o span manual terá seu chamador como seu span pai. Da mesma forma,
INSTRUMENTAÇÃO PERSONALIZADA DO JAVA COM A
BIBLIOTECA DATADOG
ABRIL 2023
CONFIDENCIALERRO! USE A GUIA PÁGINA INICIAL PARA
APLICAR TITLE OF THE DOCUMENT AO TEXTO QUE DEVERÁ
APARECER AQUI.TITLE OF THE DOCUMENTERRO! USE A GUIA
PÁGINA INICIAL PARA APLICAR TITLE OF THE DOCUMENT AO
TEXTO QUE DEVERÁ APARECER AQUI.TITLE OF THE DOCUMENT
quaisquer métodos rastreados chamados do bloco de código envolvido terão o span manual
como seu pai.
import datadog.trace.api.DDTags;
import io.opentracing.Scope;
import io.opentracing.Span;
import io.opentracing.Tracer;
import io.opentracing.util.GlobalTracer;

class SomeClass {
void someMethod() {
Tracer tracer = GlobalTracer.get();

// Service and resource name tags are required.


// You can set them when creating the span:
Span span = tracer.buildSpan("<OPERATION_NAME>")
.withTag(DDTags.SERVICE_NAME, "<SERVICE_NAME>")
.withTag(DDTags.RESOURCE_NAME, "<RESOURCE_NAME>")
.start();
// Note: The scope in the try with resource block below
// will be automatically closed at the end of the code block.
// If you do not use a try with resource statement, you need
// to call scope.close().
try (Scope scope = tracer.activateSpan(span)) {
// Alternatively, set tags after creation
span.setTag("my.tag", "value");

// The code you're tracing

} catch (Exception e) {
// Set error on span
} finally {
// Close span in a finally block
span.finish();
}
}
}

 Estendendo tracers
As bibliotecas de rastreamento são projetadas para serem extensíveis. Os clientes podem
considerar escrever um pós-processador personalizado chamado TraceInterceptor para
interceptar Spans e ajustá-los ou descartá-los conforme necessário (por exemplo, com base
em expressões regulares). O seguinte exemplo implementa dois interceptadores para
alcançar lógica de pós-processamento complexa.
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
INSTRUMENTAÇÃO PERSONALIZADA DO JAVA COM A
BIBLIOTECA DATADOG
ABRIL 2023
CONFIDENCIALERRO! USE A GUIA PÁGINA INICIAL PARA
APLICAR TITLE OF THE DOCUMENT AO TEXTO QUE DEVERÁ
APARECER AQUI.TITLE OF THE DOCUMENTERRO! USE A GUIA
PÁGINA INICIAL PARA APLICAR TITLE OF THE DOCUMENT AO
TEXTO QUE DEVERÁ APARECER AQUI.TITLE OF THE DOCUMENT
import datadog.trace.api.interceptor.TraceInterceptor;
import datadog.trace.api.interceptor.MutableSpan;

class FilteringInterceptor implements TraceInterceptor {


@Override
public Collection<? extends MutableSpan> onTraceComplete(
Collection<? extends MutableSpan> trace) {

List<MutableSpan> filteredTrace = new ArrayList<>();


for (final MutableSpan span : trace) {
String orderId = (String) span.getTags().get("order.id");

// Drop spans when the order id starts with "TEST-"


if (orderId == null || !orderId.startsWith("TEST-")) {
filteredTrace.add(span);
}
}

return filteredTrace;
}

@Override
public int priority() {
// some high unique number so this interceptor is last
return 100;
}
}

class PricingInterceptor implements TraceInterceptor {


@Override
public Collection<? extends MutableSpan> onTraceComplete(
Collection<? extends MutableSpan> trace) {

for (final MutableSpan span : trace) {


Map<String, Object> tags = span.getTags();
INSTRUMENTAÇÃO PERSONALIZADA DO JAVA COM A
BIBLIOTECA DATADOG
ABRIL 2023
CONFIDENCIALERRO! USE A GUIA PÁGINA INICIAL PARA
APLICAR TITLE OF THE DOCUMENT AO TEXTO QUE DEVERÁ
APARECER AQUI.TITLE OF THE DOCUMENTERRO! USE A GUIA
PÁGINA INICIAL PARA APLICAR TITLE OF THE DOCUMENT AO
TEXTO QUE DEVERÁ APARECER AQUI.TITLE OF THE DOCUMENT
Double originalPrice = (Double) tags.get("order.price");
Double discount = (Double) tags.get("order.discount");

// Set a tag from a calculation from other tags


if (originalPrice != null && discount != null) {
span.setTag("order.value", originalPrice - discount);
}
}

return trace;
}

@Override
public int priority() {
return 20; // some unique number
}
}

Próximo ao início da sua aplicação, registre os interceptadores da seguinte forma:


datadog.trace.api.GlobalTracer.get().addTraceInterceptor(new FilteringInterceptor());
datadog.trace.api.GlobalTracer.get().addTraceInterceptor(new PricingInterceptor());

Configuração do cliente e do Agente de rastreamento


Existem configurações adicionais possíveis para o cliente de rastreamento e o Agente
Datadog para a propagação de contexto, bem como para excluir Recursos específicos do
envio de rastreamentos para a Datadog, no caso de não desejar que esses rastreamentos
sejam contados em métricas calculadas, como verificações de integridade.

 Propagação de contexto com extração e injeção de cabeçalhos


Você pode configurar a propagação de contexto para rastreamentos distribuídos por meio
da injeção e extração de cabeçalhos. Leia Propagação de contexto de rastreamento para
mais informações.

 Filtragem de recursos
Os rastreamentos podem ser excluídos com base no nome do recurso, para remover o
tráfego sintético, como verificações de integridade, do relatório de rastreamentos para a
INSTRUMENTAÇÃO PERSONALIZADA DO JAVA COM A
BIBLIOTECA DATADOG
ABRIL 2023
CONFIDENCIALERRO! USE A GUIA PÁGINA INICIAL PARA
APLICAR TITLE OF THE DOCUMENT AO TEXTO QUE DEVERÁ
APARECER AQUI.TITLE OF THE DOCUMENTERRO! USE A GUIA
PÁGINA INICIAL PARA APLICAR TITLE OF THE DOCUMENT AO
TEXTO QUE DEVERÁ APARECER AQUI.TITLE OF THE DOCUMENT
Datadog. Essas e outras configurações de segurança e ajuste fino podem ser encontradas
na página de Segurança ou em Ignorando Recursos Indesejados.

INSTRUMENTAÇÃO PERSONALIZADA DO JAVA COM A


BIBLIOTECA DATADOG
ABRIL 2023
CONFIDENCIALERRO! USE A GUIA PÁGINA INICIAL PARA
APLICAR TITLE OF THE DOCUMENT AO TEXTO QUE DEVERÁ
APARECER AQUI.TITLE OF THE DOCUMENTERRO! USE A GUIA
PÁGINA INICIAL PARA APLICAR TITLE OF THE DOCUMENT AO
TEXTO QUE DEVERÁ APARECER AQUI.TITLE OF THE DOCUMENT

Você também pode gostar