> ## 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.

# Instrument your backend

> Send logs and traces from backend services to Sazabi with OpenTelemetry, using OTLP environment variables or an OpenTelemetry Collector, and find where to send metrics.

Backend services send logs and traces to Sazabi over OTLP, the OpenTelemetry protocol. Point your OpenTelemetry SDK, or a Collector in front of it, at your intake URL. By the end you will have a service exporting telemetry and confirmed records arriving. Setup takes a few minutes plus a redeploy.

## Choose how to send

* **From the SDK.** Your service exports logs and traces straight to Sazabi with two environment variables. Use this when you can restart the service with new configuration.
* **Through a Collector.** Your service exports to a Collector you already run, and the Collector forwards to Sazabi. Use this to keep one pipeline, batch in one place, or fan out to other backends too.

If your logs live on a platform you host on, such as Vercel or Cloudflare, connect it instead; see [How data gets into Sazabi](https://docs.sazabi.com/send-data.md).

## Send from the SDK

**Step 1**

Get your intake URL. Open [**Settings > Log streams**](https://app.sazabi.com/settings/log-source-providers), add the OpenTelemetry source, and copy the **Intake URL** from its setup screen. The URL embeds your public key, so copy the whole URL and send no separate key or header. To create the source from the CLI, run `npx -y @sazabi/cli@latest log-sources create otel --mode manual`; it prints the intake URL.

**Step 2**

Add the OpenTelemetry SDK for your language with an OTLP log and trace exporter. For install commands in Node.js and Python, and a Python logs-only setup, see [OpenTelemetry](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/opentelemetry.md).

**Step 3**

Set the exporter environment where the process starts:

```bash title="Environment" theme={"system"}
OTEL_EXPORTER_OTLP_ENDPOINT=your-intake-url
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_SERVICE_NAME=checkout-api
```

Use the intake URL as is. The SDK appends `/v1/logs` and `/v1/traces` itself, so do not add a path.

**Step 4**

Restart or redeploy so the SDK starts with the new environment.

Sazabi's OTLP intake takes HTTP only, as protobuf or JSON. Many SDKs default to gRPC, which the intake does not accept, so keep `OTEL_EXPORTER_OTLP_PROTOCOL` set to `http/protobuf`. `OTEL_SERVICE_NAME` sets the service name you filter and group by in Sazabi; give each service its own.

## Send through a Collector

Add an `otlphttp` exporter that points at your intake URL, and put it in the logs and traces pipelines:

```yaml title="otelcol.yaml" theme={"system"}
receivers:
  otlp:
    protocols:
      http:
        endpoint: 0.0.0.0:4318

exporters:
  otlphttp/sazabi:
    endpoint: your-intake-url

service:
  pipelines:
    logs:
      receivers: [otlp]
      exporters: [otlphttp/sazabi]
    traces:
      receivers: [otlp]
      exporters: [otlphttp/sazabi]
```

Then point each service at the Collector with `OTEL_EXPORTER_OTLP_ENDPOINT`. For file, Kubernetes, and other receivers, see [OpenTelemetry Collector](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/otel-collector.md).

## Send metrics and traces separately

Sazabi stores every signal as a log record, but each signal has its own intake path:

* **Logs and traces** go to the OpenTelemetry source's intake URL above. Spans become records you can search next to your logs.
* **Metrics** sent to that URL are stored too, each data point as a record under the same source. To keep metrics under their own source, create an OpenTelemetry Metrics source and set `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` to its intake URL, which already ends in `/v1/metrics`. See [Send metrics](https://docs.sazabi.com/send-data/metrics.md).
* **Traces only.** To store spans and the exceptions they record as separate error records, use an OpenTelemetry Traces source. See [Send traces](https://docs.sazabi.com/send-data/traces.md).

If your SDK exports metrics by default and you only want logs and traces, set `OTEL_METRICS_EXPORTER=none` so it stops sending them.

## Verify

Confirm real records reach your project.

1. Restart the service and make a request that writes a log line or produces a trace.
2. Open the [Intake page](https://docs.sazabi.com/send-data/intake.md) and look for records from the OpenTelemetry source. They typically arrive within a minute or two.
3. Search for your service by name. In a thread, ask the Sazabi agent for logs from it, or run `npx -y @sazabi/cli@latest logs ask "logs from checkout-api" --since 1h`.

You should see records carrying your service name and the log lines or spans you generated.

## Troubleshooting

* **No records.** Confirm the environment variables are set in the process that runs the service, not only in a build step. Check the service's output for OpenTelemetry export errors.
* **Export errors or connection failures.** Confirm the protocol is `http/protobuf` and the endpoint is the complete intake URL, including `https://`. A partial or hand-built URL is rejected.
* **Traces arrive but logs do not.** Some SDKs configure trace export only. Add a log exporter to the SDK setup.
* **Metrics are missing.** Metrics need their own source; see [Send metrics and traces separately](#send-metrics-and-traces-separately).

For more, see [Troubleshooting ingestion](https://docs.sazabi.com/send-data/troubleshooting.md).

## Next steps

Your intake URL also works with logging libraries and frameworks that have their own OpenTelemetry integration. These pages cover specific setups:

* Collectors and agents: [Grafana Alloy](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/grafana-alloy.md), [Vector](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/vector.md), and [Fluent Bit](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/fluent-bit.md).
* TypeScript: [evlog](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/evlog.md) for wide events and structured errors.
* Error tracking: [Sentry SDK](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/sentry-sdk.md), to forward from a Sentry SDK you already run.
* Workflow engines and AI frameworks: [Temporal](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/temporal.md), [Inngest](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/inngest.md), [Trigger.dev](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/trigger-dev.md), [LangChain](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/langchain.md), and [Mastra](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/mastra.md).

## Further reading

> [card] [Instrument your frontend](https://docs.sazabi.com/send-data/frontend.md)
>
> Correlate browser events with these backend records.

> [card] [Search logs](https://docs.sazabi.com/explore/search.md)
>
> Ask questions about the records you now send.


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