diff --git a/Makefile b/Makefile index 25618a0b35c..922218229ee 100644 --- a/Makefile +++ b/Makefile @@ -446,7 +446,7 @@ generate_cbindgen: cbindgen_binary # Regenerate components-rs/ddtrace.h componen mkdir -pv "$(BUILD_DIR)"; \ export CARGO_TARGET_DIR="$(BUILD_DIR)/target"; \ fi; \ - cargo run -p tools -- $(PROJECT_ROOT)/components-rs/common.h $(PROJECT_ROOT)/components-rs/ddtrace.h $(PROJECT_ROOT)/components-rs/live-debugger.h $(PROJECT_ROOT)/components-rs/telemetry.h $(PROJECT_ROOT)/components-rs/sidecar.h $(PROJECT_ROOT)/components-rs/crashtracker.h $(PROJECT_ROOT)/components-rs/library-config.h \ + cargo run -p tools --bin dedup_headers -- $(PROJECT_ROOT)/components-rs/common.h $(PROJECT_ROOT)/components-rs/ddtrace.h $(PROJECT_ROOT)/components-rs/live-debugger.h $(PROJECT_ROOT)/components-rs/telemetry.h $(PROJECT_ROOT)/components-rs/sidecar.h $(PROJECT_ROOT)/components-rs/crashtracker.h $(PROJECT_ROOT)/components-rs/library-config.h \ ) cbindgen_binary: diff --git a/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/TelemetryHelpers.groovy b/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/TelemetryHelpers.groovy index 85f768bab08..eaacfa2bd68 100644 --- a/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/TelemetryHelpers.groovy +++ b/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/TelemetryHelpers.groovy @@ -73,6 +73,10 @@ class TelemetryHelpers { static names = ['logs'] List logs + Logs(Map m) { + this(m.logs as List) + } + Logs(List m) { logs = m.collect { new Log(it as Map) } } diff --git a/components-rs/common.h b/components-rs/common.h index 395882afdf4..e0c4853efb2 100644 --- a/components-rs/common.h +++ b/components-rs/common.h @@ -1472,6 +1472,10 @@ typedef struct ddog_crasht_OsInfo { typedef struct ddog_crasht_ProcInfo { uint32_t pid; + /** + * Optional crashing thread id; 0 means unset. + */ + uint32_t tid; } ddog_crasht_ProcInfo; typedef struct ddog_crasht_SigInfo { diff --git a/components-rs/crashtracker.h b/components-rs/crashtracker.h index 96ed333d622..7abb5ae38a5 100644 --- a/components-rs/crashtracker.h +++ b/components-rs/crashtracker.h @@ -646,6 +646,16 @@ DDOG_CHECK_RETURN struct ddog_VoidResult ddog_crasht_CrashInfoBuilder_with_message(struct ddog_crasht_Handle_CrashInfoBuilder *builder, ddog_CharSlice message); +/** + * # Safety + * The `builder` can be null, but if non-null it must point to a Builder made by this module, + * which has not previously been dropped. + * The CharSlice must be valid. + */ +DDOG_CHECK_RETURN +struct ddog_VoidResult ddog_crasht_CrashInfoBuilder_with_thread_name(struct ddog_crasht_Handle_CrashInfoBuilder *builder, + ddog_CharSlice thread_name); + /** * # Safety * The `builder` can be null, but if non-null it must point to a Builder made by this module, diff --git a/components-rs/live-debugger.h b/components-rs/live-debugger.h index 550a6093f4d..9c6f404b9fa 100644 --- a/components-rs/live-debugger.h +++ b/components-rs/live-debugger.h @@ -58,7 +58,8 @@ struct ddog_DebuggerPayload *ddog_create_log_probe_snapshot(const struct ddog_Pr const ddog_CharSlice *message, ddog_CharSlice service, ddog_CharSlice language, - uint64_t timestamp); + uint64_t timestamp, + ddog_CharSlice process_tags); void ddog_update_payload_message(struct ddog_DebuggerPayload *payload, ddog_CharSlice message); diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 9a54c4f157c..80aa55013fb 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -241,12 +241,12 @@ ddog_MaybeError ddog_sidecar_enqueue_telemetry_point(ddog_CharSlice session_id_f * Pointers must be valid, strings must be null-terminated if not null. */ ddog_MaybeError ddog_sidecar_enqueue_telemetry_metric(ddog_CharSlice session_id_ffi, - ddog_CharSlice runtime_id_ffi, - ddog_CharSlice service_name_ffi, - ddog_CharSlice env_name_ffi, - ddog_CharSlice metric_name_ffi, - enum ddog_MetricType metric_type, - enum ddog_MetricNamespace metric_namespace); + ddog_CharSlice runtime_id_ffi, + ddog_CharSlice service_name_ffi, + ddog_CharSlice env_name_ffi, + ddog_CharSlice metric_name_ffi, + enum ddog_MetricType metric_type, + enum ddog_MetricNamespace metric_namespace); /** * Sends a trace to the sidecar via shared memory. diff --git a/ext/live_debugger.c b/ext/live_debugger.c index 72907c49a44..b2f4a912be0 100644 --- a/ext/live_debugger.c +++ b/ext/live_debugger.c @@ -13,6 +13,7 @@ #include "zend_hrtime.h" #include "components-rs/common.h" #include "zend_generators.h" +#include "process_tags.h" ZEND_EXTERN_MODULE_GLOBALS(ddtrace); @@ -391,7 +392,13 @@ static void dd_log_probe_ensure_payload(dd_log_probe_dyn *dyn, dd_log_probe_def ddog_update_payload_message(dyn->payload, *msg); } else { dyn->service = ddtrace_active_service_name(); - dyn->payload = ddog_create_log_probe_snapshot(&def->parent.probe, msg, dd_zend_string_to_CharSlice(dyn->service), DDOG_CHARSLICE_C("php"), ddtrace_nanoseconds_realtime() / 1000000); + dyn->payload = ddog_create_log_probe_snapshot( + &def->parent.probe, + msg, + dd_zend_string_to_CharSlice(dyn->service), + DDOG_CHARSLICE_C("php"), + ddtrace_nanoseconds_realtime() / 1000000, + dd_zend_string_to_CharSlice(ddtrace_process_tags_get_serialized())); } } diff --git a/ext/process_tags.c b/ext/process_tags.c index e4811bc1531..9c6a06a7ecc 100644 --- a/ext/process_tags.c +++ b/ext/process_tags.c @@ -193,7 +193,7 @@ static void serialize_process_tags(void) { } zend_string *ddtrace_process_tags_get_serialized(void) { - return (ddtrace_process_tags_enabled() && process_tags.serialized) ? process_tags.serialized : NULL; + return (ddtrace_process_tags_enabled() && process_tags.serialized) ? process_tags.serialized : ZSTR_EMPTY_ALLOC(); } bool ddtrace_process_tags_enabled(void){ diff --git a/ext/serializer.c b/ext/serializer.c index 4f7f57b1a6b..108b458a080 100644 --- a/ext/serializer.c +++ b/ext/serializer.c @@ -1613,7 +1613,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo if (is_first_span) { zend_string *process_tags = ddtrace_process_tags_get_serialized(); - if (process_tags) { + if (ZSTR_LEN(process_tags)) { ddog_add_str_span_meta_zstr(rust_span, "_dd.process_tags", process_tags); } } diff --git a/libdatadog b/libdatadog index 534d009c5ba..f483c69f73a 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 534d009c5ba3e40d8badf9c0417837325c91a686 +Subproject commit f483c69f73acb72e688623cc634cf9f204d7cc14 diff --git a/tests/ext/crashtracker_jit_tags.phpt b/tests/ext/crashtracker_jit_tags.phpt index 41babc46824..7c90b6576ed 100644 --- a/tests/ext/crashtracker_jit_tags.phpt +++ b/tests/ext/crashtracker_jit_tags.phpt @@ -42,20 +42,24 @@ $rr->waitForRequest(function ($request) { return false; } $body = json_decode($request["body"], true); - if ($body["request_type"] != "logs" || !isset($body["payload"][0]["message"])) { - return false; - } + $batch = $body["request_type"] == "message-batch" ? $body["payload"] : [$body]; - foreach ($body["payload"] as $payload) { - $payload["message"] = json_decode($payload["message"], true); - if (!isset($payload["message"]["metadata"])) { - break; + foreach ($batch as $json) { + if ($json["request_type"] != "logs" || !isset($json["payload"]["logs"])) { + continue; } - $output = json_encode($payload, JSON_PRETTY_PRINT); - echo $output; + foreach ($json["payload"]["logs"] as $payload) { + $payload["message"] = json_decode($payload["message"], true); + if (!isset($payload["message"]["metadata"])) { + break; + } - return true; + $output = json_encode($payload, JSON_PRETTY_PRINT); + echo $output; + + return true; + } } return false; diff --git a/tests/ext/crashtracker_segfault.phpt b/tests/ext/crashtracker_segfault.phpt index 5ee381170a6..0b69c8968ab 100644 --- a/tests/ext/crashtracker_segfault.phpt +++ b/tests/ext/crashtracker_segfault.phpt @@ -36,23 +36,27 @@ $rr->waitForRequest(function ($request) { return false; } $body = json_decode($request["body"], true); - if ($body["request_type"] != "logs" || !isset($body["payload"][0]["message"])) { - return false; - } + $batch = $body["request_type"] == "message-batch" ? $body["payload"] : [$body]; - foreach ($body["payload"] as $payload) { - $payload["message"] = json_decode($payload["message"], true); - if (!isset($payload["message"]["metadata"])) { - break; - } - if (($payload["message"]["kind"] ?? "") == "Crash ping") { + foreach ($batch as $json) { + if ($json["request_type"] != "logs" || !isset($json["payload"]["logs"])) { continue; } - $output = json_encode($payload, JSON_PRETTY_PRINT); - echo $output; + foreach ($json["payload"]["logs"] as $payload) { + $payload["message"] = json_decode($payload["message"], true); + if (!isset($payload["message"]["metadata"])) { + break; + } + if (($payload["message"]["kind"] ?? "") == "Crash ping") { + continue; + } + + $output = json_encode($payload, JSON_PRETTY_PRINT); + echo $output; - return true; + return true; + } } return false; diff --git a/tests/ext/crashtracker_segfault_disabled.phpt b/tests/ext/crashtracker_segfault_disabled.phpt index bb73bfdf5c4..654a966632b 100644 --- a/tests/ext/crashtracker_segfault_disabled.phpt +++ b/tests/ext/crashtracker_segfault_disabled.phpt @@ -35,17 +35,24 @@ $rr->waitForRequest(function ($request) { return false; } $body = json_decode($request["body"], true); - if ($body["request_type"] != "logs" || !isset($body["payload"][0]["message"])) { - return false; - } + $batch = $body["request_type"] == "message-batch" ? $body["payload"] : [$body]; + + foreach ($batch as $json) { + if ($json["request_type"] != "logs" || !isset($json["payload"]["logs"])) { + continue; + } - $payload = $body["payload"][0]; - $payload["message"] = json_decode($payload["message"], true); - $output = json_encode($payload, JSON_PRETTY_PRINT); + foreach ($json["payload"]["logs"] as $payload) { + $payload["message"] = json_decode($payload["message"], true); + $output = json_encode($payload, JSON_PRETTY_PRINT); - echo $output; + echo $output; + + return true; + } + } - return true; + return false; }); ?> diff --git a/tests/ext/crashtracker_segfault_windows.phpt b/tests/ext/crashtracker_segfault_windows.phpt index 29b611106d7..0e3a9113043 100644 --- a/tests/ext/crashtracker_segfault_windows.phpt +++ b/tests/ext/crashtracker_segfault_windows.phpt @@ -49,20 +49,24 @@ $rr->waitForRequest(function ($request) { return false; } $body = json_decode($request["body"], true); - if ($body["request_type"] != "logs" || !isset($body["payload"][0]["message"])) { - return false; - } + $batch = $body["request_type"] == "message-batch" ? $body["payload"] : [$body]; - foreach ($body["payload"] as $payload) { - $payload["message"] = json_decode($payload["message"], true); - if (!isset($payload["message"]["metadata"])) { - break; + foreach ($batch as $json) { + if ($json["request_type"] != "logs" || !isset($json["payload"]["logs"])) { + continue; } - $output = json_encode($payload, JSON_PRETTY_PRINT); - echo $output; + foreach ($json["payload"]["logs"] as $payload) { + $payload["message"] = json_decode($payload["message"], true); + if (!isset($payload["message"]["metadata"])) { + break; + } - return true; + $output = json_encode($payload, JSON_PRETTY_PRINT); + echo $output; + + return true; + } } return false; diff --git a/tests/ext/live-debugger/debugger_log_probe.phpt b/tests/ext/live-debugger/debugger_log_probe.phpt index 3e7aece3c3a..7edb7199ba9 100644 --- a/tests/ext/live-debugger/debugger_log_probe.phpt +++ b/tests/ext/live-debugger/debugger_log_probe.phpt @@ -62,7 +62,7 @@ reset_request_replayer(); ?> --EXPECTF-- int(30) -array(5) { +array(6) { ["service"]=> string(22) "debugger_log_probe.php" ["ddsource"]=> @@ -247,4 +247,6 @@ array(5) { [true] [true] " + ["process_tags"]=> + NULL } diff --git a/tests/ext/live-debugger/debugger_log_probe_process_tags.phpt b/tests/ext/live-debugger/debugger_log_probe_process_tags.phpt new file mode 100644 index 00000000000..0ed61760f9f --- /dev/null +++ b/tests/ext/live-debugger/debugger_log_probe_process_tags.phpt @@ -0,0 +1,61 @@ +--TEST-- +Live debugger log probe includes process_tags +--SKIPIF-- + +--ENV-- +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_DYNAMIC_INSTRUMENTATION_ENABLED=1 +DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS=0.01 +DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED=1 +--INI-- +datadog.trace.agent_test_session_token=live-debugger/log_probe_process_tags +--FILE-- + ["methodName" => "simple_function"], + "captureSnapshot" => true, + "segments" => [ + ["str" => "Simple message"], + ], + ]); + + \DDTrace\start_span(); // submit span data +}); + +simple_function(); + +$dlr = new DebuggerLogReplayer; +$log = $dlr->waitForDebuggerDataAndReplay(); +$payload = json_decode($log["body"], true)[0]; + +if (isset($payload["process_tags"])) { + echo "Process tags found in payload\n"; + $processTags = $payload["process_tags"]; + + var_dump($processTags); +} else { + echo "ERROR: process_tags not found in payload\n"; +} + +?> +--CLEAN-- + +--EXPECTF-- +Process tags found in payload +string(%d) "entrypoint.basedir:live-debugger,entrypoint.name:debugger_log_probe_process_tags,entrypoint.type:script,entrypoint.workdir:%s,runtime.sapi:cli" + diff --git a/tests/ext/live-debugger/debugger_span_decoration_probe.phpt b/tests/ext/live-debugger/debugger_span_decoration_probe.phpt index 9320df9cb9c..9716393f6d7 100644 --- a/tests/ext/live-debugger/debugger_span_decoration_probe.phpt +++ b/tests/ext/live-debugger/debugger_span_decoration_probe.phpt @@ -101,7 +101,7 @@ array(2) { string(%d) "/debugger/v1/input?ddtags=debugger_version:1.%s,env:none,version:,runtime_id:%s-%s-%s-%s-%s,host_name:%s" array(1) { [0]=> - array(5) { + array(6) { ["service"]=> string(34) "debugger_span_decoration_probe.php" ["ddsource"]=> @@ -142,5 +142,7 @@ array(1) { } ["message"]=> string(32) "Evaluation errors for probe id 2" + ["process_tags"]=> + NULL } } diff --git a/tests/ext/live-debugger/exception-replay_001.phpt b/tests/ext/live-debugger/exception-replay_001.phpt index ef1888464a3..4b23b4cccae 100644 --- a/tests/ext/live-debugger/exception-replay_001.phpt +++ b/tests/ext/live-debugger/exception-replay_001.phpt @@ -47,7 +47,7 @@ reset_request_replayer(); --EXPECTF-- array(2) { [0]=> - array(5) { + array(6) { ["service"]=> string(24) "exception-replay_001.php" ["ddsource"]=> @@ -126,9 +126,11 @@ array(2) { } ["message"]=> NULL + ["process_tags"]=> + NULL } [1]=> - array(5) { + array(6) { ["service"]=> string(24) "exception-replay_001.php" ["ddsource"]=> @@ -231,5 +233,7 @@ array(2) { } ["message"]=> NULL + ["process_tags"]=> + NULL } } \ No newline at end of file diff --git a/tests/ext/live-debugger/exception-replay_002.phpt b/tests/ext/live-debugger/exception-replay_002.phpt index 1880a57a5b7..80f7d247faf 100644 --- a/tests/ext/live-debugger/exception-replay_002.phpt +++ b/tests/ext/live-debugger/exception-replay_002.phpt @@ -76,7 +76,7 @@ require __DIR__ . "/live_debugger.inc"; reset_request_replayer(); ?> --EXPECTF-- -array(5) { +array(6) { ["service"]=> string(24) "exception-replay_002.php" ["ddsource"]=> @@ -1029,4 +1029,6 @@ array(5) { } ["message"]=> NULL + ["process_tags"]=> + NULL } diff --git a/tests/ext/live-debugger/exception-replay_non_regression_2989_mysqli.phpt b/tests/ext/live-debugger/exception-replay_non_regression_2989_mysqli.phpt index a684465fab3..524bac94f28 100644 --- a/tests/ext/live-debugger/exception-replay_non_regression_2989_mysqli.phpt +++ b/tests/ext/live-debugger/exception-replay_non_regression_2989_mysqli.phpt @@ -49,7 +49,7 @@ reset_request_replayer(); ?> --EXPECTF-- Warning: mysqli::__construct(): php_network_getaddresses: getaddrinfo %s -%Aarray(5) { +%Aarray(6) { ["service"]=> string(47) "exception-replay_non_regression_2989_mysqli.php" ["ddsource"]=> @@ -124,4 +124,6 @@ Warning: mysqli::__construct(): php_network_getaddresses: getaddrinfo %s } ["message"]=> NULL + ["process_tags"]=> + NULL } diff --git a/tests/ext/telemetry/integration_runtime_error.phpt b/tests/ext/telemetry/integration_runtime_error.phpt index 8aa28dab6fb..ec9c53c8946 100644 --- a/tests/ext/telemetry/integration_runtime_error.phpt +++ b/tests/ext/telemetry/integration_runtime_error.phpt @@ -44,7 +44,7 @@ for ($i = 0; $i < 300; ++$i) { $batch = $json["request_type"] == "message-batch" ? $json["payload"] : [$json]; foreach ($batch as $json) { if ($json["request_type"] == "logs") { - $logs = $json['payload']; + $logs = $json['payload']['logs']; ksort($logs); var_dump(array_values($logs));