Azure Spring Apps 的結構化應用程式記錄

注意

Azure Spring Apps 是 Azure Spring Cloud 服務的新名稱。 雖然服務有新的名稱,但在我們努力更新資產,例如螢幕快照、影片和圖表時,您會在某些地方看到舊名稱一段時間。

本文適用於: ✔️基本/標準✔️企業

本文說明如何在 Azure Spring Apps 中產生及收集結構化應用程式記錄數據。 透過適當的設定,Azure Spring Apps 會透過Log Analytics提供實用的應用程式記錄查詢和分析。

記錄架構需求

若要改善記錄查詢體驗,應用程式記錄必須是 JSON 格式且符合架構。 Azure Spring Apps 會使用此架構來剖析您的應用程式,並串流至 Log Analytics。

注意

啟用 JSON 記錄格式會使難以從主控台讀取記錄串流輸出。 若要取得人類可讀取的輸出,請將 --format-json 自變數附加至 az spring app logs CLI 命令。 請參閱 格式化 JSON 結構化記錄

JSON 架構需求:

Json 金鑰 Json 值類型 必要 Log Analytics 中的數據行 描述
timestamp string Yes AppTimestamp UTC 格式的時間戳
記錄 string No 記錄器 記錄
level string No CustomLevel 記錄層級
thread string No 對話 thread
message string No 訊息 記錄訊息
stackTrace string No StackTrace 例外狀況堆疊追蹤
exceptionClass string No ExceptionClass 例外狀況類別名稱
Mdc 巢狀 JSON No 對應的診斷內容
mdc.traceId string No TraceId 分散式追蹤的追蹤標識碼
mdc.spanId string No SpanId 分散式追蹤的span標識碼
  • “timestamp” 字段是必要的,而且應該是 UTC 格式,所有其他字段都是選擇性的。
  • “mdc” 字段中的 “traceId” 和 “spanId” 用於追蹤目的。
  • 以一行記錄每個 JSON 記錄。

記錄檔記錄範例

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

限制

JSON 記錄的每一行最多有 16 K 個字節。 如果單一記錄記錄的 JSON 輸出超過此限制,則會分成多行,而且每個原始行都會收集到數據行中 Log ,而不會在結構上剖析。

一般而言,這種情況發生在具有深層堆疊追蹤的例外狀況記錄上,特別是在啟用 AppInsights 同進程代理程式。 將限制設定套用至 stacktrace 輸出(請參閱下列組態範例),以確保最終輸出正確剖析。

產生符合架構規範的 JSON 記錄

針對 Spring 應用程式,您可以使用常見的 記錄架構來產生預期的 JSON 記錄格式,例如 LogbackLog4j2

使用記錄備份進行記錄

使用 Spring Boot 入門版時,預設會使用 Logback。 針對 Logback 應用程式,請使用 logstash-encoder 來產生 JSON 格式的記錄。 Spring Boot 2.1 版或更新版本支援此方法。

程式:

  1. 在您的檔案中 pom.xml 新增logstash相依性。

    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>6.5</version>
    </dependency>
    
  2. 更新組 logback-spring.xml 態檔以設定 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. 使用具有後綴的logback-spring.xml記錄組態檔-spring時,您可以根據 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>
    

    針對本機開發,請使用 JVM 自變數 -Dspring.profiles.active=dev執行 Spring 應用程式,然後您可以看到人類可讀取的記錄,而不是 JSON 格式化的行。

使用log4j2記錄

針對log4j2應用程式,請使用 json-template-layout 來產生 JSON 格式的記錄。 Spring Boot 2.1+版支援此方法。

程式:

  1. 從 排除 spring-boot-starter-logging ,在您的檔案中新增相pom.xml依性 spring-boot-starter-log4j2log4j-layout-template-jsonspring-boot-starter

    <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. 在您的類別路徑中準備 JSON 配置範本檔案 jsonTemplate.json

    {
        "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. 在組態檔中使用 log4j2-spring.xml 這個 JSON 版面配置範本。

    <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>
    

分析 Log Analytics 中的記錄

正確設定應用程式之後,您的應用程式主控台記錄會串流至Log Analytics。 結構可在Log Analytics中啟用有效率的查詢。

檢查Log Analytics中的記錄結構

請使用下列程序:

  1. 移至服務實例的服務概觀頁面。

  2. 選取 [監視] 區段中的 [記錄] 專案。

  3. 執行此查詢。

    AppPlatformLogsforSpring
    | where TimeGenerated > ago(1h)
    | project AppTimestamp, Logger, CustomLevel, Thread, Message, ExceptionClass, StackTrace, TraceId, SpanId
    
  4. 應用程式記錄會傳回,如下圖所示:

    Screenshot of the Azure portal showing the log Results pane.

顯示包含錯誤的記錄專案

若要檢閱發生錯誤的記錄專案,請執行下列查詢:

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

使用此查詢來尋找錯誤,或修改查詢詞彙來尋找特定的例外狀況類別或錯誤碼。

顯示特定 traceId 的記錄專案

若要檢閱特定追蹤標識碼 「trace_id」 的記錄專案,請執行下列查詢:

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

下一步