Repository navigation
Conversation
The operator now exposes metrics about its own work, next to the generic controller-runtime, workqueue, client-go and Go runtime metrics, all prefixed solr_operator_: Gauges computed at scrape time from the operator's cache, so they never go stale when a resource is deleted: - managed_resources by kind and namespace - solrcloud_info, _desired_replicas, _ready_replicas, _up_to_date_replicas and _ready per SolrCloud - solrcloud_cluster_operations by operation and running/queued state - solrbackup_state (running/succeeded/failed) per SolrBackup - solrprometheusexporter_ready per SolrPrometheusExporter Counters incremented by the controllers: - reconciles_total per resource and result - solrcloud_cluster_operations_total by operation and completed/failed/paused result - solrbackup_runs_total by result - solr_api_requests_total per SolrCloud and result The helm chart gets metrics.podMonitor.* values to create a PodMonitor for the operator pods, only sets prometheus.io/scrape when metrics are enabled, and adds prometheus.io/port and prometheus.io/path annotations. New docs page getting-started/operator-metrics.adoc lists the metrics, how to scrape them and example queries. Closes apache#690
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved metrics defects can misattribute resource namespaces, double-count completed backup runs after failed status patches, and incorrectly report readiness when replicas are omitted.
3 open issues
What changed in this PR
Adds application-level monitoring for the Solr Operator, addressing #690 through resource gauges and operational counters on the existing /metrics endpoint.
Changes:
- Adds cache-backed resource metrics and counters for reconciles, cluster operations, backups, and Solr API requests.
- Adds configurable scrape annotations and an optional Helm-managed PodMonitor.
- Adds metric tests, scraping guidance, example queries, and upgrade notes.
| File | Description |
|---|---|
| main.go | Registers the cache-backed metrics collector. |
| helm/solr-operator/values.yaml | Adds scrape annotation and PodMonitor settings. |
| helm/solr-operator/templates/podmonitor.yaml | Defines the optional operator PodMonitor. |
| helm/solr-operator/templates/deployment.yaml | Makes scrape annotations configurable. |
| helm/solr-operator/README.md | Documents monitoring and Helm settings. |
| helm/solr-operator/Chart.yaml | Records monitoring additions in the changelog. |
| go.mod | Promotes Prometheus libraries to direct dependencies. |
| docs/modules/upgrade-notes/pages/upgrade-notes.adoc | Explains monitoring-related upgrade changes. |
| docs/modules/getting-started/pages/running-the-operator.adoc | Links to the metrics guide. |
| docs/modules/getting-started/pages/operator-metrics.adoc | Documents scraping, metrics, and example queries. |
| docs/modules/getting-started/nav.adoc | Adds the metrics guide to navigation. |
| controllers/util/solr_api/v2.go | Counts v2 Solr API request outcomes. |
| controllers/util/solr_api/api.go | Counts Solr Collections API request outcomes. |
| controllers/suite_test.go | Registers resource metrics for integration tests. |
| controllers/solrprometheusexporter_controller.go | Instruments exporter reconciles. |
| controllers/solrcloud_controller.go | Instruments reconciles and cluster operation outcomes. |
| controllers/solrbackup_controller.go | Instruments reconciles and backup completion. |
| controllers/resource_metrics.go | Collects resource counts, readiness, and operation state. |
| controllers/resource_metrics_test.go | Tests resource gauges and cache read failures. |
| controllers/resource_metrics_integration_test.go | Tests metrics against the manager cache. |
| controllers/metrics/metrics.go | Defines counters, reconcile instrumentation, and cleanup. |
| controllers/metrics/metrics_test.go | Tests counter recording and deleted-resource cleanup. |
Review effort: Balanced
Default desired replicas to DefaultSolrReplicas when spec.replicas is not persisted yet, so a new SolrCloud is not reported as ready with zero desired pods. Increment solrbackup_runs_total only after the status patch that records the finish succeeds, so a failed patch does not count the same run again on the retry. Set honorLabels on the PodMonitor endpoint, so the namespace label keeps naming the Solr resource's namespace instead of the operator pod's.
janhoy
marked this pull request as ready for review
November 9, 2026 08:08
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

🤖 AI assisted 🤖
Fixes #690
The operator now exposes metrics about its own work on the existing
/metricsendpoint, next to the generic controller-runtime, workqueue, client-go and Go runtime metrics. All of them are prefixedsolr_operator_.Gauges, computed at scrape time from the operator's cache so they reflect exactly what the operator sees and disappear with the resource:
managed_resourcesper kind and namespace;solrcloud_info(Solr version),solrcloud_desired_replicas,solrcloud_ready_replicas,solrcloud_up_to_date_replicasandsolrcloud_readyper SolrCloud;solrcloud_cluster_operationsby operation and running/queued state;solrbackup_state(running/succeeded/failed) per SolrBackup;solrprometheusexporter_readyper exporter.Counters, incremented by the controllers:
reconciles_totalper resource and result (controller-runtime only counts per controller, this tells which resource);solrcloud_cluster_operations_totalby operation and completed/failed/paused result;solrbackup_runs_totalby result;solr_api_requests_totalper SolrCloud and result. Counter series are removed when the operator sees the resource has been deleted. The reconcile and queue-depth stats asked for in the issue are already covered bycontroller_runtime_*andworkqueue_*, so the docs point at those instead of duplicating them.The helm chart gets a
prometheussection mirroring thesolrchart:prometheus.scrapeAnnotations.enable(defaulttrue, since the operator pods have always carriedprometheus.io/scrape) now also addsprometheus.io/portandprometheus.io/path, andprometheus.podMonitor.*creates a PodMonitor for the operator pods for a Prometheus Operator setup. The PodMonitor setshonorLabels, so thenamespacelabel of the metrics keeps naming the Solr resource's namespace rather than the operator pod's; the docs say the same abouthonor_labelsfor annotation-based scrape configs. It is not gated on CRD detection, so offline rendering works.New docs page
getting-started/operator-metrics.adoccovers scraping, the metrics reference, the useful generic metrics, multi-replica behaviour and example alert queries. Upgrade note and chart changelog included.Testing
Unit tests for the counters and the reconciler wrapper, fake-client tests for the collector including read errors, and an envtest spec that registers the collector on the real manager cache like
main.godoes and checks that series appear and disappear with a SolrCloud.make lint,make check-docsandmake unit-testspass. E2E tests were not run.Overlaps with #880 only in
values.yaml(both add keys underprometheus) and the chart changelog.