This is an automated email from the ASF dual-hosted git repository.
janhoy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 6f0d0b5b729 Fix consumers of JVM CPU metrics renamed by OTel
Prometheus exporter update (#4711)
6f0d0b5b729 is described below
commit 6f0d0b5b7295611acf7c3d95030530b415a4b965
Author: Jan Høydahl <[email protected]>
AuthorDate: Fri Aug 7 19:37:45 2026 +0200
Fix consumers of JVM CPU metrics renamed by OTel Prometheus exporter update
(#4711)
This also fixes the PlacementPluginIntegrationTest.testAttributeFetcherImpl
test failures
---
.../fix-jvm-cpu-utilization-metric-name.yml | 10 +++++
.../cluster/placement/impl/NodeMetricImpl.java | 2 +-
.../util/circuitbreaker/CPUCircuitBreaker.java | 2 +-
.../org/apache/solr/util/TestCircuitBreakers.java | 48 ++++++++++++++++++++++
.../pages/major-changes-in-solr-10.adoc | 3 ++
.../solr/client/solrj/impl/NodeValueFetcher.java | 2 +-
6 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/changelog/unreleased/fix-jvm-cpu-utilization-metric-name.yml
b/changelog/unreleased/fix-jvm-cpu-utilization-metric-name.yml
new file mode 100644
index 00000000000..1c329ff841d
--- /dev/null
+++ b/changelog/unreleased/fix-jvm-cpu-utilization-metric-name.yml
@@ -0,0 +1,10 @@
+title: >
+ The Prometheus JVM CPU metrics are now named `jvm_system_cpu_utilization` and
+ `jvm_cpu_recent_utilization` (the `_ratio` suffix was dropped) following the
+ OpenTelemetry Prometheus exporter update.
+type: changed
+authors:
+ - name: Jan Høydahl
+links:
+ - name: PR#4711
+ url: https://github.com/apache/solr/pull/4711
diff --git
a/solr/core/src/java/org/apache/solr/cluster/placement/impl/NodeMetricImpl.java
b/solr/core/src/java/org/apache/solr/cluster/placement/impl/NodeMetricImpl.java
index 4f76896a320..96ba2d1b676 100644
---
a/solr/core/src/java/org/apache/solr/cluster/placement/impl/NodeMetricImpl.java
+++
b/solr/core/src/java/org/apache/solr/cluster/placement/impl/NodeMetricImpl.java
@@ -38,7 +38,7 @@ public class NodeMetricImpl<T> extends MetricImpl<T>
implements NodeMetric<T> {
/** System load average. */
public static final NodeMetricImpl<Double> SYSLOAD_AVG =
- new NodeMetricImpl<>("sysLoadAvg", "jvm_system_cpu_utilization_ratio");
+ new NodeMetricImpl<>("sysLoadAvg", "jvm_system_cpu_utilization");
/** Number of available processors. */
public static final NodeMetricImpl<Integer> AVAILABLE_PROCESSORS =
diff --git
a/solr/core/src/java/org/apache/solr/util/circuitbreaker/CPUCircuitBreaker.java
b/solr/core/src/java/org/apache/solr/util/circuitbreaker/CPUCircuitBreaker.java
index 09248363bcd..391f88049dc 100644
---
a/solr/core/src/java/org/apache/solr/util/circuitbreaker/CPUCircuitBreaker.java
+++
b/solr/core/src/java/org/apache/solr/util/circuitbreaker/CPUCircuitBreaker.java
@@ -112,7 +112,7 @@ public class CPUCircuitBreaker extends CircuitBreaker
implements SolrCoreAware {
return this.cc
.getMetricManager()
.getPrometheusMetricReader("solr.jvm")
- .collect(name -> name.contains("jvm_system_cpu_utilization_ratio"))
+ .collect(name -> name.contains("jvm_system_cpu_utilization"))
.stream()
.filter(GaugeSnapshot.class::isInstance)
.map(GaugeSnapshot.class::cast)
diff --git a/solr/core/src/test/org/apache/solr/util/TestCircuitBreakers.java
b/solr/core/src/test/org/apache/solr/util/TestCircuitBreakers.java
index 648ac035854..88bdee78087 100644
--- a/solr/core/src/test/org/apache/solr/util/TestCircuitBreakers.java
+++ b/solr/core/src/test/org/apache/solr/util/TestCircuitBreakers.java
@@ -19,8 +19,10 @@ package org.apache.solr.util;
import static org.hamcrest.CoreMatchers.containsString;
+import com.sun.management.OperatingSystemMXBean;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
+import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@@ -30,6 +32,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
+import org.apache.lucene.util.SuppressForbidden;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.common.SolrException;
@@ -43,6 +46,7 @@ import
org.apache.solr.util.circuitbreaker.CircuitBreakerRegistry;
import org.apache.solr.util.circuitbreaker.LoadAverageCircuitBreaker;
import org.apache.solr.util.circuitbreaker.MemoryCircuitBreaker;
import org.junit.After;
+import org.junit.Assume;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -271,6 +275,39 @@ public class TestCircuitBreakers extends SolrTestCaseJ4 {
assertThatHighQueryLoadTrips(circuitBreaker, 5);
}
+ /**
+ * Reads a real CPU usage value from the metrics, guarding against a
regression where a renamed
+ * JVM metric made {@link CPUCircuitBreaker#calculateLiveCPUUsage()}
silently return -1. Gated by
+ * an independent native-CPU probe so that a name regression fails here
rather than being mistaken
+ * for an unsupported machine (both otherwise yield -1).
+ */
+ public void testCPUCircuitBreakerReadsLiveUsage() {
+ Assume.assumeTrue("No native CPU measurement on this machine",
nativeCpuMeasurementSupported());
+
+ double usage = new
ExposedCPUCircuitBreaker(h.getCoreContainer()).liveCPUUsage();
+ assertTrue("Expected CPU usage >= 0 but got " + usage, usage >= 0);
+ }
+
+ @SuppressForbidden(reason = "Probing com.sun OperatingSystemMXBean for
native CPU support")
+ private static boolean nativeCpuMeasurementSupported() {
+ if (!(ManagementFactory.getOperatingSystemMXBean() instanceof
OperatingSystemMXBean osBean)) {
+ return false;
+ }
+ // getCpuLoad() needs two samples and may return a negative value on the
first calls
+ for (int i = 0; i < 10; i++) {
+ if (osBean.getCpuLoad() >= 0) {
+ return true;
+ }
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return false;
+ }
+ }
+ return false;
+ }
+
/**
* Common assert method to be reused in tests
*
@@ -441,6 +478,17 @@ public class TestCircuitBreakers extends SolrTestCaseJ4 {
}
}
+ /** Exposes the real (protected) CPU usage calculation for testing. */
+ private static class ExposedCPUCircuitBreaker extends CPUCircuitBreaker {
+ public ExposedCPUCircuitBreaker(CoreContainer coreContainer) {
+ super(coreContainer);
+ }
+
+ double liveCPUUsage() {
+ return calculateLiveCPUUsage();
+ }
+ }
+
private static class FakeLoadAverageCircuitBreaker extends
LoadAverageCircuitBreaker {
@Override
protected double calculateLiveLoadAverage() {
diff --git
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
index c3ae79d9afa..a065a7413e1 100644
---
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
+++
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
@@ -420,6 +420,9 @@ Users who consume Solr metrics via OTLP and rely on the
10.0 underscore-format n
(e.g., `crossdc.consumer.output.total` →
`solr.crossdc.consumer.output.total`)
* All CrossDC producer metrics have been renamed:
`solr.core.crossdc.producer.*` → `solr.crossdc.producer.*`
(e.g., `solr.core.crossdc.producer.submitted` →
`solr.crossdc.producer.submitted`)
+* The Prometheus JVM CPU utilization metrics lost their `_ratio` suffix, as
the updated OpenTelemetry
+ exporter no longer maps the OTel unit `1` to a `_ratio` suffix:
`jvm_system_cpu_utilization_ratio` →
+ `jvm_system_cpu_utilization` and `jvm_cpu_recent_utilization_ratio` →
`jvm_cpu_recent_utilization`.
Update your dashboards or other metrics consumers accordingly.
diff --git
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/NodeValueFetcher.java
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/NodeValueFetcher.java
index 3dd91fca5d3..abd31c5d86c 100644
---
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/NodeValueFetcher.java
+++
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/NodeValueFetcher.java
@@ -74,7 +74,7 @@ public class NodeValueFetcher {
.sum();
}
},
- SYSLOADAVG("sysLoadAvg", "jvm_system_cpu_utilization_ratio");
+ SYSLOADAVG("sysLoadAvg", "jvm_system_cpu_utilization");
public final String tagName;
public final String metricName;