Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
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
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 @@ -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);
}
Expand Down Expand Up @@ -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);

Expand Down
27 changes: 16 additions & 11 deletions solr/core/src/java/org/apache/solr/core/SolrCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,12 @@ public class SolrCore implements SolrInfoBean, Closeable {
private AttributedLongCounter newSearcherMaxReachedCounter;
private AttributedLongCounter newSearcherOtherErrorsCounter;
private AttributedLongTimer newSearcherTimer;

@Deprecated(
since = "10.1",
forRemoval = true) // Duplicate of solr.core.indexsearcher.warmup_time - remove
private AttributedLongTimer newSearcherWarmupTimer;

private List<AutoCloseable> toClose;

private final String metricTag = SolrMetricProducer.getUniqueMetricTag(this, null);
Expand Down Expand Up @@ -1340,49 +1345,49 @@ 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",
"solr.core.indexsearcher.open.warmup_time",
"DEPRECATED - Use solr.core.indexsearcher.warmup_time instead",
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);
})));

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

Expand Down Expand Up @@ -1417,7 +1422,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())
Expand All @@ -1427,7 +1432,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 @@ -1437,7 +1442,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(
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 @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
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_executor",
"solr.node.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 @@ -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);
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();
}

// Return named filtered snapshots if not label filters provided
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
() -> {
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 @@ -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());
Expand Down Expand Up @@ -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(
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Loading