prometheus联合查询的要求
prometheus的指标主要是组成是metrics_name,metrics_label,timestamp,value。其中timestamp是在一个指标的时间序列中可以看到。
例如metrics_name[5m]
这样可以看到这个metrics里5分钟内的一个时间序列值,这里就可以看到时间戳了。
剩下的组成部分,我们都是比较常见的,metrics_name,metrics_label,value。
prometheus不同的metrics_name可以做运算,前提条件是metrics_label是相同的。
这里并不要求metrics_label完全相同,我们可以根据ignoring和on的操作来进行label的筛选.
method_code:http_errors:rate5m{method="get", code="500"} 24
method:http_requests:rate5m{method="get"} 600
可以选择使用ignoring(code)或者on(method)的方式进行运算,这两个表达式都是对label的数据进行筛选,保留下来的指标参与运算中来。
那么如果是另外一种情况呢
method_code:http_errors:rate5m{method="get", code="500"} 24
method:http_requests:rate5m{http_method="get"} 600
根据prometheus的规则,你会发现下面的http_method对应的就是上面的method。只是因为一些原因分开表达了。他们其实表达的是同一个事情,如果是这样,我们应该如何进行运算呢?
解决方案
- 抓取的时候进行整理
prometheus抓取数据的时候是有很多能力的。其中就有一项可以对抓取到的label进行修改。只需要编写表达式就可以。例如上面的http_method,可以在这里进行label_name的转化。把
http_method转化为method进行存储。查询数据的时候只会有method。这就满足了prometheus的要求。 - 查询语句使用label_replace
label_replace也可以在查询语句的时候进行一定的修改。这个是一个中间结果,他并不会存储到promethus中。我们需要把method:http_requests:rate5m{http_method=“get”}先通过表达式转化成我们需要的method:http_requests:rate5m{method=“get”}。
prometheus的label_replace正好满足我们的需求。
label_replace(method:http_requests:rate5m{http_method="get"}, "method", "$1", "http_method", "(.*)")
上面的这个函数表达式,
method:http_requests:rate5m{http_method=“get”} 这个表示我们查询出的序列。
method表示要加入的label_name
$1表示后面的正则表达式匹配到的内容
http_method是原有的label_name
(.*)是一个正则表达式,匹配我们的数据,这里简单就是全部。
执行完这个表达式以后,就会返回一个prometheus的新序列,其中含有label method,他的值就是http_method的值。拿着这个序列再进行下一步的计算。
小结
以上两种方式都能满足我们的表达,第一种比较彻底,从存储上就已经修改过来了,第二张是一个临时方案,他不会更改存储的数据内容,这个比较适合不想改变原有结构的方案,但是他每次改动的数据有限,小的改动可以考虑第二种方案,大的改动就适合第一种。