Skip to main content

Health and metrics

Heimdall exposes three endpoints aimed at orchestrators, load balancers, and Prometheus.

Liveness — GET /healthz

Returns 200 OK with body ok as long as the process is able to handle HTTP requests. There is no real check behind it — by definition a process that can answer this endpoint is alive.

Use this for the liveness probe in Kubernetes / Docker. If the body or status code stops responding, the orchestrator should restart the pod.

curl -fsSL http://localhost:8080/healthz
# ok

Readiness — GET /readyz

Runs every health check registered with services.AddHealthChecks() and returns a structured JSON report. The HTTP status code is 200 when every check reports healthy, 503 otherwise.

curl -fsSL http://localhost:8080/readyz | jq
{
"status": "Healthy",
"entries": {
"upstream": {
"status": "Healthy",
"description": "https://api.nuget.org/v3/index.json reachable"
}
}
}

The bundled upstream check is UpstreamReadinessCheck — it probes each configured feed's upstream URL. When the upstream is unreachable, the endpoint returns 503 and an entry describing why. Use this for the readiness probe so the load balancer takes Heimdall out of rotation during upstream outages.

Metrics — GET /metrics

Prometheus exposition via prometheus-net. The path defaults to /metrics and is configurable:

heimdall:
observability:
metrics:
path: "/metrics"

UseHttpMetrics() (prometheus-net.AspNetCore) automatically publishes the standard ASP.NET Core HTTP counters:

MetricTypeNotes
http_requests_received_totalcounterPer method/path/status.
http_request_duration_secondshistogramLatency buckets.
http_requests_in_progressgaugeConcurrent requests.
process_*gaugesStandard process and GC metrics.
dotnet_collection_count_totalcounterGC collections by generation.

Scrape config example:

scrape_configs:
- job_name: heimdall
metrics_path: /metrics
static_configs:
- targets: ["heimdall.internal:8080"]

Key dashboards are sketched in Monitoring.