cxdot.integration.name=otlp, not micrometer. The Micrometer integration stays listed as
available after its metrics arrive, and it reports no health status.
Adding the OTLP registry is additive. Spring Boot sends every metric to every registry the
app includes, so your existing StatsD or Datadog registry keeps sending what it sends today.
The CXDOT Collector supports Micrometer 1.11 or greater.
Supported telemetry types
The CXDOT Collector supports these telemetry types from Micrometer:Prerequisites
Sending Micrometer metrics over OTLP has the following prerequisites:- Find each service’s Spring Boot version: look for
spring-bootin its Gradle or Maven dependencies. The setup differs by Spring Boot line. - Micrometer 1.11 or greater, the first version that sends delta temporality. Spring Boot 3.1 and later include it. Spring Boot 2 and 3.0 include an older version. See Upgrade Micrometer. Upgrading Micrometer doesn’t require upgrading Spring Boot.
- Run the CXDOT Collector on each node with host networking, the Helm chart’s default. OTLP
ingest is on by default, so apps send to their node’s IP address on port
4318.
Configure
Follow the section for each service’s Spring Boot line, then confirm collection with the steps in Validate.Spring Boot 2 (2.5 to 2.7)
Spring Boot 2 includes Micrometer 1.7 to 1.9 and doesn’t configure the OTLP registry itself. To send metrics from a Spring Boot 2 service, follow these steps:- Upgrade Micrometer to 1.11 or greater. See Upgrade Micrometer.
-
Add the Micrometer OTLP registry. For example, add the following to the
dependenciesblock ofbuild.gradle:Keep any registry the app already uses, such as StatsD, until you stop sending to it. -
Define the OTLP registry as a bean. Spring Boot adds it beside your other registries and
applies your common tags and distribution settings to it. For example, add the following
class to your app:
-
Point the registry at the CXDOT Collector on the same node, and set delta temporality. For
example, set these environment variables on the app’s container:
If your services already set
HOST_IPorDD_AGENT_HOSTfor StatsD, reuse it: both hold the node’s address. The same settings work asmanagement.otlp.metrics.export.urlandmanagement.otlp.metrics.export.aggregation-temporalityin your app’s configuration. -
Set
OTEL_SERVICE_NAMEto the service’s name, and any other resource attributes withOTEL_RESOURCE_ATTRIBUTES. The bean doesn’t take the name fromspring.application.name. -
Optional: Turn on percentile histograms, so Palo Alto Networks Cortex XCOR can calculate
percentiles across all of a service’s instances. Set
management.metrics.distribution.percentiles-histogram.http.server.requests=truefor each timer you want percentiles for. If the service also sends to Datadog through the StatsD registry, wait until you turn StatsD off. The setting makes StatsD send timers as distributions. Datadog then stops receiving the timers’.avg,.count,.max,.median, and.95percentilemetrics. Client-side percentiles, themanagement.metrics.distribution.percentilessetting, don’t reach Cortex XCOR from a timer that also has service level objective (SLO) boundaries. The OTLP registry sends that timer’s histogram instead of the percentiles. Use percentile histograms for those timers. -
Optional: To get each timer’s exact maximum, register a gauge in your app that reads it.
For example, use a Micrometer
TimeGaugeoverTimer.max(). Without a gauge, you can only estimate a timer’s maximum from its percentile histogram buckets.
Spring Boot 3 (3.0 to 3.5)
Spring Boot 3 configures the OTLP registry for you. Spring Boot 3.1 and later include Micrometer 1.11 or greater and have an aggregation temporality setting. Spring Boot 3.0 includes Micrometer 1.10 and has no such setting, so it needs two extra steps, marked in the following list. To send metrics from a Spring Boot 3 service, follow these steps:- Spring Boot 3.0 only: Upgrade Micrometer to 1.11 or greater, since 3.0 includes 1.10. See Upgrade Micrometer.
-
Add the Micrometer OTLP registry. For example, add the following to the
dependenciesblock ofbuild.gradle:Spring Boot manages the version. Keep any registry the app already uses, such as StatsD, until you stop sending to it. -
Spring Boot 3.0 only: Define the registry’s configuration as a bean. Spring Boot 3.0 has
no aggregation temporality setting, and builds the registry from your bean instead of its
own. For example, add the following class to your app:
With the bean, also set
OTEL_SERVICE_NAMEto the service’s name, and any other resource attributes withOTEL_RESOURCE_ATTRIBUTES. -
Point the registry at the CXDOT Collector on the same node, and set delta temporality. For
example, set these environment variables on the app’s container:
If your services already set
HOST_IPorDD_AGENT_HOSTfor StatsD, reuse it: both hold the node’s address. The same settings work asmanagement.otlp.metrics.export.urlandmanagement.otlp.metrics.export.aggregation-temporalityin your app’s configuration. -
Optional: Turn on percentile histograms, so Cortex XCOR can calculate
percentiles across all of a service’s instances. Set
management.metrics.distribution.percentiles-histogram.http.server.requests=truefor each timer you want percentiles for. If the service also sends to Datadog through the StatsD registry, wait until you turn StatsD off. The setting makes StatsD send timers as distributions. Datadog then stops receiving the timers’.avg,.count,.max,.median, and.95percentilemetrics. Client-side percentiles, themanagement.metrics.distribution.percentilessetting, don’t reach Cortex XCOR from a timer that also has service level objective (SLO) boundaries. The OTLP registry sends that timer’s histogram instead of the percentiles. Use percentile histograms for those timers. -
Optional: To get each timer’s exact maximum, register a gauge in your app that reads it.
For example, use a Micrometer
TimeGaugeoverTimer.max(). Without a gauge, you can only estimate a timer’s maximum from its percentile histogram buckets.
Spring Boot 4 (4.0 and 4.1)
Spring Boot 4 includes Micrometer 1.16 or greater, and configures the OTLP registry once the app includes Spring Boot’s OpenTelemetry module. To send metrics from a Spring Boot 4 service, follow these steps:-
Add the Micrometer OTLP registry and Spring Boot’s OpenTelemetry module. For example, add
the following to the
dependenciesblock ofbuild.gradle:spring-boot-starter-opentelemetryalso includes the module. Without it, Spring Boot 4 doesn’t configure the OTLP registry, and logs nothing about it. Keep any registry the app already uses, such as StatsD, until you stop sending to it. -
Point the registry at the CXDOT Collector on the same node, and set delta temporality. For
example, set these environment variables on the app’s container:
If your services already set
HOST_IPorDD_AGENT_HOSTfor StatsD, reuse it: both hold the node’s address. The same settings work asmanagement.otlp.metrics.export.urlandmanagement.otlp.metrics.export.aggregation-temporalityin your app’s configuration. On Spring Boot 4.1, OpenTelemetry environment variables such asOTEL_EXPORTER_OTLP_ENDPOINTandOTEL_METRIC_EXPORT_INTERVALoverride these settings. If the app’s container sets them for another OpenTelemetry exporter, setmanagement.opentelemetry.map-environment-variables=falseso the registry keeps your settings. -
Optional: Turn on percentile histograms, so Cortex XCOR can calculate
percentiles across all of a service’s instances. Set
management.metrics.distribution.percentiles-histogram.http.server.requests=truefor each timer you want percentiles for. If the service also sends to Datadog through the StatsD registry, wait until you turn StatsD off. The setting makes StatsD send timers as distributions. Datadog then stops receiving the timers’.avg,.count,.max,.median, and.95percentilemetrics. Client-side percentiles, themanagement.metrics.distribution.percentilessetting, don’t reach Cortex XCOR from a timer that also has service level objective (SLO) boundaries. The OTLP registry sends that timer’s histogram instead of the percentiles. Use percentile histograms for those timers. -
Optional: For each timer’s exact maximum:
- Spring Boot 4.1: Set
management.otlp.metrics.export.publish-max-gauge-for-histograms=true. The registry then also sends each timer’s maximum as a gauge, such ashttp.server.requests.max. - Spring Boot 4.0: Register a gauge in your app that reads the timer’s maximum. For
example, use a Micrometer
TimeGaugeoverTimer.max().
- Spring Boot 4.1: Set
Upgrade Micrometer
Spring Boot 2 and 3.0 include a Micrometer version older than 1.11. To upgrade Micrometer, follow these steps:-
Check the version. In Gradle, run
./gradlew dependencyInsight --dependency micrometer-core. In Maven, runmvn dependency:tree -Dincludes=io.micrometer. -
Set the version with the form that matches how your build manages dependency versions:
-
Gradle with the Spring dependency management plugin
(
io.spring.dependency-management). Add the following tobuild.gradle: -
Gradle with Spring Boot’s bill of materials imported as a platform. Add the following to
the
dependenciesblock. UseenforcedPlatformso it overrides the version Spring Boot’s bill of materials sets: -
Maven with
spring-boot-starter-parentas the parent. Add the following topom.xml: -
Maven importing
spring-boot-dependenciesas a bill of materials. Import the Micrometer bill of materials first, so its versions win:
-
Gradle with the Spring dependency management plugin
(
- Check the version again. If it still shows the old version, the form doesn’t match how your build manages versions. The build ignores a property it doesn’t read and reports no error.
Validate
To validate collection, follow these steps:-
In the Live Telemetry Analyzer,
filter on
__name__=jvm.memory.used. Confirm that time series from your app arrive. -
In Metrics Explorer,
run the following query:
Confirm that the query reports a value for your app.
Troubleshooting
- No OTLP metrics from a Spring Boot 2 app: Confirm that the app defines the registry bean, and that Micrometer is 1.11 or greater.
- No OTLP metrics from a Spring Boot 4 app: Confirm that the app includes
spring-boot-opentelemetry. On Spring Boot 4.1, also read the URL in the app’sFailed to publish metrics to OTLP receiverwarnings. AnOTEL_EXPORTER_OTLP_ENDPOINTset for another exporter, often on port4317, overrides the registry’s URL. In that case, setmanagement.opentelemetry.map-environment-variables=false. - Micrometer still reports the old version after you upgrade: The Gradle or Maven form doesn’t
match your build. For example,
ext['micrometer.version']has no effect when your build imports Spring Boot’s bill of materials as a Gradle platform. Use the form in Upgrade Micrometer that matches your build. - Counters and timers look cumulative: The app isn’t sending delta temporality. On Spring
Boot 2, use the registry bean exactly as shown. A bean that maps only exact property names
misses the
aggregation-temporalitysetting. On Spring Boot 3.0, Spring Boot ignores the setting unless the app defines theOtlpConfigbean. Before Spring Boot 4.1,OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCEdoesn’t replace the setting. - Timer maximums are missing: Cortex XCOR keeps a histogram’s count, sum, and buckets, but not its maximum, whatever the temporality. Send the maximum as a gauge, as the optional maximum step for your Spring Boot line describes.
- Metrics carry
service.name="unknown_service": On Spring Boot 2 and 3.0, setOTEL_SERVICE_NAMEon the app. - Request counts are double what you expect: The app’s metrics reach the CXDOT Collector by two paths, for example over OTLP and as DogStatsD forwarded by another agent. Send each app’s metrics by one path.
Turn off your previous registry
Keep your existing registry until the service’s dashboards and monitors work with the OTLP metrics. Their queries don’t change on their own: the OTLP registry sends different metric names and shapes, so rewrite each query with the forms in Query Micrometer metrics. While both registries send, expect the old and new charts to agree in level but not point for point, because each registry samples gauges at its own moments. Queries on Datadog’s.median and .95percentile timer metrics, and on client-side
percentiles of a timer with SLO boundaries, need percentile histograms on that timer. Without
them, the OTLP registry sends nothing to calculate those values from. With the StatsD
registry, turning on percentile histograms also changes what Datadog receives, so turn them on
as part of the cutover.
When the dashboards and monitors work, turn off the old registry and restart the service:
Query Micrometer metrics
Cortex XCOR keeps Micrometer’s dotted metric names, so queries quote them. Your Micrometer tags carry over as labels of the same name. The following table lists queries for common questions about a service, and the timer setting each query needs:
Cortex XCOR stores a histogram’s count, sum, and buckets, but not its maximum.
Without a gauge, a timer’s maximum is an estimate: the upper bound of the bucket that holds
the slowest request. On Spring Boot 4.1, set
management.otlp.metrics.export.publish-max-gauge-for-histograms=true. The registry then also
sends each timer’s maximum as a gauge named after the timer, such as
{"http.server.requests.max"}. On earlier Spring Boot lines, register a gauge in your app
that reads the timer’s maximum. For example, use a Micrometer TimeGauge over Timer.max().