Migra registros a entornos de ejecución de Java de segunda generación

Algunos aspectos del registro en los entornos de ejecución de segunda generación (Java 11 y versiones posteriores) son diferentes del entorno de ejecución de primera generación (Java 8). A diferencia del entorno de ejecución de primera generación, en los entornos de ejecución de segunda generación, los registros de la app no se agrupan en registros de solicitud dentro del Explorador de registros. Además, en los entornos de ejecución de segunda generación, App Engine escribe cada registro de la app asociado con una solicitud como una entrada de registro independiente en Cloud Logging.

En esta guía, se describe cómo implementar los mismos métodos de registro que usaste en tus apps del entorno de ejecución de primera generación y lograr casi los mismos resultados de correlación de filtrado y registro cuando migras tu app a Java 11+.

Diferencias clave

En la siguiente tabla, se tratan las diferencias en el registro entre los entornos de ejecución de primera y segunda generación:

Entorno de ejecución de primera generación (Java 8) Entornos de ejecución de segunda generación (Java 11 y versiones posteriores)
Registros de solicitudes y apps (también llamados registros de aplicaciones) App Engine incorpora todos los registros de la app dentro del registro de solicitud. App Engine no incorpora los registros de la app dentro del registro de solicitudes asociado.
stdout y stderr App Engine incorpora registros escritos en stdout y stderr dentro del registro de solicitud. App Engine no incorpora registros escritos en stdout y stderr.
Registros de plataforma de App Engine App Engine no emite registros de plataforma internos. App Engine emite registros de plataforma internos durante el inicio o el cierre de una instancia con el nombre de registro /var/log/google_init.log.
Cuota de la API de Cloud Logging Cada solicitud corresponde a una escritura de Cloud Logging. Cada entrada de registro de la app asociada con una solicitud corresponde a una escritura de Cloud Logging. El uso de la API de Cloud Logging aumenta en los entornos de ejecución de segunda generación.

Registros de solicitud y registros de la app

El comportamiento del registro en los entornos de ejecución de primera y segunda generación difiere de las siguientes maneras:

  • En el entorno de ejecución de primera generación, App Engine incorpora los registros de la app en el campo protoPayload.line de los registros de la solicitud. Para ver los registros de la app, expande una solicitud en el Explorador de registros.

    En la siguiente imagen, se muestran los registros de apps y solicitudes correlacionados en el entorno de ejecución de primera generación:

    Registros correlacionados en Java 8

  • En los entornos de ejecución de segunda generación, los registros de solicitudes no contienen entradas de registro de la app porque el campo protoPayload.line está ausente en el registro de solicitudes. En cambio, App Engine registra cada registro de la app como una entrada independiente. El nombre del registro depende de tu configuración de registro. var/log/app contiene registros emitidos mediante frameworks de registro estándar, como java.util.logging o Simple Logging Facade para Java (SLF4J). Los registros stderr y stdout contienen registros de la app que se registran mediante System.err.print() o System.out.print().

    En la siguiente imagen, se muestran registros de apps y solicitudes independientes en los entornos de ejecución de segunda generación:

    Separa registros en Java 11

stdout y stderr

En el entorno de ejecución de primera generación, App Engine considera los registros emitidos en stdout y stderr como registros de la app, y agrupa automáticamente estas entradas de registro de la app en el registro de solicitudes asociado.

En los entornos de ejecución de segunda generación, App Engine no correlaciona los registros emitidos en stdout y stderr de forma predeterminada. Para agrupar entidades de registro de apps con el registro de solicitudes mediante stdout y stderr, sigue las instrucciones en Escribe registros estructurados en stdout y stderr.

No recomendamos acceder a stdout ni stderr, ya que ciertos registros de la plataforma de App Engine (JVM, Jetty y registros de infraestructura internos) también se emiten a stderr. Los registros de la app y los registros de la plataforma aparecen junto con el nombre de registro stderr, lo que genera ambigüedad. Esto es exagerado en los entornos de ejecución de segunda generación, ya que App Engine tiene un mayor volumen de registros de plataforma.

Registros de plataforma de App Engine

En el entorno de ejecución de primera generación, App Engine no emite registros de plataforma.

En los entornos de ejecución de segunda generación, App Engine emite registros de plataforma durante el inicio o el cierre de las instancias con el nombre de registro /var/log/google_init.log.

Puedes ignorar los registros de la plataforma de forma segura. Para evitar ver estos registros, agrega un filtro al Explorador de registros con la consulta logName="/var/log/google_init.log".

