Exemplo de instrumentação Java

Neste documento, descrevemos como instrumentar um app Java para coletar dados de rastreamento e métrica usando o SDK OpenTelemetry e um coletor do OpenTelemetry. Também descreve como gravar registros JSON estruturados para saída padrão. Para testar a instrumentação, faça o download e execute o app de exemplo. Ele usa o Spring Boot Framework e gera dados de registro, métricas e rastreamento.

Ao usar um coletor do OpenTelemetry, você instrumenta seu aplicativo com o SDK e o exportador OTLP no processo do SDK. Essa instrumentação é independente de fornecedor. Você também implanta um coletor do OpenTelemetry que recebe telemetria do exportador no processo e exporta essa telemetria para seu projeto Google Cloud . Para saber mais sobre coletores, consulte Coletor do OpenTelemetry criado pelo Google.

Recomendamos que você use um coletor do OpenTelemetry para exportar seus dados de telemetria quando o ambiente for compatível com o uso do coletor. Em alguns ambientes, é necessário usar um exportador no processo que envia dados diretamente para o projetoGoogle Cloud . Para saber mais sobre a instrumentação no processo, consulte Migrar do exportador do Trace para o endpoint do OTLP.

Para saber mais sobre instrumentação, consulte os seguintes documentos:

Sobre a instrumentação manual e sem código

A instrumentação descrita neste documento depende da instrumentação sem código do OpenTelemetry para enviar telemetria ao seu projeto Google Cloud . Para Java, a instrumentação sem código se refere à prática de injetar dinamicamente bytecode em bibliotecas e frameworks para capturar telemetria. A instrumentação sem código pode coletar telemetria para itens como chamadas HTTP de entrada e saída. Para mais informações, consulte Agente Java.

O OpenTelemetry também oferece uma API para adicionar instrumentação personalizada ao seu próprio código. O OpenTelemetry se refere a isso como instrumentação manual. Este documento não descreve a instrumentação manual. Para exemplos e informações sobre esse tópico, consulte Instrumentação manual.

Antes de começar

  1. Faça login na sua conta do Google Cloud . Se você começou a usar o Google Cloud, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
  2. Instale a CLI do Google Cloud.

  3. Ao usar um provedor de identidade (IdP) externo, primeiro faça login na gcloud CLI com sua identidade federada.

  4. Para inicializar a gcloud CLI, execute o seguinte comando:

    gcloud init
  5. Crie ou selecione um Google Cloud projeto.

    Funções necessárias para selecionar ou criar um projeto

    • Selecionar um projeto: não é necessário um papel específico do IAM para selecionar um projeto. Você pode escolher qualquer projeto em que tenha recebido um papel.
    • Criar um projeto: para criar um projeto, é necessário ter o papel de Criador de projetos (roles/resourcemanager.projectCreator), que contém a permissão resourcemanager.projects.create. Saiba como conceder papéis.
    • Crie um projeto do Google Cloud :

      gcloud projects create PROJECT_ID

      Substitua PROJECT_ID por um nome para o projeto Google Cloud que você está criando.

    • Selecione o projeto Google Cloud que você criou:

      gcloud config set project PROJECT_ID

      Substitua PROJECT_ID pelo nome do projeto do Google Cloud .

  6. Verifique se o faturamento está ativado para o projeto do Google Cloud .

  7. Ative as APIs Cloud Logging, Cloud Monitoring, Cloud Trace e Telemetry:

    Funções necessárias para ativar APIs

    Para ativar as APIs, é necessário ter o papel do IAM de administrador do Service Usage (roles/serviceusage.serviceUsageAdmin), que contém a permissão serviceusage.services.enable. Saiba como conceder papéis.

    gcloud services enable logging.googleapis.com monitoring.googleapis.com cloudtrace.googleapis.com telemetry.googleapis.com
  8. Instale a CLI do Google Cloud.

  9. Ao usar um provedor de identidade (IdP) externo, primeiro faça login na gcloud CLI com sua identidade federada.

  10. Para inicializar a gcloud CLI, execute o seguinte comando:

    gcloud init
  11. Crie ou selecione um Google Cloud projeto.

    Funções necessárias para selecionar ou criar um projeto

    • Selecionar um projeto: não é necessário um papel específico do IAM para selecionar um projeto. Você pode escolher qualquer projeto em que tenha recebido um papel.
    • Criar um projeto: para criar um projeto, é necessário ter o papel de Criador de projetos (roles/resourcemanager.projectCreator), que contém a permissão resourcemanager.projects.create. Saiba como conceder papéis.
    • Crie um projeto do Google Cloud :

      gcloud projects create PROJECT_ID

      Substitua PROJECT_ID por um nome para o projeto Google Cloud que você está criando.

    • Selecione o projeto Google Cloud que você criou:

      gcloud config set project PROJECT_ID

      Substitua PROJECT_ID pelo nome do projeto do Google Cloud .

  12. Verifique se o faturamento está ativado para o projeto do Google Cloud .

  13. Ative as APIs Cloud Logging, Cloud Monitoring, Cloud Trace e Telemetry:

    Funções necessárias para ativar APIs

    Para ativar as APIs, é necessário ter o papel do IAM de administrador do Service Usage (roles/serviceusage.serviceUsageAdmin), que contém a permissão serviceusage.services.enable. Saiba como conceder papéis.

    gcloud services enable logging.googleapis.com monitoring.googleapis.com cloudtrace.googleapis.com telemetry.googleapis.com
  14. Se você executar a amostra no Cloud Shell, em recursos Google Cloud ou em um ambiente de desenvolvimento local, as permissões listadas nesta seção serão suficientes. Para aplicativos de produção, geralmente uma conta de serviço fornece as credenciais para gravar dados de registro, métrica e rastreamento.

    Para receber as permissões necessárias para que o aplicativo de exemplo grave dados de registros, métricas e trace, peça ao administrador para conceder a você os seguintes papéis do IAM no projeto:

    Para ter as permissões necessárias para visualizar seus dados de registros, métricas e rastreamentos, peça ao administrador para conceder a você os seguintes papéis do IAM no projeto:

    Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

    Também é possível conseguir as permissões necessárias usando papéis personalizados ou outros papéis predefinidos.

