Skip to content

Commit a937681

Browse files
committed
add readme for otel addon
1 parent de146ed commit a937681

1 file changed

Lines changed: 130 additions & 0 deletions

File tree

addons/otel/README.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# FlowTracker OpenTelemetry (OTel) Bridge
2+
3+
This addon provides a bridge between **FlowTracker** and the **OpenTelemetry** ecosystem.
4+
5+
It allows you to write simple, lightweight instrumentation using FlowTracker, but export the data to industry-standard backend systems like **Jaeger**, **Grafana Tempo**, **Datadog**, **HoneyComb**, and **New Relic**.
6+
7+
## 📦 Installation
8+
9+
This is a separate module. You must install it alongside the core library and the OpenTelemetry SDK.
10+
11+
```bash
12+
# 1. Install FlowTracker Core
13+
go get github.com/spdeepak/flowtracker
14+
15+
# 2. Install the Bridge
16+
go get github.com/spdeepak/flowtracker/otel-exporter
17+
18+
# 3. Install OTel SDK dependencies (Required to configure the destination)
19+
go get go.opentelemetry.io/otel \
20+
go.opentelemetry.io/otel/sdk \
21+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp
22+
```
23+
24+
## 🚀 How it Works
25+
26+
1. **Instrumentation:** You use `flowtracker` as normal. It captures the execution flow, timestamps, and tags efficiently in memory.
27+
2. **Export:** When the request finishes, this exporter takes the completed `Trace` object.
28+
3. **Conversion:** It recursively maps the FlowTracker spans to OpenTelemetry Spans, preserving hierarchy, timestamps, and attributes.
29+
4. **Push:** It uses the standard OTel SDK to push the data to your configured backend (via HTTP/gRPC).
30+
31+
## 🛠 Usage
32+
33+
You need to configure the **OpenTelemetry SDK** (TracerProvider) in your application startup, and then pass it to the FlowTracker exporter.
34+
35+
### 1. Setup Jaeger or Grafana Tempo (Locally)
36+
37+
If you want to test this locally, run Jaeger via Docker:
38+
39+
```bash
40+
docker run -d --name jaeger \
41+
-p 16686:16686 \
42+
-p 4318:4318 \
43+
jaegertracing/all-in-one:latest
44+
```
45+
46+
or see the [docker compose file in examples](./../../examples/otlp/docker-compose.yaml)
47+
48+
### 2. Integration Code
49+
50+
```go
51+
package main
52+
53+
import (
54+
"context"
55+
"log"
56+
"net/http"
57+
58+
"github.com/spdeepak/flowtracker"
59+
otelexporter "github.com/spdeepak/flowtracker/otel-exporter"
60+
61+
"go.opentelemetry.io/otel"
62+
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
63+
"go.opentelemetry.io/otel/sdk/resource"
64+
sdktrace "go.opentelemetry.io/otel/sdk/trace"
65+
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
66+
)
67+
68+
func initTracer(ctx context.Context) *sdktrace.TracerProvider {
69+
// Configure OTLP Exporter to point to Jaeger/Tempo
70+
exporter, err := otlptracehttp.New(ctx,
71+
otlptracehttp.WithEndpoint("localhost:4318"), // Standard OTLP HTTP port
72+
otlptracehttp.WithInsecure(),
73+
)
74+
if err != nil {
75+
log.Fatalf("Failed to create exporter: %v", err)
76+
}
77+
78+
// Define Service Name
79+
res, _ := resource.Merge(
80+
resource.Default(),
81+
resource.NewWithAttributes(
82+
semconv.SchemaURL,
83+
semconv.ServiceName("my-flowtracker-service"),
84+
),
85+
)
86+
87+
// Create Tracer Provider
88+
tp := sdktrace.NewTracerProvider(
89+
sdktrace.WithBatcher(exporter),
90+
sdktrace.WithResource(res),
91+
)
92+
93+
otel.SetTracerProvider(tp)
94+
return tp
95+
}
96+
97+
func main() {
98+
ctx := context.Background()
99+
tp := initTracer(ctx)
100+
101+
// Ensure data is flushed on shutdown
102+
defer tp.Shutdown(ctx)
103+
104+
// --- THE BRIDGE ---
105+
// Create the exporter using the OTel Provider configured above
106+
bridgeExporter := otelexporter.New(tp)
107+
108+
// Register Middleware
109+
mw := flowtracker.NewMiddleware(flowtracker.WithExporter(bridgeExporter))
110+
111+
http.ListenAndServe(":8080", mw(http.DefaultServeMux))
112+
}
113+
```
114+
115+
## 📝 ID Mapping & Attributes
116+
117+
OpenTelemetry requires strictly formatted 128-bit Trace IDs and 64-bit Span IDs. FlowTracker uses simple strings.
118+
119+
To ensure data integrity, the exporter behaves as follows:
120+
121+
1. **New IDs:** The exporter generates **new, valid OTel UUIDs** for every trace and span so they are accepted by the backend.
122+
2. **Cross-Reference:** It automatically adds the original FlowTracker IDs as attributes to every span. You can search for these in your UI:
123+
* `flowtracker.trace_id`
124+
* `flowtracker.span_id`
125+
3. **Tags:** All tags added via `flowtracker.AddTag()` are converted to OTel Attributes.
126+
127+
## ⚠️ Limitations
128+
129+
* **Post-Processing:** FlowTracker traces are exported only *after* the root request finishes. This means you will not see "live" partial traces in Jaeger while the request is still processing (unlike native OTel streaming).
130+
* **Context Propagation:** If you make an HTTP call to *another* microservice from within your app, you must manually inject the OTel headers if you want distributed tracing across services. This bridge focuses on **internal** process flow.

0 commit comments

Comments
 (0)