# OpenTelemetry providers

> Send Elide telemetry to an OTLP collector, Sentry, Datadog, PostHog, Honeycomb, or Grafana Cloud: which signals each accepts, its credential variable, endpoint, and a setup recipe.

A provider is a preset for one destination: it fills in the endpoint, the authentication header, and the signals and
protocols the service accepts. Every provider is reached over OTLP.

| Provider | Sent by default | Sent when listed | Protocols | Credential variable |
| --- | --- | --- | --- | --- |
| `otlp` | traces, metrics, logs; profiles when on | — | all | none; use `headerEnv` |
| `sentry` | traces, logs | — | `http/protobuf` | `SENTRY_DSN` |
| `datadog` | metrics, logs | traces | `http/protobuf`; `http/json` except logs | `DD_API_KEY` |
| `posthog` | logs | traces | `http/protobuf` | `POSTHOG_PROJECT_TOKEN` |
| `honeycomb` | traces, metrics, logs | — | all | `HONEYCOMB_API_KEY` |
| `grafana` | traces, metrics, logs | — | `http/protobuf` | `GRAFANA_CLOUD_OTLP_CREDENTIAL` |

Default signals are sent unless the destination lists `signals`. The others are sent only when named in `signals`
(or `ELIDE_OTEL_SIGNALS`). "all" is `grpc`, `http/protobuf`, and `http/json`. Errors travel inside traces, logs, and
metrics, so every provider receives them; see [Errors](https://elide.help/docs/opentelemetry/signals#errors).

Asking a provider for a signal or protocol it does not accept, or leaving its credential variable unset, leaves
telemetry off for the run with a warning; see [Configuration errors](https://elide.help/docs/opentelemetry/troubleshooting#configuration-errors).
Credential values never appear in logs or errors.

## Pick a provider at run time

`ELIDE_OTEL_PROVIDER` adds one destination for a provider, with `ELIDE_OTEL_REGION` and `ELIDE_OTEL_SIGNALS` for its
options:

```bash
ELIDE_OTEL_PROVIDER=honeycomb HONEYCOMB_API_KEY=... elide serve app.ts
```

The `--otel-provider=` flag does the same for one command. Use `elide.pkl` to keep the choice with the project, or to
send to several providers at once.

## OTLP collector or agent

Any OTLP receiver: the OpenTelemetry Collector, Grafana Alloy, a vendor agent, or a backend with an OTLP endpoint.

```bash
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 elide serve app.ts
```

```pkl
opentelemetry {
  destinations {
    ["collector"] {
      endpoint = "https://otel.example.com"
      protocol = "grpc"
      headerEnv { ["authorization"] = "OTEL_COLLECTOR_AUTH" }
    }
  }
}
```

| Setting | Value |
| --- | --- |
| Default endpoint | `http://localhost:4318`; `http://localhost:4317` with `grpc` |
| HTTP paths | `/v1/traces`, `/v1/metrics`, `/v1/logs`, `/v1development/profiles`, appended to `endpoint` |
| gRPC | `endpoint` used as given, with `http://` (plaintext) or `https://` |
| Authentication | `headers`, `headerEnv`, or `OTEL_EXPORTER_OTLP_HEADERS` |

Only `otlp` destinations take profiles, once profiles are turned on; see [Profiles](https://elide.help/docs/opentelemetry/signals#profiles).

## Sentry

Traces and logs, with the project's DSN:

```bash
ELIDE_OTEL_PROVIDER=sentry SENTRY_DSN=https://<key>@o123.ingest.us.sentry.io/456 elide serve app.ts
```

```pkl
opentelemetry {
  destinations {
    ["sentry"] { provider = "sentry"; dsn = "SENTRY_DSN" }
  }
}
```

| Setting | Value |
| --- | --- |
| Credential | `dsn` names the variable; default `SENTRY_DSN` |
| Endpoint | From the DSN: `https://<host>/api/<project>/integration/otlp/v1/{traces,logs}` |
| Header | `x-sentry-auth: sentry sentry_key=<key>` |
| Signals | traces, logs |

Uncaught errors reach Sentry as `exception` log records and as `exception` events on the failing span.

## Datadog

Metrics and logs by default, through Datadog's agentless OTLP intake:

```bash
ELIDE_OTEL_PROVIDER=datadog ELIDE_OTEL_REGION=us5 DD_API_KEY=... elide serve app.ts
```

```pkl
opentelemetry {
  destinations {
    ["datadog"] {
      provider = "datadog"
      site = "us5"
      signals { "metrics"; "logs"; "traces" }
    }
  }
}
```

| Setting | Value |
| --- | --- |
| Credential | `credential` names the variable; default `DD_API_KEY`. Sent as `dd-api-key`. |
| Site | `site`, then `DD_SITE`, then `datadoghq.com` |
| Endpoint | `https://otlp.<site>/v1/{traces,metrics,logs}` |
| Signals | metrics and logs by default; traces when listed |
| Temporality | Metrics are sent as delta. Setting `cumulative` with Datadog is an error. |

| `site` | Host |
| --- | --- |
| `us1`, `us` | `datadoghq.com` |
| `us3` | `us3.datadoghq.com` |
| `us5` | `us5.datadoghq.com` |
| `eu`, `eu1` | `datadoghq.eu` |
| `ap1` | `ap1.datadoghq.com` |
| `ap2` | `ap2.datadoghq.com` |
| `gov`, `us1-fed` | `ddog-gov.com` |
| any domain | used as given, e.g. `datadoghq.com` |

Traces are opt-in because Datadog's agentless trace intake must be enabled for your organization. With a Datadog
Agent running locally, use an `otlp` destination pointed at the Agent's OTLP receiver instead.

## PostHog

Logs by default; traces when listed:

```bash
ELIDE_OTEL_PROVIDER=posthog POSTHOG_PROJECT_TOKEN=phc_... elide serve app.ts
```

```pkl
opentelemetry {
  destinations {
    ["posthog"] { provider = "posthog"; region = "eu"; signals { "logs"; "traces" } }
  }
}
```

| Setting | Value |
| --- | --- |
| Credential | `credential` names the variable; default `POSTHOG_PROJECT_TOKEN`. Sent as `Authorization: Bearer`. |
| Region | `us` (default) or `eu` |
| Endpoint | `https://<region>.i.posthog.com/i/v1/{traces,logs}` |
| Signals | logs by default; traces when listed |

## Honeycomb

Traces, metrics, and logs:

```bash
ELIDE_OTEL_PROVIDER=honeycomb HONEYCOMB_API_KEY=... elide serve app.ts
```

```pkl
opentelemetry {
  service { name = "checkout" }
  destinations {
    ["honeycomb"] { provider = "honeycomb"; region = "eu"; protocol = "grpc" }
  }
}
```

| Setting | Value |
| --- | --- |
| Credential | `credential` names the variable; default `HONEYCOMB_API_KEY`. Sent as `x-honeycomb-team`. |
| Region | `us` (`api.honeycomb.io`, default) or `eu` (`api.eu1.honeycomb.io`) |
| Endpoint | `https://<host>/v1/{traces,metrics,logs}`; `<host>:443` with `grpc` |
| Signals | traces, metrics, logs |

Honeycomb names datasets after `service.name`; set it, or data lands in `unknown_service:elide`.

## Grafana Cloud

Traces, metrics, and logs through the stack's OTLP gateway. The credential is `<instance id>:<token>` from the
stack's OpenTelemetry connection page:

```bash
ELIDE_OTEL_PROVIDER=grafana ELIDE_OTEL_REGION=prod-us-east-0 \
GRAFANA_CLOUD_OTLP_CREDENTIAL=123456:glc_... elide serve app.ts
```

```pkl
opentelemetry {
  destinations {
    ["grafana"] { provider = "grafana"; region = "prod-us-east-0" }
  }
}
```

| Setting | Value |
| --- | --- |
| Credential | `credential` names the variable; default `GRAFANA_CLOUD_OTLP_CREDENTIAL`. Sent as HTTP basic auth. |
| Region | Required unless `endpoint` is set: the stack's zone, such as `prod-us-east-0` or `prod-eu-west-2` |
| Endpoint | `https://otlp-gateway-<zone>.grafana.net/otlp/v1/{traces,metrics,logs}` |
| Signals | traces, metrics, logs |

## Samples

- [OTLP to a local collector](https://elide.help/docs/code-samples#otlp-to-a-local-collector)
