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 <[email protected]> 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. *
