日志服务数据加工最佳实践: 事件判断

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: 本篇介绍日志服务数据加工: 事件判断最佳实践汇总

场景1:判断字段是否存在

原始日志

a: a_vlue
b:    // 空串

LOG DSL编排

方案一:使用e_has, e_not_has

e_if(e_has("a"), e_set("has_a", true))
e_if(e_has("b"), e_set("has_b", true))
e_if(e_has("c"), e_set("has_c", true))
e_if(e_not_has("a"), e_set("not_has_a", true))
e_if(e_not_has("b"), e_set("not_has_b", true))
e_if(e_not_has("c"), e_set("not_has_c", true))

方案二:使用e_search

e_if(e_search("a: *"), e_set("has_a", true))
e_if(e_search("b: *"), e_set("has_b", true))
e_if(e_search("c: *"), e_set("has_c", true))
e_if(e_search("not a: *"), e_set("not_has_a", true))
e_if(e_search("not b: *"), e_set("not_has_b", true))
e_if(e_search("not c: *"), e_set("not_has_c", true))

加工后日志

a: a_vlue
b:    // 空串
has_a: true
has_b: true
has_c: false
not_has_a: false
not_has_b: false
not_has_c: true
  • 以上两种方案都可用于判断字段是否存在,但是方案一更直观、易理解。
  • 以上加工规则中的两个e_if可通过e_if(条件1,操作1,条件2,操作2)的形式合并为一个e_if,此处为了易于读者阅读,拆成两个。

场景2:判断字段值存在且不为空

原始日志

a: a_vlue
b:     // 空串

LOG DSL编排

方案一:使用字段取值函数v

e_if(v("a"), e_set("not_empty_a", true))
e_if(v("b"), e_set("not_empty_b", true))
e_if(v("c"), e_set("not_empty_c", true))
  • 字段取值函数v,当对应字段存在且值不为空时,其自动转换的Bool值为true,否则为false

方案二:使用e_search

# 至少一个字符
e_if(e_search('a: "?"'), e_set("not_empty_a", true))
e_if(e_search('b: "?"'), e_set("not_empty_b", true))
e_if(e_search('c: "?"'), e_set("not_empty_c", true))

# 正则
e_if(e_search('a~=".+"'), e_set("not_empty_a", true))
e_if(e_search('b~=".+"'), e_set("not_empty_b", true))
e_if(e_search('c~=".+"'), e_set("not_empty_c", true))

# 存在且不为空
e_if(e_search('a: * and not a==""'), e_set("not_empty_a", true))
e_if(e_search('b: * and not b==""'), e_set("not_empty_b", true))
e_if(e_search('c: * and not c==""'), e_set("not_empty_b", true))

加工后日志

a: a_vlue
b:     // 空串
not_empty_a: true
not_empty_b: false
not_empty_c: false
  • 以上三方案都可用于判断字段是否存在,但是方案一更简洁。
  • 以上加工规则中的两个e_if可通过e_if(条件1,操作1,条件2,操作2)的形式合并为一个e_if,此处为了易于读者阅读,拆成两个。

场景3:判断字段值存在但为空

原始日志

a: a_vlue
b:   // 空串

LOG DSL编排

方案一:使用字段取值函数v

e_if(op_and(e_has("a"), op_not(v("a"))), e_set("empty_a", true))
e_if(op_and(e_has("b"), op_not(v("b"))), e_set("empty_b", true))
e_if(op_and(e_has("c"), op_not(v("c"))), e_set("empty_c", true))

# 错误的方案
e_if(op_not(v("a")), e_set("empty_a", true))
e_if(op_not(v("b")), e_set("empty_b", true))
e_if(op_not(v("c")), e_set("empty_c", true))
  • 字段取值函数v,当对应字段存在且值不为空时,其自动转换的Bool值为true,否则为false. 但是只不存在是, 其返回None, op_not(None)时也是返回True.

方案二:使用e_search

e_if(e_search('a==""'), e_set("empty_a", true))
e_if(e_search('b==""'), e_set("empty_b", true))
e_if(e_search('c==""'), e_set("empty_c", true))

