> ## Documentation Index
> Fetch the complete documentation index at: https://logixlysia-claude-elysia-v2-open-beta-i2faib.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# OTLP

> Ship logs to any OpenTelemetry-compatible backend

Send logs to any OTLP/HTTP logs endpoint as standard `ExportLogsServiceRequest` JSON — an OpenTelemetry Collector, Grafana Cloud, New Relic, Honeycomb, SigNoz, or any other OTLP-compatible backend. If your platform speaks OTLP and doesn't have a dedicated adapter, this is the one to use.

## Setup

1. Find your backend's OTLP/HTTP endpoint and auth headers (for a local collector this is `http://localhost:4318` and usually no auth).
2. Set the standard OpenTelemetry environment variables:

```bash theme={null}
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
OTEL_EXPORTER_OTLP_HEADERS=x-api-key=your-key # optional, k=v,k2=v2
OTEL_SERVICE_NAME=my-api                      # optional
```

3. Wire the transport:

```ts theme={null}
import { Elysia } from 'elysia'
import logixlysia from 'logixlysia'
import { createOtlpTransport } from 'logixlysia/otlp'

const app = new Elysia()
  .use(
    logixlysia({
      config: {
        transports: [createOtlpTransport()]
      }
    })
  )
  .get('/', () => 'ok')
  .listen(3000)
```

## Environment Variables

The adapter honors the standard OpenTelemetry exporter variables:

| Variable                           | Required | Description                                                                          |
| ---------------------------------- | -------- | ------------------------------------------------------------------------------------ |
| `OTEL_EXPORTER_OTLP_ENDPOINT`      | Yes\*    | OTLP HTTP base URL — `/v1/logs` is appended                                          |
| `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | Yes\*    | Signal-specific logs URL, used **as-is**; takes precedence over the generic endpoint |
| `OTEL_EXPORTER_OTLP_HEADERS`       | No       | Extra headers in `k=v,k2=v2` format (vendor auth); values may be percent-encoded     |
| `OTEL_EXPORTER_OTLP_LOGS_HEADERS`  | No       | Signal-specific headers; take precedence over the generic headers                    |
| `OTEL_SERVICE_NAME`                | No       | Value of the `service.name` resource attribute                                       |

\* One of the two endpoint variables (or the `endpoint` option) is required.

## Options

```ts theme={null}
const otlp = createOtlpTransport({
  endpoint: 'https://otlp.example.com',
  headers: { 'x-api-key': process.env.MY_KEY ?? '' },
  resourceAttributes: { 'deployment.environment': 'production' },
  serviceName: 'my-api'
})
```

| Option               | Type                     | Default                       | Description                                          |
| -------------------- | ------------------------ | ----------------------------- | ---------------------------------------------------- |
| `endpoint`           | `string`                 | `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP HTTP base URL                                   |
| `headers`            | `Record<string, string>` | parsed from env               | Extra request headers; overrides env headers per key |
| `serviceName`        | `string`                 | `logixlysia`                  | `service.name` resource attribute                    |
| `resourceAttributes` | `Record<string, string>` | —                             | Extra OTLP resource attributes                       |

Plus the shared batching options: `maxBatchSize`, `flushIntervalMs`, `timeout`, `retries` — see the [overview](/docs/adapters/overview#shared-behavior).

## Payload

Logs post to `{endpoint}/v1/logs`. Levels map to OpenTelemetry severity numbers (`DEBUG` → 5, `INFO` → 9, `WARNING` → 13, `ERROR` → 17), and meta fields flatten into dot-notation attributes (`request.method`, `status`, `durationMs`, `context.requestId`, …).

Pair this with [`logixlysia/otel`](/docs/integrations/otel) to include `context.trace_id` / `context.span_id` and correlate logs with traces in your backend.

## Vendor Examples

**Grafana Cloud** (OTLP gateway):

```bash theme={null}
OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp-gateway-prod-eu-west-2.grafana.net/otlp
OTEL_EXPORTER_OTLP_HEADERS='Authorization=Basic BASE64_OF_INSTANCE_ID_AND_TOKEN'
```

**New Relic**:

```bash theme={null}
OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.nr-data.net
OTEL_EXPORTER_OTLP_HEADERS=api-key=<license-key>
```

**Local collector** — point at port 4318 and let the collector fan out:

```ts theme={null}
createOtlpTransport({ endpoint: 'http://localhost:4318' })
```

## Troubleshooting

* **`404`** — the endpoint should be the **base URL only**; the adapter appends `/v1/logs` itself.
* **`401` / `403`** — check the header format in `OTEL_EXPORTER_OTLP_HEADERS`; values must not be URL-encoded.
* **Nothing arrives** — logs flush in batches (2 s by default); call `flush()` before short-lived processes exit.
