如何在LogQL中创建自定义计算字段供聚合函数使用
LogQL计算日志字段差值后做分位聚合方案
问题场景
需要处理携带多时间戳字段的JSON格式日志,示例日志结构如下:
{ "time": "2022-06-22T10:33:08.710037238Z", "@version": "1", "message": "Duration at response processing ends", "logger_name": "com.mks.cloud.filters.MainFilter", "thread_name": "reactor-http-epoll-1", "level": "INFO", "level_value": 20000, "rqst_id_ts": "b65c37d9284584e71b1dcd84b6a74075", "rqst_end_ts": "1655893988698", "rqst_start_ts": "1655893988698", "rsp_start_ts": "1655893988709", "rsp_end_ts": "1655893988709" }
目标是计算rsp_end_ts - rqst_start_ts得到请求总耗时,再基于该耗时值做quantile_over_time分位统计。直接unwrap原始时间戳字段得到的分位值无业务意义,直接在unwrap阶段写算术表达式无法运行。
可行方案
方案1:查询阶段直接计算派生字段(Loki 2.4+ 支持)
使用label_format管道阶段完成类型转换和差值计算,生成自定义耗时字段后再做unwrap聚合,可直接运行的查询语句如下:
quantile_over_time(0.99, {app="myapp"} |~ "rsp_end_ts" | json | __error__ = "" | label_format rqst_duration = toInt64(rsp_end_ts) - toInt64(rqst_start_ts) | __error__ = "" | unwrap rqst_duration [5m] ) by (tsNs)
注意事项:
- 示例日志中时间戳是字符串格式,必须通过
toInt64()显式转为整数类型才能参与算术运算,否则会触发计算错误被错误过滤规则拦截 label_format支持加减乘除、取模等基础算术运算,同时内置了类型转换、字符串处理、时间处理类函数,可满足绝大多数派生字段计算需求- 最后一段
__error__=""过滤会同时拦截JSON解析、字段计算阶段产生的所有错误条目,无需重复编写过滤规则
方案2:采集端预计算字段(适配低版本Loki)
如果使用的Loki版本低于2.4,查询阶段不支持数值计算能力,可以在日志采集链路(Promtail、Fluent Bit、Logstash等)提前计算好rqst_duration字段写入日志,查询时直接unwrap该字段即可,示例查询逻辑:
quantile_over_time(0.99, {app="myapp"} |~ "rsp_end_ts" | json | __error__ = "" | unwrap rqst_duration [5m] ) by (tsNs)
内容的提问来源于stack exchange,提问作者MarkoPaulo
相关产品推荐
相关产品推荐

