Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
multi_service_tracing_example.cpp File Reference

Demonstrates distributed tracing across multiple services. More...

#include <iostream>
#include <memory>
#include <string>
#include <chrono>
#include <thread>
#include <iomanip>
#include "kcenon/monitoring/tracing/distributed_tracer.h"
Include dependency graph for multi_service_tracing_example.cpp:

Go to the source code of this file.

Classes

class  ApiGatewayService
 Simulated API Gateway service. More...
 
class  AuthService
 Simulated Authentication service. More...
 
class  UserService
 Simulated User service. More...
 
class  CacheService
 Simulated Cache service. More...
 

Functions

void display_span (const trace_span &span, int depth)
 Display single span.
 
void display_children (const std::vector< trace_span > &spans, const std::string &parent_id, int depth)
 Display children recursively.
 
void display_trace_tree (const std::vector< trace_span > &spans)
 Display trace tree structure.
 
void simulate_multi_service_request ()
 Simulate complete multi-service request flow.
 
int main ()
 

Detailed Description

Demonstrates distributed tracing across multiple services.

Definition in file multi_service_tracing_example.cpp.

Function Documentation

◆ display_children()

void display_children ( const std::vector< trace_span > & spans,
const std::string & parent_id,
int depth )

Display children recursively.

Examples
multi_service_tracing_example.cpp.

Definition at line 350 of file multi_service_tracing_example.cpp.

352 {
353 for (const auto& span : spans) {
354 if (span.parent_span_id == parent_id) {
355 display_span(span, depth);
356 display_children(spans, span.span_id, depth + 1);
357 }
358 }
359}
void display_children(const std::vector< trace_span > &spans, const std::string &parent_id, int depth)
Display children recursively.
void display_span(const trace_span &span, int depth)
Display single span.

References display_children(), and display_span().

Referenced by display_children(), and display_trace_tree().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ display_span()

void display_span ( const trace_span & span,
int depth )

Display single span.

Examples
multi_service_tracing_example.cpp.

Definition at line 323 of file multi_service_tracing_example.cpp.

323 {
324 std::string indent(depth * 2, ' ');
325 std::string prefix = depth == 0 ? "┌─" : "├─";
326
327 std::cout << indent << prefix << " [" << span.service_name << "] "
328 << span.operation_name << std::endl;
329 std::cout << indent << " Span ID: " << span.span_id << std::endl;
330 std::cout << indent << " Duration: " << span.duration.count() << "µs" << std::endl;
331
332 if (!span.tags.empty()) {
333 std::cout << indent << " Tags:";
334 int count = 0;
335 for (const auto& [key, value] : span.tags) {
336 if (count++ < 3) { // Show first 3 tags
337 std::cout << " " << key << "=" << value;
338 }
339 }
340 if (span.tags.size() > 3) {
341 std::cout << " +" << (span.tags.size() - 3) << " more";
342 }
343 std::cout << std::endl;
344 }
345}
std::unordered_map< std::string, std::string > tags
std::chrono::microseconds duration

References kcenon::monitoring::trace_span::duration, kcenon::monitoring::trace_span::operation_name, kcenon::monitoring::trace_span::service_name, kcenon::monitoring::trace_span::span_id, and kcenon::monitoring::trace_span::tags.

Referenced by display_children(), and display_trace_tree().

Here is the caller graph for this function:

◆ display_trace_tree()

void display_trace_tree ( const std::vector< trace_span > & spans)

Display trace tree structure.

Examples
multi_service_tracing_example.cpp.

Definition at line 291 of file multi_service_tracing_example.cpp.

291 {
292 std::cout << "\n=== Trace Tree Structure ===" << std::endl;
293
294 // Find root span
295 const trace_span* root = nullptr;
296 for (const auto& span : spans) {
297 if (span.parent_span_id.empty()) {
298 root = &span;
299 break;
300 }
301 }
302
303 if (!root) {
304 std::cout << "No root span found" << std::endl;
305 return;
306 }
307
308 std::cout << "\nTrace ID: " << root->trace_id << "\n" << std::endl;
309
310 // Display root
311 display_span(*root, 0);
312
313 // Display children
314 display_children(spans, root->span_id, 1);
315
316 std::cout << "\n=== Total Spans: " << spans.size() << " ===" << std::endl;
317 std::cout << "Total trace duration: " << root->duration.count() << "µs" << std::endl;
318}
Trace span representing a unit of work in distributed tracing.

References display_children(), display_span(), kcenon::monitoring::trace_span::duration, kcenon::monitoring::trace_span::span_id, and kcenon::monitoring::trace_span::trace_id.

Referenced by simulate_multi_service_request().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( )

