Log applicazioni strutturato per Azure Spring Apps

Nota

Azure Spring Apps è il nuovo nome del servizio Azure Spring Cloud. Anche se il servizio ha un nuovo nome, il nome precedente verrà visualizzato in alcune posizioni per un po' mentre si lavora per aggiornare gli asset, ad esempio screenshot, video e diagrammi.

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

Questo articolo illustra come generare e raccogliere dati di log 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 al comando dell'interfaccia --format-json della az spring app logs riga di comando. 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 di log
Stacktrace string No StackTrace Analisi dello stack di 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 Log colonna 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 pom.xml file.

    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>6.5</version>
    </dependency>
    
  2. Aggiornare il logback-spring.xml file di configurazione 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 -spring suffisso 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 -Dspring.profiles.active=devJVM , 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 pom.xml file.

    <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 jsonTemplate.json modello di layout 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 log4j2-spring.xml file di configurazione.

    <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. Passare 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 of the Azure portal showing the log Results pane.

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 una classe di eccezione o un codice di 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