成喆 2019-06-10 06:31:17 浏览 16 评论 0
python
函数
日志
日志服务
JSON
正则表达式
表达式
数组
数据加工
数据规整
编排语法
摘要: 日志服务数据加工上线, 本文概述其语法框架与样例, 覆盖事件操作宏, 事件类操作函数, 字段类操作函数, 表达式函数等
1. 全局操作事件
1.1. 字段赋值(set event)
1.1.1. 语法介绍
语法:
SET_EVENT[[_]数字]_新字段 = 固定值
SET_EVENT[[_]数字]_新字段 = 表达式函数
说明
设置单个字段值, 字段名为新字段, 如果已经存在, 则会覆盖现有字段值
新字段的字符约束是: 中英文数字_组成, 但不能以数字开头. 注意: 支持中文, 但不支持:, 因此不能通过这种方式设置日志的 tag 等, 可以参考通用操作完成这类需求.
表达式函数返回无值 None 时, 该操作会被忽略
表达式函数返回的任何类型的值都会被转化成字符串(例如, 数字会被格式化为字符串, 放回到事件中)
特定情况下需要对同一个字段进行多次设置时, 需要使用中间的 [[_] 数字用不同值做占位符区分.
完整的表达式函数信息, 请参考表达式函数
1.1.2. 样例
例子 1: 设置固定值
添加一个新字段 city 值为上海.
SET_EVENT_city = "上海"
例子 2: 复制字段值
调用单个表达式函数 v, 将现有字段 ret 的值, 赋值给新字段 result.
SET_EVENT_result = v("ret")
例子 3: 动态设置值
这里组合调用表达式函数, 从字段 ret 和 return 中首先存在的字段的值, 返回其小写赋值给字段 result
SET_EVENT_result = str_lower(v("ret", "return"))
例子 4: 多次设置字段值
首先设置字段 event_type 的默认值:
SET_EVENT_1_event_type = "login event"
经过一些其他操作后, 字段 result 值为 fail 的事件的字段, 将其 event_type 设置为 login failed event:
- # 中间一些其他操作
- SET_EVENT_2_event_type = op_if(op_eq(v("ret"), "fail"), "login failed event", v("event_type"))
注意: 这里需要使用不同数字在同一个字段名前做占位符.
1.2. 字段提取 (extract event)
1.2.1. 语法介绍
语法:
EXTRACT_EVENT[[_]数字]_字段 = 字符串
EXTRACT_EVENT[[_]数字]_字段 = 字段操作类函数
说明
对单个字段的值进行操作, 一般是提取值到多个字段, 例如正则表达式, JSON 展开, 查表富化, 键值对拆分等, 也包括根据字段值, 将一条事件分裂成多条.
字符串是字段操作类函数 REGEX 的一种简写.
提取的多个值默认会在原字段不存在或者值为空时覆盖, 进一步参考提取字段的值检查与覆盖模式
字段的字符约束是: 中英文数字_组成, 但不能以数字开头. 注意: 支持中文, 但不支持:, 因此不能通过这种方式对日志的 tag 等进行操作, 可以参考通用操作完成这类需求.
表达式函数返回无值 None 时, 该操作会被忽略
某些情况需要对同一个字段的值进行多次提取时, 需要使用中间的 [[_] 数字用不同值做占位符区分.
完整的字段类操作函数信息, 请参考字段类操作函数
1.2.2. 样例
例子 1: 正则表达式提取值
从字段 email 中提取用户名 user, 邮箱司名 company:
EXTRACT_EVENT_email = r"(?P<user>\w+)@(?P<company>\w+)\.com"
注意: 字符串是字段操作类函数正则表达式 (REGEX) 的简写方式, 详情参考其更多使用方法.
例子 2: 根据字段值映射新字段
根据字段 level 的值, 调用字段类操作函数 LOOKUP 映射出新字段 level_info 来:
EXTRACT_EVENT_level = LOOKUP({"1": "info","2": "warning","3": "error", "*": "other"},"level_info")
例子 3: 展开 JSON
根据字段 request_body 和 response_body 的值, 调用字段类操作函数 JSON 自动展开 (深度默认为 10) 成多个值:
- EXTRACT_EVENT_request_body = JSON
- EXTRACT_EVENT_response_body = JSON(depth=1)
不带参数的 JSON 是简化的调用方式, 更多 JSON 功能参数, 具体参考手册.
例子 4: 多次提取字段值
首先对字段 response_body 展开 JSON, 再用正则表达式提取其中的某个特定值:
- EXTRACT_EVENT_1_response_body = JSON(depth=1)
- EXTRACT_EVENT_2_response_body = r"trace_id=(?P<trace_id>[\w\-]+)"
注意: 这里需要使用不同数字在同一个字段名前做占位符.
1.3. 通用操作
1.3.1. 语法介绍
语法:
TRANSFORM_ANY_[占位符] = 操作
TRANSFORM_ANY_[占位符] = 操作列表
操作
通用操作有三种形式, 包含了前面的两种操作的扩展形式, 和第三种事件操作类函数:
字段赋值操作 = {"新字段名": 固定值或表达式函数, "另一个字段名": }
字段提取操作 = 字段输入, 字符串或字段操作类函数
一般操作 = 事件操作类函数
操作列表
多个操作的列表, 如 [操作 1, 操作 2, 操作 3, ....] 构成的列表, 会被依次执行下去, 除非某个操作丢弃了事件.
注意: 多个操作, 必须用 [] 括起来.
说明
字段赋值操作: 是一个
{ key1: value1, key2: value2}
的多个键值对形式, 支持多个值的赋值.
字段提取操作: 是一个输入, 操作的单个配对, 其中输入可以不仅仅是一个字段, 例如 OSSLOOKUP 中支持多个输入做映射.
一般操作: 覆盖了对事件的常规性操作, 例如: 丢弃事件, 保留或丢弃特定字段等, 也包括输出事件等
多个通用操作需要使用不同值做占位符区分, 一般用数字累加即可.
完整的事件类操作函数信息, 详情参照事件类操作函数详情
1.3.2. 样例
例子 1: 多个字段赋值操作
对多个字段赋值, 也支持表达式函数.
TRANSFORM_ANY_1 = {"__topic__": "default topic", "tag:__type__": v("event_type"), "level": "1"}
例子 2: 根据字段值提取
根据字段 request_body 的值, 调用字段类操作函数 JSON 展开成多个值:
TRANSFORM_ANY_2 = "request_body", JSON(depth=1)
例子 3: 一般操作
丢弃事件字段 field1 和 field2:
TRANSFORM_ANY_3 = DROP_F(["field1", "field2"])
例子 4: 多个操作
多个操作按顺序执行:
TRANSFORM_ANY_4 = [ {"email": "abc@default.com"}, ("request_body", JSON) ]
例子 4: 表达式函数与操作类函数互操作
根据字段字段 valid 的值是否为 true 来保留或丢弃事件:
TRANSFORM_ANY_5 = op_if(op_eq(v("valid"), "true"), KEEP, DROP)
注意: 其中 KEEP 和 DROP 是保留和丢弃事件类操作的标示.
1.4. 带条件的通用操作
1.4.1. 语法介绍
语法:
TRANSFORM_EVENT_占位符 = 条件操作
TRANSFORM_EVENT_占位符 = 条件操作列表
条件操作
就是带条件的通用操作, 如果条件满足, 即执行其操作, 否则无操作.:
条件操作 = 条件, 操作
注意: 其中操作也可以是操作列表, 详情参考操作
条件
条件是用于判断当前事件是否满足特定条件的表达式, 其形式有三种:
- 固定条件标识
- - {
- "字段名 1", "正则表达式 1"
- }
- - {
- "字段名 1", NOT("正则表达式 1")
- } # NOT
- - {
- "字段名 1", "正则表达式 1", "字段名 2": "正则表达式 2", ...
- } # AND
- 表达式函数
- 以上形式的列表, 如:[ {"字段名 1": "正则表达式 1"}, {"字段名 2": "正则表达式 2"}, ... ] # OR
条件操作的列表
多个条件操作的列表, 如 [条件操作 1, 条件操作 2, 条件操作 3, ....] 构成的列表. 每次检查每个条件操作的条件, 满足即执行器操作, 否则无操作. 之后继续检查下一条条件操作, 除非某一步丢弃了事件.
注意: 整个列表必须用 [] 括起来, 其中每个条件操作都需要用 () 括起来.
条件语法说明
固定条件标识: 是使用某些预定义的标识, 例如 ANY,ALL 等都标识所有, 也就是任意事件均会匹配并执行后续操作.
键值对:{ key : value } 是对字段值用正则完全匹配, 注意, 其中的字段的值必须与正则表达式是完全匹配 (从头到尾匹配) 才能算满足条件.
例如: 字段 user 的值为 "i love python", 那么正则表达式 "i love" 或者 "python" 均无法匹配.
多个键值队的关系是 AND 关系, 必须全满足才能执行配对的操作(列表).
对正则用 NOT 调动后, 逻辑关系变成了 not
可以通过表达式函数来以返回的值作为判断条件(默认空字符串, None, 布尔值 False, 数字 0, 空列表等表示不满足, 其他情况表示都表示满足.
通过对多个逻辑用列表组合, 表达了 OR 的意义, 也就是只需要有一个满足, 即执行配对的操作(列表)
注意 OR,AND,NOT 等等逻辑目前版本不能任意嵌套.
有复杂逻辑判断的, 可以使用表达式函数.
表达式函数参考表达式函数
1.4.2. 样例
例子 1: 值匹配后操作
字段 result 是 failed 或 failure 时, 设置事件主题为 login_failed_event:
TRANSFORM_EVENT_1 = {"result": r"failed|failure"}, {"__topic__": "login_failed_event"}
例子 2: 根据字段值判断再提取
当字段 request_body 存在且值非空时, 调用字段类操作函数 JSON 对字段 request_body 进行展开成多个值:
TRANSFORM_EVENT_2 = NO_EMPTY("request_body"), ("request_body", JSON)
这里使用了特定表达式函数 NO_EMPTY 表示存在字段 request_body 且非空.
例子 3: 高级判断再操作
当字段 valid 的值是 failed 时, 丢弃事件:
TRANSFORM_EVENT_3 = op_if(v("valid"), "failed"), DROP
例子 4: 多个条件操作
多个操作按顺序执行:
- TRANSFORM_EVENT_3 = [
- (ANY, {"__topic__": "default_login"}),
- ( {"valid": "failed"}, {"__topic__": "login_failed_event"} )
- ]
注意, 多个条件操作使用 [] 进行括起来, 其中每个条件操作, 都使用 () 括起来.
1.5. 基于条件分派操作
1.5.1. 语法介绍
语法:
DISPATCH_EVENT_占位符 = 条件操作列表
说明
形式与待条件的通用操作基本一致
其中多个条件操作的列表, 每次检查每个条件操作的条件, 不满足会持续检查下一个条件操作, 满足即执行器配对的操作(列表), 之后就不再执行后续的条件操作了.
1.5.2. 样例
例子 4: 条件分派
按照字段 http_status 来设置不同的事件主题:
- DISPATCH_EVENT_1 = [
- ({"http_status": r"2\d+"} , {"__topic__": "success_event"}),
- ({"http_status": r"3\d+"} , {"__topic__": "redirection_event"}),
- ({"http_status": r"4\d+"} , {"__topic__": "unauthorized_event"}),
- ({"http_status": r"5\d+"} , {"__topic__": "internal_server_error_event"}),
- ]
注意, 多个条件操作使用 [] 进行括起来, 其中每个条件操作, 都使用 () 括起来.
1.6. 常见事件操作的简化宏
1.6.1 保留 / 丢弃事件
语法
对于满足条件的事件保留或丢弃
KEEP_EVENT_占位符 = 条件
DROP_EVENT_占位符 = 条件
说明
条件: 与带条件的通用操作中的条件一致, 也可以是列表, 参考条件
1.6.2 保留 / 丢弃字段
语法
对于满足条件的字段名保留或丢弃
KEEP_FIELDS_占位符 = 字符串或字符串列表
DROP_FIELDS_占位符 = 字符串或字符串列表
字符串或字符串列表
字符串: 这里的字符串指的是正则表达式, 当字段名符合条件时保留或者丢弃字符串.
列表: 表示用 [] 括起来的正则表达式字符串列表, 如: ["abc", "xyz"]
提供了一些预定好的 meta 的字段名的标识, 可以直接使用, 例如 F_TIME 表示时间字段, F_META 表示时间, 主题等字段.
说明
条件: 与带条件的通用操作中的条件一致, 也可以是列表, 参考条件
因为日志服务中的事件还包含了隐藏的元字段: 包括__time__,__topic__等, 如果删除了__time__, 那么事件时间将被重置为当前时间, 使用 KEEP_FIELDS_时需要特别注意, 不要误删.
常用 KEEP_FIELDS_格式是:
[F_TIME, F_META, F_TAGS, "f1", "f2" ]
1.6.3 重命名字段
语法
- ALIAS_xxx = {
- "现有字段名正则 1": "新字段名 1", "现有字段正则 2": "新字段名 2",
- }
- RENAME_FIELDS_xxx = {
- "现有字段名正则 1": "新字段名 1", "现有字段正则 2": "新字段名 2",
- }
说明
ALIAS_与 RENAME_FIELDS_没有区别
这里的现有字段名实际是一个正则表达式, 当有多个字段匹配时, 所有字段均会改为新字段名, 新字段名的值是其中一个, 具体哪个未知. 则主要解决多种数据源的日志混合时, 字段名统一简化用.
1.6.4 输出事件
将满足条件的事件输出
语法
OUTPUT_xxx = 条件
COUTPUT_xxx = 条件
说明
条件: 与带条件的通用操作中的条件一致, 也可以是列表, 参考条件
OUTPUT 将满足条件的事件输出后, 事件不再进行后续处理,(可以理解为被丢弃了).
COUTPUT 将满足条件的事件输出后, 事件会继续后续处理,(可以理解为复制一份输出了).
事件类操作函数
`OUTPUT 与 COUTPUT` 支持更多的行为定制. 参考事件类操作函数
2. 表达式函数
返回特定值的表达式, 一般是单个表达式函数或其调用组合, 覆盖如下几大类, 100 多个并持续增加:
基本操作函数: 字段取值, 控制, 比较, 容器判断, 字段存在内容判断, 多字段操作等
转换函数: 基础类型转换, 数字转换
算术函数: 基础计算, 多值计算比较, 数学计算, 数学参数等
字符串函数: 多字段操作, 编码 / 解码, 排序, 倒叙, 替换, 常规规整, 查找判断, 切分, 格式化, 字符集判断等
日期时间函数: 智能日期时间转换, 获取日期时间属性, 获取日期时间, 获取 Unix 时间戳, 获取日期时间字符串, 修改日期 - 时间, 修改日期时间, 比较日期时间等
正则表达式函数: 字段提取, 匹配判断, 替换, 切分等
进一步详情, 请参考用户手册.
3. 字段类操作函数
基于输入的字段的值, 进行操作, 注意: 目前不支持字段类操作函数与表达式函数互操作.
覆盖如下几大类, 并持续增加:
正则提取列: 正则的完整支持, 包括动态提取字段名等
CSV 格式提取: CSV 标准的支持
字典映射: 直接字段映射
外部 OSS 多列映射: 从外部 OSS 上的 CSV 关联对数据进行富化, 支持增量刷新, 宽匹配等.
外部数据库多列映射: 从外部数据库关联对数据进行富化, 支持动态刷新, 宽匹配等.
外部 Logstore 多列映射: 从外部 logstore 关联对数据进行富化, 支持增量刷新, 宽匹配等.
自动 KV: 自动提取 KV, 也支持自定义分隔符, auto-escape 场景
JSON 自动展开: 支持自动展开 JSON 内容, 包括数组, 支持展开过程的定制.
JSON-JMES 过滤: 支持基于 JMES 的动态选择与计算后再处理.
分裂事件(基于 JSON 数组或字符串): 基于字符串数组或 JSON 数组进行事件分裂
多列合并(基于 JSON 数组或字符串): 基于字符串数组或 JSON 数组进行多字段合并
进一步详情, 请参考用户手册.
提取字段的值检查与覆盖模式
关键字字符集:
执行此策略的方法有: REGEX(动态 Key 名),JSON,KV
默认:
[\u4e00-\u9fa5\u0800-\u4e00a-zA-Z][\w\-\.]*
不符合规范的例子: 123=abc 1k=200 {"123": "456"}等
设置覆盖模式, 通过参数 mode
支持的提取方式: REGEX,KV,CSV, Lookup, JSON
("msg",REGEX(r"(\w+):(\d+)",{r"k_\1": r"v_\2"}, mode="fill-auto")
fill - 当原字段不存在或者值为空时
add - 当原字段不存在时设置
overwrite - 总是设置
fill/add/overwrite-auto - (当新值非空时才操作)
默认: fill-auto
4. 事件类操作函数详情
对事件进行直接操作的函数,
覆盖如下几类:
多字段 KV 提取
事件 Meta 操作: 字段丢弃, 重命名
事件输出: 复制输出, 输出后丢弃, 多目标配置, 重载元 meta, 附加更多 TAG 等
注意: 事件类操作也支持与特定表达式函数互操作, 如被表达式函数返回.
进一步详情, 请参考用户手册.
进一步参考
欢迎扫码加入官方钉钉群 (11775223)获得实时更新与阿里云工程师的及时直接的支持:
来源: https://yq.aliyun.com/articles/704938