乾貨 | Logstash自定義正則表達式ETL實戰

0、題記
本文創建在乾貨 | Logstash Grok數據結構化ETL實戰上,並專一於在Grok中使用自定義正則表達式。html

有時Logstash沒有咱們須要的模式。幸運的是,咱們有正則表達式庫:Oniguruma。git

Oniguruma是一個靈活的正則表達式庫。 它包含多種語言的不一樣正則表達式實現的特性。github

Github地址:https://github.com/kkos/oniguruma正則表達式

一、基礎再認知
Logstash:一個服務器端數據處理管道,它同時從多個源中提取數據,對其進行轉換,而後將其發送到Elasticsearch「存儲」。服務器

Grok:Logstash中的過濾器,用於將非結構化數據解析爲結構化和可查詢的數據。數據結構

正則表達式:定義搜索模式的字符序列。app

若是已經運行了Logstash,則無需安裝其餘正則表達式庫,由於「Grok位於正則表達式之上,所以任何正則表達式在grok中都有效」 -elasticsearch

官方文檔:https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.htmlide

二、正則匹配模式分類解讀
2.1 Grok
grok語法以下:ui

1%{SYNTAX:SEMANTIC}

Syntax: 默認的grok模式
Semantic: 是關鍵詞。
這樣寫很枯燥,實踐一把。

乾貨 | Logstash自定義正則表達式ETL實戰
2.2 Oniguruma
oniguruma語法以下:

1(?<field_name>the pattern here)

field_name:是關鍵詞。
pattern :這裏的模式是你放入正則表達式模式的地方。

2.3 Grok + Oniguruma
您能夠將Grok和Oniguruma結合起來,以下所示:

1%{SYNTAX:SEMANTIC} (?<field_name>the pattern here)

很差理解?不要擔憂,2.2和2.3的示例在下面的章節詳細解讀。

三、實踐一把
3.1 樣例數據
爲了演示如何在Grok中使用Oniguruma,咱們將使用下面的日誌數據做爲示例。

1production 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/

上面的模式產生告終果:

1{
2 "environment": [
3 [
4 "production"
5 ]
6 ],
7 "method": [
8 [
9 "GET"
10 ]
11 ],
12 "url": [
13 [
14 "/v2/blacklist/"
15 ]
16 ],
17 "response_status": [
18 [
19 "200"
20 ]
21 ],
22 "BASE10NUM": [
23 [
24 "200"
25 ]
26 ],
27 "response_time": [
28 [
29 "24ms"
30 ]
31 ],
32 "user_id": [
33 [
34 "5ba9e948801d34906b96e0c20"
35 ]
36 ]
37}

這並不完整。 user_agent和req.body沒有映射。
要提取user_agent和req.body,咱們須要仔細檢查它的結構。

乾貨 | Logstash自定義正則表達式ETL實戰
3.4 空白分隔符
1 GET /v2/blacklist/ 200 24ms 5ba9e948801d34906b96e0c20

由空格分隔,這很容易使用。

可是,對於user_agent,根據發送請求的硬件類型,可能存在動態數量的空格。

1Panya/1.6.3 (com.sn.panya.host; build:1; iOS 10.3.3) Alamofire/4.66.0

咱們如何解釋這種不斷變化?

提示:看一下req.body的結構。

1{\」user_id\」:\」5bd4c2f4569f470016bd8d55\」,\」reason\」:\」SPAMMER\」}

咱們能夠看到req.body由大括號{}組成。

利用這些知識,咱們能夠構建一個自定義正則表達式模式,以查找第一個左括號內的全部內容,而後再抓取全部內容。

以下正則的含義是:匹配從開頭到「{」的全部字符。

乾貨 | Logstash自定義正則表達式ETL實戰

谷歌搜索「regex match everything until character」 找到解決問題的正則思路:
https://stackoverflow.com/questions/2013124/regex-matching-up-to-the-first-occurrence-of-a-character/2013150#2013150

後半部分組合後的正則以下:

1(?<user_agent>[^{]*) %{GREEDYDATA:body}

user_agent和req.body將被提取出來。

3.5 所有放在一塊兒
將此應用於grok調試器中的自定義正則表達式模式,獲得了咱們想要的結果:

乾貨 | Logstash自定義正則表達式ETL實戰
四、更新Logstash.conf驗證
在您安裝ELK堆棧的服務器上,導航到Logstash配置。

1sudo vi /etc/logstash/conf.d/logstash.conf

貼上正則部份內容:

1input {
2 file {
3 path => "/your_logs/.log"
4 }
5}
6filter{
7 grok {
8 match => { "message" => "%{WORD:environment} %{WORD:method} %{URIPATH:url} %{NUMBER:response_status} %{WORD:response_time} %{USERNAME:user_id} (?<user_agent>[^{]
) %{GREEDYDATA:body}"}
9 }
10}
11output {
12 elasticsearch {
13 hosts => [ "localhost:9200" ]
14 }
15}

保存更改後,從新啓動Logstash並檢查其狀態以確保它仍然有效。

1sudo service logstash restart
2sudo service logstash status

最後,爲了確保更改生效,請務必刷新Kibana中Logstash的Elasticsearch索引!

乾貨 | Logstash自定義正則表達式ETL實戰
五、小結
Oniguruma + Grok 組合實現自定義解析規則。Logstash文本模式的靈活性和可定製性使其成爲構建非結構化日誌的理想選擇(只要數據結構具備可預測性)。

嘗試在Logstash中結合Oniguruma實現自定義解析,提高解析的細化粒度。

相關文章
相關標籤/搜索