#include <iostream>
#include <memory>
#include <chrono>
#include <thread>
#include <vector>
using namespace std::chrono_literals;
config.
headers[
"x-api-key"] =
"example-key";
config.
headers[
"x-environment"] =
"development";
return config;
}
std::vector<trace_span> spans;
auto now = std::chrono::system_clock::now();
std::string trace_id = "0123456789abcdef0123456789abcdef";
root.
status = trace_span::status_code::ok;
root.
tags[
"http.method"] =
"GET";
root.
tags[
"http.url"] =
"/api/users";
root.
tags[
"http.status_code"] =
"200";
spans.push_back(root);
db_span.
span_id =
"fedcba9876543210";
db_span.
status = trace_span::status_code::ok;
db_span.
tags[
"db.system"] =
"postgresql";
db_span.
tags[
"db.statement"] =
"SELECT * FROM users";
db_span.
tags[
"db.name"] =
"user_db";
spans.push_back(db_span);
cache_span.
span_id =
"1234567890abcdef";
cache_span.
status = trace_span::status_code::ok;
cache_span.
tags[
"cache.key"] =
"user:123";
cache_span.
tags[
"cache.hit"] =
"false";
spans.push_back(cache_span);
return spans;
}
std::cout << "=== OTLP Export Example ===" << std::endl;
try {
std::cout << "\n1. Configuring OTLP exporter..." << std::endl;
auto validation = config.validate();
if (validation.is_err()) {
std::cerr << " Configuration validation failed: "
<< validation.error().message << std::endl;
return;
}
std::cout << " โ Configuration validated" << std::endl;
std::cout << " Endpoint: " << config.endpoint << std::endl;
std::cout << " Service: " << config.service_name
<< " v" << config.service_version << std::endl;
std::cout << " Max batch size: " << config.max_batch_size << std::endl;
std::cout << " Max retries: " << config.max_retry_attempts << std::endl;
std::cout << "\n2. Creating OTLP exporter..." << std::endl;
std::cout << " โ Exporter created" << std::endl;
std::cout << "\n3. Starting exporter..." << std::endl;
auto start_result = exporter->start();
if (start_result.is_err()) {
std::cerr << " โ Failed to start exporter: "
<< start_result.error().message << std::endl;
std::cerr << " Note: Make sure an OTLP receiver is running on "
<< config.endpoint << std::endl;
std::cerr << " You can use: docker run -p 4317:4317 otel/opentelemetry-collector"
<< std::endl;
return;
}
std::cout << " โ Exporter started and connected" << std::endl;
std::cout << "\n4. Creating sample trace spans..." << std::endl;
std::cout << " โ Created " << spans.size() << " spans" << std::endl;
for (const auto& span : spans) {
std::cout << " - " << span.operation_name
<< " (duration: " << span.duration.count() << "ยตs)" << std::endl;
}
std::cout << "\n5. Exporting spans..." << std::endl;
auto export_result = exporter->export_spans(spans);
if (export_result.is_ok()) {
std::cout << " โ Export succeeded" << std::endl;
} else {
std::cerr << " โ Export failed: "
<< export_result.error().message << std::endl;
}
std::cout << "\n6. Exporter statistics:" << std::endl;
auto detailed_stats = exporter->get_detailed_stats();
std::cout << " Spans exported: " << detailed_stats.spans_exported << std::endl;
std::cout << " Spans dropped: " << detailed_stats.spans_dropped << std::endl;
std::cout << " Export failures: " << detailed_stats.export_failures << std::endl;
std::cout << " Retry attempts: " << detailed_stats.retries << std::endl;
std::cout << " Total export time: "
<< detailed_stats.total_export_time.count() << "ยตs" << std::endl;
std::cout << "\n7. Shutting down exporter..." << std::endl;
exporter->flush();
exporter->shutdown();
std::cout << " โ Exporter shutdown complete" << std::endl;
std::cout << "\n=== Example completed successfully ===" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
}
std::cout << "\n=== Batch Export Optimization ===" << std::endl;
try {
auto start_result = exporter->start();
if (start_result.is_err()) {
std::cerr << " Skipping batch demo (no OTLP receiver available)" << std::endl;
return;
}
std::cout << "\n1. Creating large batch of spans..." << std::endl;
std::vector<trace_span> large_batch;
auto now = std::chrono::system_clock::now();
for (int i = 0; i < 25; ++i) {
span.
trace_id =
"batch00000000000000000000000000" + std::to_string(i);
span.
span_id =
"span000000000000" + std::to_string(i);
span.
start_time = now + std::chrono::milliseconds(i);
span.
status = trace_span::status_code::ok;
large_batch.push_back(span);
}
std::cout << " Created " << large_batch.size() << " spans" << std::endl;
std::cout << "\n2. Exporting batch..." << std::endl;
auto export_result = exporter->export_spans(large_batch);
if (export_result.is_ok()) {
std::cout << " โ Batch export succeeded" << std::endl;
} else {
std::cerr << " โ Batch export failed: "
<< export_result.error().message << std::endl;
}
auto stats = exporter->get_detailed_stats();
std::cout << "\n3. Final statistics:" << std::endl;
std::cout << " Total exported: " << stats.spans_exported << std::endl;
std::cout << " Batches sent: " << stats.batches_sent << std::endl;
exporter->shutdown();
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
}
std::cout << "OpenTelemetry Protocol (OTLP) Export Example\n" << std::endl;
std::cout << "\n" << std::string(60, '=') << "\n" << std::endl;
return 0;
}
Distributed tracing implementation for monitoring system.
std::unique_ptr< otlp_grpc_exporter > create_otlp_grpc_exporter(const std::string &endpoint="localhost:4317")
Create OTLP gRPC exporter with default configuration.
void demonstrate_batch_export()
Demonstrate batch export optimization.
std::vector< trace_span > create_sample_spans()
Create sample trace spans for export.
otlp_grpc_config create_otlp_config()
Configure OTLP exporter with custom settings.
void demonstrate_otlp_export()
Demonstrate OTLP export with error handling.
OTLP gRPC trace exporter implementation.
Configuration for OTLP gRPC exporter.
std::string service_version
Service version.
std::unordered_map< std::string, std::string > resource_attributes
Resource attributes.
std::string endpoint
OTLP receiver endpoint.
std::size_t max_retry_attempts
Maximum retry attempts.
std::chrono::milliseconds batch_timeout
Batch export timeout.
std::string service_name
Service name.
std::size_t max_queue_size
Maximum queued spans.
std::size_t max_batch_size
Maximum spans per batch.
std::chrono::milliseconds initial_backoff
Initial retry backoff.
std::chrono::milliseconds max_backoff
Maximum retry backoff.
std::chrono::milliseconds timeout
Request timeout.
std::unordered_map< std::string, std::string > headers
Custom headers.
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::chrono::system_clock::time_point end_time
std::string operation_name
std::chrono::system_clock::time_point start_time