You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/12/19 11:43:55 UTC

(camel) 01/07: Experiment

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch mm
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 9f334c14e9707f26e84bae61f945cb0c79ab75ca
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Dec 18 16:34:28 2023 +0100

    Experiment
---
 .../prometheus/MicrometerPrometheusConfigurer.java |  6 +++
 .../prometheus/MicrometerPrometheus.java           | 60 ++++++++++++++++++++--
 .../component/micrometer/MicrometerConsole.java    |  2 +-
 .../routepolicy/MicrometerRoutePolicy.java         | 33 ++++++++++++
 .../MetricsConfigurationPropertiesConfigurer.java  |  6 +++
 .../camel-main-configuration-metadata.json         |  1 +
 core/camel-main/src/main/docs/main.adoc            |  3 +-
 .../camel/main/MetricsConfigurationProperties.java | 21 ++++++++
 8 files changed, 126 insertions(+), 6 deletions(-)

diff --git a/components/camel-micrometer-prometheus/src/generated/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheusConfigurer.java b/components/camel-micrometer-prometheus/src/generated/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheusConfigurer.java
index 479105554d7..3466314c9cd 100644
--- a/components/camel-micrometer-prometheus/src/generated/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheusConfigurer.java
+++ b/components/camel-micrometer-prometheus/src/generated/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheusConfigurer.java
@@ -25,6 +25,8 @@ public class MicrometerPrometheusConfigurer extends org.apache.camel.support.com
         case "Binders": target.setBinders(property(camelContext, java.lang.String.class, value)); return true;
         case "camelcontext":
         case "CamelContext": target.setCamelContext(property(camelContext, org.apache.camel.CamelContext.class, value)); return true;
+        case "clearonreload":
+        case "ClearOnReload": target.setClearOnReload(property(camelContext, boolean.class, value)); return true;
         case "enableexchangeeventnotifier":
         case "EnableExchangeEventNotifier": target.setEnableExchangeEventNotifier(property(camelContext, boolean.class, value)); return true;
         case "enablemessagehistory":
@@ -48,6 +50,8 @@ public class MicrometerPrometheusConfigurer extends org.apache.camel.support.com
         case "Binders": return java.lang.String.class;
         case "camelcontext":
         case "CamelContext": return org.apache.camel.CamelContext.class;
+        case "clearonreload":
+        case "ClearOnReload": return boolean.class;
         case "enableexchangeeventnotifier":
         case "EnableExchangeEventNotifier": return boolean.class;
         case "enablemessagehistory":
@@ -72,6 +76,8 @@ public class MicrometerPrometheusConfigurer extends org.apache.camel.support.com
         case "Binders": return target.getBinders();
         case "camelcontext":
         case "CamelContext": return target.getCamelContext();
+        case "clearonreload":
+        case "ClearOnReload": return target.isClearOnReload();
         case "enableexchangeeventnotifier":
         case "EnableExchangeEventNotifier": return target.isEnableExchangeEventNotifier();
         case "enablemessagehistory":
diff --git a/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheus.java b/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheus.java
index d8cab4db2e4..cbe38ac8515 100644
--- a/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheus.java
+++ b/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheus.java
@@ -18,11 +18,13 @@ package org.apache.camel.component.micrometer.prometheus;
 
 import java.io.Closeable;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.StringJoiner;
 
+import io.micrometer.core.instrument.Meter;
 import io.micrometer.core.instrument.MeterRegistry;
 import io.micrometer.core.instrument.binder.MeterBinder;
 import io.micrometer.prometheus.PrometheusConfig;
@@ -49,12 +51,14 @@ import org.apache.camel.component.micrometer.routepolicy.MicrometerRoutePolicyNa
 import org.apache.camel.component.platform.http.PlatformHttpComponent;
 import org.apache.camel.component.platform.http.main.MainHttpServer;
 import org.apache.camel.component.platform.http.vertx.VertxPlatformHttpRouter;
+import org.apache.camel.spi.CamelEvent;
 import org.apache.camel.spi.CamelMetricsService;
 import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.ManagementStrategy;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.Registry;
 import org.apache.camel.spi.annotations.JdkService;
+import org.apache.camel.support.SimpleEventNotifierSupport;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
@@ -86,6 +90,8 @@ public class MicrometerPrometheus extends ServiceSupport implements CamelMetrics
     private boolean enableExchangeEventNotifier = true;
     @Metadata(defaultValue = "true")
     private boolean enableRouteEventNotifier = true;
