Registro de aplicaciones estructurado para Azure Spring Apps

Nota:

Azure Spring Apps es el nuevo nombre del servicio Azure Spring Cloud. Aunque el servicio tiene un nuevo nombre, verá el nombre antiguo en algunos lugares durante un tiempo mientras trabajamos para actualizar recursos, como capturas de pantalla, vídeos y diagramas.

La información de este artículo puede ponerse en práctica en: ✔️ Básico o Estándar ✔️ Enterprise

En este artículo se explica cómo generar y recopilar datos de registro de aplicaciones estructurados en Azure Spring Apps. Con la configuración adecuada, Azure Spring Apps ofrece consultas y análisis útiles de los registros de aplicaciones a través de Log Analytics.

Requisitos del esquema de registro

Para mejorar la experiencia de consulta de registros, es necesario que un registro de aplicaciones esté en formato JSON y se ajuste a un esquema. Azure Spring Apps usa este esquema para analizar la aplicación y transmitirla a Log Analytics.

Nota:

La habilitación del formato de registro JSON dificulta la lectura de la salida del streaming de registros desde la consola. Para obtener una salida legible, anexe el argumento --format-json al comando de la CLI az spring app logs. Consulte Aplicación de formato a los registros estructurados de JSON.

Requisitos del esquema JSON:

Clave JSON Tipo de valor JSON Obligatorio Columna en Log Analytics Descripción
timestamp string AppTimestamp Marca de tiempo en formato UTC
logger string No Registrador logger
level string No CustomLevel log level
thread string No Hilo thread
message string No Mensaje mensaje del registro
stackTrace string No StackTrace seguimiento de la pila de excepciones
exceptionClass string No ExceptionClass nombre de clase de la excepción
mdc JSON anidado No contexto de diagnóstico asignado
mdc.traceId string No TraceId Identificador de seguimiento para el seguimiento distribuido
mdc.spanId string No SpanId Identificador de intervalo para el seguimiento distribuido
  • El campo "timestamp" es obligatorio y debe estar en formato UTC. todos los demás campos son opcionales.
  • "TraceId" y "spanId" en el campo "mdc" se usan con fines de seguimiento.
  • Coloque cada registro JSON en una sola línea.

Ejemplo de fila de registro

