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]

Reply via email to