Skip to content

Semconv applied for Camel JMX metrics#16088

Merged
trask merged 35 commits intoopen-telemetry:mainfrom
robsunday:jmx-camel
Feb 20, 2026
Merged

Semconv applied for Camel JMX metrics#16088
trask merged 35 commits intoopen-telemetry:mainfrom
robsunday:jmx-camel

Conversation

@robsunday
Copy link
Copy Markdown
Contributor

@robsunday robsunday commented Feb 2, 2026

Includes:

  • Metric and attribute names updated to better reflect semconv
  • Metric mappings reordered to be consistent between beans
  • One line comments with full metric names added
  • New test application added

Breaking changes
Metrics:

  • camel.context.exchange renamed to camel.context.exchange.count

  • camel.context.exchange.failed renamed to camel.context.exchange.failed.count

  • camel.context.exchange.failed_handled renamed to camel.context.exchange.failed.handled

  • camel.context.exchange.processing.delta_time renamed to camel.context.exchange.processing.duration.last_delta. ms unit changed to s

  • camel.context.exchange.processing.last_time renamed to camel.context.exchange.processing.duration.last. ms unit changed to s

  • camel.context.exchange.processing.max_time renamed to camel.context.exchange.processing.duration.max. ms unit changed to s

  • camel.context.exchange.processing.mean_time renamed to camel.context.exchange.processing.duration.mean. ms unit changed to s

  • camel.context.exchange.processing.min_time renamed to camel.context.exchange.processing.duration.min. ms unit changed to s

  • camel.context.exchange.processing.time renamed to camel.context.exchange.processing.duration.sum. ms unit changed to s

  • camel.context.exchange.redelivered renamed to camel.context.exchange.redelivered.count

  • camel.context.exchange.redelivered_external renamed to camel.context.exchange.redelivered.external

  • camel.processor.exchange renamed to camel.processor.exchange.count

  • camel.processor.exchange.failed renamed to camel.processor.exchange.failed.count

  • camel.processor.exchange.failed_handled renamed to camel.processor.exchange.failed.handled

  • camel.processor.exchange.processing.delta_time renamed to camel.processor.exchange.processing.duration.last_delta. ms unit changed to s

  • camel.processor.exchange.processing.last_time renamed to camel.processor.exchange.processing.duration.last. ms unit changed to s

  • camel.processor.exchange.processing.max_time renamed to camel.processor.exchange.processing.duration.max. ms unit changed to s

  • camel.processor.exchange.processing.mean_time renamed to camel.processor.exchange.processing.duration.mean. ms unit changed to s

  • camel.processor.exchange.processing.min_time renamed to camel.processor.exchange.processing.duration.min. ms unit changed to s

  • camel.processor.exchange.processing.time renamed to camel.processor.exchange.processing.duration.sum. ms unit changed to s

  • camel.processor.exchange.redelivered renamed to camel.processor.exchange.redelivered.count

  • camel.processor.exchange.redelivered_external renamed to camel.processor.exchange.redelivered.external

  • camel.route.exchange renamed to camel.route.exchange.count

  • camel.route.exchange.failed renamed to camel.route.exchange.failed.count

  • camel.route.exchange.failed_handled renamed to camel.route.exchange.failed.handled

  • camel.route.exchange.processing.delta_time renamed to camel.route.exchange.processing.duration.last_delta. ms unit changed to s

  • camel.route.exchange.processing.last_time renamed to camel.route.exchange.processing.duration.last. ms unit changed to s

  • camel.route.exchange.processing.max_time renamed to camel.route.exchange.processing.duration.max. ms unit changed to s

  • camel.route.exchange.processing.mean_time renamed to camel.route.exchange.processing.duration.mean. ms unit changed to s

  • camel.route.exchange.processing.min_time renamed to camel.route.exchange.processing.duration.min. ms unit changed to s

  • camel.route.exchange.processing.time renamed to camel.route.exchange.processing.duration.sum. ms unit changed to s

  • camel.route.exchange.redelivered renamed to camel.route.exchange.redelivered.count

  • camel.route.exchange.redelivered_external renamed to camel.route.exchange.redelivered.external

  • camel.threadpool.active renamed to camel.threadpool.task.active

  • camel.threadpool.pool.core_size renamed to camel.threadpool.thread.limit.lower

  • camel.threadpool.pool.largest_size renamed to camel.threadpool.thread.max

  • camel.threadpool.pool.size renamed to camel.threadpool.thread.count

  • camel.threadpool.task renamed to camel.threadpool.task.count

  • camel.threadpool.task.queue_size renamed to camel.threadpool.task.queue.size. {threads} unit changed to {task}

