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

# Send Traces with OpenTelemetry

> Configure OpenTelemetry in your application to generate and export trace data to Honeycomb using the OTLP exporter.

export const CalloutLearn = ({children}) => {
  return <Callout icon="brain-circuit" color="#8B5CF6">
      {children}
    </Callout>;
};

Honeycomb supports [OpenTelemetry](https://opentelemetry.io/).
OpenTelemetry is an open-source framework for collecting and managing telemetry data from distributed systems.
It provides a standardized way of instrumenting code to generate telemetry data, such as traces, metrics, and logs, and exporting that data to various backends for analysis and visualization.
OpenTelemetry supports multiple programming languages and platforms, making it easy to integrate with a variety of systems.

OpenTelemetry comprises two main components: instrumentation libraries and exporters.
The instrumentation libraries enable developers to collect telemetry data from their applications, while the exporters allow users to send the data to backends like Honeycomb.

<CalloutLearn>
  For more structured learning, check out the [OpenTelemetry Foundations](https://academy.honeycomb.io/app/courses/3c8c4ded-ce8c-4df1-8150-b73fdf59f2b0) course from Honeycomb Academy.
</CalloutLearn>

If instrumenting code for the first time, we recommend using OpenTelemetry.

If your application is already instrumented with OpenTelemetry, you can send OpenTelemetry Protocol (OTLP) data directly to Honeycomb.
To learn more, read [Using the Honeycomb OpenTelemetry Endpoint](#using-the-honeycomb-opentelemetry-endpoint).

Honeycomb supports receiving telemetry data via OpenTelemetry's native protocol, [OTLP](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md), over gRPC, HTTP/protobuf, and HTTP/JSON.
The minimum supported versions of OTLP [protobuf definitions](https://github.com/open-telemetry/opentelemetry-proto) are 1.0 for traces, metrics, and logs.

If a system is already instrumented with legacy instrumentation like OpenTracing, Zipkin, or Jaeger, you should use an [OpenTelemetry Collector](/send-data/opentelemetry/collector/) to convert into OTLP and export your data to Honeycomb.

## Instrumenting with OpenTelemetry

Select your application's language for instructions on instrumenting with OpenTelemetry:

<Columns cols={2}>
  <Card title="OpenTelemetry for Go" href="/send-data/go/opentelemetry-sdk/">
    Instrument your Go application with OpenTelemetry.
  </Card>

  <Card title="OpenTelemetry for Java" href="/send-data/java/opentelemetry-agent/">
    Instrument your Java application with OpenTelemetry.
  </Card>

  <Card title="OpenTelemetry for .NET" href="/send-data/dotnet/">
    Instrument your .NET application with OpenTelemetry.
  </Card>

  <Card title="OpenTelemetry for Node.js" href="/send-data/javascript-nodejs/opentelemetry-sdk/">
    Instrument your Node.js application with OpenTelemetry.
  </Card>

  <Card title="OpenTelemetry for Python" href="/send-data/python/opentelemetry-sdk/">
    Instrument your Python application with OpenTelemetry.
  </Card>

  <Card title="OpenTelemetry for Ruby" href="/send-data/ruby/opentelemetry-sdk/">
    Instrument your Ruby application with OpenTelemetry.
  </Card>
</Columns>

## Using the Honeycomb OpenTelemetry Endpoint

If your language is not listed above, you can send data to Honeycomb directly over OTLP with an OpenTelemetry SDK or the OpenTelemetry Collector.

<Tip>
  For Rust, we recommend that you use the [`opentelemetry`](https://crates.io/crates/opentelemetry) and [`opentelemetry-otlp`](https://crates.io/crates/opentelemetry-otlp) crates to send data over OTLP to Honeycomb.
  Follow the instructions below for the required configuration values.
</Tip>

An OpenTelemetry integration should set the endpoint and headers.

<Tabs>
  <Tab title="Environment Variables">
    1. Set the endpoint:

       * For OTLP/gRPC:
         * US instance: `export OTEL_EXPORTER_OTLP_ENDPOINT=api.honeycomb.io:443`
         * EU instance: `export OTEL_EXPORTER_OTLP_ENDPOINT=api.eu1.honeycomb.io:443`
       * For OTLP/HTTPS:
         * US instance: `export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io/`
         * EU instance: `export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.eu1.honeycomb.io/`

    2. Set your API key:

       ```shell theme={}
       export OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=your-api-key"
       ```

    3. Set the service name in the `OTEL_SERVICE_NAME` environment variable:

       ```shell theme={}
       export OTEL_SERVICE_NAME=your-service-name
       ```

       **Note**: If you use [Honeycomb Classic](/troubleshoot/product-lifecycle/recommended-migrations/#migrate-from-honeycomb-classic-to-honeycomb-environments), set the `x-honeycomb-dataset` in the HTTP Headers.

       ```shell theme={}
       export OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=your-api-key,x-honeycomb-dataset=your-dataset-name"
       ```
  </Tab>

  <Tab title="In Code">
    1. Set the endpoint in SDK initialization code:

       * For OTLP/gRPC:
         * US instance: `api.honeycomb.io:443`
         * EU instance: `api.eu1.honeycomb.io:443`
       * For OTLP/HTTPS:
         * US instance:
           * `https://api.honeycomb.io/v1/traces` for traces
           * `https://api.honeycomb.io/v1/metrics` for metrics
           * `https://api.honeycomb.io/v1/logs` for logs
         * EU instance:
           * `https://api.eu1.honeycomb.io/v1/traces` for traces
           * `https://api.eu1.honeycomb.io/v1/metrics` for metrics
           * `https://api.eu1.honeycomb.io/v1/logs` for logs

    2. For HTTP requests, define the API key in the HTTP headers.

       For example, in Rust, it may look like this:

       ```rust theme={}
       //...
       const API_KEY: &str = "your-api-key-here";

       //...

       .with_headers(HashMap::from([
           ("x-honeycomb-team".into(), API_KEY.into())
           //...
       ]))
       ```

    3. Set the service name in the `OTEL_SERVICE_NAME` environment variable:

       ```shell theme={}
       export OTEL_SERVICE_NAME=your-service-name
       ```

       **Note**: If you use [Honeycomb Classic](/troubleshoot/product-lifecycle/recommended-migrations/#migrate-from-honeycomb-classic-to-honeycomb-environments), set the `x-honeycomb-dataset` in the HTTP Headers.
  </Tab>
</Tabs>

## About the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable

When using the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable with an SDK and an HTTP exporter, the final path of the endpoint is modified by the SDK to represent the specific signal being sent.

For example, when exporting trace data, the endpoint is updated to append `v1/traces`.
When exporting metrics data, the endpoint is updated to append `v1/metrics`.
So, if you were to set the `OTEL_EXPORTER_OTLP_ENDPOINT` to `https://api.honeycomb.io`, traces would be sent to `https://api.honeycomb.io/v1/traces` and metrics would be sent to `https://api.honeycomb.io/v1/metrics`.

The same modification is not necessary for gRPC.

```shell theme={}
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io # US instance
#export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.eu1.honeycomb.io # EU instance
```

If the desired outcome is to send data to a different endpoint depending on the signal, use `OTEL_EXPORTER_OTLP_<SIGNAL>_ENDPOINT` instead of the more generic `OTEL_EXPORTER_OTLP_ENDPOINT`.

When using a signal-specific environment variable, these paths must be appended manually.
Set `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` for traces, appending the endpoint with `v1/traces`, and `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` for metrics, appending the endpoint with `v1/metrics`.

Send both traces and metrics to Honeycomb using this method by setting the following variables:

```shell theme={}
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://api.honeycomb.io/v1/traces # US instance
#export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://api.eu1.honeycomb.io/v1/traces # EU instance

export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://api.honeycomb.io/v1/metrics # US instance
#export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://api.eu1.honeycomb.io/v1/metrics # EU instance
```

More details about endpoints and signals can be found in the [OpenTelemetry Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md).

## Instrumented Fields

With its Automatic Instrumentation, OpenTelemetry automatically tracks trace and span relationships using the following fields:

| Field             | Description                                                                                        |
| ----------------- | -------------------------------------------------------------------------------------------------- |
| `name`            | Name of the function or method where the span was created                                          |
| `service.name`    | Name of the instrumented service                                                                   |
| `duration_ms`     | Length of time the span took, in milliseconds                                                      |
| `trace.span_id`   | Unique identifier for each span                                                                    |
| `trace.trace_id`  | Unique identifier of the trace this span belongs to                                                |
| `trace.parent_id` | Unique identifier of this span's parent span, which is the call location this span was called from |
