Class TranslateMetricsAggregate


public final class TranslateMetricsAggregate extends OptimizerRules.OptimizerRule<Aggregate>
Rate aggregation is special because it must be computed per time series, regardless of the grouping keys. The keys must be `_tsid` or a pair of `_tsid` and `time_bucket`. To support user-defined grouping keys, we first execute the rate aggregation using the time-series keys, then perform another aggregation with the resulting rate using the user-specific keys.

This class translates the aggregates in the METRICS commands to standard aggregates. This approach helps avoid introducing new plans and operators for metrics aggregations specially.

Examples:

 METRICS k8s max(rate(request))

 becomes

 METRICS k8s
 | STATS rate(request) BY _tsid
 | STATS max(`rate(request)`)

 METRICS k8s max(rate(request)) BY host

 becomes

 METRICS k8s
 | STATS rate(request), VALUES(host) BY _tsid
 | STATS max(`rate(request)`) BY host=`VALUES(host)`

 METRICS k8s avg(rate(request)) BY host

 becomes

 METRICS k8s
 | STATS rate(request), VALUES(host) BY _tsid
 | STATS sum=sum(`rate(request)`), count(`rate(request)`) BY host=`VALUES(host)`
 | EVAL `avg(rate(request))` = `sum(rate(request))` / `count(rate(request))`
 | KEEP `avg(rate(request))`, host

 METRICS k8s avg(rate(request)) BY host, bucket(@timestamp, 1minute)

 becomes

 METRICS k8s
 | EVAL  `bucket(@timestamp, 1minute)`=datetrunc(@timestamp, 1minute)
 | STATS rate(request), VALUES(host) BY _tsid,`bucket(@timestamp, 1minute)`
 | STATS sum=sum(`rate(request)`), count(`rate(request)`) BY host=`VALUES(host)`, `bucket(@timestamp, 1minute)`
 | EVAL `avg(rate(request))` = `sum(rate(request))` / `count(rate(request))`
 | KEEP `avg(rate(request))`, host, `bucket(@timestamp, 1minute)`
 
Non-rate aggregates will be rewritten as a pair of to_partial and from_partial aggregates, where the `to_partial` aggregates will be executed in the first pass and always produce an intermediate output regardless of the aggregate mode. The `from_partial` aggregates will be executed on the second pass and always receive intermediate output produced by `to_partial`. Examples:
 METRICS k8s max(rate(request)), max(memory_used) becomes:

 METRICS k8s
 | STATS rate(request), $p1=to_partial(max(memory_used)) BY _tsid
 | STATS max(`rate(request)`), `max(memory_used)` = from_partial($p1, max($_))

 METRICS k8s max(rate(request)) avg(memory_used) BY host

 becomes

 METRICS k8s
 | STATS rate(request), $p1=to_partial(sum(memory_used)), $p2=to_partial(count(memory_used)), VALUES(host) BY _tsid
 | STATS max(`rate(request)`), $sum=from_partial($p1, sum($_)), $count=from_partial($p2, count($_)) BY host=`VALUES(host)`
 | EVAL `avg(memory_used)` = $sum / $count
 | KEEP `max(rate(request))`, `avg(memory_used)`, host

 METRICS k8s min(memory_used) sum(rate(request)) BY pod, bucket(@timestamp, 5m)

 becomes

 METRICS k8s
 | EVAL `bucket(@timestamp, 5m)` = datetrunc(@timestamp, '5m')
 | STATS rate(request), $p1=to_partial(min(memory_used)), VALUES(pod) BY _tsid, `bucket(@timestamp, 5m)`
 | STATS sum(`rate(request)`), `min(memory_used)` = from_partial($p1, min($)) BY pod=`VALUES(pod)`, `bucket(@timestamp, 5m)`
 | KEEP `min(memory_used)`, `sum(rate(request))`, pod, `bucket(@timestamp, 5m)`