共用方式為


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

注意

基本標準和企業方案將從 2025 年 3 月中旬開始淘汰,並停用 3 年。 建議您轉換至 Azure Container Apps。 如需詳細資訊,請參閱 Azure Spring Apps 淘汰公告

標準 耗用量和專用 方案將從 2024 年 9 月 30 日起淘汰,並在六個月後完成關閉。 建議您轉換至 Azure Container Apps。 如需詳細資訊,請參閱 將 Azure Spring Apps 標準取用和專用方案遷移至 Azure Container Apps

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

本文說明如何在 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 字串 Yes AppTimestamp 時間戳記 (UTC 格式)
logger 字串 No 記錄器 logger
level 字串 No CustomLevel 記錄層級
thread 字串 No Thread thread
message 字串 No 訊息 記錄訊息
stackTrace 字串 No StackTrace 例外狀況堆疊追蹤
exceptionClass 字串 No ExceptionClass 例外狀況類別名稱
mdc 巢狀 JSON No 對應的診斷內容
mdc.traceId 字串 No TraceId 分散式追蹤的追蹤識別碼
mdc.spanId 字串 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 內含式代理程式時。 請將限制設定套用至堆疊追蹤輸出 (參閱下列組態範例),確保可正確剖析最終輸出。

產生符合結構描述的 JSON 記錄

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

使用 logback 記錄

使用 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. 使用 -spring 尾碼 (如 logback-spring.xml) 的記錄組態檔時,您可根據 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 排除 spring-boot-starter-logging,在 pom.xml 檔案中新增相依性 spring-boot-starter-log4j2log4j-layout-template-json

    <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. 應用程式記錄傳回結果,如下圖所示:

    Azure 入口網站的螢幕擷取畫面,其中顯示 [記錄結果] 窗格。

顯示包含錯誤的記錄項目

若要檢閱包含錯誤的記錄項目,請執行下列查詢:

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

下一步