MicroProfile 指标 - 计算抛出异常的数量

MicroProfile metrics - counting the number of thrown exceptions not working

我有一个 java 使用 Quarkus 开发的 REST 服务。

现在我正在尝试使用 MicroProfile Metrics supported by Quarkus Metrics Implementation.

向服务添加一些指标

我的目标是使用a Counter metric来计算应用程序中抛出的异常数。

因此,我添加了所需的注释来标记要注册为 Counted 指标的异常(我已经实现了自定义异常)构造函数。目前,我的代码如下所示。

public class MyException extends RuntimeException {

   @Counted(name = "errorCounterMetric", description = "Meter metric for exception description")
   public MyException(final String errorMsg, final Throwable exception) {
      super(errorMsg, exception);
   }

}

因此,每次调用上述异常构造函数时,相关计数器指标也应增加1。

但是,问题在于 MicroProfile 指标端点始终将上述指标的值显示为 0,无论引发异常的次数如何。

谁能帮我理解这里的问题,或者是否有更好的方法来达到相同的结果?

在 Quarkus 中,@Counted 注解被实现为 CDI(上下文和依赖注入)拦截器。它要求带注释的对象是 managed bean(以便它可以包装在代理对象中以允许拦截方法调用)。

异常通常不是 bean(并且您通常不希望 create/manage 使用 CDI bean 生命周期的异常)。如果我尝试你的例子,CDI 需要更多信息,以便它可以构造拦截的 bean(这显然不是你的意图):

Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type java.lang.String and qualifiers [@Default]
        - java member: ....CountedException#<init>()
        - declared on CLASS bean [types=[java.io.Serializable, java.lang.Exception, java.lang.Throwable, ....CountedException, java.lang.RuntimeException, java.lang.Object], qualifiers=[@Default, @Any], target=....CountedException]

我相信你想做的只是计算这种异常被创建了多少次。为此,您应该跳过尝试使用注释,而直接使用计数器,例如使用千分尺扩展:

public class CountedException extends RuntimeException {
    public CountedException(final String errorMsg, final Throwable exception) {
        super(errorMsg, exception);
        Metrics.counter("errorCounterMetric").increment();
    }
}

使用 MP 指标类似:

public class CountedException extends RuntimeException {
    public CountedException(final String errorMsg, final Throwable exception) {
        super(errorMsg, exception);
        MetricRegistries.get(Type.APPLICATION).counter("errorCounterMetric").inc();
    }
}

相同的结果,但您避免了围绕 bean 的生命周期混淆。

有趣的是,这将允许您记录有关创建这些异常的原因的更多信息。

例如(也使用千分尺命名约定):

public class CountedException extends RuntimeException {
    public CountedException(final String errorMsg, final Throwable exception) {
        super(errorMsg, exception);
        String cause = exception == null ? "null" : exception.getClass().getSimpleName();
        Metrics.counter("error.counter.metric", "cause", cause).increment();
    }
}

或 MP 指标:

public class CountedException extends RuntimeException {
    public CountedException(final String errorMsg, final Throwable exception) {
        super(errorMsg, exception);
        String cause = exception == null ? "null" : exception.getClass().getSimpleName();
        MetricRegistries.get(Type.APPLICATION).counter("errorCounterMetric", new Tag("cause", cause)).inc();
    }
}

这应该仍然有一个很好的有界基数,但是(编造一些东西)你会看到创建这个异常以包装 NullPointerException、IOException、null 或...的频率。 =17=]