Metrics and the statistics page

A Prometheus endpoint and a live statistics page, both built in and both off until you ask for them. Neither accumulates anything: they are rendered from the balancer's own state at the moment they are read.

Two ways to see what SSLB3 is doing, aimed at different readers. The metrics endpoint is for a scraper and an alert; the statistics page is for a person with a question right now. They report the same state, so they cannot disagree.

The metrics endpoint

Its own plaintext listener, separate from the data plane, serving /metrics in the usual exposition format.

sslb.conf

[Prometheus]
Enabled = yes
BindAddress = ::
ListenPort = 9101
Path = /metrics

On Kubernetes it is a chart value, and the container port is already declared:

shell

helm upgrade sslb3 oci://docker.hacking.hu/public/sslb3-ingress \
  --set config.prometheus.enabled=true

What it reports

Thirty-four metric families, in six groups:

GroupWhat you get

Listeners and workers

Every listener with its address and protocol, connections per worker, and the configured ceiling. Enough to see both the total load and whether it is spread evenly across workers.

Serverfarms and backends

Every farm with its balancer and layer 7 module, its backend count and how many are healthy; then each backend with its own health, weight and connection count.

Session affinity

Sessions held against the configured maximum, plus hits, misses and evictions — the three numbers that say whether affinity is working or quietly falling back to balancing.

Intrusion detection

Sources tracked and sources blocked, with connections and requests refused, blocks issued and observations recorded. The mode is a label, so an alert can tell detecting from enforcing.

Kernel fast path

Which facility is forwarding, whether the last reconcile succeeded, how many services moved, and per listener whether it was eligible and the reason if not — plus the connections the kernel carried, which SSLB3 never saw and which are therefore missing from every other counter.

Build and configuration

The version, and derived facts worth alerting on rather than reading from a config file — such as whether any farm still claims a host at layer 7.

Every family carries HELP text saying what it means and, where it is not obvious, why it is worth alerting on. A metric that needs the documentation open to interpret is a metric nobody will act on at three in the morning.

The ones worth an alert

Most of these describe configuration and are useful as labels to join against. A few are genuinely operational:

promql

# A farm with no healthy backend left.
sslb3_serverfarm_backends_healthy == 0

# The fast path stopped working. Traffic is fine -- SSLB3 serves what the kernel
# is not carrying -- but it is no longer accelerating anything.
sslb3_fastpath_healthy == 0

# A route quietly fell off the native path onto the script path.
sslb3_routes_requests == 0

# Approaching the connection ceiling.
sum(sslb3_worker_connections) / sslb3_max_connections > 0.8

The statistics page

A single self-contained page on its own listener, showing the same state arranged for reading. It answers "what is happening right now" without a query language.

sslb.conf

[Stats]
Enabled = yes
BindAddress = ::
ListenPort = 9102
RefreshInterval = 2

It updates over a WebSocket rather than by reloading. A page that reloads loses your scroll position and whatever you were reading, every couple of seconds — which makes it useless for the thing you actually want it for, which is watching a number move while you change something.

Workers, affinity and detection

Connections per worker, the affinity store’s hit rate, and what the intrusion detector has been doing. Placed at the top, because these are the numbers you check first when something feels wrong.

Listeners

Every socket that is accepting, with its protocol and the farm it is pinned to.

Serverfarms and backends

Each farm with how its traffic actually reaches its backends — parsed, spliced, or carried by the kernel — and every backend beneath it with its health and connection count.

Kernel fast path

Which forwarder is in use, how many services are eligible, how many are actually being forwarded, and for each one that is not, the reason. Byte columns appear only for a forwarder that measures bytes.

The page itself is a React application built with Vite and embedded in the balancer binary as one HTML file, so there is nothing to deploy alongside and no request to anywhere else.

Why both are off by default

Because they are unauthenticated, and what they serve is a description of your deployment: every backend address, every farm name, every listener. That belongs somewhere only your scraper and your operators can reach, and the safe default for something you have not thought about yet is off.

Neither is a path on the admin API, deliberately. The two want opposite things — the admin API changes configuration, so it is TLS-only and authenticated and always will be, while a scrape endpoint is read-only and called every few seconds by a robot that usually cannot be handed a credential. Requiring one is how metrics end up not being collected.

Reaching them

On Kubernetes, without exposing either:

shell

kubectl -n sslb3 port-forward deploy/sslb3-ingress 9101:9101   # metrics
kubectl -n sslb3 port-forward deploy/sslb3-ingress 9102:9102   # the page

The chart can also create a ServiceMonitor where the Prometheus Operator is running, so the endpoint is scraped without anything else being able to reach it.

And the log

Separate from both, and worth knowing about: access logging is per connection and off by default. It is also one of the conditions that keeps a service in SSLB3's path rather than the kernel's — a forwarded connection is one SSLB3 never sees, so it is not one it can log.