Instrumentar o app para coletar traces, métricas e registros

Para instrumentar o app para coletar dados de rastreamento e métrica e gravar um JSON estruturado para saída padrão, siga as etapas a seguir, conforme descrito nas próximas seções deste documento:

  1. Configurar o app para usar o agente Java do OpenTelemetry
  2. Configurar o OpenTelemetry
  3. Configurar a geração de registros estruturados
  4. Gravar registros estruturados

Configurar o app para usar o agente Java do OpenTelemetry

Para configurar o app para gravar registros estruturados e coletar métricas e rastrear dados usando o OpenTelemetry, atualize a invocação do app para usar o Agente Java do OpenTelemetry. Esse método de instrumentação do app é conhecido como instrumentação automática, porque não requer modificação do código do app.

O exemplo de código a seguir ilustra um Dockerfile que faz o download do arquivo JAR do agente Java do OpenTelemetry e atualiza a invocação da linha de comando para transmitir a sinalização -javaagent.

Para ver o exemplo completo, clique em Mais e selecione Ver no GitHub.

RUN wget -O /opentelemetry-javaagent.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.31.0/opentelemetry-javaagent.jar
CMD sh -c "java -javaagent:/opentelemetry-javaagent.jar -cp app:app/lib/* com.example.demo.DemoApplication \
	2>&1 | tee /var/log/app.log"

Como alternativa, também é possível definir a sinalização -javaagent na variável de ambiente JAVA_TOOL_OPTIONS:

export JAVA_TOOL_OPTIONS="-javaagent:PATH/TO/opentelemetry-javaagent.jar"

Configurar o OpenTelemetry

A configuração padrão do agente Java do OpenTelemetry exporta traces e métricas usando o protocolo OTLP. Ela também configura o OpenTelemetry para usar o formato Contexto de Rastreamento do W3C para propagar o contexto do trace. Essa configuração garante que os períodos tenham o relacionamento pai-filho correto em um trace.

Para mais informações e opções de configuração, consulte Instrumentação automática em Java do OpenTelemetry.

Configurar a geração de registros estruturados

Para incluir as informações de trace como parte dos registros formatados em JSON gravados na saída padrão, configure seu app para gerar registros estruturados no formato JSON. Recomendamos usar o Log4j2 como implementação da geração de registros. O exemplo de código a seguir ilustra um arquivo log4j2.xml configurado para gerar registros estruturados JSON usando o Layout do modelo JSON:

<!-- Format JSON logs for the Cloud Logging agent
https://cloud.google.com/logging/docs/structured-logging#special-payload-fields -->

<!-- Log4j2's JsonTemplateLayout includes a template for Cloud Logging's special JSON fields
https://logging.apache.org/log4j/2.x/manual/json-template-layout.html#event-templates -->
<JsonTemplateLayout eventTemplateUri="classpath:GcpLayout.json">
  <!-- Extend the included GcpLayout to include the trace and span IDs from Mapped
  Diagnostic Context (MDC) so that Cloud Logging can correlate Logs and Spans

  Since log4j2 2.24.0, GcpLayout.json already includes trace context logging from MDC and
  the below additional fields are no longer needed -->
  <EventTemplateAdditionalField
    key="logging.googleapis.com/trace"
    format="JSON"
    value='{"$resolver": "mdc", "key": "trace_id"}'
  />
  <EventTemplateAdditionalField
    key="logging.googleapis.com/spanId"
    format="JSON"
    value='{"$resolver": "mdc", "key": "span_id"}'
  />
  <EventTemplateAdditionalField
    key="logging.googleapis.com/trace_sampled"
    format="JSON"
    value="true"
  />