{"timestamp":"2021-01-08T09:23:51.280Z","logger":"com.example.demo.HelloController","level":"ERROR","thread":"http-nio-1456-exec-4","mdc":{"traceId":"c84f8a897041f634","spanId":"c84f8a897041f634"},"stackTrace":"java.lang.RuntimeException: get an exception\r\n\tat com.example.demo.HelloController.throwEx(HelloController.java:54)\r\n\","message":"Got an exception","exceptionClass":"RuntimeException"}

Limitaciones

Cada línea de los registros JSON tiene como máximo 16 K bytes. Si la salida JSON de un registro único supera este límite, se divide en varias líneas y cada línea sin procesar se recopila en la Log columna sin analizarse estructuralmente.

Por lo general, esta situación se produce en el registro de excepciones con stacktrace profundo, especialmente cuando la aplicación Ideas agente en proceso está habilitada. Aplique la configuración de límite a la salida de stacktrace (consulte los ejemplos de configuración siguientes) para asegurarse de que la salida final se analiza correctamente.

Generación de un registro JSON conforme al esquema

En el caso de las aplicaciones spring, puede generar el formato de registro JSON esperado mediante marcos de registro comunes, como Logback y Log4j2.

Registro con logback

Al usar los inicios de Spring Boot, logback se usa de forma predeterminada. En el caso de las aplicaciones de Logback, use logstash-encoder para generar el registro con formato JSON. Este método es compatible con Spring Boot versión 2.1 o posterior.

El procedimiento es el siguiente:

  1. Agregue la dependencia de logstash al archivo pom.xml.

    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>6.5</version>
    </dependency>
    
  2. Actualice el archivo de configuración logback-spring.xml para configurar el formato JSON.

    <configuration>
        <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
                <providers>
                    <timestamp>
                        <fieldName>timestamp</fieldName>
                        <timeZone>UTC</timeZone>
                    </timestamp>
                    <loggerName>
                        <fieldName>logger</fieldName>
                    </loggerName>
                    <logLevel>
                        <fieldName>level</fieldName>
                    </logLevel>
                    <threadName>
                        <fieldName>thread</fieldName>
                    </threadName>
                    <nestedField>
                        <fieldName>mdc</fieldName>
                        <providers>
                            <mdc />
                        </providers>
                    </nestedField>
                    <stackTrace>
                        <fieldName>stackTrace</fieldName>
                        <!-- maxLength - limit the length of the stack trace -->
                        <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
                            <maxDepthPerThrowable>200</maxDepthPerThrowable>
                            <maxLength>14000</maxLength>
                            <rootCauseFirst>true</rootCauseFirst>
                        </throwableConverter>
                    </stackTrace>
                    <message />
                    <throwableClassName>
                        <fieldName>exceptionClass</fieldName>
                    </throwableClassName>
                </providers>
            </encoder>
        </appender>
        <root level="info">
            <appender-ref ref="stdout" />
        </root>
    </configuration>
    
  3. Al usar el archivo de configuración de registro con un sufijo -spring, como logback-spring.xml, puede establecer la configuración de registro en función del perfil activo de Spring.

    <configuration>
        <springProfile name="dev">
            <!-- JSON appender definitions for local development, in human readable format -->
            <include resource="org/springframework/boot/logging/logback/defaults.xml" />
            <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
            <root level="info">
                <appender-ref ref="CONSOLE" />
            </root>
        </springProfile>
    
        <springProfile name="!dev">
            <!-- JSON appender configuration from previous step, used for staging / production -->
            ...
        </springProfile>
    </configuration>
    

    Para el desarrollo local, ejecute la aplicación Spring con el argumento -Dspring.profiles.active=dev de JVM; así, podrá ver registros legibles para el usuario en lugar de líneas con formato JSON.

Registro con log4j2

En el caso de las aplicaciones de log4j2, use json-template-layout para generar el registro con formato JSON. Este método se admite en Spring Boot versión 2.1 y posteriores.

El procedimiento es el siguiente:

  1. Excluya spring-boot-starter-logging de spring-boot-starter y agregue las dependencias spring-boot-starter-log4j2 y log4j-layout-template-json al archivo pom.xml.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-layout-template-json</artifactId>
        <version>2.14.0</version>
    </dependency>
    
  2. Prepare un archivo de plantilla de diseño JSON jsonTemplate.json en la ruta de acceso de clase.

    {
        "mdc": {
            "$resolver": "mdc"
        },
        "exceptionClass": {
            "$resolver": "exception",
            "field": "className"
        },
        "stackTrace": {
            "$resolver": "exception",
            "field": "stackTrace",
            "stringified": true
        },
        "message": {
            "$resolver": "message",
            "stringified": true
        },
        "thread": {
            "$resolver": "thread",
            "field": "name"
        },
        "timestamp": {
            "$resolver": "timestamp",
            "pattern": {
                "format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
                "timeZone": "UTC"
            }
        },
        "level": {
            "$resolver": "level",
            "field": "name"
        },
        "logger": {
            "$resolver": "logger",
            "field": "name"
        }
    }
    
  3. Use esta plantilla de diseño JSON en el archivo de configuración log4j2-spring.xml.

    <configuration>
        <appenders>
            <console name="Console" target="SYSTEM_OUT">
                <!-- maxStringLength - limit the length of the stack trace -->
                <JsonTemplateLayout eventTemplateUri="classpath:jsonTemplate.json" maxStringLength="14000" />
            </console>
        </appenders>
        <loggers>
            <root level="info">
                <appender-ref ref="Console" />
            </root>
        </loggers>
    </configuration>
    

Análisis de los registros en Log Analytics

Una vez configurada correctamente la aplicación, el registro de la consola de la aplicación se transmite a Log Analytics. La estructura permite realizar consultas eficaces en Log Analytics.

Comprobación de la estructura del registro en Log Analytics

Utilice el siguiente procedimiento:

  1. Vaya a la página de información general del servicio de la instancia de servicio.

  2. Seleccione la entrada Registros de la sección Supervisión.

  3. Ejecute esta consulta.

    AppPlatformLogsforSpring
    | where TimeGenerated > ago(1h)
    | project AppTimestamp, Logger, CustomLevel, Thread, Message, ExceptionClass, StackTrace, TraceId, SpanId
    
  4. Los registros de aplicaciones se devuelven como se muestra en la siguiente imagen:

    Screenshot of the Azure portal showing the log Results pane.

Visualización de entradas de registro que contienen errores

Para revisar las entradas del registro que tienen un error, ejecute la siguiente consulta:

AppPlatformLogsforSpring
| where TimeGenerated > ago(1h) and CustomLevel == "ERROR"
| project AppTimestamp, Logger, ExceptionClass, StackTrace, Message, AppName
| sort by AppTimestamp

Use esta consulta para buscar errores o modificar los términos de la consulta para encontrar clases de excepción o códigos de error específicos.

Visualización de las entradas del registro de un traceId específico

Para revisar las entradas del registro de un identificador de seguimiento específico "trace_id", ejecute la siguiente consulta:

AppPlatformLogsforSpring
| where TimeGenerated > ago(1h)
| where TraceId == "trace_id"
| project AppTimestamp, Logger, TraceId, SpanId, StackTrace, Message, AppName
| sort by AppTimestamp

Pasos siguientes