En la siguiente imagen, se muestran los registros de plataforma en los entornos de ejecución de segunda generación:

Registros de plataforma

Cuota de la API de Cloud Logging

En el entorno de ejecución de primera generación, App Engine incorpora todos los registros de la app emitidos durante una solicitud en un solo registro de solicitud y envía la solicitud incorporada a Cloud Logging. Cada solicitud corresponde a una escritura de Cloud Logging.

En los entornos de ejecución de segunda generación, App Engine envía cada registro de app a Cloud Logging en entradas de registro separadas, lo que genera un aumento en la cantidad total de escrituras de Cloud Logging por solicitud.

Google Cloud determina la facturación según el almacenamiento general que usa Cloud Logging. Incluso si el almacenamiento general requerido para los registros no aumenta significativamente, las escrituras por minuto aumentan, según la cantidad de registros de la aplicación que App Engine escriba por solicitud. Si la app supera la cuota de escritura de Cloud Logging, puedes solicitar un aumento de la cuota de uso.

Para obtener más información, consulta los precios de Cloud Logging.

Descripción general del proceso de migración

Incluso si los registros de la app no están incorporados dentro de los registros de solicitud en los entornos de ejecución de segunda generación, es posible conservar la experiencia de visualización de registros como las apps de primera generación.

Puedes elegir una de las siguientes opciones para configurar el registro en los entornos de ejecución de segunda generación:

Usa el paquete java.util.logging (JUL)

Si tus apps que usan el entorno de ejecución de primera generación implementan el paquete java.util.logging para todos los requisitos de registro, la migración a entornos de ejecución de segunda generación no requiere cambios en el código.

En el siguiente ejemplo, se muestra cómo puedes usar el paquete java.util.logging para registrar en los entornos de ejecución de segunda generación:

    package com.example.appengine.my_app;
    import java.io.IOException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.*;
    import java.util.logging.Logger;

    @WebServlet(name = "HelloAppEngine", value = "/")
    public class HelloAppEngine extends HttpServlet {

      // Use the java.util.logging.Logger to log messages
      private static final Logger logger = Logger.getLogger(HelloAppEngine.class.getName());

      @Override
      public void doGet(HttpServletRequest request, HttpServletResponse response)
          throws IOException {
        // Sample log messages
        logger.info("Info message");
        logger.warning("Warning message");
        logger.severe("Severe message");

        response.setContentType("text/plain");
        response.getWriter().println("Hello App Engine");
      }
    }

Agrupa los registros de apps con el registro de solicitudes

En los entornos de ejecución de segunda generación, el campo protoPayload.line en el registro de solicitud no contiene registros de la app. El Explorador de registros usa el campo trace para agrupar registros de solicitudes y de la app. El paquete java.util.logging agrega de forma automática el ID de seguimiento a todos los registros de la solicitud y de la app. Para ver los registros correlacionados en el Explorador de registros, consulta Visualiza registros correlacionados.

Usa la fachada de registro simple para Java (SLF4J)

SLF4J es la interfaz de registro más popular que se usa en las aplicaciones de Java. Al ser una fachada, la interfaz de SLF4J es independiente de la plataforma del backend de registro, lo que te permite elegir cualquier backend adecuado para las aplicaciones.

En la siguiente imagen, se muestran las opciones de integración para dos backends de SLF4J, incluida la biblioteca java.util.logging y el adjuntador de Logback:

Descripción general de SLF4J

SLF4J con el paquete java.util.logging

SLF4J te permite integrar tu app en Cloud Logging cuando usas SLF4J con java.util.logging como backend de registro. De forma predeterminada, App Engine agrega un ID de seguimiento a todos los registros de las solicitudes y de la app. Este mecanismo permite agrupar los registros de solicitudes y de apps en el Explorador de registros.

Para implementar SLF4J con java.util.logging, sigue estos pasos:

  1. Agrega la dependencia slf4j-jdk14.jar al archivo pom.xml. El archivo slf4j-jdk14.jar proporciona la integración de backend para la biblioteca java.util.logging:

    <!-- SLF4J interface -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>2.0.4</version>
    </dependency>
    <!-- JUL implementation for SLF4J -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-jdk14</artifactId>
      <version>2.0.9</version>
    </dependency>
    
  2. Crea un archivo WEB-INF/logging.properties para agregar configuraciones personalizadas:

    com.example.appengine.java8.HelloAppEngine.level = INFO
    
  3. Actualiza el archivo appengine-web.xml a fin de incluir el valor <property> para WEB-INF/logging.properties:

    <system-properties>
      <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
    </system-properties>
    

