如何在label_replace后正确使用increase实现HTTP状态码分段聚合?
按状态码段(2xx/4xx/5xx)聚合请求量的PromQL解决方案
问题背景
我们有计数器指标http_server_requests_seconds_count,样例数据如下:
http_server_requests_seconds_count{instance="localhost:8080", method="GET", outcome="SUCCESS", status="200", uri="/actuator/health"} 20 http_server_requests_seconds_count{instance="localhost:8080", method="GET", outcome="SUCCESS", status="201", uri="/abc/xyz"} 50
原本按status统计时间范围请求量的查询是:
sum(increase(http_server_requests_seconds_count)[$__interval]) by (status)
现在需要按2xx、4xx、5xx这类状态码段聚合,但尝试的查询报错:
sum(increase(label_replace(http_server_requests_seconds_count, "status_new", "${1}xx", "status", "(2|3|4|5)(.{2})")[$__interval])) by (status_new)
错误信息:
Error executing query: invalid parameter "query": 1:114: parse error: ranges only allowed for vector selectors
错误原因
[$__interval]时间范围只能直接跟在原始指标选择器后面,不能放在label_replace处理后的表达式上——label_replace返回的是瞬时向量,无法直接附加时间范围。
正确解决方案
方法一:先计算增量,再做标签替换与聚合
把时间范围放在原始指标上,先计算区间增量,再生成状态码段标签,最后聚合:
sum(label_replace(increase(http_server_requests_seconds_count[$__interval]), "status_class", "${1}xx", "status", "(2|4|5).*")) by (status_class)
- 逻辑:先对原始指标计算
$__interval内的请求增量,再通过正则提取状态码第一位,生成status_class标签(如2xx、4xx),最后按新标签求和。 - 正则说明:
(2|4|5).*匹配以2、4、5开头的所有状态码,捕获组${1}取第一位,拼接成xx后缀。
方法二:利用内置outcome标签(如果可靠)
观察到指标中已有outcome="SUCCESS"标签,Spring Boot Actuator生成的指标里,outcome会自动映射状态码段:
SUCCESS对应2xxCLIENT_ERROR对应4xxSERVER_ERROR对应5xx
如果该标签是可靠的,可直接用以下简洁查询:
sum(increase(http_server_requests_seconds_count[$__interval])) by (outcome)
方法三:标签关联式聚合(备选)
如果需要更灵活的标签映射,可通过标签关联的方式实现:
sum by (status_prefix) ( increase(http_server_requests_seconds_count[$__interval]) * on(status) group_left(status_prefix) ( label_replace(http_server_requests_seconds_count, "status_prefix", "${1}xx", "status", "(2|4|5).*") ) )
内容的提问来源于stack exchange,提问作者SoT
相关产品推荐
相关产品推荐

