有奖捉虫:行业应用 & 管理与支持文档专题 HOT

简介

键值提取函数常见的使用场景如下图,处理为结构化数据之后,可以进一步用于 SQL 分析的场景。
?
?
?

ext_sep() 函数

函数定义

基于分隔符(单字符)提取字段值内容

语法描述

ext_sep("源字段名", "目标字段1,目标字段2,目标字段...", sep="分隔符", quote="不参与分割的部分", restrict=False, mode="overwrite")

参数说明

参数名称
参数描述
参数类型
是否必须
参数默认值
参数取值范围
field
待提取的字段名
string
-
用户日志中已存在的字段名
output
单个字段名或以英文半角逗号拼接的多个新字段名
string
-
-
sep
分隔符
string
,
任意单字符
quote
将值包括起来的字符
string
-
-
restrict
默认为 False。当提取的值个数与用户输入的目标字段数不一致时:
True:忽略,不进行任何提取处理
False:尽量匹配前几个字段
bool
False
-
mode
新字段的写入模式。默认强制覆盖
string
overwrite
-

示例

示例1:使用逗号作为分隔符,提取日志中的值。原始日志:
{"content": "hello Go,hello Java,hello python"}
加工规则:
//使用逗号作为分割符号,将content字段值分割为三段,分别对应f1,f2,f3三个字段。
ext_sep("content", "f1, f2, f3", sep=",", quote="", restrict=False, mode="overwrite")
//丢弃content字段
fields_drop("content")
加工结果:
{"f1":"hello Go","f2":"hello Java","f3":"hello python"}
示例2:使用 quote 将字符串整体处理。原始日志:
{"content": " Go,%hello ,Java%,python"}
加工规则:
ext_sep("content", "f1, f2", quote="%", restrict=False)
加工结果:
//%hello ,Java%虽然也有逗号,但它作为一个整体,就不参与分隔符提取。
{"content":" Go,%hello ,Java%,python","f1":" Go","f2":"hello ,Java"}
示例3:当 restrict=True, 表示当分割的值的个数和目标字段不同时,函数不执行。原始日志:
{"content": "1,2,3"}
加工规则:
ext_sep("content", "f1, f2", restrict=True)
加工结果:
{"content":"1,2,3"}

ext_sepstr() 函数

函数定义

基于指定的字符(多字符)提取字段值内容

语法描述

ext_sepstr("源字段名","目标字段1,目标字段2,目标字段...", sep="abc", restrict=False, mode="overwrite")

参数说明

参数名称
参数描述
参数类型
是否必须
参数默认值
参数取值范围
field
待提取的字段名
string
-
用户日志中已存在的字段名
output
单个字段名或以英文半角逗号拼接的多个新字段名
string
-
-
sep
分隔字符(串)
string
,
-
restrict
默认为False。当提取的值个数与用户输入的目标字段数不一致时:
True:忽略,不进行任何提取处理。
False:尽量匹配前几个字段
bool
False
-
mode
新字段的写入模式。默认强制覆盖
string
overwrite
-

示例

原始日志:
{"message":"1##2##3"}
加工规则:
//使用“##”作为分割符,提取键值。
ext_sepstr("message", "f1,f2,f3,f4", sep="##")
加工结果:
//当目标字段的个数超出了分隔出的值,超出的字段返回"".
{"f1":"1","f2":"2","message":"1##2##3","f3":"3","f4":""}

ext_json() 函数

函数定义

从 JSON 中提取字段值

语法描述

ext_json("源字段名",prefix="",suffix="",format="full",exclude_node="不平铺的JSON节点")

参数说明

参数名称
参数描述
参数类型
是否必须
参数默认值
参数取值范围
field
待提取的字段名
string
-
-
prefix
新字段前缀
string
-
-
suffix
新字段后缀
string
-
-
format
full:字段名格式为全路径(父节点 parent + 连接符 sep + prefix + key 当前节点 + suffix)
simple:非全路径(prefix + key 当前节点 + suffix)
string
simple
-
sep
拼接符,用来拼接节点名使用
string
#
-
depth
最大展开层级深度,超过此层级的节点不再展开
number
100
1-500
expand_array
数组节点是否展开
bool
False
-
include_node
基于正则匹配节点名称的白名单
string
-
-
exclude_node
基于正则匹配节点名称的黑名单
string
-
-
include_path
基于正则匹配节点路径的白名单
string
-
-
exclude_path
基于正则匹配节点路径的黑名单
string
-
-
retain
保留某些特殊字符不做转义,例如:\\n、\\t
string
-
-
escape
是否需要对数据进行转义,默认值 True,有特殊字符时不能转义
bool
True
-

