Skip to main content

Solr

Solr exposes Prometheus-format metrics natively at /solr/admin/metrics?wt=prometheus, so no exporter sidecar is needed. The OpenTelemetry Collector scrapes that endpoint with the prometheus receiver to collect 70+ metrics spanning request throughput and latency, searcher cache hit ratios, JVM heap and GC, indexing backlog, and index and disk capacity from Solr 7.x+. This guide configures the receiver, points it at a Solr node, and ships metrics to base14 Scout.

Prerequisites​

RequirementMinimumRecommended
Solr7.x10.0
OTel Collector Contrib0.90.0latest
base14 ScoutAny-

Before starting:

  • Solr's HTTP port (8983) must be reachable from the host running the Collector.
  • The /solr/admin/metrics endpoint is enabled by default.
  • A Scout account and OTLP endpoint.
  • OTel Collector installed - see Docker Compose Setup.

What You'll Monitor​

Metrics are grouped into three tiers by how you use them. Scrape Core always, alert on Operational, and reach for Diagnostic during an incident or capacity review.

Core - is it up and serving​

MetricWhat it tells you
upScrape succeeded - the metrics endpoint is reachable and monitoring itself is alive.
solr_core_requests_totalRequest throughput per handler and core - the headline KPI for "is Solr answering queries".

Operational - what to alert on​

GroupMetricsWhat it tells you
Request latencysolr_core_requests_times_milliseconds, solr_node_requests_times_millisecondsPer-handler and node-level request latency (count / sum / quantiles).
Node throughputsolr_node_requests_totalNode-level request count alongside the per-core total.
Searcher cachesolr_core_indexsearcher_cache_lookups_total, solr_core_indexsearcher_cache_ops_totalCache lookups and hits / inserts / evictions by op - the inputs to hit ratio.
JVM memoryjvm_memory_used_bytes, jvm_memory_limit_bytesHeap / non-heap in use against the ceiling; the saturation signal for OOM and GC risk.
GCjvm_gc_duration_secondsStop-the-world pause time; rising pauses hurt query latency.
Indexing backlogsolr_core_update_docs_pending_commitDocs added but not yet committed - a climbing value means commits are stalled.
Capacitysolr_core_index_size_megabytes, solr_disk_space_megabytes, solr_cores_loadedOn-disk index size per core, free disk for Solr data, and the count of loaded cores.

Hit ratio is not a single metric - derive it as solr_core_indexsearcher_cache_ops_total{...hits} over solr_core_indexsearcher_cache_lookups_total.

Diagnostic - for investigation and tuning​

Higher cardinality; enable on demand. In production you can drop this tier with metric_relabel_configs and keep Core + Operational.

GroupMetricsWhen you reach for it
Searcher cachessolr_core_indexsearcher_cache_size, _cache_ram_used_bytes, _cache_warmup_time_milliseconds, _live_docs_cache_total, _termstats_cache, solr_core_field_cache_entries, _field_cache_size_bytesPer-cache sizing, RAM, and warmup cost when tuning cache configuration.
Index / searcher detailsolr_core_indexsearcher_index_docs, _index_num_docs, _index_version, _index_commit_size_megabytes, _open_time_milliseconds, _open_warmup_time_milliseconds, solr_core_segments, solr_core_searcher_new_total, solr_core_indexwriter_flushes_total, solr_core_disk_space_megabytes, solr_core_ref_countSegment counts, searcher reopens, and index internals during merge or commit investigation.
Update / transaction logsolr_core_update_auto_commits_total, _commit_ops_total, _commit_stats, _committed_ops_total, _cumulative_ops, _log_buffered_ops, _log_replay_logs_remaining, _log_size_remaining_bytes, _log_state, _submitted_ops_totalCommit cadence and tlog replay state when indexing or recovery misbehaves.
Replicationsolr_core_replication_index_generation, _index_size_megabytes, _index_version, _is_enabled, _is_follower, _is_leaderLeader / follower role and replication progress (read their not-configured defaults on a standalone node).
Executors / thread poolssolr_core_executor_thread_pool_size, _executor_thread_pool_tasks, solr_node_executor_task_times_milliseconds, _executor_tasks_running, _executor_tasks_total, _executor_thread_pool_size, _executor_thread_pool_tasksThread-pool depth and task timing under concurrency.
JVM detailjvm_buffer_*, jvm_class_*, jvm_cpu_*, jvm_memory_allocation_bytes, _memory_committed_bytes, _memory_init_bytes, _memory_used_after_last_gc_bytes, jvm_network_*, jvm_system_cpu_utilization_ratio, jvm_thread_countThe full JVM breakdown - buffers, class loading, CPU, allocation, and threads - for deep JVM tuning.

