You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2025/03/20 08:39:37 UTC
(camel) branch main updated: feat(components): include a micrometer metric gauge for app
This is an automated email from the ASF dual-hosted git repository.
pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 5b69ce725a7 feat(components): include a micrometer metric gauge for app
5b69ce725a7 is described below
commit 5b69ce725a766f75d60f9eed605f2186a1a9b6ed
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Wed Mar 19 12:10:21 2025 +0100
feat(components): include a micrometer metric gauge for app
Add some logic that attempts to scan the runtime and provide such information as an additional metric
---
.../component/micrometer/MicrometerConstants.java | 2 +
.../AbstractMicrometerEventNotifier.java | 10 +++
.../micrometer/json/AbstractMicrometerService.java | 84 ++++++++++++++++++++++
...MicrometerExchangeEventNotifierDynamicTest.java | 2 +-
.../MicrometerExchangeEventNotifierStaticTest.java | 2 +-
...ExceptionRouteMicrometerMessageHistoryTest.java | 2 +-
.../messagehistory/ManagedMessageHistoryTest.java | 2 +-
.../MicrometerMessageHistoryTest.java | 2 +-
.../SpringMicrometerMessageHistoryTest.java | 2 +-
.../ManagedMicrometerRoutePolicyTest.java | 2 +-
.../MicrometerRoutePolicyConfigurationTest.java | 2 +-
...MicrometerRoutePolicyMulticastSubRouteTest.java | 8 ++-
.../MicrometerRoutePolicySubRouteTest.java | 5 +-
.../ZMicrometerRoutePolicyExcludePatternTest.java | 6 +-
14 files changed, 118 insertions(+), 13 deletions(-)
diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConstants.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConstants.java
index e6b25516393..ff3255dc0e4 100644
--- a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConstants.java
+++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConstants.java
@@ -58,6 +58,8 @@ public final class MicrometerConstants {
public static final String DEFAULT_CAMEL_ROUTES_RUNNING = "camel.routes.running";
public static final String DEFAULT_CAMEL_ROUTES_RELOADED = "camel.routes.reloaded";
+ public static final String APP_INFO_METER_NAME = "app.info";
+
public static final String ROUTE_ID_TAG = "routeId";
public static final String NODE_ID_TAG = "nodeId";
public static final String FAILED_TAG = "failed";
diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/AbstractMicrometerEventNotifier.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/AbstractMicrometerEventNotifier.java
index 420ebb98eff..898279a62fe 100644
--- a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/AbstractMicrometerEventNotifier.java
+++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/AbstractMicrometerEventNotifier.java
@@ -40,6 +40,7 @@ public abstract class AbstractMicrometerEventNotifier<T extends CamelEvent> exte
private CamelContext camelContext;
private MeterRegistry meterRegistry;
private boolean prettyPrint;
+ private boolean skipCamelInfo = false;
private TimeUnit durationUnit = TimeUnit.MILLISECONDS;
protected AbstractMicrometerEventNotifier(Class<T> eventType) {
@@ -72,6 +73,14 @@ public abstract class AbstractMicrometerEventNotifier<T extends CamelEvent> exte
this.prettyPrint = prettyPrint;
}
+ public boolean isSkipCamelInfo() {
+ return skipCamelInfo;
+ }
+
+ public void setSkipCamelInfo(boolean skipCamelInfo) {
+ this.skipCamelInfo = skipCamelInfo;
+ }
+
public TimeUnit getDurationUnit() {
return durationUnit;
}
@@ -99,6 +108,7 @@ public abstract class AbstractMicrometerEventNotifier<T extends CamelEvent> exte
registryService = new MicrometerEventNotifierService();
registryService.setMeterRegistry(getMeterRegistry());
registryService.setPrettyPrint(isPrettyPrint());
+ registryService.setSkipCamelInfo(isSkipCamelInfo());
registryService.setDurationUnit(getDurationUnit());
registryService.setMatchingTags(Tags.of(KIND, KIND_EXCHANGE));
camelContext.addService(registryService);
diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/json/AbstractMicrometerService.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/json/AbstractMicrometerService.java
index 574cd8bf596..ecba8f75e31 100644
--- a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/json/AbstractMicrometerService.java
+++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/json/AbstractMicrometerService.java
@@ -16,6 +16,8 @@
*/
package org.apache.camel.component.micrometer.json;
+import java.util.ArrayList;
+import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
@@ -32,11 +34,14 @@ import org.apache.camel.component.micrometer.MicrometerConstants;
import org.apache.camel.spi.Registry;
import org.apache.camel.support.service.ServiceSupport;
+import static org.apache.camel.component.micrometer.MicrometerConstants.APP_INFO_METER_NAME;
+
public class AbstractMicrometerService extends ServiceSupport {
private CamelContext camelContext;
private MeterRegistry meterRegistry;
private boolean prettyPrint = true;
+ private boolean skipCamelInfo = false;
private TimeUnit durationUnit = TimeUnit.MILLISECONDS;
private Iterable<Tag> matchingTags = Tags.empty();
private Predicate<String> matchingNames;
@@ -67,6 +72,14 @@ public class AbstractMicrometerService extends ServiceSupport {
this.prettyPrint = prettyPrint;
}
+ public boolean isSkipCamelInfo() {
+ return skipCamelInfo;
+ }
+
+ public void setSkipCamelInfo(boolean skipCamelInfo) {
+ this.skipCamelInfo = skipCamelInfo;
+ }
+
public TimeUnit getDurationUnit() {
return durationUnit;
}
@@ -126,6 +139,10 @@ public class AbstractMicrometerService extends ServiceSupport {
}
}
+ if (!this.skipCamelInfo) {
+ registerAppInfo(meterRegistry);
+ }
+
// json mapper
this.mapper = new ObjectMapper()
.registerModule(new MicrometerModule(getDurationUnit(), getMatchingNames(), getMatchingTags()));
@@ -139,4 +156,71 @@ public class AbstractMicrometerService extends ServiceSupport {
protected void doStop() {
// noop
}
+
+ // This method does a best effort attempt to recover information about versioning of the runtime.
+ // It is also in charge to include the information in the meterRegistry passed in.
+ private void registerAppInfo(MeterRegistry meterRegistry) {
+ Optional<RuntimeInfo> rt = RuntimeInfo.quarkus();
+ if (!rt.isPresent()) {
+ rt = RuntimeInfo.springboot();
+ }
+ if (!rt.isPresent()) {
+ // If not other runtime is available, we assume we're on Camel main
+ rt = Optional.of(new RuntimeInfo(RuntimeInfo.MAIN, getCamelContext().getVersion()));
+ }
+ meterRegistry.gaugeCollectionSize(
+ APP_INFO_METER_NAME,
+ Tags.of(
+ "camel.version", getCamelContext().getVersion(),
+ "camel.context", getCamelContext().getName(),
+ "camel.runtime.provider", rt.get().runtimeProvider,
+ "camel.runtime.version", rt.get().runtimeVersion),
+ new ArrayList<String>());
+ }
+
+ private static class RuntimeInfo {
+ private static String QUARKUS = "Quarkus";
+ private static String SPRING_BOOT = "Spring-Boot";
+ private static String MAIN = "Main";
+
+ String runtimeProvider;
+ String runtimeVersion;
+
+ private RuntimeInfo(String runtimeProvider, String runtimeVersion) {
+ this.runtimeProvider = runtimeProvider;
+ this.runtimeVersion = runtimeVersion;
+ }
+
+ static Optional<RuntimeInfo> quarkus() {
+ Optional<String> version = scan("io.quarkus.runtime.Application");
+ if (version.isPresent()) {
+ return Optional.of(new RuntimeInfo(QUARKUS, version.get()));
+ }
+ return Optional.empty();
+ }
+
+ static Optional<RuntimeInfo> springboot() {
+ Optional<String> version = scan("org.springframework.boot.SpringApplication");
+ if (version.isPresent()) {
+ return Optional.of(new RuntimeInfo(SPRING_BOOT, version.get()));
+ }
+ return Optional.empty();
+ }
+
+ static Optional<String> scan(String fqn) {
+ try {
+ Class<?> clazz = Class.forName(fqn);
+ Package pkg = clazz.getPackage();
+
+ if (pkg != null) {
+ return Optional.of(pkg.getImplementationVersion());
+ }
+ } catch (ClassNotFoundException e) {
+ // NOOP
+ }
+
+ return Optional.empty();
+ }
+ }
+
}
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifierDynamicTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifierDynamicTest.java
index df606835e90..8d76fdaebec 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifierDynamicTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifierDynamicTest.java
@@ -72,7 +72,7 @@ public class MicrometerExchangeEventNotifierDynamicTest extends AbstractMicromet
Set<MeterRegistry> set = meterRegistry.getRegistries();
assertEquals(2, set.size());
for (MeterRegistry mr : set) {
- assertEquals(14, mr.getMeters().size());
+ assertEquals(15, mr.getMeters().size());
int counter = 0;
for (Meter m : mr.getMeters()) {
if (m.getId().getName().equals(MicrometerConstants.DEFAULT_CAMEL_EXCHANGE_EVENT_METER_NAME) &&
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifierStaticTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifierStaticTest.java
index f0143809d34..4892f341bfb 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifierStaticTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifierStaticTest.java
@@ -59,7 +59,7 @@ public class MicrometerExchangeEventNotifierStaticTest extends MicrometerExchang
Set<MeterRegistry> set = meterRegistry.getRegistries();
assertEquals(2, set.size());
for (MeterRegistry mr : set) {
- assertEquals(5, mr.getMeters().size());
+ assertEquals(6, mr.getMeters().size());
int counter = 0;
for (Meter m : mr.getMeters()) {
if (m.getId().getName().equals(MicrometerConstants.DEFAULT_CAMEL_EXCHANGE_EVENT_METER_NAME) &&
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ExceptionRouteMicrometerMessageHistoryTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ExceptionRouteMicrometerMessageHistoryTest.java
index bdb392401f3..140bdb2f205 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ExceptionRouteMicrometerMessageHistoryTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ExceptionRouteMicrometerMessageHistoryTest.java
@@ -65,7 +65,7 @@ public class ExceptionRouteMicrometerMessageHistoryTest extends CamelTestSupport
MockEndpoint.assertIsSatisfied(context);
// there should be 3 names
- assertEquals(3, registry.getMeters().size());
+ assertEquals(4, registry.getMeters().size());
// get the message history service
MicrometerMessageHistoryService service = context.hasService(MicrometerMessageHistoryService.class);
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ManagedMessageHistoryTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ManagedMessageHistoryTest.java
index a1b7a5d7de8..903fb5d22f0 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ManagedMessageHistoryTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ManagedMessageHistoryTest.java
@@ -115,7 +115,7 @@ public class ManagedMessageHistoryTest extends CamelTestSupport {
MockEndpoint.assertIsSatisfied(context);
// there should be 3 names
- assertEquals(3, meterRegistry.getMeters().size());
+ assertEquals(4, meterRegistry.getMeters().size());
// there should be 3 mbeans
Set<ObjectName> set = timerNames();
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/MicrometerMessageHistoryTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/MicrometerMessageHistoryTest.java
index 2e18d62d9be..07b9117deff 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/MicrometerMessageHistoryTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/MicrometerMessageHistoryTest.java
@@ -70,7 +70,7 @@ public class MicrometerMessageHistoryTest extends CamelTestSupport {
MockEndpoint.assertIsSatisfied(context);
// there should be 3 names
- assertEquals(3, registry.getMeters().size());
+ assertEquals(4, registry.getMeters().size());
Timer fooTimer = registry.find(DEFAULT_CAMEL_MESSAGE_HISTORY_METER_NAME).tag(NODE_ID_TAG, "foo").timer();
assertEquals(count / 2, fooTimer.count());
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/SpringMicrometerMessageHistoryTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/SpringMicrometerMessageHistoryTest.java
index 033dc1fb931..b1e89e72cce 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/SpringMicrometerMessageHistoryTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/SpringMicrometerMessageHistoryTest.java
@@ -62,7 +62,7 @@ public class SpringMicrometerMessageHistoryTest extends CamelSpringTestSupport {
// there should be 3 names
MeterRegistry registry = context.getRegistry().findByType(MeterRegistry.class).iterator().next();
- assertEquals(3, registry.getMeters().size());
+ assertEquals(4, registry.getMeters().size());
Timer fooTimer = registry.find(DEFAULT_CAMEL_MESSAGE_HISTORY_METER_NAME).tag(NODE_ID_TAG, "foo").timer();
assertEquals(count / 2, fooTimer.count());
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/ManagedMicrometerRoutePolicyTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/ManagedMicrometerRoutePolicyTest.java
index 399655f58d0..f4dae4ac025 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/ManagedMicrometerRoutePolicyTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/ManagedMicrometerRoutePolicyTest.java
@@ -59,7 +59,7 @@ public class ManagedMicrometerRoutePolicyTest extends AbstractMicrometerRoutePol
// there should be 13 names
List<Meter> meters = meterRegistry.getMeters();
- assertEquals(13, meters.size());
+ assertEquals(14, meters.size());
String name = String.format("org.apache.camel:context=%s,type=services,name=MicrometerRoutePolicyService",
context.getManagementName());
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicyConfigurationTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicyConfigurationTest.java
index dc8b935fab7..cd00b39e529 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicyConfigurationTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicyConfigurationTest.java
@@ -61,7 +61,7 @@ public class MicrometerRoutePolicyConfigurationTest extends AbstractMicrometerRo
template.request("direct:foo", x -> {
});
List<Meter> meters = meterRegistry.getMeters();
- assertEquals(2, meters.size(), "additional counters does not disable");
+ assertEquals(3, meters.size(), "additional counters does not disable");
Timer timer = (Timer) meters.stream().filter(it -> it instanceof Timer)
.findFirst().orElse(null);
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicyMulticastSubRouteTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicyMulticastSubRouteTest.java
index bb39dd94b3f..ed18d5c59ec 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicyMulticastSubRouteTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicyMulticastSubRouteTest.java
@@ -19,12 +19,14 @@ package org.apache.camel.component.micrometer.routepolicy;
import java.util.List;
import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.Timer;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.junit.jupiter.api.Test;
+import static org.apache.camel.component.micrometer.MicrometerConstants.APP_INFO_METER_NAME;
import static org.apache.camel.component.micrometer.MicrometerConstants.DEFAULT_CAMEL_ROUTE_POLICY_EXCHANGES_EXTERNAL_REDELIVERIES_METER_NAME;
import static org.apache.camel.component.micrometer.MicrometerConstants.DEFAULT_CAMEL_ROUTE_POLICY_EXCHANGES_FAILED_METER_NAME;
import static org.apache.camel.component.micrometer.MicrometerConstants.DEFAULT_CAMEL_ROUTE_POLICY_EXCHANGES_FAILURES_HANDLED_METER_NAME;
@@ -56,7 +58,7 @@ public class MicrometerRoutePolicyMulticastSubRouteTest extends AbstractMicromet
// there should be 6 metrics per route
List<Meter> meters = meterRegistry.getMeters();
- assertEquals(6 * context.getRouteDefinitions().size(), meters.size());
+ assertEquals(6 * context.getRouteDefinitions().size() + 1, meters.size());
meters.forEach(meter -> {
String meterName = meter.getId().getName();
@@ -116,6 +118,10 @@ public class MicrometerRoutePolicyMulticastSubRouteTest extends AbstractMicromet
"Counter " + counter.getId() + " should have count of " + count);
break;
}
+ case APP_INFO_METER_NAME:
+ Gauge gauge = (Gauge) meter;
+ // It's enough to validate it does not throw a class cast exception
+ break;
default: {
fail("Unexpected meter " + meterName);
break;
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicySubRouteTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicySubRouteTest.java
index 5322810d82c..8cce8672458 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicySubRouteTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicySubRouteTest.java
@@ -19,6 +19,7 @@ package org.apache.camel.component.micrometer.routepolicy;
import java.util.List;
import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.Timer;
import org.apache.camel.builder.RouteBuilder;
@@ -44,8 +45,8 @@ public class MicrometerRoutePolicySubRouteTest extends AbstractMicrometerRoutePo
// there should be 6 metrics per route
List<Meter> meters = meterRegistry.getMeters();
- assertEquals(6 * context.getRouteDefinitions().size(), meters.size());
- meters.forEach(meter -> assertTrue(meter instanceof Timer || meter instanceof Counter));
+ assertEquals(6 * context.getRouteDefinitions().size() + 1, meters.size());
+ meters.forEach(meter -> assertTrue(meter instanceof Timer || meter instanceof Counter || meter instanceof Gauge));
}
@Override
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/ZMicrometerRoutePolicyExcludePatternTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/ZMicrometerRoutePolicyExcludePatternTest.java
index abb3a396dc5..effb421434c 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/ZMicrometerRoutePolicyExcludePatternTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/routepolicy/ZMicrometerRoutePolicyExcludePatternTest.java
@@ -19,6 +19,7 @@ package org.apache.camel.component.micrometer.routepolicy;
import java.util.List;
import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.Timer;
import org.apache.camel.builder.RouteBuilder;
@@ -55,9 +56,10 @@ public class ZMicrometerRoutePolicyExcludePatternTest extends AbstractMicrometer
MockEndpoint.assertIsSatisfied(context);
// there should be 6 metrics per route (only 1 route as bar is excluded)
+ // additionally one for App info gauge
List<Meter> meters = meterRegistry.getMeters();
- assertEquals(6, meters.size());
- meters.forEach(meter -> assertTrue(meter instanceof Timer || meter instanceof Counter));
+ assertEquals(7, meters.size());
+ meters.forEach(meter -> assertTrue(meter instanceof Timer || meter instanceof Counter || meter instanceof Gauge));
}
@Override