示例

示例1:提取全部节点的 KV 成为新字段,提取时不分层级,该例子是多层嵌套。原始日志:
{
"data": "{ \\"k1\\": 100, \\"k2\\": { \\"k3\\": 200, \\"k4\\": { \\"k5\\": 300}}}"
}
加工规则:
ext_json("data")
加工结果:
{"data":"{ \\"k1\\": 100, \\"k2\\": { \\"k3\\": 200, \\"k4\\": { \\"k5\\": 300}}}","k1":"100","k3":"200","k5":"300"}
示例2:sub_field1 不参与提取。 原始日志:
{"content": "{\\"sub_field1\\":1,\\"sub_field2\\":\\"2\\"}"}
加工规则:
//exclude_node=subfield1意思就是这个节点不提取
ext_json("content", format="full", exclude_node="sub_field1")
加工结果:
{"sub_field2":"2","content":"{\\"sub_field1\\":1,\\"sub_field2\\":\\"2\\"}"}
示例3:给子节点加上前缀 prefix。原始日志:
{"content": "{\\"sub_field1\\":{\\"sub_sub_field3\\":1},\\"sub_field2\\":\\"2\\"}"}
加工规则1:
//sub_field2被提取出来时,自动加上前缀udf\\_,成为udf\\_\\_sub\\_field2
ext_json("content", prefix="udf_", format="simple")
加工结果1:
{"content":"{\\"sub_field1\\":{\\"sub_sub_field3\\":1},\\"sub_field2\\":\\"2\\"}","udf_sub_field2":"2","udf_sub_sub_field3":"1"}
加工规则2:
//format=full表示提取的字段名自带层级关系,sub_field2被提取出来时,自动加上它的父节点名称,成为#content#__sub_field2
ext_json("content", prefix="__", format="full")
加工结果2:
{"#content#__sub_field2":"2","#content#sub_field1#__sub_sub_field3":"1","content":"{\\"sub_field1\\":{\\"sub_sub_field3\\":1},\\"sub_field2\\":\\"2\\"}"}
示例4:支持特殊字符。 原始日志1:
{"content": "{\\"sub_field1\\":1,\\"sub_field2\\":\\"\\\\n2\\"}"}
加工规则1:
ext_json("content",retain="\\n")
加工结果1:
{"sub_field2":"\\\\n2","content":"{\\"sub_field1\\":1,\\"sub_field2\\":\\"\\\\n2\\"}","sub_field1":"1"}
原始日志2:
{"content": "{\\"sub_field1\\":1,\\"sub_field2\\":\\"\\\\n2\\\\t\\"}"}
加工规则2:
ext_json("content",retain="\\n,\\t")
加工结果2:
{"sub_field2":"\\\\n2\\\\t","content":"{\\"sub_field1\\":1,\\"sub_field2\\":\\"\\\\n2\\\\t\\"}","sub_field1":"1"}
示例5:自定义是否进行转义。 原始日志:
{"message":"{\\"ip\\":\\"183.6.104.157\\",\\"params\\":\\"[{\\\\\\"tokenType\\\\\\":\\\\\\"RESERVED30\\\\\\",\\\\\\"otherTokenInfo\\\\\\":{\\\\\\"unionId\\\\\\":\\\\\\"123\\\\\\"},\\\\\\"unionId\\\\\\":\\\\\\"adv\\\\\\"}]\\"}"}
加工规则:
ext_json("message", escape=False)
fields_drop("message")
加工结果:
{"ip":"183.6.104.157", "params":"[{\\"tokenType\\":\\"RESERVED30\\",\\"otherTokenInfo\\":{\\"unionId\\":\\"123\\"},\\"unionId\\":\\"adv\\"}]"}

ext_json_jmes() 函数

函数定义

从 JSON 中提取字段值

语法描述

ext_json_jmes(“源字段名”, jmes= "提取JSON的公式", output="目标字段", ignore_null=True, mode="overwrite")

参数说明

参数名称
参数描述
参数类型
是否必须
参数默认值
参数取值范围
field
待提取的字段名
string
-
-
jmes
jmes 表达式,请参见 JMESPath?
string
-
-
output
输出字段名,仅支持单个字段
string
-
-
ignore_null
是否忽略节点值为 null 的节点,默认 True,忽略 null 字段值,否则当提取结果为 null 时,将输出空字符串
bool
True
-
mode
新字段的写入模式。默认强制覆盖
string
overwrite
-

示例

