From 8a697b5f3ee6cd8888372dd539cf8be08fa00764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sun, 23 Aug 2026 18:17:43 +0200 Subject: [PATCH 1/4] SOLR-18400: Plugins screen 500s when metrics are disabled /admin/metrics now returns a valid Prometheus response with an explanatory comment instead of a 500 when metrics collection is disabled, and the Plugins screen shows a message instead of a blank page. --- .../SOLR-18400-plugins-metrics-disabled.yml | 10 ++++ .../response/PrometheusResponseWriter.java | 7 +++ ...ometheusResponseWriterMetricsDisabled.java | 48 +++++++++++++++++++ .../web/js/angular/controllers/plugins.js | 1 + solr/webapp/web/partials/plugins.html | 3 ++ 5 files changed, 69 insertions(+) create mode 100644 changelog/unreleased/SOLR-18400-plugins-metrics-disabled.yml create mode 100644 solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriterMetricsDisabled.java diff --git a/changelog/unreleased/SOLR-18400-plugins-metrics-disabled.yml b/changelog/unreleased/SOLR-18400-plugins-metrics-disabled.yml new file mode 100644 index 000000000000..90eab77d6afc --- /dev/null +++ b/changelog/unreleased/SOLR-18400-plugins-metrics-disabled.yml @@ -0,0 +1,10 @@ +title: > + Admin UI Plugins screen no longer fails with a 500 error when metrics collection is disabled. + The /admin/metrics endpoint now returns a valid Prometheus response with an explanatory comment, + and the Plugins screen displays a message instead of a blank page. +type: fixed +authors: + - name: Jan Høydahl +links: + - name: SOLR-18400 + url: https://issues.apache.org/jira/browse/SOLR-18400 diff --git a/solr/core/src/java/org/apache/solr/response/PrometheusResponseWriter.java b/solr/core/src/java/org/apache/solr/response/PrometheusResponseWriter.java index d56a85b9bbe5..daa26ce84762 100644 --- a/solr/core/src/java/org/apache/solr/response/PrometheusResponseWriter.java +++ b/solr/core/src/java/org/apache/solr/response/PrometheusResponseWriter.java @@ -63,6 +63,13 @@ public void write( // Otherwise handle MetricSnapshots var metrics = response.getValues().get("metrics"); if (metrics == null) { + // No snapshots available, e.g. when metrics collection is disabled. Emit the reason as a + // comment so the response is still a valid Prometheus exposition + var error = response.getValues().get("error"); + if (error != null) { + out.write(("# " + error + "\n").getBytes(StandardCharsets.UTF_8)); + return; + } throw new IOException("No metrics found in response"); } MetricSnapshots snapshots = (MetricSnapshots) metrics; diff --git a/solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriterMetricsDisabled.java b/solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriterMetricsDisabled.java new file mode 100644 index 000000000000..0e50b3661ad4 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriterMetricsDisabled.java @@ -0,0 +1,48 @@ +/* + * 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.solr.response; + +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.apache.solr.client.solrj.request.MetricsRequest; +import org.apache.solr.cloud.SolrCloudTestCase; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.NamedList; +import org.junit.BeforeClass; +import org.junit.Test; + +/** SOLR-18400: /admin/metrics must not 500 when metrics collection is disabled. */ +public class TestPrometheusResponseWriterMetricsDisabled extends SolrCloudTestCase { + + @BeforeClass + public static void setupCluster() throws Exception { + // metrics collection is disabled by default in MiniSolrCloudCluster + configureCluster(1).configure(); + } + + @Test + public void testMetricsDisabledReturnsComment() throws Exception { + var req = new MetricsRequest(SolrParams.of("wt", "prometheus")); + + NamedList resp = cluster.getSolrClient().request(req); + assertEquals(200, resp.get("responseStatus")); + try (InputStream in = (InputStream) resp.get("stream")) { + String output = new String(in.readAllBytes(), StandardCharsets.UTF_8); + assertEquals("# metrics collection is disabled\n", output); + } + } +} diff --git a/solr/webapp/web/js/angular/controllers/plugins.js b/solr/webapp/web/js/angular/controllers/plugins.js index bf0dd9bcac73..032a785fb17a 100644 --- a/solr/webapp/web/js/angular/controllers/plugins.js +++ b/solr/webapp/web/js/angular/controllers/plugins.js @@ -35,6 +35,7 @@ solrAdminApp.controller('PluginsController', var type = $location.search().type; Metrics.raw(params, function (response) { + $scope.metricsDisabled = (response.data || '').indexOf('metrics collection is disabled') !== -1; $scope.types = getPluginTypesFromMetrics(response.data, type); $scope.type = getSelectedType($scope.types, type); diff --git a/solr/webapp/web/partials/plugins.html b/solr/webapp/web/partials/plugins.html index 1e80b6f9b6e7..51bc7bd04959 100644 --- a/solr/webapp/web/partials/plugins.html +++ b/solr/webapp/web/partials/plugins.html @@ -17,6 +17,9 @@
+
+
Metrics collection is disabled on this node, so no plugin information is available. Start Solr with metricsEnabled=true to enable it.
+