fernandobalieiro opened a new pull request, #23864:
URL: https://github.com/apache/camel/pull/23864
# Description
The goal of this PR is to ensure that the Prometheus Event Notification
happens when a RouteId is configured in the destination Route of a message sent
through a ProducerTemplate.
## Current Scenario
When a project is configured to use `quarkus-micrometer-registry-prometheus`
and a message is sent to a `SEDA` endpoint through `ProducerTemplate`, the
following warning appears in the logs:
```
2026-06-08 14:32:45,577 WARN [org.apache.camel.support.EventHelper] (Camel
(camel-6) thread #21 - seda://producer) Error notifying event
C99DFEF70A95789-0000000000000001 exchange completed took: 3ms. This exception
will be ignored.: java.lang.IllegalArgumentException: Prometheus requires that
all meters with the same name have the same set of tag keys. There is already
an existing meter named 'camel_exchange_event_notifier_seconds' containing tag
keys [camelContext, endpointName, eventType, failed, kind]. The meter you are
attempting to register has keys [camelContext, endpointName, eventType, failed,
kind, routeId].
at
io.micrometer.prometheus.PrometheusMeterRegistry.lambda$throwExceptionOnRegistrationFailure$19(PrometheusMeterRegistry.java:619)
at
io.micrometer.core.instrument.MeterRegistry.meterRegistrationFailed(MeterRegistry.java:1291)
at
io.micrometer.prometheus.PrometheusMeterRegistry.lambda$applyToCollector$18(PrometheusMeterRegistry.java:593)
at
java.base/java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1956)
at
io.micrometer.prometheus.PrometheusMeterRegistry.applyToCollector(PrometheusMeterRegistry.java:579)
at
io.micrometer.prometheus.PrometheusMeterRegistry.newTimer(PrometheusMeterRegistry.java:328)
at
io.micrometer.core.instrument.MeterRegistry.lambda$timer$6(MeterRegistry.java:379)
at
io.micrometer.core.instrument.MeterRegistry.getOrCreateMeter(MeterRegistry.java:725)
at
io.micrometer.core.instrument.MeterRegistry.registerMeterIfNecessary(MeterRegistry.java:652)
at
io.micrometer.core.instrument.MeterRegistry.timer(MeterRegistry.java:377)
at
io.micrometer.core.instrument.Timer$Builder.register(Timer.java:471)
at
io.micrometer.core.instrument.Timer$Builder.register(Timer.java:465)
at
io.micrometer.core.instrument.composite.CompositeTimer.registerNewMeter(CompositeTimer.java:205)
at
io.micrometer.core.instrument.composite.CompositeTimer.registerNewMeter(CompositeTimer.java:35)
at
io.micrometer.core.instrument.composite.AbstractCompositeMeter.add(AbstractCompositeMeter.java:67)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at
java.base/java.util.Collections$SetFromMap.forEach(Collections.java:6060)
at
io.micrometer.core.instrument.composite.CompositeMeterRegistry.lambda$new$0(CompositeMeterRegistry.java:67)
at
io.micrometer.core.instrument.composite.CompositeMeterRegistry.lock(CompositeMeterRegistry.java:189)
at
io.micrometer.core.instrument.composite.CompositeMeterRegistry.lambda$new$1(CompositeMeterRegistry.java:67)
at
io.micrometer.core.instrument.MeterRegistry.getOrCreateMeter(MeterRegistry.java:735)
at
io.micrometer.core.instrument.MeterRegistry.registerMeterIfNecessary(MeterRegistry.java:652)
at
io.micrometer.core.instrument.MeterRegistry.timer(MeterRegistry.java:377)
at
io.micrometer.core.instrument.MeterRegistry.timer(MeterRegistry.java:534)
at
org.apache.camel.component.micrometer.eventnotifier.MicrometerExchangeEventNotifier.handleDoneEvent(MicrometerExchangeEventNotifier.java:204)
at
org.apache.camel.component.micrometer.eventnotifier.MicrometerExchangeEventNotifier.notify(MicrometerExchangeEventNotifier.java:179)
at
org.apache.camel.support.EventHelper.doNotifyEvent(EventHelper.java:1575)
at
org.apache.camel.support.EventHelper.notifyExchangeDone(EventHelper.java:783)
at
org.apache.camel.impl.engine.DefaultUnitOfWork.done(DefaultUnitOfWork.java:280)
at
org.apache.camel.support.UnitOfWorkHelper.doneUow(UnitOfWorkHelper.java:53)
at
org.apache.camel.impl.engine.CamelInternalProcessor$UnitOfWorkProcessorAdvice.after(CamelInternalProcessor.java:1178)
at
org.apache.camel.impl.engine.CamelInternalProcessor$UnitOfWorkProcessorAdvice.after(CamelInternalProcessor.java:1115)
at
org.apache.camel.impl.engine.AdviceIterator.runAfterTask(AdviceIterator.java:45)
at
org.apache.camel.impl.engine.AdviceIterator.runAfterTasks(AdviceIterator.java:39)
at
org.apache.camel.impl.engine.CamelInternalProcessor$AsyncAfterTask.done(CamelInternalProcessor.java:263)
at org.apache.camel.AsyncCallback.run(AsyncCallback.java:44)
at
org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.doRun(DefaultReactiveExecutor.java:202)
at
org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.executeReactiveWork(DefaultReactiveExecutor.java:192)
at
org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.tryExecuteReactiveWork(DefaultReactiveExecutor.java:169)
at
org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:143)
at
org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:59)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:162)
at
org.apache.camel.impl.engine.CamelInternalProcessor.processNonTransacted(CamelInternalProcessor.java:385)
at
org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:361)
at
org.apache.camel.component.seda.SedaConsumer.sendToConsumers(SedaConsumer.java:351)
at
org.apache.camel.component.seda.SedaConsumer.processPolledExchange(SedaConsumer.java:267)
at
org.apache.camel.component.seda.SedaConsumer.doRun(SedaConsumer.java:210)
at
org.apache.camel.component.seda.SedaConsumer.run(SedaConsumer.java:146)
at
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.base/java.lang.Thread.run(Thread.java:1474)
```
The issue seems to be caused by recent changes in the Micrometer framework,
as reported in the Quarkus 3.35 Release Notes:
https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.35#micrometer-prometheus-registry
A reproducer can be found in [this
repository](https://github.com/fernandobalieiro/camel-event-notifier-reproducer).
The message will appear by either running the project in Quarkus dev mode and
invoking http://localhost:8080/hello endpoint or by executing the
`ProducerRouteIT` test.
1. Clone the repository:
```bash
git clone https://github.com/fernandobalieiro/camel-event-notifier-reproducer
```
2. Start the server:
```bash
./mvnw quarkus:dev
```
3. Invoke the endpoint:
```bash
curl http://localhost:8080/hello
```
Or execute the integration tests directly:
```bash
./mvnw verify -DskipITs=false
```
The warning message containing the stack trace should appear in the logs.
## Expected Scenario
The event should be properly registered and no warning message should be
visible in the logs.
## Consideration
I'm aware that this is maybe not the best approach, as the solution requires
iterating over all routes to retrieve the target routeId, so I'm open to
suggestions.
# Target
- [X] I checked that the commit is targeting the correct branch (Camel 4
uses the `main` branch)
# Tracking
- [X] If this is a large change, bug fix, or code improvement, I checked
there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for
the change (usually before you start working on it).
# Apache Camel coding standards and style
- [X] I checked that each commit in the pull request has a meaningful
subject line and body.
- [X] I have run `mvn clean install -DskipTests` locally from root folder
and I have committed all auto-generated changes.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]