在 Spring Boot中實現包含上下文資訊的JSON日誌? - zachelrath
在除錯棘手的問題時,要使日誌發揮作用,上下文是至關重要的。每條日誌都應該始終包含與請求相關的租戶、使用者、訂單等的關鍵細節。日誌還必須是結構化的,以便可被日誌聚合器(如DataDog、StackDriver、Kibana等)解析和搜尋。
當我開始與Spring合作時,我希望實現與日誌相關的兩個關鍵目標。
- 在與特定API請求相關的所有日誌訊息中自動包含關鍵的請求環境細節
- 為每個API請求記錄一個結構化的訊息,提供關於請求(如端點、查詢引數)和響應(如狀態程式碼、持續時間)的基本細節。
具體來說:在審查日誌資訊時,通常會有一些與特定請求相關的關鍵 "上下文 "資訊,這些資訊最好是出現在與請求相關的每條日誌資訊中,但每個請求都不一樣。
例如,在認證的應用程式中,在所有的日誌訊息中包含使用者ID或租戶ID(在多租戶應用程式中),在試圖快速診斷一個問題時非常有幫助,因為你可以找到一個給定的日誌訊息,抓住租戶ID或使用者ID,然後使用這些來搜尋與該使用者相關的其他錯誤,或檢查該租戶是否有一些奇怪的配置設定,等等。或者,對於內部服務,你可能有一個訂單號,為了診斷處理該訂單的某個步驟的問題,你想過濾你的日誌,只顯示與給定訂單號相關的日誌。
我感到驚訝的是,我發現描述如何在Spring Boot中具體實現這些目標的資源很少。
此應用程式提供瞭如何使用 Log4j2 在 Spring Boot 應用程式中進行結構化、上下文日誌記錄的示例。結構化的JSON格式日誌如下案例:
{ "instant" : { "epochSecond" : 1636639189, "nanoOfSecond" : 190833000 }, "thread" : "http-nio-8080-exec-1", "level" : "INFO", "loggerName" : "com.zachelrath.springboot.structuredloggingdemo.OrderController", "message" : "Getting items", "endOfBatch" : false, "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger", "contextMap" : { "orderNumber" : "123", "retailer" : "acme" }, "threadId" : 24, "threadPriority" : 5 } { "instant" : { "epochSecond" : 1636639189, "nanoOfSecond" : 193742000 }, "thread" : "http-nio-8080-exec-1", "level" : "INFO", "loggerName" : "com.zachelrath.springboot.structuredloggingdemo.OrderController", "message" : "Got items, returning", "endOfBatch" : false, "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger", "contextMap" : { "orderNumber" : "123", "retailer" : "acme" }, "threadId" : 24, "threadPriority" : 5 } |
點選標題檢視Github程式碼,主控制器位於此處:OrderController。
執行: mvn spring-boot:run
為什麼使用Log4j2?
如果你熟悉Spring Boot,你可能會想,既然Spring Boot使用Logback作為其日誌框架,為什麼還要使用Log4j2?
我不會去爭論各種Java日誌庫的利弊,因為已經有很多其他的文章都是這樣寫的,但簡單的答案是這樣的。Log4j2的非同步日誌在高交易量方面大大超過了Logback,同時提供了一個開發者友好的API,相當容易使用。因此,我現在的公司已經將Log4j2標準化,用於高吞吐量的應用。
原理實現
Logback和Log4j2都支援一種叫做 "對映的診斷上下文"(Mapped Diagnostic Context)的功能,即MDC,每個執行緒都有一個字典/對映的上下文,然後你可以根據需要從中讀取和寫入。儲存線上程的MDC中的資料可以使用%X變數進行記錄。你可以記錄所有的MDC,也可以只記錄特定的資訊,例如,如果你的日誌模式包括%X{orderNumber},那麼只有執行緒的MDC中 "orderNumber "鍵的值會被記錄。由於每個網路請求都是由不同的執行緒來處理的,這就給了我們想要的東西。
相關文章
- 在Spring Boot中實現WebSocket實時通訊Spring BootWeb
- Spring boot學習(六)Spring boot實現AOP記錄操作日誌Spring Boot
- Spring Boot日誌框架實踐Spring Boot框架
- Spring Boot與日誌Spring Boot
- Spring Boot日誌使用Spring Boot
- Spring Boot日誌配置Spring Boot
- 如何訪問Docker容器中的Spring Boot日誌DockerSpring Boot
- Spring Boot logback日誌配置Spring Boot
- Spring Boot 整合 Logback 日誌Spring Boot
- Spring Boot日誌的使用和配置Spring Boot
- 在spring boot中訊息推送系統設計與實現Spring Boot
- Spring Boot中使用Loki日誌Spring BootLoki
- Spring Boot--日誌框架的學習Spring Boot框架
- OCP開源專案:日誌公共元件的實現(log-spring-boot-starter)元件Springboot
- 利用Spring Boot實現微服務的API閘道器統一日誌Spring Boot微服務API
- 在Spring Boot中實現OAuth2.0認證Spring BootOAuth
- Spring Boot利用AOP獲取使用者操作實現日誌記錄Spring Boot
- Spring Boot AOP 掃盲,實現介面訪問的統一日誌記錄Spring Boot
- 在Spring Boot實現國際化的案例Spring Boot
- 在Spring Boot中實現API閘道器與路由Spring BootAPI路由
- Spring boot webflux 中實現 RequestContextHolderSpring BootWebUXContext
- Spring Boot中實現Thymeleaf通知Spring Boot
- Spring Boot 揭祕與實戰(三) 日誌框架篇 – 如何快速整合日誌系統Spring Boot框架
- ELK 處理 Spring Boot 日誌,不錯!Spring Boot
- Spring boot日誌---slf4j+logbackSpring Boot
- EVCache快取在 Spring Boot中的實戰快取Spring Boot
- Spring Boot 2 中的預設日誌管理與 Logback 配置詳解Spring Boot
- Docker安裝ELK並實現JSON格式日誌分析DockerJSON
- 使用Spring Boot實現訊息佇列Spring Boot佇列
- Spring Boot 學習筆記(5):日誌配置Spring Boot筆記
- Laravel 實現使用中介軟體記錄所有請求資訊以及日誌純 JSON 格式儲存LaravelJSON
- Spring Boot 配置中的敏感資訊如何保護?Spring Boot
- 在日誌中記錄Java異常資訊的正確姿勢Java
- Spring Boot 2 中如何使用 Log4j2 記錄日誌Spring Boot
- Spring AOP實現統一日誌輸出Spring
- Spring Boot 3.4 正式釋出,結構化日誌!Spring Boot
- 在 Java Spring Boot 專案中使用結構化日誌節省時間JavaSpring Boot
- Spring Boot 入門(五):整合 AOP 進行日誌管理Spring Boot