计算值在转换为 1 之前设置为 0 的平均时间

Posted

技术标签:

【中文标题】计算值在转换为 1 之前设置为 0 的平均时间【英文标题】:Calculating average time a value was set to 0 before transitioning to 1 【发布时间】:2019-05-02 17:32:33 【问题描述】:

我已设置 Prometheus 监控,并且正在根据以下标准生成“正常运行时间”报告:“错误率

( 
  sum(increase(errors[5m]))
  / sum(increase(requests[5m]))
) <= bool 0.1

这会显示在 Grafana 的单一统计面板中。

我现在想要实现的是从“停机”状态恢复所需的平均时间。从图形上看,我需要下面标记为 12 的间隔的平均持续时间。

如何在 Prometheus 中计算此度量?


更新:我不是在寻找 stat 为 0 时的平均持续时间,而是在寻找 stat 为 0 时的平均持续时间。

例如,考虑以下时间序列(假设值每分钟采样一次):

1 1 1 0 0 1 1 1 1 1 0 0 0 1 

我们基本上有两个“下降”区间:0 00 0 0。持续时间定义为 2 分钟和 3 分钟,因此平均恢复时间为 (2+3)/2 = 2.5

我根据阅读文档和实验的理解是avg_over_time 将计算一个算术团队,例如sum(up)/count(up) = 9/14 =~ 0.64

我需要计算第一个度量,而不是第二个。

【问题讨论】:

如果数据点以固定且已知的间隔出现,您可以计算零的数量并计算持续时间。不优雅,但可能有用。 @YuriLachin - 我该怎么做?抱歉,这似乎很明显,但我需要不间断的计数,所以在上图中不是 count(1+2) 而是 count(1), count(2) 。 我对 PromQL 不熟悉,抱歉。 【参考方案1】:

TLDR;

您需要通过您在规则文件中定义的Recording rule 将其转换为 0 或 1,将要读取规则的文件路径添加到您的 prometheus.yml 中。

my_metric_below_threshold = (sum(increase(errors[5m])) / sum(increase(requests[5m]))) <= bool 0.1

然后你可以做 avg_over_time(my_metric_below_threshold[5m])

完整详情

基本上你需要的是值为 0 或 1 的 avg_over_time。 然而 bool 修饰符的结果是即时向量。但是, avg_over_time 在其调用中需要类型范围向量。 instant vector Vs. range vector is.

即时向量 - 一组时间序列,每个时间序列包含一个样本,所有样本共享相同的时间戳

范围向量 - 一组时间序列,其中包含每个时间序列随时间变化的数据点范围

解决方案是使用Recording rules。你可以看到关于这个Prometheus github、this Stack question和这个解释https://www.robustperception.io/composing-range-vector-functions-in-promql的对话。

在 PromQL 中有两种一般类型的函数,它们将时间序列作为输入,一种是采用向量并返回一个向量(例如 abs、ceil、hour、label_replace),另一种是采用范围向量并返回一个向量 (例如 rate、deriv、predict_linear、*_over_time)。

没有接受范围向量并返回范围向量的函数,也没有办法执行任何形式的子查询。即使支持子查询,您也不希望经常使用它们,因为它们会很昂贵。那么该怎么做呢?

答案是对内部函数使用记录规则,然后您可以在它创建的时间序列上使用外部函数。

因此,正如我在上面解释的以及从上面的引述中(摘自 Prometheus 上的核心开发人员),您应该能够获得所需的东西。


问题编辑后添加:

这样做并不简单,因为您需要最后一个样本的“记忆”。但是可以使用Textfile Collector 和Prometheus Http API 来完成。

    如上所述,使用 Recording rule 定义 my_metric_below_threshold。

    安装Node exporter 和Textfile Collector。

    文本文件收集器类似于 Pushgateway,因为它允许从批处理作业中导出统计信息。它还可以用于导出静态指标,例如机器的角色。 Pushgateway 应该用于服务级别指标。 textfile 模块用于与机器相关的指标。 要使用它,请在节点导出器上设置 --collector.textfile.directory 标志。收集器将使用文本格式解析该目录中与 glob *.prom 匹配的所有文件。

    编写一个脚本(即,successful_zeros.py)py/bash,它可以在任何地方运行以使用 Prometheus Http API GET /api/v1/query 查询此指标。

    将连续的零保存为环境参数并清除或增加此参数。

    以Textfile Collector 文档中描述的请求格式写入结果 - 比在 Prometheus 中拥有的successful_zeros_metrics。

    对successive_zeros_metrics 执行avg_over_time()

这是我所说的概念的伪代码:

#!/usr/bin/python

# Run as the node-exporter user like so:
# 0 1 * * * node-exporter /path/to/runner successive_zeros.py

r = requests.get('prometheus/api/v1/query'))
j = r.json()

......

if(j.get('isUp') == 0)
    successive_zeros = os.environ['successive_zeros']
else
   successive_zeros = os.environ['successive_zeros']+
   os.environ['successive_zeros'] = successive_zeros

......
print 'successive_zeros_metrics %d' % successive_zeros

【讨论】:

感谢您抽出宝贵时间撰写此全面回复。我不认为avg_over_time 是我正在寻找的,请查看我所做的更新。 @Robert Munteanu 好的,这不是那么简单。不过,我有一个想法给你。首先,您按照我的解释在记录规则中定义新指标。你可以使用来自 shell/py 脚本的文本文件收集器example1example2,还有更多。您可以使用HTTP API 查询普罗米修斯并计算连续的零。 使用文本文件收集器将此号码报告给 Prometheus。所以最终,你会有一个新的指标来报告连续零的数量,你可以对这个函数执行 avg_over_time() ,这清楚吗?需要我详细说明吗? 谢谢,我需要自己尝试一下,一旦我知道这是否适合我,就会回复。 我认为运行进程外导出器是前进的方向,因此设计方向是您提出的方向。关于 successive_zeros 指标,我认为它不会起作用。原因是我会将指标重置为 0,并且该值会扭曲 avg_over_time 的值。我现在看到的唯一方法是计算 mttr_1dmttr_7d 等的即时值。但这对我来说已经足够接近了,所以谢谢你的努力 - 我会接受答案。

以上是关于计算值在转换为 1 之前设置为 0 的平均时间的主要内容,如果未能解决你的问题,请参考以下文章

将平均值(十进制)转换为年、月和日

将 2 个连续字节转换为一个 int 值在 C# 中提高速度

使用箭头运算符计算结构的 3 个成员的平均值,需要将点运算符转换为箭头

在转换为UTC 0时区之前,Rails在哪里获得时区?

NSNumber 值在 JSON 对象转换为数据时发生变化,然后该数据再次转换回 JSON 对象

将varchar转换为十进制棒球平均值