Micrometer/Prometheus: 如何衡量处理时长?
Micrometer/Prometheus: How to measure processing duration?
我想测量处理某些数据需要多长时间:我的应用程序以固定速率从给定源读取该数据。在每个圈子之前我存储 Instant.now()
。我读取数据,将单个时间戳添加到每个条目。数据被存储、转换,就在我通过 WebSockets 发送之前,我想测量 now()
和初始时间戳之间的持续时间。
我试过了
long millis = Duration.between(dataEntry.getReceivedTimestamp(), Instant.now()).toMillis();
LOG.info(millis + "ms");
registry.timer("processingDuration").record(millis, TimeUnit.MILLISECONDS);
但想象一下,我只能使用 processingDuration_seconds_count
、_max
和 _sum
。 count
和 sum
随时间增加(当然),max
大多数时间保持不变。那么我如何看到更高和更低的负载高原呢?我尝试 irate(processingDuration_seconds_sum[10m])
至少看到跳跃,但由于 irate()
仅使用两个数据点,我仍然无法轻松识别较长时间的高负载。另外:图表中的值约为 0.6,而记录的毫秒数约为 5-10,所以我在这里丢失了实际值。
所以我尝试使用 Gauge
代替——它应该允许增加和减少值:
registry.gauge("processingDurationGauge", millis);
我以为这会在记录的毫秒范围内上下波动,但它一直是 92。
如何衡量数据的整个时间?
问题是,long
不是线程安全的,参见 this answer. Doing it as documented 按预期工作:
private final AtomicLong processingDuration;
// ...
// in constructor:
processingDuration = meterRegistry.gauge("processingDuration", new AtomicLong(0L));
// ...
// before finishing the data entries' handling:
long millis = Duration.between(dataEntry.getReceivedTimestamp(), Instant.now()).toMillis();
LOG.info(millis + "ms");
processingDuration.set(millis);
使用计时器 record
是正确的解决方案。
long millis = Duration.between(dataEntry.getReceivedTimestamp(), Instant.now()).toMillis();
LOG.info(millis + "ms");
registry.timer("processingDuration").record(millis, TimeUnit.MILLISECONDS);
假设您每 30 秒抓取一次,您可以使用 _sum
和 _count
来获取平均记录持续时间:
increase(processingDuration_seconds_sum[1m])/increase(processingDuration_seconds_count[1m])
如果您想将当前持续时间的表现与过去一天的平均值进行比较:
((increase(processingDuration_seconds_sum[1m])/
increase(processingDuration_seconds_count[1m]))*1.50) >
increase(processingDuration_seconds_sum[24h])/
increase(processingDuration_seconds_count[24h])
那只会 return 1 米平均值超过每日平均值 1.5 倍的值。 (我还没有测试过那个查询,但它应该明白了)。
我想测量处理某些数据需要多长时间:我的应用程序以固定速率从给定源读取该数据。在每个圈子之前我存储 Instant.now()
。我读取数据,将单个时间戳添加到每个条目。数据被存储、转换,就在我通过 WebSockets 发送之前,我想测量 now()
和初始时间戳之间的持续时间。
我试过了
long millis = Duration.between(dataEntry.getReceivedTimestamp(), Instant.now()).toMillis();
LOG.info(millis + "ms");
registry.timer("processingDuration").record(millis, TimeUnit.MILLISECONDS);
但想象一下,我只能使用 processingDuration_seconds_count
、_max
和 _sum
。 count
和 sum
随时间增加(当然),max
大多数时间保持不变。那么我如何看到更高和更低的负载高原呢?我尝试 irate(processingDuration_seconds_sum[10m])
至少看到跳跃,但由于 irate()
仅使用两个数据点,我仍然无法轻松识别较长时间的高负载。另外:图表中的值约为 0.6,而记录的毫秒数约为 5-10,所以我在这里丢失了实际值。
所以我尝试使用 Gauge
代替——它应该允许增加和减少值:
registry.gauge("processingDurationGauge", millis);
我以为这会在记录的毫秒范围内上下波动,但它一直是 92。
如何衡量数据的整个时间?
问题是,long
不是线程安全的,参见 this answer. Doing it as documented 按预期工作:
private final AtomicLong processingDuration;
// ...
// in constructor:
processingDuration = meterRegistry.gauge("processingDuration", new AtomicLong(0L));
// ...
// before finishing the data entries' handling:
long millis = Duration.between(dataEntry.getReceivedTimestamp(), Instant.now()).toMillis();
LOG.info(millis + "ms");
processingDuration.set(millis);
使用计时器 record
是正确的解决方案。
long millis = Duration.between(dataEntry.getReceivedTimestamp(), Instant.now()).toMillis();
LOG.info(millis + "ms");
registry.timer("processingDuration").record(millis, TimeUnit.MILLISECONDS);
假设您每 30 秒抓取一次,您可以使用 _sum
和 _count
来获取平均记录持续时间:
increase(processingDuration_seconds_sum[1m])/increase(processingDuration_seconds_count[1m])
如果您想将当前持续时间的表现与过去一天的平均值进行比较:
((increase(processingDuration_seconds_sum[1m])/
increase(processingDuration_seconds_count[1m]))*1.50) >
increase(processingDuration_seconds_sum[24h])/
increase(processingDuration_seconds_count[24h])
那只会 return 1 米平均值超过每日平均值 1.5 倍的值。 (我还没有测试过那个查询,但它应该明白了)。