This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch camel-4.22.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.22.x by this push:
new bb1a5353e12f [backport camel-4.22.x] CAMEL-26611: camel-micrometer,
camel-opentelemetry-metrics - use tags and attributes from headers as given
(#29251)
bb1a5353e12f is described below
commit bb1a5353e12fc7e41c8a57c5b8612a31a88b26ed
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Nov 5 16:52:13 2026 +0100
[backport camel-4.22.x] CAMEL-26611: camel-micrometer,
camel-opentelemetry-metrics - use tags and attributes from headers as given
(#29251)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---
.../camel/catalog/components/micrometer.json | 2 +-
.../catalog/components/opentelemetry-metrics.json | 2 +-
.../camel/catalog/docs/micrometer-component.adoc | 5 +++
.../docs/opentelemetry-metrics-component.adoc | 5 +++
.../camel/component/micrometer/micrometer.json | 2 +-
.../src/main/docs/micrometer-component.adoc | 5 +++
.../micrometer/AbstractMicrometerProducer.java | 4 ++-
.../component/micrometer/MicrometerConstants.java | 4 ++-
.../component/micrometer/CounterRouteTest.java | 40 ++++++++++++++++++++++
.../metrics/opentelemetry-metrics.json | 2 +-
.../main/docs/opentelemetry-metrics-component.adoc | 5 +++
.../metrics/AbstractOpenTelemetryProducer.java | 17 ++++-----
.../metrics/OpenTelemetryConstants.java | 3 +-
.../opentelemetry/metrics/CounterRouteTest.java | 40 ++++++++++++++++++++++
.../dsl/MicrometerEndpointBuilderFactory.java | 4 ++-
.../dsl/OpenTelemetryEndpointBuilderFactory.java | 4 ++-
16 files changed, 124 insertions(+), 20 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/micrometer.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/micrometer.json
index 2483c49591f5..9ee87d853fb2 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/micrometer.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/micrometer.json
@@ -35,7 +35,7 @@
"CamelMetricsCounterIncrement": { "index": 3, "kind": "header",
"displayName": "", "group": "producer", "label": "", "required": false,
"javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Override increment value in URI",
"constantName":
"org.apache.camel.component.micrometer.MicrometerConstants#HEADER_COUNTER_INCREMENT"
},
"CamelMetricsName": { "index": 4, "kind": "header", "displayName": "",
"group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "Override name value in URI", "constantName":
"org.apache.camel.component.micrometer.MicrometerConstants#HEADER_METRIC_NAME"
},
"CamelMetricsDescription": { "index": 5, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "Override description value in URI", "constantName":
"org.apache.camel.component.micrometer.MicrometerConstants#HEADER_METRIC_DESCRIPTION"
},
- "CamelMetricsTags": { "index": 6, "kind": "header", "displayName": "",
"group": "producer", "label": "", "required": false, "javaType":
"java.lang.Iterable<Tag>", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "To augment meter tags
defined as URI parameters", "constantName":
"org.apache.camel.component.micrometer.MicrometerConstants#HEADER_METRIC_TAGS" }
+ "CamelMetricsTags": { "index": 6, "kind": "header", "displayName": "",
"group": "producer", "label": "", "required": false, "javaType":
"java.lang.Iterable<Tag>", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "To augment meter tags
defined as URI parameters. The tags from the header are used as given; use the
tags URI parameters for Simple expressions.", "constantName":
"org.apache.camel.component.micrometer.MicrometerConstants#HEADER [...]
},
"properties": {
"metricsType": { "index": 0, "kind": "path", "displayName": "Metrics
Type", "group": "producer", "label": "", "required": true, "type": "enum",
"javaType": "io.micrometer.core.instrument.Meter.Type", "enum": [ "counter",
"summary", "timer" ], "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Type of metrics" },
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opentelemetry-metrics.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opentelemetry-metrics.json
index 789943d1dee3..5ffaa82b14ed 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opentelemetry-metrics.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opentelemetry-metrics.json
@@ -35,7 +35,7 @@
"CamelMetricsCounterIncrement": { "index": 3, "kind": "header",
"displayName": "", "group": "producer", "label": "", "required": false,
"javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Override increment value in URI",
"constantName":
"org.apache.camel.opentelemetry.metrics.OpenTelemetryConstants#HEADER_COUNTER_INCREMENT"
},
"CamelMetricsName": { "index": 4, "kind": "header", "displayName": "",
"group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "Override name value in URI", "constantName":
"org.apache.camel.opentelemetry.metrics.OpenTelemetryConstants#HEADER_METRIC_NAME"
},
"CamelMetricsDescription": { "index": 5, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "Override description value in URI", "constantName":
"org.apache.camel.opentelemetry.metrics.OpenTelemetryConstants#HEADER_METRIC_DESCRIPTION"
},
- "CamelMetricsAttributes": { "index": 6, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType":
"io.opentelemetry.api.common.Attributes", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false, "description": "To
augment meter attributes defined as URI parameters", "constantName":
"org.apache.camel.opentelemetry.metrics.OpenTelemetryConstants#HEADER_METRIC_ATTRIBUTES"
}
+ "CamelMetricsAttributes": { "index": 6, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType":
"io.opentelemetry.api.common.Attributes", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false, "description": "To
augment meter attributes defined as URI parameters. The attributes from the
header are used as given; use the attributes URI parameters for Simple
expressions.", "constantName": "org.apache.camel.opentele [...]
},
"properties": {
"metricType": { "index": 0, "kind": "path", "displayName": "Metric Type",
"group": "producer", "label": "", "required": true, "type": "enum", "javaType":
"org.apache.camel.opentelemetry.metrics.InstrumentType", "enum": [ "counter",
"summary", "timer" ], "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Type of metrics" },
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/micrometer-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/micrometer-component.adoc
index d63172bfad4f..90bb21fe09b1 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/micrometer-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/micrometer-component.adoc
@@ -148,6 +148,11 @@ from("direct:in")
will update a counter with name `new.name` instead of `name.not.used` using the
tag `dynamic-key` with value `dynamic-value` in addition to the tag `key` with
value `value`.
+The tags from the `CamelMetricsTags` header are used as given: unlike the
`tags` URI parameters,
+their keys and values are not evaluated as `Simple` expressions. A tag from
the header overrides a tag
+from the URI with the same key. To tag a meter with a value from the message,
use a `tags` URI parameter
+such as `tags.customer=${header.customerId}`, or compute the value in the
route before setting the header.
+
All Metrics specific headers are removed from the message once the Micrometer
endpoint finishes processing of exchange. While processing exchange
Micrometer endpoint will catch all exceptions and write log entry using level
`warn`.
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opentelemetry-metrics-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opentelemetry-metrics-component.adoc
index 6890a325bb17..e39125702e55 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opentelemetry-metrics-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opentelemetry-metrics-component.adoc
@@ -90,6 +90,11 @@ from("direct:in")
will update a counter with name `new.name` (instead of `name.not.used`) using
the attribute `dynamic-key` with value `dynamic-value` in addition to the
attribute `key` with value `value`.
+The attributes from the `CamelMetricsAttributes` header are used as given:
unlike the `attributes` URI parameters,
+their keys and values are not evaluated as `Simple` expressions. An attribute
from the header overrides an attribute
+from the URI with the same key. To add an attribute with a value from the
message, use an `attributes` URI parameter
+such as `attributes.customer=${header.customerId}`, or compute the value in
the route before setting the header.
+
All Metrics specific headers are removed from the message once the
OpenTelemetry endpoint finishes processing the exchange. While processing the
exchange
the OpenTelemetry endpoint will catch all exceptions and write log entry using
level `warn`.
diff --git
a/components/camel-micrometer/src/generated/resources/META-INF/org/apache/camel/component/micrometer/micrometer.json
b/components/camel-micrometer/src/generated/resources/META-INF/org/apache/camel/component/micrometer/micrometer.json
index 2483c49591f5..9ee87d853fb2 100644
---
a/components/camel-micrometer/src/generated/resources/META-INF/org/apache/camel/component/micrometer/micrometer.json
+++
b/components/camel-micrometer/src/generated/resources/META-INF/org/apache/camel/component/micrometer/micrometer.json
@@ -35,7 +35,7 @@
"CamelMetricsCounterIncrement": { "index": 3, "kind": "header",
"displayName": "", "group": "producer", "label": "", "required": false,
"javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Override increment value in URI",
"constantName":
"org.apache.camel.component.micrometer.MicrometerConstants#HEADER_COUNTER_INCREMENT"
},
"CamelMetricsName": { "index": 4, "kind": "header", "displayName": "",
"group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "Override name value in URI", "constantName":
"org.apache.camel.component.micrometer.MicrometerConstants#HEADER_METRIC_NAME"
},
"CamelMetricsDescription": { "index": 5, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "Override description value in URI", "constantName":
"org.apache.camel.component.micrometer.MicrometerConstants#HEADER_METRIC_DESCRIPTION"
},
- "CamelMetricsTags": { "index": 6, "kind": "header", "displayName": "",
"group": "producer", "label": "", "required": false, "javaType":
"java.lang.Iterable<Tag>", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "To augment meter tags
defined as URI parameters", "constantName":
"org.apache.camel.component.micrometer.MicrometerConstants#HEADER_METRIC_TAGS" }
+ "CamelMetricsTags": { "index": 6, "kind": "header", "displayName": "",
"group": "producer", "label": "", "required": false, "javaType":
"java.lang.Iterable<Tag>", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "To augment meter tags
defined as URI parameters. The tags from the header are used as given; use the
tags URI parameters for Simple expressions.", "constantName":
"org.apache.camel.component.micrometer.MicrometerConstants#HEADER [...]
},
"properties": {
"metricsType": { "index": 0, "kind": "path", "displayName": "Metrics
Type", "group": "producer", "label": "", "required": true, "type": "enum",
"javaType": "io.micrometer.core.instrument.Meter.Type", "enum": [ "counter",
"summary", "timer" ], "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Type of metrics" },
diff --git
a/components/camel-micrometer/src/main/docs/micrometer-component.adoc
b/components/camel-micrometer/src/main/docs/micrometer-component.adoc
index d63172bfad4f..90bb21fe09b1 100644
--- a/components/camel-micrometer/src/main/docs/micrometer-component.adoc
+++ b/components/camel-micrometer/src/main/docs/micrometer-component.adoc
@@ -148,6 +148,11 @@ from("direct:in")
will update a counter with name `new.name` instead of `name.not.used` using the
tag `dynamic-key` with value `dynamic-value` in addition to the tag `key` with
value `value`.
+The tags from the `CamelMetricsTags` header are used as given: unlike the
`tags` URI parameters,
+their keys and values are not evaluated as `Simple` expressions. A tag from
the header overrides a tag
+from the URI with the same key. To tag a meter with a value from the message,
use a `tags` URI parameter
+such as `tags.customer=${header.customerId}`, or compute the value in the
route before setting the header.
+
All Metrics specific headers are removed from the message once the Micrometer
endpoint finishes processing of exchange. While processing exchange
Micrometer endpoint will catch all exceptions and write log entry using level
`warn`.
diff --git
a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/AbstractMicrometerProducer.java
b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/AbstractMicrometerProducer.java
index c89b6b7234d9..ba1175a296b8 100644
---
a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/AbstractMicrometerProducer.java
+++
b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/AbstractMicrometerProducer.java
@@ -64,11 +64,13 @@ public abstract class AbstractMicrometerProducer<T extends
Meter> extends Defaul
String defaultMetricsDescription = simple(exchange,
getEndpoint().getMetricsDescription(), String.class);
String finalMetricsDescription = getStringHeader(in,
HEADER_METRIC_DESCRIPTION, defaultMetricsDescription);
Iterable<Tag> headerTags = getTagHeader(in, HEADER_METRIC_TAGS,
Tags.empty());
- Iterable<Tag> finalTags = Tags.concat(tags, headerTags).stream()
+ // only the tags from the endpoint are simple expressions, the tags
from the header are used as given
+ Iterable<Tag> finalTags = Tags.of(tags).stream()
.map(tag -> Tag.of(
simple(exchange, tag.getKey(), String.class),
simple(exchange, tag.getValue(), String.class)))
.reduce(Tags.empty(), Tags::and, Tags::and)
+ .and(headerTags)
.and(Tags.of(
CAMEL_CONTEXT_TAG,
getEndpoint().getCamelContext().getName()));
try {
diff --git
a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConstants.java
b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConstants.java
index 997968187465..8584214872d4 100644
---
a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConstants.java
+++
b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConstants.java
@@ -37,7 +37,9 @@ public final class MicrometerConstants {
public static final String HEADER_METRIC_NAME = HEADER_PREFIX + "Name";
@Metadata(description = "Override description value in URI", javaType =
"String")
public static final String HEADER_METRIC_DESCRIPTION = HEADER_PREFIX +
"Description";
- @Metadata(description = "To augment meter tags defined as URI parameters",
javaType = "java.lang.Iterable<Tag>")
+ @Metadata(description = "To augment meter tags defined as URI parameters.
The tags from the header are used as given;"
+ + " use the tags URI parameters for Simple
expressions.",
+ javaType = "java.lang.Iterable<Tag>")
public static final String HEADER_METRIC_TAGS = HEADER_PREFIX + "Tags";
public static final String DEFAULT_CAMEL_MESSAGE_HISTORY_METER_NAME =
"camel.message.history";
diff --git
a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/CounterRouteTest.java
b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/CounterRouteTest.java
index 9feb4a31cccb..9000086a864d 100644
---
a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/CounterRouteTest.java
+++
b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/CounterRouteTest.java
@@ -16,8 +16,11 @@
*/
package org.apache.camel.component.micrometer;
+import java.util.Map;
+
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import org.apache.camel.BindToRegistry;
import org.apache.camel.EndpointInject;
@@ -35,8 +38,10 @@ import
org.springframework.context.support.AbstractApplicationContext;
import static
org.apache.camel.component.micrometer.MicrometerConstants.HEADER_COUNTER_DECREMENT;
import static
org.apache.camel.component.micrometer.MicrometerConstants.HEADER_COUNTER_INCREMENT;
import static
org.apache.camel.component.micrometer.MicrometerConstants.HEADER_METRIC_NAME;
+import static
org.apache.camel.component.micrometer.MicrometerConstants.HEADER_METRIC_TAGS;
import static
org.apache.camel.component.micrometer.MicrometerConstants.METRICS_REGISTRY_NAME;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
@CamelSpringTest
public class CounterRouteTest extends CamelSpringTestSupport {
@@ -56,6 +61,9 @@ public class CounterRouteTest extends CamelSpringTestSupport {
@Produce("direct:in-4")
private ProducerTemplate producer4;
+ @Produce("direct:in-5")
+ private ProducerTemplate producer5;
+
@BindToRegistry(METRICS_REGISTRY_NAME)
private MeterRegistry registry = new SimpleMeterRegistry();
@@ -85,6 +93,10 @@ public class CounterRouteTest extends CamelSpringTestSupport
{
from("direct:in-4")
.to("micrometer:counter:D?increment=${body.length}&tags.a=${body.length}")
.to("mock:out");
+
+ from("direct:in-5")
+
.to("micrometer:counter:I?tags.a=${body.length}&tags.b=uri")
+ .to("mock:out");
}
};
}
@@ -136,4 +148,32 @@ public class CounterRouteTest extends
CamelSpringTestSupport {
assertEquals(Integer.toString(message.length()),
counter.getId().getTag("a"));
endpoint.assertIsSatisfied();
}
+
+ @Test
+ public void testHeaderTagsAreUsedAsGiven() throws Exception {
+ endpoint.expectedMessageCount(1);
+ producer5.sendBodyAndHeaders("Hello", Map.of(
+ "k", "key",
+ HEADER_METRIC_TAGS, Tags.of("c", "${body}", "${header.k}",
"d")));
+ Counter counter = registry.find("I").counter();
+ assertEquals(1.0D, counter.count(), 0.01D);
+ // the tags from the uri are resolved per exchange
+ assertEquals("5", counter.getId().getTag("a"));
+ assertEquals("uri", counter.getId().getTag("b"));
+ // the tags from the header are not
+ assertEquals("${body}", counter.getId().getTag("c"));
+ assertEquals("d", counter.getId().getTag("${header.k}"));
+ assertNull(counter.getId().getTag("key"));
+ endpoint.assertIsSatisfied();
+ }
+
+ @Test
+ public void testHeaderTagOverridesUriTagWithSameKey() throws Exception {
+ endpoint.expectedMessageCount(1);
+ producer5.sendBodyAndHeader("Hello", HEADER_METRIC_TAGS, Tags.of("b",
"header"));
+ Counter counter = registry.find("I").counter();
+ assertEquals("5", counter.getId().getTag("a"));
+ assertEquals("header", counter.getId().getTag("b"));
+ endpoint.assertIsSatisfied();
+ }
}
diff --git
a/components/camel-opentelemetry-metrics/src/generated/resources/META-INF/org/apache/camel/opentelemetry/metrics/opentelemetry-metrics.json
b/components/camel-opentelemetry-metrics/src/generated/resources/META-INF/org/apache/camel/opentelemetry/metrics/opentelemetry-metrics.json
index 789943d1dee3..5ffaa82b14ed 100644
---
a/components/camel-opentelemetry-metrics/src/generated/resources/META-INF/org/apache/camel/opentelemetry/metrics/opentelemetry-metrics.json
+++
b/components/camel-opentelemetry-metrics/src/generated/resources/META-INF/org/apache/camel/opentelemetry/metrics/opentelemetry-metrics.json
@@ -35,7 +35,7 @@
"CamelMetricsCounterIncrement": { "index": 3, "kind": "header",
"displayName": "", "group": "producer", "label": "", "required": false,
"javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Override increment value in URI",
"constantName":
"org.apache.camel.opentelemetry.metrics.OpenTelemetryConstants#HEADER_COUNTER_INCREMENT"
},
"CamelMetricsName": { "index": 4, "kind": "header", "displayName": "",
"group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "Override name value in URI", "constantName":
"org.apache.camel.opentelemetry.metrics.OpenTelemetryConstants#HEADER_METRIC_NAME"
},
"CamelMetricsDescription": { "index": 5, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "Override description value in URI", "constantName":
"org.apache.camel.opentelemetry.metrics.OpenTelemetryConstants#HEADER_METRIC_DESCRIPTION"
},
- "CamelMetricsAttributes": { "index": 6, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType":
"io.opentelemetry.api.common.Attributes", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false, "description": "To
augment meter attributes defined as URI parameters", "constantName":
"org.apache.camel.opentelemetry.metrics.OpenTelemetryConstants#HEADER_METRIC_ATTRIBUTES"
}
+ "CamelMetricsAttributes": { "index": 6, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType":
"io.opentelemetry.api.common.Attributes", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false, "description": "To
augment meter attributes defined as URI parameters. The attributes from the
header are used as given; use the attributes URI parameters for Simple
expressions.", "constantName": "org.apache.camel.opentele [...]
},
"properties": {
"metricType": { "index": 0, "kind": "path", "displayName": "Metric Type",
"group": "producer", "label": "", "required": true, "type": "enum", "javaType":
"org.apache.camel.opentelemetry.metrics.InstrumentType", "enum": [ "counter",
"summary", "timer" ], "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Type of metrics" },
diff --git
a/components/camel-opentelemetry-metrics/src/main/docs/opentelemetry-metrics-component.adoc
b/components/camel-opentelemetry-metrics/src/main/docs/opentelemetry-metrics-component.adoc
index 6890a325bb17..e39125702e55 100644
---
a/components/camel-opentelemetry-metrics/src/main/docs/opentelemetry-metrics-component.adoc
+++
b/components/camel-opentelemetry-metrics/src/main/docs/opentelemetry-metrics-component.adoc
@@ -90,6 +90,11 @@ from("direct:in")
will update a counter with name `new.name` (instead of `name.not.used`) using
the attribute `dynamic-key` with value `dynamic-value` in addition to the
attribute `key` with value `value`.
+The attributes from the `CamelMetricsAttributes` header are used as given:
unlike the `attributes` URI parameters,
+their keys and values are not evaluated as `Simple` expressions. An attribute
from the header overrides an attribute
+from the URI with the same key. To add an attribute with a value from the
message, use an `attributes` URI parameter
+such as `attributes.customer=${header.customerId}`, or compute the value in
the route before setting the header.
+
All Metrics specific headers are removed from the message once the
OpenTelemetry endpoint finishes processing the exchange. While processing the
exchange
the OpenTelemetry endpoint will catch all exceptions and write log entry using
level `warn`.
diff --git
a/components/camel-opentelemetry-metrics/src/main/java/org/apache/camel/opentelemetry/metrics/AbstractOpenTelemetryProducer.java
b/components/camel-opentelemetry-metrics/src/main/java/org/apache/camel/opentelemetry/metrics/AbstractOpenTelemetryProducer.java
index f033094546e4..db469ee5a212 100644
---
a/components/camel-opentelemetry-metrics/src/main/java/org/apache/camel/opentelemetry/metrics/AbstractOpenTelemetryProducer.java
+++
b/components/camel-opentelemetry-metrics/src/main/java/org/apache/camel/opentelemetry/metrics/AbstractOpenTelemetryProducer.java
@@ -16,10 +16,6 @@
*/
package org.apache.camel.opentelemetry.metrics;
-import java.util.HashMap;
-import java.util.Map;
-
-import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import org.apache.camel.Exchange;
@@ -63,14 +59,13 @@ abstract public class AbstractOpenTelemetryProducer<T>
extends DefaultProducer {
String defaultMetricsDescription = simple(exchange,
getEndpoint().getMetricsDescription(), String.class);
String finalMetricsDescription = getStringHeader(in,
HEADER_METRIC_DESCRIPTION, defaultMetricsDescription);
- Map<AttributeKey<?>, Object> map = new HashMap<>(attributes.asMap());
- map.putAll(getAttributesHeader(in, HEADER_METRIC_ATTRIBUTES,
Attributes.empty()).asMap());
-
+ // only the attributes from the endpoint are simple expressions, the
attributes from the header are used as given
AttributesBuilder ab = Attributes.builder();
- for (Map.Entry<AttributeKey<?>, Object> entry : map.entrySet()) {
- ab.put(simple(exchange, entry.getKey().toString(), String.class),
- simple(exchange, entry.getValue().toString(),
String.class));
- }
+ attributes.forEach((key, value) -> ab.put(
+ simple(exchange, key.getKey(), String.class),
+ simple(exchange, value.toString(), String.class)));
+ getAttributesHeader(in, HEADER_METRIC_ATTRIBUTES, Attributes.empty())
+ .forEach((key, value) -> ab.put(key.getKey(),
value.toString()));
ab.put(CAMEL_CONTEXT_ATTRIBUTE,
getEndpoint().getCamelContext().getName());
try {
diff --git
a/components/camel-opentelemetry-metrics/src/main/java/org/apache/camel/opentelemetry/metrics/OpenTelemetryConstants.java
b/components/camel-opentelemetry-metrics/src/main/java/org/apache/camel/opentelemetry/metrics/OpenTelemetryConstants.java
index 2a2d61c78b94..dcaa6a7000f2 100644
---
a/components/camel-opentelemetry-metrics/src/main/java/org/apache/camel/opentelemetry/metrics/OpenTelemetryConstants.java
+++
b/components/camel-opentelemetry-metrics/src/main/java/org/apache/camel/opentelemetry/metrics/OpenTelemetryConstants.java
@@ -34,7 +34,8 @@ public class OpenTelemetryConstants {
public static final String HEADER_METRIC_NAME = HEADER_PREFIX + "Name";
@Metadata(description = "Override description value in URI", javaType =
"String")
public static final String HEADER_METRIC_DESCRIPTION = HEADER_PREFIX +
"Description";
- @Metadata(description = "To augment meter attributes defined as URI
parameters",
+ @Metadata(description = "To augment meter attributes defined as URI
parameters. The attributes from the header are used"
+ + " as given; use the attributes URI parameters
for Simple expressions.",
javaType = "io.opentelemetry.api.common.Attributes")
public static final String HEADER_METRIC_ATTRIBUTES = HEADER_PREFIX +
"Attributes";
diff --git
a/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/CounterRouteTest.java
b/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/CounterRouteTest.java
index 9756532f35ce..5dfb1039fafd 100644
---
a/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/CounterRouteTest.java
+++
b/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/CounterRouteTest.java
@@ -17,6 +17,7 @@
package org.apache.camel.opentelemetry.metrics;
import java.util.Collection;
+import java.util.Map;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
@@ -36,6 +37,7 @@ import static
org.apache.camel.opentelemetry.metrics.OpenTelemetryConstants.HEAD
import static
org.apache.camel.opentelemetry.metrics.OpenTelemetryConstants.HEADER_METRIC_NAME;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNull;
public class CounterRouteTest extends CamelTestSupport {
@@ -76,6 +78,10 @@ public class CounterRouteTest extends CamelTestSupport {
.setHeader(OpenTelemetryConstants.HEADER_COUNTER_INCREMENT,
simple("${body.length}"))
.to("opentelemetry-metrics:counter:F")
.to("mock:result");
+
+ from("direct:in7")
+
.to("opentelemetry-metrics:counter:J?attributes.a=${body.length}&attributes.b=uri")
+ .to("mock:result");
}
};
}
@@ -226,6 +232,40 @@ public class CounterRouteTest extends CamelTestSupport {
MockEndpoint.assertIsSatisfied(context);
}
+ @Test
+ public void testHeaderAttributesAreUsedAsGiven() throws Exception {
+ MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
+ mockEndpoint.expectedMessageCount(1);
+ template.sendBodyAndHeaders("direct:in7", "Hello", Map.of(
+ "k", "key",
+ HEADER_METRIC_ATTRIBUTES, Attributes.of(
+ AttributeKey.stringKey("c"), "${body}",
+ AttributeKey.stringKey("${header.k}"), "d")));
+
+ Attributes attributes = getMetric("J").getAttributes();
+ // the attributes from the uri are resolved per exchange
+ assertEquals("5", attributes.get(AttributeKey.stringKey("a")));
+ assertEquals("uri", attributes.get(AttributeKey.stringKey("b")));
+ // the attributes from the header are not
+ assertEquals("${body}", attributes.get(AttributeKey.stringKey("c")));
+ assertEquals("d",
attributes.get(AttributeKey.stringKey("${header.k}")));
+ assertNull(attributes.get(AttributeKey.stringKey("key")));
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testHeaderAttributeOverridesUriAttributeWithSameKey() throws
Exception {
+ MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
+ mockEndpoint.expectedMessageCount(1);
+ template.sendBodyAndHeader("direct:in7", "Hello",
HEADER_METRIC_ATTRIBUTES,
+ Attributes.of(AttributeKey.stringKey("b"), "header"));
+
+ Attributes attributes = getMetric("J").getAttributes();
+ assertEquals("5", attributes.get(AttributeKey.stringKey("a")));
+ assertEquals("header", attributes.get(AttributeKey.stringKey("b")));
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
protected LongPointData getMetric(String metricName) {
PointData pd = otelExtension.getMetrics().stream()
.filter(d -> d.getName().equals(metricName))
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MicrometerEndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MicrometerEndpointBuilderFactory.java
index 8eaeb80ca7fc..8fa3ab03f49e 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MicrometerEndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MicrometerEndpointBuilderFactory.java
@@ -365,7 +365,9 @@ public interface MicrometerEndpointBuilderFactory {
return "CamelMetricsDescription";
}
/**
- * To augment meter tags defined as URI parameters.
+ * To augment meter tags defined as URI parameters. The tags from the
+ * header are used as given; use the tags URI parameters for Simple
+ * expressions.
*
* The option is a: {@code java.lang.Iterable<Tag>} type.
*
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpenTelemetryEndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpenTelemetryEndpointBuilderFactory.java
index efe458b25c3b..e5d029e1e922 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpenTelemetryEndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpenTelemetryEndpointBuilderFactory.java
@@ -395,7 +395,9 @@ public interface OpenTelemetryEndpointBuilderFactory {
return "CamelMetricsDescription";
}
/**
- * To augment meter attributes defined as URI parameters.
+ * To augment meter attributes defined as URI parameters. The
attributes
+ * from the header are used as given; use the attributes URI parameters
+ * for Simple expressions.
*
* The option is a: {@code io.opentelemetry.api.common.Attributes}
type.
*