Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
otlp_export_example.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, ๐Ÿ€โ˜€๐ŸŒ•๐ŸŒฅ ๐ŸŒŠ
3// See the LICENSE file in the project root for full license information.
4
18#include <iostream>
19#include <memory>
20#include <chrono>
21#include <thread>
22#include <vector>
23
26
27using namespace kcenon::monitoring;
28using namespace std::chrono_literals;
29
34 otlp_grpc_config config;
35
36 // Endpoint configuration
37 config.endpoint = "localhost:4317"; // Default OTLP gRPC port
38
39 // Timeout settings
40 config.timeout = 10s;
41 config.batch_timeout = 5s;
42
43 // Batch configuration for optimization
44 config.max_batch_size = 512; // Export up to 512 spans at once
45 config.max_queue_size = 2048; // Queue up to 2048 spans before dropping
46
47 // Retry configuration with exponential backoff
48 config.max_retry_attempts = 3;
49 config.initial_backoff = 100ms;
50 config.max_backoff = 10s;
51
52 // TLS configuration (optional)
53 config.use_tls = false;
54 // config.certificate_path = "/path/to/cert.pem";
55
56 // Service identification
57 config.service_name = "monitoring_system_example";
58 config.service_version = "2.0.0";
59
60 // Custom headers (e.g., for authentication)
61 config.headers["x-api-key"] = "example-key";
62 config.headers["x-environment"] = "development";
63
64 // Resource attributes (describe the service)
65 config.resource_attributes["service.namespace"] = "examples";
66 config.resource_attributes["service.instance.id"] = "instance-001";
67 config.resource_attributes["deployment.environment"] = "dev";
68 config.resource_attributes["host.name"] = "example-host";
69
70 return config;
71}
72
76std::vector<trace_span> create_sample_spans() {
77 std::vector<trace_span> spans;
78
79 auto now = std::chrono::system_clock::now();
80 std::string trace_id = "0123456789abcdef0123456789abcdef";
81
82 // Root span
83 trace_span root;
84 root.trace_id = trace_id;
85 root.span_id = "0123456789abcdef";
86 root.operation_name = "http_request";
87 root.service_name = "api_gateway";
88 root.start_time = now;
89 root.end_time = now + 150ms;
90 root.calculate_duration();
91 root.status = trace_span::status_code::ok;
92 root.tags["http.method"] = "GET";
93 root.tags["http.url"] = "/api/users";
94 root.tags["http.status_code"] = "200";
95 spans.push_back(root);
96
97 // Child span 1: database query
98 trace_span db_span;
99 db_span.trace_id = trace_id;
100 db_span.span_id = "fedcba9876543210";
101 db_span.parent_span_id = root.span_id;
102 db_span.operation_name = "db_query";
103 db_span.service_name = "user_service";
104 db_span.start_time = now + 10ms;
105 db_span.end_time = now + 100ms;
106 db_span.calculate_duration();
107 db_span.status = trace_span::status_code::ok;
108 db_span.tags["db.system"] = "postgresql";
109 db_span.tags["db.statement"] = "SELECT * FROM users";
110 db_span.tags["db.name"] = "user_db";
111 spans.push_back(db_span);
112
113 // Child span 2: cache lookup
114 trace_span cache_span;
115 cache_span.trace_id = trace_id;
116 cache_span.span_id = "1234567890abcdef";
117 cache_span.parent_span_id = root.span_id;
118 cache_span.operation_name = "cache_get";
119 cache_span.service_name = "cache_service";
120 cache_span.start_time = now + 5ms;
121 cache_span.end_time = now + 8ms;
122 cache_span.calculate_duration();
123 cache_span.status = trace_span::status_code::ok;
124 cache_span.tags["cache.key"] = "user:123";
125 cache_span.tags["cache.hit"] = "false";
126 spans.push_back(cache_span);
127
128 return spans;
129}
130
135 std::cout << "=== OTLP Export Example ===" << std::endl;
136
137 try {
138 // Step 1: Create and validate configuration
139 std::cout << "\n1. Configuring OTLP exporter..." << std::endl;
140
141 auto config = create_otlp_config();
142 auto validation = config.validate();
143
144 if (validation.is_err()) {
145 std::cerr << " Configuration validation failed: "
146 << validation.error().message << std::endl;
147 return;
148 }
149
150 std::cout << " โœ“ Configuration validated" << std::endl;
151 std::cout << " Endpoint: " << config.endpoint << std::endl;
152 std::cout << " Service: " << config.service_name
153 << " v" << config.service_version << std::endl;
154 std::cout << " Max batch size: " << config.max_batch_size << std::endl;
155 std::cout << " Max retries: " << config.max_retry_attempts << std::endl;
156
157 // Step 2: Create exporter
158 std::cout << "\n2. Creating OTLP exporter..." << std::endl;
159
160 auto exporter = create_otlp_grpc_exporter(config);
161 std::cout << " โœ“ Exporter created" << std::endl;
162
163 // Step 3: Start exporter (connects to OTLP receiver)
164 std::cout << "\n3. Starting exporter..." << std::endl;
165
166 auto start_result = exporter->start();
167 if (start_result.is_err()) {
168 std::cerr << " โœ— Failed to start exporter: "
169 << start_result.error().message << std::endl;
170 std::cerr << " Note: Make sure an OTLP receiver is running on "
171 << config.endpoint << std::endl;
172 std::cerr << " You can use: docker run -p 4317:4317 otel/opentelemetry-collector"
173 << std::endl;
174 return;
175 }
176
177 std::cout << " โœ“ Exporter started and connected" << std::endl;
178
179 // Step 4: Create sample spans
180 std::cout << "\n4. Creating sample trace spans..." << std::endl;
181
182 auto spans = create_sample_spans();
183 std::cout << " โœ“ Created " << spans.size() << " spans" << std::endl;
184
185 for (const auto& span : spans) {
186 std::cout << " - " << span.operation_name
187 << " (duration: " << span.duration.count() << "ยตs)" << std::endl;
188 }
189
190 // Step 5: Export spans
191 std::cout << "\n5. Exporting spans..." << std::endl;
192
193 auto export_result = exporter->export_spans(spans);
194 if (export_result.is_ok()) {
195 std::cout << " โœ“ Export succeeded" << std::endl;
196 } else {
197 std::cerr << " โœ— Export failed: "
198 << export_result.error().message << std::endl;
199 }
200
201 // Step 6: Check exporter statistics
202 std::cout << "\n6. Exporter statistics:" << std::endl;
203
204 auto detailed_stats = exporter->get_detailed_stats();
205 std::cout << " Spans exported: " << detailed_stats.spans_exported << std::endl;
206 std::cout << " Spans dropped: " << detailed_stats.spans_dropped << std::endl;
207 std::cout << " Export failures: " << detailed_stats.export_failures << std::endl;
208 std::cout << " Retry attempts: " << detailed_stats.retries << std::endl;
209 std::cout << " Total export time: "
210 << detailed_stats.total_export_time.count() << "ยตs" << std::endl;
211
212 // Step 7: Flush and shutdown
213 std::cout << "\n7. Shutting down exporter..." << std::endl;
214
215 exporter->flush();
216 exporter->shutdown();
217 std::cout << " โœ“ Exporter shutdown complete" << std::endl;
218
219 std::cout << "\n=== Example completed successfully ===" << std::endl;
220
221 } catch (const std::exception& e) {
222 std::cerr << "Exception: " << e.what() << std::endl;
223 }
224}
225
230 std::cout << "\n=== Batch Export Optimization ===" << std::endl;
231
232 try {
233 // Configure for batch export
235 config.max_batch_size = 10; // Small batch for demonstration
236
237 auto exporter = create_otlp_grpc_exporter(config);
238 auto start_result = exporter->start();
239
240 if (start_result.is_err()) {
241 std::cerr << " Skipping batch demo (no OTLP receiver available)" << std::endl;
242 return;
243 }
244
245 std::cout << "\n1. Creating large batch of spans..." << std::endl;
246
247 // Create 25 spans (will be split into 3 batches of 10, 10, 5)
248 std::vector<trace_span> large_batch;
249 auto now = std::chrono::system_clock::now();
250
251 for (int i = 0; i < 25; ++i) {
252 trace_span span;
253 span.trace_id = "batch00000000000000000000000000" + std::to_string(i);
254 span.span_id = "span000000000000" + std::to_string(i);
255 span.operation_name = "batch_operation_" + std::to_string(i);
256 span.service_name = "batch_service";
257 span.start_time = now + std::chrono::milliseconds(i);
258 span.end_time = span.start_time + 10ms;
259 span.calculate_duration();
260 span.status = trace_span::status_code::ok;
261 large_batch.push_back(span);
262 }
263
264 std::cout << " Created " << large_batch.size() << " spans" << std::endl;
265 std::cout << " Batch size: " << config.max_batch_size << std::endl;
266
267 // Export in batch
268 std::cout << "\n2. Exporting batch..." << std::endl;
269 auto export_result = exporter->export_spans(large_batch);
270
271 if (export_result.is_ok()) {
272 std::cout << " โœ“ Batch export succeeded" << std::endl;
273 } else {
274 std::cerr << " โœ— Batch export failed: "
275 << export_result.error().message << std::endl;
276 }
277
278 // Show final statistics
279 auto stats = exporter->get_detailed_stats();
280 std::cout << "\n3. Final statistics:" << std::endl;
281 std::cout << " Total exported: " << stats.spans_exported << std::endl;
282 std::cout << " Batches sent: " << stats.batches_sent << std::endl;
283
284 exporter->shutdown();
285
286 } catch (const std::exception& e) {
287 std::cerr << "Exception: " << e.what() << std::endl;
288 }
289}
290
291int main() {
292 std::cout << "OpenTelemetry Protocol (OTLP) Export Example\n" << std::endl;
293
294 // Demonstrate basic OTLP export
296
297 std::cout << "\n" << std::string(60, '=') << "\n" << std::endl;
298
299 // Demonstrate batch export optimization
301
302 return 0;
303}
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.
int main()
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::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.
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::chrono::system_clock::time_point start_time