Quarkus: SmallRye + LambdaGauge bug

Created on 20 Apr 2020  路  5Comments  路  Source: quarkusio/quarkus

Describe the bug
When trying to register a LambdaGauge metric there is an exception.

Expected behavior
The gauge is registered properly.

Actual behavior
There is an exception. Metrics is not registered.

To Reproduce
Steps to reproduce the behavior:

  1. metricFactory.register("name", new LambdaGauge( () -> 5 ));
  2. Exception: Failed to start application: java.lang.IllegalArgumentException: number> is not a valid MetricType

You can use microprofile-metrics-quickstart and add to PrimeNumberChecker.java:

    @Inject
    MetricRegistry metricRegistry;

    @PostConstruct
    public void init() {
// this produces the exception
        metricRegistry.register("test", new LambdaGauge(() -> 5));
    }

Environment (please complete the following information):

  • Quarkus version or git rev: 1.3.2.Final

Additional context
There is obviously a bug at MetricRegistryImpl:86-90

        if (metricCls.getName().contains("Lambda")) {
            String tname = metricCls.getGenericInterfaces()[0].getTypeName(); // TODO [0] is brittle
            tname = tname.substring(tname.lastIndexOf('.') + 1);
            tname = tname.toLowerCase();
            type = MetricType.from(tname);
kinbug

Most helpful comment

Fixed for SmallRye Metrics 3.0 and 2.4.2. Unless someone really wants it in quick, I'd wait with releasing 2.4.2 until there's a bit more to include.

The MetricRegistry was confused because the gauge's impl class contains the word Lambda, so it was mistakenly considered to be a lambda expression. I improved the logic and this should not happen anymore.

All 5 comments

/cc @patriot1burke

cc @jmartisk

A workaround I found is to use the Metadata Metadata.builder().withName("name").withType(MetricType.GAUGE).build() instead of name makes it work.
Another possible bug (this is how I found out the workaround): If not using metadata to specify MetricType.GAUGE the metric type will be "unknown" and not rendered (even though it extends Gauge interface). So this might be more than I initially assumed - some +1 error in substring.

While I agree this is a bug and I will see what can be done to fix inferring the metric type, LambdaGauge is in the .runtime package so it's not intended as a public API, so I'd very much recommend against using it in an application.
If you need to register a gauge based on a lambda expression, I'd suggest simply casting a lambda expression to a Gauge:

registry.register("test", (Gauge<Long>)() -> 42L);

Fixed for SmallRye Metrics 3.0 and 2.4.2. Unless someone really wants it in quick, I'd wait with releasing 2.4.2 until there's a bit more to include.

The MetricRegistry was confused because the gauge's impl class contains the word Lambda, so it was mistakenly considered to be a lambda expression. I improved the logic and this should not happen anymore.

Was this page helpful?
0 / 5 - 0 ratings