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 17cb3fd9c112b4abc6a161e3d2db9d5494f74cb7 Author: Claus Ibsen <[email protected]> AuthorDate: Wed Nov 15 21:01:05 2023 +0100 CAMEL-20105: camel-micromemter - Make it easier to configure for camel-main --- .../prometheus/MicrometerPrometheusConfigurer.java | 73 ++++++++++ ...nent.micrometer.prometheus.MicrometerPrometheus | 2 + .../org/apache/camel/micrometer-prometheus | 2 + .../prometheus/MicrometerPrometheus.java | 152 +++++++++++++++++++++ .../org/apache/camel/spi/CamelMetricsService.java | 27 ++++ .../org/apache/camel/main/BaseMainSupport.java | 23 +++- parent/pom.xml | 1 - 7 files changed, 278 insertions(+), 2 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 new file mode 100644 index 00000000000..2f934e1d64e --- /dev/null +++ b/components/camel-micrometer-prometheus/src/generated/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheusConfigurer.java @@ -0,0 +1,73 @@ +/* Generated by camel build tools - do NOT edit this file! */ +package org.apache.camel.component.micrometer.prometheus; + +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.spi.ExtendedPropertyConfigurerGetter; +import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.spi.ConfigurerStrategy; +import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.util.CaseInsensitiveMap; +import org.apache.camel.component.micrometer.prometheus.MicrometerPrometheus; + +/** + * Generated by camel build tools - do NOT edit this file! + */ +@SuppressWarnings("unchecked") +public class MicrometerPrometheusConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter { + + @Override + public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { + org.apache.camel.component.micrometer.prometheus.MicrometerPrometheus target = (org.apache.camel.component.micrometer.prometheus.MicrometerPrometheus) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "camelcontext": + case "CamelContext": target.setCamelContext(property(camelContext, org.apache.camel.CamelContext.class, value)); return true; + case "enableexchangeeventnotifier": + case "EnableExchangeEventNotifier": target.setEnableExchangeEventNotifier(property(camelContext, boolean.class, value)); return true; + case "enablemessagehistory": + case "EnableMessageHistory": target.setEnableMessageHistory(property(camelContext, boolean.class, value)); return true; + case "enablerouteeventnotifier": + case "EnableRouteEventNotifier": target.setEnableRouteEventNotifier(property(camelContext, boolean.class, value)); return true; + case "enableroutepolicy": + case "EnableRoutePolicy": target.setEnableRoutePolicy(property(camelContext, boolean.class, value)); return true; + default: return false; + } + } + + @Override + public Class<?> getOptionType(String name, boolean ignoreCase) { + switch (ignoreCase ? name.toLowerCase() : name) { + case "camelcontext": + case "CamelContext": return org.apache.camel.CamelContext.class; + case "enableexchangeeventnotifier": + case "EnableExchangeEventNotifier": return boolean.class; + case "enablemessagehistory": + case "EnableMessageHistory": return boolean.class; + case "enablerouteeventnotifier": + case "EnableRouteEventNotifier": return boolean.class; + case "enableroutepolicy": + case "EnableRoutePolicy": return boolean.class; + default: return null; + } + } + + @Override + public Object getOptionValue(Object obj, String name, boolean ignoreCase) { + org.apache.camel.component.micrometer.prometheus.MicrometerPrometheus target = (org.apache.camel.component.micrometer.prometheus.MicrometerPrometheus) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "camelcontext": + case "CamelContext": return target.getCamelContext(); + case "enableexchangeeventnotifier": + case "EnableExchangeEventNotifier": return target.isEnableExchangeEventNotifier(); + case "enablemessagehistory": + case "EnableMessageHistory": return target.isEnableMessageHistory(); + case "enablerouteeventnotifier": + case "EnableRouteEventNotifier": return target.isEnableRouteEventNotifier(); + case "enableroutepolicy": + case "EnableRoutePolicy": return target.isEnableRoutePolicy(); + default: return null; + } + } +} + diff --git a/components/camel-micrometer-prometheus/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.micrometer.prometheus.MicrometerPrometheus b/components/camel-micrometer-prometheus/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.micrometer.prometheus.MicrometerPrometheus new file mode 100644 index 00000000000..9f7e2f12222 --- /dev/null +++ b/components/camel-micrometer-prometheus/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.micrometer.prometheus.MicrometerPrometheus @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.component.micrometer.prometheus.MicrometerPrometheusConfigurer diff --git a/components/camel-micrometer-prometheus/src/generated/resources/META-INF/services/org/apache/camel/micrometer-prometheus b/components/camel-micrometer-prometheus/src/generated/resources/META-INF/services/org/apache/camel/micrometer-prometheus new file mode 100644 index 00000000000..aef3c09ef27 --- /dev/null +++ b/components/camel-micrometer-prometheus/src/generated/resources/META-INF/services/org/apache/camel/micrometer-prometheus @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.component.micrometer.prometheus.MicrometerPrometheus 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 new file mode 100644 index 00000000000..b6fee55cb02 --- /dev/null +++ b/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheus.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.micrometer.prometheus; + +import io.micrometer.prometheus.PrometheusConfig; +import io.micrometer.prometheus.PrometheusMeterRegistry; +import org.apache.camel.CamelContext; +import org.apache.camel.StaticService; +import org.apache.camel.api.management.ManagedResource; +import org.apache.camel.component.micrometer.eventnotifier.MicrometerExchangeEventNotifier; +import org.apache.camel.component.micrometer.eventnotifier.MicrometerRouteEventNotifier; +import org.apache.camel.component.micrometer.messagehistory.MicrometerMessageHistoryFactory; +import org.apache.camel.component.micrometer.routepolicy.MicrometerRoutePolicyFactory; +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.annotations.JdkService; +import org.apache.camel.support.service.ServiceSupport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@JdkService("micrometer-prometheus") +@Configurer +@ManagedResource(description = "Micrometer Metrics Prometheus") +public class MicrometerPrometheus extends ServiceSupport implements CamelMetricsService, StaticService { + + private static final Logger LOG = LoggerFactory.getLogger(MicrometerPrometheus.class); + + // TODO: option to configure prometheus + // TODO: context-path / port for http scrape service + + private CamelContext camelContext; + private final PrometheusMeterRegistry meterRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT); + + @Metadata(defaultValue = "true") + private boolean enableRoutePolicy = true; + @Metadata(defaultValue = "false") + private boolean enableMessageHistory; + @Metadata(defaultValue = "true") + private boolean enableExchangeEventNotifier = true; + @Metadata(defaultValue = "true") + private boolean enableRouteEventNotifier = true; + + @Override + public CamelContext getCamelContext() { + return camelContext; + } + + @Override + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + public boolean isEnableRoutePolicy() { + return enableRoutePolicy; + } + + /** + * Set whether to enable the MicrometerRoutePolicyFactory for capturing metrics on route processing times. + */ + public void setEnableRoutePolicy(boolean enableRoutePolicy) { + this.enableRoutePolicy = enableRoutePolicy; + } + + public boolean isEnableMessageHistory() { + return enableMessageHistory; + } + + /** + * 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. + */ + public void setEnableMessageHistory(boolean enableMessageHistory) { + this.enableMessageHistory = enableMessageHistory; + } + + public boolean isEnableExchangeEventNotifier() { + return enableExchangeEventNotifier; + } + + /** + * Set whether to enable the MicrometerExchangeEventNotifier for capturing metrics on exchange processing times. + */ + public void setEnableExchangeEventNotifier(boolean enableExchangeEventNotifier) { + this.enableExchangeEventNotifier = enableExchangeEventNotifier; + } + + public boolean isEnableRouteEventNotifier() { + return enableRouteEventNotifier; + } + + /** + * Set whether to enable the MicrometerRouteEventNotifier for capturing metrics on the total number of routes and + * total number of routes running. + */ + public void setEnableRouteEventNotifier(boolean enableRouteEventNotifier) { + this.enableRouteEventNotifier = enableRouteEventNotifier; + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + + if (isEnableRoutePolicy()) { + MicrometerRoutePolicyFactory factory = new MicrometerRoutePolicyFactory(); + factory.setMeterRegistry(meterRegistry); + camelContext.addRoutePolicyFactory(factory); + } + + ManagementStrategy managementStrategy = camelContext.getManagementStrategy(); + if (isEnableExchangeEventNotifier()) { + MicrometerExchangeEventNotifier notifier = new MicrometerExchangeEventNotifier(); + notifier.setMeterRegistry(meterRegistry); + managementStrategy.addEventNotifier(notifier); + } + + if (isEnableRouteEventNotifier()) { + MicrometerRouteEventNotifier notifier = new MicrometerRouteEventNotifier(); + notifier.setMeterRegistry(meterRegistry); + managementStrategy.addEventNotifier(notifier); + } + + if (isEnableMessageHistory()) { + if (!camelContext.isMessageHistory()) { + camelContext.setMessageHistory(true); + } + MicrometerMessageHistoryFactory factory = new MicrometerMessageHistoryFactory(); + factory.setMeterRegistry(meterRegistry); + camelContext.setMessageHistoryFactory(factory); + } + + LOG.info("MicrometerPrometheus enabled"); + } +} diff --git a/core/camel-api/src/generated/java/org/apache/camel/spi/CamelMetricsService.java b/core/camel-api/src/generated/java/org/apache/camel/spi/CamelMetricsService.java new file mode 100644 index 00000000000..9dcf87829c5 --- /dev/null +++ b/core/camel-api/src/generated/java/org/apache/camel/spi/CamelMetricsService.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.spi; + +import org.apache.camel.CamelContextAware; +import org.apache.camel.Service; + +/** + * A Camel metrics service is a factory for micrometer metrics. + */ +public interface CamelMetricsService extends Service, CamelContextAware { + +} diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java index fe09836d7f0..660fa08e5f6 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java @@ -57,6 +57,7 @@ import org.apache.camel.spi.AutowiredLifecycleStrategy; import org.apache.camel.spi.BacklogDebugger; import org.apache.camel.spi.CamelBeanPostProcessor; import org.apache.camel.spi.CamelEvent; +import org.apache.camel.spi.CamelMetricsService; import org.apache.camel.spi.CamelTracingService; import org.apache.camel.spi.ContextReloadStrategy; import org.apache.camel.spi.DataFormat; @@ -1420,7 +1421,13 @@ public abstract class BaseMainSupport extends BaseService { } boolean enabled = obj != null ? CamelContextHelper.parseBoolean(camelContext, obj.toString()) : true; if (enabled) { - // TODO: + CamelMetricsService micrometer = resolveMicrometerService(camelContext); + setPropertiesOnTarget(camelContext, micrometer, metricsProperties, "camel.metrics.", failIfNotSet, true, + autoConfiguredProperties); + if (camelContext.hasService(CamelMetricsService.class) == null) { + // add as service so micrometer can be active + camelContext.addService(micrometer, true, true); + } } } @@ -2079,6 +2086,20 @@ public abstract class BaseMainSupport extends BaseService { return answer; } + private static CamelMetricsService resolveMicrometerService(CamelContext camelContext) throws Exception { + CamelMetricsService answer = camelContext.hasService(CamelMetricsService.class); + if (answer == null) { + answer = camelContext.getRegistry().findSingleByType(CamelMetricsService.class); + } + if (answer == null) { + answer = camelContext.getCamelContextExtension().getBootstrapFactoryFinder() + .newInstance("micrometer-prometheus", CamelMetricsService.class) + .orElseThrow(() -> new IllegalArgumentException( + "Cannot find CamelMetricsService on classpath. Add camel-micrometer-prometheus to classpath.")); + } + return answer; + } + private static MainHttpServerFactory resolveMainHttpServerFactory(CamelContext camelContext) { // lookup in service registry first MainHttpServerFactory answer = camelContext.getRegistry().findSingleByType(MainHttpServerFactory.class); diff --git a/parent/pom.xml b/parent/pom.xml index 64734e4ad97..a5f985fc7ed 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -1752,7 +1752,6 @@ <groupId>org.apache.camel</groupId> <artifactId>camel-micrometer-prometheus</artifactId> <version>${project.version}</version> - <type>jar</type> </dependency> <dependency> <groupId>org.apache.camel</groupId>
