Gateway Metrics
The gateway exports Prometheus metrics for API requests, database readiness, gateway interceptors, the OCSF log file, and multi-replica capacity. Use them to alert on saturation, to follow rollouts, and to choose autoscaling signals.
Enable the Metrics Endpoint
The gateway serves GET /metrics in the Prometheus text format on its own
listener, separate from the API and health ports. When the listener is
disabled, the gateway records no metrics. Enable it in one of these ways:
- In
gateway.toml, setmetrics_bind_addressunder[openshell.gateway], for examplemetrics_bind_address = "0.0.0.0:9090". Refer to Gateway Configuration. - On the command line, pass
--metrics-portor setOPENSHELL_METRICS_PORT. The standalone gateway binary defaults to0, which disables the endpoint. - In the Helm chart, set
service.metricsPort, which defaults to9090. The chart renders the TOML key, a container port namedmetrics, and ametricsport on the gateway Service. Set it to0to disable the endpoint.
A stopping gateway keeps serving metrics until the process exits.
The metrics endpoint uses plaintext HTTP with no authentication. Anyone who
can reach the port can read the metrics. The Helm chart publishes the port on
the gateway Service, so a LoadBalancer or NodePort Service exposes it
outside the cluster. Keep the Service internal, and restrict the port to your
monitoring system.
The following NetworkPolicy keeps the API and health ports open and accepts
metrics scrapes only from the monitoring namespace. Adjust the ports if you
changed service.port, service.healthPort, or service.metricsPort.
Scrape Each Replica
Capacity metrics describe one gateway replica, so scrape every gateway pod
rather than the Service, and keep the namespace and pod labels on each
series. With the Prometheus Operator, a PodMonitor adds those labels
automatically:
With a plain Prometheus configuration, use pod discovery and copy the labels yourself:
To check one pod without Prometheus, read its metrics through the Kubernetes API server proxy:
The API server connects to the pod from the control plane. A NetworkPolicy
like the one above blocks that connection unless it also allows the control
plane on the metrics port. kubectl port-forward reaches the pod through the
kubelet instead, and NetworkPolicy does not block it. Start the port-forward:
Then read the metrics from another terminal:
Metric Names
Every metric name starts with openshell_, followed by the subsystem that
records it:
Names follow Prometheus conventions. Counters end in _total, and names with a
unit end in that unit, such as _seconds or _bytes. Metrics carry no gateway
name label, so use your scrape configuration to tell installations apart.
Histograms and Summaries
The multi-replica latency metrics and the configuration build and apply
durations are Prometheus histograms with _bucket, _sum, and _count series
and buckets from 1 millisecond to 15 seconds, so histogram_quantile can
aggregate them across replicas. The older
*_duration_seconds metrics and the interceptor latency metric are summaries
with quantile labels that each replica computes on its own. Do not average
summary quantiles across pods.
Multi-Replica Capacity Metrics
These metrics describe how much work one replica holds and how the replicas interact. No metric carries a sandbox, channel, endpoint, or replica identifier, because the scrape target already identifies the replica.
Supervisor sessions:
Relays:
Routed requests include local relay setup and outbound requests to the replica that owns a sandbox’s supervisor session:
Mutation locks:
The labels take these values:
operationisrelay,report_provider_readiness,report_endpoint_status, orget_sandbox_provider_status. Only relay setup includes the local route; the other operations count outbound peer calls, not local API handling. On the owning replica,openshell_server_grpc_requests_totalrecords the matchingmethod, such asPeerRelayforrelay.relay_kindissshortcpfor relays, andnonefor other operations. An omitted relay target counts asssh, matching the protocol’s compatibility behavior. TCP hostnames and ports are not labels.routeislocalwhen this replica tries its own supervisor session, orpeerwhen it tries another replica. A routed retry counts again, including a change from local to peer routing. Waiting for an owner does not count. IncomingPeerRelayrequests do not increment this counter on the receiving replica; they appear in that replica’s gRPC request counter instead. This counter does not measure active connections, unique client requests, or unfinished attempts.reasonisreplica_capacitywhen the gateway replica’s pending-relay budget is full, orsandbox_capacitywhen one sandbox’s budget on that replica, 32 pending relays, is full.outcomeissuccess,local_error, orremote_error. A relay succeeds when the supervisor claims it; this does not measure the data stream.local_errormeans the attempt failed on this replica, andremote_errormeans the owning replica returned an error or the open connection to it failed. Onroute="local"this replica is the owner, so failures that appear asremote_erroron the peer route, such as an unclaimed relay (deadline_exceeded) or a full relay budget (resource_exhausted), appear aslocal_error. A cancelled attempt recordslocal_errorwithgrpc_code="cancelled", even when the owner was already handling it.grpc_codeis the lowercase gRPC status name, such asok,unavailable, orresource_exhausted, from local setup, the local supervisor claim, or the peer RPC. For a peer relay, the gateway then reports a failure to the client asUNAVAILABLE. The other RPCs return the owner’s status to the client unchanged. The label is not namedcodebecauseopenshell_server_grpc_requests_totaluses that name for the numeric status code.scopeisglobal,workspace, orsandbox.
Gauges and counters exist from startup. They start at 0, except
openshell_server_relay_pending_capacity and
openshell_server_mutation_lock_connections_capacity, which start at their
limits. openshell_server_routed_request_attempts_total starts with seven
outcome="success", grpc_code="ok" series: four relay kind and route
combinations, and three other peer operations with relay_kind="none". Other outcomes and codes,
and every histogram, appear after their first sample, so write alert expressions
that tolerate absent series.
Request and Readiness Metrics
The gateway also records every API request and its background database check:
Configuration Delivery Metrics
With config_delivery_mode = "push", the gateway builds each supervisor’s
configuration and sends it over the supervisor session. These metrics stay
empty in poll mode, where GetSandboxConfig and
GetSandboxProviderEnvironment in the request metrics carry the same work.
The labels take these values:
- Each configuration carries the sandbox configuration and the provider environment it names. Credentials are resolved only when that provider environment changed.
- On builds,
outcomeisok,failed, ortimeout. A failed build retries with a per-session backoff from 1 to 30 seconds. Each session also rebuilds its configuration every 30 seconds to repair a missed change. - On deliveries,
outcomeisqueued,coalesced(held until the supervisor answers its previous update),unchanged,no_active_session,unsupported_session,payload_too_large,stream_closed(the session’s stream stopped draining, so the session was closed for the supervisor to reconnect),owner_moved, orowner_lookup_failed. - On
apply_results_totalandapply_duration_seconds,outcomeis aConfigApplyOutcomename, such asCONFIG_APPLY_OUTCOME_APPLIED. - On peer notifications,
outcomeisaccepted,stale_owner,unsupported_peer,peer_error, ortimeout.
Gateway Interceptor Metrics
Gateways with gateway interceptors record their evaluations:
OCSF Log Metrics
Gateways that write an OCSF JSONL file record its queue and writer:
OCSF Log Export Metrics
Gateways with OCSF log export enabled record its queue and exporter:
Next Steps
- See the Observability Overview for traces and OCSF events.
- To monitor capacity and choose autoscaling signals for multiple gateway replicas, refer to High Availability.
- To configure the metrics listener in
gateway.toml, refer to Gateway Configuration.