一套標準的ASP.NET Core容器化應用日誌收集分析方案
- 2020 年 11 月 27 日
- 筆記
- Asp.Net Core
講故事
關注我公眾號的朋友,應該知道我寫了一些雲原生應用收集和分析相關的文章,其中內容大多聚焦某個具體的組件:
- 超級有用的TraceId,快點用起來吧!
- 如何利用NLog輸出結構化日誌,並在Kibana優雅分析日誌? |
- 既然能直接向ElasticSearch寫日誌,為什麼還要logstash日誌攝取器?
本文記錄一套標準的、無侵入的的容器化應用日誌收集方案:
- 什麼樣的日誌應該被收集?
- 如何輸出為結構化日誌?
- 使用EFK無侵入的收集分析日誌
定製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<Startup>();
});
② 編寫NLog[JsonLayout]將傳統文本日誌轉換為JSON格式日誌:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="//www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogFile="logs/nlog-internal.log" internalLogLevel="Info" >
<targets async="true">
<target name="console" xsi:type="Console">
<layout xsi:type="JsonLayout" includeAllProperties="true" excludeProperties="EventId_Id,EventId_Name,EventId">
<attribute name="time" layout="${date:format=yyyy/MM/dd HH\:mm\:ss.fff zzz}" />
<attribute name="category" layout="${logger}" />
<attribute name="log_level" layout="${level:lowerCase=true}" />
<attribute name="message" layout="${message}" />
<attribute name="trace_id" layout="${aspnet-TraceIdentifier:ignoreActivityId=true}" />
<attribute name="user_id" layout="${aspnet-user-identity}" />
<attribute name="exception" layout="${exception:format=tostring}" />
</layout>
</target>
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="console" ruleName="console" />
</rules>
</nlog>
與業務緊密相關的日誌字符:
- includeAllProperties=”true” 輸出日誌條目的所有屬性
- trace_id=${aspnet-TraceIdentifier:ignoreActivityId=true} 取得trace_id,排障時很有用
- user_id=${aspnet-user-identity} 取得該條日誌生產者的名字
啟動應用日誌長這樣:
請保持所有應用日誌的輸出目標為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字段)會被編碼,這就很尷尬了,處心積慮的結構化日誌沒有萃取出日誌字段!!
多番搜索,在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
這樣輸出的結果就是:
nice,後面就請自由在Kibana中分析日誌吧。
完整的EFK收集容器日誌的源碼配置,github傳送門://github.com/zaozaoniao/dockercompose-efk
以上就是小碼甲總結的使用EFK收集分析容器化ASP.NET Core應用的全過程, 可學習可商用。