Skip to content

Prometheus Metrics

NORA exposes Prometheus-compatible metrics at the /metrics endpoint. By default no authentication is required; set NORA_AUTH_PUBLIC_METRICS=false to require it.

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
/rpm/*rpm
/deb/*deb
/cpan/*cpan
/hf/*hf
/ui*ui
(other paths)other
MetricTypeLabelsDescription
nora_cache_requests_totalCounterregistry, resultCache lookups (hit or miss)
MetricTypeLabelsDescription
nora_storage_operations_totalCounteroperation, statusStorage operations by operation (get, get_range, get_reader, put, delete, copy, list, list_with_meta, stat, pin) and status (ok, error; miss for stat/pin; integrity_fail / verify_error for get)
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

registry is the breaker key: the format name, or <format>:<upstream URL> for Docker, PyPI and npm, which keep one breaker per configured upstream. Filter a format with registry=~"pypi(:.*)?".

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
nora_gc_proxy_cache_evicted_totalCounterProxy-cached RPM/Debian files evicted by the size cap (NORA_GC_PROXY_CACHE_MAX_BYTES)
nora_gc_proxy_cache_bytes_freed_totalCounterBytes freed by proxy-cache eviction
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
nora_upload_sessionsGauge(none)Docker blob upload sessions currently held (sessions expire after 30 minutes)
nora_upload_in_flightGauge(none)Docker blob uploads currently streaming to disk

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)
nora_upstream_policy_blocked_totalCounterregistry, reasonUpstream 4xx answers carrying a geo or WAF block signature, relayed to the client as 404 (reason ∈ geo, waf)

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 (reason ∈ leader, budget)
MetricTypeLabelsDescription
nora_curation_decisions_totalCounterdecisionCuration decisions by effective outcome (allow, block, audit, skip)
nora_quarantine_holds_totalCounterregistry, outcomeArtifacts held by the digest quarantine (outcome ∈ blocked, 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)
nora_auth_oidc_rejected_totalCounterreasonOIDC token rejections by reason (no_provider, disabled, lifetime_exceeded, no_role_rule, algorithm, jwks, jwt_invalid, other)
nora_namespace_isolation_refused_totalCounterregistryRequests for an internal-namespace name refused by namespace isolation
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)
nora_packument_rebuilt_totalCounterregistrynpm packuments reassembled from per-version data because the stored packument was missing
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