一、ELK介紹
對於日誌來說,最常見的需求就是收集、存儲、查詢、展示,開源社區正好有相對應的開源項目:logstash(收集)、elasticsearch(存儲+搜索)、kibana(展示),我們將這三個組合起來的技術稱之爲ELKStack,所以說ELKStack指的是Elasticsearch、Logstash、Kibana技術棧的結合。
二、Logstash簡介
Logstash 是一款強大的數據處理工具,它可以實現數據傳輸,格式處理,格式化輸出,還有強大的插件功能,常用於日誌處理。
三、Logstash工作原理
- 輸入
1) file:從文件系統上的文件讀取,與UNIX命令非常相似 tail -0F
2) syslog:在已知端口上偵聽syslog消息進行解析
3) redis:使用redis通道和redis列表從redis服務器讀取。Redis通常用作集中式Logstash安
4) 裝中的“代理”,該安裝將Logstash事件從遠程Logstash“託運人”排隊。
5) beats:處理 Beats發送的事件,beats包括filebeat、packetbeat、winlogbeat。 - 過濾
1) grok:解析並構造任意文本。Grok是目前Logstash中將非結構化日誌數據解析爲結構化和可查詢內容的最佳方式。Logstash內置了120種模式,您很可能會找到滿足您需求的模式!
2) mutate:對事件字段執行常規轉換。您可以重命名,刪除,替換和修改事件中的字段。
3) drop:完全刪除事件,例如調試事件。
4) clone:製作事件的副本,可能添加或刪除字段。
5) geoip:添加有關IP地址的地理位置的信息(也在Kibana中顯示驚人的圖表!) - 輸出
1) elasticsearch:將事件數據發送給Elasticsearch。如果您計劃以高效,方便且易於查詢的格式保存數據...... Elasticsearch是您的最佳選擇
2) file:將事件數據寫入磁盤上的文件。
3) graphite:將事件數據發送到graphite,這是一種用於存儲和繪製指標的流行開源工具。http://graphite.readthedocs.io/en/latest/
4) statsd:將事件數據發送到statsd,這是一種“偵聽統計信息,如計數器和定時器,通過UDP發送並將聚合發送到一個或多個可插入後端服務”的服務。如果您已經在使用statsd,這可能對您有用! - 編解碼器
編解碼器基本上是流過濾器,可以作爲輸入或輸出的一部分運行。使用編解碼器可以輕鬆地將消息傳輸與序列化過程分開。流行的編解碼器包括json, multiline等。
json:以JSON格式編碼或解碼數據。
multiline:將多行文本事件(例如java異常和堆棧跟蹤消息)合併到一個事件中
四、Logstash優點
- 可伸縮性
節拍應該在一組Logstash節點之間進行負載平衡。
建議至少使用兩個Logstash節點以實現高可用性。
每個Logstash節點只部署一個Beats輸入是很常見的,但每個Logstash節點也可以部署多個Beats輸入,以便爲不同的數據源公開獨立的端點。 - 彈性
Logstash持久隊列提供跨節點故障的保護。對於Logstash中的磁盤級彈性,確保磁盤冗餘非常重要。對於內部部署,建議您配置RAID。在雲或容器化環境中運行時,建議您使用具有反映數據SLA的複製策略的永久磁盤。 - 可過濾
對事件字段執行常規轉換。您可以重命名,刪除,替換和修改事件中的字段。 - 可擴展插件生態系統,提供超過200個插件,以及創建和貢獻自己的靈活性。
五、Logstash缺點
Logstash耗資源較大,運行佔用CPU和內存高。另外沒有消息隊列緩存,存在數據丟失隱患。
六、Logstash的使用
- 使用命令行運行一個簡單的logstash程序
logstash/bin/logstash -e 'input{stdin{}}output{stdout{codec=>rubydebug}}'
輸入 abc 輸出如下{
"message" => "abc",
"@version" => "1",
"@timestamp" => "2016-08-20T03:33:00.769Z",
"host" => "iZ23tzjZ"
}
- 配置語法講解
最基本的配置文件定義,必須包含input 和 output。
修改logstash.conf文件,如下
# 最基本的配置文件定義,必須包含input 和 output。
input{
stdin{ }
}
output{
stdout{
codec=>rubydebug
}
}
# 如果需要對數據進操作,則需要加上filter段
input{
stdin{ }
}
filter{
# 裏面可以包含各種數據處理的插件,如文本格式處理 grok、鍵值定義 kv、字段添加、
# geoip 獲取地理位置信息等等...
}
output{
stdout{
codec=>rubydebug
}
}
# 可以定義多個輸入源與多個輸出位置
input{
stdin{ }
file{
path => ["/var/log/message"]
type => "system"
start_position => "beginning"
}
}
output{
stdout{
codec=>rubydebug
}
file {
path => "/var/datalog/mysystem.log.gz"
gzip => true
}
}
運行命令
logstash -f logstash.conf
七、Logstash持久化到磁盤
在config/logstash.yml中進行配置以下內容
queue.type: persisted
path.queue: /usr/share/logstash/data #隊列存儲路徑;如果隊列類型爲persisted,則生效
queue.page_capacity: 250mb #隊列爲持久化,單個隊列大小
queue.max_events: 0 #當啓用持久化隊列時,隊列中未讀事件的最大數量,0爲不限制
queue.max_bytes: 1024mb #隊列最大容量
queue.checkpoint.acks: 1024 #在啓用持久隊列時強制執行檢查點的最大數量,0爲不限制
queue.checkpoint.writes: 1024 #在啓用持久隊列時強制執行檢查點之前的最大數量的寫入事件,0爲不限制
queue.checkpoint.interval: 1000 #當啓用持久隊列時,在頭頁面上強制一個檢查點的時間間隔
經測試,當重啓Logstash的時候,數據沒有丟失
八、Logstash性能測試,模擬數據量1千萬條
Logstash有kibana專門的模擬數據插件,以及速率分析工具
配置Logstash目錄下面的pipeline/logstash.conf
input{
generator {
count => 10000000 # 模擬數據1千萬條
message =>'INFO 2018-07-30 0911 springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator[startingWith:40] - Generating unique operation named: getUsingGET1$i' # 模擬數據具體內容
codec=>multiline { #multiline插件,用於合併事件
pattern => "^\s" #匹配空格
what=>"previous" #當匹配到空格,合併到上一個事件,如果是next,則合併到下一個事件
}
type=>"probe_log" #類型名稱
}
}
filter {
grok {
match =>{ "message" => "%{LOGLEVEL:level}\s%{TIMESTAMP_ISO8601:timestamp}\s%{JAVACLASS:class}[%{WORD:method}:%{NUMBER:line}]\s-\s(?([\s\S]*))" } #通過正則表達式匹配日誌
}
date {
match => [ "timestamp" , "yyyy-MM-dd HHss", "ISO8601" ] #匹配timestamp字段
target => "@timestamp" #覆蓋@timestamp
}
mutate {
remove_field => "timestamp" #移除timestamp字段
}
}
output {
elasticsearch{ #輸出到elasticsearch
hosts => ["192.168.2.227:9200"]
index => "logstash-api-%{+YYYY.MM.dd}"
}
九、1千萬條數據測試結果
模擬數據量1千萬條
通過kibana的monitoring監控
後面四個分別爲使用持久隊列過濾、使用持久隊列不過濾、使用內存隊列過濾、使用內存隊列不過濾的情況,估算出下面一張表
接收速率(event/s) |
發送速率(event/s) |
管道的發送速率(event/s) |
平均延時 |
|
使用內存隊列,不過濾 |
15758/s |
15745/s |
10500/s |
0.24ms |
使用內存隊列,過濾 |
11982/s |
11966/s |
7680/s |
0.33ms |
使用持久隊列,不過濾 |
13760/s |
14300/s |
9000/s |
0.25ms |
使用持久隊列,過濾 |
11657/s |
10331/s |
7000/s |
0.39ms |
如果有說的不明白或者錯誤的地方,歡迎指正!