.NET Core + ELK搭建視覺化日誌分析平臺(上)

PayneQin發表於2020-03-04

Hi,各位朋友,大家好!歡迎大家關注我的部落格,我的部落格地址是: https://blog.yuanpei.me。今天是遠端辦公以來的第一個週末,雖然公司計劃在遠端兩週後恢復正常辦公,可面對著每天都有人離開的疫情,深知這一切都不會那麼容易。窗外的陽光透過玻璃照射進屋子,這一切都昭示著春天的腳步漸漸近了。可春天來了,有的人卻沒有再回來。那些在2019年結束時許下的美好期待、豪言壯語,在這樣一場災難面前,終究是如此的無力而蒼白。可不管怎麼樣,生活還是要繼續,在這些無法出門的日子裡,在這樣一個印象深刻的春節長假裡,除了做好勤洗手多通風戴口罩這些防疫保護措施以外,博主還是希望大家能夠抽空學習,通過知識來充實這“枯燥"的生活。所以,從今天開始,我將為大家帶來 .NET Core + ELK搭建視覺化日誌分析平臺 系列文章,希望大家喜歡。

什麼是ELK

當接觸到一個新的事物的時候,我們最好是從它的概念開始入手。那麼,什麼是ELK呢?ELK,是ElastaicsearchLogstashKibana三款軟體的簡稱。其中,Elastaicsearch是一個開源的全文搜尋引擎。如果你沒有聽說過它,那至少應該聽說過Lucene這個開源搜尋引擎。事實上,ElastaicsearchLucene的封裝,它提供了REST API 的操作介面 。而Logstash則是一個開源的資料收集引擎,具有實時的管道,它可以動態地將不同的資料來源的資料統一起來。最後,Kibana是一個日誌視覺化分析的平臺,它提供了一系列日誌分析的Web介面,可以使用它對日誌進行高效地搜尋、分析和視覺化操作。至此,我們可以給ELK一個簡單的定義:

ELK是一個集日誌收集、搜尋、日誌聚合和日誌分析於一身的完整解決方案。

