问题描述
我需要计算按特定标头分组的 API 调用.例如,我想知道有多少 API 调用具有 headerX=valueY
.
I have a requirement to count API calls grouped by certain headers. For example, I want to find out how many API calls had headerX=valueY
.
为此,我想发布一个这样的指标(请忽略命名约定),以便我以后可以查询.
For that, I want to publish a metric like this (please ignore the naming convention) so that I can query later.
http_request{HeaderX=valueR、HeaderY=valueM 等...}
如果 Prometheus 可以做到这一点,请帮助我.
If that's possible to do with Prometheus, please help me with it.
推荐答案
正如@tkausl 所观察到的,这是可能的,但不推荐.您没有说明您使用的是哪个特定客户端(即 Java、Go、Python 等),所以这里有一个 Java 示例":
As @tkausl observed, it is possible but not recommended. You don't say which specific client (i.e. Java, Go, Python etc.) you're using, so here's a Java example":
static final Counter httpRequests = Counter.build()
.name("http_requests_total")
.help("Total number of requests by path and header values.")
.labelNames("path", "content_type", "user_agent")
.register();
然后在您的请求处理程序/拦截器中:
And then in your request handler/interceptor:
httpRequests.labels(requestPath, contentType, userAgent).inc();
不推荐这样做的原因是,如果您的标头可以具有无限数量的值(并且它们可以,因为您可以使用任意随机标头值发出 curl
请求),那么您可以最终得到无限数量的时间序列.例如
The reason this not recommended is that if your headers can have an infinite number of values (and they can, since you can make a curl
request with whatever random header values you please) then you can end up with an infinite number of time series. E.g.
http_requests_total{path="/",content_type="text/plain",user_agent="curl 1.0"} 5
http_requests_total{path="/",content_type="text/plain",user_agent="curl 1.0-whatever"} 1
http_requests_total{path="/",content_type="text/plain",user_agent="curl 1.0-the"} 1
http_requests_total{path="/",content_type="text/plain",user_agent="curl 1.0-client"} 1
http_requests_total{path="/",content_type="text/plain",user_agent="curl 1.0-wants"} 1
现在将每个标签的值相乘(假设您有 10 个 API 端点、10 个不同的内容类型和 100 个不同的用户代理,您自己就有 10k 个指标.
Now multiply that for each label (say you have 10 API endpoints, 10 different content types and 100 different user agents, you've got yourself 10k metrics.
因此,如果您真的对几个可能的标头和一些可能的值(比如 JSON、XML 和文本;以及 Chrome、Firefox 和 IE)感兴趣,那么记录这些特定值(比如 "application/json"
) 或使用正则表达式匹配 ".*Chrome.*"
然后将 "Chrome"
记录为标签值.对于任何不匹配的标头值,您可以使用 "other"
或您想要的任何特定值.这样你的客户就不能炸毁你的 Prometheus.(客户端库可能比 Prometheus 管理多个值的时间长得多,Prometheus 需要为每个值保留一个时间序列,即使它永远停留在 1.)
So if you're really interested in a couple of possible headers and a handful of possible values (say JSON, XML and text; and Chrome, Firefox and IE), then record those specific values (say "application/json"
) or use a regex to match for ".*Chrome.*"
and then record "Chrome"
as the label value. And for any header value that doesn't match, you can use "other"
or whatever specific value you want. That way your clients can't blow up your Prometheus. (The client library can likely manage the multiple values much longer than Prometheus, which needs to keep a timeseries for each value, even if it's forever stuck at 1.)
这篇关于我不能将原始请求数据推送到 Prometheus 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!