Log applicazioni strutturato per Azure Spring Apps

Nota

I piani Basic, Standard ed Enterprise saranno deprecati a partire dalla metà di marzo 2025, con un periodo di ritiro di 3 anni. È consigliabile eseguire la transizione ad App Azure Container. Per altre informazioni, vedere l'annuncio di ritiro di Azure Spring Apps.

Il piano Standard a consumo e dedicato sarà deprecato a partire dal 30 settembre 2024, con un arresto completo dopo sei mesi. È consigliabile eseguire la transizione ad App Azure Container. Per altre informazioni, vedere Eseguire la migrazione del consumo di Azure Spring Apps Standard e del piano dedicato alle app Azure Container.

Questo articolo si applica a: ✔️ Basic/Standard ✔️ Enterprise

Questo articolo illustra come generare e raccogliere dati di registro applicazioni strutturati in Azure Spring Apps. Con la configurazione corretta, Azure Spring Apps offre utili query e analisi del log applicazioni tramite Log Analytics.

Requisiti dello schema dei log

Per migliorare l'esperienza di query di log, è necessario che un log applicazioni sia in formato JSON e conforme a uno schema. Azure Spring Apps usa questo schema per analizzare l'applicazione e trasmettere l'applicazione a Log Analytics.

Nota

L'abilitazione del formato di log JSON rende difficile leggere l'output del flusso di log dalla console. Per ottenere un output leggibile, aggiungere l'argomento --format-json al comando dell'interfaccia della riga di comando az spring app logs. Vedere Formattare i log strutturati JSON.

Requisiti dello schema JSON:

Chiave JSON Tipo valore JSON Richiesto Colonna in Log Analytics Descrizione
timestamp string AppTimestamp timestamp in formato UTC
logger string No Logger logger
level string No CustomLevel livello di log
thread string No Thread thread
messaggio string No Message messaggio log
stackTrace string No StackTrace analisi dello stack delle eccezioni
exceptionClass string No ExceptionClass nome della classe di eccezione
mdc JSON annidato No Contesto di diagnostica mappato
mdc.traceId string No TraceId ID traccia per la traccia distribuita
mdc.spanId string No SpanId SPAN ID per la traccia distribuita
  • Il campo "timestamp" è obbligatorio e deve essere in formato UTC, tutti gli altri campi sono facoltativi.
  • "traceId" e "spanId" nel campo "mdc" vengono usati a scopo di traccia.
  • Registrare ogni record JSON in una riga.

Esempio di record di 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"}

Limiti

Ogni riga dei log JSON ha al massimo 16 K byte. Se l'output JSON di un singolo record di log supera questo limite, viene suddiviso in più righe e ogni riga non elaborata viene raccolta nella colonna Log senza essere analizzata strutturalmente.

In genere, questa situazione si verifica nella registrazione delle eccezioni con stacktrace avanzato, soprattutto quando l'Agente In-Process di AppInsights è abilitato. Applicare le impostazioni limite all'output stacktrace (vedere gli esempi di configurazione seguenti) per assicurarsi che l'output finale venga analizzato correttamente.

Generare un log JSON conforme allo schema

Per le applicazioni Spring, è possibile generare il formato di log JSON previsto usando framework di registrazione comuni, ad esempio Logback e Log4j2.

Log con logback

Quando si usano gli starter Spring Boot, per impostazione predefinita viene usato Logback. Per le app di logback, usare logstash-encoder per generare log in formato JSON. Questo metodo è supportato in Spring Boot versione 2.1 o successiva.

Procedura:

  1. Aggiungere la dipendenza logstash nel file pom.xml.

    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>6.5</version>
    </dependency>
    
  2. Aggiornare il file di configurazione logback-spring.xml per impostare il 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. Quando si usa il file di configurazione della registrazione con suffisso -spring come logback-spring.xml, è possibile impostare la configurazione della registrazione in base al profilo attivo 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>
    

    Per lo sviluppo locale, eseguire l'applicazione Spring con l'argomento JVM -Dspring.profiles.active=dev, quindi è possibile visualizzare i log leggibili invece delle righe in formato JSON.

Log con log4j2

Per le app log4j2, usare json-template-layout per generare log in formato JSON. Questo metodo è supportato in Spring Boot versione 2.1+.

Procedura:

  1. Escludere spring-boot-starter-logging da spring-boot-starter, aggiungere dipendenze spring-boot-starter-log4j2, log4j-layout-template-json nel file 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. Preparare un file modello di layout JSON jsonTemplate.json nel percorso della 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. Usare questo modello di layout JSON nel file di configurazione 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>
    

Analizzare i log in Log Analytics

Dopo aver configurato correttamente l'applicazione, il log della console dell'applicazione viene trasmesso a Log Analytics. La struttura abilita query efficienti in Log Analytics.

Controllare la struttura dei log in Log Analytics

A tale scopo, seguire questa procedura:

  1. Andare alla pagina di panoramica del servizio dell'istanza del servizio.

  2. Selezionare la voce Log nella sezione Monitoraggio.

  3. Eseguire questa query.

    AppPlatformLogsforSpring
    | where TimeGenerated > ago(1h)
    | project AppTimestamp, Logger, CustomLevel, Thread, Message, ExceptionClass, StackTrace, TraceId, SpanId
    
  4. I log dell'applicazione vengono restituiti come illustrato nell'immagine seguente:

    Screenshot del portale di Azure che mostra il riquadro Dei risultati del log.

Mostra voci di log contenenti errori

Per esaminare le voci di log con un errore, eseguire la query seguente:

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

Usare questa query per trovare gli errori o modificare i termini della query per trovare classi o codici errore specifici.

Visualizzare le voci di log per un traceId specifico

Per esaminare le voci di log per un ID di traccia specifico "trace_id", eseguire la query seguente:

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

Passaggi successivi