Journal des applications structuré pour Azure Spring Apps

Remarque

Azure Spring Apps est le nouveau nom du service Azure Spring Cloud. Bien que le service ait un nouveau nom, vous verrez l’ancien nom à divers endroits pendant un certain temps, car nous travaillons à mettre à jour les ressources telles que les captures d’écran, les vidéos et les diagrammes.

Cet article s’applique au : Niveau ✔️ De base/Standard ✔️ Entreprise

Cet article explique comment générer et collecter des données de journal structuré des applications dans Azure Spring Apps. Avec une configuration adéquate, Azure Spring Apps permet d’interroger et d’analyser les journaux des applications grâce à Log Analytics.

Configuration requise pour le schéma des journaux

Afin d’améliorer l’expérience d’interrogation des journaux, un journal d’application doit être au format JSON et conforme à un schéma. Azure Spring Apps utilise ce schéma pour analyser votre application et transmettre le résultat à Log Analytics.

Remarque

L’activation du format de journal JSON complique la lecture de la sortie de diffusion de journaux à partir de la console. Pour recevoir une sortie lisible par l’utilisateur, ajoutez --format-jsonl'argument à la commande CLI az spring app logs. Consultez Formater les journaux structurés JSON.

Configuration requise pour le schéma JSON :

Clé JSON Type de valeur JSON Requis Colonne dans Log Analytics Description
timestamp string Oui AppTimestamp timestamp au format UTC
logger string Non Logger logger
level string Non CustomLevel log level
thread string Non Fil de discussion thread
message string Non Message message du journal
stackTrace string Non StackTrace arborescence des appels de procédure des exceptions
exceptionClass string Non ExceptionClass nom de la classe d’exception
mdc JSON imbriqué Non contexte de diagnostic mappé
mdc.traceId string Non TraceId ID de trace pour le suivi distribué
mdc.spanId string Non SpanId ID d’étendue pour le suivi distribué
  • Le champ « timestamp » est obligatoire et doit être au format UTC, tous les autres champs sont facultatifs.
  • « traceId » et « spanId » dans le champ « mdc » sont utilisés à des fins de suivi.
  • Consignez chaque enregistrement JSON sur une seule ligne.

Exemple d’enregistrement de journal

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

Limites

Chaque ligne des journaux JSON comporte au maximum 16 K octets. Si la sortie JSON d’un enregistrement de journal unique dépasse cette limite, elle est divisée en plusieurs lignes et chaque ligne brute est collectée dans la Log colonne sans être analysée structurellement.

En règle générale, cette situation se produit sur la journalisation des exceptions avec stacktrace profond, en particulier lorsque l’application Recommandations Agent in-process est activée. Appliquez les paramètres de limite à la sortie du StackTrace (voir les exemples de configuration ci-dessous) pour vous assurer que la sortie finale est correctement analysée.

Générer un journal JSON conforme au schéma

Pour les applications Spring, vous pouvez générer le format de journal JSON attendu à l’aide de frameworks de journalisation courants, tels que Logback et Log4j2.

Consigner avec logback

Lorsque vous utilisez des starters Spring Boot, Logback est utilisé par défaut. Pour les applications Logback, utilisez logstash-encoder pour générer un journal au format JSON. Cette méthode est prise en charge dans Spring Boot version 2.1 ou ultérieure.

La procédure :

  1. Ajoutez la dépendance logstash dans votre fichier pom.xml.

    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>6.5</version>
    </dependency>
    
  2. Mettez à jour votre fichier config logback-spring.xml pour définir le format 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. Lorsque vous utilisez le fichier config de la journalisation avec un suffixe -spring tel que logback-spring.xml, vous pouvez définir la configuration de la journalisation en fonction du profil actif 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>
    

    Pour le développement local, exécutez l’application Spring avec l’argument JVM -Dspring.profiles.active=dev. Vous pourrez alors voir des journaux lisibles plutôt que des lignes au format JSON.

Consigner avec log4j2

Pour les applications log4j2, utilisez json-template-layout pour générer un journal au format JSON. Cette méthode est prise en charge dans Spring Boot version 2.1+.

La procédure :

  1. Excluez spring-boot-starter-logging de spring-boot-starter, ajoutez les dépendances spring-boot-starter-log4j2 et log4j-layout-template-json dans votre fichier 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. Préparez un fichier de modèle de layout JSON jsonTemplate.json dans votre chemin d’accès 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. Utilisez ce modèle de layout JSON dans votre fichier config 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>
    

Analyser les journaux dans Log Analytics

Une fois votre application correctement configurée, le journal de la console d’application est diffusé en continu vers Log Analytics. La structure permet une interrogation efficace dans Log Analytics.

Vérifier la structure du journal dans Log Analytics

Suivez la procédure suivante :

  1. Accédez à la page de la vue d’ensemble du service de votre instance de service.

  2. Sélectionnez l’entrée Journaux de la section Surveillance.

  3. Exécutez cette requête.

    AppPlatformLogsforSpring
    | where TimeGenerated > ago(1h)
    | project AppTimestamp, Logger, CustomLevel, Thread, Message, ExceptionClass, StackTrace, TraceId, SpanId
    
  4. Les journaux des applications sont renvoyés comme indiqué dans l’image suivante :

    Screenshot of the Azure portal showing the log Results pane.

Afficher les entrées de journal contenant des erreurs

Pour consulter les entrées de journal qui contiennent une erreur, exécutez la requête suivante :

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

Utilisez cette requête pour rechercher des erreurs ou modifiez les termes de la requête pour rechercher une classe d’exception ou un code d’erreur spécifique.

Afficher les entrées de journal pour un traceId spécifique

Pour consulter les entrées de journal d’un ID de suivi « trace_id » spécifique, exécutez la requête suivante :

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

Étapes suivantes