0、題記
本文建立在乾貨 | Logstash Grok數據結構化ETL實戰上,並專注於在Grok中使用自定義正則表達式。
有時Logstash沒有我們需要的模式。 幸運的是,我們有正則表達式庫:Oniguruma。
Oniguruma是一個靈活的正則表達式庫。 它包含多種語言的不同正則表達式實現的特性。
Github地址:https://github.com/kkos/oniguruma
1、基礎再認知
Logstash:一個服務器端數據處理管道,它同時從多個源中提取數據,對其進行轉換,然後將其發送到Elasticsearch“存儲”。
Grok:Logstash中的過濾器,用於將非結構化數據解析爲結構化和可查詢的數據。
正則表達式:定義搜索模式的字符序列。
如果已經運行了Logstash,則無需安裝其他正則表達式庫,因爲“Grok位於正則表達式之上,因此任何正則表達式在grok中都有效” -
官方文檔:https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html
2、正則匹配模式分類解讀
2.1 Grok
grok語法如下:
%{SYNTAX:SEMANTIC}
Syntax: 默認的grok模式
Semantic: 是關鍵詞。
這樣寫很枯燥,實踐一把。
2.2 Oniguruma
oniguruma語法如下:
(?<field_name>the pattern here)
field_name:是關鍵詞。
pattern :這裏的模式是你放入正則表達式模式的地方。
2.3 Grok + Oniguruma
您可以將Grok和Oniguruma結合起來,如下所示:
%{SYNTAX:SEMANTIC} (?<field_name>the pattern here)
不好理解?不要擔心,2.2和2.3的示例在下面的章節詳細解讀。
3、實踐一把
3.1 樣例數據
爲了演示如何在Grok中使用Oniguruma,我們將使用下面的日誌數據作爲示例。
production GET /v2/blacklist/ 200 24ms 5ba9e948801d34906b96e0c20 Panya/1.6.3 (com.sn.panya.host; build:1; iOS 10.3.3) Alamofire/4.66.0 {\"user_id\":\"5bd4c2f4569f470016bd8d55\",\"reason\":\"SPAMMER\"}
3.2 結構化日誌數據
- production == environment
- GET == method
- /v2/blacklist == url
- 200 == response_status
- 24ms == response_time
- 5bc6e716b5d6cb35fc9687c0 == user_id
- Panya/1.6.3 (com.sn.panya.host; build:1; iOS 10.3.3) Alamofire/4.66.0 == user_agent
- {“user_id”:“5bd4c2f4569f470016bd8d55”,“reason”:“SPAMMER”} == req.body
3.3 非結構化轉化爲結構化目標
目標是找到一種模式來構建和解析非結構化日誌數據。
爲此,我們將使用Grok Debugger和RegExr。
Grok Debugger :https://grokdebug.herokuapp.com/
RegExr:https://regexr.com/
上面的模式產生了結果:
{
"environment": [
[
"production"
]
],
"method": [
[
"GET"
]
],
"url": [
[
"/v2/blacklist/"
]
],
"response_status": [
[
"200"
]
],
"BASE10NUM": [
[
"200"
]
],
"response_time": [
[
"24ms"
]
],
"user_id": [
[
"5ba9e948801d34906b96e0c20"
]
]
}
這並不完整。 user_agent和req.body沒有映射。
要提取user_agent和req.body,我們需要仔細檢查它的結構。
3.4 空白分隔符
GET /v2/blacklist/ 200 24ms 5ba9e948801d34906b96e0c20
由空格分隔,這很容易使用。
但是,對於user_agent,根據發送請求的硬件類型,可能存在動態數量的空格。
Panya/1.6.3 (com.sn.panya.host; build:1; iOS 10.3.3) Alamofire/4.66.0
我們如何解釋這種不斷變化?
提示:看一下req.body的結構。
{\”user_id\”:\”5bd4c2f4569f470016bd8d55\”,\”reason\”:\”SPAMMER\”}
我們可以看到req.body由大括號{}組成。
利用這些知識,我們可以構建一個自定義正則表達式模式,以查找第一個左括號內的所有內容,然後再抓取所有內容。
如下正則的含義是:匹配從開頭到“{”的所有字符。
谷歌搜索“regex match everything until character” 找到解決問題的正則思路:
https://stackoverflow.com/questions/2013124/regex-matching-up-to-the-first-occurrence-of-a-character/2013150#2013150
後半部分組合後的正則如下:
(?<user_agent>[^{]*) %{GREEDYDATA:body}
user_agent和req.body將被提取出來。
3.5 全部放在一起
將此應用於grok調試器中的自定義正則表達式模式,得到了我們想要的結果:
4、更新Logstash.conf驗證
在您安裝ELK堆棧的服務器上,導航到Logstash配置。
sudo vi /etc/logstash/conf.d/logstash.conf
貼上正則部分內容:
input {
file {
path => "/your_logs/*.log"
}
}
filter{
grok {
match => { "message" => "%{WORD:environment} %{WORD:method} %{URIPATH:url} %{NUMBER:response_status} %{WORD:response_time} %{USERNAME:user_id} (?<user_agent>[^{]*) %{GREEDYDATA:body}"}
}
}
output {
elasticsearch {
hosts => [ "localhost:9200" ]
}
}
保存更改後,重新啓動Logstash並檢查其狀態以確保它仍然有效。
sudo service logstash restart
sudo service logstash status
最後,爲了確保更改生效,請務必刷新Kibana中Logstash的Elasticsearch索引!
5、小結
- Oniguruma + Grok 組合實現自定義解析規則。 Logstash文本模式的靈活性和可定製性使其成爲構建非結構化日誌的理想選擇(只要數據結構具有可預測性)。
- 嘗試在Logstash中結合Oniguruma實現自定義解析,提升解析的細化粒度。
銘毅天下——Elasticsearch基礎、進階、實戰第一公衆號