Definition at line 420 of file multi_service_tracing_example.cpp.

420 {
421 std::cout << "Multi-Service Distributed Tracing Example\n" << std::endl;
422
424
425 std::cout << "\n" << std::string(60, '=') << std::endl;
426 std::cout << "\nKey Concepts Demonstrated:" << std::endl;
427 std::cout << "1. Trace context propagation across services" << std::endl;
428 std::cout << "2. Parent-child span relationships" << std::endl;
429 std::cout << "3. Baggage propagation for cross-cutting data" << std::endl;
430 std::cout << "4. W3C Trace Context standard" << std::endl;
431 std::cout << "5. Service-specific span tags and metadata" << std::endl;
432
433 return 0;
434}
void simulate_multi_service_request()
Simulate complete multi-service request flow.

References simulate_multi_service_request().

Here is the call graph for this function:

◆ simulate_multi_service_request()

void simulate_multi_service_request ( )

Simulate complete multi-service request flow.

Examples
multi_service_tracing_example.cpp.

Definition at line 364 of file multi_service_tracing_example.cpp.

364 {
365 std::cout << "=== Multi-Service Distributed Tracing Example ===" << std::endl;
366
367 std::vector<trace_span> collected_spans;
368
369 // Step 1: API Gateway receives request
370 std::cout << "\n--- Step 1: API Gateway ---" << std::endl;
371 ApiGatewayService gateway;
372 auto gateway_span = gateway.handle_request("/api/user/profile", "GET");
373 auto gateway_ctx = gateway.create_context(gateway_span);
374
375 // Step 2: Check cache (parallel to auth)
376 std::cout << "\n--- Step 2: Cache Lookup ---" << std::endl;
377 CacheService cache;
378 auto cache_span = cache.cache_lookup(gateway_ctx, "user:user-12345");
379 collected_spans.push_back(cache_span);
380
381 // Step 3: Authenticate request
382 std::cout << "\n--- Step 3: Authentication ---" << std::endl;
383 AuthService auth;
384 auto auth_span = auth.verify_token(gateway_ctx, "eyJhbGc...");
385 collected_spans.push_back(auth_span);
386
387 // Create context for user service call
388 trace_context user_ctx;
389 user_ctx.trace_id = gateway_ctx.trace_id;
390 user_ctx.span_id = gateway_span.span_id;
391 user_ctx.baggage = gateway_ctx.baggage;
392
393 // Step 4: Fetch user profile (after cache miss)
394 std::cout << "\n--- Step 4: User Profile Service ---" << std::endl;
395 UserService user_service;
396 auto user_span = user_service.get_user_profile(user_ctx, "user-12345");
397 collected_spans.push_back(user_span);
398
399 // Complete gateway span
400 std::this_thread::sleep_for(5ms);
401 gateway_span.end_time = std::chrono::system_clock::now();
402 gateway_span.calculate_duration();
403 gateway_span.status = trace_span::status_code::ok;
404 gateway_span.tags["http.status_code"] = "200";
405 collected_spans.insert(collected_spans.begin(), gateway_span);
406
407 // Display complete trace
408 display_trace_tree(collected_spans);
409
410 // Show baggage propagation
411 std::cout << "\n=== Baggage Propagation ===" << std::endl;
412 std::cout << "Baggage items propagated across all services:" << std::endl;
413 for (const auto& [key, value] : gateway_span.baggage) {
414 std::cout << " " << key << " = " << value << std::endl;
415 }
416
417 std::cout << "\n=== Example completed successfully ===" << std::endl;
418}
Simulated API Gateway service.
trace_span handle_request(const std::string &endpoint, const std::string &method)
Handle incoming HTTP request.
trace_context create_context(const trace_span &span)
Create trace context for propagation.
Simulated Authentication service.
trace_span verify_token(const trace_context &parent_ctx, const std::string &)
Verify user authentication.
Simulated Cache service.
trace_span cache_lookup(const trace_context &parent_ctx, const std::string &key)
Check cache for user data.
Simulated User service.
trace_span get_user_profile(const trace_context &parent_ctx, const std::string &user_id)
Fetch user profile.
void display_trace_tree(const std::vector< trace_span > &spans)
Display trace tree structure.
Trace context for propagation across service boundaries.
std::unordered_map< std::string, std::string > baggage

References kcenon::monitoring::trace_context::baggage, CacheService::cache_lookup(), ApiGatewayService::create_context(), display_trace_tree(), UserService::get_user_profile(), ApiGatewayService::handle_request(), kcenon::monitoring::trace_context::span_id, kcenon::monitoring::trace_context::trace_id, and AuthService::verify_token().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function: