Caddy.Metrics (Caddy v2.3.1)

View Source

Prometheus metrics integration for Caddy reverse proxy.

Provides access to Caddy's Prometheus metrics endpoint, parsing the exposition format into Elixir data structures.

Enabling Metrics in Caddy

Add the servers metrics directive to your Caddyfile:

{
  servers {
    metrics
  }
}

Usage

# One-time fetch
{:ok, metrics} = Caddy.Metrics.fetch()
{:ok, raw_text} = Caddy.Metrics.fetch_raw()

# Access specific metrics
requests = Caddy.Metrics.get(metrics, :http_requests_total)

# Health derivation
Caddy.Metrics.healthy?(metrics)
Caddy.Metrics.error_rate(metrics)
Caddy.Metrics.latency_p99(metrics)

Configuration

config :caddy,
  metrics_enabled: true,
  metrics_interval: 15_000,
  metrics_endpoint: "/metrics"

Summary

Functions

Calculate the error rate from HTTP request metrics.

Fetch and parse metrics from Caddy's Prometheus endpoint.

Fetch raw Prometheus text from Caddy's metrics endpoint.

Get a specific metric value from parsed metrics.

Check if Caddy and upstreams are healthy based on metrics.

Get the median (p50) latency from request duration metrics.

Get the p99 latency from request duration metrics.

Get total request count from metrics.

Types

label_set()

@type label_set() :: %{optional(atom()) => String.t()}

t()

@type t() :: %Caddy.Metrics{
  http_request_duration_seconds: %{optional(label_set()) => number()},
  http_request_size_bytes: %{optional(label_set()) => number()},
  http_requests_total: %{optional(label_set()) => number()},
  http_response_size_bytes: %{optional(label_set()) => number()},
  process_cpu_seconds_total: number() | nil,
  process_open_fds: integer() | nil,
  process_resident_memory_bytes: integer() | nil,
  raw: binary(),
  reverse_proxy_upstreams_healthy: %{optional(label_set()) => number()},
  timestamp: DateTime.t(),
  tls_handshake_duration_seconds: %{optional(label_set()) => number()},
  tls_handshakes_total: %{optional(label_set()) => number()}
}

Functions

error_rate(metrics)

@spec error_rate(t()) :: float()

Calculate the error rate from HTTP request metrics.

Returns the ratio of 5xx responses to total responses (0.0 to 1.0). Returns 0.0 if no request metrics are available.

Examples

{:ok, metrics} = Caddy.Metrics.fetch()
Caddy.Metrics.error_rate(metrics)
#=> 0.02  # 2% error rate

fetch()

@spec fetch() :: {:ok, t()} | {:error, term()}

Fetch and parse metrics from Caddy's Prometheus endpoint.

Returns a structured %Caddy.Metrics{} struct with parsed metric values.

Examples

{:ok, metrics} = Caddy.Metrics.fetch()
metrics.http_requests_total
#=> %{%{server: "srv0", handler: "reverse_proxy", method: "GET", code: "200"} => 12345}

fetch_raw()

@spec fetch_raw() :: {:ok, binary()} | {:error, term()}

Fetch raw Prometheus text from Caddy's metrics endpoint.

Returns the raw Prometheus exposition format text.

Examples

{:ok, text} = Caddy.Metrics.fetch_raw()
# Returns multi-line Prometheus format text

get(metrics, metric_name)

@spec get(t(), atom()) :: term()

Get a specific metric value from parsed metrics.

Supported Metrics

  • :http_requests_total - Total HTTP requests by labels
  • :http_request_duration_seconds - Request latency histograms
  • :http_request_size_bytes - Request body sizes
  • :http_response_size_bytes - Response body sizes
  • :tls_handshake_duration_seconds - TLS handshake latency
  • :tls_handshakes_total - Total TLS handshakes
  • :reverse_proxy_upstreams_healthy - Upstream health status
  • :process_cpu_seconds_total - Process CPU time
  • :process_resident_memory_bytes - Process memory usage
  • :process_open_fds - Open file descriptors

Examples

{:ok, metrics} = Caddy.Metrics.fetch()
Caddy.Metrics.get(metrics, :http_requests_total)
#=> %{%{server: "srv0", code: "200"} => 1234}

healthy?(metrics)

@spec healthy?(t()) :: boolean()

Check if Caddy and upstreams are healthy based on metrics.

Returns true if all reverse proxy upstreams report healthy status (value = 1). Returns true if no upstream metrics are available (no upstreams configured).

Examples

{:ok, metrics} = Caddy.Metrics.fetch()
Caddy.Metrics.healthy?(metrics)
#=> true

latency_p50(metrics)

@spec latency_p50(t()) :: float() | nil

Get the median (p50) latency from request duration metrics.

Returns the 50th percentile latency in seconds, or nil if not available.

latency_p99(metrics)

@spec latency_p99(t()) :: float() | nil

Get the p99 latency from request duration metrics.

Returns the 99th percentile latency in seconds, or nil if not available.

Examples

{:ok, metrics} = Caddy.Metrics.fetch()
Caddy.Metrics.latency_p99(metrics)
#=> 0.234

total_requests(metrics)

@spec total_requests(t()) :: integer()

Get total request count from metrics.