+    @Metadata(defaultValue = "true")
+    private boolean clearOnReload = true;
     @Metadata(defaultValue = "0.0.4", enums = "0.0.4,1.0.0")
     private String textFormatVersion = "0.0.4";
     @Metadata
@@ -107,7 +113,7 @@ public class MicrometerPrometheus extends ServiceSupport implements CamelMetrics
 
     /**
      * Controls the name style to use for metrics.
-     *
+     * <p>
      * Default = uses micrometer naming convention. Legacy = uses the classic naming style (camelCase)
      */
     public void setNamingStrategy(String namingStrategy) {
@@ -132,7 +138,7 @@ public class MicrometerPrometheus extends ServiceSupport implements CamelMetrics
     /**
      * Set whether to enable the MicrometerMessageHistoryFactory for capturing metrics on individual route node
      * processing times.
-     *
+     * <p>
      * Depending on the number of configured route nodes, there is the potential to create a large volume of metrics.
      * Therefore, this option is disabled by default.
      */
@@ -163,13 +169,24 @@ public class MicrometerPrometheus extends ServiceSupport implements CamelMetrics
         this.enableRouteEventNotifier = enableRouteEventNotifier;
     }
 
+    public boolean isClearOnReload() {
+        return clearOnReload;
+    }
+
+    /**
+     * Clear the captured metrics data when Camel is reloading routes such as when using Camel JBang.
+     */
+    public void setClearOnReload(boolean clearOnReload) {
+        this.clearOnReload = clearOnReload;
+    }
+
     public String getTextFormatVersion() {
         return textFormatVersion;
     }
 
     /**
      * The text-format version to use with Prometheus scraping.
-     *
+     * <p>
      * 0.0.4 = text/plain; version=0.0.4; charset=utf-8 1.0.0 = application/openmetrics-text; version=1.0.0;
      * charset=utf-8
      */
