29using namespace std::chrono_literals;
34 const std::string& parent_id,
49 std::cout <<
"\n[" <<
service_name_ <<
"] Processing " << method <<
" " << endpoint << std::endl;
57 span.
start_time = std::chrono::system_clock::now();
60 span.
tags[
"http.method"] = method;
61 span.
tags[
"http.url"] = endpoint;
62 span.
tags[
"http.target"] = endpoint;
63 span.
tags[
"component"] =
"http_server";
66 span.
baggage[
"user.id"] =
"user-12345";
67 span.
baggage[
"session.id"] =
"sess-67890";
68 span.
baggage[
"request.priority"] =
"high";
70 std::cout <<
" โ Created root span: " << span.
span_id << std::endl;
71 std::cout <<
" Trace ID: " << span.
trace_id << std::endl;
72 std::cout <<
" Baggage: user.id=" << span.
baggage[
"user.id"] << std::endl;
87 std::cout <<
" โ Context for propagation: "
97 for (
int i = 0; i < 32; ++i) {
98 id +=
"0123456789abcdef"[rand() % 16];
106 for (
int i = 0; i < 16; ++i) {
107 id +=
"0123456789abcdef"[rand() % 16];
125 std::cout <<
"\n[" <<
service_name_ <<
"] Verifying authentication token" << std::endl;
135 span.
start_time = std::chrono::system_clock::now();
141 span.
tags[
"auth.token_type"] =
"bearer";
142 span.
tags[
"auth.method"] =
"jwt";
144 std::cout <<
" โ Created child span: " << span.
span_id << std::endl;
145 std::cout <<
" Parent span: " << span.
parent_span_id << std::endl;
146 std::cout <<
" Inherited baggage: user.id=" << span.
baggage[
"user.id"] << std::endl;
149 std::this_thread::sleep_for(5ms);
151 span.
end_time = std::chrono::system_clock::now();
153 span.
status = trace_span::status_code::ok;
154 span.
tags[
"auth.result"] =
"success";
156 std::cout <<
" โ Authentication successful (duration: "
157 << span.
duration.count() <<
"ยตs)" << std::endl;
165 for (
int i = 0; i < 16; ++i) {
166 id +=
"0123456789abcdef"[rand() % 16];
184 std::cout <<
"\n[" <<
service_name_ <<
"] Fetching user profile" << std::endl;
185 std::cout <<
" User ID from baggage: " << parent_ctx.
baggage.at(
"user.id") << std::endl;
194 span.
start_time = std::chrono::system_clock::now();
200 span.
tags[
"db.system"] =
"postgresql";
201 span.
tags[
"db.name"] =
"users_db";
202 span.
tags[
"db.statement"] =
"SELECT * FROM users WHERE id = ?";
203 span.
tags[
"db.user_id"] = user_id;
205 std::cout <<
" โ Created child span: " << span.
span_id << std::endl;
206 std::cout <<
" Parent span: " << span.
parent_span_id << std::endl;
209 std::this_thread::sleep_for(15ms);
211 span.
end_time = std::chrono::system_clock::now();
213 span.
status = trace_span::status_code::ok;
214 span.
tags[
"db.rows_returned"] =
"1";
216 std::cout <<
" โ User profile fetched (duration: "
217 << span.
duration.count() <<
"ยตs)" << std::endl;
225 for (
int i = 0; i < 16; ++i) {
226 id +=
"0123456789abcdef"[rand() % 16];
244 std::cout <<
"\n[" <<
service_name_ <<
"] Cache lookup" << std::endl;
253 span.
start_time = std::chrono::system_clock::now();
259 span.
tags[
"cache.type"] =
"redis";
260 span.
tags[
"cache.key"] = key;
262 std::cout <<
" โ Created child span: " << span.
span_id << std::endl;
265 std::this_thread::sleep_for(2ms);
267 span.
end_time = std::chrono::system_clock::now();
269 span.
status = trace_span::status_code::ok;
270 span.
tags[
"cache.hit"] =
"false";
272 std::cout <<
" โ Cache miss (duration: "
273 << span.
duration.count() <<
"ยตs)" << std::endl;
281 for (
int i = 0; i < 16; ++i) {
282 id +=
"0123456789abcdef"[rand() % 16];
292 std::cout <<
"\n=== Trace Tree Structure ===" << std::endl;
296 for (
const auto& span : spans) {
297 if (span.parent_span_id.empty()) {
304 std::cout <<
"No root span found" << std::endl;
308 std::cout <<
"\nTrace ID: " << root->
trace_id <<
"\n" << std::endl;
316 std::cout <<
"\n=== Total Spans: " << spans.size() <<
" ===" << std::endl;
317 std::cout <<
"Total trace duration: " << root->
duration.count() <<
"ยตs" << std::endl;
324 std::string indent(depth * 2,
' ');
325 std::string prefix = depth == 0 ?
"โโ" :
"โโ";
327 std::cout << indent << prefix <<
" [" << span.
service_name <<
"] "
329 std::cout << indent <<
" Span ID: " << span.
span_id << std::endl;
330 std::cout << indent <<
" Duration: " << span.
duration.count() <<
"ยตs" << std::endl;
332 if (!span.
tags.empty()) {
333 std::cout << indent <<
" Tags:";
335 for (
const auto& [key, value] : span.
tags) {
337 std::cout <<
" " << key <<
"=" << value;
340 if (span.
tags.size() > 3) {
341 std::cout <<
" +" << (span.
tags.size() - 3) <<
" more";
343 std::cout << std::endl;
351 const std::string& parent_id,
353 for (
const auto& span : spans) {
354 if (span.parent_span_id == parent_id) {
365 std::cout <<
"=== Multi-Service Distributed Tracing Example ===" << std::endl;
367 std::vector<trace_span> collected_spans;
370 std::cout <<
"\n--- Step 1: API Gateway ---" << std::endl;
372 auto gateway_span = gateway.
handle_request(
"/api/user/profile",
"GET");
376 std::cout <<
"\n--- Step 2: Cache Lookup ---" << std::endl;
378 auto cache_span = cache.
cache_lookup(gateway_ctx,
"user:user-12345");
379 collected_spans.push_back(cache_span);
382 std::cout <<
"\n--- Step 3: Authentication ---" << std::endl;
384 auto auth_span = auth.
verify_token(gateway_ctx,
"eyJhbGc...");
385 collected_spans.push_back(auth_span);
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;
394 std::cout <<
"\n--- Step 4: User Profile Service ---" << std::endl;
397 collected_spans.push_back(user_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);
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;
417 std::cout <<
"\n=== Example completed successfully ===" << std::endl;
421 std::cout <<
"Multi-Service Distributed Tracing Example\n" << std::endl;
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;
Simulated API Gateway service.
static std::string generate_trace_id()
trace_span handle_request(const std::string &endpoint, const std::string &method)
Handle incoming HTTP request.
std::string service_name_
trace_context create_context(const trace_span &span)
Create trace context for propagation.
static std::string generate_span_id()
Simulated Authentication service.
trace_span verify_token(const trace_context &parent_ctx, const std::string &)
Verify user authentication.
static std::string generate_span_id()
std::string service_name_
std::string service_name_
static std::string generate_span_id()
trace_span cache_lookup(const trace_context &parent_ctx, const std::string &key)
Check cache for user data.
std::string service_name_
trace_span get_user_profile(const trace_context &parent_ctx, const std::string &user_id)
Fetch user profile.
static std::string generate_span_id()
Distributed tracing implementation for monitoring system.
void display_children(const std::vector< trace_span > &spans, const std::string &parent_id, int depth)
Display children recursively.
void simulate_multi_service_request()
Simulate complete multi-service request flow.
void display_trace_tree(const std::vector< trace_span > &spans)
Display trace tree structure.
void display_span(const trace_span &span, int depth)
Display single span.
Trace context for propagation across service boundaries.
std::string to_w3c_traceparent() const
Serialize to W3C Trace Context format.
std::unordered_map< std::string, std::string > baggage
Trace span representing a unit of work in distributed tracing.
std::string parent_span_id
void calculate_duration()
Calculate duration if span is finished.
std::unordered_map< std::string, std::string > tags
std::unordered_map< std::string, std::string > baggage
std::chrono::system_clock::time_point end_time
std::chrono::microseconds duration
std::string operation_name
std::chrono::system_clock::time_point start_time