Skip to content

Native Crossplane telemetry

The Crossplane runtime and the pinned Grafana provider already expose managed-resource telemetry. This page records the exact signal contract and the boundary of what that telemetry can tell an operator. It does not add instrumentation to the composition function and it does not install a monitoring stack.

Metric families

The function module pins github.com/crossplane/crossplane-runtime/v2 v2.4.0. The runtime source constructs the four managed reconciler histograms in pkg/reconciler/managed/metrics.go and the three state-recorder gauges in pkg/statemetrics/mr_state_metrics.go. All seven use the Prometheus crossplane subsystem and carry exactly one label: gvk.

FamilyTypeNative meaningFleet question it answers
crossplane_managed_resource_first_time_to_reconcile_secondsHistogramTime from creation until the controller first detects a resource whose initial observation is captured as Synced=UnknownAre resources of a kind taking longer than usual to enter reconciliation?
crossplane_managed_resource_first_time_to_readiness_secondsHistogramTime from creation until the first Ready=True condition for a resource whose initial observation is captured as Synced=UnknownAre resources of a kind taking longer than usual to become ready?
crossplane_managed_resource_deletion_secondsHistogramTime from deletion timestamp until deletion completesAre deletions of a kind taking longer than usual?
crossplane_managed_resource_drift_secondsHistogram, ALPHA upstreamTime since the previous successful reconcile when the resource is found out of sync; provider restart is excludedIs drift detection for a kind delayed?
crossplane_managed_resource_existsGaugeNumber of managed resources of a kindHow many resources of a kind exist?
crossplane_managed_resource_readyGaugeNumber of managed resources of a kind in Ready=TrueHow many resources of a kind are ready?
crossplane_managed_resource_syncedGaugeNumber of managed resources of a kind in Synced=TrueHow many resources of a kind are synced?

For an activated kind, the difference between crossplane_managed_resource_exists and crossplane_managed_resource_synced is a fleet-level count of resources that are not currently Synced=True. The label value is the group, version, and kind string; it is not an object identity.

The provider starts state metrics

The installed provider package is Grafana Crossplane provider v2.14.0, pinned by digest in platform/provider/provider-grafana.yaml. In the v2.14.0 source, cmd/provider/main.go creates both managed.NewMRMetricRecorder() and statemetrics.NewMRStateMetrics(), registers both with the controller-runtime metrics registry, and passes both through MetricOptions. A generated managed controller then creates statemetrics.NewMRStateRecorder(...) and adds it to the manager when those options are present. The source path is visible, for example, in accesspolicyrotatingtoken/zz_controller.go.

Therefore the three state-recorder families are part of the provider's native path for activated managed-resource kinds. SafeStart still controls when each activated controller is registered, so a kind that is not activated has no resource series to report. This is a pinned-source conclusion; this repository does not contact a live provider or cluster to exercise it.

Provider scrape path

The Crossplane Helm chart is pinned to 2.3.4 in deploy/argocd/crossplane.yaml. Its metrics.enabled: true value adds /metrics, port 8080, and prometheus.io/* scrape annotations to the Crossplane and RBAC Manager pods, and exposes container port 8080 on those two pods. It does not modify the provider package DeploymentRuntimeConfig or discover the provider pod.

The provider has its own controller-runtime metrics server. The provider source leaves the manager's metrics options at their defaults; its pinned controller-runtime dependency (pkg/metrics/server/server.go) defaults that server to HTTP :8080 with the /metrics endpoint. The optional deploy/monitoring Kustomize overlay patches the provider DeploymentRuntimeConfig with these pod annotations:

prometheus.io/path: /metrics
prometheus.io/port: "8080"
prometheus.io/scrape: "true"

The overlay includes the normal platform/ base and is not referenced by the default platform installation. A consumer can select deploy/monitoring as the platform Kustomize root, or copy its patch into an existing private overlay that already includes platform/. The default tree therefore remains inert, and just check does not require a Prometheus, PodMonitor, or ServiceMonitor CRD. No monitoring stack is bundled here; the consumer supplies the scraper and its security policy.

What native telemetry cannot answer

The gvk label intentionally aggregates across objects. Native telemetry cannot identify the stuck object's name, namespace, composite owner, stack, or provider configuration. It also has no token expiry timestamp, rotation window, or remaining lifetime label. A nonzero unsynced count can trigger fleet-level investigation, but it cannot say which token needs attention or how close that token is to expiry.

The per-object stuck-token question is answered by the credential-health conditions on the composite from GCV-0087. Conditions and object inspection provide the identity and reason; native Crossplane metrics provide the aggregate kind-level signal.

Scope

This reference adds no composition-function instrumentation, exporter, custom metric, PodMonitor, ServiceMonitor, or monitoring stack. The only new deployment surface is the consumer-selected pod annotation patch described above.