@@ -184,7 +201,7 @@ public class MicrometerPrometheus extends ServiceSupport implements CamelMetrics
     /**
      * Additional Micrometer binders to include such as jvm-memory, processor, jvm-thread, and so forth. Multiple
      * binders can be separated by comma.
-     *
+     * <p>
      * The following binders currently is available from Micrometer: class-loader, commons-object-pool2,
      * file-descriptor, hystrix-metrics-binder, jvm-compilation, jvm-gc, jvm-heap-pressure, jvm-info, jvm-memory,
      * jvm-thread, log4j2, logback, processor, uptime
@@ -257,6 +274,41 @@ public class MicrometerPrometheus extends ServiceSupport implements CamelMetrics
             factory.setMeterRegistry(meterRegistry);
             camelContext.setMessageHistoryFactory(factory);
         }
+
+        if (clearOnReload) {
+            camelContext.getManagementStrategy().addEventNotifier(new SimpleEventNotifierSupport() {
+
+                @Override
+                public boolean isEnabled(CamelEvent event) {
+                    return event instanceof CamelEvent.RouteReloadedEvent;
+                }
+
+                @Override
+                public void notify(CamelEvent event) throws Exception {
+                    // when reloading then there may be more routes in the same batch, so we only want
+                    // to log the summary at the end
+                    if (event instanceof CamelEvent.RouteReloadedEvent) {
+                        CamelEvent.RouteReloadedEvent re = (CamelEvent.RouteReloadedEvent) event;
+                        if (re.getIndex() >= re.getTotal()) {
+                            LOG.info("Resetting Micrometer Registry after reloading routes");
+
+                            // remove all meters that are from Camel and associated routes via routeId as tag
+                            List<Meter> toRemove = new ArrayList<>();
+                            for (Meter m : meterRegistry.getMeters()) {
+                                String n = m.getId().getName();
+                                if (n.startsWith("camel_") || n.startsWith("camel.")) {
+                                    String t = m.getId().getTag("routeId");
+                                    if (t != null) {
+                                        toRemove.add(m);
+                                    }
+                                }
+                            }
+                            toRemove.forEach(meterRegistry::remove);
+                        }
+                    }
+                }
+            });
+        }
     }
 
     @Override
diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConsole.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConsole.java
index 4c87e4ada99..6cbff3403a3 100644
--- a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConsole.java
+++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConsole.java
@@ -45,7 +45,7 @@ public class MicrometerConsole extends AbstractDevConsole {
         StringBuilder sb = new StringBuilder();
 
         MeterRegistry mr = lookupMeterRegistry();
-        sb.append(String.format("MeterRegistry: %s\n", mr.getClass().getName()));
+        sb.append(String.format("MeterRegistry: %s\n\n", mr.getClass().getName()));
 
         int i = 0;
         for (Meter m : mr.getMeters()) {
diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicy.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicy.java
index a53dc85753f..264cb58d6cf 100644
--- a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicy.java
+++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicy.java
@@ -220,6 +220,7 @@ public class MicrometerRoutePolicy extends RoutePolicySupport implements NonMana
     @Override
     public void onInit(Route route) {
         super.onInit(route);
+
         if (getMeterRegistry() == null) {
             setMeterRegistry(MicrometerUtils.getOrCreateMeterRegistry(
                     route.getCamelContext().getRegistry(), METRICS_REGISTRY_NAME));
@@ -239,7 +240,10 @@ public class MicrometerRoutePolicy extends RoutePolicySupport implements NonMana
         } catch (Exception e) {
             throw RuntimeCamelException.wrapRuntimeCamelException(e);
         }
+    }
 
+    @Override
+    public void onStart(Route route) {
         // create statistics holder
         // for now we record only all the timings of a complete exchange (responses)
         // we have in-flight / total statistics already from camel-core
@@ -247,6 +251,35 @@ public class MicrometerRoutePolicy extends RoutePolicySupport implements NonMana
                 it -> new MetricsStatistics(getMeterRegistry(), it, getNamingStrategy(), configuration));
     }
 
+    @Override
+    public void onRemove(Route route) {
+        // route is removed, so remove metrics from micrometer
+        MetricsStatistics stats = statisticsMap.remove(route);
+        if (stats != null) {
+            if (stats.exchangesSucceeded != null) {
+                meterRegistry.remove(stats.exchangesSucceeded);
+            }
+            if (stats.exchangesFailed != null) {
+                meterRegistry.remove(stats.exchangesFailed);
+            }
+            if (stats.exchangesTotal != null) {
+                meterRegistry.remove(stats.exchangesTotal);
+            }
+            if (stats.externalRedeliveries != null) {
+                meterRegistry.remove(stats.externalRedeliveries);
+            }
+            if (stats.failuresHandled != null) {
+                meterRegistry.remove(stats.failuresHandled);
+            }
+            if (stats.timer != null) {
+                meterRegistry.remove(stats.timer);
+            }
+            if (stats.longTaskTimer != null) {
+                meterRegistry.remove(stats.longTaskTimer);
+            }
+        }
+    }
+
     @Override
     public void onExchangeBegin(Route route, Exchange exchange) {
         Optional.ofNullable(statisticsMap.get(route))
diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/MetricsConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/MetricsConfigurationPropertiesConfigurer.java
index 9d53c533439..59fd581efe0 100644
--- a/core/camel-main/src/generated/java/org/apache/camel/main/MetricsConfigurationPropertiesConfigurer.java
+++ b/core/camel-main/src/generated/java/org/apache/camel/main/MetricsConfigurationPropertiesConfigurer.java
@@ -23,6 +23,8 @@ public class MetricsConfigurationPropertiesConfigurer extends org.apache.camel.s
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "binders":
         case "Binders": target.setBinders(property(camelContext, java.lang.String.class, value)); return true;
+        case "clearonreload":
+        case "ClearOnReload": target.setClearOnReload(property(camelContext, boolean.class, value)); return true;
         case "enableexchangeeventnotifier":
         case "EnableExchangeEventNotifier": target.setEnableExchangeEventNotifier(property(camelContext, boolean.class, value)); return true;
         case "enablemessagehistory":
@@ -46,6 +48,8 @@ public class MetricsConfigurationPropertiesConfigurer extends org.apache.camel.s
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "binders":
         case "Binders": return java.lang.String.class;
+        case "clearonreload":
+        case "ClearOnReload": return boolean.class;
         case "enableexchangeeventnotifier":
         case "EnableExchangeEventNotifier": return boolean.class;
         case "enablemessagehistory":
@@ -70,6 +74,8 @@ public class MetricsConfigurationPropertiesConfigurer extends org.apache.camel.s
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "binders":
         case "Binders": return target.getBinders();
+        case "clearonreload":
+        case "ClearOnReload": return target.isClearOnReload();
         case "enableexchangeeventnotifier":
         case "EnableExchangeEventNotifier": return target.isEnableExchangeEventNotifier();
         case "enablemessagehistory":
diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index d7d8b717315..3a1734b8152 100644
--- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -173,6 +173,7 @@
     { "name": "camel.lra.localParticipantContextPath", "description": "The context-path for the local participant. Is default \/lra-participant", "sourceType": "org.apache.camel.main.LraConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "\/lra-participant" },
     { "name": "camel.lra.localParticipantUrl", "description": "The URL for the local participant", "sourceType": "org.apache.camel.main.LraConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
     { "name": "camel.metrics.binders", "description": "Additional Micrometer binders to include such as jvm-memory, processor, jvm-thread, and so forth. Multiple binders can be separated by comma. The following binders currently is available from Micrometer: class-loader, commons-object-pool2, file-descriptor, hystrix-metrics-binder, jvm-compilation, jvm-gc, jvm-heap-pressure, jvm-info, jvm-memory, jvm-thread, log4j2, logback, processor, uptime", "sourceType": "org.apache.camel.main.Metr [...]
+    { "name": "camel.metrics.clearOnReload", "description": "Clear the captured metrics data when Camel is reloading routes such as when using Camel JBang.", "sourceType": "org.apache.camel.main.MetricsConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.metrics.enabled", "description": "To enable Micrometer metrics.", "sourceType": "org.apache.camel.main.MetricsConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.metrics.enableExchangeEventNotifier", "description": "Set whether to enable the MicrometerExchangeEventNotifier for capturing metrics on exchange processing times.", "sourceType": "org.apache.camel.main.MetricsConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.metrics.enableMessageHistory", "description": "Set whether to enable the MicrometerMessageHistoryFactory for capturing metrics on individual route node processing times. Depending on the number of configured route nodes, there is the potential to create a large volume of metrics. Therefore, this option is disabled by default.", "sourceType": "org.apache.camel.main.MetricsConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index 7541bf137cf..87322318756 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -360,12 +360,13 @@ The camel.opentelemetry supports 4 options, which are listed below.
 
 
 === Camel Micrometer Metrics configurations
-The camel.metrics supports 8 options, which are listed below.
+The camel.metrics supports 9 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
 | *camel.metrics.binders* | Additional Micrometer binders to include such as jvm-memory, processor, jvm-thread, and so forth. Multiple binders can be separated by comma. The following binders currently is available from Micrometer: class-loader, commons-object-pool2, file-descriptor, hystrix-metrics-binder, jvm-compilation, jvm-gc, jvm-heap-pressure, jvm-info, jvm-memory, jvm-thread, log4j2, logback, processor, uptime |  | String
+| *camel.metrics.clearOnReload* | Clear the captured metrics data when Camel is reloading routes such as when using Camel JBang. | true | boolean
 | *camel.metrics.enabled* | To enable Micrometer metrics. | false | boolean
 | *camel.metrics.enableExchange{zwsp}EventNotifier* | Set whether to enable the MicrometerExchangeEventNotifier for capturing metrics on exchange processing times. | true | boolean
 | *camel.metrics.enableMessage{zwsp}History* | Set whether to enable the MicrometerMessageHistoryFactory for capturing metrics on individual route node processing times. Depending on the number of configured route nodes, there is the potential to create a large volume of metrics. Therefore, this option is disabled by default. | false | boolean
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MetricsConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/MetricsConfigurationProperties.java
index f5c7772149c..108c9dfc2a8 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/MetricsConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/MetricsConfigurationProperties.java
@@ -38,6 +38,8 @@ public class MetricsConfigurationProperties implements BootstrapCloseable {
     private boolean enableExchangeEventNotifier = true;
     @Metadata(defaultValue = "true")
     private boolean enableRouteEventNotifier = true;
+    @Metadata(defaultValue = "true")
+    private boolean clearOnReload = true;
     @Metadata(defaultValue = "0.0.4", enums = "0.0.4,1.0.0")
     private String textFormatVersion = "0.0.4";
     @Metadata
@@ -124,6 +126,17 @@ public class MetricsConfigurationProperties implements BootstrapCloseable {
         this.enableRouteEventNotifier = enableRouteEventNotifier;
     }
 
+    public boolean isClearOnReload() {
+        return clearOnReload;
+    }
+
+    /**
+     * Clear the captured metrics data when Camel is reloading routes such as when using Camel JBang.
+     */
+    public void setClearOnReload(boolean clearOnReload) {
+        this.clearOnReload = clearOnReload;
+    }
+
     public String getTextFormatVersion() {
         return textFormatVersion;
     }
@@ -214,6 +227,14 @@ public class MetricsConfigurationProperties implements BootstrapCloseable {
         return this;
     }
 
+    /**
+     * Clear the captured metrics data when Camel is reloading routes such as when using Camel JBang.
+     */
+    public MetricsConfigurationProperties withClearOnReload(boolean clearOnReload) {
+        this.clearOnReload = clearOnReload;
+        return this;
+    }
+
     /**
      * The text-format version to use with Prometheus scraping.
      *