【问题标题】:Quarkus Metrics - intercept metrics endpointQuarkus Metrics - 拦截指标端点
【发布时间】:2021-03-30 22:33:30
【问题描述】:

在使用https://quarkus.io/guides/micrometer 时,有没有办法监听 /metrics 端点?

我想收集一些需要调用不同 API 的指标...而不是设置时间表 (https://quarkus.io/guides/scheduler-reference)...

例子:

  • 我在 Kubernetes API 中查询一些自定义资源
  • 然后我想用不同的标签更新一些仪表

首先/metrics 给我们:

# HELP test_metric_a  
# TYPE test_metric_a gauge
test_metric_a{namespace="test123",user="admin",} 1.0
test_metric_a{namespace="testabc",user="admin",} 1.0

# HELP test_metric_b  
# TYPE test_metric_b gauge
test_metric_b 0.0

第二个/metrics可能会给:

# HELP test_metric_a  
# TYPE test_metric_a gauge
test_metric_a 0.0

# HELP test_metric_b  
# TYPE test_metric_b gauge
test_metric_b{namespace="testabc",user="admin",} 2.0

我如何使用 https://quarkus.io/guides/micrometer 调用 Kubernetes API,因为应用程序内可能没有任何更改导致仪表/注册表更新,但外部事件或时间流逝会导致状态(所需的指标输出)改变...

请注意,自定义指标(见下面的 cmets)只被调用一次(我猜它是一个单例?)。理想情况下,我希望每次/metrics 被回答时都被调用...

进一步编辑以显示仪表是如何创建/更新的:

@ApplicationScoped
public class MyMetrics {

    private final MeterRegistry registry;

    MyMetrics(MeterRegistry registry) {
        this.registry = registry;
    }

    //...

    // somehow call this whenever /metrics is hit?
    protected void updateGauges() {
        // use KubernetesClient to query K8s API to gather some customer resources, then process that list... etc...
        // there is a loop over the below for user/namespace pairs in the tags
        //final Tags tags = getTags();
        //int count = getCount();
        //registry.gauge("test_metric_a", tags, count);

        // so this could roll out to something like:
        registry.gauge("test_metric_a", Tags.of("user", "user1", "namespace", "ns1"), 1);
        registry.gauge("test_metric_a", Tags.of("user", "user2", "namespace", "ns1"), 2);
        registry.gauge("test_metric_a", Tags.of("user", "user1", "namespace", "ns2"), 1);

        registry.gauge("test_metric_b", Tags.of("user", "user1", "namespace", "ns1"), 1);
        registry.gauge("test_metric_b", Tags.of("user", "user2", "namespace", "ns1"), 1);
    }
}

...也许这些gauges 可能是counters...但问题仍然存在...

【问题讨论】:

  • 你能澄清你的问题吗?我们可以定义custom metric,并且在这个指标内,我们应该可以从外部服务等获取数据。
  • @Turing85 这是我需要的推动力,谢谢。我一直在以错误的、颠倒的方式思考这个问题……我会改变我的方法,它是事件驱动的,而不是指标驱动的……
  • 尝试了自定义指标...没有达到我想要的效果...我将用一个示例更新问题。
  • 你能更新一下你如何声明你的仪表吗?请注意,仪表不会记录中间值或调用自身:在收集指标之前它们不会记录值。

标签: quarkus micrometer


【解决方案1】:

好的。正如我在评论中所说,当收集指标时(例如,在 Prometheus 的情况下,当端点被抓取时)会观察到仪表的值。

如果您正在谈论添加包含命名空间之类的标签,常见标签示例可能适合您,您可以在其中预先计算标签:

registry.config().commonTags("stack", "prod", "region", "us-east-1");

这会将这些标签添加到 所有 指标,但您可以使用 MeterFilter 更具选择性(例如,仅将标签添加到符合某些条件的指标)。

new MeterFilter() {
    @Override
    public Meter.Id map(Meter.Id id) {
       if(id.getName().startsWith("test")) {
          return id.withName("extra." + id.getName()).withTag("extra.tag", "value");
       }
       return id;
    }
}

https://micrometer.io/docs/concepts#_common_tags

如果您尝试根据从 Kubernetes API 检索到的数据更新标签/标签值,您可能需要运行一个定期任务(例如计划任务),该任务将使用新标签重新注册仪表。

请注意,对于已被垃圾收集的仪表,千分尺将忽略或返回 NaN(取决于您使用的注册表),因此如果您希望使用以前的标签值注册的仪表保持不变,您需要使它们变得强大参考文献。

【讨论】:

  • 谢谢。我认为答案是某种预定任务(我希望避免的事情)。
猜你喜欢
  • 2023-01-03
  • 2020-11-11
  • 1970-01-01
  • 2020-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多