日志服务 键值提取函数

这篇说说了腾讯云日志服务中多种键值提取函数,包括ext_sep()、ext_sepstr()、ext_json()、ext_json_jmes()、ext_regex()、ext_kv()、ext_first_notnull()和ext_grok(),用于将非结构化日志解析为结构化字段,便于后续SQL分析。 ext_sep(): 基于单字符分隔符提取字段值,支持quote参数忽略特定分隔符。 ext_json(): 。

相关产品
日志服务 产品页,含版本规格、价格与购买入口。

一、简介

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

三、函数定义

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

四、语法描述

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("源字段名","目标字段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":""}

十三、函数定义

从 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\\_field2ext_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\\"}]"}

十八、函数定义

从 JSON 中提取字段值。

十九、语法描述

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

20、参数说明

参数名称 参数描述 参数类型 是否必须 参数默认值 参数取值范围
field 待提取的字段名 string 是 – –
jmes jmes 表达式,请参见 JMESPath说明:如果 jmes 中包含了特殊字符,例如 . \\ * + ? ^ $ | () [] {} – /时,需要加上转义符。 string 是 – –
output 输出字段名,仅支持单个字段 string 是 – –
ignore_null 是否忽略节点值为 null 的节点,默认 True,忽略 null 字段值,否则当提取结果为 null 时,将输出空字符串 bool 否 True –
mode 新字段的写入模式。默认强制覆盖 string 否 overwrite 字段提取模式说明

21、示例

·示例1:提取节点值(叶子结点)。

原始日志:

{"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\\"}"}

23、函数定义

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

24、语法描述

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

25、参数说明

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

26、示例

·示例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"}

28、函数定义

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

29、语法描述

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

30、参数说明

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

31、示例

日志中有两级分割符“|”和“=”。

原始日志:

{"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"}

33、函数定义

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

34、语法描述

ext_first_notnull(值1, 值2, …)

35、参数说明

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

36、示例

原始日志:

{"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"}

38、函数定义

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

注意:当你的日志中有特殊字符如 . \\ * + ? ^ $ | () [] {} – / 时,grok 语法中需要加转义,例如:2024 Nov 9 -trump,对应的 grok 语句:%{YEAR:year} %{MONTH:month} %{MONTHDAY:day} \\-%{WORD:trump},提取结果:{ "year": 2024, "month": "Nov", "day": 9,"President": "trump"}

39、语法描述

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

40、参数说明

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

41、示例

·示例1:使用默认的 Pattern 提取日期和引号中的字符串。

原始日志:

{"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:使用自定义 Pattern 提取键值对。

原始日志:

{"content":"Beijing-1104,Beijing-Beijing"}

加工规则:

//extend 参数的作用是对自定义模式进行定义。其中 ID1=%{WORD}-%{INT} 表明 ID1 模式由一个单词、一个连字符和一个整数组成;ID2=%{WORD}-%{WORD} 表示 ID2 模式由一个单词、一个连字符和另一个单词组成。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"}

42、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 日志
LOGLEVEL LOGLEVEL 匹配 Log 的 Level,例如 warn、debug、info 等
赞 (0)
上一篇 4天前
下一篇 4天前