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:
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.