@@ -16,7 +16,6 @@ This example demonstrates how to integrate the LaunchDarkly C++ Server SDK with
1616- CMake 3.19 or later
1717- Boost 1.81 or later
1818- LaunchDarkly SDK key
19- - OpenTelemetry collector (or compatible backend) running on ` localhost:4318 `
2019
2120## Building
2221
@@ -30,33 +29,19 @@ cmake --build . --target hello-cpp-server-otel
3029
3130## Running
3231
33- ### 1. Start an OpenTelemetry Collector
34-
35- The easiest way is using Docker:
36-
37- ``` bash
38- docker run -p 4318:4318 otel/opentelemetry-collector:latest
39- ```
40-
41- Or use Jaeger (which has a built-in OTLP receiver):
42-
43- ``` bash
44- docker run -d -p 16686:16686 -p 4318:4318 jaegertracing/all-in-one:latest
45- ```
46-
47- ### 2. Set Your LaunchDarkly SDK Key
32+ ### 1. Set Your LaunchDarkly SDK Key
4833
4934Either edit ` main.cpp ` and set the ` SDK_KEY ` constant, or use an environment variable:
5035
5136``` bash
5237export LD_SDK_KEY=your-sdk-key-here
5338```
5439
55- ### 3 . Create a Feature Flag
40+ ### 2 . Create a Feature Flag
5641
5742In your LaunchDarkly dashboard, create a boolean flag named ` show-detailed-weather ` .
5843
59- ### 4 . Run the Example
44+ ### 3 . Run the Example
6045
6146``` bash
6247./build/examples/hello-cpp-server-otel/hello-cpp-server-otel
@@ -69,74 +54,36 @@ You should see:
6954
7055*** Weather server running on http://0.0.0.0:8080
7156*** Try: curl http://localhost:8080/weather
72- *** OpenTelemetry tracing enabled (OTLP HTTP to localhost:4318)
57+ *** OpenTelemetry tracing enabled, sending traces to LaunchDarkly
7358*** LaunchDarkly integration enabled with OpenTelemetry tracing hook
7459```
7560
76- ### 5 . Make Requests
61+ ### 4 . Make Requests
7762
7863``` bash
7964curl http://localhost:8080/weather
8065```
8166
82- ### 6. View Traces
83-
84- If using Jaeger, open http://localhost:16686 in your browser. You should see traces with:
67+ ### 5. View Traces in LaunchDarkly
8568
86- - HTTP request spans
87- - Feature flag evaluation events with attributes:
88- - ` feature_flag.key ` : "show-detailed-weather"
89- - ` feature_flag.provider.name ` : "LaunchDarkly"
90- - ` feature_flag.context.id ` : Context canonical key
91- - ` feature_flag.result.value ` : The flag value (since ` IncludeValue ` is enabled)
69+ 1 . Go to your LaunchDarkly project
70+ 2 . Navigate to the Observability section
71+ 3 . View traces containing your feature flag evaluations with attributes:
72+ - ` feature_flag.key ` : "show-detailed-weather"
73+ - ` feature_flag.provider.name ` : "LaunchDarkly"
74+ - ` feature_flag.context.id ` : Context canonical key
75+ - ` feature_flag.result.value ` : The flag value (since ` IncludeValue ` is enabled)
9276
93- ## How It Works
77+ ### Custom OTLP Endpoint
9478
95- ### OpenTelemetry Setup
79+ To send traces to a different OpenTelemetry collector, set the ` LD_OTEL_ENDPOINT ` environment variable:
9680
97- ``` cpp
98- void InitTracer () {
99- opentelemetry::exporter::otlp::OtlpHttpExporterOptions opts;
100- opts.url = "http://localhost:4318/v1/traces";
101-
102- auto exporter = opentelemetry::exporter::otlp::OtlpHttpExporterFactory::Create(opts);
103- auto processor = trace_sdk::SimpleSpanProcessorFactory::Create(std::move(exporter));
104- std::shared_ptr<trace_api::TracerProvider> provider =
105- trace_sdk::TracerProviderFactory::Create (std::move (processor));
106- trace_api::Provider::SetTracerProvider(provider);
107- }
108- ```
109-
110- ### LaunchDarkly Hook Setup
111-
112- ``` cpp
113- auto hook_options = launchdarkly::server_side::integrations::otel::TracingHookOptionsBuilder()
114- .IncludeValue(true ) // Include flag values in traces
115- .CreateSpans(false ) // Only create span events, not full spans
116- .Build();
117- auto tracing_hook = std::make_shared<launchdarkly::server_side::integrations::otel::TracingHook>(hook_options);
118-
119- auto config = launchdarkly::server_side::ConfigBuilder(sdk_key)
120- .Hooks(tracing_hook)
121- .Build();
122- ```
123-
124- ### Passing Parent Span Context
125-
126- When using async frameworks like Boost.Beast, you need to manually pass the parent span:
127-
128- ``` cpp
129- auto span = tracer->StartSpan ("HTTP GET /weather");
130- auto scope = trace_api::Scope(span);
131-
132- // Create hook context with the span
133- auto hook_ctx = launchdarkly::server_side::integrations::otel::MakeHookContextWithSpan(span);
134-
135- // Pass it to the evaluation
136- auto flag_value = ld_client->BoolVariation(context, "my-flag", false, hook_ctx);
81+ ``` bash
82+ export LD_OTEL_ENDPOINT=http://localhost:4318/v1/traces
83+ ./build/examples/hello-cpp-server-otel/hello-cpp-server-otel
13784```
13885
139- This ensures feature flag events appear as children of the correct span .
86+ Note: The ` /v1/traces ` path is automatically appended to the endpoint .
14087
14188## What You'll See
14289
@@ -146,23 +93,20 @@ This ensures feature flag events appear as children of the correct span.
14693*** SDK successfully initialized!
14794
14895*** Weather server running on http://0.0.0.0:8080
96+ *** Try: curl http://localhost:8080/weather
97+ *** OpenTelemetry tracing enabled, sending traces to LaunchDarkly
98+ *** LaunchDarkly integration enabled with OpenTelemetry tracing hook
14999```
150100
151- ### In Your Traces
101+ ### In LaunchDarkly Observability
152102
153- Each HTTP request will have:
103+ Navigate to your LaunchDarkly project's Observability section to view traces. Each HTTP request will have:
1541041 . ** Root Span** : "HTTP GET /weather" with HTTP attributes
155- 2. **Span Event**: "feature_flag" with LaunchDarkly evaluation details
156-
157- Example trace structure:
158- ```
159- HTTP GET /weather (span)
160- └─ feature_flag (event)
161- ├─ feature_flag.key: "show-detailed-weather"
162- ├─ feature_flag.provider.name: "LaunchDarkly"
163- ├─ feature_flag.context.id: "user: weather-api-user "
164- └─ feature_flag.result.value: "true"
165- ```
105+ 2 . ** Feature Flag Event** : Attached to the span with evaluation details:
106+ - ` feature_flag.key ` : "show-detailed-weather"
107+ - ` feature_flag.provider.name ` : "LaunchDarkly"
108+ - ` feature_flag.context.id ` : "user: weather-api-user "
109+ - ` feature_flag.result.value ` : The evaluated flag value
166110
167111## Customization
168112
0 commit comments