创建Elastic Watcher计算两日字段百分位数差异及嵌套聚合问题
解决Elastic Watcher中获取前日/当日字段值并计算差值的问题
你的核心需求应该是拿到前日和当日的upstream、downstream字段百分比最大值,再通过差值做后续处理对吧?先看看你现有配置里的几个关键问题:
原配置的主要问题
- 日期范围定义错误:比如
aggs1和aggs2里的from和to都是now-2d/d,这相当于空时间范围,根本查不到数据。前日的正确范围应该是from: "now-2d/d", to: "now-1d/d"(从两天前午夜到一天前午夜);当日范围是from: "now-1d/d", to: "now/d"(从昨天午夜到今天午夜)。 - 聚合结构语法错误:每个
range聚合的子聚合(aggs)必须嵌套在range内部,你现在的aggs2、aggs3、aggs4都把aggs和range放在同级,这是语法错误。 - 聚合冗余:四个独立聚合完全可以合并成更简洁的结构,减少重复代码。
修正后的Watcher Input配置
下面是调整后的搜索请求体,一次搜索就能返回你需要的四个数值:
{ "query": { "bool": { "filter": { "range": { "@timestamp": { "lte": "now", "gte": "now-{{ctx.metadata.window}}" } } } } }, "aggs": { "date_ranges": { "range": { "field": "@timestamp", "ranges": [ { "key": "前日", "from": "now-2d/d", "to": "now-1d/d" }, { "key": "当日", "from": "now-1d/d", "to": "now/d" } ] }, "aggs": { "upstream_percent_max": { "max": { "script": { "source": "doc['upstream'].value / 100" } } }, "downstream_percent_max": { "max": { "script": { "source": "doc['downstream'].value / 100" } } } } } } }
配置说明
- 用一个
date_ranges聚合同时定义前日和当日的时间范围,每个范围用key命名方便后续识别。 - 在每个时间范围下,嵌套两个子聚合分别计算
upstream和downstream的百分比最大值,一次搜索就能拿到四个目标值:- 前日的upstream最大值
- 前日的downstream最大值
- 当日的upstream最大值
- 当日的downstream最大值
后续计算差值的处理
在Watcher的transform或者condition阶段,你可以通过ctx.payload.aggregations.date_ranges.buckets提取数值并计算差值,比如用Painless脚本:
// 提取前日的两个字段最大值 def prev_day_up = ctx.payload.aggregations.date_ranges.buckets[0].upstream_percent_max.value; def prev_day_down = ctx.payload.aggregations.date_ranges.buckets[0].downstream_percent_max.value; // 提取当日的两个字段最大值 def curr_day_up = ctx.payload.aggregations.date_ranges.buckets[1].upstream_percent_max.value; def curr_day_down = ctx.payload.aggregations.date_ranges.buckets[1].downstream_percent_max.value; // 计算差值 def up_diff = curr_day_up - prev_day_up; def down_diff = curr_day_down - prev_day_down; // 将差值存入上下文,供后续告警等动作使用 ctx.payload.up_diff = up_diff; ctx.payload.down_diff = down_diff;
这样你就能在后续的actions里使用这些差值,比如发送告警通知时带上差值信息。
内容的提问来源于stack exchange,提问作者Shantanu Deshpande
相关产品推荐
相关产品推荐

