Observability
XLB samples dataplane state once per second. The embedded console consumes those local samples; the optional OpenTelemetry exporter sends metrics to an OTLP collector at the configured export interval.
Configure OTLP export
name: production-lb
otel:
enabled: true
endpoint: "http://opentelemetry-collector:4317"
protocol: grpc
export_interval_secs: 10
headers: {}
Supported protocols are:
grpcfor OTLP/gRPC;httpfor OTLP over HTTP/protobuf.
XLB uses delta temporality for counters. Rate-like gauges such as Mbps and packets per second are calculated from the one-second maintenance sample before export, so they remain directly useful when the OTLP export interval changes. The status API separately calculates per-second connection rates for the embedded console.
The headers map is part of xlb.yaml and, with the current Helm chart, the generated ConfigMap.
Do not place a long-lived secret there unless access to that configuration is appropriately
restricted. A nearby in-cluster collector without application-level credentials is the simplest
Kubernetes arrangement.
Resource attributes
Every metric includes:
service.name:namefromxlb.yaml, orxlbwhen omitted;service.version: the XLB package version.
The Helm deployment also supplies these attributes through the Downward API:
service.instance.idservice.namespacek8s.pod.namek8s.pod.uidk8s.namespace.namek8s.node.name
Use service.instance.id or the Kubernetes Pod identity when separating individual XLB instances.
Global metrics
| Metric | Type | Meaning |
|---|---|---|
xlb.global.backends.available |
Gauge | Backends currently published by the provider |
xlb.global.connections.active |
Gauge | Active connection pairs |
xlb.global.connections.opened |
Counter | New connections opened |
xlb.global.connections.closed |
Counter | Connections closed by FIN or reset |
xlb.global.connections.orphaned |
Counter | Inactive connection pairs removed by timeout |
xlb.global.flow_pair.invariant_violations |
Counter | Missing, mismatched, or concurrently removed directional flow-pair entries observed during cleanup |
flow_pair.invariant_violations should normally remain zero. A nonzero delta deserves investigation,
especially when accompanied by connection failures or map pressure.
Per-backend traffic metrics
| Metric | Type | Labels | Meaning |
|---|---|---|---|
xlb.ingress.mbps |
Gauge | backend |
Client-to-backend bandwidth |
xlb.ingress.pps |
Gauge | backend |
Client-to-backend packets per second |
xlb.ingress.flows.active |
Gauge | backend |
Active connections for the backend |
xlb.ingress.flows.closed |
Counter | backend, type |
Client-initiated FIN or reset closures |
xlb.ingress.bytes |
Counter | backend |
Client-to-backend bytes |
xlb.egress.mbps |
Gauge | backend |
Backend-to-client bandwidth |
xlb.egress.pps |
Gauge | backend |
Backend-to-client packets per second |
xlb.egress.flows.active |
Gauge | backend |
Active return-direction connections for the backend |
xlb.egress.flows.closed |
Counter | backend, type |
Backend-initiated FIN or reset closures |
xlb.egress.bytes |
Counter | backend |
Backend-to-client bytes |
The type label is fin for an orderly TCP close and rst for a reset. ingress and egress
describe traffic direction, while the closure counters identify which side initiated the close.
Resource-pressure metrics
All utilization gauges use percentages from 0 through 100:
| Metric | Meaning |
|---|---|
xlb.resource.cpu.host.utilization |
Host CPU pressure, including kernel and softirq work |
xlb.resource.cpu.process.utilization |
XLB userspace CPU against its cgroup quota or available CPU capacity |
xlb.resource.cpu.utilization |
Greater of host and process CPU pressure |
xlb.resource.network.utilization |
Busiest RX or TX direction across attached interfaces as a percentage of link capacity |
xlb.resource.flow_map.utilization |
Directional flow entries as a percentage of map capacity |
xlb.resource.utilization |
Maximum CPU, network, or flow-map pressure |
Physical NICs commonly report their speed through sysfs. Cloud and virtual interfaces often expose byte counters but no usable link speed. Supply the documented per-interface capacity in that case:
This value is a denominator, not a packet-capacity estimate. XLB continues to measure live bytes from the attached interfaces.
If a required component cannot be measured, XLB omits the combined utilization value instead of reporting an unsafe partial percentage. The component values that remain valid are still exported.
Recommended dashboards
At minimum, graph these groups separately:
- Traffic: ingress/egress Mbps and packets per second.
- Connection lifecycle: active, opened, closed, and inactive-timeout removals.
- Backend distribution: active flows, traffic, and closure rates grouped by
backend. - Close quality: client/server FIN and reset rates using direction plus
type. - Capacity: host CPU, process CPU, network, flow map, and combined utilization.
- Correctness: flow-pair invariant violations.
Rates derived by an observability backend should be applied to counters such as bytes and closure
totals. Do not apply another rate operation to XLB's *.mbps, *.pps, or console-style
*_per_second values.
Alerting starting points
Tune thresholds from a representative baseline rather than treating these as universal defaults:
- sustained
xlb.resource.utilizationnear the deployment's chosen capacity target; - flow-map utilization rising without returning to baseline;
- no available backends;
- any flow-pair invariant violation;
- inactive-timeout removals increasing materially above normal;
- reset closure rate or reset share increasing for one backend;
- one backend receiving materially different connection or traffic share from its peers;
- the status endpoint reporting generic XDP when native mode is expected.
The health and readiness reasons are currently exposed through the HTTP status surface rather than
as separate OpenTelemetry metrics. Monitor /readyz at the orchestrator or service-discovery layer.
Autoscaling
xlb.resource.utilization is designed as the simplest autoscaling input: it is the maximum of CPU,
network, and flow-map pressure for one instance. XLB does not embed a scaling target. Operators
choose the target, minimum/maximum replicas, and stabilization policy appropriate to their traffic.
Adding replicas only helps when the upstream distribution mechanism sends new flows to them. The current flow state remains local to the instance that accepted each connection. Validate the full metrics-adapter and traffic-redistribution path before relying on an HPA policy in production.
Metrics not currently exported
The current release does not export backend handshake latency, application response latency, per-core metrics, durable lifecycle events, or a fleet-aggregated console. These should remain visibly unavailable in downstream dashboards rather than inferred from unrelated measurements.