# Integrating OpenTelemetry

This guide explains how to use EventSourcingDB with **OpenTelemetry tracing**. It covers how to propagate trace context via CloudEvents, how EventSourcingDB handles that context, and what constraints apply.

## Overview

EventSourcingDB supports **[OpenTelemetry](https://opentelemetry.io/) trace context propagation** using the **[CloudEvents Distributed Tracing extension](https://github.com/cloudevents/spec/blob/v1.0.1/extensions/distributed-tracing.md)**. This allows events to carry trace information for **distributed tracing across systems**.

EventSourcingDB **does not generate or modify tracing data**. It simply **validates**, **stores**, and **returns** the trace context provided by the client.

## Using Trace Context

To associate trace context with an event, add the **`traceparent` field** at the top level of the event. You may also include the **optional `tracestate` field**. Both fields must appear at the top level of the event, not inside `data`:

```json
{
  // ...
  "data": {
    // ...
  },
  "traceparent": "00-eb0e08452e7ee4b0d3b8b30987c37951-c31bc0a7013beab8-00",
  "tracestate": "rojo=00f067aa0ba902b7,congo=t61rcWkgMzE"
}
```

Trace context is **entirely optional**. If `traceparent` is omitted, the event is accepted without tracing metadata. However, **if `tracestate` is included, `traceparent` must also be set**. Both fields are strictly validated for correct syntax before an event is accepted.

### Trace Context Format

The **`traceparent` field** must conform to the **[W3C Trace Context specification](https://www.w3.org/TR/trace-context/)**:

```
<version>-<trace-id>-<span-id>-<trace-flags>
```

- **Version**: 2 hex digits (must be `00`)
- **Trace ID**: 32 hex digits (16 bytes)
- **Span ID**: 16 hex digits (8 bytes)
- **Trace Flags**: 2 hex digits

The **`tracestate` field** must be a **comma-separated list of key-value pairs**:

- **Keys**: lowercase letters and digits only
- **Values**: printable ASCII characters, excluding commas and equal signs
- **Max total length**: 512 characters

> **What Do `rojo` and `congo` Mean?**
>
> These are **example vendor keys** from the W3C spec, demonstrating how multiple telemetry systems can share trace metadata. In real applications, you'd use identifiers relevant to your tracing backend (e.g., `datadog=...`, `vendorX=...`).

## Reading and Observing Trace Context

When events are read or observed, any `traceparent` and `tracestate` values are **returned exactly as stored** – unmodified and in their original form. This allows downstream systems or analysis tools to **follow the trace across service boundaries**.

```json
{
  // ...
  "data": {
    // ...
  },
  "traceparent": "00-eb0e08452e7ee4b0d3b8b30987c37951-c31bc0a7013beab8-00",
  "tracestate": "rojo=00f067aa0ba902b7,congo=t61rcWkgMzE"
}
```

## Best Practices

- **Always set `traceparent`** when emitting events from a traced operation
- **Use `tracestate` only if needed** by your telemetry backend
- **Validate trace context** before writing events
- Use tools like **[Jaeger](https://www.jaegertracing.io/)** or **[Grafana Tempo](https://grafana.com/oss/tempo/)** to **visualize traces** across services

Propagating trace context through events enables end-to-end observability – even in **asynchronous, decoupled architectures**.
