Elastic Stack 日誌分析平臺搭建筆記
Elastic Stack(舊稱 ELK Stack))是最受歡迎的開源日誌平臺 [ref ]。Elastic Stack 由 Elasticsearch、Logstash、Kibana 和 Beats 四個元件組成:
- Beats ,是輕量型採集器的平臺,從邊緣機器向 Logstash 和 Elasticsearch 傳送資料。
- Logstash ,集中、轉換和儲存資料,是動態資料收集管道,擁有可擴充套件的外掛生態系統,能夠與 Elasticsearch 產生強大的協同作用。
- Elasticsearch ,搜尋、分析和儲存您的資料,是基於 JSON 的分散式搜尋和分析引擎,專為實現水平擴充套件、高可靠性和管理便捷性而設計。
- Kibana ,實現資料視覺化,導覽 Elastic Stack。能夠以圖表的形式呈現資料,並且具有可擴充套件的使用者介面,供您全方位配置和管理 Elastic Stack。
Elastic Stack 是逐步發展而來的,一開始只有 Elasticsearch,專注做搜尋引擎,2013 年 1 月 Kibana 及其作者 Rashid Khan 加入 Elasticsearch 公司,同年 8 月 Logstash 及作者 Jordan Sissel 也 加入 ,原本的非官方的 ELK Stack,正式成為官方用語。2015 年 3 月,舊金山舉行的第 1 屆 Elastic{ON} 大會上,Elasticsearch 公司改名為 Elastic。兩個月後,Packetbeat 專案也 加入 Elastic,Packetbeat 和 Filebeat(之前叫做 Logstash-forwarder ,由 Logstash 作者 Jordan Sissel 開發)專案被整合改造為 Beats。加上 Beats 以後,官方不知道如何將 “B” 和 E-L-K 組合在一起(用過 ELKB 或 BELK),ELK Stack 於是改名為 Elastic Stack,並在 2016 年 10 月正式釋出 Elastic Stack 5.0 [ref1 , ref2 , ref3 ]。
使用 Logstash
Logstash( home , github )最初是來自 Dreamhost 運維工程師 Jordan Sissel 的開源專案,是管理事件和日誌的工具,能夠用於採集資料,轉換資料,然後將資料傳送到您最喜歡的“儲存庫”中(比如 Elasticsearch)。Logstash 使用 JRuby 開發,2011 年 5 月釋出 1.0 版本。2013 年 8 月 Jordan Sissel 帶著 Logstash 加入 Elasticsearch 公司,Logstash 成為 Elastic Stack 一員。
在 Ubuntu 下 安裝 、 啟動 Logstash 可以使用下面命令:
$ sudo apt-get install logstash# 安裝 logstash $ sudo systemctl start logstash.service# 系統服務方式啟動 logstash $ /usr/share/logstash/bin/logstash --version# 檢視 logstash 版本 logstash 6.5.4 $ sudo vim /etc/logstash/logstash.yml# 檢視預設 logstash.yml $ sudo vim /etc/logstash/logstash-sample.conf# 檢視示例 logstash-sample.conf
安裝完成後,二進位制檔案在 /usr/share/logstash/bin
目錄下,配置檔案位於 /etc/logstash
目錄,日誌輸出位於 /var/log/logstash
目錄,其他詳細的目錄位置的分佈情況,可以閱讀 官方文件 。
最簡單的示例
Logstash 管道(pipeline)由 input
、 filter
和 output
三個元素組成,其中 input
和 output
必須設定,而 filter
可選。 input
外掛從資料來源中消費資料, filter
外掛按指定方式修改資料, output
外掛將資料寫入特定目標中 [doc ]。
現在來試試 Logstash 下 Hello Wolrd 級別的示例,執行下面命令:
$ sudo /usr/share/logstash/bin/logstash -e 'input { stdin { } } output { stdout {} }'
-e
選項能夠使 Logstash 直接在 命令列 中設定管道配置。示例中 input
外掛為 stdin (標準輸入), output
外掛是 stdout (標準輸出)。若在控制檯輸入 hello world
,相應的控制檯將輸出:
{ "@version" => "1", "host" => "ubuntu109", "@timestamp" => 2019-01-12T05:52:56.291Z, "message" => "hello world" }
值得注意的是,輸出內容編碼格式預設為 rubydebug
,使用 Ruby 的 " awesome_print " 庫列印。另外,響應輸出 @timestamp
欄位的值為 2019-01-12T05:52:56.291Z
,這是 ISO 8601 時間格式,時區是 0(zero),和北京時間相差 8 個小時。
輸出內容編碼格式,可以通過 codec
指令指定。除了預設的 rubydebug
外,官方還支援其他 20 多種編碼格式,參見 doc 。若把編碼格式改為 json
,即 stdout { codec => json }
,輸出結果將變成:
{"message":"hello world","@version":"1","@timestamp":"2019-01-12T05:52:56.291Z","host":"ubuntu109"}
管道配置也可以儲存到檔案中,以 *.conf
作為檔案字尾,比如儲存為 test-stdin-stdout.conf
:
input { stdin { } } output { stdout { } }
啟動 logstash 時, -f
選項用於指定管道配置檔案的路徑:
$ sudo /usr/share/logstash/bin/logstash -f ~/test-stdin-stdout.conf
預設情況下,在啟動 logstash 後,若再修改管道配置檔案,新的修改需要重啟 logstash 才能載入生效。在開發除錯時,不太方便。解決這個問題,可以使用 -r
命令列 選項 。開啟這個選項後,只要確定配置檔案已經發生變更,便會自動重新載入配置檔案。
file 輸入外掛
上文日誌是控制檯輸入的,但真實情況日誌在日誌檔案中,要想使用 Logstash 讀取日誌檔案,官方提供了 file 輸入外掛。管道配置檔案示例 test-file-stdout.conf
,如下:
input { file { path => ["/home/yulewei/test.log"] sincedb_path => "/dev/null" start_position => "beginning" } } filter { } output { stdout { codec => rubydebug } }
啟動 Logstash:
$ sudo /usr/share/logstash/bin/logstash -r -f ~/test-file-stdout.conf
配置檔案中的 path
指令用於指定日誌檔案的路徑。 start_position
指令設定 Logstash 啟動時讀取日誌檔案的位置,可以設定為 beginning
或者 end
,預設是 end
,即檔案末尾。
為了跟蹤每個輸入檔案中已處理了哪些資料,Logstash 檔案輸入外掛會使用名為 sincedb 的檔案來記錄現有位置。由於我們的配置用於開發,所以我們希望能夠重複讀取檔案,並進而希望禁用 sincedb 檔案。在 Linux 系統上,將 sincedb_path
指令設定為 “/dev/null” 即可禁用。若沒有禁用,預設儲存的 sincedb 檔案將在 /usr/share/logstash/data/plugins/inputs/file/
目錄下。
grok 過濾外掛
上文的例子,做的核心事情就是把日誌行轉換到 message
欄位,並附加某些元資料,如 @timestamp
。如果要想解析自己的日誌,把非結構化日誌轉換結構換日誌,有兩個過濾器特別常用: dissect 會根據分界符來解析日誌,而 grok 則會根據正則表示式匹配來執行。
如果資料結構定義非常完善,dissect 過濾外掛的執行效果非常好,而且執行速度非常快捷高效。同時,其也更加容易上手,對於不熟悉正則表示式的使用者而言,更是如此。通常而言,grok 的功能更加強大,而且可以處理各種各樣的資料。然而,正則表示式匹配會耗費更多資源,而且速度也會慢一些,如果未能正確進行優化的話,尤為如此。
現在先來看下 grok 過濾外掛。grok 模式的基本語法是 %{SYNTAX:SEMANTIC}
, SYNTAX
是用於匹配資料的模式(或正則表示式)名稱, SEMANTIC
是識別符號或欄位名稱。Logstash 提供了超過 120 種預設的 grok 模式,全部預定義的模式可以在 github 上找到。典型的預定義模式(非完整列表) [github ]:
- WORD - 匹配單個詞彙的模式
- NUMBER - 匹配整數或浮點數(正值或負值均可)的模式
- POSINT - 匹配正整數的模式
- EMAILADDRESS - 郵箱地址
- IP - 匹配 IPv4 或 IPv6 IP 地址的模式
- URI - URI 地址
- TIMESTAMP_ISO8601 - ISO8601 格式的時間
- NOTSPACE - 匹配非空格的任何內容的格式
- SPACE - 匹配任何數量的連續空格的模式
- DATA - 匹配任何資料型別的限定數量的模式
- GREEDYDATA - 匹配剩餘所有資料的格式
比如, 3.44
可以使用 NUMBER
模式進行匹配, 192.168.2.104
可以使用 IP
模式。 %{NUMBER:num} %{IP:client}
模式,將會用 NUMBER
模式把 3.44
識別為 num
欄位,用 IP
模式把 192.168.2.104
識別為 client
欄位。預設情況識別獲得的欄位值是字串型別,grok 外掛支援把型別轉換為 int
或 float
。要想把 3.44
轉換為浮點數,可以使用 %{NUMBER:num:float}
。
假設有如下日誌內容:
Will, [email protected], 42, 1024, 3.14
grok 匹配表示式可以寫成這樣:
%{WORD:name}, %{EMAILADDRESS:email}, %{NUMBER:num1}, %{NUMBER:num2:int}, %{NUMBER:pi:float}
即,在這一行日誌中依次提取出, name
、 email
、 num1
、 num2
和 pi
欄位。完整的 filter
過濾器配置的寫法:
filter { grok { match => { "message" => "%{WORD:name}, %{EMAILADDRESS:email}, %{NUMBER:num1}, %{NUMBER:num2:int}, %{NUMBER:pi:float}" } } }
啟動 logstash:
$ sudo /usr/share/logstash/bin/logstash -r -f ~/test-file-grok-stdout.conf
控制檯將輸出:
{ "@version" => "1", "message" => "Will, [email protected], 42, 1024, 3.14", "num1" => "42", "pi" => 3.14, "@timestamp" => 2019-01-12T08:12:49.581Z, "path" => "/home/yulewei/test-grok.log", "host" => "ubuntu109", "email" => "[email protected]", "name" => "Will", "num2" => 1024 }
Logstash 提供了超過 120 種預設的 grok 模式,基本上滿足大多數使用場景。若沒有符合要求的預定義的模式,可以使用 Oniguruma 語法指定正則表示式:
(?<field_name>the pattern here)
上文中的 %{WORD:name}
和 %{EMAILADDRESS:email}
,等價的正則表示式的寫法如下 [ref1 , ref2 ]:
(?<name>\w+) (?<email>[a-zA-Z][a-zA-Z0-9_.+-=:]+@[0-9A-Za-z][0-9A-Za-z-]{0,62}\.[0-9A-Za-z][0-9A-Za-z-]{0,62})
除錯 grok 匹配表示式容易出錯,官方提供視覺化的 Grok Debugger 工具,提高除錯效率。
解析 http 伺服器日誌
現在來看下,真實的日誌解析案例,使用 grok 過濾外掛解析 http 伺服器日誌。通用日誌格式( Common Log Format ),是 http 伺服器的標準的日誌格式。對通用日誌格式擴充套件,加上額外的 referer 和 user-agent 欄位,稱為組合日誌格式(Combined Log Format)。兩種日誌格式包含的欄位如下:
# 通用日誌格式 %remote-host %ident %authuser %timestamp "%request" %status %bytes # 組合日誌格式 %remote-host %ident %authuser %timestamp "%request" %status %bytes "%referer" "%user-agent"
Apache 和 Nginx 伺服器預設的日誌格式,採用的就是通用日誌格式或者組合日誌格式。解析這兩種日誌格式,Logstash 提供預定義模式 COMMONAPACHELOG 和 COMBINEDAPACHELOG 。
典型的 nginx 日誌例子:
192.168.2.104 - - [13/Jan/2019:02:01:15 +0800] "GET /images/avatar.png HTTP/1.1" 200 266975 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:64.0) Gecko/20100101 Firefox/64.0"
管道配置檔案示例 test-file-grokhttp-stdout.conf
,如下:
input { file { path => ["/var/log/nginx/access.log"] sincedb_path => "/dev/null" start_position => "beginning" } } filter { grok { match => { "message" => "%{COMBINEDAPACHELOG}" } remove_field => ["message"] } } output { stdout { } }
示例中使用了 grok 的預定義模式 COMBINEDAPACHELOG 。另外, remove_field
指令 用於把輸出事件中某欄位刪除,示例中是 message
欄位。
啟動 logstash:
$ sudo /usr/share/logstash/bin/logstash -r -f ~/test-file-grokhttp-stdout.conf
解析獲得的結構化資料,如下:
{ "auth" => "-", "host" => "ubuntu109", "verb" => "GET", "clientip" => "192.168.2.104", "@version" => "1", "httpversion" => "1.1", "@timestamp" => 2019-01-13T13:35:52.983Z, "bytes" => "266975", "timestamp" => "13/Jan/2019:02:01:15 +0800", "request" => "/images/avatar.png", "response" => "200", "referrer" => "\"-\"", "path" => "/var/log/nginx/access.log", "agent" => "\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:64.0) Gecko/20100101 Firefox/64.0\"", "ident" => "-" }
dissect 過濾外掛
和 grok 過濾外掛使用正則表示式提取欄位不同,dissect 過濾外掛使用分界符切割來提取欄位。由於沒有使用正則表示式,執行速度相對 grok 快很多。使用 dissect 過濾外掛時,需要指明提取欄位的順序,還要指明這些欄位之間的分界符。過濾外掛會對資料進行單次傳輸,並匹配模式中的分界符。同時,過濾外掛還會將分界符之間的資料分配至指定欄位。過濾外掛不會對所提取資料的格式進行驗證。
現在看下示例, test-dissect.log
檔案內容如下:
Will, [email protected], 42, 1024, 3.14
dissect 匹配規則可以寫成這樣:
%{name}, %{email}, %{num1}, %{num2}, %{num3}
完整的配置檔案, test-file-dissect-stdout.conf
:
input { file { path => ["/home/yulewei/test-dissect.log"] sincedb_path => "/dev/null" start_position => "beginning" } } filter { dissect { mapping => { "message" => "%{name}, %{email}, %{num1}, %{num2}, %{num3}" } convert_datatype => { "num2" => "int" "num3" => "float" } } } output { stdout { } }
和 grok 外掛一樣,預設提取的欄位是字串型別。配置檔案中的 convert_datatype
指令用於將型別轉為 int
或 float
。
啟動 logstash:
$ sudo /usr/share/logstash/bin/logstash -r -f ~/test-file-dissect-stdout.conf
輸出結果:
{ "host" => "ubuntu109", "num1" => "42", "message" => "Will, [email protected], 42, 1024, 3.14", "@version" => "1", "name" => "Will", "num2" => 1024, "@timestamp" => 2019-01-13T13:32:10.900Z, "path" => "/home/yulewei/test-dissect.log", "email" => "[email protected]", "num3" => 3.14 }
輸出到 Elasticsearch
上文舉的例子全部都是,輸出控制檯,使用 stdout
輸出外掛,沒有實用價值。Elastic Stack 的核心其實是 Elasticsearch,使用Elasticsearch 搜尋和分析日誌。想要將資料傳送到 Elasticsearch,可以使用 elasticsearch 輸出外掛。
安裝 Elasticsearch
如果沒有安裝 Elasticsearch,參考 官方文件 按步驟安裝。唯一要注意的是,在執行 apt install
命令前,必須先新增 elastic 的軟體源地址,否則無法正常啟動。核心命令如下:
$ sudo apt-get install elasticsearch# 安裝 elasticsearch $ sudo systemctl start elasticsearch.service# 系統服務方式啟動 elasticsearch $ curl http://localhost:9200/# 用 rest 介面檢視 elasticsearch { "name" : "1t9JXt5", "cluster_name" : "elasticsearch", "cluster_uuid" : "yQgVsvupSqGCGQbwqnanIg", "version" : { "number" : "6.5.4", "build_flavor" : "default", "build_type" : "deb", "build_hash" : "d2ef93d", "build_date" : "2018-12-17T21:17:40.758843Z", "build_snapshot" : false, "lucene_version" : "7.5.0", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search" }
預設情況下 elasticsearch 伺服器繫結的 ip 地址是迴環地址 127.0.0.1
,若想繫結特定 ip 地址,可以修改 /etc/elasticsearch/elasticsearch.yml
配置檔案中的 network.host 選項:
network.host: 192.168.2.109
修改完成並重啟後,elasticsearch 伺服器訪問地址從 http://localhost:9200/
變成 http://192.168.2.109:9200/
。
輸出到 Elasticsearch
現在來看下 elasticsearch 輸出外掛。示例, test-file-elasticsearch.conf
:
input { file { path => ["/home/yulewei/test.log"] sincedb_path => "/dev/null" start_position => "beginning" } } output { elasticsearch { hosts => ["http://192.168.2.109:9200"] index => "logstash-%{+YYYY.MM.dd}" } }
示例的 elasticsearch
輸出外掛使用了 hosts
和 index
指令。 hosts
指令,用於指定 elasticsearch 伺服器的地址。而 index
指令,用於指定 elasticsearch 索引的名稱模式,該指令預設值為 logstash-%{+YYYY.MM.dd}
。在字串內部的 %{...}
,是 Logstash 字串插值語法,官方稱之為 sprintf format
[doc ]。 +YYYY.MM.dd
,用於指定 @timestamp
的格式化的格式。 logstash-%{+YYYY.MM.dd}
,格式化後最終生成的值可能將是 logstash-2019.01.13
。
啟動 logstash:
$ sudo /usr/share/logstash/bin/logstash -r -f ~/test-file-elasticsearch.conf
檢視在 elasticsearch 上新建立的 logstash-*
索引以及從 logstash 同步過來的日誌資料:
$ curl http://192.168.2.109:9200/_cat/indices yellow open logstash-2019.01.13tFjc5xL_QYeNw4oqe4odeg 5 13 0 15.5kb 15.5kb $ curl 'http://192.168.2.109:9200/logstash-*/_search?pretty' -H 'Content-Type: application/json' -d'{"size": 1}' { "took" : 0, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 3, "max_score" : 1.0, "hits" : [ { "_index" : "logstash-2019.01.13", "_type" : "doc", "_id" : "RUHNRWgBLIBntI4FV8Rf", "_score" : 1.0, "_source" : { "path" : "/home/yulewei/test.log", "@timestamp" : "2019-01-13T06:01:51.303Z", "@version" : "1", "host" : "ubuntu109", "message" : "hello world" } } ] } }
可以看到,新的索引名為 logstash-2019.01.13
。同步過來的日誌記錄全部有 5 條,第 1 條日誌的 message
內容是 hello world
。
使用 Kibana
Kibana,能夠對 Elasticsearch 中的資料進行視覺化,是 Elastic Stack 的視窗。在 Ubuntu 下 安裝 Kibana 可以使用下面命令:
$ sudo apt-get install kibana# 安裝 kibana,當前最新版為 6.5.4 $ sudo systemctl start kibana.service# 系統服務方式啟動 kibana
預設配置下,kibana 服務訪問地址是 http://localhost:5601/
,連線的 elasticsearch 地址是 http://localhost:9200
,這兩個配置分別由 server.host
和 elasticsearch.url
控制 [doc ]。上文嘗試過把 elasticsearch 服務 ip 地址繫結到 192.168.2.109
。現在來試下繫結 ip 地址到 kibana,編輯配置檔案 /etc/kibana/kibana.yml
,修改為:
server.host: "192.168.2.109" elasticsearch.url: "http://192.168.2.109:9200"
使用 sudo systemctl restart kibana.service
重啟後,kibana 服務訪問地址變成 http://192.168.2.109:5601/
。
elasticsearch 伺服器上存在索引 logstash-2019.01.13
,要想把這個索引匯入到 kibana,參考官方 教程 即可。點選 Management
選單,然後建立索引模式(index pattern)。索引模式可以直接為 logstash-2019.01.13
,這樣匹配單個索引。若要匹配多個時間的 logstash 索引,可以使用萬用字元 *
,比如 logstash-*
。如果要匹配全部 2019 年 01 月的索引,可以寫成 logstash-2019.01*
。完成索引模式定義後,便可以在 Discover
選單下檢視索引,如圖:
使用 Filebeat
Filebeat,輕量型日誌採集器 [home ]。其前身是由 Logstash 作者 Jordan Sissel 開發的 Logstash Forwarder 。Logstash Forwarder 專案因為和收購過來的 Packetbeat 專案功能相近,並且都是 Go 語言開發,就一起被整合改造為 Beats [ref ]。
我們知道,Logstash 使用 JRuby 開發,執行依賴 JVM,會消耗較多的系統資源。為了減少系統資源(CPU、記憶體和網路)的使用,Logstash Forwarder 改用 Go 語言開發。另外,在功能上也做了精簡,只做單一的資料傳輸,不像 Logstash 有資料過濾能力。Logstash 類似於功能多樣的“瑞士軍刀”,能提供從多個數據源載入資料的功能,使用各種強大的外掛來處理日誌,並提供將多個來源的輸出資料進行儲存的功能。簡而言之,Logstash 提供資料 ETL(資料的提取、變換和載入)的功能;而 Beats 是輕量級的資料傳輸工具,能將資料傳輸到 Logstash 或 Elasticsearch 中,其間沒有對資料進行任何轉換 [Gupta2017 ]。Filebeat 和 Logstash 的關係如下圖所示 [logz.io ]:
安裝 filebeat 很簡單,參考 官方文件 即可,核心命令如下:
$ sudo apt-get install filebeat# 安裝 filebeat $ filebeat version# 檢視 filebeat 版本 filebeat version 6.5.4 (amd64), libbeat 6.5.4 [bd8922f1c7e93d12b07e0b3f7d349e17107f7826 built 2018-12-17 20:22:29 +0000 UTC] $ sudo systemctl start filebeat.service# 系統服務方式啟動 filebeat
輸出到 Elasticsearch
修改 filebeat 配置檔案 /etc/filebeat/ filebeat.yml ,示例如下:
filebeat.inputs: - type: log paths: - /home/yulewei/test.log output.elasticsearch: hosts: ["192.168.2.109:9200"]
filebeat.inputs
選項用於配置日誌的 輸入方式 。子選項 type
支援 log
、 stdin
、 redis
、 udp
、 tcp
等,示例中使用了 log
,表明從日誌檔案輸入。
output
選項用於配置日誌的 輸出方式 ,配置支援 elasticsearch、logstash、kafka、redis、file、console 等,一次只能選擇配置其中某一個。示例配置了 output.elasticsearch.hosts
,指定日誌輸出目標 elasticsearch 的主機地址。 output.elasticsearch.index
可以用來指定索引 index 名稱模式,預設是 filebeat-%{[beat.version]}-%{+yyyy.MM.dd}
(比如 filebeat-6.5.4-2019.01.12
) [doc ]。
完成 filebeat.yml
修改後,重啟 filebeat,將可以看到,在 elasticsearch 上新建立的 filebeat-*
索引:
$ curl http://192.168.2.109:9200/_cat/indices yellow open filebeat-6.5.4-2019.01.12 B4JbQDnZQuK5XvsQ77uedA 3 1 11043 01.7mb1.7mb
輸出到 Logstash
上文的示例直接把 Filebeat 採集的日誌傳輸到 Elasticsearch,日誌資料並沒有被解析或者轉換。若想解析和轉換日誌,需要在Filebeat 和 Elasticsearch 中間引入 Logstash。現在看下把日誌輸出到 Logstash 的示例配置檔案, filebeat.yml
示例:
filebeat.inputs: - type: log paths: - /home/yulewei/test.log output.logstash: hosts: ["localhost:5044"]
filebeat.inputs
和上文的示例一樣。不同的是,把 output.elasticsearch.hosts
改成了 output.logstash.hosts
,指定日誌輸出目標 Logstash 的主機地址。 5044
這個埠是 Logstash 用於監聽 Filebeat 的埠。
現在來看下 Logstash 的管道配置檔案,示例 test-beats-stdout.conf
:
input { beats { port => 5044 } } output { stdout { codec => rubydebug } }
示例中,使用了 beats 輸入外掛,配置的埠就 filebeat.yml
中指定的 5044
。輸出外掛為 stdout
,即把 Logstash 採集到日誌輸出到控制檯。
重啟 filebeat 和 logstash:
$ cat test.log# 檢視日誌檔案內容 hello world $ sudo systemctl restart filebeat.service# 重啟 filebeat $ sudo /usr/share/logstash/bin/logstash -r -f ~/test-beats-stdout.conf
控制檯輸出:
{ "tags" => [ [0] "beats_input_codec_plain_applied" ], "source" => "/home/yulewei/test.log", "input" => { "type" => "log" }, "message" => "hello world", "@timestamp" => 2019-01-12T13:32:05.131Z, "@version" => "1", "prospector" => { "type" => "log" }, "beat" => { "hostname" => "ubuntu109", "version" => "6.5.4", "name" => "ubuntu109" }, "offset" => 0, "host" => { "os" => { "version" => "16.04.4 LTS (Xenial Xerus)", "platform" => "ubuntu", "codename" => "xenial", "family" => "debian" }, "architecture" => "x86_64", "id" => "29b1bf39547d4ca9ae26c3b7656ff9e3", "containerized" => false, "name" => "ubuntu109" } }
整合 Filebeat, Logstash, Elasticsearch, Kibana
真實場景下,日誌檔案可能分佈在多臺伺服器上,同一臺伺服器上也可能分佈著不同來源型別的日誌。現在我們來嘗試下,使用 Filebeat 把兩個日誌檔案各自採集到兩個不同的 Elasticsearch 索引中,並用 Kibana 視覺化。有兩個日誌檔案 test-beats1.log
和 test-beats2.log
,內容如下:
$ cat test-beats1.log hello world1 hello world1 $ cat test-beats2.log hello world2
filebeat.yml
配置示例:
filebeat.inputs: - type: log paths: - /home/yulewei/test-beats1.log fields: log_type: test1 - type: log paths: - /home/yulewei/test-beats2.log fields: log_type: test2 output.logstash: hosts: ["localhost:5044"]
示例配置檔案使用了 filebeat.inputs.fields
選項, fields 選項用於在日誌事件輸出中新增欄位。新增的欄位名可以任意指定,示例中名為 log_type
。因為現在在 filebeat 配置中同時匯入兩個日誌檔案,輸出到同一個 logstash 中。使用這個額外欄位是為了區分日誌是來自 test-beats1.log
還是 test-beats2.log
。示例中,第 1 個日誌事件輸出的 log_type
欄位值配置為 test1
, 第 2 個日誌配置為 test2
。
管道配置檔案示例, test-beats-elasticsearch.conf
:
input { beats { port => 5044 } } output { elasticsearch { hosts => ["http://192.168.2.109:9200"] index => "filebeat-%{[fields][log_type]}-%{+YYYY.MM.dd}" } stdout { codec => rubydebug } }
輸出外掛同時使用了 elasticsearch
和 stdout
。配置檔案中的 elasticsearch
輸出外掛的 index
指令被設定為 filebeat-%{[fields][log_type]}-%{+YYYY.MM.dd}
。 [fields][log_type]
引用的是在 filebeat.yml
的 filebeat.inputs.fields
選項新增的 log_type
欄位(關於在配置檔案引用欄位的語法,可以參考 官方文件 )。根據 log_type
欄位不同,把日誌將輸出到不同的索引中。因為 filebeat.yml
配置檔案中設定的 log_type
欄位是 test1
或者 test2
,所以最終生成的索引名是 filebeat-test1-*
或者 filebeat-test1-*
。 filebeat-test1-*
索引中全部日誌資料來自 test-beats1.log
日誌檔案, filebeat-test2-*
索引資料來自 test-beats2.log
。
啟動 filebeat 和 logstash:
$ sudo systemctl restart filebeat.service $ sudo /usr/share/logstash/bin/logstash -r -f ~/test-beats-elasticsearch.conf
控制檯輸出:
... { "@version" => "1", "host" => { "name" => "ubuntu109" }, "message" => "hello world2", "prospector" => { "type" => "log" }, "fields" => { "log_type" => "test2" }, "offset" => 0, "tags" => [ [0] "beats_input_codec_plain_applied" ], "beat" => { "name" => "ubuntu109", "version" => "6.5.4", "hostname" => "ubuntu109" }, "@timestamp" => 2019-01-13T09:32:11.845Z, "source" => "/home/yulewei/test-beats2.log", "input" => { "type" => "log" } } ...
檢視在 elasticsearch 上新建立的 filebeat-test1-*
和 filebeat-test1-*
索引:
$ curl http://192.168.2.109:9200/_cat/indices/filebeat-* yellow open filebeat-test1-2019.01.13 NLVfFJl5TQ-7I1r9KoVLaQ 5 1 5 0 31.8kb 31.8kb yellow open filebeat-test2-2019.01.13 NnsBp3P9Q3-mLc8chE-Tiw 5 1 3 0 24.1kb 24.1kb
在 kibana 上檢視收集的日誌:
參考資料
- 發展歷程| Elastic https://www.elastic.co/cn/abo...
- 2013-01 Welcome Drew & Rashid (Kibana) https://www.elastic.co/blog/w...
- 2013-08 Welcome Jordan & Logstash https://www.elastic.co/blog/w...
- 2015-05 Welcome Packetbeat, Tudor & Monica https://www.elastic.co/blog/w...
- 2015-11 The Beats 1.0.0 https://www.elastic.co/blog/b...
- 2016-02 Heya, Elastic Stack and X-Pack https://www.elastic.co/blog/h...
- 2016-10 Elastic Stack 5.0 正式釋出 https://www.elastic.co/cn/blo...
- 2018-05 官方:Logstash 實用介紹 https://www.elastic.co/cn/blo...
- Filebeat vs. Logstash — The Evolution of a Log Shipper https://logz.io/blog/filebeat...
- 精通Elastic Stack,Gupta,2017 https://book.douban.com/subje...
- logstash - open source log management https://web.archive.org/web/2...
- Logstash Config Language https://web.archive.org/web/2...
- Accessing Event Data and Fields in the Configuration https://www.elastic.co/guide/...
- Logstash Configuration Examples https://www.elastic.co/guide/...