Ejemplo de instrumentación de Java

En este documento, se describe cómo modificar una app de Java para recopilar datos de seguimiento y métricas con el framework de código abierto de OpenTelemetry y cómo escribir registros JSON estructurados en salida estándar. En este documento, también se proporciona información sobre una app de Java Spring Boot muestra que puedes instalar y ejecutar. La app está configurada para generar métricas, seguimientos y registros. Los pasos son los mismos, sin importar si usas el framework Spring Boot.

Para obtener más información sobre la instrumentación, consulta los siguientes documentos:

Acerca de la instrumentación manual y sin código

La instrumentación descrita en este documento se basa en la instrumentación sin código de OpenTelemetry para enviar telemetría a tu proyecto de Google Cloud . En Java, la instrumentación sin código hace referencia a la práctica de insertar de forma dinámica el código de bytes en bibliotecas y frameworks para capturar telemetría. La instrumentación sin código puede recopilar telemetría para llamadas HTTP entrantes y salientes. Para obtener más información, consulta Agente de Java.

OpenTelemetry también proporciona una API para agregar instrumentación personalizada a tu propio código. OpenTelemetry hace referencia a esto como instrumentación manual. En este documento, no se describe la instrumentación manual. Para obtener información y ejemplos sobre ese tema, consulta Instrumentación manual.