</JsonTemplateLayout>

A configuração anterior extrai informações sobre o período ativo do Contexto de diagnóstico mapeado do SLF4J e adiciona essas informações como atributos ao registro. Esses atributos podem ser usados para correlacionar um registro com um trace:

  • logging.googleapis.com/trace: nome do recurso do trace associado à entrada de registro.
  • logging.googleapis.com/spanId: o ID do período com o trace associado à entrada de registro.
  • logging.googleapis.com/trace_sampled: o valor desse campo precisa ser true ou false.

Para mais informações sobre esses campos, consulte a estrutura LogEntry.

Gravar registros estruturados

Para gravar registros estruturados que se vinculam a um trace, use a API de geração de registros SLF4J. Por exemplo, a instrução a seguir mostra como chamar o método Logger.info():

logger.info("handle /multi request with subRequests={}", subRequests);

O agente Java do OpenTelemetry preenche automaticamente o Contexto de diagnóstico mapeado do SLF4J com o contexto de período do período ativo atual no OpenTelemetry Context. O Contexto de diagnóstico mapeado é incluído nos registros JSON, conforme descrito em Configurar geração de registros estruturados.

Executar um app de exemplo configurado para coletar telemetria

A instrumentação no app de exemplo usa formatos neutros em relação a fornecedores, como JSON para dados de registro e OTLP para dados de métricas e traces. O app também usa o Spring Boot Framework. O OpenTelemetry Collector envia dados de métricas e registros para seu projeto usando exportadores do Google. Ele envia os dados de trace para seu projeto usando a API Telemetry, que usa OTLP.

O app tem dois endpoints:

  • O endpoint /multi é processado pela função handleMulti. O gerador de carga no app emite solicitações para o endpoint /multi. Quando esse endpoint recebe uma solicitação, ele envia de três a sete solicitações para o endpoint /single no servidor local.

    /**
     * handleMulti handles an http request by making 3-7 http requests to the /single endpoint.
     *
     * <p>OpenTelemetry instrumentation requires no changes here. It will automatically generate a
     * span for the controller body.
     */
    @GetMapping("/multi")
    public Mono<String> handleMulti() throws Exception {
      int subRequests = ThreadLocalRandom.current().nextInt(3, 8);
    
      // Write a structured log with the request context, which allows the log to
      // be linked with the trace for this request.
      logger.info("handle /multi request with subRequests={}", subRequests);
    
      // Make 3-7 http requests to the /single endpoint.
      return Flux.range(0, subRequests)
          .concatMap(
              i -> client.get().uri("http://localhost:8080/single").retrieve().bodyToMono(Void.class))
          .then(Mono.just("ok"));
    }
  • O endpoint /single é processado pela função handleSingle. Quando esse endpoint recebe uma solicitação, ele fica suspenso por um pequeno atraso e depois responde com uma string.

    /**
     * handleSingle handles an http request by sleeping for 100-200 ms. It writes the number of
     * milliseconds slept as its response.
     *
     * <p>OpenTelemetry instrumentation requires no changes here. It will automatically generate a
     * span for the controller body.
     */
    @GetMapping("/single")
    public String handleSingle() throws InterruptedException {
      int sleepMillis = ThreadLocalRandom.current().nextInt(100, 200);
      logger.info("Going to sleep for {}", sleepMillis);
      Thread.sleep(sleepMillis);
      logger.info("Finishing the request");
      return String.format("slept %s\n", sleepMillis);
    }

Fazer o download e implantar o app

Para executar a amostra:

  1. No console do Google Cloud , ative o Cloud Shell.

    Ativar o Cloud Shell

    Na parte de baixo do console Google Cloud , uma sessão do Cloud Shell é iniciada e exibe um prompt de linha de comando. O Cloud Shell é um ambiente shell com a CLI do Google Cloud já instalada e com valores já definidos para o projeto atual. A inicialização da sessão pode levar alguns segundos.

  2. Clone o repositório:

    git clone https://github.com/GoogleCloudPlatform/opentelemetry-operations-java
    
  3. Acesse o diretório da amostra:

    cd opentelemetry-operations-java/examples/instrumentation-quickstart
    
  4. Crie e execute a amostra:

    docker compose up --abort-on-container-exit
    

    Se você não estiver usando o Cloud Shell, execute o aplicativo com a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS apontando para um arquivo de credenciais. O Application Default Credentials fornece um arquivo de credenciais em $HOME/.config/gcloud/application_default_credentials.json.

    # Set environment variables
    export GOOGLE_CLOUD_PROJECT="PROJECT_ID"
    export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.config/gcloud/application_default_credentials.json"
    export USERID="$(id -u)"
    
    # Run
    docker compose -f docker-compose.yaml -f docker-compose.creds.yaml up --abort-on-container-exit
    

