Log do aplicativo estruturado para o Azure Spring Apps

Observação

Os planos Básico, Standard e Enterprise serão preteridos a partir de meados de março de 2025, com um período de desativação de 3 anos. Recomendamos a transição para os Aplicativos de Contêiner do Azure. Para mais informações, confira o anúncio de desativação dos Aplicativos Spring do Azure.

O plano Standard de consumo e dedicado será preterido a partir de 30 de setembro de 2024, com um desligamento completo após seis meses. Recomendamos a transição para os Aplicativos de Contêiner do Azure. Para mais informações, confira Migrar o plano Standard de consumo e dedicado dos Aplicativos Spring do Azure para os Aplicativos de Contêiner do Azure.

Este artigo se aplica ao: ✔️ nível Básico/Standard ✔️ nível Enterprise

Este artigo explica como gerar e coletar dados do log do aplicativo estruturado no Azure Spring Apps. Com a configuração adequada, o Azure Spring Apps fornece consulta e análise úteis de log do aplicativo por meio do Log Analytics.

Requisitos do esquema do log

Para melhorar a experiência de consulta de log, um log de aplicativo precisa estar no formato JSON e em conformidade com um esquema. O Azure Spring Apps usa esse esquema para analisar o aplicativo e transmitir para o Log Analytics.

Observação

A habilitação do formato de log JSON dificulta a leitura da saída de streaming de log no console. Para obter uma saída legível, acrescente o argumento --format-json no comando az spring app logs da CLI. Consulte Formatar logs JSON estruturados.

Requisitos do esquema do JSON:

Chave Json Tipo de valor Json Obrigatório Coluna no Log Analytics Descrição
timestamp string Sim AppTimestamp carimbo de data/hora no formato UTC
agente string Não Agente agente
Nível  string Não CustomLevel nível de log
thread string Não Thread thread
message string No Mensagem mensagem de log
stackTrace string Não StackTrace rastreamento de pilha de exceção
exceptionClass string Não ExceptionClass nome da classe de exceção
mdc aninhado JSON Não contexto de diagnóstico mapeado
mdc.traceId string Não TraceId ID de rastreamento para rastreamento distribuído
mdc.spanId string Não SpanID ID de intervalo para rastreamento distribuído
  • O campo "carimbo de data/hora" é obrigatório e deve estar no formato UTC, todos os outros campos são opcionais.
  • "traceId" e "spanId" no campo "mdc" são usados para fins de rastreamento.
  • Registre cada registro JSON em uma linha.

Exemplo de registro de log

{"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"}

Limitações

Cada linha dos logs JSON tem no máximo 16 K bytes. Se a saída JSON de um único registro de log exceder esse limite, ela será dividida em várias linhas e cada linha bruta será coletada na coluna Log sem ser analisada estruturalmente.

Em geral, essa situação acontece no log de exceções com rastreamento de pilha profundo, especialmente quando o AppInsights In-Process Agent está habilitado. Aplique as configurações de limite à saída do rastreamento de pilha (consulte os exemplos de configuração abaixo) para garantir que a saída final seja analisada corretamente.

Gerar log JSON compatível com esquema

Para aplicativos Spring, você pode gerar o formato de log JSON esperado usando as estruturas de log comuns, como Logback e Log4j2.

Log com logback

Ao usar iniciadores Spring Boot, o Logback é usado por padrão. Para aplicativos de Logback, use logstash-encoder para gerar log formatado em JSON. Esse método tem suporte no Spring Boot versão 2.1 ou posterior.

Procedimento:

  1. Adicione a dependência logstash no arquivo pom.xml.

    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>6.5</version>
    </dependency>
    
  2. Atualize o arquivo de configuração logback-spring.xml para definir o 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. Ao usar o arquivo de configuração de log com um sufixo -spring, como logback-spring.xml, defina a configuração de log com base no perfil ativo do 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 o desenvolvimento local, execute o aplicativo Spring com o argumento JVM -Dspring.profiles.active=dev e você verá logs legíveis em vez de linhas formatadas em JSON.

Registrar com log4j2

Para aplicativos log4j2, use json-template-layout para gerar o log formatado em JSON. Esse método é compatível com o Spring Boot versão 2.1+.

Procedimento:

  1. Exclua spring-boot-starter-logging de spring-boot-starter e adicione as dependências spring-boot-starter-log4j2 e log4j-layout-template-json no arquivo 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 um arquivo de modelo de layout JSON jsonTemplate.json em seu caminho de classe.

    {
        "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 este modelo de layout JSON em seu arquivo de configuração 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>
    

Analisar os logs no Log Analytics

Depois que o aplicativo for configurado corretamente, o log do console do aplicativo será transmitido para o Log Analytics. A estrutura permite uma consulta eficiente no Log Analytics.

Verificar a estrutura do log no Log Analytics

Use este procedimento:

  1. Vá para a página Visão geral do serviço da sua instância de serviço.

  2. Selecione a entrada Logs na seção Monitoramento.

  3. Execute esta consulta.

    AppPlatformLogsforSpring
    | where TimeGenerated > ago(1h)
    | project AppTimestamp, Logger, CustomLevel, Thread, Message, ExceptionClass, StackTrace, TraceId, SpanId
    
  4. Os logs de aplicativo retornam conforme mostrado na imagem a seguir:

    Captura de tela do portal do Azure mostrando o painel Resultados do log.

Mostrar as entradas de log contendo erros

Para analisar as entradas de log que têm erro, execute a seguinte consulta:

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

Use essa consulta para localizar erros ou modificar os termos da consulta para localizar uma classe de exceção ou um código de erro específicos.

Mostrar as entradas de log para uma traceId específica

Para analisar as entradas de log de uma "trace_id" (ID de rastreamento) específica, execute a seguinte consulta:

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

Próximas etapas