# 以下是错误调用
e_if(e_search('a:""'), e_set("empty_a", true))
e_if(e_search('b:""'), e_set("empty_b", true))

注意, 以上错误调用中, 因为:e_search是部分查询, 字段存在时, 无论是否空串的情况下, 空串a: ""永远会真.

加工后日志

a: a_vlue
b:    // 空串
empty_a: false
empty_b: true
empty_b: false
  • 以上方案中显然方案二更简洁.
  • 以上加工规则中的两个e_if可通过e_if(条件1,操作1,条件2,操作2)的形式合并为一个e_if,此处为了易于读者阅读,拆成两个。

场景4:基于字段值的逻辑查询判断

原始日志

"日志1"
http_host:  m1.abcd.com
status:  200
request_method:  GET
scheme:  https
header_length: 700
body_length: 1200

"日志2"
http_host:  m2.abcd.com
status:  200
request_method:  POST
scheme:  https
header_length: 100
body_length: 800

"日志3"
http_host:  m3.abcd.com
status:  200
request_method:  GET
scheme:  http
header_length: 700
body_length: 800

"日志4"
http_host:  m4.abcd.com
status:  404
request_method:  GET
scheme:  https
header_length: 100
body_length: 300

加工需求1

  • 为所有status字段值为200的日志事件, 添加一个字段type,其值为normal

LOG DSL编排

