diff --git a/changelog/unreleased/SOLR-18165-dot-separated-metric-names.yml b/changelog/unreleased/SOLR-18165-dot-separated-metric-names.yml new file mode 100644 index 000000000000..58fc4ce8b3c2 --- /dev/null +++ b/changelog/unreleased/SOLR-18165-dot-separated-metric-names.yml @@ -0,0 +1,9 @@ +title: Use dot-separated OTel metric names for OTLP export. This is a back-compat break from version 10.0 +type: changed +authors: + - name: Jan Høydahl + url: https://home.apache.org/phonebook.html?uid=janhoy + - name: Matthew Biscocho +links: + - name: SOLR-18165 + url: https://issues.apache.org/jira/browse/SOLR-18165 diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java index 9ca9b377cb2e..0899d20086f1 100644 --- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java +++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java @@ -809,7 +809,7 @@ private void loadInternal() { caffeineCache.initializeMetrics( solrMetricsContext, Attributes.builder().put(NAME_ATTR, cacheName).build(), - "solr_node_cache"); + "solr.node.cache"); } m.put(cacheName, c); } @@ -952,7 +952,7 @@ private void loadInternal() { ExecutorUtil.newMDCAwareFixedThreadPool( cfg.getCoreLoadThreadCount(isZooKeeperAware()), new SolrNamedThreadFactory("coreLoadExecutor")), - "solr_node_executor", + "solr.node.executor", "coreLoadExecutor", SolrInfoBean.Category.CONTAINER); diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java index 93699357426b..01101d008e83 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrCore.java +++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java @@ -254,7 +254,6 @@ public class SolrCore implements SolrInfoBean, Closeable { private AttributedLongCounter newSearcherMaxReachedCounter; private AttributedLongCounter newSearcherOtherErrorsCounter; private AttributedLongTimer newSearcherTimer; - private AttributedLongTimer newSearcherWarmupTimer; private List toClose; private final String metricTag = SolrMetricProducer.getUniqueMetricTag(this, null); @@ -1340,41 +1339,33 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri newSearcherCounter = new AttributedLongCounter( parentContext.longCounter( - "solr_core_searcher_new", "Total number of new searchers opened"), + "solr.core.searcher.new", "Total number of new searchers opened"), baseSearcherAttributes); newSearcherMaxReachedCounter = new AttributedLongCounter( parentContext.longCounter( - "solr_core_searcher_warming_max", + "solr.core.searcher.warming_max", "Total number of maximum concurrent warming searchers reached"), baseSearcherAttributes); newSearcherOtherErrorsCounter = new AttributedLongCounter( parentContext.longCounter( - "solr_core_searcher_errors", "Total number of searcher errors"), + "solr.core.searcher.errors", "Total number of searcher errors"), baseSearcherAttributes); newSearcherTimer = new AttributedLongTimer( parentContext.longHistogram( - "solr_core_indexsearcher_open_time", + "solr.core.indexsearcher.open.time", "Time to open new searchers", OtelUnit.MILLISECONDS), baseSearcherAttributes); - newSearcherWarmupTimer = - new AttributedLongTimer( - parentContext.longHistogram( - "solr_core_indexsearcher_open_warmup_time", - "Time to warmup new searchers", - OtelUnit.MILLISECONDS), - baseSearcherAttributes); - observables.add( parentContext.observableLongGauge( - "solr_core_ref_count", + "solr.core.ref_count", "The current number of active references to a Solr core", (observableLongMeasurement -> { observableLongMeasurement.record(getOpenCount(), baseGaugeCoreAttributes); @@ -1382,7 +1373,7 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri observables.add( parentContext.observableDoubleGauge( - "solr_core_disk_space", + "solr.core.disk_space", "Solr core disk space metrics", (observableDoubleMeasurement -> { @@ -1417,7 +1408,7 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri observables.add( parentContext.observableDoubleGauge( - "solr_core_index_size", + "solr.core.index.size", "Index size for a Solr core", (observableDoubleMeasurement -> { if (!isClosed()) @@ -1427,7 +1418,7 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri OtelUnit.MEGABYTES)); parentContext.observableLongGauge( - "solr_core_segments", + "solr.core.segments", "Number of segments in a Solr core", (observableLongMeasurement -> { if (isReady()) @@ -1437,7 +1428,7 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri if (coreContainer.isZooKeeperAware()) observables.add( parentContext.observableLongGauge( - "solr_core_is_leader", + "solr.core.is_leader", "Indicates whether this Solr core is currently the leader", (observableLongMeasurement -> { observableLongMeasurement.record( @@ -2684,7 +2675,6 @@ public RefCounted getSearcher( future = searcherExecutor.submit( () -> { - AttributedLongTimer.MetricTimer warmupContext = newSearcherWarmupTimer.start(); try { newSearcher.warm(currSearcher); } catch (Throwable e) { @@ -2692,8 +2682,6 @@ public RefCounted getSearcher( if (e instanceof Error) { throw (Error) e; } - } finally { - warmupContext.stop(); } return null; }); diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java index 8b367cf8c300..3ec327aa3499 100644 --- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java @@ -882,55 +882,55 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri ObservableDoubleMeasurement indexSizeMetric = solrMetricsContext.doubleGaugeMeasurement( - "solr_core_replication_index_size", + "solr.core.replication.index.size", "Size of the index in megabytes", OtelUnit.MEGABYTES); ObservableLongMeasurement indexVersionMetric = solrMetricsContext.longGaugeMeasurement( - "solr_core_replication_index_version", "Current index version"); + "solr.core.replication.index.version", "Current index version"); ObservableLongMeasurement indexGenerationMetric = solrMetricsContext.longGaugeMeasurement( - "solr_core_replication_index_generation", "Current index generation"); + "solr.core.replication.index.generation", "Current index generation"); ObservableLongMeasurement isLeaderMetric = solrMetricsContext.longGaugeMeasurement( - "solr_core_replication_is_leader", "Whether this node is a leader (1) or not (0)"); + "solr.core.replication.is_leader", "Whether this node is a leader (1) or not (0)"); ObservableLongMeasurement isFollowerMetric = solrMetricsContext.longGaugeMeasurement( - "solr_core_replication_is_follower", "Whether this node is a follower (1) or not (0)"); + "solr.core.replication.is_follower", "Whether this node is a follower (1) or not (0)"); ObservableLongMeasurement replicationEnabledMetric = solrMetricsContext.longGaugeMeasurement( - "solr_core_replication_is_enabled", "Whether replication is enabled (1) or not (0)"); + "solr.core.replication.is_enabled", "Whether replication is enabled (1) or not (0)"); ObservableLongMeasurement isPollingDisabledMetric = solrMetricsContext.longGaugeMeasurement( - "solr_core_replication_is_polling_disabled", + "solr.core.replication.is_polling_disabled", "Whether polling is disabled (1) or not (0)"); ObservableLongMeasurement isReplicatingMetric = solrMetricsContext.longGaugeMeasurement( - "solr_core_replication_is_replicating", + "solr.core.replication.is_replicating", "Whether replication is in progress (1) or not (0)"); ObservableLongMeasurement timeElapsedMetric = solrMetricsContext.longGaugeMeasurement( - "solr_core_replication_time_elapsed", + "solr.core.replication.time_elapsed", "Time elapsed during replication in seconds", OtelUnit.SECONDS); ObservableLongMeasurement bytesDownloadedMetric = solrMetricsContext.longGaugeMeasurement( - "solr_core_replication_downloaded_size", + "solr.core.replication.downloaded_size", "Total bytes downloaded during replication", OtelUnit.BYTES); ObservableLongMeasurement downloadSpeedMetric = solrMetricsContext.longGaugeMeasurement( - "solr_core_replication_download_speed", "Download speed in bytes per second"); + "solr.core.replication.download_speed", "Download speed in bytes per second"); metricsCallback = solrMetricsContext.batchCallback( diff --git a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java index b76a9778d115..e70e81ad654e 100644 --- a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java +++ b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java @@ -198,27 +198,27 @@ public HandlerMetrics( requests = factory.attributedLongCounter( - "solr_core_requests", "HTTP Solr requests", Attributes.empty()); + "solr.core.requests", "HTTP Solr requests", Attributes.empty()); numServerErrors = factory.attributedLongCounter( - "solr_core_requests_errors", + "solr.core.requests.errors", "HTTP Solr request errors", Attributes.of(SOURCE_ATTR, "server")); numClientErrors = factory.attributedLongCounter( - "solr_core_requests_errors", + "solr.core.requests.errors", "HTTP Solr request errors", Attributes.of(SOURCE_ATTR, "client")); numTimeouts = factory.attributedLongCounter( - "solr_core_requests_timeout", "HTTP Solr request timeouts", Attributes.empty()); + "solr.core.requests.timeout", "HTTP Solr request timeouts", Attributes.empty()); requestTimes = factory.attributedLongTimer( - "solr_core_requests_times", + "solr.core.requests.times", "HTTP Solr request times", OtelUnit.MILLISECONDS, Attributes.empty()); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java index c6d9474e0de8..9fe8d9403c4e 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java @@ -132,14 +132,14 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri coreAdminAsyncTracker.standardExecutor = solrMetricsContext.instrumentedExecutorService( coreAdminAsyncTracker.standardExecutor, - "solr_node_executor", + "solr.node.executor", "asyncCoreAdminExecutor", getCategory()); coreAdminAsyncTracker.expensiveExecutor = solrMetricsContext.instrumentedExecutorService( coreAdminAsyncTracker.expensiveExecutor, - "solr_node_executor", + "solr.node.executor", "asyncCoreExpensiveAdminExecutor", getCategory()); } diff --git a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java index a8e9513e5875..6dc30f47b9bb 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java +++ b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java @@ -439,6 +439,6 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri httpListenerFactory.initializeMetrics(solrMetricsContext, Attributes.empty()); commExecutor = solrMetricsContext.instrumentedExecutorService( - commExecutor, "solr_core_executor", "httpShardExecutor", SolrInfoBean.Category.QUERY); + commExecutor, "solr.core.executor", "httpShardExecutor", SolrInfoBean.Category.QUERY); } } diff --git a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java index 5a82e1088b05..27e2f838a8c5 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java @@ -392,7 +392,7 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri attributes.toBuilder().put(CATEGORY_ATTR, getCategory().toString()).build(); this.toClose = this.solrMetricsContext.observableLongGauge( - "solr_core_suggester_total_size", + "solr.core.suggester.total.size", "Total memory size in bytes of all suggester", (observableLongMeasurement) -> { observableLongMeasurement.record(ramBytesUsed(), suggesterAttributes); diff --git a/solr/core/src/java/org/apache/solr/metrics/otel/FilterablePrometheusMetricReader.java b/solr/core/src/java/org/apache/solr/metrics/otel/FilterablePrometheusMetricReader.java index 5664ff047b15..6461b3bb52a8 100644 --- a/solr/core/src/java/org/apache/solr/metrics/otel/FilterablePrometheusMetricReader.java +++ b/solr/core/src/java/org/apache/solr/metrics/otel/FilterablePrometheusMetricReader.java @@ -65,8 +65,9 @@ public MetricSnapshots collect( return super.collect(); } - // Prometheus appends a suffix to the metrics depending on the metric type. We need to sanitize - // the suffix off if they filter by Prometheus name instead of OTEL name. + // Users may filter by Prometheus-format names (e.g. "solr_core_requests") or with a + // Prometheus type suffix (e.g. "solr_core_requests_total"). Strip any such suffix so we can + // compare against the Prometheus base name returned by getMetadata().getPrometheusName(). Set sanitizedNames = includedNames.stream() .map( @@ -84,7 +85,18 @@ public MetricSnapshots collect( if (sanitizedNames.isEmpty()) { snapshotsToFilter = super.collect(); } else { - snapshotsToFilter = super.collect(sanitizedNames::contains); + // We collect all metrics and filter by Prometheus name rather than using + // super.collect(Predicate) which matches on OTel internal names. This avoids a mismatch + // when OTel names use dot-separators (e.g. "solr.core.requests") but users filter by the + // Prometheus underscore-format name they see in the output (e.g. "solr_core_requests"). + MetricSnapshots all = super.collect(); + MetricSnapshots.Builder nameFiltered = MetricSnapshots.builder(); + for (MetricSnapshot snapshot : all) { + if (sanitizedNames.contains(snapshot.getMetadata().getPrometheusName())) { + nameFiltered.metricSnapshot(snapshot); + } + } + snapshotsToFilter = nameFiltered.build(); } // Return named filtered snapshots if not label filters provided diff --git a/solr/core/src/java/org/apache/solr/metrics/otel/instruments/AttributedInstrumentFactory.java b/solr/core/src/java/org/apache/solr/metrics/otel/instruments/AttributedInstrumentFactory.java index b4cd5cd514fe..ceb982bf80a6 100644 --- a/solr/core/src/java/org/apache/solr/metrics/otel/instruments/AttributedInstrumentFactory.java +++ b/solr/core/src/java/org/apache/solr/metrics/otel/instruments/AttributedInstrumentFactory.java @@ -132,7 +132,7 @@ public AttributedLongTimer attributedLongTimer( /** Replace core metric name prefix to node prefix */ private String toNodeMetricName(String coreMetricName) { - return coreMetricName.replace("solr_core", "solr_node"); + return coreMetricName.replace("solr.core", "solr.node"); } /** Filter out core attributes and keep all others for node-level metrics */ diff --git a/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java b/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java index fb8d92120a2c..10abe1918b0a 100644 --- a/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java +++ b/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java @@ -60,10 +60,10 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri this.solrMetricsContext = parentContext; var solrCacheStats = solrMetricsContext.longGaugeMeasurement( - "solr_core_field_cache_entries", "Number of field cache entries"); + "solr.core.field_cache.entries", "Number of field cache entries"); var solrCacheSize = solrMetricsContext.longGaugeMeasurement( - "solr_core_field_cache_size", "Size of field cache in bytes", OtelUnit.BYTES); + "solr.core.field_cache.size", "Size of field cache in bytes", OtelUnit.BYTES); this.toClose = solrMetricsContext.batchCallback( () -> { diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java index 862b6a22ac41..ba61bc85d834 100644 --- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java +++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java @@ -612,7 +612,7 @@ public void register() { caffeineCache.initializeMetrics( solrMetricsContext, core.getCoreAttributes().toBuilder().put(NAME_ATTR, cache.name()).build(), - "solr_core_indexsearcher_cache"); + "solr.core.indexsearcher.cache"); } } initializeMetrics(solrMetricsContext, core.getCoreAttributes()); @@ -2637,14 +2637,14 @@ public void initializeMetrics(SolrMetricsContext solrMetricsContext, Attributes warmupTimer = new AttributedLongTimer( solrMetricsContext.longHistogram( - "solr_core_indexsearcher_warmup_time", + "solr.core.indexsearcher.warmup_time", "Searcher warmup time (ms)", OtelUnit.MILLISECONDS), baseAttributes); toClose.add( solrMetricsContext.observableLongCounter( - "solr_core_indexsearcher_live_docs_cache", + "solr.core.indexsearcher.live_docs.cache", "LiveDocs cache metrics", obs -> { obs.record( @@ -2660,7 +2660,7 @@ public void initializeMetrics(SolrMetricsContext solrMetricsContext, Attributes // reader stats (numeric) toClose.add( solrMetricsContext.observableLongGauge( - "solr_core_indexsearcher_index_num_docs", + "solr.core.indexsearcher.index.num_docs", "Number of live docs in the index", obs -> { try { @@ -2672,7 +2672,7 @@ public void initializeMetrics(SolrMetricsContext solrMetricsContext, Attributes toClose.add( solrMetricsContext.observableLongGauge( - "solr_core_indexsearcher_index_docs", + "solr.core.indexsearcher.index.docs", "Total number of docs in the index (including deletions)", obs -> { try { @@ -2683,7 +2683,7 @@ public void initializeMetrics(SolrMetricsContext solrMetricsContext, Attributes // indexVersion (numeric) toClose.add( solrMetricsContext.observableLongGauge( - "solr_core_indexsearcher_index_version", + "solr.core.indexsearcher.index.version", "Lucene index version", obs -> { try { @@ -2694,7 +2694,7 @@ public void initializeMetrics(SolrMetricsContext solrMetricsContext, Attributes // size of the currently opened commit toClose.add( solrMetricsContext.observableDoubleGauge( - "solr_core_indexsearcher_index_commit_size", + "solr.core.indexsearcher.index.commit_size", "Size of the current index commit (megabytes)", obs -> { try { diff --git a/solr/core/src/java/org/apache/solr/search/stats/StatsCache.java b/solr/core/src/java/org/apache/solr/search/stats/StatsCache.java index e79051449de0..5c4570faa9c6 100644 --- a/solr/core/src/java/org/apache/solr/search/stats/StatsCache.java +++ b/solr/core/src/java/org/apache/solr/search/stats/StatsCache.java @@ -336,7 +336,7 @@ public void initializeMetrics(SolrMetricsContext solrMetricsContext, Attributes .build(); this.toClose = solrMetricsContext.observableLongGauge( - "solr_core_indexsearcher_termstats_cache", + "solr.core.indexsearcher.termstats.cache", "Operation counts for the searcher term statistics cache, reported per operation type", obs -> { var cacheMetrics = getCacheMetrics(); diff --git a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java index 373a9289bc90..fc7476a4c759 100644 --- a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java +++ b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java @@ -246,102 +246,102 @@ private void createMetrics(Attributes baseAttributes, boolean aggregateToNodeReg addCommandsCumulative = factory.attributedLongUpDownCounter( - "solr_core_update_cumulative_ops", + "solr.core.update.cumulative.ops", "Cumulative number of update commands processed. Cumulative can decrease from rollback command", Attributes.of(OPERATION_ATTR, "adds")); deleteByIdCommandsCumulative = factory.attributedLongUpDownCounter( - "solr_core_update_cumulative_ops", + "solr.core.update.cumulative.ops", "Cumulative number of update commands processed. Cumulative can decrease from rollback command", Attributes.of(OPERATION_ATTR, "deletes_by_id")); deleteByQueryCommandsCumulative = factory.attributedLongUpDownCounter( - "solr_core_update_cumulative_ops", + "solr.core.update.cumulative.ops", "Cumulative number of update commands processed. Cumulative can decrease from rollback command", Attributes.of(OPERATION_ATTR, "deletes_by_query")); commitCommands = factory.attributedLongCounter( - "solr_core_update_commit_ops", + "solr.core.update.commit.ops", "Total number of commit operations", Attributes.of(OPERATION_ATTR, "commits")); optimizeCommands = factory.attributedLongCounter( - "solr_core_update_commit_ops", + "solr.core.update.commit.ops", "Total number of commit operations", Attributes.of(OPERATION_ATTR, "optimize")); mergeIndexesCommands = factory.attributedLongCounter( - "solr_core_update_commit_ops", + "solr.core.update.commit.ops", "Total number of commit operations", Attributes.of(OPERATION_ATTR, "merge_indexes")); expungeDeleteCommands = factory.attributedLongCounter( - "solr_core_update_commit_ops", + "solr.core.update.commit.ops", "Total number of commit operations", Attributes.of(OPERATION_ATTR, "expunge_deletes")); rollbackCommands = factory.attributedLongCounter( - "solr_core_update_maintenance_ops", + "solr.core.update.maintenance.ops", "Total number of maintenance operations", Attributes.of(OPERATION_ATTR, "rollback")); splitCommands = factory.attributedLongCounter( - "solr_core_update_maintenance_ops", + "solr.core.update.maintenance.ops", "Total number of maintenance operations", Attributes.of(OPERATION_ATTR, "split")); numErrorsCumulative = factory.attributedLongCounter( - "solr_core_update_errors", "Total number of update errors", Attributes.empty()); + "solr.core.update.errors", "Total number of update errors", Attributes.empty()); submittedAdds = factory.attributedLongCounter( - "solr_core_update_submitted_ops", + "solr.core.update.submitted.ops", "Total number of submitted update operations", Attributes.of(OPERATION_ATTR, "adds")); submittedDeleteById = factory.attributedLongCounter( - "solr_core_update_submitted_ops", + "solr.core.update.submitted.ops", "Total number of submitted update operations", Attributes.of(OPERATION_ATTR, "deletes_by_id")); submittedDeleteByQuery = factory.attributedLongCounter( - "solr_core_update_submitted_ops", + "solr.core.update.submitted.ops", "Total number of submitted update operations", Attributes.of(OPERATION_ATTR, "deletes_by_query")); committedAdds = factory.attributedLongCounter( - "solr_core_update_committed_ops", + "solr.core.update.committed.ops", "Total number of committed update operations", Attributes.of(OPERATION_ATTR, "adds")); committedDeleteById = factory.attributedLongCounter( - "solr_core_update_committed_ops", + "solr.core.update.committed.ops", "Total number of committed update operations", Attributes.of(OPERATION_ATTR, "deletes_by_id")); committedDeleteByQuery = factory.attributedLongCounter( - "solr_core_update_committed_ops", + "solr.core.update.committed.ops", "Total number of committed update operations", Attributes.of(OPERATION_ATTR, "deletes_by_query")); // Create observable metrics only for core registry observables.add( solrMetricsContext.observableLongCounter( - "solr_core_update_auto_commits", + "solr.core.update.auto_commits", "Current number of auto commits", (observableLongMeasurement -> { observableLongMeasurement.record( @@ -354,7 +354,7 @@ private void createMetrics(Attributes baseAttributes, boolean aggregateToNodeReg observables.add( solrMetricsContext.observableLongGauge( - "solr_core_update_commit_stats", + "solr.core.update.commit.stats", "Metrics around commits", (observableLongMeasurement -> { if (commitTracker.getDocsUpperBound() > 0) { @@ -386,7 +386,7 @@ private void createMetrics(Attributes baseAttributes, boolean aggregateToNodeReg observables.add( solrMetricsContext.observableLongGauge( - "solr_core_update_docs_pending_commit", + "solr.core.update.docs.pending_commit", "Current number of documents pending commit. Value is reset to 0 on commit.", (observableLongMeasurement) -> { observableLongMeasurement.record( diff --git a/solr/core/src/java/org/apache/solr/update/PeerSync.java b/solr/core/src/java/org/apache/solr/update/PeerSync.java index 5034797956d7..7d69b4de9c61 100644 --- a/solr/core/src/java/org/apache/solr/update/PeerSync.java +++ b/solr/core/src/java/org/apache/solr/update/PeerSync.java @@ -154,17 +154,17 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri syncErrors = new AttributedLongCounter( solrMetricsContext.longCounter( - "solr_core_peer_sync_errors", "Total number of sync errors with peer"), + "solr.core.peer_sync.errors", "Total number of sync errors with peer"), baseAttributes); syncSkipped = new AttributedLongCounter( solrMetricsContext.longCounter( - "solr_core_peer_sync_skipped", "Total number of skipped syncs with peer"), + "solr.core.peer_sync.skipped", "Total number of skipped syncs with peer"), baseAttributes); syncTime = new AttributedLongTimer( solrMetricsContext.longHistogram( - "solr_core_peer_sync_time", "Peer sync times", OtelUnit.MILLISECONDS), + "solr.core.peer_sync.time", "Peer sync times", OtelUnit.MILLISECONDS), baseAttributes); } diff --git a/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java b/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java index 00097cb981d5..272e610718b9 100644 --- a/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java +++ b/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java @@ -109,17 +109,17 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri syncErrors = new AttributedLongCounter( solrMetricsContext.longCounter( - "solr_core_sync_with_leader_errors", "Total number of sync errors with leader"), + "solr.core.sync_with_leader.errors", "Total number of sync errors with leader"), baseAttributes); syncSkipped = new AttributedLongCounter( solrMetricsContext.longCounter( - "solr_core_sync_with_leader_skipped", "Total number of skipped syncs with leader"), + "solr.core.sync_with_leader.skipped", "Total number of skipped syncs with leader"), baseAttributes); syncTime = new AttributedLongTimer( solrMetricsContext.longHistogram( - "solr_core_sync_with_leader_time", "leader sync times", OtelUnit.MILLISECONDS), + "solr.core.sync_with_leader.time", "leader sync times", OtelUnit.MILLISECONDS), baseAttributes); } diff --git a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java index 2f028f08587f..18439f76a56f 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java +++ b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java @@ -258,22 +258,22 @@ private void initMetrics(final SolrCore core) { mergesCounter = solrMetricsContext.longCounter( - "solr_core_indexwriter_merges", "Number of total merge operations, " + descSuffix); + "solr.core.indexwriter.merges", "Number of total merge operations, " + descSuffix); mergeDocsCounter = solrMetricsContext.longCounter( - "solr_core_indexwriter_merge_docs", + "solr.core.indexwriter.merge.docs", "Number of documents involved in merge, " + descSuffix); mergeSegmentsCounter = solrMetricsContext.longCounter( - "solr_core_indexwriter_merge_segments", + "solr.core.indexwriter.merge.segments", "Number of segments involved in merge, " + descSuffix); flushesCounter = solrMetricsContext.longCounter( - "solr_core_indexwriter_flushes", "Number of flush to disk operations triggered"); + "solr.core.indexwriter.flushes", "Number of flush to disk operations triggered"); var mergesTimerBase = solrMetricsContext.longHistogram( - "solr_core_indexwriter_merge_time", + "solr.core.indexwriter.merge.time", "Time spent merging segments, " + descSuffix, OtelUnit.MILLISECONDS); majorMergeTimer = diff --git a/solr/core/src/java/org/apache/solr/update/UpdateLog.java b/solr/core/src/java/org/apache/solr/update/UpdateLog.java index cf026c95c2ef..6d3099b65094 100644 --- a/solr/core/src/java/org/apache/solr/update/UpdateLog.java +++ b/solr/core/src/java/org/apache/solr/update/UpdateLog.java @@ -637,14 +637,14 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri observables.add( solrMetricsContext.observableLongGauge( - "solr_core_update_log_buffered_ops", + "solr.core.update_log.buffered.ops", "The current number of buffered operations", (observableLongMeasurement -> observableLongMeasurement.record(computeBufferedOps(), baseAttributes)))); observables.add( solrMetricsContext.observableLongGauge( - "solr_core_update_log_replay_logs_remaining", + "solr.core.update_log.replay.logs_remaining", "The current number of tlogs remaining to be replayed", (observableLongMeasurement -> { observableLongMeasurement.record(logs.size(), baseAttributes); @@ -652,7 +652,7 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri observables.add( solrMetricsContext.observableLongGauge( - "solr_core_update_log_size_remaining", + "solr.core.update_log.size_remaining", "The total size in bytes of all tlogs remaining to be replayed", (observableLongMeasurement -> { observableLongMeasurement.record(getTotalLogsSize(), baseAttributes); @@ -663,7 +663,7 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri observables.add( solrMetricsContext.observableLongGauge( - "solr_core_update_log_state", + "solr.core.update_log.state", "The current state of the update log. Replaying (0), buffering (1), applying buffered (2), active (3)", (observableLongMeasurement -> { observableLongMeasurement.record(state.getValue(), baseAttributes); @@ -672,20 +672,20 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri applyingBufferedOpsCounter = new AttributedLongCounter( solrMetricsContext.longCounter( - "solr_core_update_log_applied_buffered_ops", + "solr.core.update_log.applied_buffered_ops", "Total number of buffered operations applied"), baseAttributes); replayOpsCounter = new AttributedLongCounter( solrMetricsContext.longCounter( - "solr_core_update_log_replay_ops", "Total number of log replay operations"), + "solr.core.update_log.replay.ops", "Total number of log replay operations"), baseAttributes); copyOverOldUpdatesCounter = new AttributedLongCounter( solrMetricsContext.longCounter( - "solr_core_update_log_old_updates_copied", + "solr.core.update_log.old_updates_copied", "Total number of updates copied from previous tlog or last tlog to a new tlog"), baseAttributes); } diff --git a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java index 8abb54c066d0..ed0f4f4e850a 100644 --- a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java +++ b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java @@ -167,10 +167,10 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri trackHttpSolrMetrics.initializeMetrics(solrMetricsContext, Attributes.empty()); updateExecutor = solrMetricsContext.instrumentedExecutorService( - updateExecutor, "solr_core_executor", "updateOnlyExecutor", getCategory()); + updateExecutor, "solr.core.executor", "updateOnlyExecutor", getCategory()); recoveryExecutor = solrMetricsContext.instrumentedExecutorService( - recoveryExecutor, "solr_core_executor", "recoveryExecutor", getCategory()); + recoveryExecutor, "solr.core.executor", "recoveryExecutor", getCategory()); } @Override diff --git a/solr/modules/cross-dc/src/java/org/apache/solr/crossdc/update/processor/ProducerMetrics.java b/solr/modules/cross-dc/src/java/org/apache/solr/crossdc/update/processor/ProducerMetrics.java index 73e52a62ff99..b456fd0d48ca 100644 --- a/solr/modules/cross-dc/src/java/org/apache/solr/crossdc/update/processor/ProducerMetrics.java +++ b/solr/modules/cross-dc/src/java/org/apache/solr/crossdc/update/processor/ProducerMetrics.java @@ -47,36 +47,36 @@ public ProducerMetrics(SolrMetricsContext solrMetricsContext, SolrCore solrCore) var localProcessed = solrMetricsContext.longCounter( - "solr_core_crossdc_producer_local_processed", + "solr.core.crossdc.producer.local.processed", "The number of local documents processed (success or error)"); var localSubmitted = solrMetricsContext.longCounter( - "solr_core_crossdc_producer_submitted", + "solr.core.crossdc.producer.submitted", "The number of documents submitted to the Kafka topic (success or error)"); var localSubmittedAdd = solrMetricsContext.longCounter( - "solr_core_crossdc_producer_submitted_add", + "solr.core.crossdc.producer.submitted.add", "The number of add requests submitted to the Kafka topic (success or error)"); var localSubmittedDbi = solrMetricsContext.longCounter( - "solr_core_crossdc_producer_submitted_delete_by_id", + "solr.core.crossdc.producer.submitted.delete_by_id", "The number of Delete-By-Id requests submitted to the Kafka topic (success or error)"); var localSubmittedDbq = solrMetricsContext.longCounter( - "solr_core_crossdc_producer_submitted_delete_by_query", + "solr.core.crossdc.producer.submitted.delete_by_query", "The number of Delete-By-Query requests submitted to the Kafka topic (success or error)"); var localSubmittedCommit = solrMetricsContext.longCounter( - "solr_core_crossdc_producer_submitted_commit", + "solr.core.crossdc.producer.submitted.commit", "The number of standalone Commit requests submitted to the Kafka topic (success or error)"); var histogramDocSizes = solrMetricsContext.longHistogram( - "solr_core_crossdc_producer_document_size", + "solr.core.crossdc.producer.document_size", "Histogram of the processed document sizes processed", OtelUnit.BYTES); var tooLargeErrors = solrMetricsContext.longCounter( - "solr_core_crossdc_producer_doc_too_large_errors", + "solr.core.crossdc.producer.doc_too_large_errors", "The number of documents that were too large to send to the Kafka topic"); this.local = 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 269bf1df6f64..4a736dfc688b 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 @@ -292,6 +292,28 @@ Attention: == Solr 10.1 +=== OpenTelemetry + +The new OTEL based metric system introduced in 10.0 is considered BETA, and some breaking changes are to be expected in this and coming minor releases. + +==== OTLP Metric Names Changed to Dot-Separated Format + +*Breaking change for OTLP consumers.* + +Solr's metric names exported via OTLP now follow the https://opentelemetry.io/docs/specs/semconv/general/naming/[OpenTelemetry semantic convention] of using dot-separated names instead of the underscore-separated names used in Solr 10.0. + +For example, `solr_core_requests` is now `solr.core.requests`, and `solr_node_executor` is now `solr.node.executor`. + +*Prometheus output is unaffected.* The OTel Prometheus exporter automatically converts dots to underscores, so the `/admin/metrics?wt=prometheus` endpoint continues to produce the same metric names as before (e.g., `solr_core_requests_total`). + +*Workaround for OTLP consumers depending on the old names:* +Users who consume Solr metrics via OTLP and rely on the 10.0 underscore-format names can use metric renaming or transformation features in their OpenTelemetry Collector pipeline to convert the new dot-separated names back to the old format during the transition. + +==== Metric `solr_core_indexsearcher_open_warmup_time` removed + +The metric `solr_core_indexsearcher_open_warmup_time` has been removed as it duplicated `solr_core_indexsearcher_warmup_time`. +Update your dashboards to use `solr_core_indexsearcher_warmup_time` instead. + === Lucene Codec Change Solr 10.1 upgrades the underlying Lucene library from 10.3 to 10.4, which introduces a new index codec (`Lucene104`).