[
https://issues.apache.org/jira/browse/CAMEL-22672?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18038859#comment-18038859
]
Jonas Beyer edited comment on CAMEL-22672 at 11/21/25 2:25 PM:
---------------------------------------------------------------
I have observed the same issue as in
https://issues.apache.org/jira/browse/CAMEL-22349 with lots of unidentifiable
metrics and chose the described solution via naming and disabling.
Then I saw your approach of basically disabling _all_ trace metrics, which
should be at odds with our solution, but is not, because it does not seem to
work.
To be honest I'm quite confused by the last changes;
#
[https://github.com/apache/camel-spring-boot/commit/e59028f4bdfd0810752c622f01366e9d6613398f]:
This beans works in a custom {{@Configuration}} as that causes
[https://github.com/spring-projects/spring-boot/blob/v3.5.7/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java#L128]
to not match and therefore there is no Spring {{MeterObservationHandler}}
creating metrics. But you registered your no-op handler with
[https://github.com/apache/camel-spring-boot/blob/e59028f4bdfd0810752c622f01366e9d6613398f/components-starter/camel-observation-starter/src/main/java/org/apache/camel/observation/starter/ObservationAutoConfiguration.java#L39],
so after the Spring handler is already registered.
#
[https://github.com/apache/camel-spring-boot/commit/4a4e5451cd9f2b9d146486c1acc6999317c4b22e]:
Now both beans are registered with the same name leading to a context startup
failure. This was fixed by renaming the Camel bean, but now both beans are
registered and invoked. The no-op handler may do nothing, but the Spring
handler creates metrics as before.
#
[https://github.com/apache/camel-spring-boot/commit/598b0a98178179c7614d9f5d0ed285cb51cbafea]:
I feel like
[https://github.com/apache/camel-spring-boot/blob/598b0a98178179c7614d9f5d0ed285cb51cbafea/components-starter/camel-observation-starter/src/main/java/org/apache/camel/observation/starter/ObservationAutoConfiguration.java#L37]
should be {{@ConditionalOnClass}} instead. As it stands, this configuration
will now just not be loaded ...
Am I misunderstanding something here?
was (Author: JIRAUSER311448):
I have observed the same issue as in
https://issues.apache.org/jira/browse/CAMEL-22349 with lots of unidentifiable
metrics and chose the described solution via naming and disabling.
Then I saw your approach of basically disabling _all_ trace metrics, which
should be at odds with our solution, but is not, because it does not seem to
work.
To be honest I'm quite confused by the last changes;
#
[https://github.com/apache/camel-spring-boot/commit/e59028f4bdfd0810752c622f01366e9d6613398f:]
This beans works in a custom {{@Configuration}} as that causes
[https://github.com/spring-projects/spring-boot/blob/v3.5.7/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java#L128]
to not match and therefore there is no Spring {{MeterObservationHandler}}
creating metrics. But you registered your no-op handler with
[https://github.com/apache/camel-spring-boot/blob/e59028f4bdfd0810752c622f01366e9d6613398f/components-starter/camel-observation-starter/src/main/java/org/apache/camel/observation/starter/ObservationAutoConfiguration.java#L39],
so after the Spring handler is already registered.
#
[https://github.com/apache/camel-spring-boot/commit/4a4e5451cd9f2b9d146486c1acc6999317c4b22e:]
Now both beans are registered with the same name leading to a context startup
failure. This was fixed by renaming the Camel bean, but now both beans are
registered and invoked. The no-op handler may do nothing, but the Spring
handler creates metrics as before.
#
[https://github.com/apache/camel-spring-boot/commit/598b0a98178179c7614d9f5d0ed285cb51cbafea:]
I feel like
[https://github.com/apache/camel-spring-boot/blob/598b0a98178179c7614d9f5d0ed285cb51cbafea/components-starter/camel-observation-starter/src/main/java/org/apache/camel/observation/starter/ObservationAutoConfiguration.java#L37]
should be {{@ConditionalOnClass}} instead. As it stands, this configuration
will now just not be loaded ...
Am I misunderstanding something here?
> [camel-observation] observations and metrics
> --------------------------------------------
>
> Key: CAMEL-22672
> URL: https://issues.apache.org/jira/browse/CAMEL-22672
> Project: Camel
> Issue Type: Bug
> Affects Versions: 4.13.0
> Reporter: Jonas Beyer
> Assignee: Pasquale Congiusti
> Priority: Minor
> Fix For: 4.17.0
>
>
> This is a bit of a revival of CAMEL-22349, which as far as I can tell has not
> been resolved. The idea seems to be that
> [https://github.com/apache/camel-spring-boot/pull/1493/files] would cause
> {{@ConditionalOnMissingBean(MeterObservationHandler.class)}} in
> {{org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration}}
> to fail, which would prevent the creation of metrics ... in the whole
> context.
> This did not work because the Camel {{ObservationAutoConfiguration}} has
> {{@AutoConfigureAfter}} the Spring one. And so Spring tried to create both
> beans leading to CAMEL-22612. The fix renamed the bean, so now both are
> successfully created and with the Spring one also metrics.
> I ran into the problem of many metrics on 4.14.0 and my main issue was the
> naming, as {{process2}} or {{to13}} are no sensible identifiers. By naming
> them hierarchically they could be conveniently suppressed via the property
> {{management.metrics.enable.[prefix]: false}} or a configurable
> {{MeterFilter}} instead of disabling the functionality.
> Our current workaround is:
> {code:java}
> import java.util.Map;
> import java.util.concurrent.ConcurrentHashMap;
> import java.util.concurrent.atomic.AtomicInteger;
> import org.apache.camel.Endpoint;
> import org.apache.camel.Exchange;
> import org.apache.camel.NamedNode;
> import org.apache.camel.observation.MicrometerObservationTracer;
> import org.apache.camel.spi.NodeIdFactory;
> import org.apache.camel.support.ExtendedExchangeExtension;
> import org.apache.commons.lang3.Strings;
> import lombok.RequiredArgsConstructor;
> import lombok.experimental.Delegate;
> import lombok.val;
> public class CamelNodeIdFactory implements NodeIdFactory {
> private static final String PREFIX = "camel-node";
> private static final Map<String, AtomicInteger> NODE_COUNTERS = new
> ConcurrentHashMap<>();
> @Override
> public String createId(NamedNode definition) {
> val id = getId(definition);
> val counter = NODE_COUNTERS.computeIfAbsent(id, k -> new
> AtomicInteger()).incrementAndGet();
> return id + (counter > 1 ? counter : "");
> }
> private String getId(NamedNode definition) {
> if (definition == null) {
> return PREFIX;
> } else if (definition.getId() != null) {
> return Strings.CS.prependIfMissing(definition.getId(), PREFIX + ".");
> } else {
> val parentId = getId(definition.getParent());
> return parentId + "." + definition.getShortName();
> }
> }
> @RequiredArgsConstructor
> public static class SpanDecorator implements
> org.apache.camel.tracing.SpanDecorator {
> @Delegate
> private final org.apache.camel.tracing.SpanDecorator delegate;
> @Override
> public String getOperationName(Exchange exchange, Endpoint endpoint) {
> val exchangeExtension = (ExtendedExchangeExtension)
> exchange.getExchangeExtension();
> val nodeId = exchangeExtension.getHistoryNodeId();
> return nodeId != null ? nodeId :
> Strings.CS.prependIfMissing(exchangeExtension.getFromRouteId(), PREFIX + ".");
> }
> }
> public static class Tracer extends MicrometerObservationTracer {
> @Override
> protected org.apache.camel.tracing.SpanDecorator
> getSpanDecorator(Endpoint endpoint) {
> return new SpanDecorator(super.getSpanDecorator(endpoint));
> }
> }
> }{code}
> with
> {code:java}
> @Bean(initMethod = "", destroyMethod = "") // Camel handles the lifecycle
> of this bean
> public MicrometerObservationTracer micrometerObservationTracer(CamelContext
> camelContext,
> Tracer tracer,
> ObservationRegistry registry) {
>
> camelContext.getCamelContextExtension().addContextPlugin(NodeIdFactory.class,
> new CamelNodeIdFactory());
> val micrometerObservationTracer = new CamelNodeIdFactory.Tracer();
> micrometerObservationTracer.setTracer(tracer);
> micrometerObservationTracer.setObservationRegistry(registry);
> micrometerObservationTracer.setTracingStrategy(new
> MicrometerTracingStrategy(micrometerObservationTracer));
> micrometerObservationTracer.init(camelContext);
> return micrometerObservationTracer;
> } {code}
> This could of course be cleaner if properly integrated into Camel.
> It already enables us to turn off all route-specific metrics by default
> {code:java}
> management.metrics.enable.camel-node: false{code}
> and turn on specific ones
> {code:java}
> management.metrics.enable.camel-node.[node-id]: true {code}
>
> This is not perfect as the node id is part of the metric name instead of a
> tag, but it is clear which part of the route is measured
> ({{{}camel_node_heartbeat_log_seconds{}}} instead of {{{}log[n]{}}}) - and it
> doesn't interfere with the rest of the Spring Boot context.
> cc [~squakez]
--
This message was sent by Atlassian Jira
(v8.20.10#820010)