Antes de comenzar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. Si usas un proveedor de identidad externo (IdP), primero debes acceder a gcloud CLI con tu identidad federada.

  4. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

    gcloud init
  5. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Cloud Logging, Cloud Monitoring, and Cloud Trace APIs:

    gcloud services enable logging.googleapis.com monitoring.googleapis.com cloudtrace.googleapis.com
  8. Install the Google Cloud CLI.

  9. Si usas un proveedor de identidad externo (IdP), primero debes acceder a gcloud CLI con tu identidad federada.

  10. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

    gcloud init
  11. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Enable the Cloud Logging, Cloud Monitoring, and Cloud Trace APIs:

    gcloud services enable logging.googleapis.com monitoring.googleapis.com cloudtrace.googleapis.com
  14. Instrumenta tu app para recopilar seguimientos, métricas y registros

    Si deseas instrumentar tu app para recopilar datos de seguimiento y métricas, y escribir JSON estructurado en la salida estándar, realiza los pasos que se describen en las siguientes secciones de este documento:

    1. Configura tu app para usar el agente de Java de OpenTelemetry
    2. Configura OpenTelemetry
    3. Configura el registro estructurado
    4. Escribe registros estructurados

    Configura tu app para usar el agente de Java de OpenTelemetry

    Si deseas configurar la app para que escriba registros estructurados y recopile métricas y datos de seguimiento mediante OpenTelemetry, actualiza la invocación de tu app para usar el agente de Java de OpenTelemetry. Este método para instrumentar tu app se conoce como instrumentación automática porque no requiere modificar el código de tu app.

    En la siguiente muestra de código, se ilustra un Dockerfile que descarga el archivo JAR del agente de Java de OpenTelemetry y actualiza la invocación de la línea de comandos para pasar la marca -javaagent.

    Para ver la muestra completa, haz clic en Más y, luego, selecciona Ver en 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, también puedes establecer la marca -javaagent en la variable de entorno JAVA_TOOL_OPTIONS:

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

    Configura OpenTelemetry

    La configuración predeterminada para el agente de Java de OpenTelemetry exporta seguimientos y métricas mediante el protocolo OTLP. También configura OpenTelemetry para usar el formato de contexto de seguimiento W3C a fin de propagar el contexto de seguimiento. Esta configuración garantiza que los intervalos tengan la relación superior-secundaria correcta dentro de un seguimiento.

    Para obtener más información y opciones de configuración, consulta Instrumentación automática de Java de OpenTelemetry.

    Configura el registro estructurado

    Para incluir la información de seguimiento como parte de los registros con formato JSON escritos en el resultado estándar, configura tu aplicación para que genere registros estructurados en formato JSON. Te recomendamos usar Log4j2 como tu implementación de registros. En la siguiente muestra de código, se ilustra un archivo log4j2.xml configurado para generar registros estructurados JSON a través del diseño de plantilla de 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>

    La configuración anterior extrae información sobre el intervalo activo del contexto de diagnóstico asignado de SLF4J y agrega esa información como atributos al registro. Estos atributos se pueden usar para correlacionar un registro con un seguimiento:

    • logging.googleapis.com/trace: el nombre del recurso del seguimiento asociado a la entrada de registro.
    • logging.googleapis.com/spanId: el ID de intervalo con el seguimiento asociado a la entrada de registro.
    • logging.googleapis.com/trace_sampled: el valor de este campo debe ser true o false.

    Para obtener más información sobre estos campos, consulta la estructura LogEntry.

    Escribe registros estructurados

    Para escribir registros estructurados que se vinculen a un seguimiento, usa la API de Logging de SLF4J. Por ejemplo, con la siguiente instrucción, se muestra cómo llamar al método Logger.info():

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

    El agente de Java de OpenTelemetry propaga de forma automática el contexto de diagnóstico asignado de SLF4J con el contexto de intervalo del intervalo activo actual en el contexto de OpenTelemetry. El contexto de diagnóstico asignado se incluye en los registros JSON como se describe en Configura el registro estructurado.

    Ejecuta una app de ejemplo configurada para recopilar telemetría

    La app de ejemplo usa formatos que no dependen de los proveedores, incluidos JSON para los registros y OTLP para las métricas y los seguimientos, y el framework de Spring Boot. Para enrutar la telemetría a Google Cloud, esta muestra usa el Collector de OpenTelemetry configurado con los exportadores de Google. La app tiene dos extremos:

    • La función handleMulti controla el extremo /multi. El generador de cargas de la app envía solicitudes al extremo /multi. Cuando este extremo recibe una solicitud, envía entre tres y siete solicitudes al extremo /single en el 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"));
      }
    • La función handleSingle controla el extremo /single. Cuando este extremo recibe una solicitud, se suspende durante un retraso breve y, luego, responde con una cadena.

      /**
       * 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);
      }

    Descarga e implementa la app

    Para ejecutar la muestra, haz lo siguiente:

    1. In the Google Cloud console, activate Cloud Shell.

      Activate Cloud Shell

      At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

    2. Clona el repositorio:

      git clone https://github.com/GoogleCloudPlatform/opentelemetry-operations-java
      
    3. Ve al directorio de muestra:

      cd opentelemetry-operations-java/examples/instrumentation-quickstart
      
    4. Compila y ejecuta la muestra:

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

      Si no ejecutas en Cloud Shell, ejecuta la aplicación con la variable de entorno GOOGLE_APPLICATION_CREDENTIALS que apunta a un archivo de credenciales. Las credenciales predeterminadas de la aplicación proporcionan un archivo de credenciales en $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
      
    5. Consulta tus métricas

      La instrumentación de OpenTelemetry en la app de ejemplo genera métricas de Prometheus que puedes ver mediante el Explorador de métricas:

      • Prometheus/http_server_duration_milliseconds/histogram registra la duración de las solicitudes del servidor y almacena los resultados en un histograma.

      • Prometheus/http_client_duration_milliseconds/histogram registra la duración de las solicitudes del cliente y almacena los resultados en un histograma.

      Para ver las métricas que genera la app de muestra, haz lo siguiente:
      1. En la consola de Google Cloud , accede a la página  Explorador de métricas:

        Acceder al Explorador de métricas

        Si usas la barra de búsqueda para encontrar esta página, selecciona el resultado cuyo subtítulo es Monitoring.

      2. En la barra de herramientas de la consola de Google Cloud , selecciona tu proyecto de Google Cloud . Para las configuraciones de App Hub, selecciona el proyecto host de App Hub o el proyecto de administración de la carpeta habilitada para apps.
      3. En el elemento Métrica, expande el menú Seleccionar una métrica, ingresa http_server en la barra de filtros y, luego, usa los submenús para seleccionar un métrica y tipo de recurso específicos:
        1. En el menú Recursos activos, elige Destino de Prometheus.
        2. En el menú Categorías de métricas activas, elige Http.
        3. En el menú Métricas activas, selecciona una métrica.
        4. Haz clic en Aplicar.
      4. Configura cómo se ven los datos.

        Cuando las mediciones de una métrica son acumulativas, el Explorador de métricas normaliza automáticamente los datos medidos por el período de alineación, lo que hace que el gráfico muestre una frecuencia. Para obtener más información, consulta Categorías, tipos y conversiones.

        Cuando se miden valores de números enteros o dobles, como con las dos métricas counter, el Explorador de métricas suma automáticamente todas las series temporales. Para ver los datos de las rutas HTTP /multi y /single, establece el primer menú de la entrada Agregación como Ninguna.

        Para obtener más información sobre la configuración de un gráfico, consulta elige métricas cuando uses el Explorador de métricas.

      Ve tus seguimientos

      Es posible que pasen varios minutos hasta que estén disponibles tus datos de seguimiento. Por ejemplo, cuando tu proyecto recibe datos de seguimiento, es posible que Google Cloud Observability necesite crear una base de datos para almacenarlos. La creación de la base de datos puede tardar unos minutos y, durante ese período, no habrá datos de seguimiento disponibles para ver.

      Para ver tus datos de seguimiento, haz lo siguiente:

      1. En la consola de Google Cloud , ve a la página Explorador de seguimiento:

        Ve al Explorador de seguimiento

        También puedes usar la barra de búsqueda para encontrar esta página.

      2. En la sección de la tabla de la página, selecciona una fila con el nombre del tramo /multi.
      3. En el diagrama de Gantt del panel Detalles de seguimiento, selecciona el intervalo etiquetado como /multi.

        Se abre un panel que muestra información sobre la solicitud HTTP. Estos detalles incluyen el método, el código de estado, la cantidad de bytes y el usuario-agente del emisor.

      4. Para ver los registros asociados con este seguimiento, selecciona la pestaña Registros y eventos.

        La pestaña muestra registros individuales. Para ver los detalles de la entrada de registro, expande la entrada de registro. También puedes hacer clic en Ver registros y ver el registro con el Explorador de registros.

      Si deseas obtener más información para usar el explorador de Cloud Trace, consulta Busca y explora seguimientos.

      Mira los registros

      En el Explorador de registros, puedes inspeccionar tus registros y, también, puedes ver los seguimientos asociados, cuando existen.

      1. En la consola de Google Cloud , ve a la página Explorador de registros.

        Acceder al Explorador de registros

        Si usas la barra de búsqueda para encontrar esta página, selecciona el resultado cuyo subtítulo es Logging.

      2. Ubica un registro con la descripción de handle /multi request.

        Para ver los detalles del registro, expande la entrada de registro.

      3. Haz clic en Seguimientos en una entrada de registro con el mensaje "Controla solicitudes múltiples" y, luego, selecciona Ver detalles de seguimiento.

        Se abrirá el panel Detalles de seguimiento y se mostrará el seguimiento seleccionado.

        Es posible que tus datos de registro estén disponibles varios minutos antes que tus datos de seguimiento. Si se produce un error cuando ves los datos de seguimiento, ya sea buscando un seguimiento por ID o siguiendo los pasos de esta tarea, espera uno o dos minutos y vuelve a intentarlo.

      Para obtener más información sobre el uso del Explorador de registros, consulta Visualiza registros con el Explorador de registros.

      ¿Qué sigue?