Ver suas métricas

A instrumentação do OpenTelemetry no app de amostra gera métricas do Prometheus, que podem ser visualizadas usando o Metrics Explorer:

  • Prometheus/http_server_duration_milliseconds/histogram registra a duração das solicitações do servidor e armazena os resultados em um histograma.

  • Prometheus/http_client_duration_milliseconds/histogram registra a duração das solicitações do cliente e armazena os resultados em um histograma.

Para visualizar as métricas geradas pelo app de exemplo, faça o seguinte:
  1. No console Google Cloud , acesse a página do  Metrics explorer:

    Acesse o Metrics Explorer

    Se você usar a barra de pesquisa para encontrar essa página, selecione o resultado com o subtítulo Monitoring.

  2. Na barra de ferramentas do console Google Cloud , selecione seu projeto Google Cloud . Para configurações do App Hub, selecione o projeto host do App Hub ou o projeto de gerenciamento da pasta habilitada para apps.
  3. No elemento Metric, expanda o menu Selecionar uma métrica, digite http_server na barra de filtro e use os submenus para selecionar um tipo de recurso e métrica específicos:
    1. No menu Active resources, selecione Prometheus Target.
    2. No menu Categorias de métrica ativas, selecione Instância.
    3. No menu Métricas ativas, selecione uma métrica de faturamento†.
    4. Clique em Aplicar.
  4. Para adicionar filtros que removem séries temporais dos resultados da consulta, use o elemento Filtro.

  5. Configure a visualização dos dados.

    Quando as medições de uma métrica são cumulativas, o Metrics Explorer normaliza automaticamente os dados medidos pelo período de alinhamento, o que resulta na exibição de uma taxa no gráfico. Para mais informações, consulte Tipos, tipos e conversões.

    Quando valores inteiros ou duplos são medidos, como acontece com as duas métricas counter, o Metrics Explorer soma automaticamente todas as séries temporais. Para visualizar os dados das rotas HTTP /multi e /single, defina o primeiro menu da entrada Agregação como Nenhum.

    Para mais informações sobre como configurar um gráfico, consulte Selecionar métricas ao usar o Metrics Explorer.

Visualizar os rastros

Pode levar vários minutos até que os dados de rastreamento estejam disponíveis. Por exemplo, quando os dados de rastreamento são recebidos pelo seu projeto, o Google Cloud Observability pode precisar criar um banco de dados para armazenar esses dados. A criação do banco de dados pode levar alguns minutos. Durante esse período, nenhum dado de rastreamento fica disponível para visualização.

Para visualizar os dados de trace, faça o seguinte:

  1. No console Google Cloud , acesse a página Explorador de traces:

    Acessar o Explorador de traces

    Também é possível encontrar essa página usando a barra de pesquisa.

  2. Na seção de tabela da página, selecione uma linha com o nome do intervalo /multi.
  3. No diagrama de Gantt no painel Detalhes do trace, selecione o período rotulado como /multi.

    Um painel é aberto com informações sobre a solicitação HTTP. Esses detalhes incluem o método, o código de status, o número de bytes e o user agent do autor da chamada.

  4. Para visualizar os registros associados a esse trace, selecione a guia Registros e eventos.

    A guia mostra registros individuais. Para exibir os detalhes da entrada de registro, expanda a entrada de registro. Também é possível clicar em Ver registros e ver o registro usando a Análise de registros.

Para mais informações sobre como usar o explorador do Cloud Trace, consulte Encontrar e explorar traces.

Acessar os registros

Na Análise de registros, é possível inspecionar os registros e visualizar os traces associados, quando eles existirem.

  1. No console do Google Cloud , acesse a página Análise de registros:

    Acessar a Análise de registros

    Se você usar a barra de pesquisa para encontrar essa página, selecione o resultado com o subtítulo Monitoring.

  2. Localize um registro com a descrição de handle /multi request.

    Para ver os detalhes do registro, expanda a entrada.

  3. Clique em Traces em uma entrada de registro com a mensagem "handle /multi request" e selecione View trace details.

    O painel Detalhes do trace é aberto e mostra o trace selecionado.

    Os dados de registros podem ficar disponíveis vários minutos antes dos dados de rastreamento. Se você encontrar um erro ao visualizar dados de rastreamento pesquisando um rastreamento por ID ou seguindo as etapas desta tarefa, aguarde um ou dois minutos e tente novamente.

Para mais informações sobre como usar a Análise de registros, consulte Ver registros usando a Análise de registros.

A seguir