Skip to content

Add camel-quarkus-micrometer-observability extension with native support#8879

Open
JinyuChen97 wants to merge 1 commit into
apache:mainfrom
JinyuChen97:support-camel-micrometer-observability
Open

Add camel-quarkus-micrometer-observability extension with native support#8879
JinyuChen97 wants to merge 1 commit into
apache:mainfrom
JinyuChen97:support-camel-micrometer-observability

Conversation

@JinyuChen97

@JinyuChen97 JinyuChen97 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Adds a new Quarkus extension for camel-micrometer-observability, bridging Camel's telemetry SPI to Micrometer Tracing via the OTel bridge.

Extension (runtime):

  • MicrometerObservabilityTracerProducer: CDI @DefaultBean producer that bridges from the Quarkus-provided OpenTelemetry bean to Micrometer Tracing by constructing OtelTracer, OtelPropagator and ObservationRegistry.
  • CamelMicrometerObservabilityConfig: five Quarkus config properties under quarkus.camel.micrometer-observability.
  • Runtime dependencies: quarkus-opentelemetry, micrometer-tracing-bridge-otel.

Extension (deployment):

  • MicrometerObservabilityProcessor: three BuildSteps —
    • FeatureBuildItem to register the feature name
    • AdditionalBeanBuildItem to keep MicrometerObservabilityTracerProducer unremovable
    • UnremovableBeanBuildItem to keep the Camel Tracer bean alive

Integration tests (JVM + Native, 4 tests):

  • testSpansAreGenerated: verifies the full pipeline Camel → MicrometerObservabilityTracer → OtelTracer bridge → OTel SDK → InMemorySpanExporter.
  • testExcludePatternsAreApplied: verifies exclude-patterns suppresses spans for matching endpoints.
  • testConfigPropertiesAreWired: verifies all five config properties are correctly propagated to the live MicrometerObservabilityTracer via CamelMicrometerObservabilityConfig.
  • testUpstreamW3CTracePropagation: verifies W3C traceparent propagation using the real OTel propagator.

Test infrastructure uses InMemorySpanExporter (opentelemetry-sdk-testing) for validating the full OTel pipeline.

Fixes #8885

Co-authored-by: Bob bob@ibm.com

@JinyuChen97
JinyuChen97 force-pushed the support-camel-micrometer-observability branch from 1abed60 to 1ce580c Compare July 14, 2026 13:07

This extension is fully supported in native mode.

The extension registers `io.micrometer.tracing.test.simple.SimpleTraceContext` for runtime

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.

nitpick: I think that it is not necessary to list all configuration here. Having the extension placed in extensions and not extensions-jvm makes clear that native is suppoorted. Also when anybody adds something to configuration, the doc will be out-of-date

Comment thread catalog/pom.xml
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-micrometer-observability</artifactId>

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.

