NORA exposes Prometheus-compatible metrics at the /metrics endpoint. No authentication is required.
curl http://localhost:4000/metrics
| Metric | Type | Labels | Description |
|---|
nora_http_requests_total | Counter | registry, method, status | Total HTTP requests processed |
nora_http_request_duration_seconds | Histogram | registry, method | Request latency (buckets: 1ms to 10s) |
The registry label is derived from the request path:
| Path prefix | Label |
|---|
/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 |
| Metric | Type | Labels | Description |
|---|
nora_cache_requests_total | Counter | registry, result | Cache lookups (hit or miss) |
| Metric | Type | Labels | Description |
|---|
nora_storage_operations_total | Counter | operation, status | Storage operations (get, put, delete, list) with ok or error status |
nora_artifacts_total | Gauge | registry | Artifacts currently stored per registry (rises and falls with GC) |
nora_storage_bytes | Gauge | registry | Stored artifact bytes per registry (label total = full footprint incl. metadata) |
nora_storage_get_bytes | Histogram | registry | Body size of buffered Storage::get() reads (buckets: 1KB to 512MB) |
nora_storage_verify_duration_seconds | Histogram | registry | SHA-256 integrity-verify wall-clock per buffered get, including blocking-pool queue time |
Available when NORA_CB_ENABLED=true.
| Metric | Type | Labels | Description |
|---|
nora_circuit_breaker_state | Gauge | registry | Current state: 0 = closed, 1 = open, 2 = half-open |
nora_circuit_breaker_rejections_total | Counter | registry | Requests rejected by an open breaker |
| Metric | Type | Description |
|---|
nora_gc_blobs_removed_total | Counter | Orphaned blobs removed by GC |
nora_gc_bytes_freed_total | Counter | Bytes freed by GC |
nora_gc_duration_seconds | Histogram | Duration of GC runs (buckets: 0.1s to 300s) |
nora_gc_last_run_timestamp | Gauge | Unix timestamp of last GC run |
nora_gc_metadata_phantoms_total | Counter | Phantom version entries cleaned from metadata |
nora_gc_stat_failures_total | Counter | Orphans GC could not stat (kept, age unknown) — nonzero means GC may be unable to reclaim space; alert on it |
| Metric | Type | Description |
|---|
nora_retention_versions_deleted_total | Counter | Versions removed by retention policies |
nora_retention_bytes_freed_total | Counter | Bytes freed by retention |
nora_retention_duration_seconds | Histogram | Duration of retention runs (buckets: 0.1s to 300s) |
nora_retention_last_run_timestamp | Gauge | Unix timestamp of last retention run |
| Metric | Type | Labels | Description |
|---|
nora_downloads_total | Counter | registry | Total artifact downloads |
nora_uploads_total | Counter | registry | Total artifact uploads |
Emitted on the proxy path when NORA fetches from a configured upstream.
| Metric | Type | Labels | Description |
|---|
nora_upstream_request_duration_seconds | Histogram | registry, status | Upstream proxy request latency (buckets: 1ms to 30s) |
nora_proxy_active_downloads | Gauge | (none) | Docker blob proxy downloads currently streaming |
nora_proxy_download_bytes_total | Counter | (none) | Total bytes downloaded from upstream Docker registries (verified downloads only) |
Conditional-request (304) revalidation and single-flight request coalescing on the proxy path.
| Metric | Type | Labels | Description |
|---|
nora_proxy_upstream_304_total | Counter | registry | Upstream 304 Not Modified responses on revalidation |
nora_proxy_revalidation_bytes_saved_total | Counter | registry | Body bytes not re-downloaded thanks to a 304 revalidation |
nora_proxy_revalidation_errors_total | Counter | registry | Revalidation attempts that fell back to a full fetch |
nora_proxy_coalesced_total | Counter | registry | Follower requests served from the single-flight leader without an upstream fetch |
nora_proxy_inflight | Gauge | registry | Distinct keys currently being fetched under single-flight coalescing |
nora_proxy_coalesce_fallthrough_total | Counter | registry, reason | Followers that fell through to their own fetch instead of coalescing (reason ∈ leader, budget) |
| Metric | Type | Labels | Description |
|---|
nora_curation_decisions_total | Counter | decision | Curation decisions by effective outcome (allow, block, audit, skip) |
nora_quarantine_holds_total | Counter | registry, outcome | Artifacts held by the digest quarantine (outcome ∈ blocked, observed) |
| Metric | Type | Labels | Description |
|---|
nora_auth_namespace_scope_total | Counter | provider, decision | OIDC namespace_scope enforcement decisions (allow, deny, would_deny) |
nora_response_upstream_url_leak_total | Counter | registry | Upstream hostname detected in an outgoing response body |
nora_leak_detection_skipped_total | Counter | reason | Leak-detection scans skipped (body too large or unknown size) |
| Metric | Type | Labels | Description |
|---|
nora_cache_write_errors_total | Counter | registry, operation | Cache write failures in background cache tasks |
nora_metadata_corrupt_total | Counter | registry | Corrupt metadata detected during publish (parse failure on existing data) |
| Metric | Type | Labels | Description |
|---|
nora_uptime_seconds | Gauge | (none) | Process uptime in seconds |
# Request rate by registry (5m window)
sum by (registry) (rate(nora_http_requests_total[5m]))
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])