Skip to content

Prometheus Metrics

NORA exposes Prometheus-compatible metrics at the /metrics endpoint. No authentication is required.

Terminal window
curl http://localhost:4000/metrics
MetricTypeLabelsDescription
nora_http_requests_totalCounterregistry, method, statusTotal HTTP requests processed
nora_http_request_duration_secondsHistogramregistry, methodRequest latency (buckets: 1ms to 10s)

The registry label is derived from the request path:

Path prefixLabel
/v2*docker
/npm*npm
/simple*, /packages*pypi
/maven2*maven
/cargo*cargo
/go/*go
/raw/*raw
/gems/*gems
/terraform/*terraform
/ansible/*ansible
/nuget/*nuget
/pub/*pub
/conan/*conan
/ui*ui
(other paths)other
MetricTypeLabelsDescription
nora_cache_requests_totalCounterregistry, resultCache lookups (hit or miss)
MetricTypeLabelsDescription
nora_storage_operations_totalCounteroperation, statusStorage operations (get, put, delete, list) with ok or error status
nora_artifacts_totalGaugeregistryArtifacts currently stored per registry (rises and falls with GC)
nora_storage_bytesGaugeregistryStored artifact bytes per registry (label total = full footprint incl. metadata)
nora_storage_get_bytesHistogramregistryBody size of buffered Storage::get() reads (buckets: 1KB to 512MB)
nora_storage_verify_duration_secondsHistogramregistrySHA-256 integrity-verify wall-clock per buffered get, including blocking-pool queue time

Available when NORA_CB_ENABLED=true.

MetricTypeLabelsDescription
nora_circuit_breaker_stateGaugeregistryCurrent state: 0 = closed, 1 = open, 2 = half-open
nora_circuit_breaker_rejections_totalCounterregistryRequests rejected by an open breaker
MetricTypeDescription
nora_gc_blobs_removed_totalCounterOrphaned blobs removed by GC
nora_gc_bytes_freed_totalCounterBytes freed by GC
nora_gc_duration_secondsHistogramDuration of GC runs (buckets: 0.1s to 300s)
nora_gc_last_run_timestampGaugeUnix timestamp of last GC run
nora_gc_metadata_phantoms_totalCounterPhantom version entries cleaned from metadata
nora_gc_stat_failures_totalCounterOrphans GC could not stat (kept, age unknown) — nonzero means GC may be unable to reclaim space; alert on it
MetricTypeDescription
nora_retention_versions_deleted_totalCounterVersions removed by retention policies
nora_retention_bytes_freed_totalCounterBytes freed by retention
nora_retention_duration_secondsHistogramDuration of retention runs (buckets: 0.1s to 300s)
nora_retention_last_run_timestampGaugeUnix timestamp of last retention run
MetricTypeLabelsDescription
nora_downloads_totalCounterregistryTotal artifact downloads
nora_uploads_totalCounterregistryTotal artifact uploads

Emitted on the proxy path when NORA fetches from a configured upstream.

MetricTypeLabelsDescription
nora_upstream_request_duration_secondsHistogramregistry, statusUpstream proxy request latency (buckets: 1ms to 30s)
nora_proxy_active_downloadsGauge(none)Docker blob proxy downloads currently streaming
nora_proxy_download_bytes_totalCounter(none)Total bytes downloaded from upstream Docker registries (verified downloads only)

Conditional-request (304) revalidation and single-flight request coalescing on the proxy path.

MetricTypeLabelsDescription
nora_proxy_upstream_304_totalCounterregistryUpstream 304 Not Modified responses on revalidation
nora_proxy_revalidation_bytes_saved_totalCounterregistryBody bytes not re-downloaded thanks to a 304 revalidation
nora_proxy_revalidation_errors_totalCounterregistryRevalidation attempts that fell back to a full fetch
nora_proxy_coalesced_totalCounterregistryFollower requests served from the single-flight leader without an upstream fetch
nora_proxy_inflightGaugeregistryDistinct keys currently being fetched under single-flight coalescing
nora_proxy_coalesce_fallthrough_totalCounterregistry, reasonFollowers that fell through to their own fetch instead of coalescing (reasonleader, budget)
MetricTypeLabelsDescription
nora_curation_decisions_totalCounterdecisionCuration decisions by effective outcome (allow, block, audit, skip)
nora_quarantine_holds_totalCounterregistry, outcomeArtifacts held by the digest quarantine (outcomeblocked, observed)
MetricTypeLabelsDescription
nora_auth_namespace_scope_totalCounterprovider, decisionOIDC namespace_scope enforcement decisions (allow, deny, would_deny)
nora_response_upstream_url_leak_totalCounterregistryUpstream hostname detected in an outgoing response body
nora_leak_detection_skipped_totalCounterreasonLeak-detection scans skipped (body too large or unknown size)
MetricTypeLabelsDescription
nora_cache_write_errors_totalCounterregistry, operationCache write failures in background cache tasks
nora_metadata_corrupt_totalCounterregistryCorrupt metadata detected during publish (parse failure on existing data)
MetricTypeLabelsDescription
nora_uptime_secondsGauge(none)Process uptime in seconds
# Request rate by registry (5m window)
sum by (registry) (rate(nora_http_requests_total[5m]))
# Cache hit ratio
sum(rate(nora_cache_requests_total{result="hit"}[5m]))
/
sum(rate(nora_cache_requests_total[5m]))
# p99 latency per registry
histogram_quantile(0.99, sum by (le, registry) (rate(nora_http_request_duration_seconds_bucket[5m])))
# Circuit breaker alerts (open state)
nora_circuit_breaker_state == 1
# GC bytes freed per hour
increase(nora_gc_bytes_freed_total[1h])
prometheus.yml
scrape_configs:
- job_name: nora
scrape_interval: 15s
static_configs:
- targets: ['nora:4000']
metrics_path: /metrics