idea: Because there are 2 micrometer-observabilty components in Camel (https://camel.apache.org/components/4.18.x/others/micrometer-observability.html and https://camel.apache.org/components/4.18.x/others/micrometer-observability.html), should we use the number '2' in the name of CQ extension to reflect which one of the components we are extending?

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.

there is only one micrometer-observability component in camel upstream, I think i need to follow the same and no need to add '2'?

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.

If I read correctly, there are:

So I guess we should use camel-quarkus-micrometer-observability as the name of the artifact id but maybe mention the number 2 in the doc page

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.

@@ -0,0 +1,9 @@
This extension is fully supported in native mode.

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.

Same as before, we probably don't need to document this.


For Brave/Zipkin, add `micrometer-tracing-bridge-brave` instead and configure the reporter of your choice.

=== Filtering endpoints

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.

Probably don't needed to be mentioned, as it is part of the camel doc. (this comment can be applied on more parts of this page)

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.

I have reword the usage.adoc, please check.


@BuildStep
RuntimeInitializedClassBuildItem runtimeInitializedClasses() {
return new RuntimeInitializedClassBuildItem("io.micrometer.tracing.test.simple.SimpleTraceContext");

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.

This class is from micrometer-tracing-test, there it is not needed to register it, if the test dependency is not present. Something like

      if
  (index.getIndex().getClassByName("io.micrometer.tracing.test.simple.SimpleTraceContext") !=
  null) {
          runtimeInit.produce(new RuntimeInitializedClassBuildItem(
              "io.micrometer.tracing.test.simple.SimpleTraceContext"));
      }

would be better (or different way of condition..

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.

oh yeah, there is no need to register it only for test purpose, I have move this to application.properties in integration test for test only.

@JinyuChen97
JinyuChen97 force-pushed the support-camel-micrometer-observability branch from 1ce580c to 20ffcc8 Compare July 15, 2026 11:02
@JinyuChen97
JinyuChen97 requested a review from JiriOndrusek July 16, 2026 12:15

@apupier apupier left a comment

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.

Would be worthy to wait for someone else approval as I'm not very comfortable on Observability topic


# Configuration properties wired by MicrometerObservabilityTracerProducer — verified by testConfigPropertiesAreWired
quarkus.camel.micrometer-observability.exclude-patterns = direct:excluded
quarkus.camel.micrometer-observability.include-patterns = direct:traced,direct:excluded

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.

Why direct:excluded is also part of the include-patterns? is it to test that the exclude patterns has an higher priority?

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.

sorry for causing misunderstanding, this is only for testing if quarkus.camel.micrometer-observability.include-patterns can be captured by registered CDI bean CamelMicrometerObservabilityConfig to MicrometerObservabilityTracerProducer. I will remove this, not necessary to be here.

@JinyuChen97
JinyuChen97 force-pushed the support-camel-micrometer-observability branch from 20ffcc8 to f9443fb Compare July 16, 2026 14:19

@jamesnetherton jamesnetherton left a comment

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.

The main concern I have is with how the MicrometerObservabilityTracerProducer wires up the Micrometer Tracer and Propagator. The current implementation optionally injects them as CDI beans:

@Inject
Instance<Tracer> tracerInstance;

@Inject
Instance<Propagator> propagatorInstance;

The problem is that no Quarkus extension currently produces Micrometer Tracer or Propagator CDI beans. So in practice, tracerInstance.isResolvable() will always be false, and the producer falls through to letting Camel's initTracer() handle it — which defaults to Tracer.NOOP and Propagator.NOOP with warning logs. The extension would appear to work but silently produce no traces.

I actually experimented with this extension some time back. The approach I took is to explicitly bridge from the Quarkus-provided OpenTelemetry bean to Micrometer using quarkus-micrometer-opentelemetry (note this currently has preview status) & micrometer-tracing-bridge-otel:

@Inject
OpenTelemetry openTelemetry;

// In the producer method:
Tracer otelTracer = openTelemetry.getTracer("camel");
OtelCurrentTraceContext currentTraceContext = new OtelCurrentTraceContext();
OtelTracer micrometerTracer = new OtelTracer(otelTracer, currentTraceContext, event -> {},
          new OtelBaggageManager(currentTraceContext, List.of(), List.of()));
OtelPropagator micrometerPropagator = new OtelPropagator(openTelemetry.getPropagators(), otelTracer);

tracer.setTracer(micrometerTracer);
tracer.setPropagator(micrometerPropagator);

This ensures Camel's Micrometer spans are correctly bridged into the same OTel trace context that Quarkus and Vert.x use, so parent-child span relationships work across the full stack.

That way you don't burden the user with having to produce a bunch of CDI beans (which I think is what MicrometerObservabilityConfiguration is doing in the tests).

A couple of other things worth considering:

  • SDK disable check: The opentelemetry2 extension checks oTelRuntimeConfig.sdkDisabled() and returns null when tracing is disabled. This extension should probably do the same for consistency.
  • Test fidelity: Using opentelemetry-sdk-testing's InMemorySpanExporter instead of micrometer-tracing-test's SimpleTracer would validate the full pipeline (Camel → Micrometer bridge → OTel SDK → exporter), proving that spans actually reach OTel rather than only exercising the Micrometer layer.

Adds a new Quarkus extension for camel-micrometer-observability, bridging
Camel's telemetry SPI to Micrometer Tracing via the OTel bridge.

Extension (runtime):
- MicrometerObservabilityTracerProducer: CDI @DefaultBean producer that bridges
  from the Quarkus-provided OpenTelemetry bean to Micrometer Tracing by
  constructing OtelTracer, OtelPropagator and ObservationRegistry.
- CamelMicrometerObservabilityConfig: five Quarkus config properties under
  quarkus.camel.micrometer-observability.
- Runtime dependencies: quarkus-opentelemetry, micrometer-tracing-bridge-otel.

Extension (deployment):
- MicrometerObservabilityProcessor: three BuildSteps — FeatureBuildItem,
  AdditionalBeanBuildItem (producer unremovable), UnremovableBeanBuildItem
  (Camel Tracer bean).

Integration tests (JVM + Native, 4 tests):
- testSpansAreGenerated: verifies the full pipeline
  Camel → MicrometerObservabilityTracer → OtelTracer bridge → OTel SDK →
  InMemorySpanExporter.
- testExcludePatternsAreApplied: verifies exclude-patterns suppresses spans
  for matching endpoints.
- testConfigPropertiesAreWired: verifies all five config properties are
  correctly propagated to the live MicrometerObservabilityTracer via
  CamelMicrometerObservabilityConfig.
- testUpstreamW3CTracePropagation: verifies W3C traceparent propagation
  using the real OTel propagator.

Test infrastructure uses InMemorySpanExporter (opentelemetry-sdk-testing)
for validating the full OTel pipeline.

Co-authored-by: Bob <bob@ibm.com>
@JinyuChen97
JinyuChen97 force-pushed the support-camel-micrometer-observability branch from f9443fb to 0fd5a0a Compare July 20, 2026 14:57
@JinyuChen97

Copy link
Copy Markdown
Contributor Author

The main concern I have is with how the MicrometerObservabilityTracerProducer wires up the Micrometer Tracer and Propagator. The current implementation optionally injects them as CDI beans:

@Inject
Instance<Tracer> tracerInstance;

@Inject
Instance<Propagator> propagatorInstance;

The problem is that no Quarkus extension currently produces Micrometer Tracer or Propagator CDI beans. So in practice, tracerInstance.isResolvable() will always be false, and the producer falls through to letting Camel's initTracer() handle it — which defaults to Tracer.NOOP and Propagator.NOOP with warning logs. The extension would appear to work but silently produce no traces.

I actually experimented with this extension some time back. The approach I took is to explicitly bridge from the Quarkus-provided OpenTelemetry bean to Micrometer using quarkus-micrometer-opentelemetry (note this currently has preview status) & micrometer-tracing-bridge-otel:

@Inject
OpenTelemetry openTelemetry;

// In the producer method:
Tracer otelTracer = openTelemetry.getTracer("camel");
OtelCurrentTraceContext currentTraceContext = new OtelCurrentTraceContext();
OtelTracer micrometerTracer = new OtelTracer(otelTracer, currentTraceContext, event -> {},
          new OtelBaggageManager(currentTraceContext, List.of(), List.of()));
OtelPropagator micrometerPropagator = new OtelPropagator(openTelemetry.getPropagators(), otelTracer);

tracer.setTracer(micrometerTracer);
tracer.setPropagator(micrometerPropagator);

This ensures Camel's Micrometer spans are correctly bridged into the same OTel trace context that Quarkus and Vert.x use, so parent-child span relationships work across the full stack.

That way you don't burden the user with having to produce a bunch of CDI beans (which I think is what MicrometerObservabilityConfiguration is doing in the tests).

A couple of other things worth considering:

  • SDK disable check: The opentelemetry2 extension checks oTelRuntimeConfig.sdkDisabled() and returns null when tracing is disabled. This extension should probably do the same for consistency.
  • Test fidelity: Using opentelemetry-sdk-testing's InMemorySpanExporter instead of micrometer-tracing-test's SimpleTracer would validate the full pipeline (Camel → Micrometer bridge → OTel SDK → exporter), proving that spans actually reach OTel rather than only exercising the Micrometer layer.

Thanks for your feedback! Considering quarkus-micrometer-opentelemetry is preview status and confirmed camel-micrometer-observability is tracing only(only register tracing observation handlers in camel)so this extension should be no metric export to otel. using quarkus-opentelemetry instead to bridge from the quarkus-opentelemetry bean to micrometer tracing with micrometer-tracing-bridge-otel will be enough.

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.

Support component camel-micrometer-observability

4 participants