ABP 使用ElasticSearch、Kibana、Docker 進行日誌收集
後續會根據公司使用的技術,進行技術整理分享,都是乾貨哦別忘了關注我!!!
最近領導想要我把專案日誌進行一個統一收集,因為現在環境有什麼報錯資訊都是看Logs資料夾的日誌資料,如果只有一個專案那到無所謂,但是我們現在的服務進行了模組拆分,所以看日誌需要一個一個的找不方便,之前我有接觸過Seq、ElasticSearch進行日誌收集統一檢視。
技術點
- ElasticSearch
ElasticSearch 是一個非常適合索引日誌和分析資料的開源資料庫。
- Kibana
Kibana 是 ElasticSearch 的開源資料視覺化使用者介面。將 ElasticSearch 視為資料庫,將 Kibana 視為 Web 使用者介面,您可以使用它在 ElasticSearch 中構建圖形和查詢資料。
- Serilog
Serilog 是一個用於 ASP.NET Core 的外掛,它使日誌記錄變得容易。Serilog 有多種可用的接收器 - 例如,您可以獲得純文字、SQL 和 ElasticSearch 接收器等等。
為什麼用ElasticSearch(當然後面也會介紹Seq)
- 它是免費和開源
基本功能是免費的,大部分都是免費的。如果您需要 Kibana 中的安全和警報功能,您可以購買 Kibana 的商業 X-pack 訂閱,也可以安裝一些開源替代品。
- RESTful API
查詢結果以 JSON 格式返回,這意味著結果易於使用。通過 RESTful API 查詢和插入資料意味著可以輕鬆使用任何程式語言來處理 ElasticSearch。
- 易於查詢
ElasticSearch 有一個基於 Apache Lucene 的內建全文搜尋引擎。與其他資料庫相比,Lucene 易於查詢。即使是非技術人員也可以編寫常見查詢。
- 速度很快 - 非常快
查詢大型 SQL 資料庫可能需要 10 或 20 秒。大型 ElasticSearch 資料庫上的類似查詢通常會在 10 毫秒內返回結果。
- 它是可擴充套件
它很容易擴充套件。再加上它是開源的,這意味著它在錢包上也很容易。
- 易於設定
只需啟動一個包含 ElasticSearch 和 Kibana 容器的 docker compose 檔案,您就可以開始記錄和搜尋了。
Docker搭建Elasticsearch 和 Kibana環境
這裡我們使用了docker-compose所以我們需要安裝docker-compose然後建立一個 docker-compose.yml 檔案。
mkdir -p home/docker/docker-compose
cd home/docker/docker-compose
建立一個名為 docker-compose.yml 的新檔案
vi docker-compose.yml
docker-compose.yml檔案內容
- 設定es記憶體,java程式一般很吃記憶體,根據伺服器配置進行調優
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- kibana漢化(7.0以上版本),根據個人情況決定
- output.i18n.locale="zh-CN"
version: '3.1'
services:
elasticsearch:
container_name: elasticsearch
hostname: elasticsearch
image: docker.elastic.co/elasticsearch/elasticsearch:7.9.2
restart: always
ports:
- 9200:9200
- 9300:9300
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
environment:
- xpack.monitoring.enabled=true
- xpack.watcher.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- discovery.type=single-node
kibana:
container_name: kibana
hostname: kibana
image: docker.elastic.co/kibana/kibana:7.9.2
restart: always
ports:
- 5601:5601
depends_on:
- elasticsearch
environment:
- ELASTICSEARCH_URL=http://localhost:9200
volumes:
elasticsearch-data:
執行 docker-compose.yml 檔案
容器啟動之後需要等待一會,因為初始化需要一段時間
# 構建啟動容器 -d 後臺執行
docker-compose up -d
# 停止up 命令所啟動的容器,並移除網路
docker-compose down
驗證環境
- 驗證 Elasticsearch 是否已啟動並正在執行,我們可以訪問
http://localhost:9200
(就是我們剛才開放Elasticsearch的9200埠)
- 驗證 Kibana 是否已啟動並正在執行,我們可以訪問
http://localhost:5601
(就是我們剛才開放Kibana的5601埠)
使用Abp配合Serilog 記錄日誌到 Elasticsearch
-
Serilog 包新增到專案中
- Serilog.AspNetCore
- Serilog.Enrichers.Environment
- Serilog.Sinks.Debug
- Serilog.Sinks.ElasticSearch
- Serilog.Exceptions
-
appsettings.json 中新增 Serilog 日誌和Elasticsearch地址
{
// Serilog 日誌配置
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Information",
"System": "Warning"
}
}
},
// Elasticsearch地址
"ElasticConfiguration": {
"Uri": "http://localhost:9200"
},
"AllowedHosts": "*"
}
在 Program.cs 中配置日誌記錄
接下來,通過新增以下 using 語句在 Program.cs 中配置日誌記錄:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Sinks.Elasticsearch;
using System;
using System.Reflection;
using Serilog.Exceptions;
接下來,設定 main 方法。我們要做的是在建立主機之前設定日誌記錄。這樣,如果主機無法啟動,我們可以記錄任何錯誤。
public static void Main(string[] args)
{
// 配置日誌資訊
ConfigureLogging();
// 然後建立主機,這樣如果主機出現故障,我們就可以記錄錯誤
CreateHost(args);
}
然後,在 program.cs 中新增 ConfigureLogging 和 ElasticsearchSinkOptions 方法
private static void ConfigureLogging()
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",
optional: true)
.Build();
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithExceptionDetails()
.Enrich.WithMachineName()
.WriteTo.Debug()
.WriteTo.Console()
.WriteTo.Elasticsearch(ConfigureElasticSink(configuration, environment))
.Enrich.WithProperty("Environment", environment)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
private static ElasticsearchSinkOptions ConfigureElasticSink(IConfigurationRoot configuration, string environment)
{
return new ElasticsearchSinkOptions(new Uri(configuration["ElasticConfiguration:Uri"]))
{
// 自動建立模組
AutoRegisterTemplate = true,
// 建立索引(如果不設定預設就是logstash-2022.03.06這種時間格式的)
IndexFormat = $"{Assembly.GetExecutingAssembly().GetName().Name.ToLower().Replace(".", "-")}-{environment?.ToLower().Replace(".", "-")}"
};
}
最後,新增 CreateHost 和 CreateHostBuilder 方法。請注意 CreateHostBuilder 周圍的 try/catch 塊。
private static void CreateHost(string[] args)
{
try
{
CreateHostBuilder(args).Build().Run();
}
catch (System.Exception ex)
{
Log.Fatal($"Failed to start {Assembly.GetExecutingAssembly().GetName().Name}", ex);
throw;
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureAppConfiguration(configuration =>
{
configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
configuration.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",
optional: true);
})
.UseSerilog();
然後執行一次你的程式,讓它自動建立好索引資訊,後面我們就只需要配置了
kibana配置資訊
- 點選進入預設管理空間
- 管理空間配置
Kibana 目前還不會顯示任何日誌。您必須先指定索引,然後才能檢視記錄的資料。
這裡就可以看到logstash就是我們建立的索引(我之前沒有設定索引所以就預設是logstash-2022.03.06)
輸入你的索引模式。它將顯示剛剛建立的索引模式。您可以鍵入整個索引,或使用萬用字元。
在下一頁上,選擇 @timestamp 欄位作為時間過濾器欄位名稱,然後單擊建立索引模式按鈕。
您現在可以通過單擊導航窗格中的 Discover 連結來檢視日誌。
我們程式中打出來的日誌就會被收集到這裡,這裡我就不演示怎麼寫打日誌的程式碼了哈。(剛才上廁所尿劈叉了)
配置日誌過期策略
因為我們的日誌資訊一般都不需要保留很長的時間。
(一般儲存3天左右就夠了,過期的日誌將自動清除,這樣也能減少我們日誌記憶體的消耗)
- 記得關掉熱階段的滾動更新
- 開啟刪除階段,設定過期時間,快照可以不用
關聯索引策略模式
選擇我們剛才設定的策略模組,進行關聯。(這樣我們的日誌就會自動釋放啦)