示例1:只提取多层 JSON 中的一个节点。 原始日志:
{"content": "{\\"a\\":{\\"b\\":{\\"c\\":{\\"d\\":\\"value\\"}}}}"}
加工规则:
//jmes="a.b.c.d"的意思是取a.b.c.d的值。
ext_json_jmes("content", jmes="a.b.c.d", output="target")
加工结果:
{"content":"{\\"a\\":{\\"b\\":{\\"c\\":{\\"d\\":\\"value\\"}}}}","target":"value"}
示例2:原始日志:
{"content": "{\\"a\\":{\\"b\\":{\\"c\\":{\\"d\\":\\"value\\"}}}}"}
加工规则:
//jmes="a.b.c.d"的意思是取a.b.c的值。
ext_json_jmes("content", jmes="a.b.c", output="target")
加工结果:
{"content":"{\\"a\\":{\\"b\\":{\\"c\\":{\\"d\\":\\"value\\"}}}}","target":"{\\"d\\":\\"value\\"}"}

ext_regex() 函数

函数定义

基于正则表达式提取字段值

语法描述

ext_regex(“源字段名”, regex="正则表达式", output=“目标字段1,目标字段2,目标字段......., mode="overwrite")

参数说明

参数名称
参数描述
参数类型
是否必须
参数默认值
参数取值范围
field
待提取的字段名
string
-
-
regex
regex 表达式,如果包含了特殊字符,用户输入时需要进行转义,否则提示语法错误
string
-
-
output
单个字段名或以英文半角逗号拼接的多个新字段名
string
-
-
mode
新字段的写入模式。默认强制覆盖
string
overwrite
-

示例

示例1:匹配数字原始日志:
{"content": "1234abcd5678"}
加工规则:
ext_regex("content", regex="\\d+", output="target1,target2")
加工结果:
{"target2":"5678","content":"1234abcd5678","target1":"1234"}
示例2:有命名捕获,自动填充部分字段值。 原始日志:
{"content": "1234abcd"}
加工规则:
ext_regex("content", regex="(?<target1>\\d+)(.*)", output="target2")
加工结果:
{"target2":"abcd","content":"1234abcd","target1":"1234"}

ext_kv() 函数

函数定义

基于两级分割符提取字段值

语法描述

ext_kv("源字段名", pair_sep=r"\\s", kv_sep="=", prefix="", suffix="", mode="fill-auto")

参数说明

参数名称
参数描述
参数类型
是否必须
参数默认值
参数取值范围
field
待提取的字段名
string
-
-
pair_sep
一级分隔符,分割多个键值对
string
-
-
kv_sep
二级分隔符,分割键和值
string
-
-
prefix
新字段前缀
string
-
-
suffix
新字段后缀
string
-
-
mode
新字段的写入模式。默认强制覆盖
string
-
-

示例

日志中有两级分割符“|”和“=”。
原始日志:
{"content": "a=1|b=2|c=3"}
加工规则:
ext_kv("content", pair_sep="|", kv_sep="=")
加工结果:
{"a":"1","b":"2","c":"3","content":"a=1|b=2|c=3"}

ext_first_notnull() 函数

函数定义

返回参数中第一个非 null 且非空字符的结果值

语法描述

ext_first_notnull(值1, 值2, ...)

参数说明

参数名称
参数描述
参数类型
是否必须
参数默认值
参数取值范围
可变参列表
参与计算的参数或表达式
string
-
-

示例

原始日志:
{"data1": null, "data2": "", "data3": "first not null"}
加工规则:
fields_set("result", ext_first_notnull(v("data1"), v("data2"), v("data3")))
加工结果:
{"result":"first not null","data3":"first not null","data2":"","data1":"null"}

ext_grok 函数

函数定义

基于 Grok 提取匹配结果值,Grok 是一种采用组合多个预定义的正则表达式。

语法描述

ext_grok(字段, grok="", extend="")

参数说明

参数名称
参数描述
参数类型
是否必须
参数默认值
参数取值范围
field
字段
string
-
-
grok
表达式
string
-
-
extend
用户自定义的 GROK 表达式
string
-
-

示例

