【问题标题】:How do I track sporadic data with prometheus in nodejs?如何在 nodejs 中使用 prometheus 跟踪零星数据?
【发布时间】:2021-11-15 18:38:25
【问题描述】:

我在 nodejs 中使用prom-client 来发布/metrics 端点。我想监控随着时间的推移偶尔发生的不同数量的销售。

在 prometheus 中跟踪零星或不连续指标的最佳方法是什么?现有的指标类型似乎都不合适。

这是一个简单的设置,带有Gauge,显然没有捕获

import express from 'express'
import promClient, { Gauge } from 'prom-client'

export const someMetric = new Gauge({
  name: 'some_metric',
  help: 'Track some metric; type = [a, b, c]',
  labelNames: ['one', 'two'],
})

const metricServer = express()
metricServer.get('/metrics', async (req, res) => {
  console.log('Metrics scraped')
  res
    .set('content-type', 'text/plain')
    .send(await promClient.register.metrics())
})

// intermittent callback that reports sales
service.onSale(value => {
  // this will simply overwrite the previous sale :(
  someMetric.labels('a', 'all').set(value)
})

metricServer.listen(9991, () =>
  console.log(`???? Prometheus listening on http://localhost:9991/metrics`)
)

我目前的计划是创建一个新数据库,以在内部跟踪滚动的 24 小时平均销售额,然后将其作为单个连续指标公开给 prometheus。不过,除了 prometheus 的聚合功能之外,在内部保持滚动平均值似乎很尴尬。

【问题讨论】:

  • 我无法评论 Prometheus,因为我不关心它并实现了 influxDB。但是,如果没有明确的数据类型可以帮助您,您当前的计划听起来很合理。我会考虑不使用平均值,而是使用移动总和。平均值是一个低通滤波器,您的“零星”数据看起来像是滤波器的高频尖峰。
  • 为什么不随着时间的推移聚合?即使它们不是连续的,您仍然可以使用仪表。您的间隔应该足够大以捕获您想要的数据。
  • @juanecabellob 与 Prometheus 聚合还是在内部聚合?也许你可以解释一个完整的答案。谢谢!
  • @RaineRevere 在我这样做之前,您到底想跟踪什么数据?警报还是阴谋?
  • 用于随时间绘制

标签: node.js prometheus prom-client


【解决方案1】:

在不知道捕获这些数据的确切目的的情况下,很难判断量表、摘要或直方图是否最适合您的需求,但我会尽我所能满足我的假设。但首先,让我们先简化一下 Prometheus 所做的事情,这可能有助于想象我的发展方向。

Prometheus 是一个时间序列数据库。这意味着,每次您的数据被抓取时,它都会在给定的时间戳上保存您的指标快照及其记录值,因此在一个非常简化的版本中,您最终会得到类似 <timestamp, your_metric{label="1"} value> 的内容。

假设您只想获取销售期间支付的金额,并且您的客户数量有限,Gauges 可以帮助您在任何给定时间查看支付金额,通过标签区分任何客户*(尽管,计数器也可以)。

现在,您的问题是关于跟踪数据。绘制这应该不是问题。即使数据不连续,您也会在任何绘图仪中看到数据,例如格拉法纳。但是,看到点 (<timestamp, value of your metric for each label combination>) 或细线不会说明任何故事,使它们几乎毫无意义并且难以跟踪。为了使这些数据连续,您可以做的就是随着时间的推移进行聚合。随着时间的推移进行聚合,您可以在每个时间戳处获取聚合值,而不是在您选择的时间窗口中获取聚合值。

让我们试着想象一下:

Prometheus 每 2 秒抓取一次数据。在 30 分钟内,您的仪表仅记录 4 次销售。两个不同的客户在 1 分钟有两个,两个不同的客户在 20 分钟有两个。如果按原样绘制,您将看到 4 个点。如果你汇总这个,例如平均而言,您会在第 1 分钟和第 20 分钟看到两个点,其中包含两个销售的平均值。

如果您有兴趣看到一个连续的故事,例如要查看给定时间段内的平均销售额是多少,您需要随着时间的推移进行汇总。关键区别:在任何绘图点,您都会看到该时间戳和所选时间窗口之间的聚合值。因此,如果您在上面的示例中使用 avg_over_time 而不是 avg 并选择 30 分钟的时间窗口,那么您将有 0 到第 1 分钟,从第 1 分钟到第 20 分钟,您会看到平均值在第 1 分钟发生的两次销售,从第 20 分钟到第 31 分钟(从第 1 分钟开始两次销售后 30 分钟),您会看到所有 4 次销售的平均值。然后,从第 31 分钟到第 50 分钟,您将看到最后 2 次销售的平均值,然后从第 50 分钟再次看到 0。如果您选择更大的时间窗口,例如 24 小时,您将获得相同的效果。请记住,这个数字越大,Prometheus DB 的计算量就越大。拥有大量标签*,每个标签都具有很大的值差异,这将使此类时间窗口变得非常缓慢。对此的查询如下所示:

*我强调指标基数的重要性:the more labels you add to a metric, the more entries prometheus has to go over to do calculations since for each label combination it will create a time-series

【讨论】:

  • 感谢您的详细解答!如果我在一个抓取窗口内从同一个客户那里获得两次销售会发生什么?如果我使用仪表,第一个不会被覆盖吗?我必须在一个抓取窗口中记录所有销售额的总和,但是我会丢失关于有多少不同销售额的信息。
  • 即我仍然从根本上困惑,不是关于如何在普罗米修斯中查询数据,而是关于如何从相对于抓取窗口可能很多的不连续事件中捕获数据。这让我觉得我应该使用直方图,而不用担心能够区分单个销售额。
  • 是的,它将被覆盖。在这种情况下,您可以使用计量器并通过某种唯一的 ID 区分不同的销售,但可能会适得其反,或者直方图,但您可能会如您所指出的那样丢失获取个人信息的信息。根据您所说的,使用直方图可能会更好。
  • 好的,谢谢!
猜你喜欢
  • 2017-08-06
  • 2018-01-01
  • 2011-02-04
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 2021-08-08
  • 2020-07-08
  • 2022-01-25
相关资源
最近更新 更多