En la siguiente imagen, se muestra cómo SLF4J con java.util.logging agrega automáticamente el ID de seguimiento a un registro de la app:

Agrupar registros de apps por solicitud con ID de seguimiento

Para ajustar la vista del Explorador de registros a una vista centrada en las solicitudes, como el entorno de ejecución de primera generación, consulta Visualiza registros correlacionados.

Usa SLF4J con agregador de Logback

Si tus apps de entorno de ejecución de primera generación usan la implementación integrada de SLF4J con Logback, debes actualizar tu código fuente y, luego, implementar pasos adicionales para agrupar los registros de la app y de la solicitud.

Para integrar tu app en Cloud Logging, sigue estos pasos:

  1. Incluye el agregador google-cloud-logging-logback en tu archivo pom.xml para instalar el adjuntador de registros para Logback:

     <!-- SLF4J interface -->
     <dependency>
           <groupId>org.slf4j</groupId>
           <artifactId>slf4j-api</artifactId>
           <version>2.0.4</version>
     </dependency>
    
     <!-- Logback JARs -->
     <dependency>
           <groupId>ch.qos.logback</groupId>
           <artifactId>logback-classic</artifactId>
           <version>1.3.6</version>
     </dependency>
     <dependency>
           <groupId>ch.qos.logback</groupId>
           <artifactId>logback-core</artifactId>
           <version>1.3.5</version>
     </dependency>
    
     <!-- Google Cloud logging appender for Logback -->
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-logging-logback</artifactId>
     </dependency>
    
  2. Crea un optimizador de registros para agregar un ID de seguimiento a cada campo LogEntry. La siguiente clase TraceIdLoggingEnhancer usa la API de ApiProxy para recuperar el ID de seguimiento asociado con una solicitud:

      import com.google.appengine.api.utils.SystemProperty;
      import com.google.cloud.logging.LogEntry;
      import com.google.cloud.logging.LoggingEnhancer;
    
      import com.google.apphosting.api.ApiProxy;
      import com.google.apphosting.api.ApiProxy.Environment;
    
      // Add trace ID to the log entry
      public class TraceIdLoggingEnhancer implements LoggingEnhancer {
    
        @Override
        public void enhanceLogEntry(LogEntry.Builder logEntry) {
          final String PROJECT_ID = SystemProperty.applicationId.get();
    
          Environment environment = ApiProxy.getCurrentEnvironment();
    
          if (environment instanceof ApiProxy.EnvironmentWithTrace) {
            ApiProxy.EnvironmentWithTrace environmentWithTrace = (ApiProxy.EnvironmentWithTrace) environment;
            environmentWithTrace
                .getTraceId()
                .ifPresent(
                    id ->
                      logEntry.setTrace(String.format("projects/%s/traces/%s", PROJECT_ID, id)));
          }
        }
      }
      // [END logging_enhancer]
    
  3. Agrega la configuración del adjuntador de Cloud Logging en el archivo logback.xml para configurar Logback. El framework de Logback administra la configuración a través del archivo logback.xml en WEB-INF/classes:

    <configuration>
      <appender name="CLOUD" class="com.google.cloud.logging.logback.LoggingAppender">
          <!-- This should be set to the new Logging Enhancer in the app code. -->
          <enhancer>com.example.appengine.my_app.enhancers.TraceIdLoggingEnhancer</enhancer>
          <resourceType>gae_app</resourceType>
      </appender>
      <root level="info">
          <appender-ref ref="CLOUD" />
      </root>
    </configuration>
    

    En la siguiente imagen, se muestra la estructura final del directorio de la app:

    Estructura del directorio

Visualiza registros correlacionados

Puedes ver los registros correlacionados en el Explorador de registros mediante el campo de ID de seguimiento en cada entrada de registro. Para ver los registros correlacionados en el Explorador de registros, sigue estos pasos:

  1. En el panel de navegación de la consola de Google Cloud, elige Logging y, luego, Explorador de registros:

    Ir al Explorador de registros

  2. En Tipo de recurso, selecciona Aplicación en GAE.

  3. Para ver y correlacionar los registros de solicitudes, en Nombre del registro, elige request_log. Como alternativa, para correlacionar por registros de solicitud, haz clic en Correlacionar por y elige request_log.

    Correlacionar registros

  4. En el panel Resultados de la consulta, para expandir una entrada de registro, haz clic en Expandir. En la expansión, cada registro de solicitud mostrará los registros de la app asociados.