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

# Send OpenLLMetry traces to Bronto

> Instrument LLM providers and frameworks with Traceloop OpenLLMetry and send the resulting OpenTelemetry traces to Bronto.

[OpenLLMetry](https://github.com/traceloop/openllmetry) is a collection of OpenTelemetry instrumentations maintained by Traceloop. It adds tracing for LLM provider SDKs, agent frameworks, and vector databases that may not be covered by the official OpenTelemetry contrib packages.

Use OpenLLMetry when you need broader automatic coverage—for example, Anthropic instrumentation in Node.js—or want framework-level workflow and task spans. If an official OTel contrib instrumentation covers your provider, prefer it for the most direct alignment with the latest [OTel GenAI semantic conventions](https://github.com/open-telemetry/semantic-conventions-genai).

<Note>
  OpenLLMetry is built on OpenTelemetry, but attribute coverage varies by language, instrumentation, and release. Current JavaScript provider instrumentations use current fields such as `gen_ai.provider.name`, `gen_ai.operation.name`, and `gen_ai.usage.input_tokens` / `gen_ai.usage.output_tokens`. Older releases and some Python, framework, workflow, or task spans may also emit legacy or `traceloop.*` attributes. Keep OpenLLMetry updated and verify the fields emitted by the version you deploy.
</Note>

## Prerequisites

* A Bronto API key with ingestion permissions—see [API Keys](/Account-Management/API-Keys)
* An application that uses a supported LLM provider or framework
* Python or Node.js; see OpenLLMetry's [current support matrix](https://docs.traceloop.com/docs/openllmetry/tracing/supported) before choosing an instrumentation
* Optional: an OTel Collector configured using [Connect OpenTelemetry to Bronto](/agent-setup/open-telemetry)

## Choose an integration approach

OpenLLMetry provides a bundled SDK and individual instrumentation packages:

* Use the **bundled SDK** for the simplest setup. It detects supported libraries and configures tracing and export.
* Use **individual instrumentations** when your application already owns its OTel `TracerProvider`, processors, and exporters. This avoids creating a second provider and lets OpenLLMetry spans follow your existing sampling and export configuration.

Do not enable two instrumentations for the same provider call. For example, choose either the OTel contrib OpenAI instrumentation or OpenLLMetry's OpenAI instrumentation, otherwise a single request can produce duplicate spans.

## Node.js

Install the bundled SDK:

```bash theme={"dark"}
npm install @traceloop/node-server-sdk
```

Initialize it before importing any LLM provider or framework module so that OpenLLMetry can patch the module as it loads:

```ts theme={"dark"}
import * as traceloop from "@traceloop/node-server-sdk";

traceloop.initialize({ appName: "llm-service" });

// Import provider SDKs only after OpenLLMetry is initialized.
const { Anthropic } = await import("@anthropic-ai/sdk");
```

If you already manage the OTel SDK, install only the provider instrumentation you need. For example:

```bash theme={"dark"}
npm install @traceloop/instrumentation-anthropic
```

Register it with the same `NodeSDK` or `registerInstrumentations` configuration as your other OTel instrumentations. See [Node.js: GenAI semantic conventions](/opentelemetry/nodejs#genai-semantic-conventions) for the shared SDK setup.

## Python

Install and initialize the bundled SDK before making provider calls:

```bash theme={"dark"}
pip install --upgrade traceloop-sdk
```

```python theme={"dark"}
from traceloop.sdk import Traceloop

Traceloop.init(app_name="llm-service")
```

OpenLLMetry also publishes individual `opentelemetry-instrumentation-*` packages. If your application already configures a global OTel `TracerProvider`, use the individual package and the normal OTel auto-instrumentation flow instead of initializing a second SDK. See [Python: GenAI semantic conventions](/opentelemetry/python#genai-semantic-conventions).

## Send traces to Bronto

### Through an OTel Collector

Point OpenLLMetry at the Collector's OTLP/HTTP receiver. `TRACELOOP_BASE_URL` is a base endpoint; OpenLLMetry appends `/v1/traces`:

```bash theme={"dark"}
export TRACELOOP_BASE_URL="http://otel-collector:4318"
```

Configure the Collector to forward traces to Bronto as described in [Connect OpenTelemetry to Bronto](/agent-setup/open-telemetry). The Collector is recommended in production because it centralizes credentials, batching, sampling, retries, and fan-out.

### Directly to Bronto

Set the Bronto ingestion base URL and API-key header. Do not include `/v1/traces` in `TRACELOOP_BASE_URL` because OpenLLMetry adds it automatically.

<Tabs>
  <Tab title="EU">
    ```bash theme={"dark"}
    export TRACELOOP_BASE_URL="https://ingestion.eu.bronto.io"
    export TRACELOOP_HEADERS="x-bronto-api-key=<YOUR_API_KEY>"
    ```
  </Tab>

  <Tab title="US">
    ```bash theme={"dark"}
    export TRACELOOP_BASE_URL="https://ingestion.us.bronto.io"
    export TRACELOOP_HEADERS="x-bronto-api-key=<YOUR_API_KEY>"
    ```
  </Tab>
</Tabs>

`TRACELOOP_HEADERS` is required because Bronto authenticates with `x-bronto-api-key`; `TRACELOOP_API_KEY` sends a bearer token and is intended for the Traceloop service.

## Control prompt and response capture

OpenLLMetry captures prompts, completions, and embeddings on spans **by default**. These values may contain personal data, credentials, proprietary context, or large payloads. Disable content capture globally unless you have intentionally approved collecting it:

```bash theme={"dark"}
export TRACELOOP_TRACE_CONTENT=false
```

In Node.js you can instead configure `traceContent: false`:

```ts theme={"dark"}
traceloop.initialize({
  appName: "llm-service",
  traceContent: false,
});
```

This setting does not remove model metadata or token usage. It suppresses prompt, response, and embedding content collected by OpenLLMetry instrumentations.

## What you get

On current provider spans, query the OTel GenAI semantic-convention attributes that the provider response makes available:

| Attribute                                                                           | What it represents                                   |
| ----------------------------------------------------------------------------------- | ---------------------------------------------------- |
| `gen_ai.provider.name`                                                              | Model provider, such as `anthropic` or `openai`      |
| `gen_ai.operation.name`                                                             | Operation type, such as `chat` or `text_completion`  |
| `gen_ai.request.model` / `gen_ai.response.model`                                    | Requested and returned model names                   |
| `gen_ai.request.max_tokens`                                                         | Configured output-token limit                        |
| `gen_ai.request.temperature` / `gen_ai.request.top_p`                               | Sampling parameters                                  |
| `gen_ai.response.finish_reasons`                                                    | Reasons generation stopped                           |
| `gen_ai.usage.input_tokens` / `gen_ai.usage.output_tokens`                          | Input and output token counts                        |
| `gen_ai.usage.cache_read.input_tokens` / `gen_ai.usage.cache_creation.input_tokens` | Prompt-cache token counts, when reported             |
| `gen_ai.system_instructions`                                                        | System instructions, when content capture is enabled |
| `gen_ai.input.messages` / `gen_ai.output.messages`                                  | Structured messages, when content capture is enabled |

OpenLLMetry may add fields outside this list, including `gen_ai.usage.total_tokens`, provider-specific extensions, and `traceloop.*` workflow or task attributes. These can be useful, but they are not a portable substitute for the current OTel fields above.

## Verify in Bronto

Open [Log Search](https://app.bronto.io/search) and filter on the service name or standard GenAI fields. For example, find Anthropic calls with token usage:

```sql theme={"dark"}
"$gen_ai.provider.name" = 'anthropic'
AND "$gen_ai.usage.input_tokens" > 0
```

To compare usage across providers, create a visualization using **Sum**, **Median**, or **P75**, **P90**, **P95**, or **P99** on `$gen_ai.usage.input_tokens` or `$gen_ai.usage.output_tokens`, grouped by `$gen_ai.provider.name`.

See [LLM Observability](/ai-features/llm-observability#4-search-and-aggregate) for the complete query and aggregation examples.

## Troubleshooting

* **No Node.js provider spans:** initialize OpenLLMetry before importing the provider SDK. Module patching cannot instrument an SDK that was loaded first.
* **Duplicate model spans:** disable the overlapping contrib or OpenLLMetry instrumentation so only one package instruments each provider.
* **No traces after a short-lived script exits:** temporarily use `disableBatch: true` in Node.js or `disable_batch=True` in Python while testing, or shut down the SDK cleanly before exit.
* **404 from direct export:** remove `/v1/traces` from `TRACELOOP_BASE_URL`; OpenLLMetry appends the signal path.
* **Queries do not match:** inspect a span from the installed package. Upgrade older OpenLLMetry releases and base shared dashboards on the current `gen_ai.*` fields listed above.

## References

* [OpenLLMetry Python repository](https://github.com/traceloop/openllmetry)
* [OpenLLMetry-JS repository](https://github.com/traceloop/openllmetry-js)
* [OpenLLMetry initialization options](https://docs.traceloop.com/docs/openllmetry/configuration)
* [OpenLLMetry content-capture controls](https://docs.traceloop.com/docs/openllmetry/privacy/traces)
* [OpenTelemetry GenAI semantic conventions](https://github.com/open-telemetry/semantic-conventions-genai)
* [LLM Observability](/ai-features/llm-observability)
