276 {
277 std::cout << "=== Distributed Tracing Example ===" << std::endl;
278
279 try {
280
281 std::cout << "\n--- Part 1: Basic Span Management ---" << std::endl;
282
284
285
286 auto root_span_result = tracer.
start_span(
"main_operation",
"example_service");
287 if (!root_span_result.is_ok()) {
288 std::cerr << "Failed to create root span" << std::endl;
289 return 1;
290 }
291
292 auto root_span = root_span_result.value();
293
294 std::cout << "Created root span:" << std::endl;
295 std::cout << " Trace ID: " << root_span->trace_id << std::endl;
296 std::cout << " Span ID: " << root_span->span_id << std::endl;
297 std::cout << " Operation: " << root_span->operation_name << std::endl;
298
299
300 root_span->tags["version"] = "1.0.0";
301 root_span->tags["environment"] = "development";
302
303
304 root_span->baggage["user.id"] = "user789";
305 root_span->baggage["session.id"] = "sess123";
306
307
308 std::cout << "\nCreating child spans..." << std::endl;
309
310 auto child1_result = tracer.
start_child_span(*root_span,
"child_operation_1");
311 auto child2_result = tracer.
start_child_span(*root_span,
"child_operation_2");
312
313 if (child1_result.is_ok() && child2_result.is_ok()) {
314 auto child1 = child1_result.value();
315 auto child2 = child2_result.value();
316
317 std::cout << " Child 1 span ID: " << child1->span_id << std::endl;
318 std::cout << " Child 2 span ID: " << child2->span_id << std::endl;
319
320
321 std::this_thread::sleep_for(10ms);
322
323
326 }
327
328
330
331 std::cout << "All spans finished" << std::endl;
332
333
334 std::cout << "\n--- Part 2: Distributed System Simulation ---" << std::endl;
336
337
338 std::cout << "\n--- Part 3: Trace Analysis ---" << std::endl;
340
341
342 std::cout << "\n--- Part 4: Context Propagation ---" << std::endl;
343
344 auto demo_span_result = tracer.
start_span(
"propagation_demo");
345 if (demo_span_result.is_ok()) {
346 auto demo_span = demo_span_result.value();
347
348
350
351
352 std::map<std::string, std::string> http_headers;
354
355 std::cout << "Context injected into headers:" << std::endl;
356 for (const auto& [key, value] : http_headers) {
357 std::cout << " " << key << ": " << value << std::endl;
358 }
359
360
362 if (extracted_context.is_ok()) {
363 std::cout << "\nContext extracted from headers:" << std::endl;
364 std::cout << " Trace ID: " << extracted_context.value().trace_id << std::endl;
365 std::cout << " Span ID: " << extracted_context.value().span_id << std::endl;
366
367
369 extracted_context.value(),
370 "continued_operation"
371 );
372
373 if (continued_span.is_ok()) {
374 std::cout << " Continued span ID: "
375 << continued_span.value()->span_id << std::endl;
377 }
378 }
379
381 }
382
383 } catch (const std::exception& e) {
384 std::cerr << "Exception: " << e.what() << std::endl;
385 return 1;
386 }
387
388 std::cout << "\n=== Example completed successfully ===" << std::endl;
389
390 return 0;
391}
Distributed tracer for managing spans and traces.
common::Result< std::shared_ptr< trace_span > > start_span_from_context(const trace_context &context, const std::string &operation_name)
Start a span from trace context (for incoming requests)
common::Result< trace_context > extract_context_from_carrier(const Carrier &carrier)
Extract trace context from carrier.
trace_context extract_context(const trace_span &span) const
Extract trace context for propagation.
void inject_context(const trace_context &context, Carrier &carrier)
Inject trace context into carrier (e.g., HTTP headers)
void simulate_distributed_system()
void analyze_traces(distributed_tracer &tracer)