示例1 原始日志:
{"content":"2019 June 24 \\"I am iron man\\""}
加工规则:
ext_grok("content", grok="%{YEAR:year} %{MONTH:month} %{MONTHDAY:day} %{QUOTEDSTRING:motto}")
fields_drop("content")
加工结果:
{"day":"24", "month":"June", "motto":"I am iron man", "year":"2019"}
示例2 原始日志:
{"content":"Beijing-1104,Beijing-Beijing"}
加工规则:
ext_grok("content", grok="%{ID1:user_id1},%{ID2:user_id2}",extend="ID1=%{WORD}-%{INT},ID2=%{WORD}-%{WORD}")
fields_drop("content")
加工结果:
{"user_id1":"Beijing-1104", "user_id2":"Beijing-Beijing"}
Grok 参考:
类型
模式(pattern)
说明
常见模式
EXTRACTJSON
匹配 JSON 类型数据
CHINAID
匹配中国居民身份证号
USERNAME
匹配字母、数字和._-组合
USER
匹配字母、数字和._-组合
EMAILLOCALPART
匹配邮箱从开头到@字符前内容,例如:123@abc.com,匹配内容为123
EMAILADDRESS
匹配邮箱
HTTPDUSER
匹配邮箱或者用户名
INT
匹配 INT 数字
BASE10NUM
匹配十进制数
NUMBER
匹配数字
BASE16NUM
匹配十六进制数
BASE16FLOAT
匹配十六进制浮点数
POSINT
匹配正整数
NONNEGINT
匹配非负整数
WORD
匹配字母、数字、下划线
NOTSPACE
匹配非空格内容
SPACE
匹配空格
DATA
匹配换行符
GREEDYDATA
匹配0个或多个除换行符
QUOTEDSTRING
匹配引用内容。例如:I am "Iron Man",会匹配到 Iron Man
UUID
匹配 UUID
Networking
MAC
匹配 MAC 地址
CISCOMAC
匹配 CISCOMAC 地址
WINDOWSMAC
匹配 WINDOWSMAC 地址
COMMONMAC
匹配 COMMONMAC 地址
IPV6
匹配 IPV6
IPV4
匹配 IPV4
IP
匹配 IPV6或 IPV4
HOSTNAME
匹配 HOSTNAME
IPORHOST
匹配 IP 或 HOSTNAME
HOSTPORT
匹配 IPORHOST 或者 POSTINT
Paths
PATH
匹配 UNIXPATH 或者 WINPATH
UNIXPATH
匹配 UNIXPATH
WINPATH
匹配 WINPATH
URIPROTO
匹配 URI 中的头部分,例如:http://hostname.domain.tld/_astats?application=&inf.name=eth0会匹配到 http
TTY
匹配 TTY 路径
URIHOST
匹配 IPORHOST 和 POSINT,例如:http://hostname.domain.tld/_astats?application=&inf.name=eth0,会匹配到 hostname.domain.tld
URI
匹配内容中的 URI
日期
MONTH
匹配数字或者月份英文缩写或者全拼等格式月份
MONTHNUM
匹配数字格式月份
MONTHDAY
匹配月份中的 day
DAY
匹配星期的英文全拼或者缩写
YEAR
匹配年份
时间
HOUR
匹配小时
MINUTE
匹配分钟
SECOND
匹配秒
TIME
匹配完整的时间
DATE_US
匹配 Month-Day-Year 或 Month/Day/Year 形式的日期
DATE_EU
匹配 Day-Month-Year、Day/Month/Year 或 Day.Month.Year 形式的日期
ISO8601_TIMEZONE
匹配 ISO8601格式的小时和分钟
ISO8601_SECOND
匹配 ISO8601格式的秒钟
TIMESTAMP_ISO8601
匹配 ISO8601格式的时间
DATE
匹配 US 或 EU 格式的时间
DATESTAMP
匹配完整日期和时间
TZ
匹配 UTC
DATESTAMP_RFC822
匹配 RFC822格式时间
DATESTAMP_RFC2822
匹配 RFC2822格式时间
DATESTAMP_OTHER
匹配其他格式时间
DATESTAMP_EVENTLOG
匹配 EVENTLOG 格式的时间
HTTPDERROR_DATE
匹配 HTTPDERROR 格式的时间
SYSLOG
SYSLOGTIMESTAMP
匹配Syslog格式的时间
PROG
匹配 program内容
SYSLOGPROG
匹配 program 和 pid 内容
SYSLOGHOST
匹配 IPORHOST
SYSLOGFACILITY
匹配 facility
HTTPDATE
匹配日期时间
LOGFORMATL
LOGFORMAT
匹配 Syslog,默认 TraditionalFormat 格式的 Syslog 日志
COMMONAPACHELOG
匹配 commonApache 日志
COMBINEDAPACHELOG
匹配组合 Apache 日志
HTTPD20_ERRORLOG
匹配 HTTPD20日志
HTTPD24_ERRORLOG
匹配 HTTPD24日志
HTTPD_ERRORLOG
匹配 HTTPD 日志
LOGLEVELS
LOGLEVELS
匹配 Log 的 Level,例如 warn、debug 等
?


http://www.vxiaotou.com