天天看點

幹貨 | Logstash自定義正規表達式ETL實戰

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}

1

Syntax: 預設的grok模式

Semantic: 是關鍵詞。

這樣寫很枯燥,實踐一把。

幹貨 | Logstash自定義正規表達式ETL實戰

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": [

 "response_time": [

     "24ms"

 "user_id": [

     "5ba9e948801d34906b96e0c20"

 ]

}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

這并不完整。 user_agent和req.body沒有映射。

要提取user_agent和req.body,我們需要仔細檢查它的結構。

幹貨 | Logstash自定義正規表達式ETL實戰

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由大括号{}組成。

利用這些知識,我們可以建構一個自定義正規表達式模式,以查找第一個左括号内的所有内容,然後再抓取所有内容。

如下正則的含義是:比對從開頭到“{”的所有字元。

幹貨 | Logstash自定義正規表達式ETL實戰

谷歌搜尋“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調試器中的自定義正規表達式模式,得到了我們想要的結果:

幹貨 | Logstash自定義正規表達式ETL實戰

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索引!