e_if(e_match("status", "200"), e_set("type", "normal))
或者
e_if(e_search("status==200"), e_set("type", "normal"))
  • 在此相对简单的场景下,以上两种方式都可以,并无太大差别。
  • 一般情况下status: 200也可以, 只是==更精准一些.

加工后的日志

"日志1"
type: normal
http_host:  m1.abcd.com
status:  200
request_method:  GET
scheme:  https
header_length: 700
body_length: 1200

"日志2"
type: normal
http_host:  m2.abcd.com
status:  200
request_method:  POST
scheme:  https
header_length: 100
body_length: 800

"日志3"
type: normal
http_host:  m3.abcd.com
status:  200
request_method:  GET
scheme:  http
header_length: 700
body_length: 800

"日志4"
http_host:  m4.abcd.com
status:  404
request_method:  GET
scheme:  https
header_length: 100
body_length: 300

加工需求2

  • 为所有status字段值为200 并且 request_method字段值为GET 并且 scheme字段值为https 的日志事件, 添加一个字段type,其值为normal

LOG DSL编排

e_if(e_search("status==200 and request_method==GET and scheme==https"), e_set("type", "normal"))
或者
e_if(e_match_all("status", "200", "request_method","GET", "scheme", "https"), e_set("type", "normal"))
  • 在此场景下,需要同时满足多个字段的匹配条件,可以使用e_searche_match_all
  • e_search用法相对更简洁一些。
  • 一般情况下e_search==也可以换成:status: 200也可以, 只是==更精准一些.

加工后的日志

"日志1"
type: normal
http_host:  m1.abcd.com
status:  200
request_method:  GET
scheme:  https
header_length: 700
body_length: 1200

"日志2"
http_host:  m2.abcd.com
status:  200
request_method:  POST
scheme:  https
header_length: 100
body_length: 800

"日志3"
http_host:  m3.abcd.com
status:  200
request_method:  GET
scheme:  http
header_length: 700
body_length: 800

"日志4"
http_host:  m4.abcd.com
status:  404
request_method:  GET
scheme:  https
header_length: 100
body_length: 300

加工需求3

  • 为所有status字段值为200 或者 request_method字段值为GET 或者 scheme字段值为https 的日志事件, 添加一个字段type,其值为normal

LOG DSL编排

e_if(e_search("status==200 or request_method==GET or scheme==https"), e_set("type", "normal"))
或者
e_if(e_match_any("status", "200", "request_method","GET", "scheme", "https"), e_set("type", "normal"))
  • 在此场景下,需要满足多个字段的匹配条件中的其中一个,可以使用e_searche_match_any
  • e_search用法相对更简洁一些。

加工后的日志

"日志1"
type: normal
http_host:  m1.abcd.com
status:  200
request_method:  GET
scheme:  https
header_length: 700
body_length: 100

"日志2"
type: normal
http_host:  m2.abcd.com
status:  200
request_method:  POST
scheme:  https
header_length: 100
body_length: 800

"日志3"
type: normal
http_host:  m3.abcd.com
status:  200
request_method:  GET
scheme:  http
header_length: 700
body_length: 800

"日志4"
type: normal
http_host:  m4.abcd.com
status:  404
request_method:  GET
scheme:  https
header_length: 100
body_length: 1300

加工需求4

  • 为所有status字段值为200 并且 request_method字段值为GET 并且 header_lengthbody_length的字段值之和小于等于1000的日志事件, 添加一个字段type,其值为normal

LOG DSL编排

e_if(op_and(e_search("status: 200 and request_method: GET"), op_le(op_sum(v("header_length"), v("body_length")), 1000)), e_set("type", "normal"))
  • 在更复杂的逻辑场景下,可通过e_search和其他表达式函数的组合来完成。

加工后的日志

"日志1"
type: normal
http_host:  m1.abcd.com
status:  200
request_method:  GET
scheme:  https
header_length: 700
body_length: 100

"日志2"
http_host:  m2.abcd.com
status:  200
request_method:  POST
scheme:  https
header_length: 100
body_length: 800

"日志3"
http_host:  m3.abcd.com
status:  200
request_method:  GET
scheme:  http
header_length: 700
body_length: 800

"日志4"
http_host:  m4.abcd.com
status:  404
request_method:  GET
scheme:  https
header_length: 100
body_length: 1300

进一步参考

欢迎扫码加入官方钉钉群获得实时更新与阿里云工程师的及时直接的支持:
image

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
4月前
|
SQL 关系型数据库 MySQL
我使用flinkcdc的sql形式进行全量同步,4张表,有两张表数据没进去,看日志,id怎么是null呢?
我使用flinkcdc的sql形式进行全量同步,4张表,有两张表数据没进去,看日志,id怎么是null呢?
116 40
|
6月前
|
XML Java API
SpringBoot3.x日志生产最佳实践原来是这样!
SpringBoot3.x日志生产最佳实践原来是这样!
153 0
|
21小时前
|
机器学习/深度学习
R语言计量经济学:工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
R语言计量经济学:工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
22 0
|
25天前
|
存储 SQL Serverless
Serverless 应用引擎常见问题之应用下的【应用事件】以及企业级特性下的【事件中心】没有日志如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
33 0
|
2月前
|
JSON 监控 Java
Java Web开发中的异常处理与日志记录最佳实践
Java Web开发中的异常处理与日志记录最佳实践
|
3月前
|
存储 JSON 运维
【运维】Powershell 服务器系统管理信息总结(进程、线程、磁盘、内存、网络、CPU、持续运行时间、系统账户、日志事件)
【运维】Powershell 服务器系统管理信息总结(进程、线程、磁盘、内存、网络、CPU、持续运行时间、系统账户、日志事件)
49 0
|
4月前
|
SQL 存储 监控
使用CloudLens for SLS监控Project资源配额最佳实践
本文主要介绍如何使用CloudLens for SLS中全局错误日志、监控指标做Project 资源配额的水位监控 、超限监控 以及 如何提交资源配额提升申请。
79337 19
使用CloudLens for SLS监控Project资源配额最佳实践
|
4月前
|
SQL 关系型数据库 MySQL
⑩⑥ 【MySQL】详解 触发器TRIGGER,协助 确保数据的完整性,日志记录,数据校验等操作。
⑩⑥ 【MySQL】详解 触发器TRIGGER,协助 确保数据的完整性,日志记录,数据校验等操作。
37 0
|
4月前
|
缓存 关系型数据库 MySQL
这个错误提示表明Flink CDC在解析MySQL的二进制日志时,找不到对应表的TableMap事件。
这个错误提示表明Flink CDC在解析MySQL的二进制日志时,找不到对应表的TableMap事件。
145 2
|
8小时前
|
存储 数据库 流计算
Flink CDC为什么我几张表十来条数据就产生了那么大日志?
Flink CDC为什么我几张表十来条数据就产生了那么大日志?
108 0

相关产品

  • 日志服务