Attributes:

  • camel_class_resolver removed
  • camel_version removed
  • context renamed to camel.context
  • destination renamed to camel.destination
  • pool_id renamed to camel.threadpool.name
  • processor renamed to camel.processor
  • route renamed to camel.route

Non breaking changes
Metrics:

  • camel.threadpool.thread.limit.upper added

Copy link
Copy Markdown
Contributor

@SylvainJuge SylvainJuge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread instrumentation/jmx-metrics/library/camel.md Outdated
Comment thread instrumentation/jmx-metrics/library/camel.md Outdated
Comment thread instrumentation/jmx-metrics/library/camel.md Outdated
Comment thread settings.gradle.kts
Reordering of items in camel.md to follow alphabetical order
Comment thread instrumentation/jmx-metrics/library/src/main/resources/jmx/rules/camel.yaml Outdated
Comment thread instrumentation/jmx-metrics/library/src/main/resources/jmx/rules/camel.yaml Outdated
Comment thread instrumentation/jmx-metrics/library/camel.md Outdated
@robsunday robsunday marked this pull request as ready for review February 18, 2026 13:22
@robsunday robsunday requested a review from a team as a code owner February 18, 2026 13:22
@SylvainJuge
Copy link
Copy Markdown
Contributor

Also, because this is a breaking change, it would be beneficial to document all the renames/changes in the PR description like #14996.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.yaml metric/attribute naming and ordering, adding full metric-name comments and adopting sourceUnit conversions.
  • 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 CamelTest metrics 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: s with sourceUnit: 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.

Comment thread instrumentation/jmx-metrics/library/camel.md Outdated
Comment thread instrumentation/jmx-metrics/testing-apps/camel-testing-app/build.gradle.kts Outdated
robsunday and others added 7 commits February 19, 2026 12:09
…etry/instrumentation/jmx/rules/CamelTest.java

Co-authored-by: Copilot <[email protected]>
…etry/instrumentation/jmx/rules/CamelTest.java

Co-authored-by: Copilot <[email protected]>
# Conflicts:
#	instrumentation/jmx-metrics/library/src/test/java/io/opentelemetry/instrumentation/jmx/rules/assertions/AttributeMatcherGroup.java
@robsunday
Copy link
Copy Markdown
Contributor Author

Testing application was significantly refactored to get rid of SpringBoot dependency. There were compatibility issues between supported SpringBoot, Gradle and Camel SpringBoot support.

Comment on lines 1 to 3
camel.main.jmx-enabled=true
camel.main.jmx-management-statistics-level=Extended
camel.jmx.statistics-level=All
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. If Camel based application use org.apache.camel.main.Main class (this one does) then application.properties is read automatically.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +28 to +34
| 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. |
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. Listing the processor metrics in two separate sections (with and without camel.destination)
  2. Adding a note explaining that camel.destination is optional
  3. Using notation like "(optional)" or bracketing the attribute name to indicate optionality
Suggested change
| 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. |

Copilot uses AI. Check for mistakes.
| 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. |
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. Listing the threadpool metrics in two separate sections (with and without camel.route)
  2. Adding a note explaining that camel.route is optional
  3. Using notation like "(optional)" or bracketing the attribute name to indicate optionality
Suggested change
| 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.

Copilot uses AI. Check for mistakes.
Comment thread instrumentation/jmx-metrics/library/camel.md Outdated
@trask trask merged commit 935ef1f into open-telemetry:main Feb 20, 2026
85 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants