@@ -32,7 +32,7 @@ static bool already_done = false;
32
32
# define OS_PATH "linux-gnu/"
33
33
#endif
34
34
35
- static void ddloader_telemetryf (telemetry_reason reason , const char * format , ...);
35
+ static void ddloader_telemetryf (telemetry_reason reason , const char * error , const char * format , ...);
36
36
37
37
static char * ddtrace_pre_load_hook (void ) {
38
38
char * libddtrace_php ;
@@ -218,7 +218,11 @@ void ddloader_logf(log_level level, const char *format, ...) {
218
218
va_end (va );
219
219
}
220
220
221
- static void ddloader_telemetryf (telemetry_reason reason , const char * format , ...) {
221
+ /**
222
+ * @param error The c-string this is pointing to must not exceed 150 bytes
223
+ */
224
+ static void ddloader_telemetryf (telemetry_reason reason , const char * error , const char * format , ...) {
225
+ log_level level = ERROR ;
222
226
switch (reason ) {
223
227
case REASON_ERROR :
224
228
LOG (ERROR , "Error during instrumentation of application. Aborting." );
@@ -229,13 +233,17 @@ static void ddloader_telemetryf(telemetry_reason reason, const char *format, ...
229
233
case REASON_INCOMPATIBLE_RUNTIME :
230
234
LOG (ERROR , "Aborting application instrumentation due to an incompatible runtime" );
231
235
break ;
236
+ case REASON_COMPLETE :
237
+ case REASON_ALREADY_LOADED :
238
+ level = INFO ;
239
+ break ;
232
240
default :
233
241
break ;
234
242
}
235
243
236
244
va_list va ;
237
245
va_start (va , format );
238
- ddloader_logv (reason == REASON_COMPLETE ? INFO : ERROR , format , va );
246
+ ddloader_logv (level , format , va );
239
247
va_end (va );
240
248
241
249
if (!telemetry_forwarder_path ) {
@@ -257,13 +265,15 @@ static void ddloader_telemetryf(telemetry_reason reason, const char *format, ...
257
265
return ; // parent
258
266
}
259
267
260
- char * points = "" ;
268
+ char points_buf [256 ] = {0 };
269
+ char * points = points_buf ;
261
270
switch (reason ) {
262
271
case REASON_ERROR :
263
- points =
264
- "\
265
- {\"name\": \"library_entrypoint.error\"}, \"tags\": [\"error_type:NA\"]}\
266
- " ;
272
+ snprintf (points_buf , sizeof (points_buf ), "\
273
+ {\"name\": \"library_entrypoint.error\", \"tags\": [\"error_type:%s\"]}\
274
+ " ,
275
+ error ? error : "NA"
276
+ );
267
277
break ;
268
278
269
279
case REASON_EOL_RUNTIME :
@@ -282,6 +292,13 @@ static void ddloader_telemetryf(telemetry_reason reason, const char *format, ...
282
292
" ;
283
293
break ;
284
294
295
+ case REASON_ALREADY_LOADED :
296
+ points =
297
+ "\
298
+ {\"name\": \"library_entrypoint.abort\", \"tags\": [\"reason:already_loaded\"]}\
299
+ " ;
300
+ break ;
301
+
285
302
case REASON_COMPLETE :
286
303
if (injection_forced ) {
287
304
points =
@@ -417,13 +434,13 @@ static PHP_MINIT_FUNCTION(ddloader_injected_extension_minit) {
417
434
}
418
435
}
419
436
if (!config ) {
420
- TELEMETRY (REASON_ERROR , "Unable to find the configuration for the injected extension. Something went wrong" );
437
+ TELEMETRY (REASON_ERROR , "ext_not_found" , " Unable to find the configuration for the injected extension. Something went wrong" );
421
438
return SUCCESS ;
422
439
}
423
440
424
441
zend_module_entry * module = ddloader_zend_hash_str_find_ptr (php_api_no , & module_registry , config -> ext_name , strlen (config -> ext_name ));
425
442
if (module ) {
426
- LOG ( INFO , "Extension '%s' is already loaded, unregister the injected extension" , config -> ext_name );
443
+ TELEMETRY ( REASON_ALREADY_LOADED , NULL , "Extension '%s' is already loaded, unregister the injected extension" , config -> ext_name );
427
444
ddloader_unregister_module (config -> tmp_name );
428
445
429
446
return SUCCESS ;
@@ -433,7 +450,7 @@ static PHP_MINIT_FUNCTION(ddloader_injected_extension_minit) {
433
450
434
451
// Normally done by zend_startup_module_ex, but we temporarily replaced these to skip potential errors. Check it ourselves here.
435
452
if (!ddloader_check_deps (config -> orig_module_deps )) {
436
- TELEMETRY (REASON_INCOMPATIBLE_RUNTIME , "Extension '%s' dependencies are not met, unregister the injected extension" , config -> ext_name );
453
+ TELEMETRY (REASON_INCOMPATIBLE_RUNTIME , NULL , "Extension '%s' dependencies are not met, unregister the injected extension" , config -> ext_name );
437
454
ddloader_unregister_module (config -> tmp_name );
438
455
439
456
return SUCCESS ;
@@ -455,7 +472,7 @@ static PHP_MINIT_FUNCTION(ddloader_injected_extension_minit) {
455
472
456
473
module = ddloader_zend_hash_str_find_ptr (php_api_no , & module_registry , config -> ext_name , strlen (config -> ext_name ));
457
474
if (!module ) {
458
- TELEMETRY (REASON_ERROR , "Extension '%s' not found after renaming. Something wrong happened" , config -> ext_name );
475
+ TELEMETRY (REASON_ERROR , "renamed_ext_not_found" , " Extension '%s' not found after renaming. Something wrong happened" , config -> ext_name );
459
476
return SUCCESS ;
460
477
}
461
478
@@ -465,7 +482,7 @@ static PHP_MINIT_FUNCTION(ddloader_injected_extension_minit) {
465
482
module -> deps = config -> orig_module_deps ;
466
483
module -> functions = config -> orig_module_functions ;
467
484
if (module -> functions && zend_register_functions (NULL , module -> functions , NULL , module -> type ) == FAILURE ) {
468
- TELEMETRY (REASON_ERROR , "Unable to register extension's functions" );
485
+ TELEMETRY (REASON_ERROR , "cannot_register_functions" , " Unable to register extension's functions" );
469
486
return SUCCESS ;
470
487
}
471
488
@@ -475,9 +492,9 @@ static PHP_MINIT_FUNCTION(ddloader_injected_extension_minit) {
475
492
476
493
zend_result ret = module -> module_startup_func (INIT_FUNC_ARGS_PASSTHRU );
477
494
if (ret == FAILURE ) {
478
- TELEMETRY (REASON_ERROR , "'%s' MINIT function failed" , config -> ext_name );
495
+ TELEMETRY (REASON_ERROR , "error_minit" , " '%s' MINIT function failed" , config -> ext_name );
479
496
} else {
480
- TELEMETRY (REASON_COMPLETE , "Application instrumentation bootstrapping complete ('%s')" , config -> ext_name )
497
+ TELEMETRY (REASON_COMPLETE , NULL , "Application instrumentation bootstrapping complete ('%s')" , config -> ext_name )
481
498
}
482
499
483
500
return ret ;
@@ -486,7 +503,12 @@ static PHP_MINIT_FUNCTION(ddloader_injected_extension_minit) {
486
503
static int ddloader_load_extension (unsigned int php_api_no , char * module_build_id , bool is_zts , bool is_debug , injected_ext * config ) {
487
504
char * ext_path = ddloader_find_ext_path (config -> ext_dir , config -> ext_name , php_api_no , is_zts , is_debug );
488
505
if (!ext_path ) {
489
- TELEMETRY (REASON_INCOMPATIBLE_RUNTIME , "'%s' extension file not found" , config -> ext_name );
506
+ if (is_debug ) {
507
+ TELEMETRY (REASON_INCOMPATIBLE_RUNTIME , NULL , "'%s' extension file not found (debug build)" , config -> ext_name );
508
+ } else {
509
+ TELEMETRY (REASON_ERROR , "so_not_found" , "'%s' extension file not found" , config -> ext_name );
510
+ }
511
+
490
512
return SUCCESS ;
491
513
}
492
514
@@ -499,32 +521,32 @@ static int ddloader_load_extension(unsigned int php_api_no, char *module_build_i
499
521
LOG (INFO , "Running '%s' pre-load hook" , config -> ext_name );
500
522
char * err = config -> pre_load_hook ();
501
523
if (err ) {
502
- TELEMETRY (REASON_ERROR , "An error occurred while running '%s' pre-load hook: %s" , config -> ext_name , err );
524
+ TELEMETRY (REASON_ERROR , "error_ext_pre_load" , " An error occurred while running '%s' pre-load hook: %s" , config -> ext_name , err );
503
525
goto abort ;
504
526
}
505
527
}
506
528
507
529
void * handle = DL_LOAD (ext_path );
508
530
if (!handle ) {
509
- TELEMETRY (REASON_ERROR , "Cannot load '%s' extension file: %s" , config -> ext_name , dlerror ());
531
+ TELEMETRY (REASON_ERROR , "cannot_load_file" , " Cannot load '%s' extension file: %s" , config -> ext_name , dlerror ());
510
532
goto abort ;
511
533
}
512
534
513
535
zend_module_entry * (* get_module )(void ) = (zend_module_entry * (* )(void )) ddloader_dl_fetch_symbol (handle , "_get_module" );
514
536
if (!get_module ) {
515
- TELEMETRY (REASON_ERROR , "Cannot fetch '%s' module entry" , config -> ext_name );
537
+ TELEMETRY (REASON_ERROR , "cannot_fetch_mod_entry" , " Cannot fetch '%s' module entry" , config -> ext_name );
516
538
goto abort_and_unload ;
517
539
}
518
540
519
541
zend_module_entry * module_entry = get_module ();
520
542
521
543
if (module_entry -> zend_api != php_api_no ) {
522
- TELEMETRY (REASON_ERROR , "'%s' API number mismatch between module (%d) and runtime (%d)" , config -> ext_name , module_entry -> zend_api ,
544
+ TELEMETRY (REASON_ERROR , "api_mismatch" , " '%s' API number mismatch between module (%d) and runtime (%d)" , config -> ext_name , module_entry -> zend_api ,
523
545
php_api_no );
524
546
goto abort_and_unload ;
525
547
}
526
548
if (strcmp (module_entry -> build_id , module_build_id )) {
527
- TELEMETRY (REASON_ERROR , "'%s' Build ID mismatch between module (%s) and runtime (%s)" , config -> ext_name , module_entry -> build_id ,
549
+ TELEMETRY (REASON_ERROR , "build_id_mismatch" , " '%s' Build ID mismatch between module (%s) and runtime (%s)" , config -> ext_name , module_entry -> build_id ,
528
550
module_build_id );
529
551
goto abort_and_unload ;
530
552
}
@@ -554,7 +576,7 @@ static int ddloader_load_extension(unsigned int php_api_no, char *module_build_i
554
576
ddloader_restore_zend_error_cb ();
555
577
556
578
if (module_entry == NULL ) {
557
- TELEMETRY (REASON_ERROR , "Cannot register '%s' module" , config -> ext_name );
579
+ TELEMETRY (REASON_ERROR , "cannot_register_ext" , " Cannot register '%s' module" , config -> ext_name );
558
580
goto abort_and_unload ;
559
581
}
560
582
@@ -660,7 +682,7 @@ static int ddloader_api_no_check(int api_no) {
660
682
}
661
683
662
684
if (!package_path ) {
663
- TELEMETRY (REASON_ERROR , "DD_LOADER_PACKAGE_PATH environment variable is not set" );
685
+ TELEMETRY (REASON_ERROR , "path_env_var_not_set" , " DD_LOADER_PACKAGE_PATH environment variable is not set" );
664
686
return SUCCESS ;
665
687
}
666
688
@@ -680,7 +702,7 @@ static int ddloader_api_no_check(int api_no) {
680
702
default :
681
703
if (!force_load || api_no < 320151012 ) {
682
704
telemetry_reason reason = api_no < 320151012 ? REASON_EOL_RUNTIME : REASON_INCOMPATIBLE_RUNTIME ;
683
- TELEMETRY (reason , "Found incompatible runtime (api no: %d). Supported runtimes: PHP 7.0 to 8.3" , api_no );
705
+ TELEMETRY (reason , NULL , "Found incompatible runtime (api no: %d). Supported runtimes: PHP 7.0 to 8.3" , api_no );
684
706
685
707
// If we return FAILURE, this Zend extension would be unload, BUT it would produce an error
686
708
// similar to "The Zend Engine API version 220100525 which is installed, is newer."
@@ -720,7 +742,7 @@ static int ddloader_build_id_check(const char *build_id) {
720
742
721
743
// Guardrail
722
744
if (* module_build_id == '\0' ) {
723
- TELEMETRY (REASON_ERROR , "Invalid build id" );
745
+ TELEMETRY (REASON_ERROR , "invalid_build_id" , " Invalid build id" );
724
746
return SUCCESS ;
725
747
}
726
748
0 commit comments