Manage Runners Logo
Manage Runners
Documentation menu

Metrics

Show the CPU, RAM and disk usage of your runners in the dashboard, send it to your own OpenTelemetry backend such as OpenObserve or Grafana Cloud, or both.

Metrics are the CPU, RAM and disk usage of a runner’s server, measured about once a minute by a small collector on the server. They help you choose the right server type and concurrency, and let you watch your runners next to the rest of your infrastructure.

Each runner has two independent destinations for them:

  • Show in dashboard: charts on the runner’s card in the dashboard.
  • Send to: one of your organization’s connections, an OpenTelemetry (OTLP/HTTP) endpoint such as OpenObserve, Grafana Cloud or your own OpenTelemetry Collector. The collector pushes the metrics there directly; Manage Runners never connects to your endpoint itself.

A runner can use either, both or neither. Both need an active plan for the runner’s organization; any plan qualifies. See Billing and plans.

Choose the destinations for a runner

Set Show in dashboard and Send to under Metrics when you create, edit or duplicate a runner.

  • Show in dashboard is on by default for new runners when your plan is active.
  • Send to is None by default. Choose a connection from the list, or add one first on the Metrics page. A duplicate keeps the connection of the original.

Turning Show in dashboard on needs an active plan, and so does choosing a connection. Turning it off or choosing None does not.

Changing either setting of an active runner recreates its server, because the collector receives its settings when the server is created. Running jobs are interrupted. The edit form warns you before you save.

With Send to set and Show in dashboard off, the server still runs the collector. It sends its samples only to your endpoint and reports nothing but the last export result to Manage Runners, so the dashboard shows no charts for that runner.

Show in dashboard

A runner card with CPU, RAM and disk charts for the last 24 hours

Under Resource usage, each active runner with Show in dashboard on shows:

  • CPU usage in percent,
  • RAM used of the total, in GB,
  • Disk usage for each disk of the server.

Each value comes with a chart. Choose the time range with the Metrics selector above the cards: last hour, 24 hours, 7 days, 30 days or 90 days. Only ranges for which data exists are offered. Manage Runners keeps samples for 90 days.

The first values appear a few minutes after the runner starts. If the newest sample is older than three minutes, the card says how long no data has arrived.

Connections

A connection is a named OTLP endpoint with its headers, the destination for Send to. An organization can have several, for example one per team or backend, and each runner sends to one or none. Open Metrics in the dashboard navigation to see the connections and the runners that send to them; owners and editors can add, change and delete them, viewers can read them.

Select New connection and fill in:

  • Name: unique within the organization, for example Grafana Cloud. Runner forms and cards show it.
  • OTLP endpoint: the base URL of your OTLP/HTTP receiver, as you would set OTEL_EXPORTER_OTLP_ENDPOINT. The collector sends to /v1/metrics below it. Only https:// is accepted, and the server certificate must be publicly trusted.
  • Headers: up to 8. A new connection starts with an Authorization row, which you can fill in, rename or remove. Values are stored encrypted and never shown again; when you edit a connection, leave a value empty to keep it. Names and values together may have 4096 characters; values may contain printable ASCII characters except " and \.

The endpoint and headers are written to the server of each runner that sends to the connection, and CI jobs on the runner can read them, for example through Hetzner’s metadata service. Use credentials that can only write metrics, never an administrator token.

Change or delete a connection

Renaming a connection changes nothing on the runners. Saving a new endpoint or new headers while runners send to the connection recreates the servers of the active ones. The dashboard lists them and asks before it saves. Paused runners get the new settings when you resume them; Unknown runners keep the previous settings until you edit or recreate them. Other connections and their runners are not affected.

Deleting a connection sets Send to to None on the runners that use it and recreates the active ones without it, after the same confirmation.

After the plan has ended, owners and editors can still delete connections, but not add or change them. The servers are not recreated then; their collectors stop sending once Manage Runners rejects their credential, and the copy of the settings on existing servers stays until they are recreated or deleted.

