1. 程式人生 > >一套標準的ASP.NET Core容器化應用日誌收集分析方案

一套標準的ASP.NET Core容器化應用日誌收集分析方案

## 講故事 關注我公眾號的朋友,應該知道我寫了一些雲原生應用收集和分析相關的文章,其中內容大多聚焦某個具體的元件: - 超級有用的TraceId,快點用起來吧! - 如何利用NLog輸出結構化日誌,並在Kibana優雅分析日誌? | - 既然能直接向ElasticSearch寫日誌,為什麼還要logstash日誌攝取器? 本文記錄一套標準的、無侵入的的容器化應用日誌收集方案: 1. 什麼樣的日誌應該被收集? 2. 如何輸出為結構化日誌? 3. 使用EFK無侵入的收集分析日誌 ![](https://img2020.cnblogs.com/blog/587720/202011/587720-20201127185050308-1696200810.png) 定製ASP.NET Core日誌; 將結構化日誌輸出到stdout;Fluentbit無侵入式轉發容器日誌;儲存在Es並在Kibana上分析日誌 ## 定製ASP.NET Core日誌 面向網際網路的經典應用,不外乎三部分日誌:請求、業務處理、資料庫操作。 在實際採集日誌時,關注[特定日誌場景]: - 提供給第三方呼叫的API(有撕逼可能性) - 核心流程業務 (996排障) - 資料庫操作(刪庫跑路可能性) - 應用內部http請求 - Warn、Error、Fatal級別日誌(持續關注) ASP.NETCore靈活的配置系統、可插拔的元件系統,讓我們輕鬆配置日誌、管理日誌元件。 ### 日誌配置 ASP.NET Core應用的日誌配置取決於appsettings.{Environment}.json檔案的Logging配置節, 支援多個LogProvider、過濾日誌、定製特定種類日誌的收集級別。 ``` "Logging": { "LogLevel": { "Microsoft": "Warning", "Microsoft.AspNetCore.Hosting.Diagnostics": "Information", // 提供給第三方呼叫API日誌 "Microsoft.Hosting.Lifetime": "Information", "Microsoft.EntityFrameworkCore.Database.Command": "Information", //資料庫操作sql日誌 "System.Net.Http.HttpClient": "Information", // 記錄內部http請求 "Default": "Warning" // 除以上日誌之外,記錄Warning+級別日誌 } } ``` 以上Logging配置針對[特定日誌場景],滿足經典網際網路應用的日誌採集需求。 ### NLog Provider 結構化日誌提出[MessageTemplate]來解決傳統文字日誌對機器不友好的問題。 ① 這裡使用NLog Provider接管所有的日誌輸出 ``` // Please install-package NLog.Web.AspNetCore internal static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureLogging((hostBuilder, loggerBuilder) => { loggerBuilder.ClearProviders(); loggerBuilder.AddNLog("nlog.production.config"); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); ``` ② 編寫NLog[JsonLayout]將傳統文字日誌轉換為JSON格式日誌: ```
``` 與業務緊密相關的日誌字元: - includeAllProperties="true" 輸出日誌條目的所有屬性 - trace_id=${aspnet-TraceIdentifier:ignoreActivityId=true} 取得trace_id,排障時很有用 - user_id=${aspnet-user-identity} 取得該條日誌生產者的名字 啟動應用日誌長這樣: ![](https://img2020.cnblogs.com/blog/587720/202011/587720-20201127185025909-628493337.png) 請保持所有應用日誌的輸出目標為stdout,讓Fluent-bit無侵入採集! ....【TODO: 容器製作映象!!!!】 ... ## Fluent-Bit收集容器日誌 Fluent-bit採集日誌,小巧夠用! 採集容器日誌需要將容器應用的Logging Driver改為[Fluentd] Fluentd Driver預設會在宿主機24224埠監聽*Forward*訊息 。 一個簡單的容器Docker-compose示例: ``` version: "3.7" services: website: image: ${DOCKER_REGISTRY}/eap/website:0.1 ports: - "80:80" environment: - TZ=Asia/Shanghai networks: - webnet logging: driver: fluentd options: # fluentd-address: localhost:24224 tag: eap-website restart: always networks: webnet: external: true name: eap-net ``` Fluentd Driver採集的格式如下 : ``` { "container_id": "...", "container_name": "...", "source": "stdout", "log": "This is log content" } ``` 容器應用產生的json日誌(log欄位)會被編碼,這就很尷尬了,處心積慮的結構化日誌沒有萃取出日誌欄位!! ![](https://img2020.cnblogs.com/blog/587720/202011/587720-20201127184828941-1141194149.png) ![](https://img2020.cnblogs.com/blog/587720/202011/587720-20201127184902184-368316166.jpg) 多番搜尋,在Fluentbit上找到Decoders外掛, 能將被編碼的JSON字串解碼: 完整的fluent-bit.conf 如下: ``` [SERVICE] flush 1 log_Level info daemon off http_server on // 在宿主機作為http server啟動 http_listen 0.0.0.0 http_port 2020 storage.metrics on Parsers_File parsers.conf [INPUT] name forward max_chunk_size 1M max_buffer_size 5M [FILTER] Name parser Match * Key_Name log // 要解析的欄位 Parser docker // 以docker日誌格式解析在parser.conf檔案 Preserve_Key True // 保留原解析的欄位 Reserve_Data True // 保留原始其他欄位 [OUTPUT] name es match * host es01 port 9200 logstash_format on replace_dots on retry_limit false ``` 這樣輸出的結果就是: ![](https://img2020.cnblogs.com/blog/587720/202011/587720-20201127184942263-1081960572.png) nice,後面就請自由在Kibana中分析日誌吧。 完整的EFK收集容器日誌的原始碼配置,github傳送門:https://github.com/zaozaoniao/dockercompose-efk 以上就是小碼甲總結的使用EFK收集分析容器化ASP.NET Core應用的全過程, 可學習可商用。 - https://docs.fluentbit.io/manual/pipeline/parsers/decoders