Croway opened a new pull request, #29139: URL: https://github.com/apache/camel/pull/29139
_Claude Code on behalf of Croway_ [CAMEL-26565](https://issues.apache.org/jira/browse/CAMEL-26565), follow-up of #28729 (CAMEL-26415). ## Problem #28729 stopped searching the meter registry for the last-exchange gauge, but since 4.21 `MicrometerExchangeEventNotifier` still searches it on every sent and completed event. `getOrCreateTimer()`, added by #23864 (CAMEL-23719), calls `find(name).tags(tags).timer()`, which copies and filters every registered meter. The notifier's cost per exchange therefore grows with the number of meters in the application. `notify()` also calls `CamelContext.getRoute(routeId)` on every event to check whether the route was created by a kamelet or a route template. That call copies the route list under `routesLock`, which limits throughput when several threads process exchanges. ## Changes - `getOrCreateTimer()` uses `Timer.builder(...).register(registry)` again, as before #23864. `register()` returns the existing timer through the registry's map lookup by id. - Since #23864 the `routeId` tag is always present (empty when unknown), so a timer name always has the same tag keys and `register()` cannot trip Prometheus's tag-key check. - `MicrometerExchangeEventNotifierProducerTemplateTest`, added by #23864 with a Prometheus registry, still passes. - `addInflightMeter()` already decides once per route whether a kamelet or template route is skipped. That decision is now kept in a set, so the exchange events no longer look the route up. The set is updated when routes are removed and cleared on stop. ## Measurements These were in my comment on #28729. JMH, Camel 4.22.1 + Micrometer 1.17.2, JDK 21. Routes are `from(direct)` + 3 × `to(log)`. Each cell shows **4.22.1 / + #28729 / + this change**: | routes (meters) | µs per exchange, 1 thread | exchanges/s, 4 threads | |---|---|---| | 1 (23) | 6.6 / 6.4 / **3.9** | – | | 10 (131) | 20.6 / 19.3 / **4.3** | 160k / 170k / **551k** | | 50 (611) | 90.4 / 89.6 / **4.3** | 40k / 37k / **666k** | | 200 (2,411) | 386 / 359 / **4.9** | 10k / 10k / **599k** | I also measured a Camel Spring Boot application: JPA stream → split → split, 1M records, all `camel.metrics` defaults, Prometheus registry. Units are µs per record: | meters | 4.10.7 | 4.22.1 | 4.22.1 + #28729 | 4.22.1 + #28729 + this change | |---:|---:|---:|---:|---:| | 1,127 | 3.45 | 29.77 | 13.46 | **2.83** | | 3,127 | 4.12 | 74.17 | 23.34 | **2.74** | The timers, counts and gauge recorded are the same as before. ## Testing - `MicrometerExchangeEventNotifierHotPathTest`: - counts the registry searches made by exchange events. It fails without this change: 200 searches for 50 exchanges. - checks that a kamelet route stays unmetered, including one added at runtime, and that a regular route reusing a removed route's id is metered. - camel-micrometer: 117 tests pass with `-Psourcecheck`. ## Backports - `camel-4.22.x`: a straight cherry-pick. - `camel-4.18.x`: only the `getRoute()` part, because 4.18.x has neither #23864 nor the timer search. -- 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]
