@@ -176,141 +176,110 @@ int main() {
176176 profile->add_endpoint_count (" /api/products" , 200 );
177177 std::cout << " ✅ Added endpoint mappings and counts" << std::endl;
178178
179- // Check if we should export to Datadog or save to file
179+ // Create exporter based on environment variables
180180 const char * agent_url = std::getenv (" DD_AGENT_URL" );
181181 const char * api_key = std::getenv (" DD_API_KEY" );
182182
183- if (agent_url || api_key) {
184- // Export to Datadog
185- std::cout << " \n === Exporting to Datadog ===" << std::endl;
186-
187- // Create a cancellation token for the export
188- // In a real application, you could clone this and cancel from another thread
189- // Example: auto token_clone = cancel_token->clone_token(); token_clone->cancel();
190- auto cancel_token = new_cancellation_token ();
191-
192- try {
193- // Example: Create an additional file to attach (e.g., application metadata)
194- std::string app_metadata = R"( {
195- "app_version": "1.2.3",
196- "build_id": "abc123",
197- "profiling_mode": "continuous",
198- "sample_count": 100
199- })" ;
200- std::vector<uint8_t > metadata_bytes (app_metadata.begin (), app_metadata.end ());
201-
202- if (api_key) {
203- // Agentless mode - send directly to Datadog intake
204- const char * site = std::getenv (" DD_SITE" );
205- std::string dd_site = site ? site : " datadoghq.com" ;
206-
207- std::cout << " Creating agentless exporter (site: " << dd_site << " )..." << std::endl;
208- auto exporter = ProfileExporter::create_agentless_exporter (
209- " dd-trace-cpp" ,
210- " 1.0.0" ,
211- " native" ,
183+ std::cout << " \n === Creating Exporter ===" << std::endl;
184+
185+ // Create appropriate exporter based on configuration
186+ std::unique_ptr<rust::Box<ProfileExporter>> exporter;
187+ try {
188+ if (api_key) {
189+ // Agentless mode - send directly to Datadog intake
190+ const char * site = std::getenv (" DD_SITE" );
191+ std::string dd_site = site ? site : " datadoghq.com" ;
192+ std::cout << " Creating agentless exporter (site: " << dd_site << " )..." << std::endl;
193+ exporter = std::make_unique<rust::Box<ProfileExporter>>(
194+ ProfileExporter::create_agentless_exporter (
195+ " dd-trace-cpp" , " 1.0.0" , " native" ,
212196 {
213197 Tag{.key = " service" , .value = " profiling-example" },
214198 Tag{.key = " env" , .value = " dev" },
215199 Tag{.key = " example" , .value = " cxx" }
216200 },
217- dd_site.c_str (),
218- api_key,
219- 10000 // 10 second timeout (0 = use default)
220- );
221- std::cout << " ✅ Exporter created" << std::endl;
222-
223- std::cout << " Exporting profile to Datadog with additional metadata..." << std::endl;
224-
225- exporter->send_profile_with_cancellation (
226- *profile,
227- // Files to compress and attach
228- {AttachmentFile{
229- .name = " app_metadata.json" ,
230- .data = {metadata_bytes.data (), metadata_bytes.size ()}
231- }},
232- // Additional per-profile tags
233- {
234- Tag{.key = " export_id" , .value = " 12345" },
235- Tag{.key = " host" , .value = " example-host" }
236- },
237- // Process-level tags (comma-separated)
238- " language:cpp,profiler_version:1.0,runtime:native" ,
239- // Internal metadata (JSON string)
240- R"( {"profiler_version": "1.0", "custom_field": "demo"})" ,
241- // System info (JSON string)
242- R"( {"os": "macos", "arch": "arm64", "cores": 8})" ,
243- *cancel_token
244- );
245- std::cout << " ✅ Profile exported successfully!" << std::endl;
246- } else {
247- // Agent mode - send to local Datadog agent
248- std::cout << " Creating agent exporter (url: " << agent_url << " )..." << std::endl;
249- auto exporter = ProfileExporter::create_agent_exporter (
250- " dd-trace-cpp" ,
251- " 1.0.0" ,
252- " native" ,
201+ dd_site.c_str (), api_key, 10000
202+ )
203+ );
204+ } else if (agent_url) {
205+ // Agent mode - send to local Datadog agent
206+ std::cout << " Creating agent exporter (url: " << agent_url << " )..." << std::endl;
207+ exporter = std::make_unique<rust::Box<ProfileExporter>>(
208+ ProfileExporter::create_agent_exporter (
209+ " dd-trace-cpp" , " 1.0.0" , " native" ,
253210 {
254211 Tag{.key = " service" , .value = " profiling-example" },
255212 Tag{.key = " env" , .value = " dev" },
256213 Tag{.key = " example" , .value = " cxx" }
257214 },
258- agent_url,
259- 10000 // 10 second timeout (0 = use default)
260- );
261- std::cout << " ✅ Exporter created" << std::endl;
262-
263- std::cout << " Exporting profile to Datadog with additional metadata..." << std::endl;
264-
265- exporter->send_profile_with_cancellation (
266- *profile,
267- // Files to compress and attach
268- {AttachmentFile{
269- .name = " app_metadata.json" ,
270- .data = {metadata_bytes.data (), metadata_bytes.size ()}
271- }},
272- // Additional per-profile tags
215+ agent_url, 10000
216+ )
217+ );
218+ } else {
219+ // File mode - dump HTTP request for debugging/testing
220+ std::cout << " Creating file exporter (profile_dump.txt)..." << std::endl;
221+ exporter = std::make_unique<rust::Box<ProfileExporter>>(
222+ ProfileExporter::create_file_exporter (
223+ " dd-trace-cpp" , " 1.0.0" , " native" ,
273224 {
274- Tag{.key = " export_id" , .value = " 12345" },
275- Tag{.key = " host" , .value = " example-host" }
225+ Tag{.key = " service" , .value = " profiling-example" },
226+ Tag{.key = " env" , .value = " dev" },
227+ Tag{.key = " example" , .value = " cxx" }
276228 },
277- // Process-level tags (comma-separated)
278- " language:cpp,profiler_version:1.0,runtime:native" ,
279- // Internal metadata (JSON string)
280- R"( {"profiler_version": "1.0", "custom_field": "demo"})" ,
281- // System info (JSON string)
282- R"( {"os": "macos", "arch": "arm64", "cores": 8})" ,
283- *cancel_token
284- );
285- std::cout << " ✅ Profile exported successfully!" << std::endl;
286- }
287-
288- } catch (const std::exception& e) {
289- std::cerr << " ⚠️ Failed to export profile: " << e.what () << std::endl;
290- std::cerr << " Falling back to file export..." << std::endl;
291-
292- // Fall back to file export on error
293- auto serialized = profile->serialize_to_vec ();
294- std::ofstream out (" profile.pprof" , std::ios::binary);
295- out.write (reinterpret_cast <const char *>(serialized.data ()), serialized.size ());
296- out.close ();
297- std::cout << " ✅ Profile written to profile.pprof" << std::endl;
229+ " profile_dump.txt"
230+ )
231+ );
298232 }
299- } else {
300- // Save to file
301- std::cout << " \n === Saving to File ===" << std::endl;
302- std::cout << " Serializing profile..." << std::endl;
303- auto serialized = profile->serialize_to_vec ();
304- std::cout << " ✅ Profile serialized to " << serialized.size () << " bytes" << std::endl;
233+ std::cout << " ✅ Exporter created" << std::endl;
305234
306- std::ofstream out ( " profile.pprof " , std::ios::binary);
307- out. write ( reinterpret_cast < const char *>(serialized. data ()), serialized. size ());
308- out. close ();
309- std::cout << " ✅ Profile written to profile.pprof " << std::endl ;
235+ // Create a cancellation token for the export
236+ // In a real application, you could clone this and cancel from another thread
237+ // Example: auto token_clone = cancel_token->clone_token(); token_clone->cancel ();
238+ auto cancel_token = new_cancellation_token () ;
310239
311- std::cout << " \n ℹ️ To export to Datadog instead, set environment variables:" << std::endl;
312- std::cout << " Agent mode: DD_AGENT_URL=http://localhost:8126" << std::endl;
313- std::cout << " Agentless mode: DD_API_KEY=<your-api-key> [DD_SITE=datadoghq.com]" << std::endl;
240+ // Prepare metadata (same for all export modes)
241+ std::string app_metadata = R"( {
242+ "app_version": "1.2.3",
243+ "build_id": "abc123",
244+ "profiling_mode": "continuous",
245+ "sample_count": 100
246+ })" ;
247+ std::vector<uint8_t > metadata_bytes (app_metadata.begin (), app_metadata.end ());
248+
249+ // Export the profile (unified code path)
250+ std::cout << " Exporting profile with additional metadata..." << std::endl;
251+ (*exporter)->send_profile_with_cancellation (
252+ *profile,
253+ // Files to compress and attach
254+ {AttachmentFile{
255+ .name = " app_metadata.json" ,
256+ .data = {metadata_bytes.data (), metadata_bytes.size ()}
257+ }},
258+ // Additional per-profile tags
259+ {
260+ Tag{.key = " export_id" , .value = " 12345" },
261+ Tag{.key = " host" , .value = " example-host" }
262+ },
263+ // Process-level tags (comma-separated)
264+ " language:cpp,profiler_version:1.0,runtime:native" ,
265+ // Internal metadata (JSON string)
266+ R"( {"profiler_version": "1.0", "custom_field": "demo"})" ,
267+ // System info (JSON string)
268+ R"( {"os": "macos", "arch": "arm64", "cores": 8})" ,
269+ *cancel_token
270+ );
271+ std::cout << " ✅ Profile exported successfully!" << std::endl;
272+
273+ // Print mode-specific info
274+ if (!agent_url && !api_key) {
275+ std::cout << " ℹ️ HTTP request written to profile_dump.txt" << std::endl;
276+ std::cout << " ℹ️ Use the utils in libdd-profiling to parse the HTTP dump" << std::endl;
277+ std::cout << " \n ℹ️ To export to Datadog instead, set environment variables:" << std::endl;
278+ std::cout << " Agent mode: DD_AGENT_URL=http://localhost:8126" << std::endl;
279+ std::cout << " Agentless mode: DD_API_KEY=<your-api-key> [DD_SITE=datadoghq.com]" << std::endl;
280+ }
281+ } catch (const std::exception& e) {
282+ std::cerr << " ⚠️ Failed to export profile: " << e.what () << std::endl;
314283 }
315284
316285 std::cout << " \n ✅ Success!" << std::endl;
0 commit comments