Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions solr/core/src/java/org/apache/solr/core/CoreContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ private void loadInternal() {
caffeineCache.initializeMetrics(
solrMetricsContext,
Attributes.builder().put(NAME_ATTR, cacheName).build(),
"solr_node_cache");
"solr.node.cache");
}
m.put(cacheName, c);
}
Expand Down Expand Up @@ -957,7 +957,7 @@ private void loadInternal() {
ExecutorUtil.newMDCAwareFixedThreadPool(
cfg.getCoreLoadThreadCount(isZooKeeperAware()),
new SolrNamedThreadFactory("coreLoadExecutor")),
"solr_node_executor",
"solr.node.executor",
"coreLoadExecutor",
SolrInfoBean.Category.CONTAINER);

Expand Down
20 changes: 10 additions & 10 deletions solr/core/src/java/org/apache/solr/core/SolrCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -1323,47 +1323,47 @@ 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",
"solr.core.indexsearcher.open.warmup.time",
"Time to warmup new searchers",
OtelUnit.MILLISECONDS),
baseSearcherAttributes);

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);
}));

parentContext.observableDoubleGauge(
"solr_core_disk_space",
"solr.core.disk_space",
"Solr core disk space metrics",
(observableDoubleMeasurement -> {

Expand Down Expand Up @@ -1397,7 +1397,7 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri
OtelUnit.MEGABYTES);

parentContext.observableDoubleGauge(
"solr_core_index_size",
"solr.core.index.size",
"Index size for a Solr core",
(observableDoubleMeasurement -> {
if (!isClosed())
Expand All @@ -1407,7 +1407,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())
Expand All @@ -1416,7 +1416,7 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri

if (coreContainer.isZooKeeperAware())
parentContext.observableLongGauge(
"solr_core_is_leader",
"solr.core.is_leader",
"Indicates whether this Solr core is currently the leader",
(observableLongMeasurement -> {
observableLongMeasurement.record(
Expand Down
22 changes: 11 additions & 11 deletions solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -879,55 +879,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");

solrMetricsContext.batchCallback(
() -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,27 +187,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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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_expensive_executor",
"solr.node.expensive.executor",
"asyncCoreExpensiveAdminExecutor",
getCategory());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,8 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri
super.initializeMetrics(parentContext, attributes);
var suggesterAttributes =
attributes.toBuilder().put(CATEGORY_ATTR, getCategory().toString()).build();

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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> sanitizedNames =
includedNames.stream()
.map(
Expand All @@ -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();
Comment on lines 68 to +99
}

// Return named filtered snapshots if not label filters provided
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,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 */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ public SolrMetricsContext getSolrMetricsContext() {
public void initializeMetrics(SolrMetricsContext parentContext, Attributes attributes) {
var solrCacheStats =
parentContext.longGaugeMeasurement(
"solr_core_field_cache_entries", "Number of field cache entries");
"solr.core.field_cache.entries", "Number of field cache entries");
var solrCacheSize =
parentContext.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);
parentContext.batchCallback(
() -> {
if (enableEntryList && enableJmxEntryList) {
Expand Down
14 changes: 7 additions & 7 deletions solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,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());
Expand Down Expand Up @@ -2636,13 +2636,13 @@ 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);

solrMetricsContext.observableLongCounter(
"solr_core_indexsearcher_live_docs_cache",
"solr.core.indexsearcher.live_docs.cache",
"LiveDocs cache metrics",
obs -> {
obs.record(
Expand All @@ -2656,7 +2656,7 @@ public void initializeMetrics(SolrMetricsContext solrMetricsContext, Attributes
});
// reader stats (numeric)
solrMetricsContext.observableLongGauge(
"solr_core_indexsearcher_index_num_docs",
"solr.core.indexsearcher.index.num_docs",
"Number of live docs in the index",
obs -> {
try {
Expand All @@ -2667,7 +2667,7 @@ public void initializeMetrics(SolrMetricsContext solrMetricsContext, Attributes
});

solrMetricsContext.observableLongGauge(
"solr_core_indexsearcher_index_docs",
"solr.core.indexsearcher.index.docs",
"Total number of docs in the index (including deletions)",
obs -> {
try {
Expand All @@ -2677,7 +2677,7 @@ public void initializeMetrics(SolrMetricsContext solrMetricsContext, Attributes
});
// indexVersion (numeric)
solrMetricsContext.observableLongGauge(
"solr_core_indexsearcher_index_version",
"solr.core.indexsearcher.index.version",
"Lucene index version",
obs -> {
try {
Expand All @@ -2687,7 +2687,7 @@ public void initializeMetrics(SolrMetricsContext solrMetricsContext, Attributes
});
// size of the currently opened commit
solrMetricsContext.observableDoubleGauge(
"solr_core_indexsearcher_index_commit_size",
"solr.core.indexsearcher.index.commit_size",
"Size of the current index commit (megabytes)",
obs -> {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ public void initializeMetrics(SolrMetricsContext parentContext, Attributes attri
.put(SolrMetricProducer.CATEGORY_ATTR, Category.CACHE.toString())
.build();
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();
Expand Down
Loading
Loading