# OpenTelemetry (/docs/integrations/opentelemetry)



OpenTelemetry [#opentelemetry]

The OpenTelemetry app in RawTree Cloud or RawTree BYOC accepts native OTLP and
writes rows into RawTree. The app must be enabled for your cluster.

If you already use an OpenTelemetry SDK or Collector, point OTLP at the service endpoints.
Authenticate with a cluster API key.
Select the destination database with `x-rawtree-database`.
If you omit it, the service uses the key's stored default database.

Before sending telemetry, open the cluster in the service dashboard.
Select **Apps** and install **OpenTelemetry**.
Installation enables the cluster's native OTLP/HTTP and OTLP/gRPC endpoints.
The app does not start or resume the cluster.
Make sure the cluster is available before you export telemetry.

```bash
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.rawtree.com/otlp
export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer%20$API_KEY,x-rawtree-database=analytics"
```

The OpenTelemetry app writes traces to `traces`, logs to `logs`, and metrics to `metrics` by default.

Endpoints [#endpoints]

| Signal  | OTLP/HTTP endpoint      | OTLP/gRPC service                                                | Destination table |
| ------- | ----------------------- | ---------------------------------------------------------------- | ----------------- |
| Traces  | `POST /otlp/v1/traces`  | `opentelemetry.proto.collector.trace.v1.TraceService/Export`     | `traces`          |
| Logs    | `POST /otlp/v1/logs`    | `opentelemetry.proto.collector.logs.v1.LogsService/Export`       | `logs`            |
| Metrics | `POST /otlp/v1/metrics` | `opentelemetry.proto.collector.metrics.v1.MetricsService/Export` | `metrics`         |

The OpenTelemetry app accepts OTLP/HTTP JSON (`application/json`), OTLP/HTTP protobuf (`application/x-protobuf`), and OTLP/gRPC protobuf.
Both transports accept gzip-compressed requests.
OTLP/HTTP request bodies are limited to 100 MiB after decompression.
Larger exports return `413`.

For OTLP/gRPC, use `https://api.rawtree.com` as the endpoint. When running the local Docker Compose stack, use `http://localhost:4317`.

Custom destination tables [#custom-destination-tables]

Set a signal-specific header when you want telemetry in a non-default table. `x-rawtree-database` selects the database and the signal header selects the table.

| Signal  | Header                    |
| ------- | ------------------------- |
| Traces  | `x-rawtree-traces-table`  |
| Logs    | `x-rawtree-logs-table`    |
| Metrics | `x-rawtree-metrics-table` |

```bash
export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer%20$API_KEY,x-rawtree-database=analytics,x-rawtree-traces-table=my_traces"
```

OpenTelemetry Collector [#opentelemetry-collector]

Use the OTLP/HTTP exporter to forward all signals from a Collector:

```yaml
exporters:
  otlphttp/rawtree:
    endpoint: https://api.rawtree.com/otlp
    headers:
      Authorization: Bearer ${env:RAWTREE_API_KEY}
      x-rawtree-database: analytics
```

See the full [OpenTelemetry Collector example](/docs/integrations/opentelemetry-collector). For a sandbox telemetry walkthrough, see the [Daytona OpenTelemetry example](/docs/integrations/daytona).

SDK snippets [#sdk-snippets]

Most SDKs read the same environment variables. Use these for Node.js, Python, Go, and other standard OTLP exporters:

```bash
export OTEL_SERVICE_NAME=my-service
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.rawtree.com/otlp
export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer%20$API_KEY"
export OTEL_EXPORTER_OTLP_COMPRESSION=gzip
```

If your exporter expects per-signal endpoints instead of a base endpoint, use:

```bash
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://api.rawtree.com/otlp/v1/traces
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://api.rawtree.com/otlp/v1/logs
export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://api.rawtree.com/otlp/v1/metrics
```

60-second smoke test [#60-second-smoke-test]

When setting up OTel collection, send one JSON OTLP span:

```bash
curl -X POST "https://api.rawtree.com/otlp/v1/traces" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"resourceSpans":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"otel-smoke-test"}}]},"scopeSpans":[{"spans":[{"traceId":"5B8EFFF798038103D269B633813FC60C","spanId":"EEE19B7EC3C1B174","name":"rawtree smoke test"}]}]}]}'
```

Query it back:

```bash
rtree query "SELECT name, service.name FROM traces WHERE service.name = 'otel-smoke-test' LIMIT 1"
```

If the query returns no rows, inspect the insert execution in the platform Queries screen.
Check the OTLP API request status in the Logs screen.

Partial success [#partial-success]

If the service accepts an export but drops invalid records, the OTLP response includes `partialSuccess`.
It reports `rejectedSpans`, `rejectedLogRecords`, or `rejectedDataPoints` with an error message.
Some SDKs do not show partial success clearly.
If telemetry is missing, inspect the API request in Logs and the related insert in Queries.

Row shapes [#row-shapes]

Native OTLP endpoints apply the service's built-in OpenTelemetry transforms. See [Transforms](/docs/guides/transform/transforms#opentelemetry-output) for the fields the transforms emit for traces, logs, and metrics.
