按 HTTP 状态分组时不返回任何数据的错误率

Iai*_*can 3 grafana prometheus

我在 Grafana 中有一个图表,使用 Prometheus 数据源来显示 API 的错误率。这对于这个查询工作得很好:

sum(rate(va_request_response_code{endpoint="api", statusCode!="200"}[5m])) by (exported_endpoint, statusCode)
Run Code Online (Sandbox Code Playgroud)

我从 API 获取非 200 响应代码的比率,然后在运行 3 个 API 实例时将这些比率相加。然后,我按照exported_endpoint(用户请求的实际路径)和statusCode返回的确切 HTTP 状态代码对它们进行分组。

虽然这作为原始数字有点用处,但并没有那么有用。每秒 100 个请求中出现 100 个错误是非常糟糕的,而每秒 1,000,000 个请求中出现 100 个错误则不是什么问题。因此,我想除以请求总数,但我很挣扎。如果我做:

(sum(rate(va_request_response_code{endpoint="api", statusCode!="200"}[5m])) by (exported_endpoint, statusCode))/(sum(rate(va_request_response_code{endpoint="api"}[5m])) by (exported_endpoint))
Run Code Online (Sandbox Code Playgroud)

然后它只是显示No data points这是有意义的,因为在第一种情况下它是按被除数中的 statusCode 分组而不是除数中的,因此它必须意味着它正在尝试在除法之前找到匹配项。相反,这样做确实有效:

(sum(rate(va_request_response_code{endpoint="api", statusCode!="200"}[5m])) by (exported_endpoint))/(sum(rate(va_request_response_code{endpoint="api"}[5m])) by (exported_endpoint))
Run Code Online (Sandbox Code Playgroud)

但随后我失去了我想要的按状态代码分组。理想情况下,我想知道 x% 的请求返回404,y% 返回500。这可能吗?

Ali*_*ean 9

你需要这样写:

sum by (exported_endpoint, statusCode) (rate(va_request_response_code{endpoint="api", statusCode!="200"}[5m]))
  / ignoring(statusCode) group_left
sum by (exported_endpoint) (rate(va_request_response_code{endpoint="api"}[5m]))
Run Code Online (Sandbox Code Playgroud)

即取两个向量,左边一个有statusCode标签,右边一个没有;将它们分开,忽略statusCode标签;然后将左向量的标签应用于结果。

以下是PromQL 中多对一和一对多匹配的 Prometheus 文档的链接。