> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sazabi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# RunsOn

> Point your RunsOn stack's OpenTelemetry export at Sazabi to stream control-plane logs, traces and runner bootstrap logs.

[All RunsOn integration capabilities](https://docs.sazabi.com/catalogs/integrations/runs-on)

## About

[RunsOn](https://runs-on.com) runs self-hosted GitHub Actions runners in your own AWS account. Its Flex and Fleet stacks [export OpenTelemetry](https://runs-on.com/docs/observability/opentelemetry/) over OTLP/HTTP to one endpoint you set on the stack. Set that endpoint to your Sazabi intake URL and the control plane sends its structured operator logs (`job_launched`, `job_summary`, `operator_snapshot`, `spot_interruption`) and traces. Runners with the `otel` extra also send their bootstrap log and agent spans. No collector, RunsOn API access, or workflow change is needed, and the CloudWatch logs and GitHub job logs are unchanged.

Control-plane records carry the resource `service.name` `runs-on-flex` or `runs-on-fleet`, with the stack name as `service.namespace`. Runner records carry `service.name` `runs-on-agent`.

> [!NOTE]
>
> RunsOn sends logs, traces and metrics to the same endpoint, and has no setting to turn metric export off. Its metrics arrive on this source too, and Sazabi stores each data point as a searchable record, the way the [OpenTelemetry Metrics](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/opentelemetry-metrics.md) source does. To keep metrics in their own source, run an OpenTelemetry Collector between RunsOn and Sazabi and send its metrics pipeline to the OpenTelemetry Metrics source.

## Prerequisites

* A RunsOn Flex or Fleet stack on v3.2.0 or later, deployed with the [Terraform module](https://runs-on.com/docs/maintenance/configuration/flex/terraform/) or, for Flex, the [CloudFormation template](https://runs-on.com/docs/maintenance/configuration/flex/cloudformation/). Runner-side export needs Flex v2.12.0 or Fleet v3.2.0.
* Outbound HTTPS from the RunsOn control plane and runners to your Sazabi intake host
* Your Sazabi intake URL, shown above — open the log source and copy the **Intake URL** from its setup screen (the public key is embedded in the URL)

## Set up in the dashboard

**Step 1**

### Set the stack's OTLP endpoint

Replace `<your intake host>` with the intake URL shown above, without `https://`. Use the base URL with no path: RunsOn appends `/v1/logs`, `/v1/traces` and `/v1/metrics` itself. Leave the exporter headers empty; the public key is in the hostname.

**Flex or Fleet with Terraform.** Add these inputs to your RunsOn module block, then run `terraform apply`. Both enable flags default to `true`.

```hcl title="Terraform" theme={"system"}
otel_exporter_endpoint = "https://<your intake host>"
otel_logs_enabled      = true
otel_traces_enabled    = true
```

**Flex with CloudFormation.** Update the stack in place with the current template, set `OtelExporterEndpoint` to `https://<your intake host>`, and leave every other parameter as it is. Logs and traces are exported as soon as the endpoint is set.

**Step 2**

### Add runner bootstrap logs (optional)

Runners export their bootstrap log (`output.log`) and agent spans only with the `otel` extra. Keep any extras you already use.

| Stack | Setting |
| - | - |
| Flex Terraform | `mandatory_extras = ["otel"]` |
| Flex CloudFormation | `MandatoryExtras` = `otel`, joined with `+` to existing extras (for example `s3-cache+otel`) |
| Flex, per job | `extras=otel` in the job's `runs-on` label |
| Fleet Terraform | `extras = ["otel"]` in each runner definition of the `runners` map |

An `extras` job label replaces the runner's extras list, so list every extra the job needs (`extras=s3-cache+otel`). Fleet workflows can't opt in per job.

**Step 3**

### Hand off the change

If your RunsOn configuration is version-controlled, commit it on a new branch, push it, and open a pull request. Otherwise apply it directly. In Terraform, pass the intake URL through a variable rather than a literal.

## Set up with the CLI

You can also register the RunsOn log source with the [Sazabi CLI](https://docs.sazabi.com/reference/cli.md) (installed and authenticated — see [CLI reference](https://docs.sazabi.com/reference/cli/log-sources.md)).

Registering the source mints the same intake URL the dashboard shows above (the public key is embedded in its hostname):

```bash theme={"system"}
sazabi log-sources create runs_on --mode manual
```

The command prints the intake URL for the new source — copy the whole URL and use it in the configuration shown above. Run `sazabi log-sources get <log-source-id>` at any time to reprint the endpoint, or `sazabi log-sources list` to see every log source in the project.

## Verify

Run any workflow job on RunsOn. Open the [Intake page](https://docs.sazabi.com/guides/instrument/intake.md) in the Sazabi dashboard and confirm records from the **RunsOn** source appear within a minute or two, then search for `service.name` `runs-on-flex` or `runs-on-fleet`, or a `job_summary` event.

## Troubleshooting

**No records** — Confirm the stack update finished and the endpoint has no path. The control-plane logs in CloudWatch show OTLP export errors.

**Control-plane records, but no runner records** — The runner needs the `otel` extra. Run a new job after the change.

**Only traces and metrics** — Check that `otel_logs_enabled` isn't `false` in Terraform.

**Expecting GitHub job output** — Runner logs are RunsOn's bootstrap and agent log, not the GitHub Actions job log.

## Further reading

> [card] [Intake](https://docs.sazabi.com/guides/instrument/intake.md)
>
> See per-source ingestion volume and health.

> [card] [Log sources](https://docs.sazabi.com/catalogs/log-sources.md)
>
> Browse the full log source catalog.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.