Semconv applied for Camel JMX metrics#16088
Conversation
SylvainJuge
left a comment
There was a problem hiding this comment.
Ideally it would be great to have an end-to-end integration test as we are completely blind if those metrics actually map to anything right now.
Camel test application added.
… expose this attribute
…etric. Reverting unnecessary changes in matchers.
Reordering of items in camel.md to follow alphabetical order
Added mapping of MaximumPoolSize property
|
Also, because this is a breaking change, it would be beneficial to document all the renames/changes in the PR description like #14996. |
There was a problem hiding this comment.
Pull request overview
Updates Camel JMX metrics to better align with semantic conventions, and adds a dedicated Camel Spring Boot test application plus an end-to-end validation test to ensure the YAML rules produce the expected metrics.
Changes:
- Reworked
camel.yamlmetric/attribute naming and ordering, adding full metric-name comments and adoptingsourceUnitconversions. - Added a new Spring Boot + Camel “testing app” JAR and wired it into the JMX metrics library test execution.
- Introduced more flexible attribute matching in tests (applicability predicate) and added a comprehensive
CamelTestmetrics assertion suite.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| settings.gradle.kts | Includes the new Camel testing-app Gradle module. |
| instrumentation/jmx-metrics/testing-apps/camel-testing-app/build.gradle.kts | Defines the Spring Boot + Camel test application build (bootJar). |
| instrumentation/jmx-metrics/testing-apps/camel-testing-app/src/main/resources/application.properties | Enables Camel JMX/statistics needed for metric emission. |
| instrumentation/jmx-metrics/testing-apps/camel-testing-app/src/main/java/io/opentelemetry/instrumentation/jmx/cameltest/CamelTestApplication.java | Spring Boot entrypoint for the Camel test app. |
| instrumentation/jmx-metrics/testing-apps/camel-testing-app/src/main/java/io/opentelemetry/instrumentation/jmx/cameltest/CamelTestRouter.java | Generates periodic Camel activity to drive JMX metrics. |
| instrumentation/jmx-metrics/testing-apps/camel-testing-app/src/main/java/io/opentelemetry/instrumentation/jmx/cameltest/BirdSpeciesRestController.java | Simple backend endpoint to exercise Camel routes/processors. |
| instrumentation/jmx-metrics/library/build.gradle.kts | Adds the Camel test app artifact to the library test inputs/system properties. |
| instrumentation/jmx-metrics/library/src/test/java/io/opentelemetry/instrumentation/jmx/rules/TargetSystemTest.java | Refactors artifact copying and exposes helpers for new target-system tests. |
| instrumentation/jmx-metrics/library/src/test/java/io/opentelemetry/instrumentation/jmx/rules/assertions/AttributeMatcherGroup.java | Adds applicability predicate support for optional/conditional attribute groups. |
| instrumentation/jmx-metrics/library/src/test/java/io/opentelemetry/instrumentation/jmx/rules/CamelTest.java | New end-to-end container test validating Camel metrics emitted from camel.yaml. |
| instrumentation/jmx-metrics/library/src/main/resources/jmx/rules/camel.yaml | Renames/remaps Camel metrics/attributes toward semconv-style naming and units. |
| instrumentation/jmx-metrics/library/camel.md | Adds/updates Camel metrics documentation under the library module. |
| instrumentation/jmx-metrics/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jmx/JmxMetricInsightInstallerTest.java | Adjusts rule-validation coverage to match javaagent module rule set. |
| instrumentation/jmx-metrics/javaagent/camel.md | Removes outdated javaagent Camel metrics doc (moved to library). |
| instrumentation/jmx-metrics/README.md | Updates the Camel doc link to point at the library documentation. |
Comments suppressed due to low confidence (3)
instrumentation/jmx-metrics/library/src/main/resources/jmx/rules/camel.yaml:28
- Grammar: "processed context start-up" is missing "since" (should be "processed since context start-up...").
instrumentation/jmx-metrics/library/src/main/resources/jmx/rules/camel.yaml:199 - The description text "of all exchanges the selected processed" is ungrammatical/unclear (looks like a missing subject such as "route" or "processor"). Please reword so it clearly states which component processed the exchanges.
instrumentation/jmx-metrics/library/src/main/resources/jmx/rules/camel.yaml:71 - These metrics declare
unit: swithsourceUnit: ms, but the description still says "in milliseconds". This will mislead users about the actual exported unit (seconds). Update the descriptions (or units) consistently for the duration metrics in this file.
…etry/instrumentation/jmx/rules/CamelTest.java Co-authored-by: Copilot <[email protected]>
…etry/instrumentation/jmx/rules/CamelTest.java Co-authored-by: Copilot <[email protected]>
…ld.gradle.kts Co-authored-by: Copilot <[email protected]>
# Conflicts: # instrumentation/jmx-metrics/library/src/test/java/io/opentelemetry/instrumentation/jmx/rules/assertions/AttributeMatcherGroup.java
|
Testing application was significantly refactored to get rid of SpringBoot dependency. There were compatibility issues between supported SpringBoot, Gradle and Camel SpringBoot support. |
| camel.main.jmx-enabled=true | ||
| camel.main.jmx-management-statistics-level=Extended | ||
| camel.jmx.statistics-level=All |
There was a problem hiding this comment.
are those properties still relevant now that spring boot has been removed ? Does the Camel implementation actually read them from the classpath root like spring does ?
There was a problem hiding this comment.
Yes. If Camel based application use org.apache.camel.main.Main class (this one does) then application.properties is read automatically.
There was a problem hiding this comment.
But to be honest - if the file is missing then CamelTest is passing anyway.
If you set camel.main.jmx-enabled=false in this file, then CamelTest fails.
I'd leave this file anyway to make sure the test passes even if in some version defaults change.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (2)
instrumentation/jmx-metrics/library/src/main/resources/jmx/rules/camel.yaml:328
- There is an extra space at the beginning of the description. The line should start with "The number" without the leading space.
instrumentation/jmx-metrics/library/src/main/resources/jmx/rules/camel.yaml:296 - The comment indentation is inconsistent with other section headers. It should have two spaces before the # character to match the pattern used in lines 4, 108, and 201.
| | camel.processor.exchange.processing.duration.last_delta | Gauge | s | camel.context, camel.route, camel.processor, camel.destination | Indicates the difference of the Processing Time of the last two exchanges transited the selected processor. | | ||
| | camel.processor.exchange.processing.duration.max | Gauge | s | camel.context, camel.route, camel.processor, camel.destination | Indicates the longest time to process an exchange since processor start-up or the last reset operation. | | ||
| | camel.processor.exchange.processing.duration.mean | Gauge | s | camel.context, camel.route, camel.processor, camel.destination | Indicates the mean processing time for all exchanges processed since processor start-up or the last reset operation. | | ||
| | camel.processor.exchange.processing.duration.min | Gauge | s | camel.context, camel.route, camel.processor, camel.destination | Indicates the shortest time to process an exchange since processor start-up or the last reset operation. | | ||
| | camel.processor.exchange.processing.duration.sum | Counter | s | camel.context, camel.route, camel.processor, camel.destination | Indicates the total processing time to process all exchanges since start-up or the last reset operation. | | ||
| | camel.processor.exchange.redelivered.count | Counter | {exchange} | camel.context, camel.route, camel.processor, camel.destination | Number of exchanges redelivered (internal only) since selected processor start-up or the last reset operation. | | ||
| | camel.processor.exchange.redelivered.external | Counter | {exchange} | camel.context, camel.route, camel.processor, camel.destination | The total number of all external initiated redeliveries (such as from JMS broker) since processor start-up or the last reset operation. | |
There was a problem hiding this comment.
The documentation lists camel.destination as an attribute for all processor metrics, but according to the test code (lines 64-66 in CamelTest.java), this attribute is only present for destination-aware processors (e.g., to, toD, wireTap) and requires Camel 4.16.0+. Consider clarifying this in the documentation by either:
- Listing the processor metrics in two separate sections (with and without camel.destination)
- Adding a note explaining that camel.destination is optional
- Using notation like "(optional)" or bracketing the attribute name to indicate optionality
| | camel.processor.exchange.processing.duration.last_delta | Gauge | s | camel.context, camel.route, camel.processor, camel.destination | Indicates the difference of the Processing Time of the last two exchanges transited the selected processor. | | |
| | camel.processor.exchange.processing.duration.max | Gauge | s | camel.context, camel.route, camel.processor, camel.destination | Indicates the longest time to process an exchange since processor start-up or the last reset operation. | | |
| | camel.processor.exchange.processing.duration.mean | Gauge | s | camel.context, camel.route, camel.processor, camel.destination | Indicates the mean processing time for all exchanges processed since processor start-up or the last reset operation. | | |
| | camel.processor.exchange.processing.duration.min | Gauge | s | camel.context, camel.route, camel.processor, camel.destination | Indicates the shortest time to process an exchange since processor start-up or the last reset operation. | | |
| | camel.processor.exchange.processing.duration.sum | Counter | s | camel.context, camel.route, camel.processor, camel.destination | Indicates the total processing time to process all exchanges since start-up or the last reset operation. | | |
| | camel.processor.exchange.redelivered.count | Counter | {exchange} | camel.context, camel.route, camel.processor, camel.destination | Number of exchanges redelivered (internal only) since selected processor start-up or the last reset operation. | | |
| | camel.processor.exchange.redelivered.external | Counter | {exchange} | camel.context, camel.route, camel.processor, camel.destination | The total number of all external initiated redeliveries (such as from JMS broker) since processor start-up or the last reset operation. | | |
| | camel.processor.exchange.processing.duration.last_delta | Gauge | s | camel.context, camel.route, camel.processor[, camel.destination] | Indicates the difference of the Processing Time of the last two exchanges transited the selected processor. | | |
| | camel.processor.exchange.processing.duration.max | Gauge | s | camel.context, camel.route, camel.processor[, camel.destination] | Indicates the longest time to process an exchange since processor start-up or the last reset operation. | | |
| | camel.processor.exchange.processing.duration.mean | Gauge | s | camel.context, camel.route, camel.processor[, camel.destination] | Indicates the mean processing time for all exchanges processed since processor start-up or the last reset operation. | | |
| | camel.processor.exchange.processing.duration.min | Gauge | s | camel.context, camel.route, camel.processor[, camel.destination] | Indicates the shortest time to process an exchange since processor start-up or the last reset operation. | | |
| | camel.processor.exchange.processing.duration.sum | Counter | s | camel.context, camel.route, camel.processor[, camel.destination] | Indicates the total processing time to process all exchanges since start-up or the last reset operation. | | |
| | camel.processor.exchange.redelivered.count | Counter | {exchange} | camel.context, camel.route, camel.processor[, camel.destination] | Number of exchanges redelivered (internal only) since selected processor start-up or the last reset operation. | | |
| | camel.processor.exchange.redelivered.external | Counter | {exchange} | camel.context, camel.route, camel.processor[, camel.destination] | The total number of all external initiated redeliveries (such as from JMS broker) since processor start-up or the last reset operation. | |
| | camel.threadpool.thread.count | UpDownCounter | {thread} | camel.context, camel.route, camel.threadpool.name | The current number of threads in the pool. | | ||
| | camel.threadpool.thread.limit.lower | UpDownCounter | {thread} | camel.context, camel.route, camel.threadpool.name | The number of threads that are always kept in the pool, even if they are idle. | | ||
| | camel.threadpool.thread.limit.upper | UpDownCounter | {thread} | camel.context, camel.route, camel.threadpool.name | The maximum possible number of threads in the pool. | | ||
| | camel.threadpool.thread.max | Gauge | {thread} | camel.context, camel.route, camel.threadpool.name | The largest number of threads that have ever simultaneously been in the pool. | |
There was a problem hiding this comment.
The documentation lists camel.route as an attribute for all threadpool metrics, but according to the test code (lines 84-89 in CamelTest.java), this attribute is only present for route-related thread pools. Consider clarifying this in the documentation by either:
- Listing the threadpool metrics in two separate sections (with and without camel.route)
- Adding a note explaining that camel.route is optional
- Using notation like "(optional)" or bracketing the attribute name to indicate optionality
| | camel.threadpool.thread.max | Gauge | {thread} | camel.context, camel.route, camel.threadpool.name | The largest number of threads that have ever simultaneously been in the pool. | | |
| | camel.threadpool.thread.max | Gauge | {thread} | camel.context, camel.route, camel.threadpool.name | The largest number of threads that have ever simultaneously been in the pool. | | |
| Note: The `camel.route` attribute is only present for metrics from route-related thread pools. For thread pools that are not associated with a specific route, only `camel.context` and `camel.threadpool.name` will be recorded. |
Co-authored-by: Copilot <[email protected]>
…nstrumentation into jmx-camel
Includes:
Breaking changes
Metrics:
camel.context.exchangerenamed tocamel.context.exchange.countcamel.context.exchange.failedrenamed tocamel.context.exchange.failed.countcamel.context.exchange.failed_handledrenamed tocamel.context.exchange.failed.handledcamel.context.exchange.processing.delta_timerenamed tocamel.context.exchange.processing.duration.last_delta.msunit changed toscamel.context.exchange.processing.last_timerenamed tocamel.context.exchange.processing.duration.last.msunit changed toscamel.context.exchange.processing.max_timerenamed tocamel.context.exchange.processing.duration.max.msunit changed toscamel.context.exchange.processing.mean_timerenamed tocamel.context.exchange.processing.duration.mean.msunit changed toscamel.context.exchange.processing.min_timerenamed tocamel.context.exchange.processing.duration.min.msunit changed toscamel.context.exchange.processing.timerenamed tocamel.context.exchange.processing.duration.sum.msunit changed toscamel.context.exchange.redeliveredrenamed tocamel.context.exchange.redelivered.countcamel.context.exchange.redelivered_externalrenamed tocamel.context.exchange.redelivered.externalcamel.processor.exchangerenamed tocamel.processor.exchange.countcamel.processor.exchange.failedrenamed tocamel.processor.exchange.failed.countcamel.processor.exchange.failed_handledrenamed tocamel.processor.exchange.failed.handledcamel.processor.exchange.processing.delta_timerenamed tocamel.processor.exchange.processing.duration.last_delta.msunit changed toscamel.processor.exchange.processing.last_timerenamed tocamel.processor.exchange.processing.duration.last.msunit changed toscamel.processor.exchange.processing.max_timerenamed tocamel.processor.exchange.processing.duration.max.msunit changed toscamel.processor.exchange.processing.mean_timerenamed tocamel.processor.exchange.processing.duration.mean.msunit changed toscamel.processor.exchange.processing.min_timerenamed tocamel.processor.exchange.processing.duration.min.msunit changed toscamel.processor.exchange.processing.timerenamed tocamel.processor.exchange.processing.duration.sum.msunit changed toscamel.processor.exchange.redeliveredrenamed tocamel.processor.exchange.redelivered.countcamel.processor.exchange.redelivered_externalrenamed tocamel.processor.exchange.redelivered.externalcamel.route.exchangerenamed tocamel.route.exchange.countcamel.route.exchange.failedrenamed tocamel.route.exchange.failed.countcamel.route.exchange.failed_handledrenamed tocamel.route.exchange.failed.handledcamel.route.exchange.processing.delta_timerenamed tocamel.route.exchange.processing.duration.last_delta.msunit changed toscamel.route.exchange.processing.last_timerenamed tocamel.route.exchange.processing.duration.last.msunit changed toscamel.route.exchange.processing.max_timerenamed tocamel.route.exchange.processing.duration.max.msunit changed toscamel.route.exchange.processing.mean_timerenamed tocamel.route.exchange.processing.duration.mean.msunit changed toscamel.route.exchange.processing.min_timerenamed tocamel.route.exchange.processing.duration.min.msunit changed toscamel.route.exchange.processing.timerenamed tocamel.route.exchange.processing.duration.sum.msunit changed toscamel.route.exchange.redeliveredrenamed tocamel.route.exchange.redelivered.countcamel.route.exchange.redelivered_externalrenamed tocamel.route.exchange.redelivered.externalcamel.threadpool.activerenamed tocamel.threadpool.task.activecamel.threadpool.pool.core_sizerenamed tocamel.threadpool.thread.limit.lowercamel.threadpool.pool.largest_sizerenamed tocamel.threadpool.thread.maxcamel.threadpool.pool.sizerenamed tocamel.threadpool.thread.countcamel.threadpool.taskrenamed tocamel.threadpool.task.countcamel.threadpool.task.queue_sizerenamed tocamel.threadpool.task.queue.size.{threads}unit changed to{task}Attributes:
camel_class_resolverremovedcamel_versionremovedcontextrenamed tocamel.contextdestinationrenamed tocamel.destinationpool_idrenamed tocamel.threadpool.nameprocessorrenamed tocamel.processorrouterenamed tocamel.routeNon breaking changes
Metrics:
camel.threadpool.thread.limit.upperadded