Full metric reference: run curl -s 'http://localhost:8983/solr/admin/metrics?wt=prometheus' against your Solr instance, or see the Solr metrics reporting documentation.

SolrCloud-only series (overseer, ZooKeeper, shard / replica state) do not appear on a standalone node, and the replication series read their not-configured defaults until replication is set up.

Key Alerts to Configure​

Threshold guidance for the most useful Operational-tier series. Tune to your workload; these are starting points.

MetricWarningCriticalWhy it matters
solr_core_requests_times_milliseconds (p95)Rising vs baselineSustained regressionQuery slowdown; check cache hit ratio, GC, and slow queries.
cache_ops_total{...hits} / cache_lookups_totalHit ratio fallingSharply lowCache too small or churning; tune cache sizes / autowarm.
jvm_memory_used_bytes / jvm_memory_limit_bytes> 80% of limitNear limitOOM and long-GC risk; raise heap or reduce cache / field load.
rate(jvm_gc_duration_seconds)RisingSustained highStop-the-world pauses hurting latency; tune heap / GC.
solr_core_update_docs_pending_commitClimbing without commitNot drainingCommits stalled; check commit settings and indexing throughput.
solr_disk_space_megabytes (free)Trending down< 10% of volumePlan storage before the volume fills as index_size_megabytes grows.

Access Setup​

Solr serves Prometheus-format metrics natively - there is no exporter to run. The metrics live at /solr/admin/metrics and the wt=prometheus query parameter selects the Prometheus rendering.

Verify the endpoint is reachable:

Verify access
# Check Solr status
curl -s http://localhost:8983/solr/admin/info/system | head -20

# List cores
curl -s http://localhost:8983/solr/admin/cores

# Verify Prometheus metrics endpoint
curl -s 'http://localhost:8983/solr/admin/metrics?wt=prometheus' | head -20

No authentication is required by default. Clusters with Basic Authentication enabled need credentials on the scrape - see Authentication below.

The Collector's prometheus receiver must override the default /metrics path with metrics_path: /solr/admin/metrics and pass params: { wt: [prometheus] }. Both are set in the Configuration section.

Configuration​

config/otel-collector.yaml
receivers:
prometheus:
config:
scrape_configs:
- job_name: solr
scrape_interval: 30s
metrics_path: /solr/admin/metrics # Solr's endpoint, not the default /metrics
params:
wt: [prometheus] # Select Prometheus rendering
static_configs:
- targets:
- ${env:SOLR_HOST}:8983

processors:
resource:
attributes:
- key: environment
value: ${env:ENVIRONMENT}
action: upsert
- key: service.name
value: ${env:SERVICE_NAME}
action: upsert

batch:
timeout: 10s
send_batch_size: 1024

exporters:
otlphttp/b14:
endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT}
tls:
insecure_skip_verify: true # Set to false with TLS in production

service:
pipelines:
metrics:
receivers: [prometheus]
processors: [resource, batch]
exporters: [otlphttp/b14]

To control metric volume in production, drop the Diagnostic tier with a metric_relabel_configs block on the scrape config while keeping the Core and Operational series.

Environment Variables​

.env
SOLR_HOST=localhost
ENVIRONMENT=your_environment
SERVICE_NAME=your_service_name
OTEL_EXPORTER_OTLP_ENDPOINT=https://<your-tenant>.base14.io

Authentication​

For Solr clusters with Basic Authentication enabled, add basic_auth to the scrape config:

config/otel-collector.yaml (auth)
receivers:
prometheus:
config:
scrape_configs:
- job_name: solr
metrics_path: /solr/admin/metrics
params:
wt: [prometheus]
basic_auth:
username: ${env:SOLR_USERNAME}
password: ${env:SOLR_PASSWORD}
static_configs:
- targets:
- ${env:SOLR_HOST}:8983

Filtering Metrics​

To collect only specific metric groups, use Solr's group parameter:

config/otel-collector.yaml (filter)
receivers:
prometheus:
config:
scrape_configs:
- job_name: solr
metrics_path: /solr/admin/metrics
params:
wt: [prometheus]
group: [jvm, node, core] # Limit to selected metric groups
static_configs:
- targets:
- ${env:SOLR_HOST}:8983

Available groups: jvm, jetty, node, core, overseer.

Verify the Setup​

Start the Collector and check for metrics within 60 seconds:

Verify metrics collection
# Check Collector logs for scraped Solr metrics (grep the metric prefix)
docker logs otel-collector 2>&1 | grep -i "solr_core"

# Confirm the endpoint is serving Prometheus-format metrics
curl -s 'http://localhost:8983/solr/admin/metrics?wt=prometheus' \
| grep solr_core_requests_total

# Generate request and index traffic so the series move
curl -s 'http://localhost:8983/solr/demo/select?q=*:*' > /dev/null

