Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Camel Quarkus with MicroProfile Metrics and Prometheus Example #1506

Closed
wants to merge 1 commit into from
Closed

Conversation

astefanutti
Copy link
Member

Requires #1490.

Release Note

Add Camel Quarkus with MicroProfile Metrics and Prometheus Example

@astefanutti
Copy link
Member Author

Custom metrics declared using the MP Metrics annotations are not picked-up. I can speculate the classes are not registered for reflection. @jamesnetherton @lburgazzoli what would be the best approach to fix this?

@jamesnetherton
Copy link
Contributor

Do you have an example integration? IIRC there's no need to register anything for reflection, the Quarkus metrics extension would (or should) handle that if necessary.

@astefanutti
Copy link
Member Author

astefanutti commented Jun 8, 2020

@jamesnetherton the two following metrics from the example included in this PR are not picked-up:

It's possible to run the example with:

$ kamel run --name metrics Metrics.java Service.java -t quarkus.enabled=true

It's likely I miss something obvious 😃!

@jamesnetherton
Copy link
Contributor

I tested outside of camel-k in a standalone Quarkus unit test. It seems to be a problem with injecting the meters into the gauge producer method. I got:

2020-06-08 16:57:01,496 WARN  [io.sma.metrics] (vert.x-worker-thread-0) Unable to export metric org_apache_camel_quarkus_component_microprofile_it_metrics_MicroProfileMetricsRouteBuilder_successratio: java.lang.UnsupportedOperationException: Unable to retrieve name for parameter [io.quarkus.arc.impl.CurrentInjectionPointProvider$AnnotatedParameterImpl@5ffbc45d], activate the -parameters compiler argument or annotate the injected parameter with the @Metric annotation
	at io.smallrye.metrics.interceptors.SeMetricName.getParameterName(SeMetricName.java:99)
	at io.smallrye.metrics.interceptors.SeMetricName.of(SeMetricName.java:81)
	at io.smallrye.metrics.interceptors.SeMetricName.of(SeMetricName.java:47)
	at io.smallrye.metrics.interceptors.MetricNameFactory_ProducerMethod_metricName_75eed827f480e60dbfa390264b4c5c60dc12bde0_ClientProxy.of(MetricNameFactory_ProducerMethod_metricName_75eed827f480e60dbfa390264b4c5c60dc12bde0_ClientProxy.zig:176)
	at io.smallrye.metrics.MetricProducer.getMetadata(MetricProducer.java:125)
	at io.smallrye.metrics.MetricProducer.getMeter(MetricProducer.java:93)
	at io.smallrye.metrics.MetricProducer_ProducerMethod_getMeter_4db669d105a2dfe52eb03f89066ad657a4e6b338_Bean.create(MetricProducer_ProducerMethod_getMeter_4db669d105a2dfe52eb03f89066ad657a4e6b338_Bean.zig:208)
	at io.smallrye.metrics.MetricProducer_ProducerMethod_getMeter_4db669d105a2dfe52eb03f89066ad657a4e6b338_Bean.get(MetricProducer_ProducerMethod_getMeter_4db669d105a2dfe52eb03f89066ad657a4e6b338_Bean.zig:238)
	at io.smallrye.metrics.MetricProducer_ProducerMethod_getMeter_4db669d105a2dfe52eb03f89066ad657a4e6b338_Bean.get(MetricProducer_ProducerMethod_getMeter_4db669d105a2dfe52eb03f89066ad657a4e6b338_Bean.zig:273)
	at io.quarkus.arc.impl.CurrentInjectionPointProvider.get(CurrentInjectionPointProvider.java:53)

I'm not sure whether injecting the Meter metrics into the producer method can work in this scenario, because they are initially created by Camel at runtime. They are probably not available for injection when the app starts.

As a hacky workaround, this worked for me:

@Produces
@ApplicationScoped
@Metric(name = "success-ratio")
Gauge<Double> successRatio(MetricRegistry metricRegistry) {
    Meter success = MicroProfileMetricsHelper.findMetric(metricRegistry, "success", Meter.class);
    Meter generated = MicroProfileMetricsHelper.findMetric(metricRegistry, "generated", Meter.class);
    return () -> success.getOneMinuteRate() / generated.getOneMinuteRate();
}

I can try to dig into it a bit more on the camel-quarkus side to see if I can make things work as you intended.

@astefanutti
Copy link
Member Author

astefanutti commented Jun 8, 2020

You're right, using @Metric may help to avoid the issue with named parameters:

@Produces
@ApplicationScoped
@Metric(name = "success-ratio")
// Register a custom gauge that's the ratio of the 'success' meter on the 'generated' meter
Gauge<Double> successRatio(@Metric(name = "success") Meter success, @Metric(name = "generated") Meter generated) {
    return () -> success.getOneMinuteRate() / generated.getOneMinuteRate();
}

Otherwise, I wonder whether if it'd be possible to compile with -parameters?

Does the second metric show up in your test: https://github.com/apache/camel-k/pull/1506/files#diff-46af9059a84ff792cd6260dde1b5d7d2R30?

@jamesnetherton
Copy link
Contributor

Yes the second metric is showing up for me but it's always reporting as '0'.

@astefanutti
Copy link
Member Author

astefanutti commented Jun 8, 2020

Hum, for some reasons I can't seem to have these two metrics when I deploy the integration with Camel K :( The metrics from the Camel MP Metrics component do show up.

@lburgazzoli
Copy link
Contributor

lburgazzoli commented Jun 8, 2020

camel-k does not do anything cdi related so I think there should be a way to put the metric to the camel registry, maybe with @BindToRegistry, and them having the metrics component do the registration

@astefanutti
Copy link
Member Author

astefanutti commented Jun 8, 2020

My understanding is that metrics are CDI beans, so if they do not show up, it means they are not scanned as such by Quarkus. From a user standpoint, I would find it surprising to have to bind the metrics to the Camel registry. Plus it seems the example kind of work outside Camel K.

@lburgazzoli
Copy link
Contributor

lburgazzoli commented Jun 8, 2020

yep but remember camel k compiles the routes at runtime, if you bring them as external dependency it should work out of the box as they can be detected at build time

@astefanutti
Copy link
Member Author

Right. It's clear why it doesn't work then.

I wonder whether the bean classes could be declared in such way that they are used during the Quarkus build, and packaged as an extra layer of the integration image...

@lburgazzoli
Copy link
Contributor

I think we need to keep a clear separation between integrations and the ‘runtimes’ as an example java routes are not supported when compiling native code thus I think the runtime should not leak too much into any code that should be stored as part of the CR but we can explore some option.

@astefanutti
Copy link
Member Author

OK it makes sense. I'll probably revisit the example then. Let's close this in the meantime.

@astefanutti astefanutti closed this Jun 9, 2020
@astefanutti
Copy link
Member Author

I've tried relying on Jitpack to externalise the custom metrics in a separate JAR : https://github.com/astefanutti/camel-k-example-metrics.

Unfortunately, it seems the MP annotations are not taken into account. I guess these have to be scanned from source at build time, instead of bringing them as dependencies...

@lburgazzoli
Copy link
Contributor

yep, we probably need to automatically add external dependencies to the list quarkus needs to index

@astefanutti
Copy link
Member Author

@astefanutti astefanutti added the area/observability Logging, monitoring and tracing label Jul 16, 2020
@astefanutti astefanutti deleted the pr-113 branch November 22, 2021 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/observability Logging, monitoring and tracing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants