This is an automated email from the ASF dual-hosted git repository.
davsclaus 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 848d82b2e3c CAMEL-20105 (#12017)
848d82b2e3c is described below
commit 848d82b2e3c04f72af6d3509ad4d4faf19e000f6
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Nov 17 09:24:03 2023 +0100
CAMEL-20105 (#12017)
CAMEL-20105: camel-micromemter - Make it easier to configure for camel-main
---
bom/camel-bom/pom.xml | 5 +
catalog/camel-allcomponents/pom.xml | 5 +
.../main/camel-main-configuration-metadata.json | 12 +
.../org/apache/camel/catalog/others.properties | 1 +
.../catalog/others/micrometer-prometheus.json | 14 +
components/camel-micrometer-prometheus/pom.xml | 158 ++++++++++
.../prometheus/MicrometerPrometheusConfigurer.java | 91 ++++++
...nent.micrometer.prometheus.MicrometerPrometheus | 2 +
.../org/apache/camel/micrometer-prometheus | 2 +
.../services/org/apache/camel/other.properties | 7 +
.../generated/resources/micrometer-prometheus.json | 14 +
.../src/main/docs/micrometer-prometheus.adoc | 67 +++++
.../micrometer/prometheus/BindersHelper.java | 145 +++++++++
.../prometheus/MicrometerPrometheus.java | 333 +++++++++++++++++++++
.../src/main/docs/micrometer-component.adoc | 22 +-
.../component/micrometer/MicrometerConsole.java | 4 +
.../src/test/resources/log4j2.properties | 2 +-
.../http/main/DefaultMainHttpServerFactory.java | 1 +
.../platform/http/main/MainHttpServer.java | 13 +
components/pom.xml | 1 +
.../org/apache/camel/spi/CamelMetricsService.java | 27 ++
...ttpServerConfigurationPropertiesConfigurer.java | 6 +
.../main/LraConfigurationPropertiesConfigurer.java | 6 +
.../MetricsConfigurationPropertiesConfigurer.java | 91 ++++++
.../OtelConfigurationPropertiesConfigurer.java | 6 +
.../camel-main-configuration-metadata.json | 12 +
...pache.camel.main.MetricsConfigurationProperties | 2 +
core/camel-main/src/main/docs/main.adoc | 26 +-
.../org/apache/camel/main/BaseMainSupport.java | 49 +++
.../main/HttpServerConfigurationProperties.java | 20 ++
.../camel/main/LraConfigurationProperties.java | 21 ++
.../camel/main/MainConfigurationProperties.java | 22 ++
.../camel/main/MetricsConfigurationProperties.java | 241 +++++++++++++++
.../camel/main/OtelConfigurationProperties.java | 20 ++
parent/pom.xml | 12 +-
.../maven/packaging/PrepareCamelMainMojo.java | 5 +
36 files changed, 1459 insertions(+), 6 deletions(-)
diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index b45cae86a79..9a4412c8125 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -1347,6 +1347,11 @@
<artifactId>camel-micrometer</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-micrometer-prometheus</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-microprofile-config</artifactId>
diff --git a/catalog/camel-allcomponents/pom.xml
b/catalog/camel-allcomponents/pom.xml
index 8934ec40a3e..4f900d74593 100644
--- a/catalog/camel-allcomponents/pom.xml
+++ b/catalog/camel-allcomponents/pom.xml
@@ -1152,6 +1152,11 @@
<artifactId>camel-micrometer</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-micrometer-prometheus</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-microprofile-config</artifactId>
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index 3a89ff173c1..6994a0ad04f 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -11,6 +11,7 @@
{ "name": "camel.vault.gcp", "description": "Camel GCP Vault
configurations", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration" },
{ "name": "camel.vault.azure", "description": "Camel Azure Key Vault
configurations", "sourceType": "org.apache.camel.vault.AzureVaultConfiguration"
},
{ "name": "camel.opentelemetry", "description": "Camel OpenTelemtry
configurations", "sourceType":
"org.apache.camel.main.OtelConfigurationProperties" },
+ { "name": "camel.metrics", "description": "Camel Micrometer Metrics
configurations", "sourceType":
"org.apache.camel.main.MetricsConfigurationProperties" },
{ "name": "camel.faulttolerance", "description": "Fault Tolerance EIP
Circuit Breaker configurations", "sourceType":
"org.apache.camel.main.FaultToleranceConfigurationProperties" },
{ "name": "camel.resilience4j", "description": "Resilience4j EIP Circuit
Breaker configurations", "sourceType":
"org.apache.camel.main.Resilience4jConfigurationProperties" },
{ "name": "camel.lra", "description": "Camel Saga EIP (Long Running
Actions) configurations", "sourceType":
"org.apache.camel.main.LraConfigurationProperties" }
@@ -176,8 +177,18 @@
{ "name": "camel.health.routesEnabled", "description": "Whether routes
health check is enabled", "sourceType":
"org.apache.camel.main.HealthConfigurationProperties", "type": "boolean",
"javaType": "java.lang.Boolean", "defaultValue": true },
{ "name": "camel.lra.coordinatorContextPath", "description": "The
context-path for the LRA coordinator. Is default \/lra-coordinator",
"sourceType": "org.apache.camel.main.LraConfigurationProperties", "type":
"string", "javaType": "java.lang.String", "defaultValue": "\/lra-coordinator" },
{ "name": "camel.lra.coordinatorUrl", "description": "The URL for the LRA
coordinator service that orchestrates the transactions", "sourceType":
"org.apache.camel.main.LraConfigurationProperties", "type": "string",
"javaType": "java.lang.String" },
+ { "name": "camel.lra.enabled", "description": "To enable Saga LRA",
"sourceType": "org.apache.camel.main.LraConfigurationProperties", "type":
"boolean", "javaType": "boolean", "defaultValue": false },
{ "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: cache-meter-binder, class-loader,
commons-object-pool2, database-table, disk-space, executor-service,
file-descriptor, hystrix-metrics-binder, jetty-server-thread-pool,
jvm-compilation, jvm-gc, jvm-heap-pressure, jvm-info, jvm-memory [...]
+ { "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" },
+ { "name": "camel.metrics.enableRouteEventNotifier", "description": "Set
whether to enable the MicrometerRouteEventNotifier for capturing metrics on the
total number of routes and total number of routes running.", "sourceType":
"org.apache.camel.main.MetricsConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": true },
+ { "name": "camel.metrics.enableRoutePolicy", "description": "Set whether
to enable the MicrometerRoutePolicyFactory for capturing metrics on route
processing times.", "sourceType":
"org.apache.camel.main.MetricsConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": true },
+ { "name": "camel.metrics.namingStrategy", "description": "Controls the
name style to use for metrics. Default = uses micrometer naming convention.
Legacy = uses the classic naming style (camelCase)", "sourceType":
"org.apache.camel.main.MetricsConfigurationProperties", "type": "string",
"javaType": "java.lang.String", "defaultValue": "default", "enum": [ "default",
"legacy" ] },
+ { "name": "camel.metrics.textFormatVersion", "description": "The
text-format version to use with Prometheus scraping. 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", "sourceType":
"org.apache.camel.main.MetricsConfigurationProperties", "type": "string",
"javaType": "java.lang.String", "defaultValue": "0.0.4", "enum": [ "0.0.4",
"1.0.0" ] },
+ { "name": "camel.opentelemetry.enabled", "description": "To enable
OpenTelemetry", "sourceType":
"org.apache.camel.main.OtelConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.opentelemetry.encoding", "description": "Sets whether the
header keys need to be encoded (connector specific) or not. The value is a
boolean. Dashes need for instances to be encoded for JMS property keys.",
"sourceType": "org.apache.camel.main.OtelConfigurationProperties", "type":
"boolean", "javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.opentelemetry.excludePatterns", "description": "Adds an
exclude pattern that will disable tracing for Camel messages that matches the
pattern. Multiple patterns can be separated by comma.", "sourceType":
"org.apache.camel.main.OtelConfigurationProperties", "type": "string",
"javaType": "java.lang.String" },
{ "name": "camel.opentelemetry.instrumentationName", "description": "A
name uniquely identifying the instrumentation scope, such as the
instrumentation library, package, or fully qualified class name. Must not be
null.", "sourceType": "org.apache.camel.main.OtelConfigurationProperties",
"type": "string", "javaType": "java.lang.String", "defaultValue": "camel" },
@@ -234,6 +245,7 @@
{ "name": "camel.server.healthCheckEnabled", "description": "Whether to
enable health-check console. If enabled then you can access health-check status
on context-path: \/q\/health", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.host", "description": "Hostname to use for binding
embedded HTTP server", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "string",
"javaType": "java.lang.String", "defaultValue": "0.0.0.0" },
{ "name": "camel.server.maxBodySize", "description": "Maximum HTTP body
size the embedded HTTP server can accept.", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "integer",
"javaType": "java.lang.Long" },
+ { "name": "camel.server.metricsEnabled", "description": "Whether to enable
metrics. If enabled then you can access metrics on context-path: \/q\/metrics",
"sourceType": "org.apache.camel.main.HttpServerConfigurationProperties",
"type": "boolean", "javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.path", "description": "Context-path to use for
embedded HTTP server", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "string",
"javaType": "java.lang.String", "defaultValue": "\/" },
{ "name": "camel.server.port", "description": "Port to use for binding
embedded HTTP server", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "integer",
"javaType": "int", "defaultValue": 8080 },
{ "name": "camel.server.uploadEnabled", "description": "Whether to enable
file upload via HTTP (not intended for production use). This functionality is
for development to be able to reload Camel routes and code with source changes
(if reload is enabled). If enabled then you can upload\/delete files via HTTP
PUT\/DELETE on context-path: \/q\/upload\/{name}. You must also configure the
uploadSourceDir option.", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "t [...]
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
index 17cedb8b02b..ff8f24f02ba 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
@@ -27,6 +27,7 @@ lra
mail-microsoft-oauth
main
management
+micrometer-prometheus
microprofile-config
microprofile-fault-tolerance
microprofile-health
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/micrometer-prometheus.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/micrometer-prometheus.json
new file mode 100644
index 00000000000..429ab2db753
--- /dev/null
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/micrometer-prometheus.json
@@ -0,0 +1,14 @@
+{
+ "other": {
+ "kind": "other",
+ "name": "micrometer-prometheus",
+ "title": "Micrometer Prometheus",
+ "description": "Camel Micrometer Prometheus for Camel Main",
+ "deprecated": false,
+ "firstVersion": "4.3.0",
+ "supportLevel": "Preview",
+ "groupId": "org.apache.camel",
+ "artifactId": "camel-micrometer-prometheus",
+ "version": "4.3.0-SNAPSHOT"
+ }
+}
diff --git a/components/camel-micrometer-prometheus/pom.xml
b/components/camel-micrometer-prometheus/pom.xml
new file mode 100644
index 00000000000..fbd6e5eb89f
--- /dev/null
+++ b/components/camel-micrometer-prometheus/pom.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>components</artifactId>
+ <version>4.3.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-micrometer-prometheus</artifactId>
+ <packaging>jar</packaging>
+ <name>Camel :: Micrometer Prometheus</name>
+ <description>Camel Micrometer Prometheus for Camel Main</description>
+
+ <properties>
+ <firstVersion>4.3.0</firstVersion>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-micrometer</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-platform-http-main</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>io.micrometer</groupId>
+ <artifactId>micrometer-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.micrometer</groupId>
+ <artifactId>micrometer-registry-prometheus</artifactId>
+ </dependency>
+ <!-- to load micrometer binders -->
+ <dependency>
+ <groupId>io.smallrye</groupId>
+ <artifactId>jandex</artifactId>
+ <version>${jandex-version}</version>
+ </dependency>
+
+ <!-- testing -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-junit5</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-management</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-spring-junit5</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <artifactId>hamcrest-core</artifactId>
+ <groupId>org.hamcrest</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest</artifactId>
+ <version>${hamcrest-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>${assertj-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <version>${awaitility-version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <!-- generate jandex index for all the micrometer binders that can
be enabled -->
+ <plugin>
+ <groupId>io.smallrye</groupId>
+ <artifactId>jandex-maven-plugin</artifactId>
+ <version>${jandex-version}</version>
+ <executions>
+ <execution>
+ <id>make-index</id>
+ <goals>
+ <goal>jandex</goal>
+ </goals>
+ <configuration>
+ <indexName>micrometer-binder-index.dat</indexName>
+ <fileSets>
+ <fileSet>
+ <dependency>
+ <groupId>io.micrometer</groupId>
+
<artifactId>micrometer-core</artifactId>
+ </dependency>
+ <includes>
+
<include>io/micrometer/core/instrument/binder/**/*.class</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- generate a list of known binders -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>${exec-maven-plugin-version}</version>
+ <configuration>
+
<mainClass>org.apache.camel.component.micrometer.prometheus.BindersHelper</mainClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
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..479105554d7
--- /dev/null
+++
b/components/camel-micrometer-prometheus/src/generated/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheusConfigurer.java
@@ -0,0 +1,91 @@
+/* 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 "binders":
+ 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 "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;
+ case "namingstrategy":
+ case "NamingStrategy": target.setNamingStrategy(property(camelContext,
java.lang.String.class, value)); return true;
+ case "textformatversion":
+ case "TextFormatVersion":
target.setTextFormatVersion(property(camelContext, java.lang.String.class,
value)); return true;
+ default: return false;
+ }
+ }
+
+ @Override
+ public Class<?> getOptionType(String name, boolean ignoreCase) {
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "binders":
+ case "Binders": return java.lang.String.class;
+ 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;
+ case "namingstrategy":
+ case "NamingStrategy": return java.lang.String.class;
+ case "textformatversion":
+ case "TextFormatVersion": return java.lang.String.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 "binders":
+ case "Binders": return target.getBinders();
+ 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();
+ case "namingstrategy":
+ case "NamingStrategy": return target.getNamingStrategy();
+ case "textformatversion":
+ case "TextFormatVersion": return target.getTextFormatVersion();
+ 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/generated/resources/META-INF/services/org/apache/camel/other.properties
b/components/camel-micrometer-prometheus/src/generated/resources/META-INF/services/org/apache/camel/other.properties
new file mode 100644
index 00000000000..5c5e29db9e2
--- /dev/null
+++
b/components/camel-micrometer-prometheus/src/generated/resources/META-INF/services/org/apache/camel/other.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+name=micrometer-prometheus
+groupId=org.apache.camel
+artifactId=camel-micrometer-prometheus
+version=4.3.0-SNAPSHOT
+projectName=Camel :: Micrometer Prometheus
+projectDescription=Camel Micrometer Prometheus for Camel Main
diff --git
a/components/camel-micrometer-prometheus/src/generated/resources/micrometer-prometheus.json
b/components/camel-micrometer-prometheus/src/generated/resources/micrometer-prometheus.json
new file mode 100644
index 00000000000..429ab2db753
--- /dev/null
+++
b/components/camel-micrometer-prometheus/src/generated/resources/micrometer-prometheus.json
@@ -0,0 +1,14 @@
+{
+ "other": {
+ "kind": "other",
+ "name": "micrometer-prometheus",
+ "title": "Micrometer Prometheus",
+ "description": "Camel Micrometer Prometheus for Camel Main",
+ "deprecated": false,
+ "firstVersion": "4.3.0",
+ "supportLevel": "Preview",
+ "groupId": "org.apache.camel",
+ "artifactId": "camel-micrometer-prometheus",
+ "version": "4.3.0-SNAPSHOT"
+ }
+}
diff --git
a/components/camel-micrometer-prometheus/src/main/docs/micrometer-prometheus.adoc
b/components/camel-micrometer-prometheus/src/main/docs/micrometer-prometheus.adoc
new file mode 100644
index 00000000000..747b3b88530
--- /dev/null
+++
b/components/camel-micrometer-prometheus/src/main/docs/micrometer-prometheus.adoc
@@ -0,0 +1,67 @@
+= Micrometer Prometheus Component
+:doctitle: Micrometer Prometheus
+:shortname: micrometer-prometheus
+:artifactid: camel-micrometer-prometheus
+:description: Camel Micrometer Prometheus for Camel Main
+:since: 4.3
+:supportlevel: Preview
+:tabs-sync-option:
+
+*Since Camel {since}*
+
+The camel-micrometer-prometheus is used for running Camel standalone
(camel-main) and integrate with Micrometer Prometheus Registry.
+
+== Auto-detection from classpath
+
+To use this implementation all you need to do is to add the
`camel-micrometer-prometheus` dependency to the classpath,
+and turn on metrics in `application.properties` such as:
+
+[source,properties]
+----
+# enable HTTP server with metrics
+camel.server.enabled=true
+camel.server.metricsEnabled=true
+
+# turn on micrometer metrics
+camel.metrics.enabled=true
+# include more camel details
+camel.metrics.enableMessageHistory=true
+# include additional out-of-the-box micrometer metrics for cpu, jvm and used
file descriptors
+camel.metrics.binders=processor,jvm-info,file-descriptor
+----
+
+== List of known binders from Micrometer
+
+The following binders can be configured with `camel.metrics.binders` that
comes out of the box from Micrometer:
+
+|====
+|Binder Name
+
+| cache-meter-binder
+| class-loader
+| commons-object-pool2
+| database-table
+| disk-space
+| executor-service
+| file-descriptor
+| hystrix-metrics-binder
+| jetty-server-thread-pool
+| jvm-compilation
+| jvm-gc
+| jvm-heap-pressure
+| jvm-info
+| jvm-memory
+| jvm-thread
+| kafka
+| log4j2
+| logback
+| netty-allocator
+| netty-event-executor
+| ok-http-connection-pool
+| pooling-http-client-connection-manager-metrics-binder
+| postgre-sql-database
+| processor
+| tomcat
+| uptime
+
+|====
\ No newline at end of file
diff --git
a/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/BindersHelper.java
b/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/BindersHelper.java
new file mode 100644
index 00000000000..77e07eb0dcb
--- /dev/null
+++
b/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/BindersHelper.java
@@ -0,0 +1,145 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.TreeSet;
+
+import io.micrometer.core.instrument.binder.MeterBinder;
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.engine.DefaultClassResolver;
+import org.apache.camel.spi.ClassResolver;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.StringHelper;
+import org.jboss.jandex.ClassInfo;
+import org.jboss.jandex.DotName;
+import org.jboss.jandex.Index;
+import org.jboss.jandex.IndexReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class BindersHelper {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(BindersHelper.class);
+ private static final String JANDEX_INDEX =
"META-INF/micrometer-binder-index.dat";
+
+ private BindersHelper() {
+ }
+
+ public static void main(String[] args) throws Exception {
+ Set<String> answer = new TreeSet<>();
+
+ Index index = readJandexIndex(new DefaultClassResolver());
+ if (index == null) {
+ System.out.println("Cannot read " + JANDEX_INDEX + " with list of
known MeterBinder classes");
+ } else {
+ DotName dn = DotName.createSimple(MeterBinder.class);
+ List<ClassInfo> classes = index.getKnownDirectImplementors(dn);
+ for (ClassInfo info : classes) {
+ boolean deprecated = info.hasAnnotation(Deprecated.class);
+ if (deprecated) {
+ // skip deprecated
+ continue;
+ }
+ String name = info.name().local();
+ if (name.endsWith("Metrics")) {
+ name = name.substring(0, name.length() - 7);
+ }
+ name = StringHelper.camelCaseToDash(name);
+ answer.add(name);
+ }
+ }
+
+ StringJoiner sj = new StringJoiner(", ");
+ answer.forEach(sj::add);
+ System.out.println(sj);
+ }
+
+ public static List<String> discoverBinders(ClassResolver classResolver,
String names) throws IOException {
+ List<String> answer = new ArrayList<>();
+
+ LOG.debug("Loading {}", JANDEX_INDEX);
+ Index index = readJandexIndex(classResolver);
+ if (index == null) {
+ LOG.warn("Cannot read {} with list of known MeterBinder classes",
JANDEX_INDEX);
+ } else {
+ DotName dn = DotName.createSimple(MeterBinder.class);
+ List<ClassInfo> classes = index.getKnownDirectImplementors(dn);
+ LOG.debug("Found {} MeterBinder classes from {}", classes.size(),
JANDEX_INDEX);
+
+ for (String binder : names.split(",")) {
+ binder = binder.trim();
+ binder = StringHelper.dashToCamelCase(binder);
+ binder = binder.toLowerCase();
+
+ final String target = binder;
+ Optional<ClassInfo> found = classes.stream()
+ // use naming convention with and without metrics
+ .filter(c ->
c.name().local().toLowerCase().equals(target)
+ ||
c.name().local().toLowerCase().equals(target + "metrics"))
+ .findFirst();
+
+ if (found.isPresent()) {
+ String fqn = found.get().name().toString();
+ answer.add(fqn);
+ }
+ }
+ }
+
+ return answer;
+ }
+
+ public static List<MeterBinder> loadBinders(CamelContext camelContext,
List<String> binders) {
+ List<MeterBinder> answer = new ArrayList<>();
+
+ for (String fqn : binders) {
+ LOG.debug("Creating MeterBinder: {}", fqn);
+ try {
+ Class<MeterBinder> clazz =
camelContext.getClassResolver().resolveClass(fqn, MeterBinder.class);
+ MeterBinder mb = camelContext.getInjector().newInstance(clazz);
+ if (mb != null) {
+ answer.add(mb);
+ }
+ } catch (Exception e) {
+ LOG.warn("Error creating MeterBinder: {} due to: {}. This
exception is ignored.", fqn, e.getMessage(),
+ e);
+ }
+ }
+
+ return answer;
+ }
+
+ public static Index readJandexIndex(ClassResolver classResolver) throws
IOException {
+ InputStream is =
classResolver.loadResourceAsStream("META-INF/micrometer-binder-index.dat");
+ try {
+ if (is != null) {
+ IndexReader reader = new IndexReader(is);
+ return reader.read();
+ }
+ } finally {
+ IOHelper.close(is);
+ }
+ return null;
+ }
+
+}
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..caf848ba3f2
--- /dev/null
+++
b/components/camel-micrometer-prometheus/src/main/java/org/apache/camel/component/micrometer/prometheus/MicrometerPrometheus.java
@@ -0,0 +1,333 @@
+/*
+ * 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 java.io.Closeable;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.StringJoiner;
+
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.binder.MeterBinder;
+import io.micrometer.prometheus.PrometheusConfig;
+import io.micrometer.prometheus.PrometheusMeterRegistry;
+import io.prometheus.client.exporter.common.TextFormat;
+import io.vertx.core.Handler;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.ext.web.Route;
+import io.vertx.ext.web.RoutingContext;
+import io.vertx.ext.web.impl.BlockingHandlerDecorator;
+import org.apache.camel.CamelContext;
+import org.apache.camel.StaticService;
+import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.component.micrometer.MicrometerConstants;
+import org.apache.camel.component.micrometer.MicrometerUtils;
+import
org.apache.camel.component.micrometer.eventnotifier.MicrometerExchangeEventNotifier;
+import
org.apache.camel.component.micrometer.eventnotifier.MicrometerExchangeEventNotifierNamingStrategy;
+import
org.apache.camel.component.micrometer.eventnotifier.MicrometerRouteEventNotifier;
+import
org.apache.camel.component.micrometer.eventnotifier.MicrometerRouteEventNotifierNamingStrategy;
+import
org.apache.camel.component.micrometer.messagehistory.MicrometerMessageHistoryFactory;
+import
org.apache.camel.component.micrometer.messagehistory.MicrometerMessageHistoryNamingStrategy;
+import
org.apache.camel.component.micrometer.routepolicy.MicrometerRoutePolicyFactory;
+import
org.apache.camel.component.micrometer.routepolicy.MicrometerRoutePolicyNamingStrategy;
+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.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.service.ServiceSupport;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ObjectHelper;
+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);
+
+ private MainHttpServer server;
+ private VertxPlatformHttpRouter router;
+ private PlatformHttpComponent platformHttpComponent;
+
+ private CamelContext camelContext;
+ private PrometheusMeterRegistry meterRegistry;
+ private final Set<MeterBinder> createdBinders = new HashSet<>();
+
+ @Metadata(defaultValue = "default", enums = "default,legacy")
+ private String namingStrategy;
+ @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;
+ @Metadata(defaultValue = "0.0.4", enums = "0.0.4,1.0.0")
+ private String textFormatVersion = "0.0.4";
+ @Metadata
+ private String binders;
+
+ @Override
+ public CamelContext getCamelContext() {
+ return camelContext;
+ }
+
+ @Override
+ public void setCamelContext(CamelContext camelContext) {
+ this.camelContext = camelContext;
+ }
+
+ public String getNamingStrategy() {
+ return namingStrategy;
+ }
+
+ /**
+ * Controls the name style to use for metrics.
+ *
+ * Default = uses micrometer naming convention. Legacy = uses the classic
naming style (camelCase)
+ */
+ public void setNamingStrategy(String namingStrategy) {
+ this.namingStrategy = namingStrategy;
+ }
+
+ 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;
+ }
+
+ public String getTextFormatVersion() {
+ return textFormatVersion;
+ }
+
+ /**
+ * The text-format version to use with Prometheus scraping.
+ *
+ * 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
+ */
+ public void setTextFormatVersion(String textFormatVersion) {
+ this.textFormatVersion = textFormatVersion;
+ }
+
+ public String getBinders() {
+ return 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:
+ * cache-meter-binder, class-loader, commons-object-pool2, database-table,
disk-space, executor-service, file-descriptor, hystrix-metrics-binder,
jetty-server-thread-pool, jvm-compilation, jvm-gc, jvm-heap-pressure, jvm-info,
jvm-memory, jvm-thread, kafka, log4j2, logback, netty-allocator,
netty-event-executor, ok-http-connection-pool,
pooling-http-client-connection-manager-metrics-binder, postgre-sql-database,
processor, tomcat, uptime
+ */
+ public void setBinders(String binders) {
+ this.binders = binders;
+ }
+
+ @Override
+ protected void doInit() throws Exception {
+ super.doInit();
+
+ if (meterRegistry == null) {
+ Registry camelRegistry = getCamelContext().getRegistry();
+ MeterRegistry found =
MicrometerUtils.getMeterRegistryFromCamelRegistry(camelRegistry,
+ MicrometerConstants.METRICS_REGISTRY_NAME);
+ if (found == null) {
+ found = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
+ // enlist in registry so it can be reused
+ camelRegistry.bind(MicrometerConstants.METRICS_REGISTRY_NAME,
found);
+ }
+ if (!(found instanceof PrometheusMeterRegistry)) {
+ throw new IllegalArgumentException(
+ "Existing MeterRegistry: " +
found.getClass().getName() + " is not a PrometheusMeterRegistry type.");
+ }
+ meterRegistry = (PrometheusMeterRegistry) found;
+ }
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ super.doStart();
+
+ if (ObjectHelper.isNotEmpty(binders)) {
+ // load binders from micrometer
+ initBinders();
+ }
+
+ if (isEnableRoutePolicy()) {
+ MicrometerRoutePolicyFactory factory = new
MicrometerRoutePolicyFactory();
+ if ("legacy".equalsIgnoreCase(namingStrategy)) {
+
factory.setNamingStrategy(MicrometerRoutePolicyNamingStrategy.LEGACY);
+ }
+ factory.setMeterRegistry(meterRegistry);
+ camelContext.addRoutePolicyFactory(factory);
+ }
+
+ ManagementStrategy managementStrategy =
camelContext.getManagementStrategy();
+ if (isEnableExchangeEventNotifier()) {
+ MicrometerExchangeEventNotifier notifier = new
MicrometerExchangeEventNotifier();
+ if ("legacy".equalsIgnoreCase(namingStrategy)) {
+
notifier.setNamingStrategy(MicrometerExchangeEventNotifierNamingStrategy.LEGACY);
+ }
+ notifier.setMeterRegistry(meterRegistry);
+ managementStrategy.addEventNotifier(notifier);
+ }
+
+ if (isEnableRouteEventNotifier()) {
+ MicrometerRouteEventNotifier notifier = new
MicrometerRouteEventNotifier();
+ if ("legacy".equalsIgnoreCase(namingStrategy)) {
+
notifier.setNamingStrategy(MicrometerRouteEventNotifierNamingStrategy.LEGACY);
+ }
+ notifier.setMeterRegistry(meterRegistry);
+ managementStrategy.addEventNotifier(notifier);
+ }
+
+ if (isEnableMessageHistory()) {
+ if (!camelContext.isMessageHistory()) {
+ camelContext.setMessageHistory(true);
+ }
+ MicrometerMessageHistoryFactory factory = new
MicrometerMessageHistoryFactory();
+ if ("legacy".equalsIgnoreCase(namingStrategy)) {
+
factory.setNamingStrategy(MicrometerMessageHistoryNamingStrategy.LEGACY);
+ }
+ factory.setMeterRegistry(meterRegistry);
+ camelContext.setMessageHistoryFactory(factory);
+ }
+
+ server = camelContext.hasService(MainHttpServer.class);
+ router = VertxPlatformHttpRouter.lookup(camelContext);
+ platformHttpComponent = camelContext.getComponent("platform-http",
PlatformHttpComponent.class);
+
+ if (server != null && server.isMetricsEnabled() && router != null &&
platformHttpComponent != null) {
+ setupHttpScraper();
+ LOG.info("MicrometerPrometheus enabled with HTTP scraping on
/q/metrics");
+ } else {
+ LOG.info("MicrometerPrometheus enabled");
+ }
+ }
+
+ private void initBinders() throws IOException {
+ List<String> names =
BindersHelper.discoverBinders(camelContext.getClassResolver(), binders);
+ List<MeterBinder> binders = BindersHelper.loadBinders(camelContext,
names);
+
+ StringJoiner sj = new StringJoiner(", ");
+ for (MeterBinder mb : binders) {
+ mb.bindTo(meterRegistry);
+ createdBinders.add(mb);
+ sj.add(mb.getClass().getSimpleName());
+ }
+ if (!createdBinders.isEmpty()) {
+ LOG.info("Registered {} MeterBinders: {}", createdBinders.size(),
sj);
+ }
+ }
+
+ @Override
+ protected void doShutdown() throws Exception {
+ super.doShutdown();
+
+ for (MeterBinder mb : createdBinders) {
+ if (mb instanceof Closeable ac) {
+ IOHelper.close(ac);
+ }
+ }
+ createdBinders.clear();
+ }
+
+ protected void setupHttpScraper() {
+ Route metrics = router.route("/q/metrics");
+ metrics.method(HttpMethod.GET);
+
+ final String format
+ = "0.0.4".equals(textFormatVersion) ?
TextFormat.CONTENT_TYPE_004 : TextFormat.CONTENT_TYPE_OPENMETRICS_100;
+ metrics.produces(format);
+
+ Handler<RoutingContext> handler = new Handler<RoutingContext>() {
+ @Override
+ public void handle(RoutingContext ctx) {
+ String ct = format;
+ // the client may ask for version 1.0.0 via accept header
+ String ah = ctx.request().getHeader("Accept");
+ if (ah != null && ah.contains("application/openmetrics-text"))
{
+ ct = TextFormat.chooseContentType(ah);
+ }
+
+ ctx.response().putHeader("Content-Type", ct);
+ String data = meterRegistry.scrape(ct);
+ ctx.end(data);
+ }
+ };
+
+ // use blocking handler as the task can take longer time to complete
+ metrics.handler(new BlockingHandlerDecorator(handler, true));
+
+ platformHttpComponent.addHttpEndpoint("/q/metrics", null, null);
+ }
+}
diff --git
a/components/camel-micrometer/src/main/docs/micrometer-component.adoc
b/components/camel-micrometer/src/main/docs/micrometer-component.adoc
index 95efd3cd209..4326d9173b4 100644
--- a/components/camel-micrometer/src/main/docs/micrometer-component.adoc
+++ b/components/camel-micrometer/src/main/docs/micrometer-component.adoc
@@ -559,9 +559,29 @@ CDI::
The `HierarchicalNameMapper` strategy determines how meter name and tags are
assembled into an MBean name.
+== Using Camel Micrometer with Camel Main
+
+When you use Camel standalone (`camel-main`), then if you need to expose
metrics for Prometheus, then you can use `camel-micrometer-prometheus` JAR.
+And easily enable and configure this from `application.properties` as shown:
+
+[source,properties]
+----
+# enable HTTP server with metrics
+camel.server.enabled=true
+camel.server.metricsEnabled=true
+
+# turn on micrometer metrics
+camel.metrics.enabled=true
+# include more camel details
+camel.metrics.enableMessageHistory=true
+# include additional out-of-the-box micrometer metrics for cpu, jvm and used
file descriptors
+camel.metrics.binders=processor,jvm-info,file-descriptor
+----
+
+
== Using Camel Micrometer with Spring Boot
-When you use `camel-micrometer-starter` with Spring Boot, then Spring Boot
auto- configuration will automatically enable metrics capture if a
`io.micrometer.core.instrument.MeterRegistry` is available.
+When you use `camel-micrometer-starter` with Spring Boot, then Spring Boot
auto configuration will automatically enable metrics capture if a
`io.micrometer.core.instrument.MeterRegistry` is available.
For example to capture data with Prometheus, you can add the following
dependency:
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 559b1ff76fc..4c87e4ada99 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,6 +45,8 @@ public class MicrometerConsole extends AbstractDevConsole {
StringBuilder sb = new StringBuilder();
MeterRegistry mr = lookupMeterRegistry();
+ sb.append(String.format("MeterRegistry: %s\n",
mr.getClass().getName()));
+
int i = 0;
for (Meter m : mr.getMeters()) {
if (m instanceof Counter) {
@@ -133,6 +135,8 @@ public class MicrometerConsole extends AbstractDevConsole {
JsonObject root = new JsonObject();
MeterRegistry mr = lookupMeterRegistry();
+ root.put("meterRegistryClass", mr.getClass().getName());
+
int i = 0;
List<JsonObject> list = new ArrayList<>();
for (Meter m : mr.getMeters()) {
diff --git a/components/camel-micrometer/src/test/resources/log4j2.properties
b/components/camel-micrometer/src/test/resources/log4j2.properties
index 821d95af17d..c66346429d7 100644
--- a/components/camel-micrometer/src/test/resources/log4j2.properties
+++ b/components/camel-micrometer/src/test/resources/log4j2.properties
@@ -17,7 +17,7 @@
appender.file.type = File
appender.file.name = file
-appender.file.fileName = target/camel-test-metrics.log
+appender.file.fileName = target/camel-test-micrometer.log
appender.file.layout.type = PatternLayout
appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
appender.out.type = Console
diff --git
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java
index f5bac97f9ec..967e536ba6b 100644
---
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java
+++
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java
@@ -53,6 +53,7 @@ public class DefaultMainHttpServerFactory implements
CamelContextAware, MainHttp
server.setUseGlobalSslContextParameters(configuration.isUseGlobalSslContextParameters());
server.setDevConsoleEnabled(configuration.isDevConsoleEnabled());
server.setHealthCheckEnabled(configuration.isHealthCheckEnabled());
+ server.setMetricsEnabled(configuration.isMetricsEnabled());
server.setUploadEnabled(configuration.isUploadEnabled());
server.setUploadSourceDir(configuration.getUploadSourceDir());
diff --git
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
index e80cf310cc3..0738a279265 100644
---
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
+++
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
@@ -81,6 +81,7 @@ public class MainHttpServer extends ServiceSupport implements
CamelContextAware,
private VertxPlatformHttpServerConfiguration configuration = new
VertxPlatformHttpServerConfiguration();
private boolean devConsoleEnabled;
private boolean healthCheckEnabled;
+ private boolean metricsEnabled;
private boolean uploadEnabled;
private String uploadSourceDir;
@@ -124,6 +125,17 @@ public class MainHttpServer extends ServiceSupport
implements CamelContextAware,
this.healthCheckEnabled = healthCheckEnabled;
}
+ public boolean isMetricsEnabled() {
+ return metricsEnabled;
+ }
+
+ /**
+ * Whether metrics is enabled (q/metrics)
+ */
+ public void setMetricsEnabled(boolean metricsEnabled) {
+ this.metricsEnabled = metricsEnabled;
+ }
+
public boolean isUploadEnabled() {
return uploadEnabled;
}
@@ -241,6 +253,7 @@ public class MainHttpServer extends ServiceSupport
implements CamelContextAware,
}
setupUploadConsole(uploadSourceDir);
}
+ // metrics will be setup in camel-micrometer-prometheus
}
protected void setupStartupSummary() throws Exception {
diff --git a/components/pom.xml b/components/pom.xml
index 1998de8521e..4c6883bf99c 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -205,6 +205,7 @@
<module>camel-mapstruct</module>
<module>camel-metrics</module>
<module>camel-micrometer</module>
+ <module>camel-micrometer-prometheus</module>
<module>camel-microprofile</module>
<module>camel-mina</module>
<module>camel-minio</module>
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/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java
b/core/camel-main/src/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java
index 07c8e29295b..7479623930b 100644
---
a/core/camel-main/src/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java
+++
b/core/camel-main/src/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java
@@ -31,6 +31,8 @@ public class HttpServerConfigurationPropertiesConfigurer
extends org.apache.came
case "Host": target.setHost(property(camelContext,
java.lang.String.class, value)); return true;
case "maxbodysize":
case "MaxBodySize": target.setMaxBodySize(property(camelContext,
java.lang.Long.class, value)); return true;
+ case "metricsenabled":
+ case "MetricsEnabled": target.setMetricsEnabled(property(camelContext,
boolean.class, value)); return true;
case "path":
case "Path": target.setPath(property(camelContext,
java.lang.String.class, value)); return true;
case "port":
@@ -58,6 +60,8 @@ public class HttpServerConfigurationPropertiesConfigurer
extends org.apache.came
case "Host": return java.lang.String.class;
case "maxbodysize":
case "MaxBodySize": return java.lang.Long.class;
+ case "metricsenabled":
+ case "MetricsEnabled": return boolean.class;
case "path":
case "Path": return java.lang.String.class;
case "port":
@@ -86,6 +90,8 @@ public class HttpServerConfigurationPropertiesConfigurer
extends org.apache.came
case "Host": return target.getHost();
case "maxbodysize":
case "MaxBodySize": return target.getMaxBodySize();
+ case "metricsenabled":
+ case "MetricsEnabled": return target.isMetricsEnabled();
case "path":
case "Path": return target.getPath();
case "port":
diff --git
a/core/camel-main/src/generated/java/org/apache/camel/main/LraConfigurationPropertiesConfigurer.java
b/core/camel-main/src/generated/java/org/apache/camel/main/LraConfigurationPropertiesConfigurer.java
index 106befdd04b..e34dc0a7610 100644
---
a/core/camel-main/src/generated/java/org/apache/camel/main/LraConfigurationPropertiesConfigurer.java
+++
b/core/camel-main/src/generated/java/org/apache/camel/main/LraConfigurationPropertiesConfigurer.java
@@ -25,6 +25,8 @@ public class LraConfigurationPropertiesConfigurer extends
org.apache.camel.suppo
case "CoordinatorContextPath":
target.setCoordinatorContextPath(property(camelContext, java.lang.String.class,
value)); return true;
case "coordinatorurl":
case "CoordinatorUrl": target.setCoordinatorUrl(property(camelContext,
java.lang.String.class, value)); return true;
+ case "enabled":
+ case "Enabled": target.setEnabled(property(camelContext,
boolean.class, value)); return true;
case "localparticipantcontextpath":
case "LocalParticipantContextPath":
target.setLocalParticipantContextPath(property(camelContext,
java.lang.String.class, value)); return true;
case "localparticipanturl":
@@ -40,6 +42,8 @@ public class LraConfigurationPropertiesConfigurer extends
org.apache.camel.suppo
case "CoordinatorContextPath": return java.lang.String.class;
case "coordinatorurl":
case "CoordinatorUrl": return java.lang.String.class;
+ case "enabled":
+ case "Enabled": return boolean.class;
case "localparticipantcontextpath":
case "LocalParticipantContextPath": return java.lang.String.class;
case "localparticipanturl":
@@ -56,6 +60,8 @@ public class LraConfigurationPropertiesConfigurer extends
org.apache.camel.suppo
case "CoordinatorContextPath": return
target.getCoordinatorContextPath();
case "coordinatorurl":
case "CoordinatorUrl": return target.getCoordinatorUrl();
+ case "enabled":
+ case "Enabled": return target.isEnabled();
case "localparticipantcontextpath":
case "LocalParticipantContextPath": return
target.getLocalParticipantContextPath();
case "localparticipanturl":
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
new file mode 100644
index 00000000000..9d53c533439
--- /dev/null
+++
b/core/camel-main/src/generated/java/org/apache/camel/main/MetricsConfigurationPropertiesConfigurer.java
@@ -0,0 +1,91 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.main;
+
+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.main.MetricsConfigurationProperties;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class MetricsConfigurationPropertiesConfigurer 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.main.MetricsConfigurationProperties target =
(org.apache.camel.main.MetricsConfigurationProperties) obj;
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "binders":
+ case "Binders": target.setBinders(property(camelContext,
java.lang.String.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;
+ case "enabled":
+ case "Enabled": target.setEnabled(property(camelContext,
boolean.class, value)); return true;
+ case "namingstrategy":
+ case "NamingStrategy": target.setNamingStrategy(property(camelContext,
java.lang.String.class, value)); return true;
+ case "textformatversion":
+ case "TextFormatVersion":
target.setTextFormatVersion(property(camelContext, java.lang.String.class,
value)); return true;
+ default: return false;
+ }
+ }
+
+ @Override
+ public Class<?> getOptionType(String name, boolean ignoreCase) {
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "binders":
+ case "Binders": return java.lang.String.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;
+ case "enabled":
+ case "Enabled": return boolean.class;
+ case "namingstrategy":
+ case "NamingStrategy": return java.lang.String.class;
+ case "textformatversion":
+ case "TextFormatVersion": return java.lang.String.class;
+ default: return null;
+ }
+ }
+
+ @Override
+ public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+ org.apache.camel.main.MetricsConfigurationProperties target =
(org.apache.camel.main.MetricsConfigurationProperties) obj;
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "binders":
+ case "Binders": return target.getBinders();
+ 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();
+ case "enabled":
+ case "Enabled": return target.isEnabled();
+ case "namingstrategy":
+ case "NamingStrategy": return target.getNamingStrategy();
+ case "textformatversion":
+ case "TextFormatVersion": return target.getTextFormatVersion();
+ default: return null;
+ }
+ }
+}
+
diff --git
a/core/camel-main/src/generated/java/org/apache/camel/main/OtelConfigurationPropertiesConfigurer.java
b/core/camel-main/src/generated/java/org/apache/camel/main/OtelConfigurationPropertiesConfigurer.java
index 2cd0234490c..c035d6aab7c 100644
---
a/core/camel-main/src/generated/java/org/apache/camel/main/OtelConfigurationPropertiesConfigurer.java
+++
b/core/camel-main/src/generated/java/org/apache/camel/main/OtelConfigurationPropertiesConfigurer.java
@@ -21,6 +21,8 @@ public class OtelConfigurationPropertiesConfigurer extends
org.apache.camel.supp
public boolean configure(CamelContext camelContext, Object obj, String
name, Object value, boolean ignoreCase) {
org.apache.camel.main.OtelConfigurationProperties target =
(org.apache.camel.main.OtelConfigurationProperties) obj;
switch (ignoreCase ? name.toLowerCase() : name) {
+ case "enabled":
+ case "Enabled": target.setEnabled(property(camelContext,
boolean.class, value)); return true;
case "encoding":
case "Encoding": target.setEncoding(property(camelContext,
boolean.class, value)); return true;
case "excludepatterns":
@@ -34,6 +36,8 @@ public class OtelConfigurationPropertiesConfigurer extends
org.apache.camel.supp
@Override
public Class<?> getOptionType(String name, boolean ignoreCase) {
switch (ignoreCase ? name.toLowerCase() : name) {
+ case "enabled":
+ case "Enabled": return boolean.class;
case "encoding":
case "Encoding": return boolean.class;
case "excludepatterns":
@@ -48,6 +52,8 @@ public class OtelConfigurationPropertiesConfigurer extends
org.apache.camel.supp
public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
org.apache.camel.main.OtelConfigurationProperties target =
(org.apache.camel.main.OtelConfigurationProperties) obj;
switch (ignoreCase ? name.toLowerCase() : name) {
+ case "enabled":
+ case "Enabled": return target.isEnabled();
case "encoding":
case "Encoding": return target.isEncoding();
case "excludepatterns":
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 3a89ff173c1..6994a0ad04f 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
@@ -11,6 +11,7 @@
{ "name": "camel.vault.gcp", "description": "Camel GCP Vault
configurations", "sourceType": "org.apache.camel.vault.GcpVaultConfiguration" },
{ "name": "camel.vault.azure", "description": "Camel Azure Key Vault
configurations", "sourceType": "org.apache.camel.vault.AzureVaultConfiguration"
},
{ "name": "camel.opentelemetry", "description": "Camel OpenTelemtry
configurations", "sourceType":
"org.apache.camel.main.OtelConfigurationProperties" },
+ { "name": "camel.metrics", "description": "Camel Micrometer Metrics
configurations", "sourceType":
"org.apache.camel.main.MetricsConfigurationProperties" },
{ "name": "camel.faulttolerance", "description": "Fault Tolerance EIP
Circuit Breaker configurations", "sourceType":
"org.apache.camel.main.FaultToleranceConfigurationProperties" },
{ "name": "camel.resilience4j", "description": "Resilience4j EIP Circuit
Breaker configurations", "sourceType":
"org.apache.camel.main.Resilience4jConfigurationProperties" },
{ "name": "camel.lra", "description": "Camel Saga EIP (Long Running
Actions) configurations", "sourceType":
"org.apache.camel.main.LraConfigurationProperties" }
@@ -176,8 +177,18 @@
{ "name": "camel.health.routesEnabled", "description": "Whether routes
health check is enabled", "sourceType":
"org.apache.camel.main.HealthConfigurationProperties", "type": "boolean",
"javaType": "java.lang.Boolean", "defaultValue": true },
{ "name": "camel.lra.coordinatorContextPath", "description": "The
context-path for the LRA coordinator. Is default \/lra-coordinator",
"sourceType": "org.apache.camel.main.LraConfigurationProperties", "type":
"string", "javaType": "java.lang.String", "defaultValue": "\/lra-coordinator" },
{ "name": "camel.lra.coordinatorUrl", "description": "The URL for the LRA
coordinator service that orchestrates the transactions", "sourceType":
"org.apache.camel.main.LraConfigurationProperties", "type": "string",
"javaType": "java.lang.String" },
+ { "name": "camel.lra.enabled", "description": "To enable Saga LRA",
"sourceType": "org.apache.camel.main.LraConfigurationProperties", "type":
"boolean", "javaType": "boolean", "defaultValue": false },
{ "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: cache-meter-binder, class-loader,
commons-object-pool2, database-table, disk-space, executor-service,
file-descriptor, hystrix-metrics-binder, jetty-server-thread-pool,
jvm-compilation, jvm-gc, jvm-heap-pressure, jvm-info, jvm-memory [...]
+ { "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" },
+ { "name": "camel.metrics.enableRouteEventNotifier", "description": "Set
whether to enable the MicrometerRouteEventNotifier for capturing metrics on the
total number of routes and total number of routes running.", "sourceType":
"org.apache.camel.main.MetricsConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": true },
+ { "name": "camel.metrics.enableRoutePolicy", "description": "Set whether
to enable the MicrometerRoutePolicyFactory for capturing metrics on route
processing times.", "sourceType":
"org.apache.camel.main.MetricsConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": true },
+ { "name": "camel.metrics.namingStrategy", "description": "Controls the
name style to use for metrics. Default = uses micrometer naming convention.
Legacy = uses the classic naming style (camelCase)", "sourceType":
"org.apache.camel.main.MetricsConfigurationProperties", "type": "string",
"javaType": "java.lang.String", "defaultValue": "default", "enum": [ "default",
"legacy" ] },
+ { "name": "camel.metrics.textFormatVersion", "description": "The
text-format version to use with Prometheus scraping. 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", "sourceType":
"org.apache.camel.main.MetricsConfigurationProperties", "type": "string",
"javaType": "java.lang.String", "defaultValue": "0.0.4", "enum": [ "0.0.4",
"1.0.0" ] },
+ { "name": "camel.opentelemetry.enabled", "description": "To enable
OpenTelemetry", "sourceType":
"org.apache.camel.main.OtelConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.opentelemetry.encoding", "description": "Sets whether the
header keys need to be encoded (connector specific) or not. The value is a
boolean. Dashes need for instances to be encoded for JMS property keys.",
"sourceType": "org.apache.camel.main.OtelConfigurationProperties", "type":
"boolean", "javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.opentelemetry.excludePatterns", "description": "Adds an
exclude pattern that will disable tracing for Camel messages that matches the
pattern. Multiple patterns can be separated by comma.", "sourceType":
"org.apache.camel.main.OtelConfigurationProperties", "type": "string",
"javaType": "java.lang.String" },
{ "name": "camel.opentelemetry.instrumentationName", "description": "A
name uniquely identifying the instrumentation scope, such as the
instrumentation library, package, or fully qualified class name. Must not be
null.", "sourceType": "org.apache.camel.main.OtelConfigurationProperties",
"type": "string", "javaType": "java.lang.String", "defaultValue": "camel" },
@@ -234,6 +245,7 @@
{ "name": "camel.server.healthCheckEnabled", "description": "Whether to
enable health-check console. If enabled then you can access health-check status
on context-path: \/q\/health", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.host", "description": "Hostname to use for binding
embedded HTTP server", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "string",
"javaType": "java.lang.String", "defaultValue": "0.0.0.0" },
{ "name": "camel.server.maxBodySize", "description": "Maximum HTTP body
size the embedded HTTP server can accept.", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "integer",
"javaType": "java.lang.Long" },
+ { "name": "camel.server.metricsEnabled", "description": "Whether to enable
metrics. If enabled then you can access metrics on context-path: \/q\/metrics",
"sourceType": "org.apache.camel.main.HttpServerConfigurationProperties",
"type": "boolean", "javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.path", "description": "Context-path to use for
embedded HTTP server", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "string",
"javaType": "java.lang.String", "defaultValue": "\/" },
{ "name": "camel.server.port", "description": "Port to use for binding
embedded HTTP server", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "integer",
"javaType": "int", "defaultValue": 8080 },
{ "name": "camel.server.uploadEnabled", "description": "Whether to enable
file upload via HTTP (not intended for production use). This functionality is
for development to be able to reload Camel routes and code with source changes
(if reload is enabled). If enabled then you can upload\/delete files via HTTP
PUT\/DELETE on context-path: \/q\/upload\/{name}. You must also configure the
uploadSourceDir option.", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "t [...]
diff --git
a/core/camel-main/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.main.MetricsConfigurationProperties
b/core/camel-main/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.main.MetricsConfigurationProperties
new file mode 100644
index 00000000000..fd356d7ac12
--- /dev/null
+++
b/core/camel-main/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.main.MetricsConfigurationProperties
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.main.MetricsConfigurationPropertiesConfigurer
diff --git a/core/camel-main/src/main/docs/main.adoc
b/core/camel-main/src/main/docs/main.adoc
index 3dee56918ae..d92a3928706 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -154,7 +154,7 @@ The camel.main supports 126 options, which are listed below.
=== Camel Embedded HTTP Server (only for standalone; not Spring Boot or
Quarkus) configurations
-The camel.server supports 10 options, which are listed below.
+The camel.server supports 11 options, which are listed below.
[width="100%",cols="2,5,^1,2",options="header"]
|===
@@ -164,6 +164,7 @@ The camel.server supports 10 options, which are listed
below.
| *camel.server.healthCheck{zwsp}Enabled* | Whether to enable health-check
console. If enabled then you can access health-check status on context-path:
/q/health | false | boolean
| *camel.server.host* | Hostname to use for binding embedded HTTP server |
0.0.0.0 | String
| *camel.server.maxBodySize* | Maximum HTTP body size the embedded HTTP server
can accept. | | Long
+| *camel.server.metricsEnabled* | Whether to enable metrics. If enabled then
you can access metrics on context-path: /q/metrics | false | boolean
| *camel.server.path* | Context-path to use for embedded HTTP server | / |
String
| *camel.server.port* | Port to use for binding embedded HTTP server | 8080 |
int
| *camel.server.uploadEnabled* | Whether to enable file upload via HTTP (not
intended for production use). This functionality is for development to be able
to reload Camel routes and code with source changes (if reload is enabled). If
enabled then you can upload/delete files via HTTP PUT/DELETE on context-path:
/q/upload/\{name}. You must also configure the uploadSourceDir option. | false
| boolean
@@ -333,17 +334,35 @@ The camel.vault.azure supports 11 options, which are
listed below.
=== Camel OpenTelemtry configurations
-The camel.opentelemetry supports 3 options, which are listed below.
+The camel.opentelemetry supports 4 options, which are listed below.
[width="100%",cols="2,5,^1,2",options="header"]
|===
| Name | Description | Default | Type
+| *camel.opentelemetry.enabled* | To enable OpenTelemetry | false | boolean
| *camel.opentelemetry.encoding* | Sets whether the header keys need to be
encoded (connector specific) or not. The value is a boolean. Dashes need for
instances to be encoded for JMS property keys. | false | boolean
| *camel.opentelemetry.exclude{zwsp}Patterns* | Adds an exclude pattern that
will disable tracing for Camel messages that matches the pattern. Multiple
patterns can be separated by comma. | | String
| *{zwsp}camel.opentelemetry.instrumentation{zwsp}Name* | A name uniquely
identifying the instrumentation scope, such as the instrumentation library,
package, or fully qualified class name. Must not be null. | camel | String
|===
+=== Camel Micrometer Metrics configurations
+The camel.metrics supports 8 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: cache-meter-binder, class-loader, commons-object-pool2,
database-table, disk-space, executor-service, file-descriptor,
hystrix-metrics-binder, jetty-server-thread-pool, jvm-compilation, jvm-gc,
jvm-heap-pressure, jvm-info, jvm-memory, jvm-thread, kafka, log4j2 [...]
+| *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
+| *camel.metrics.enableRouteEvent{zwsp}Notifier* | Set whether to enable the
MicrometerRouteEventNotifier for capturing metrics on the total number of
routes and total number of routes running. | true | boolean
+| *camel.metrics.enableRoute{zwsp}Policy* | Set whether to enable the
MicrometerRoutePolicyFactory for capturing metrics on route processing times. |
true | boolean
+| *camel.metrics.namingStrategy* | Controls the name style to use for metrics.
Default = uses micrometer naming convention. Legacy = uses the classic naming
style (camelCase) | default | String
+| *camel.metrics.textFormat{zwsp}Version* | The text-format version to use
with Prometheus scraping. 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 | 0.0.4 |
String
+|===
+
+
=== Fault Tolerance EIP Circuit Breaker configurations
The camel.faulttolerance supports 13 options, which are listed below.
@@ -396,13 +415,14 @@ The camel.resilience4j supports 20 options, which are
listed below.
=== Camel Saga EIP (Long Running Actions) configurations
-The camel.lra supports 4 options, which are listed below.
+The camel.lra supports 5 options, which are listed below.
[width="100%",cols="2,5,^1,2",options="header"]
|===
| Name | Description | Default | Type
| *camel.lra.coordinatorContext{zwsp}Path* | The context-path for the LRA
coordinator. Is default /lra-coordinator | /lra-coordinator | String
| *camel.lra.coordinatorUrl* | The URL for the LRA coordinator service that
orchestrates the transactions | | String
+| *camel.lra.enabled* | To enable Saga LRA | false | boolean
| *camel.lra.localParticipant{zwsp}ContextPath* | The context-path for the
local participant. Is default /lra-participant | /lra-participant | String
| *camel.lra.localParticipantUrl* | The URL for the local participant | |
String
|===
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 bbaff3f289e..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;
@@ -952,6 +953,7 @@ public abstract class BaseMainSupport extends BaseService {
OrderedLocationProperties healthProperties = new
OrderedLocationProperties();
OrderedLocationProperties lraProperties = new
OrderedLocationProperties();
OrderedLocationProperties otelProperties = new
OrderedLocationProperties();
+ OrderedLocationProperties metricsProperties = new
OrderedLocationProperties();
OrderedLocationProperties routeTemplateProperties = new
OrderedLocationProperties();
OrderedLocationProperties beansProperties = new
OrderedLocationProperties();
OrderedLocationProperties devConsoleProperties = new
OrderedLocationProperties();
@@ -1015,6 +1017,12 @@ public abstract class BaseMainSupport extends
BaseService {
String option = key.substring(20);
validateOptionAndValue(key, option, value);
otelProperties.put(loc, optionKey(option), value);
+ } else if (key.startsWith("camel.metrics.")) {
+ // grab the value
+ String value = prop.getProperty(key);
+ String option = key.substring(14);
+ validateOptionAndValue(key, option, value);
+ metricsProperties.put(loc, optionKey(option), value);
} else if (key.startsWith("camel.routeTemplate")) {
// grab the value
String value = prop.getProperty(key);
@@ -1127,6 +1135,11 @@ public abstract class BaseMainSupport extends
BaseService {
setOtelProperties(camelContext, otelProperties,
mainConfigurationProperties.isAutoConfigurationFailFast(),
autoConfiguredProperties);
}
+ if (!metricsProperties.isEmpty() ||
mainConfigurationProperties.hasMetricsConfiguration()) {
+ LOG.debug("Auto-configuring Micrometer metrics from loaded
properties: {}", metricsProperties.size());
+ setMetricsProperties(camelContext, metricsProperties,
mainConfigurationProperties.isAutoConfigurationFailFast(),
+ autoConfiguredProperties);
+ }
if (!devConsoleProperties.isEmpty()) {
LOG.debug("Auto-configuring Dev Console from loaded properties:
{}", devConsoleProperties.size());
setDevConsoleProperties(camelContext, devConsoleProperties,
@@ -1396,6 +1409,28 @@ public abstract class BaseMainSupport extends
BaseService {
}
}
+ private void setMetricsProperties(
+ CamelContext camelContext, OrderedLocationProperties
metricsProperties,
+ boolean failIfNotSet, OrderedLocationProperties
autoConfiguredProperties)
+ throws Exception {
+
+ String loc = metricsProperties.getLocation("enabled");
+ Object obj = metricsProperties.remove("enabled");
+ if (ObjectHelper.isNotEmpty(obj)) {
+ autoConfiguredProperties.put(loc, "camel.metrics.enabled",
obj.toString());
+ }
+ boolean enabled = obj != null ?
CamelContextHelper.parseBoolean(camelContext, obj.toString()) : true;
+ if (enabled) {
+ 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);
+ }
+ }
+ }
+
private void setDevConsoleProperties(
CamelContext camelContext, OrderedLocationProperties properties,
boolean failIfNotSet, OrderedLocationProperties
autoConfiguredProperties) {
@@ -2051,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/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java
b/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java
index 2d9fb21e1ef..31ca9b144ec 100644
---
a/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java
+++
b/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java
@@ -41,6 +41,7 @@ public class HttpServerConfigurationProperties implements
BootstrapCloseable {
private boolean devConsoleEnabled;
private boolean healthCheckEnabled;
+ private boolean metricsEnabled;
private boolean uploadEnabled;
private String uploadSourceDir;
@@ -149,6 +150,17 @@ public class HttpServerConfigurationProperties implements
BootstrapCloseable {
this.healthCheckEnabled = healthCheckEnabled;
}
+ public boolean isMetricsEnabled() {
+ return metricsEnabled;
+ }
+
+ /**
+ * Whether to enable metrics. If enabled then you can access metrics on
context-path: /q/metrics
+ */
+ public void setMetricsEnabled(boolean metricsEnabled) {
+ this.metricsEnabled = metricsEnabled;
+ }
+
public boolean isUploadEnabled() {
return uploadEnabled;
}
@@ -242,6 +254,14 @@ public class HttpServerConfigurationProperties implements
BootstrapCloseable {
return this;
}
+ /**
+ * Whether to enable metrics. If enabled then you can access metrics on
context-path: /q/metrics
+ */
+ public HttpServerConfigurationProperties withMetricsEnabled(boolean
metricsEnabled) {
+ this.metricsEnabled = metricsEnabled;
+ return this;
+ }
+
/**
* Whether to enable file upload via HTTP (not intended for production
use). This functionality is for development
* to be able to reload Camel routes and code with source changes (if
reload is enabled). If enabled then you can
diff --git
a/core/camel-main/src/main/java/org/apache/camel/main/LraConfigurationProperties.java
b/core/camel-main/src/main/java/org/apache/camel/main/LraConfigurationProperties.java
index c0106ddbcac..0246b724b0b 100644
---
a/core/camel-main/src/main/java/org/apache/camel/main/LraConfigurationProperties.java
+++
b/core/camel-main/src/main/java/org/apache/camel/main/LraConfigurationProperties.java
@@ -28,6 +28,8 @@ public class LraConfigurationProperties implements
BootstrapCloseable {
private MainConfigurationProperties parent;
+ @Metadata(defaultValue = "false")
+ private boolean enabled;
private String coordinatorUrl;
@Metadata(defaultValue = "/lra-coordinator")
private String coordinatorContextPath = "/lra-coordinator";
@@ -48,6 +50,17 @@ public class LraConfigurationProperties implements
BootstrapCloseable {
parent = null;
}
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * To enable Saga LRA
+ */
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
public String getCoordinatorUrl() {
return coordinatorUrl;
}
@@ -104,6 +117,14 @@ public class LraConfigurationProperties implements
BootstrapCloseable {
return this;
}
+ /**
+ * To enable Saga LRA
+ */
+ public LraConfigurationProperties withEnabled(boolean enabled) {
+ this.enabled = enabled;
+ return this;
+ }
+
/**
* The context-path for the LRA coordinator.
*/
diff --git
a/core/camel-main/src/main/java/org/apache/camel/main/MainConfigurationProperties.java
b/core/camel-main/src/main/java/org/apache/camel/main/MainConfigurationProperties.java
index 79273789d92..70300e16c70 100644
---
a/core/camel-main/src/main/java/org/apache/camel/main/MainConfigurationProperties.java
+++
b/core/camel-main/src/main/java/org/apache/camel/main/MainConfigurationProperties.java
@@ -54,6 +54,7 @@ public class MainConfigurationProperties extends
DefaultConfigurationProperties<
private HealthConfigurationProperties healthConfigurationProperties;
private LraConfigurationProperties lraConfigurationProperties;
private OtelConfigurationProperties otelConfigurationProperties;
+ private MetricsConfigurationProperties metricsConfigurationProperties;
private ThreadPoolConfigurationProperties threadPoolProperties;
private Resilience4jConfigurationProperties
resilience4jConfigurationProperties;
private FaultToleranceConfigurationProperties
faultToleranceConfigurationProperties;
@@ -77,6 +78,10 @@ public class MainConfigurationProperties extends
DefaultConfigurationProperties<
otelConfigurationProperties.close();
otelConfigurationProperties = null;
}
+ if (metricsConfigurationProperties != null) {
+ metricsConfigurationProperties.close();
+ metricsConfigurationProperties = null;
+ }
if (threadPoolProperties != null) {
threadPoolProperties.close();
threadPoolProperties = null;
@@ -173,6 +178,23 @@ public class MainConfigurationProperties extends
DefaultConfigurationProperties<
return otelConfigurationProperties != null;
}
+ /**
+ * To configure Micrometer metrics.
+ */
+ public MetricsConfigurationProperties metrics() {
+ if (metricsConfigurationProperties == null) {
+ metricsConfigurationProperties = new
MetricsConfigurationProperties(this);
+ }
+ return metricsConfigurationProperties;
+ }
+
+ /**
+ * Whether there has been any Micrometer metrics configuration specified
+ */
+ public boolean hasMetricsConfiguration() {
+ return metricsConfigurationProperties != null;
+ }
+
/**
* To configure embedded HTTP server (for standalone applications; not
Spring Boot or Quarkus)
*/
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
new file mode 100644
index 00000000000..62d547b63cb
--- /dev/null
+++
b/core/camel-main/src/main/java/org/apache/camel/main/MetricsConfigurationProperties.java
@@ -0,0 +1,241 @@
+/*
+ * 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.main;
+
+import org.apache.camel.spi.BootstrapCloseable;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
+
+/**
+ * Global configuration for Micrometer Metrics.
+ */
+@Configurer(bootstrap = true)
+public class MetricsConfigurationProperties implements BootstrapCloseable {
+
+ private MainConfigurationProperties parent;
+
+ private boolean enabled;
+ @Metadata(defaultValue = "default", enums = "default,legacy")
+ private String namingStrategy;
+ @Metadata(defaultValue = "true")
+ private boolean enableRoutePolicy = true;
+ private boolean enableMessageHistory;
+ @Metadata(defaultValue = "true")
+ private boolean enableExchangeEventNotifier = true;
+ @Metadata(defaultValue = "true")
+ private boolean enableRouteEventNotifier = true;
+ @Metadata(defaultValue = "0.0.4", enums = "0.0.4,1.0.0")
+ private String textFormatVersion = "0.0.4";
+ @Metadata
+ private String binders;
+
+ public MetricsConfigurationProperties(MainConfigurationProperties parent) {
+ this.parent = parent;
+ }
+
+ public MainConfigurationProperties end() {
+ return parent;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * To enable Micrometer metrics.
+ */
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public String getNamingStrategy() {
+ return namingStrategy;
+ }
+
+ /**
+ * Controls the name style to use for metrics.
+ *
+ * Default = uses micrometer naming convention.
+ * Legacy = uses the classic naming style (camelCase)
+ */
+ public void setNamingStrategy(String namingStrategy) {
+ this.namingStrategy = namingStrategy;
+ }
+
+ 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;
+ }
+
+ public String getTextFormatVersion() {
+ return textFormatVersion;
+ }
+
+ /**
+ * The text-format version to use with Prometheus scraping.
+ *
+ * 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
+ */
+ public void setTextFormatVersion(String textFormatVersion) {
+ this.textFormatVersion = textFormatVersion;
+ }
+
+ public String getBinders() {
+ return 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:
+ * cache-meter-binder, class-loader, commons-object-pool2, database-table,
disk-space, executor-service, file-descriptor, hystrix-metrics-binder,
jetty-server-thread-pool, jvm-compilation, jvm-gc, jvm-heap-pressure, jvm-info,
jvm-memory, jvm-thread, kafka, log4j2, logback, netty-allocator,
netty-event-executor, ok-http-connection-pool,
pooling-http-client-connection-manager-metrics-binder, postgre-sql-database,
processor, tomcat, uptime
+ */
+ public void setBinders(String binders) {
+ this.binders = binders;
+ }
+
+ @Override
+ public void close() {
+ parent = null;
+ }
+
+ /**
+ * Set whether to enable the MicrometerRoutePolicyFactory for capturing
metrics on route processing times.
+ */
+ public MetricsConfigurationProperties withEnableRoutePolicy(boolean
enableRoutePolicy) {
+ this.enableRoutePolicy = enableRoutePolicy;
+ return this;
+ }
+
+ /**
+ * To enable Micrometer metrics.
+ */
+ public MetricsConfigurationProperties withEnabled(boolean enabled) {
+ this.enabled = enabled;
+ return this;
+ }
+
+ /**
+ * Controls the name style to use for metrics.
+ *
+ * Default = uses micrometer naming convention.
+ * Legacy = uses the classic naming style (camelCase)
+ */
+ public MetricsConfigurationProperties withNamingStrategy(String
namingStrategy) {
+ this.namingStrategy = namingStrategy;
+ return this;
+ }
+
+ /**
+ * 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 MetricsConfigurationProperties withEnableMessageHistory(boolean
enableMessageHistory) {
+ this.enableMessageHistory = enableMessageHistory;
+ return this;
+ }
+
+ /**
+ * Set whether to enable the MicrometerExchangeEventNotifier for capturing
metrics on exchange processing times.
+ */
+ public MetricsConfigurationProperties
withEnableExchangeEventNotifier(boolean enableExchangeEventNotifier) {
+ this.enableExchangeEventNotifier = enableExchangeEventNotifier;
+ return this;
+ }
+
+ /**
+ * Set whether to enable the MicrometerRouteEventNotifier for capturing
metrics on the total number of routes and
+ * total number of routes running.
+ */
+ public MetricsConfigurationProperties
witheEnableRouteEventNotifier(boolean enableRouteEventNotifier) {
+ this.enableRouteEventNotifier = enableRouteEventNotifier;
+ return this;
+ }
+
+ /**
+ * The text-format version to use with Prometheus scraping.
+ *
+ * 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
+ */
+ public MetricsConfigurationProperties withTextFormatVersion(String
textFormatVersion) {
+ this.textFormatVersion = textFormatVersion;
+ return this;
+ }
+
+ /**
+ * 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:
+ * cache-meter-binder, class-loader, commons-object-pool2, database-table,
disk-space, executor-service, file-descriptor, hystrix-metrics-binder,
jetty-server-thread-pool, jvm-compilation, jvm-gc, jvm-heap-pressure, jvm-info,
jvm-memory, jvm-thread, kafka, log4j2, logback, netty-allocator,
netty-event-executor, ok-http-connection-pool,
pooling-http-client-connection-manager-metrics-binder, postgre-sql-database,
processor, tomcat, uptime
+ */
+ public MetricsConfigurationProperties withBinders(String binders) {
+ this.binders = binders;
+ return this;
+ }
+
+}
diff --git
a/core/camel-main/src/main/java/org/apache/camel/main/OtelConfigurationProperties.java
b/core/camel-main/src/main/java/org/apache/camel/main/OtelConfigurationProperties.java
index a41c23a1694..567356d5d02 100644
---
a/core/camel-main/src/main/java/org/apache/camel/main/OtelConfigurationProperties.java
+++
b/core/camel-main/src/main/java/org/apache/camel/main/OtelConfigurationProperties.java
@@ -28,6 +28,7 @@ public class OtelConfigurationProperties implements
BootstrapCloseable {
private MainConfigurationProperties parent;
+ private boolean enabled;
@Metadata(defaultValue = "camel", required = true)
private String instrumentationName = "camel";
private boolean encoding;
@@ -46,6 +47,17 @@ public class OtelConfigurationProperties implements
BootstrapCloseable {
parent = null;
}
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * To enable OpenTelemetry
+ */
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
public String getInstrumentationName() {
return instrumentationName;
}
@@ -91,6 +103,14 @@ public class OtelConfigurationProperties implements
BootstrapCloseable {
return this;
}
+ /**
+ * To enable OpenTelemetry
+ */
+ public OtelConfigurationProperties withEnabled(boolean enabled) {
+ this.enabled = enabled;
+ return this;
+ }
+
/**
* Sets whether the header keys need to be encoded (connector specific) or
not. The value is a boolean. Dashes need
* for instances to be encoded for JMS property keys.
diff --git a/parent/pom.xml b/parent/pom.xml
index ca9d76f99ed..913752cdd42 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -222,7 +222,7 @@
<jackson2-version>2.15.2</jackson2-version>
<jackrabbit-version>2.21.20</jackrabbit-version>
<jasminb-jsonapi-version>0.13</jasminb-jsonapi-version>
- <jandex-version>3.1.2</jandex-version>
+ <jandex-version>3.1.5</jandex-version>
<jansi-version>2.4.0</jansi-version>
<jasypt-version>1.9.3</jasypt-version>
<java-grok-version>0.1.9</java-grok-version>
@@ -1748,6 +1748,11 @@
<artifactId>camel-micrometer</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-micrometer-prometheus</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-microprofile-config</artifactId>
@@ -2814,6 +2819,11 @@
<artifactId>micrometer-registry-jmx</artifactId>
<version>${micrometer-version}</version>
</dependency>
+ <dependency>
+ <groupId>io.micrometer</groupId>
+ <artifactId>micrometer-registry-prometheus</artifactId>
+ <version>${micrometer-version}</version>
+ </dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing</artifactId>
diff --git
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java
index e5d80ece234..43789467da0 100644
---
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java
+++
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java
@@ -206,6 +206,8 @@ public class PrepareCamelMainMojo extends
AbstractGeneratorMojo {
prefix = "camel.lra.";
} else if (file.getName().contains("Otel")) {
prefix = "camel.opentelemetry.";
+ } else if (file.getName().contains("Metrics")) {
+ prefix = "camel.metrics.";
} else if (file.getName().contains("HttpServer")) {
prefix = "camel.server.";
} else if
(file.getName().contains("ThreadPoolProfileConfigurationProperties")) {
@@ -321,6 +323,9 @@ public class PrepareCamelMainMojo extends
AbstractGeneratorMojo {
model.getGroups().add(new MainGroupModel(
"camel.opentelemetry", "Camel OpenTelemtry configurations",
"org.apache.camel.main.OtelConfigurationProperties"));
+ model.getGroups().add(new MainGroupModel(
+ "camel.metrics", "Camel Micrometer Metrics configurations",
+ "org.apache.camel.main.MetricsConfigurationProperties"));
model.getGroups()
.add(new MainGroupModel(
"camel.faulttolerance", "Fault Tolerance EIP
Circuit Breaker configurations",