本文檔介紹如何使用不同方案提取字串索引值對。
常用方案比較
字串動態索引值對提取分為關鍵字提取、值提取、關鍵字加工和值加工,常用方案為採用e_kv函數、e_kv_delimit函數和e_regex函數等。不同提取情境的三種方案如下:
方案 | 關鍵字提取 | 值提取 | 關鍵字加工 | 值加工 |
e_kv | 使用特定Regex | 支援預設的字元集、特定分隔字元或者帶(、)或(")分隔 | 支援前尾碼 | 支援文本escape |
e_kv_delimit | 使用特定Regex | 使用分隔字元 | 支援前尾碼 | 預設無 |
e_regex | 組合自訂Regex和預設字元集過濾 | 完全自訂 | 自訂 | 自訂 |
大部分索引值對的提取使用e_kv函數並配置特定參數就可以很好地滿足,尤其是帶括字元和反斜線需要提取並轉義時。其他複雜或進階的情境可以用e_regex函數來提取。部分特定情境下的索引值對使用e_kv_delimit函數會更簡單。
關鍵字提取
處理方法
e_kv、e_kv_delimit、e_regex等函數在應用於關鍵字提取的時候都應遵循欄位名提取約束。樣本1
以
k1: q=asd&a=1&b=2&__1__=3日誌為例,如果要對該格式的日誌作關鍵字和值提取,三種方案如下:e_kv函數
原始日誌
k1: q=asd&a=1&b=2&__1__=3加工規則
#預設以特定字元集提取關鍵字 e_kv("k1")加工結果
k1: q=asd&a=1&b=2 q: asd a: 1 b: 2說明沒有提取出關鍵字
__1__是因為其不符合欄位名提取約束。
e_kv_delimit函數
原始日誌
k1: q=asd&a=1&b=2&__1__=3加工規則
# 以&分隔索引值後,用&分隔提取出關鍵字 e_kv_delimit("k1", pair_sep=r"&")加工結果
k1: q=asd&a=1&b=2 q: asd a: 1 b: 2
e_regex函數
原始日誌
k1: q=asd&a=1&b=2&__1__=3加工規則
# 自行指定字元集提取關鍵字和值 e_regex("k1",r"(\w+)=([a-zA-Z0-9]+)",{r"\1": r"\2"})加工結果
k1: q=asd&a=1&b=2 q: asd a: 1 b: 2
樣本2
以
content:k1=v1&k2=v2?k3:v3為例,需要特定正則提取關鍵字,三種方案如下:e_kv函數
原始日誌
content:k1=v1&k2=v2?k3:v3加工規則
e_kv("content",sep="(?:=|:)")加工結果
content:k1=v1&k2=v2?k3:v3 k1: v1 k2: v2 k3: v3說明給參數
pair_sep、kv_sep或者sep傳遞字元集的時候,需要使用正則的不捕獲分組,形式如(?:字元集)。
e_kv_delimit函數
原始日誌
content:k1=v1&k2=v2?k3:v3加工規則
e_kv_delimit("content",pair_sep=r"&?",kv_sep="(?:=|:)")加工結果
content:k1=v1&k2=v2?k3:v3 k1: v1 k2: v2 k3: v3
e_regex函數
原始日誌
content:k1=v1&k2=v2?k3:v3加工規則
e_regex("content",r"([a-zA-Z0-9]+)[=|:]([a-zA-Z0-9]+)",{r"\1": r"\2"})加工結果
content:k1=v1&k2=v2?k3:v3 k1: v1 k2: v2 k3: v3
樣本3
對以下格式的複雜字串,使用
e_regex函數提取更方便。原始日誌
content :"key1:"value1,"key2:"value2加工規則
如果要提取字串的關鍵字前有(”)符號,需要使用
e_regex函數來提取。e_regex("content", r"(\w+):\"(\w+)", {r"\1": r"\2"})加工結果
經過DSL編排之後的日誌格式:
content :"key1:"value1,"key2:"value2 key1: value1 key2: value2
值提取
動態索引值對之間以及關鍵字與值之間有明確標識,如
a=b或a="cxxx"日誌格式的,推薦用e_kv函數,樣本如下。原始日誌
content1: k1="helloworld",the change world, k2="good"加工規則
這種情況下使用e_kv函數,提取內容不包括
the change world:e_kv("content1") # e_kv_delimit函數寫法,特別注意k2前有空格,所以e_kv_delimit函數的pair_sep參數需要使用`,\s`才能正常解析,否則解析不出來k2。 e_kv_delimit("content1",kv_sep="=", pair_sep=",\s") # e_regex函數寫法 e_regex("str",r"(\w+)=(\"\w+)",{r"\1": r"\2"})加工結果
提取後的日誌為:
content1: k1="helloworld",the change world, k2="good" k1: helloworld k2: good
對帶
"的日誌格式content:k1="v1=1"&k2=v2?k3=v3,推薦使用e_kv函數進行提取,例如:原始日誌
content:k1="v1=1"&k2=v2?k3=v3加工規則
e_kv("content",sep="=", quote="'")加工結果
處理後日誌為:
content: k1='v1=1'&k2=v2?k3=v3 k1: v1=1 k2:v2 k3:v3
如果使用
e_kv_delimit函數提取,規則為e_kv_delimit("ctx", pair_sep=r"&?", kv_sep="="),只能解析出k2: v2和k3: v3,因為其中第一個提取的索引值對中關鍵字是k1="v1,不符合欄位名提取約束會被丟棄。分隔字元的索引值對中,值包含特殊字元但沒有用特定字元包括。例如:
原始日誌
content: rats eat rice, oil|chicks eat bugs, rice|kittens eat fish, mice|加工規則(推薦)
使用e_kv_delimit函數比較合適。
e_kv_delimit("content", pair_sep="|", kv_sep=" eat ")加工結果(推薦)
處理後日誌為:
content: rats eat rice, oil|chicks eat bugs, rice|kittens eat fish, mice| kittens: fish, mice chicks: bugs, rice rats: rice, oil加工規則(不推薦)
使用
e_kv函數無法解析完整。e_kv("f1", sep="eat")加工結果(不推薦)
處理後日誌為:
content: rats eat rice, oil|chicks eat bugs, rice|kittens eat fish, mice| kittens: fish chicks: bugs rats: rice
關鍵字加工
e_kv函數和e_kv_delimit函數都可以通過prefix="", suffix=""對關鍵字和值進行加工。原始日誌
k1: q=asd&a=1&b=2加工規則
e_kv("k1", sep="=", quote='"', prefix="start_", suffix="_end") e_kv_delimit("k1", pair_sep=r"&", kv_sep="=", prefix="start_", suffix="_end") e_regex("k1",r"(\w+)=([a-zA-Z0-9]+)",{r"start_\1_end": r"\2"})加工結果
加工後的資料都是關鍵字加工形式,如下:
k1: q=asd&a=1&b=2 start_q_end: asd start_a_end: 1 start_b_end: 2
e_regex函數對關鍵字加工的能力更強,例如:加工規則
e_regex("k1",r"(\w+)=([a-zA-Z0-9]+)",{r"\1_\1": r"\2"})加工結果
加工後的資料都是關鍵字加工形式,如下:
k1: q=asd&a=1&b=2 q_q: asd a_a: 1 a_a: 2
值加工
日誌格式為
k1:"v1\"abc"形式, 同時值加工的內容存在有雙引號符號的情形,使用e_kv函數可正常進行提取,其他兩種方式較難實現。原始日誌
""" 這裡的\只是普通的符號,不是轉義符 """ content2: k1:"v1\"abc", k2:"v2", k3: "v3"加工規則1
e_kv("content2",sep=":", quote='"')使用e_kv函數規則為:
加工結果1
提取後的日誌為:
content2: k1:"v1\"abc", k2:"v2", k3: "v3" k1: v1\ k2: v2 k3: v3加工規則2
e_kv函數通過參數escape支援對\字元轉義。例如:e_kv("content2",sep=":", quote='"',escape=True)加工結果2
提取後的日誌為:
content2: k1:"v1\"abc", k2:"v2", k3: "v3" k1: v1"abc k2: v2 k3: v3
日誌格式為
a='k1=k2\';k2=k3'形式的日誌,只有e_kv函數可以正常提取出,其他兩種比較難以實現。原始日誌
data: i=c10 a='k1=k2\';k2=k3'加工規則1
預設情況下
e_kv函數的escape=False,結果為:e_kv("data", quote="'")加工結果1
提取後的日誌為:
a: k1=k2\ i: c10 k2: k3加工規則2
e_kv函數通過參數escape支援對\字元轉義。例如:e_kv("data", quote="'", escape=True)加工結果2
提取後的日誌為:
data: i=c10 a='k1=k2\';k2=k3' i: c10 a: k1=k2';k2=k3
索引值的複雜加工。
原始日誌
content: rats eat rice|chicks eat bugs|kittens eat fish|加工規則
使用
e_regex函數進行加工。e_regex("content", r"\b(\w+) eat ([^\|]+)", {r"\1": r"\2 by \1"})加工結果
處理後日誌為:
content: rats eat rice|chicks eat bugs|kittens eat fish| kittens: fish by kittens chicks: bugs by chicks rats: rice by rats
客戶案例
例如某網站日誌中有一個URL資料,針對這條資料有提取需求,按照需求設計加工規則處理日誌內容。
第一次加工
需求
需求1:對日誌解析出
proto、domain、param等內容。需求2:對
param中的索引值對做展開操作。
原始日誌
__source__: 192.168.0.100 __tag__:__client_ip__: 192.168.0.200 __tag__:__receive_time__: 1563517113 __topic__: request: https://example.com/video/getlist/s?ver=3.2.3&app_type=supplier&os=Android8.1.0加工方案
總規則
# 初步處理解析request內容 e_regex('request',grok("%{URIPROTO:uri_proto}://(?:%{USER:user}(?::[^@]*)?@)?(?:%{URIHOST:uri_domain})?(?:%{URIPATHPARAM:uri_param})?")) # 其次處理解析uri_param e_regex('uri_param',grok("%{GREEDYDATA:uri_path}\?%{GREEDYDATA:uri_query}")) # 展開kv形式 e_kv("uri_query")細分規則及對應的加工結果
使用GROK模式對欄位
request進行解析。e_regex('request',grok("%{URIPROTO:uri_proto}://(?:%{USER:user}(?::[^@]*)?@)?(?:%{URIHOST:uri_domain})?(?:%{URIPATHPARAM:uri_param})?"))對應加工結果:
uri_domain: example.com uri_param: /video/getlist/s?ver=3.2.3&app_type=supplier&os=Android8.1.0 uri_proto: https使用GROK模式對欄位
uri_param進行解析。e_regex('uri_param',grok("%{GREEDYDATA:uri_path}\?%{GREEDYDATA:uri_query}"))對應加工結果:
uri_path: /video/getlist/s uri_query: ver=3.2.3&app_type=supplier&os=Android8.1.0對
uri_param進列欄位提取,具體操作如下:e_kv("uri_query")對應加工結果:
app_type: supplier os: Android8.1.0 ver: 3.2.3
加工結果
預覽處理後日誌:
__source__: 192.168.0.100 __tag__:__client_ip__: 192.168.0.200 __tag__:__receive_time__: 1563517113 __topic__: request: https://example.com/video/getlist/s?ver=3.2.3&app_type=supplier&os=Android8.1.0 uri_domain: example.com uri_path: /video/getlist/s uri_proto: https uri_query: ver=3.2.3&app_type=supplier&os=Android8.1.0 app_type: supplier os: Android8.1.0 ver: 3.2.3假如只有解析request需求,可以直接對欄位
request使用e_kv函數。例如:e_kv("request")預覽處理後日誌:
__source__: 192.168.0.100 __tag__:__client_ip__: 192.168.0.200 __tag__:__receive_time__: 1563517113 __topic__: request: https://example.com/video/getlist/s?ver=3.2.3&app_type=supplier&os=Android8.1.0 app_type: supplier os: Android8.1.0 ver: 3.2.3進一步加工
客戶要提取其中動態欄位
ver、app_type和os等,加工規則如下。使用Regex
e_regex("url", r"\b(\w+)=([^=&]+)", {r"\1": r"\2"})使用
e_kv_delmit函數e_kv_delimit("url", pair_sep=r"?&")
方案總結
對於大部分URL函數形式,都可使用以上函數進行解析。但是針對原始日誌中的URL形式,使用
e_kv函數已經足夠,清晰明了而且形式簡單。