Examples

Backend OTLP endpoint Header
OpenObserve Cloud https://api.openobserve.ai/api/<organization> Authorization: Basic <base64 of email:token> from its ingestion settings
Self-hosted OpenObserve https://openobserve.example.com/api/<organization> Authorization: Basic <base64 of user:password>
Grafana Cloud https://otlp-gateway-prod-<region>.grafana.net/otlp Authorization: Basic <base64 of instance ID:access policy token> with the metrics:write scope
Your own OpenTelemetry Collector https://otel.example.com:4318 whatever your receiver’s authenticator expects, for example Authorization: Bearer <token>

For your own OpenTelemetry Collector, enable the otlp receiver’s HTTP protocol with TLS and an authenticator, for example the bearertokenauth extension. If your backend only accepts known addresses, allow the IP addresses of your runners.

What is sent

The metrics follow the OpenTelemetry semantic conventions for system metrics:

Metric Unit Attributes
system.cpu.utilization 1 (fraction) cpu.mode: user, nice, system, idle, iowait, interrupt, steal
system.memory.usage bytes system.memory.state: used (total minus available memory)
system.memory.limit bytes
system.memory.linux.available bytes
system.filesystem.usage bytes system.device.name, system.filesystem.mountpoint, system.filesystem.state: used, free, reserved
system.filesystem.limit bytes system.device.name, system.filesystem.mountpoint

Every sample carries the resource attributes service.name (managerunners-runner), host.name, host.id (the Hetzner server ID), cloud.provider (hetzner), cloud.region, cloud.availability_zone, managerunners.runner.id and managerunners.runner.name. Requests are protobuf, gzip-compressed, about once a minute.

Check that it works

Under Metrics destination, each runner card shows the name of its connection, or —. While sending works, nothing else is shown. If the last result was an error, a line below the name says what failed and when it was reported, for example Credentials rejected (HTTP 401/403) · reported 1 min ago:

Status What to check
Endpoint unreachable The host name, port and firewall; whether your backend allows the runner’s IP address
TLS failed The server certificate must be valid and publicly trusted
Endpoint timed out Whether the endpoint answers within five seconds
Credentials rejected The header value; HTTP 401 or 403
Request rejected The endpoint URL, for example a missing organization path; any other HTTP 3xx or 4xx
Endpoint server error Your backend; HTTP 5xx
The collector could not send from the runner The runner itself, for example memory or process limits; the collector retries and restarts its export process

A failing endpoint never stops the charts in the dashboard. The collector retries with increasing delays of up to five minutes.

How it works

The server runs the collector as a systemd service under its own user, limited to 64 MB of memory and 5% of one CPU. It collects only these system values.

Each server gets its own credential, which it uses to send samples to Manage Runners and to report the last result of Send to. The credential is revoked when the runner is deleted or becomes Unknown, and when the organization no longer has an active plan.

When the plan ends

If the organization’s plan is no longer active, the dashboard shows Metrics paused. The owner sees a link to Billing; other members are asked to contact the owner. The servers’ credentials are revoked, so their collectors stop: the charts stop updating and nothing is sent to your connections any more. After the plan is active again, pause and resume a runner to give its new server a new credential.

While the plan is on hold, you can still turn Show in dashboard off or set Send to to None in a runner’s edit form. Once the plan has expired or been cancelled, the dashboard no longer opens the runner forms. Change a runner with the CLI or the API instead, for example manage-runners runner update --id <id> --no-send-to --yes, or stop sending to a connection for all its runners at once by deleting it on the Metrics page.

With the CLI

  • Read the charts’ data with manage-runners runner metrics.
  • Choose the destinations per runner with --dashboard on|off (show in dashboard) and --send-to <id|name> or --no-send-to (send to) on runner create and runner update.
  • Manage connections with the manage-runners metrics commands.