我想实现一种新型计量器 (
HeartbeatMeter
) 来跟踪来自上游源的心跳的活跃度。
界面会非常简单,比如:
private interface HeartbeatMeter {
void beat(Instant timestamp);
}
仪表暴露 2 个仪表:
{metric.name}.alive
:如果最后一次心跳记录时间超过超时时间,则为 0,否则为 1;{metric.name}.timeout
:心跳超时(以秒为单位)。为了将此类仪表原生集成到 Micrometer 中,我想遵循其他仪表的初始化方式:
HeartbeatMeter myHeartbeat = HeartbeatMeter.builder("my.pipeline.heartbeat")
.withTimeout(30),
.tags(myTags)
.register(meterRegistry);
myHeartbeat.beat(Instant.now().toEpochMilli());
如果尚不存在具有提供的名称和标签的电表,则注册应创建一个新电表,并将其注册到电表注册表中。否则,它应该从注册表返回现有的仪表。我不知道如何实现这一目标。
到目前为止
register
构建器的方法如下:
public HeartbeatMeter register(MeterRegistry meterRegistry) {
var heartbeatMeter = new HeartbeatMeter(this.timeoutSeconds);
Gauge.builder(String.format("%s.active", this.name), heartbeatMeter.activeSupplier())
.tags(this.tags)
.register(meterRegistry);
Gauge.builder(String.format("%s.timeout", this.name), heartbeatMeter.timeoutSupplier())
.tags(this.tags)
.register(meterRegistry);
return heartbeatMeter;
}
虽然如果仪表尚未注册,它可以很好地工作,但如果仪表已存在于注册表中,它就不会工作。
有没有一种便捷的方法来实现自定义复合仪表并将其集成到千分尺中?
我对一般情况下实现自定义复合仪表感兴趣,以 HeartbeatMeter 为例。
看起来这不是一个自定义的复合仪表,而是一个简单注册两个
Gauge
的组件。你可以为此实现一个 MeterBinder
,如果你创建它的 bean,Spring Boot 会自动为你注册它。
如果尚不存在具有提供的名称和标签的电表,则注册应创建一个新电表,并将其注册到电表注册表中。否则,它应该从注册表返回现有的仪表。我不知道如何实现这一目标。
Gauge
是异步的,所以我不确定为什么你需要一个Gauge
实例,因为你不与它交互,而是与它的支持对象交互。
虽然如果仪表尚未注册,它可以很好地工作,但如果仪表已存在于注册表中,它就不会工作。
我也不明白你如何陷入
Gauge
已经存在的情况。您注册您的 Gauge
一次,无需重新注册它们或以任何方式与它们交互。如果您与他们的支撑对象交互,请参阅文档:https://docs.micrometer.io/micrometer/reference/concepts/gauges.html
如果你真的想检查
Meter
(即:Gauge
)是否已注册,MeterRegistry
有一个 find
和 get
方法来执行此操作,但是(我无法充分强调这一点)你不需要不需要它们来注册您的仪表,您可能做错了什么。