以前在 Serilog 上要將 Log 傳送到 Elastic stack 都是使用 Serilog.Sinks.Elasticsearch 這個套件,不過後來 Elastic 官方推出了 Elastic.Serilog.Sinks 套件,專門支援 Elasticsearch 8.x 和以上的版本,本次將會使用新版的 Elastic.Serilog.Sinks 套件做示範,如果是 Elasticsearch 8 以前的版本請使用由社區維護的 Serilog.Sinks.Elasticsearch 套件。
註:在 DataStreamName 中的三個參數 logs, dataSet, namespace 在 Elasticsearch 的規範中不允許出現「-」,雖然可以傳送但是因為在資料儲存中使用 {類型}-{資料集}-{命名空間} 的方式儲存,所以會造成資料分析困難
上面的程式碼在執行的時候很可能出現錯誤:
原因是將資料傳送到 http://localhost:9200 時需要驗證,而我們上面沒有輸入帳號密碼,但是新版的 Elastic.Serilog.Sinks 套件沒有可以輸入帳號密碼的位置,不過還好我們可以透過在 URL 中塞入帳號密碼的方式通過驗證:
把上面的網址替換為下面這樣即可:
註:預設帳號: elastic 預設密碼: changeme
然後開啟 http://localhost:5601/app/logs/stream ,此頁面位於側邊欄 Observability > Logs 中的 Stream,調整為最近的時間後應該就會看到 log 了
如果有修改程式碼中 DataStreamName 的第一個參數 logs ,則很可能會接收不到資料,是因為有預設的過濾條件,如果有修改的話記得在右上角的 Settings 然後修改 Log sources 中的 Log indices ,將程式碼中的內容加上「-*」即可。
參考資料:
GitHub - Serilog.Sinks.Elasticsearch
GitHub - elastic/ecs-dotnet
elastic - Elastic.Serilog.Sinks
elastic - An introduction to the Elastic data stream naming scheme
stack overflow - Serilog + serilog-sinks-elasticsearch +ElasticSearch Auth
安裝
先使用 NuGet 安裝 Elastic.Serilog.Sinks 套件,或是使用 .NET CLI 執行以下指令安裝
dotnet add package Elastic.Serilog.Sinks
基礎使用示範
在上一篇 在 Docker 上快速安裝 Elastic stack (ELK) 安裝的 Logstash monitoring API 連結是 http://localhost:9200 ,在下面程式碼中 WriteTo.Elasticsearch 中就填入這個網址
using Elastic.Channels;
using Elastic.Ingest.Elasticsearch;
using Elastic.Ingest.Elasticsearch.DataStreams;
using Elastic.Serilog.Sinks;
using Serilog;
// 初始化 log
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.Enrich.FromLogContext()
.WriteTo.Elasticsearch(new[] { new Uri("http://localhost:9200") }, opts =>
{
opts.DataStream = new DataStreamName("logs", "dataSet", "namespace");
opts.BootstrapMethod = BootstrapMethod.Failure;
opts.ConfigureChannel = channelOpts =>
{
channelOpts.BufferOptions = new BufferOptions
{
ExportMaxConcurrency = 10,
};
};
})
.CreateLogger();
// 傳送 log
Log.Information("Hello, world!");
string? input = Console.ReadLine();
// 關閉 log
Log.CloseAndFlush();
註:在 DataStreamName 中的三個參數 logs, dataSet, namespace 在 Elasticsearch 的規範中不允許出現「-」,雖然可以傳送但是因為在資料儲存中使用 {類型}-{資料集}-{命名空間} 的方式儲存,所以會造成資料分析困難
上面的程式碼在執行的時候很可能出現錯誤:
Unhandled exception. System.Exception: Failure to create component template `ecs_8.6.0_agent` for logs-data-set-*: Invalid Elasticsearch response built from a unsuccessful () low level call on PUT: /_component_template/ecs_8.6.0_agent
Exception: Failed to ping the specified node. Call: unknown resource
# Audit trail of this API call:
- [1] AllNodesDead: Took: 00:00:00.0000026
- [2] Resurrection: Node: http://localhost:9200/ Took: 00:00:00.0000002
- [3] PingFailure: Node: http://localhost:9200/ Exception: PipelineException Took: 00:00:00.0027939
# OriginalException: Elastic.Transport.TransportException: Failed to ping the specified node. Call: unknown resource
原因是將資料傳送到 http://localhost:9200 時需要驗證,而我們上面沒有輸入帳號密碼,但是新版的 Elastic.Serilog.Sinks 套件沒有可以輸入帳號密碼的位置,不過還好我們可以透過在 URL 中塞入帳號密碼的方式通過驗證:
把上面的網址替換為下面這樣即可:
http://elastic:changeme@localhost:9200
註:預設帳號: elastic 預設密碼: changeme
然後開啟 http://localhost:5601/app/logs/stream ,此頁面位於側邊欄 Observability > Logs 中的 Stream,調整為最近的時間後應該就會看到 log 了
如果有修改程式碼中 DataStreamName 的第一個參數 logs ,則很可能會接收不到資料,是因為有預設的過濾條件,如果有修改的話記得在右上角的 Settings 然後修改 Log sources 中的 Log indices ,將程式碼中的內容加上「-*」即可。
參考資料:
GitHub - Serilog.Sinks.Elasticsearch
GitHub - elastic/ecs-dotnet
elastic - Elastic.Serilog.Sinks
elastic - An introduction to the Elastic data stream naming scheme
stack overflow - Serilog + serilog-sinks-elasticsearch +ElasticSearch Auth
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com