Troubleshooting​

Connection refused on port 8983​

Cause: The Collector cannot reach Solr at the configured address.

Fix:

  1. Verify Solr is running: docker ps | grep solr or systemctl status solr.
  2. Confirm Solr is listening: curl http://localhost:8983/solr/.
  3. Check firewall rules if the Collector runs on a separate host.

Metrics endpoint returns JSON instead of Prometheus format​

Cause: The wt=prometheus parameter is missing from the scrape config, so Solr falls back to JSON, which the prometheus receiver cannot parse.

Fix:

  1. Ensure params: { wt: [prometheus] } is set on the scrape job.
  2. Confirm metrics_path is /solr/admin/metrics, not the default /metrics.
  3. Verify with curl 'http://localhost:8983/solr/admin/metrics?wt=prometheus'.

Queries are slow or latency is climbing​

Cause: A low cache hit ratio, JVM heap pressure, or GC pauses.

Look at: the searcher-cache Diagnostic series - solr_core_indexsearcher_cache_size, _cache_ram_used_bytes, and _cache_warmup_time_milliseconds - alongside jvm_memory_used_bytes against jvm_memory_limit_bytes and the jvm_gc_duration_seconds rate. A hit ratio falling while warmup time climbs points at undersized or churning caches; heap near the limit with rising GC points at memory pressure.

Fix:

  1. Tune cache sizes and autowarm counts if the hit ratio is low.
  2. Raise heap or reduce cache / field load if jvm_memory_used_bytes sits near jvm_memory_limit_bytes.

Indexing backlog grows and commits stall​

Cause: Commits are not keeping up with indexing, or the transaction log is replaying.

Look at: the update / tlog Diagnostic series - solr_core_update_commit_ops_total, solr_core_update_auto_commits_total, and solr_core_update_log_replay_logs_remaining - against the Operational solr_core_update_docs_pending_commit. A pending count that climbs while commit ops stay flat means commits are stalled; non-zero replay logs means the node is still recovering its tlog.

Fix:

  1. Review autoCommit / autoSoftCommit settings and commit cadence.
  2. Throttle indexing throughput or add capacity if commits cannot keep up.

Core-level metrics missing​

Cause: Core metrics (solr_core_*) only appear when at least one core is loaded.

Fix:

  1. Create a core: curl 'http://localhost:8983/solr/admin/cores?action=CREATE&name=demo&configSet=_default'.
  2. Verify cores exist: curl http://localhost:8983/solr/admin/cores.
  3. Check solr_cores_loaded reflects the expected count.

No metrics appearing in Scout​

Cause: Metrics are collected but not exported.

Fix:

  1. Check Collector logs for export errors: docker logs otel-collector.
  2. Verify OTEL_EXPORTER_OTLP_ENDPOINT is set correctly.
  3. Confirm the pipeline includes both the receiver and the exporter.

FAQ​

Does this work with Solr running in Kubernetes?​

Yes. Set targets to the Solr pod or service DNS (e.g., solr-0.solr.default.svc.cluster.local:8983) and keep the metrics_path and params overrides. The Collector can run as a sidecar or a DaemonSet.

How do I monitor a SolrCloud cluster?​

Add every node endpoint to the scrape config. Each node is scraped independently and identified by its instance label:

config/otel-collector.yaml (multi-node)
receivers:
prometheus:
config:
scrape_configs:
- job_name: solr
metrics_path: /solr/admin/metrics
params:
wt: [prometheus]
static_configs:
- targets:
- solr-1:8983
- solr-2:8983
- solr-3:8983

What is the difference between node and core metrics?​

Node metrics (solr_node_*) cover the whole instance - aggregate request counts, latency, and executor pools. Core metrics (solr_core_*) are per-core and include request throughput, searcher caches, index size, and update-handler stats. Core metrics only appear once a core is loaded.

Why are overseer and replication metrics empty?​

Overseer metrics only appear in SolrCloud mode on the elected overseer node, so a standalone instance does not emit them. The solr_core_replication_* series read their not-configured defaults (for example solr_core_replication_is_enabled) until replication is actually set up.

Why is the cache hit ratio not a single metric?​

Solr exposes the inputs, not the ratio. Derive it as solr_core_indexsearcher_cache_ops_total{...hits} over solr_core_indexsearcher_cache_lookups_total and chart or alert on the quotient.

What's Next?​

  • Create Dashboards: Explore pre-built dashboards or build your own. See Create Your First Dashboard.
  • Monitor More Components: Add monitoring for Elasticsearch, Redis, and other components.
  • Fine-tune Collection: Drop the Diagnostic tier in production with metric_relabel_configs to control volume; keep it available for incident investigation.
Was this page helpful?