diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index a048351789b..7bf6c07eb0f 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -27,7 +27,8 @@ Optimizations Bug Fixes --------------------- -* PR#2680: Improve reliablity of NpmTasks finding needed files/commands. (Tyler Bertrand via Eric Pugh) +* SOLR-17587: Metrics: wt=prometheus fix for non-compliant exposition format containing duplicate TYPE lines. + (Matthew Biscocho via David Smiley) Dependency Upgrades --------------------- @@ -41,6 +42,8 @@ Other Changes * GITHUB#2869: SolrTestCase now supports @LogLevel annotations (as SolrTestCaseJ4 has). Added LogLevelTestRule for encapsulation and reuse. (David Smiley) +* GITHUB#2680: Improve reliablity of NpmTasks finding needed files/commands. (Tyler Bertrand via Eric Pugh) + ================== 9.8.0 ================== New Features --------------------- diff --git a/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java index 73da8a818e4..4bba3414be9 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java @@ -186,10 +186,20 @@ private NamedList handlePrometheusExport(SolrParams params) { List metricTypes = parseMetricTypes(params); List metricFilters = metricTypes.stream().map(MetricType::asMetricFilter).collect(Collectors.toList()); + Set requestedRegistries = parseRegistries(params); + MetricRegistry mergedCoreRegistries = new MetricRegistry(); for (String registryName : requestedRegistries) { MetricRegistry dropwizardRegistry = metricManager.registry(registryName); + + // Merge all core registries into a single registry and + // append the core name to the metric to avoid duplicate metrics name + if (registryName.startsWith("solr.core")) { + mergedCoreRegistries.registerAll(getCoreNameFromRegistry(registryName), dropwizardRegistry); + continue; + } + PrometheusResponseWriter.toPrometheus( dropwizardRegistry, registryName, @@ -203,6 +213,22 @@ private NamedList handlePrometheusExport(SolrParams params) { response.add(registryName, registry); }); } + + if (!mergedCoreRegistries.getMetrics().isEmpty()) { + PrometheusResponseWriter.toPrometheus( + mergedCoreRegistries, + "solr.core", + metricFilters, + mustMatchFilter, + propertyFilter, + false, + false, + true, + (registry) -> { + response.add("solr.core", registry); + }); + } + return response; } @@ -523,6 +549,11 @@ private List parseMetricTypes(SolrParams params) { return metricTypes; } + private String getCoreNameFromRegistry(String registryName) { + String coreName = registryName.substring(registryName.indexOf('.') + 1); + return coreName.replace(".", "_"); + } + @Override public String getDescription() { return "A handler to return all the metrics gathered by Solr"; diff --git a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/PrometheusCoreFormatterInfo.java b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/PrometheusCoreFormatterInfo.java index baa7be5898b..b80b406d356 100644 --- a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/PrometheusCoreFormatterInfo.java +++ b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/PrometheusCoreFormatterInfo.java @@ -16,8 +16,6 @@ */ package org.apache.solr.metrics.prometheus.core; -import java.util.regex.Pattern; - public interface PrometheusCoreFormatterInfo { /** Category of prefix Solr Core dropwizard handler metric names */ enum CoreCategory { @@ -32,6 +30,4 @@ enum CoreCategory { INDEX, CORE } - - Pattern CLOUD_CORE_PATTERN = Pattern.compile("^core_(.*)_(shard[0-9]+)_(replica_.[0-9]+)$"); } diff --git a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreCacheMetric.java b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreCacheMetric.java index e8352d3575c..d4d9627c222 100644 --- a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreCacheMetric.java +++ b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreCacheMetric.java @@ -24,9 +24,8 @@ public class SolrCoreCacheMetric extends SolrCoreMetric { public static final String CORE_CACHE_SEARCHER_METRICS = "solr_metrics_core_cache"; - public SolrCoreCacheMetric( - Metric dropwizardMetric, String coreName, String metricName, boolean cloudMode) { - super(dropwizardMetric, coreName, metricName, cloudMode); + public SolrCoreCacheMetric(Metric dropwizardMetric, String metricName) { + super(dropwizardMetric, metricName); } /* diff --git a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreHandlerMetric.java b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreHandlerMetric.java index af9641729a9..9273e825759 100644 --- a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreHandlerMetric.java +++ b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreHandlerMetric.java @@ -30,9 +30,8 @@ public class SolrCoreHandlerMetric extends SolrCoreMetric { public static final String CORE_REQUESTS_TOTAL_TIME = "solr_metrics_core_requests_time"; public static final String CORE_REQUEST_TIMES = "solr_metrics_core_average_request_time"; - public SolrCoreHandlerMetric( - Metric dropwizardMetric, String coreName, String metricName, boolean cloudMode) { - super(dropwizardMetric, coreName, metricName, cloudMode); + public SolrCoreHandlerMetric(Metric dropwizardMetric, String metricName) { + super(dropwizardMetric, metricName); } /* diff --git a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreHighlighterMetric.java b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreHighlighterMetric.java index 52bc1292c25..d3da3d3426f 100644 --- a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreHighlighterMetric.java +++ b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreHighlighterMetric.java @@ -24,9 +24,8 @@ public class SolrCoreHighlighterMetric extends SolrCoreMetric { public static final String CORE_HIGHLIGHER_METRICS = "solr_metrics_core_highlighter_requests"; - public SolrCoreHighlighterMetric( - Metric dropwizardMetric, String coreName, String metricName, boolean cloudMode) { - super(dropwizardMetric, coreName, metricName, cloudMode); + public SolrCoreHighlighterMetric(Metric dropwizardMetric, String metricName) { + super(dropwizardMetric, metricName); } /* diff --git a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreIndexMetric.java b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreIndexMetric.java index 048fc8d2ca2..e45e1e955bd 100644 --- a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreIndexMetric.java +++ b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreIndexMetric.java @@ -24,9 +24,8 @@ public class SolrCoreIndexMetric extends SolrCoreMetric { public static final String CORE_INDEX_METRICS = "solr_metrics_core_index_size_bytes"; - public SolrCoreIndexMetric( - Metric dropwizardMetric, String coreName, String metricName, boolean cloudMode) { - super(dropwizardMetric, coreName, metricName, cloudMode); + public SolrCoreIndexMetric(Metric dropwizardMetric, String metricName) { + super(dropwizardMetric, metricName); } /* diff --git a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreMetric.java b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreMetric.java index 5010425a023..cb283ea7563 100644 --- a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreMetric.java +++ b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreMetric.java @@ -16,37 +16,45 @@ */ package org.apache.solr.metrics.prometheus.core; -import static org.apache.solr.metrics.prometheus.core.PrometheusCoreFormatterInfo.CLOUD_CORE_PATTERN; - import com.codahale.metrics.Metric; +import java.util.List; import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.solr.common.SolrException; import org.apache.solr.metrics.prometheus.SolrMetric; /** Base class is a wrapper to export a solr.core {@link com.codahale.metrics.Metric} */ public abstract class SolrCoreMetric extends SolrMetric { - public String coreName; - public SolrCoreMetric( - Metric dropwizardMetric, String coreName, String metricName, boolean cloudMode) { - super(dropwizardMetric, metricName); - this.coreName = coreName; - labels.put("core", coreName); - if (cloudMode) { - appendCloudModeLabels(); - } - } + public static Pattern CLOUD_CORE_PATTERN = + Pattern.compile( + "(?^core_(?.*)_(?shard[0-9]+)_(?replica_.[0-9]+)).(.*)$"); + public static Pattern STANDALONE_CORE_PATTERN = Pattern.compile("^core_(?.*?)\\.(.*)$"); + public static List CLOUD_LABEL_KEYS = List.of("core", "collection", "shard", "replica"); + public static List STANDALONE_LABEL_KEYS = List.of("core"); + public String coreName; - private void appendCloudModeLabels() { - Matcher m = CLOUD_CORE_PATTERN.matcher(coreName); - if (m.find()) { - labels.put("collection", m.group(1)); - labels.put("shard", m.group(2)); - labels.put("replica", m.group(3)); + public SolrCoreMetric(Metric dropwizardMetric, String metricName) { + // Remove Core Name prefix from metric as it is no longer needed for tag parsing from this point + super(dropwizardMetric, metricName.substring(metricName.indexOf(".") + 1)); + Matcher cloudPattern = CLOUD_CORE_PATTERN.matcher(metricName); + Matcher standalonePattern = STANDALONE_CORE_PATTERN.matcher(metricName); + if (cloudPattern.find()) { + coreName = cloudPattern.group("core"); + CLOUD_LABEL_KEYS.forEach( + (key) -> { + labels.put(key, cloudPattern.group(key)); + }); + } else if (standalonePattern.find()) { + coreName = standalonePattern.group("core"); + STANDALONE_LABEL_KEYS.forEach( + (key) -> { + labels.put(key, standalonePattern.group(key)); + }); } else { throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, - "Core name does not match pattern for parsing " + coreName); + "Core name does not match pattern for parsing in metric " + metricName); } } } diff --git a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreSearcherMetric.java b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreSearcherMetric.java index 93071f9b8ad..7ca694d311d 100644 --- a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreSearcherMetric.java +++ b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreSearcherMetric.java @@ -29,9 +29,8 @@ public class SolrCoreSearcherMetric extends SolrCoreMetric { public static final String CORE_SEARCHER_METRICS = "solr_metrics_core_searcher_documents"; public static final String CORE_SEARCHER_TIMES = "solr_metrics_core_average_searcher_warmup_time"; - public SolrCoreSearcherMetric( - Metric dropwizardMetric, String coreName, String metricName, boolean cloudMode) { - super(dropwizardMetric, coreName, metricName, cloudMode); + public SolrCoreSearcherMetric(Metric dropwizardMetric, String metricName) { + super(dropwizardMetric, metricName); } /* diff --git a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreTlogMetric.java b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreTlogMetric.java index 29b13e1caee..7286c99d986 100644 --- a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreTlogMetric.java +++ b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrCoreTlogMetric.java @@ -24,9 +24,8 @@ public class SolrCoreTlogMetric extends SolrCoreMetric { public static final String CORE_TLOG_METRICS = "solr_metrics_core_tlog"; - public SolrCoreTlogMetric( - Metric dropwizardMetric, String coreName, String metricName, boolean cloudMode) { - super(dropwizardMetric, coreName, metricName, cloudMode); + public SolrCoreTlogMetric(Metric dropwizardMetric, String metricName) { + super(dropwizardMetric, metricName); } /* diff --git a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrPrometheusCoreFormatter.java b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrPrometheusCoreFormatter.java index 6b2a49154f3..dd3ed025ddf 100644 --- a/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrPrometheusCoreFormatter.java +++ b/solr/core/src/java/org/apache/solr/metrics/prometheus/core/SolrPrometheusCoreFormatter.java @@ -28,13 +28,9 @@ */ public class SolrPrometheusCoreFormatter extends SolrPrometheusFormatter implements PrometheusCoreFormatterInfo { - public final String coreName; - public final boolean cloudMode; - public SolrPrometheusCoreFormatter(String coreName, boolean cloudMode) { + public SolrPrometheusCoreFormatter() { super(); - this.coreName = coreName; - this.cloudMode = cloudMode; } @Override @@ -45,7 +41,7 @@ public void exportDropwizardMetric(Metric dropwizardMetric, String metricName) { @Override public SolrMetric categorizeMetric(Metric dropwizardMetric, String metricName) { - String metricCategory = metricName.split("\\.", 2)[0]; + String metricCategory = metricName.split("\\.", 3)[1]; if (!Enums.getIfPresent(PrometheusCoreFormatterInfo.CoreCategory.class, metricCategory) .isPresent()) { return new SolrNoOpMetric(); @@ -55,17 +51,17 @@ public SolrMetric categorizeMetric(Metric dropwizardMetric, String metricName) { case QUERY: case UPDATE: case REPLICATION: - return new SolrCoreHandlerMetric(dropwizardMetric, coreName, metricName, cloudMode); + return new SolrCoreHandlerMetric(dropwizardMetric, metricName); case TLOG: - return new SolrCoreTlogMetric(dropwizardMetric, coreName, metricName, cloudMode); + return new SolrCoreTlogMetric(dropwizardMetric, metricName); case CACHE: - return new SolrCoreCacheMetric(dropwizardMetric, coreName, metricName, cloudMode); + return new SolrCoreCacheMetric(dropwizardMetric, metricName); case SEARCHER: - return new SolrCoreSearcherMetric(dropwizardMetric, coreName, metricName, cloudMode); + return new SolrCoreSearcherMetric(dropwizardMetric, metricName); case HIGHLIGHTER: - return new SolrCoreHighlighterMetric(dropwizardMetric, coreName, metricName, cloudMode); + return new SolrCoreHighlighterMetric(dropwizardMetric, metricName); case INDEX: - return new SolrCoreIndexMetric(dropwizardMetric, coreName, metricName, cloudMode); + return new SolrCoreIndexMetric(dropwizardMetric, metricName); case CORE: default: return new SolrNoOpMetric(); 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 5c6210603da..8689751a514 100644 --- a/solr/core/src/java/org/apache/solr/response/PrometheusResponseWriter.java +++ b/solr/core/src/java/org/apache/solr/response/PrometheusResponseWriter.java @@ -25,12 +25,11 @@ import java.io.IOException; import java.io.OutputStream; import java.lang.invoke.MethodHandles; -import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.function.Consumer; import java.util.function.Predicate; -import java.util.stream.Collectors; +import org.apache.solr.common.SolrException; import org.apache.solr.common.util.NamedList; import org.apache.solr.metrics.AggregateMetric; import org.apache.solr.metrics.prometheus.SolrPrometheusFormatter; @@ -115,8 +114,10 @@ public static void toPrometheus( Metric dropwizardMetric = dropwizardMetrics.get(metricName); formatter.exportDropwizardMetric(dropwizardMetric, metricName); } catch (Exception e) { - // Do not fail entirely for metrics exporting. Log and try to export next metric - log.warn("Error occurred exporting Dropwizard Metric to Prometheus", e); + throw new SolrException( + SolrException.ErrorCode.SERVER_ERROR, + "Error occurred exporting Dropwizard Metric to Prometheus", + e); } }); @@ -124,21 +125,11 @@ public static void toPrometheus( } public static SolrPrometheusFormatter getFormatterType(String registryName) { - String coreName; - boolean cloudMode = false; String[] parsedRegistry = registryName.split("\\."); switch (parsedRegistry[1]) { case "core": - if (parsedRegistry.length == 3) { - coreName = parsedRegistry[2]; - } else if (parsedRegistry.length == 5) { - coreName = Arrays.stream(parsedRegistry).skip(1).collect(Collectors.joining("_")); - cloudMode = true; - } else { - coreName = registryName; - } - return new SolrPrometheusCoreFormatter(coreName, cloudMode); + return new SolrPrometheusCoreFormatter(); case "jvm": return new SolrPrometheusJvmFormatter(); case "jetty": diff --git a/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java index a90e059e03f..4c3709f5ae5 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java @@ -725,8 +725,7 @@ public void testPrometheusMetricsCore() throws Exception { NamedList values = resp.getValues(); assertNotNull(values.get("metrics")); values = (NamedList) values.get("metrics"); - SolrPrometheusFormatter formatter = - (SolrPrometheusFormatter) values.get("solr.core.collection1"); + SolrPrometheusFormatter formatter = (SolrPrometheusFormatter) values.get("solr.core"); assertNotNull(formatter); MetricSnapshots actualSnapshots = formatter.collect(); assertNotNull(actualSnapshots); @@ -1009,8 +1008,7 @@ public void testPrometheusMetricsFilter() throws Exception { NamedList values = resp.getValues(); assertNotNull(values.get("metrics")); values = (NamedList) values.get("metrics"); - SolrPrometheusFormatter formatter = - (SolrPrometheusFormatter) values.get("solr.core.collection1"); + SolrPrometheusFormatter formatter = (SolrPrometheusFormatter) values.get("solr.core"); assertNotNull(formatter); MetricSnapshots actualSnapshots = formatter.collect(); assertNotNull(actualSnapshots); diff --git a/solr/core/src/test/org/apache/solr/metrics/SolrCoreMetricTest.java b/solr/core/src/test/org/apache/solr/metrics/SolrCoreMetricTest.java index 19a9fce2cbe..9ee34056e5e 100644 --- a/solr/core/src/test/org/apache/solr/metrics/SolrCoreMetricTest.java +++ b/solr/core/src/test/org/apache/solr/metrics/SolrCoreMetricTest.java @@ -26,12 +26,13 @@ public class SolrCoreMetricTest extends SolrTestCaseJ4 { @Test - public void testStandaloneDefaultLabels() throws InterruptedException { - String expectedCoreName = "test_core"; + public void testStandaloneDefaultLabels() { + String dropwizardMetricName = "core_Core_Name.test_core_metric"; + + String expectedCoreName = "Core_Name"; String expectedMetricName = "test_core_metric"; Labels expectedLabels = Labels.of("core", expectedCoreName); - TestSolrCoreMetric testSolrCoreMetric = - new TestSolrCoreMetric(null, expectedCoreName, expectedMetricName, false); + TestSolrCoreMetric testSolrCoreMetric = new TestSolrCoreMetric(null, dropwizardMetricName); assertEquals(expectedCoreName, testSolrCoreMetric.coreName); assertEquals(expectedMetricName, testSolrCoreMetric.metricName); @@ -39,10 +40,12 @@ public void testStandaloneDefaultLabels() throws InterruptedException { } @Test - public void testCloudDefaultLabels() throws InterruptedException { - String expectedCoreName = "core_test_core_shard1_replica_n1"; + public void testCloudDefaultLabels() { + String dropwizardMetricName = "core_Collection_Name_shard1_replica_n1.test_core_metric"; + + String expectedCoreName = "core_Collection_Name_shard1_replica_n1"; String expectedMetricName = "test_core_metric"; - String expectedCollectionName = "test_core"; + String expectedCollectionName = "Collection_Name"; String expectedShardName = "shard1"; String expectedReplicaName = "replica_n1"; @@ -56,8 +59,7 @@ public void testCloudDefaultLabels() throws InterruptedException { expectedShardName, "replica", expectedReplicaName); - TestSolrCoreMetric testSolrCoreMetric = - new TestSolrCoreMetric(null, expectedCoreName, expectedMetricName, true); + TestSolrCoreMetric testSolrCoreMetric = new TestSolrCoreMetric(null, dropwizardMetricName); assertEquals(expectedCoreName, testSolrCoreMetric.coreName); assertEquals(expectedMetricName, testSolrCoreMetric.metricName); @@ -65,9 +67,8 @@ public void testCloudDefaultLabels() throws InterruptedException { } static class TestSolrCoreMetric extends SolrCoreMetric { - public TestSolrCoreMetric( - Metric dropwizardMetric, String coreName, String metricName, boolean cloudMode) { - super(dropwizardMetric, coreName, metricName, cloudMode); + public TestSolrCoreMetric(Metric dropwizardMetric, String metricName) { + super(dropwizardMetric, metricName); } @Override diff --git a/solr/core/src/test/org/apache/solr/metrics/SolrPrometheusFormatterTest.java b/solr/core/src/test/org/apache/solr/metrics/SolrPrometheusFormatterTest.java index 5c62910b43f..76077385800 100644 --- a/solr/core/src/test/org/apache/solr/metrics/SolrPrometheusFormatterTest.java +++ b/solr/core/src/test/org/apache/solr/metrics/SolrPrometheusFormatterTest.java @@ -16,7 +16,8 @@ */ package org.apache.solr.metrics; -import static org.apache.solr.metrics.prometheus.core.PrometheusCoreFormatterInfo.CLOUD_CORE_PATTERN; +import static org.apache.solr.metrics.prometheus.core.SolrCoreMetric.CLOUD_CORE_PATTERN; +import static org.apache.solr.metrics.prometheus.core.SolrCoreMetric.STANDALONE_CORE_PATTERN; import com.codahale.metrics.Counter; import com.codahale.metrics.Gauge; @@ -146,32 +147,42 @@ public Map getValue() { @Test public void testCloudCorePattern() { - String coreName = "core_test-core_shard2_replica_t123"; - Matcher m = CLOUD_CORE_PATTERN.matcher(coreName); + String metricName = "core_test-core_shard2_replica_t123.TEST./foobar/endpoint"; + Matcher m = CLOUD_CORE_PATTERN.matcher(metricName); assertTrue(m.find()); - assertEquals("test-core", m.group(1)); - assertEquals("shard2", m.group(2)); - assertEquals("replica_t123", m.group(3)); + assertEquals("core_test-core_shard2_replica_t123", m.group("core")); + assertEquals("test-core", m.group("collection")); + assertEquals("shard2", m.group("shard")); + assertEquals("replica_t123", m.group("replica")); - coreName = "core_foo_bar_shard24_replica_p8"; - m = CLOUD_CORE_PATTERN.matcher(coreName); + metricName = "core_foo_bar_shard24_replica_p8.QUERY.random.metric-name"; + m = CLOUD_CORE_PATTERN.matcher(metricName); assertTrue(m.matches()); - assertEquals("foo_bar", m.group(1)); - assertEquals("shard24", m.group(2)); - assertEquals("replica_p8", m.group(3)); + assertEquals("core_foo_bar_shard24_replica_p8", m.group("core")); + assertEquals("foo_bar", m.group("collection")); + assertEquals("shard24", m.group("shard")); + assertEquals("replica_p8", m.group("replica")); } @Test public void testBadCloudCorePattern() { - String badCoreName = "core_solrtest_shard100_replica_xyz23"; - Matcher m = CLOUD_CORE_PATTERN.matcher(badCoreName); + String badMetricName = "core_solrtest_shard100_replica_xyz23.TEST./foobar/endpoint"; + Matcher m = CLOUD_CORE_PATTERN.matcher(badMetricName); assertFalse(m.matches()); - badCoreName = "core_solrtest_shards100_replica_x23"; - m = CLOUD_CORE_PATTERN.matcher(badCoreName); + badMetricName = "core_solrtest_shards100_replica_x23.QUERY.random.metric-name"; + m = CLOUD_CORE_PATTERN.matcher(badMetricName); assertFalse(m.matches()); } + @Test + public void testStandaloneCorePattern() { + String metricName = "core_test-core.TEST./foobar/endpoint"; + Matcher m = STANDALONE_CORE_PATTERN.matcher(metricName); + assertTrue(m.find()); + assertEquals("test-core", m.group(1)); + } + static class TestSolrPrometheusFormatter extends SolrPrometheusFormatter { @Override public void exportDropwizardMetric(Metric dropwizardMetric, String metricName) {} diff --git a/solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriter.java b/solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriter.java index 0e25201cce0..7f15a6ae894 100644 --- a/solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriter.java +++ b/solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriter.java @@ -23,7 +23,9 @@ import com.codahale.metrics.SharedMetricRegistries; import java.lang.invoke.MethodHandles; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.solr.SolrTestCaseJ4; @@ -83,8 +85,23 @@ public void testPrometheusStructureOutput() throws Exception { NamedList res = adminClient.request(req); assertNotNull("null response from server", res); String output = (String) res.get("response"); + + Set seenTypeInfo = new HashSet<>(); + List filteredResponse = - output.lines().filter(line -> !line.startsWith("#")).collect(Collectors.toList()); + output + .lines() + .filter( + line -> { + if (!line.startsWith("#")) { + return true; + } + assertTrue( + "Prometheus exposition format cannot have duplicate TYPE information", + seenTypeInfo.add(line)); + return false; + }) + .collect(Collectors.toList()); filteredResponse.forEach( (actualMetric) -> { String actualValue;