下面這張圖,展示了ElastaicsearchLogstashKibana三款軟體間的協作關係。可以注意到,Logstash負責從應用伺服器收集日誌。我們知道,現在的應用程式都是跨端應用,程式可能執行在PC、移動端、H5、小程式等等各種各樣的終端上,而Logstash則可以將這些不同的日誌資訊通過管道轉換為統一的資料介面。這些日誌將被儲存到Elasticsearch中。我們提到Elastaicsearch是一個開源的全文搜尋引擎,故而它在資料查詢上相對傳統的資料庫有著更好的優勢,並且Elasticsearch可以根據需要搭建單機或者叢集。最終,KibanaElasticsearch中查詢資料並繪製視覺化圖表,並展示在瀏覽器中。在最新的ELK架構中,新增了FireBeat這個軟體,它是它是一個輕量級的日誌收集處理工具(Agent),適合於在各個伺服器上搜集日誌後傳輸給Logstash

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-bYcNnsGc-1583291250789)(https://i.loli.net/2020/02/15/mbJRXGo56YA9jQP.png)]

總而言之,ELK可以讓我們以一種更優雅的方式來收集日誌,傳統的日誌收集通常會把日誌寫到檔案或者資料庫中。前者,不利於日誌的集中管理和查詢;後者,則無法應對海量文字檢索的需求。所以,使用ELK可以為我們帶來下面這些便利:分散式日誌資料集中式查詢和管理;系統監控,譬如對系統硬體和應用各個元件的監控;故障排查;報表功能;日誌查詢,問題排查,上線檢查; 伺服器監控、應用監控、錯誤報警;效能分析、使用者行為分析、時間管理等等

如何安裝ELK

安裝ELK的方式,首推以Docker方式安裝。關於Docker的安裝、使用請大家查閱官方文件:https://docs.docker.com/。這裡我假設大家都已經掌握了Linux和Docker的使用。首先我們拉取ELK映象:

docker pull sebp/elk

接下來,我們利用此映象來執行一個容器:

docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 --name elk sebp/elk 

通常情況下,完成這兩個步驟以後,我們就完成了ELK安裝。此時,我們可以在瀏覽器中輸入地址:http//localhost:9200,這是Elasticsearch的預設埠。如果瀏覽器中返回了了類似下面的資訊,則表示ELK安裝成功。這裡是博主獲得的關於Elasticseach的資訊:

{
  "name" : "elk",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "GGlJrOvtT2uSfoHioLCWww",
  "version" : {
    "number" : "7.5.2",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "8bec50e1e0ad29dad5653712cf3bb580cd1afcdf",
    "build_date" : "2020-01-15T12:11:52.313576Z",
    "build_snapshot" : false,
    "lucene_version" : "8.3.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

接下來,我們繼續在瀏覽器中輸入地址:http://localhost:5601/app/kibana。顯然,這是Kibana的預設地址,至此ELK的“廬山真面目”終於揭曉,首次安裝完ELK,Kibana的介面應該試類似下面這樣:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-JLcqomLs-1583291250791)(https://i.loli.net/2020/02/15/uOQSCUxfWYManK6.png)]

按照指引,我們可以新增示例資料來感受下ELK全家桶的魅力:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-fdOemAU4-1583291250792)(https://i.loli.net/2020/02/15/j6xFzedsPf7y9gL.png)]

這樣,我們就完成ELK環境的快速搭建。下面,按照慣例,我們將實現一個“Hello World”級別的例項,即:通過ELK來收集一個ASP .NET Core應用的日誌資訊。為了讓這個示例儘可能地簡單一點,我們選擇了直接向Elasticsearch寫入日誌的方式,這裡選擇的日誌庫是Serilog

Hello ELK

本文所用的例子已釋出到Github。首先,我們準備一個ASP.NET Core的專案,MVC或者Web API都可以。接下來,在專案中引入三個依賴項:SerilogSerilog.Extensions.LoggingSerilog.Sinks.ElasticSearch。對於前兩個,如果大家用過Log4Net或者NLog應該會感到非常熟悉啦,這一點不在贅述。而第三個,從名字就可以看出來這是衝著Elasticsearch來的,因為這是這個系列的第一篇文章,所以,我們直接寫Elasticsearch即可。Logstash管道相關的內容,是一個非常複雜的東西,我們會在下一篇文章中單獨來講。

接下來,主要是Serilog在ASP.NET Core中的配置。首先是Startup類,在建構函式中初始化Serilog

public Startup(IConfiguration configuration)
{
 Log.Logger = new LoggerConfiguration()
  .Enrich.FromLogContext()
  .MinimumLevel.Debug()
  .WriteTo.Elasticsearch(
  new ElasticsearchSinkOptions(new Uri("http://localhost:9200"))
  {
   MinimumLogEventLevel = LogEventLevel.Verbose,
   AutoRegisterTemplate = true
  })
  .CreateLogger();
 Configuration = configuration;
}

還記得http://localhost:9200這個地址是什麼嗎?不錯,這是Elasticsearch的預設地址,所以,這部分程式碼主要的作用就是告訴Elasticsearch,接下來的日誌資訊都寫到Elasticsearch中。為了讓日誌的資訊更豐富一點,我們這裡設定最小的日誌事件級別為Verbose

接下來,在ConfigureServices()方法中註冊ILogger例項:

services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true));

接下來,在業務層增加日誌:

private readonly ILogger _logger = Log.Logger;
      
[HttpGet]
public double Add(double n1, double n2)
{
 _logger.Information($"Invoke {typeof(CoreCalculatorService).Name}/Add: {n1},{n2}");
 return n1 + n2;
}

至此,ELK在ASP.NET Core中的整合已經全部結束,這意味著我們所有的日誌都會寫入到ELK中。那麼,要到那裡去找這些日誌資訊呢?且聽博主娓娓道來。我們在Kibana中點選左側導航欄最底下的設定按鈕,然後再點選右側的Create index pattern按鈕建立一個索引。什麼叫做索引呢?在Elasticsearch中索引相當於一張"表",而這個“表”中的一條行記錄則被稱為Document,如圖:

為Kibana建立索引1

建立索引的時候,會發現列表中列出了目前Elasticsearch中可用的資料。以博主為例,這裡的logstash-2020.02.15就是本文中的ASP.NET Core應用產生的日誌資訊。在這裡,我們可以通過一個模糊匹配來匹配同種型別的資料。通常這裡需要我們選擇一個過濾欄位,我們選擇時間戳即可:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-Weqz2iMf-1583291250796)(https://i.loli.net/2020/02/15/8fD1EabSUV7OeZM.png)]

建立完索引,就可以看到目前收集的日誌資訊了,在此基礎上,我們可以做進一步的檢索、過濾,來生成各種各樣的“查詢”。而每一個“查詢”實際上就是一個資料來源。我們就可以利用這些資料來源來完成視覺化,這是利用ELK進行視覺化分析的一般流程:

在Kibana中檢視當前日誌資訊

下面是博主自己製作的一個簡單的視覺化看板,果然很長時間沒有再用過Kibana,我都快忘記了要怎麼做一個折線圖。這實在是一篇遲到的部落格,我早該在2019年的時候就完成這個系列的,這要命的拖延症啊,雖然沒有新冠病毒恐怖,可終究不是什麼好習慣!

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-x83syorz-1583291250799)(https://i.loli.net/2020/02/15/me7v2LBIOCUfM5a.png)]

本文小結

這篇部落格是這個系列的第一篇,是一篇珊珊來遲的部落格,因為博主早在2019年就開始著手學習ELK。考慮最新公司有使用ELK的打算,而因疫情又讓博主有充足的時間,所以,博主決定把ELK相關的內容花點時間梳理出來。ELK是一個集日誌收集、搜尋、日誌聚合和日誌分析於一身的完整解決方案。博主計劃在接下來的篇幅中介紹Logstash/FireBeat管道配置、Docker容器內的日誌收集、以及自定義日誌元件開發這些話題,希望大家繼續關注我的部落格。以上就是這篇部落格的全部內容啦,晚安!

相關文章