# integration-opentelemetry/built-in (OpenTelemetry Built-in Tracing)

You can run this example with:

```bash
npx promptfoo@latest init --example integration-opentelemetry/built-in
cd integration-opentelemetry/built-in
```

This example demonstrates promptfoo's built-in OpenTelemetry tracing for LLM provider calls.

## Quick Start

1. **Set up environment variables:**

```bash
# Both providers are enabled in the example.
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...
```

To run only OpenAI, add `--filter-providers gpt-6-luna` to the eval command. Each test runs only against its matching prompt.

2. **Run the evaluation:**

```bash
npx promptfoo@latest eval -c promptfooconfig.yaml --no-cache -o results.json
```

3. **View traces in the UI:**

```bash
npx promptfoo@latest view
```

Navigate to the Traces tab to see detailed span information.

## Configuration

This example enables tracing with `tracing.enabled: true`. For configurations without that setting, enable it with `PROMPTFOO_TRACING_ENABLED=true`.

| Variable                      | Default     | Description                            |
| ----------------------------- | ----------- | -------------------------------------- |
| `PROMPTFOO_TRACING_ENABLED`   | `false`     | Enable tracing without a YAML setting  |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | -           | Export traces to external OTLP backend |
| `PROMPTFOO_OTEL_SERVICE_NAME` | `promptfoo` | Service name in traces                 |

## Viewing Traces Externally

### With Jaeger

1. Start Jaeger:

```bash
docker run -d --name jaeger \
  -e COLLECTOR_OTLP_ENABLED=true \
  -p 16686:16686 \
  -p 4318:4318 \
  jaegertracing/all-in-one:latest
```

2. Run eval with OTLP export:

```bash
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces npx promptfoo@latest eval --no-cache
```

3. View at http://localhost:16686

### With Honeycomb

```bash
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io/v1/traces \
OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=YOUR_API_KEY" \
npx promptfoo@latest eval --no-cache
```

## Trace Attributes

Each LLM call span includes:

### GenAI Semantic Conventions

- `gen_ai.provider.name` - Provider name (openai, anthropic, etc.)
- `gen_ai.operation.name` - Operation type (chat, completion, embedding)
- `gen_ai.request.model` - Requested model name
- `gen_ai.request.max_tokens` - Max tokens setting
- `gen_ai.request.temperature` - Temperature setting
- `gen_ai.usage.input_tokens` - Prompt tokens used
- `gen_ai.usage.output_tokens` - Completion tokens used
- `gen_ai.usage.cache_read.input_tokens` - Provider-cached input tokens
- `gen_ai.usage.cache_creation.input_tokens` - Input tokens used to create a provider cache entry
- `gen_ai.usage.reasoning.output_tokens` - Reasoning output tokens
- `gen_ai.response.model` - Actual model used
- `gen_ai.response.id` - Provider response ID
- `gen_ai.response.finish_reasons` - Finish reasons

### Promptfoo Attributes

- `promptfoo.provider.id` - Provider identifier
- `promptfoo.usage.total_tokens` - Total tokens
- `promptfoo.usage.cached_response_tokens` - Tokens served from the Promptfoo response cache
- `promptfoo.eval.id` - Evaluation run ID
- `promptfoo.test.index` - Test case index
- `promptfoo.prompt.label` - Prompt label

## Supported Providers

All major providers are instrumented:

| Provider          | Tracing Support |
| ----------------- | --------------- |
| OpenAI            | ✓               |
| Anthropic         | ✓               |
| Azure OpenAI      | ✓               |
| AWS Bedrock       | ✓               |
| Google Vertex AI  | ✓               |
| Ollama            | ✓               |
| Mistral           | ✓               |
| Cohere            | ✓               |
| Huggingface       | ✓               |
| IBM Watsonx       | ✓               |
| HTTP              | ✓               |
| OpenRouter        | ✓               |
| Replicate         | ✓               |
| OpenAI-compatible | ✓ (inherited)   |
| Cloudflare AI     | ✓ (inherited)   |
