From e6d051353806f567f310e2ef722aff25df7826f1 Mon Sep 17 00:00:00 2001 From: Louis Tricot Date: Wed, 18 Mar 2026 18:13:05 +0100 Subject: [PATCH 1/6] Adds container tags support for DBM --- components-rs/sidecar.h | 6 + config.m4 | 1 + config.w32 | 1 + ext/agent_info.c | 16 +++ ext/agent_info.h | 4 + ext/configuration.h | 1 + ext/ddtrace.c | 27 ++++ ext/ddtrace.stub.php | 10 ++ ext/ddtrace_arginfo.h | 4 + ext/fnv.c | 12 ++ ext/fnv.h | 22 +++ ext/process_tags.c | 128 ++++++++++++++---- ext/process_tags.h | 9 ++ libdatadog | 2 +- .../DatabaseIntegrationHelper.php | 16 +++ src/api/Tag.php | 1 + tests/Integration/DatabaseMonitoringTest.php | 117 ++++++++++++++++ 17 files changed, 350 insertions(+), 27 deletions(-) create mode 100644 ext/fnv.c create mode 100644 ext/fnv.h diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 76426c3a2bd..3439f7bc2b2 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -391,6 +391,12 @@ struct ddog_AgentInfoReader *ddog_get_agent_info_reader(const struct ddog_Endpoi */ ddog_CharSlice ddog_get_agent_info_env(struct ddog_AgentInfoReader *reader, bool *changed); +/** + * Gets the container tags hash from agent info (or empty if not existing) + */ +ddog_CharSlice ddog_get_agent_info_container_tags_hash(struct ddog_AgentInfoReader *reader, + bool *changed); + void ddog_send_traces_to_sidecar(ddog_TracesBytes *traces, struct ddog_SenderParameters *parameters); diff --git a/config.m4 b/config.m4 index 9eb5aaca874..0ad12a0c456 100644 --- a/config.m4 +++ b/config.m4 @@ -184,6 +184,7 @@ if test "$PHP_DDTRACE" != "no"; then ext/engine_hooks.c \ ext/exception_serialize.c \ ext/excluded_modules.c \ + ext/fnv.c \ ext/git.c \ ext/handlers_api.c \ ext/handlers_exception.c \ diff --git a/config.w32 b/config.w32 index 06b1a0ff048..daef23f0f1f 100644 --- a/config.w32 +++ b/config.w32 @@ -34,6 +34,7 @@ if (PHP_DDTRACE != 'no') { DDTRACE_EXT_SOURCES += " engine_hooks.c"; DDTRACE_EXT_SOURCES += " exception_serialize.c"; DDTRACE_EXT_SOURCES += " excluded_modules.c"; + DDTRACE_EXT_SOURCES += " fnv.c"; DDTRACE_EXT_SOURCES += " git.c"; DDTRACE_EXT_SOURCES += " handlers_api.c"; DDTRACE_EXT_SOURCES += " handlers_curl" + (version < 800 ? "_php7" : "") + ".c"; diff --git a/ext/agent_info.c b/ext/agent_info.c index 4c2f8d6e3f7..9fc3cc14b1f 100644 --- a/ext/agent_info.c +++ b/ext/agent_info.c @@ -2,6 +2,7 @@ #include "ddtrace.h" #include "sidecar.h" #include "configuration.h" +#include "process_tags.h" ZEND_EXTERN_MODULE_GLOBALS(ddtrace); @@ -20,3 +21,18 @@ void ddtrace_agent_info_rinit() { DDTRACE_G(agent_info_reader) = ddog_get_agent_info_reader(ddtrace_endpoint); } } + +void ddtrace_get_container_tags_hash(void) { + if (DDTRACE_G(agent_info_reader)) { + bool changed; + ddog_CharSlice hash = ddog_get_agent_info_container_tags_hash( + DDTRACE_G(agent_info_reader), + &changed + ); + if (hash.len > 0) { + zend_string *hash_str = zend_string_init(hash.ptr, hash.len, 0); + ddtrace_process_tags_set_container_tags_hash(hash_str); + zend_string_release(hash_str); + } + } +} diff --git a/ext/agent_info.h b/ext/agent_info.h index e0c4e10fb16..19c1ee397fb 100644 --- a/ext/agent_info.h +++ b/ext/agent_info.h @@ -1,7 +1,11 @@ #ifndef DD_AGENT_INFO_H #define DD_AGENT_INFO_H +#include +#include "Zend/zend_types.h" + void ddtrace_check_agent_info_env(void); void ddtrace_agent_info_rinit(void); +void ddtrace_get_container_tags_hash(void); #endif // DD_AGENT_INFO_H diff --git a/ext/configuration.h b/ext/configuration.h index 97b97875608..5a17451e141 100644 --- a/ext/configuration.h +++ b/ext/configuration.h @@ -225,6 +225,7 @@ enum ddtrace_sampling_rules_format { CONFIG(STRING, DD_TRACE_AGENT_TEST_SESSION_TOKEN, "", .ini_change = ddtrace_alter_test_session_token) \ CONFIG(BOOL, DD_TRACE_PROPAGATE_USER_ID_DEFAULT, "false") \ CONFIG(CUSTOM(INT), DD_DBM_PROPAGATION_MODE, "disabled", .parser = dd_parse_dbm_mode) \ + CONFIG(BOOL, DD_DBM_INJECT_SQL_BASEHASH, "false") \ CONFIG(SET, DD_TRACE_WORDPRESS_ADDITIONAL_ACTIONS, "") \ CONFIG(BOOL, DD_TRACE_WORDPRESS_CALLBACKS, "true") \ CONFIG(BOOL, DD_INTEGRATION_METRICS_ENABLED, "true", \ diff --git a/ext/ddtrace.c b/ext/ddtrace.c index 399e7286833..f59a6e5f0b0 100644 --- a/ext/ddtrace.c +++ b/ext/ddtrace.c @@ -1722,6 +1722,8 @@ static void dd_initialize_request(void) { ddtrace_agent_info_rinit(); + ddtrace_get_container_tags_hash(); + // Reset compile time after request init hook has compiled ddtrace_compile_time_reset(); @@ -2585,6 +2587,17 @@ PHP_FUNCTION(DDTrace_System_container_id) { } } +PHP_FUNCTION(DDTrace_System_process_tags_base_hash) { + UNUSED(execute_data); + + zend_string *base_hash = ddtrace_process_tags_get_base_hash(); + if (base_hash) { + RETVAL_STRINGL(ZSTR_VAL(base_hash), ZSTR_LEN(base_hash)); + } else { + RETURN_NULL(); + } +} + PHP_FUNCTION(DDTrace_Testing_trigger_error) { ddtrace_string message; ddtrace_zpplong_t error_type; @@ -3029,6 +3042,20 @@ PHP_FUNCTION(dd_trace_internal_fn) { ddtrace_generate_runtime_id(); ddtrace_force_new_instance_id(); RETURN_TRUE; + } else if (FUNCTION_NAME_MATCHES("reload_process_tags")) { + if (ddtrace_process_tags_enabled()) { + ddtrace_process_tags_reload(); + ddtrace_sidecar_update_process_tags(); + } + RETVAL_TRUE; + } else if (params_count == 1 && FUNCTION_NAME_MATCHES("set_container_tags_hash")) { + zval *container_tags_hash = ZVAL_VARARG_PARAM(params, 0); + if (Z_TYPE_P(container_tags_hash) == IS_STRING) { + ddtrace_process_tags_set_container_tags_hash(Z_STR_P(container_tags_hash)); + RETVAL_TRUE; + } else { + RETVAL_FALSE; + } } else if (FUNCTION_NAME_MATCHES("synchronous_flush")) { uint32_t timeout = 100; if (params_count == 1) { diff --git a/ext/ddtrace.stub.php b/ext/ddtrace.stub.php index 2b18fe79ba1..ff371b1d1a5 100644 --- a/ext/ddtrace.stub.php +++ b/ext/ddtrace.stub.php @@ -849,6 +849,16 @@ function add_endpoint(string $path, string $operation_name, string $resource_nam * @return string|null The container id, or 'null' if no id was found */ function container_id(): string|null {} + + /** + * Get the process tags base hash + * + * Returns the FNV-1a 64-bit hash of serialized process tags combined with container tags hash. + * This hash is used for Database Monitoring to correlate queries with application processes. + * + * @return string|null The base hash as a binary string (8 bytes), or 'null' if process tags are disabled or not computed + */ + function process_tags_base_hash(): string|null {} } namespace DDTrace\Config { diff --git a/ext/ddtrace_arginfo.h b/ext/ddtrace_arginfo.h index f5dbd2a5046..14e3f266ab6 100644 --- a/ext/ddtrace_arginfo.h +++ b/ext/ddtrace_arginfo.h @@ -177,6 +177,8 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_System_container_id, 0, 0, IS_STRING, 1) ZEND_END_ARG_INFO() +#define arginfo_DDTrace_System_process_tags_base_hash arginfo_DDTrace_System_container_id + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_Config_integration_analytics_enabled, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, integrationName, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -390,6 +392,7 @@ ZEND_FUNCTION(DDTrace_resource_weak_get); ZEND_FUNCTION(DDTrace_are_endpoints_collected); ZEND_FUNCTION(DDTrace_add_endpoint); ZEND_FUNCTION(DDTrace_System_container_id); +ZEND_FUNCTION(DDTrace_System_process_tags_base_hash); ZEND_FUNCTION(DDTrace_Config_integration_analytics_enabled); ZEND_FUNCTION(DDTrace_Config_integration_analytics_sample_rate); ZEND_FUNCTION(DDTrace_UserRequest_has_listeners); @@ -483,6 +486,7 @@ static const zend_function_entry ext_functions[] = { ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "are_endpoints_collected"), zif_DDTrace_are_endpoints_collected, arginfo_DDTrace_are_endpoints_collected, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "add_endpoint"), zif_DDTrace_add_endpoint, arginfo_DDTrace_add_endpoint, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\System", "container_id"), zif_DDTrace_System_container_id, arginfo_DDTrace_System_container_id, 0, NULL, NULL) + ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\System", "process_tags_base_hash"), zif_DDTrace_System_process_tags_base_hash, arginfo_DDTrace_System_process_tags_base_hash, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Config", "integration_analytics_enabled"), zif_DDTrace_Config_integration_analytics_enabled, arginfo_DDTrace_Config_integration_analytics_enabled, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Config", "integration_analytics_sample_rate"), zif_DDTrace_Config_integration_analytics_sample_rate, arginfo_DDTrace_Config_integration_analytics_sample_rate, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\UserRequest", "has_listeners"), zif_DDTrace_UserRequest_has_listeners, arginfo_DDTrace_UserRequest_has_listeners, 0, NULL, NULL) diff --git a/ext/fnv.c b/ext/fnv.c new file mode 100644 index 00000000000..308c7c1d020 --- /dev/null +++ b/ext/fnv.c @@ -0,0 +1,12 @@ +#include "fnv.h" + +uint64_t dd_fnv1_64(const unsigned char *data, size_t len) { + uint64_t hash = DD_FNV_OFFSET_BASIS; + + for (size_t i = 0; i < len; i++) { + hash ^= (uint64_t)data[i]; + hash *= DD_FNV_PRIME; + } + + return hash; +} diff --git a/ext/fnv.h b/ext/fnv.h new file mode 100644 index 00000000000..ebb40edc8da --- /dev/null +++ b/ext/fnv.h @@ -0,0 +1,22 @@ +#ifndef DD_FNV_H +#define DD_FNV_H + +#include +#include + +// FNV-1a 64-bit hash constants +// See: https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function +#define DD_FNV_PRIME 1099511628211ULL +#define DD_FNV_OFFSET_BASIS 14695981039346656037ULL + +/** + * FNV-1a 64-bit non-cryptographic hash function. + * + * @param data Pointer to the data to hash + * @param len Length of the data in bytes + * @return The 64-bit FNV-1a hash value + */ +uint64_t dd_fnv1_64(const unsigned char *data, size_t len); + +#endif // DD_FNV_H + diff --git a/ext/process_tags.c b/ext/process_tags.c index 76d0b51cba3..01953bf1891 100644 --- a/ext/process_tags.c +++ b/ext/process_tags.c @@ -1,5 +1,6 @@ #include "php.h" #include +#include #include #include #include @@ -8,6 +9,7 @@ #include "Zend/zend_smart_str.h" #include "components-rs/ddtrace.h" #include "SAPI.h" +#include "fnv.h" #ifndef PATH_MAX #define PATH_MAX 4096 @@ -32,11 +34,41 @@ typedef struct { size_t count; size_t capacity; zend_string *serialized; + zend_string *base_hash; + zend_string *container_tags_hash; ddog_Vec_Tag vec; } process_tags_t; static process_tags_t process_tags = {0}; +static void clear_process_tags(void) { + for (size_t i = 0; i < process_tags.count; i++) { + ddog_free_normalized_tag_value(process_tags.tag_list[i].value); + } + + if (process_tags.tag_list) { + pefree(process_tags.tag_list, 1); + } + + if (process_tags.serialized) { + zend_string_release(process_tags.serialized); + } + + if (process_tags.vec.ptr) { + ddog_Vec_Tag_drop(process_tags.vec); + } + + if (process_tags.base_hash) { + zend_string_release(process_tags.base_hash); + } + + if (process_tags.container_tags_hash) { + zend_string_release(process_tags.container_tags_hash); + } + + memset(&process_tags, 0, sizeof(process_tags)); +} + static inline const char *get_basename(const char *path) { if (!path || !*path) return NULL; @@ -168,6 +200,39 @@ static int cmp_process_tag_by_key(const void *tag1, const void* tag2) { return strcmp(tag_entry_1->key, tag_entry_2->key); } +static void recompute_base_hash(void) { + if (!ddtrace_process_tags_enabled() || !process_tags.serialized) { + return; + } + + if (process_tags.base_hash) { + zend_string_release(process_tags.base_hash); + process_tags.base_hash = NULL; + } + + uint64_t hash_value; + if (process_tags.container_tags_hash) { + size_t total_len = ZSTR_LEN(process_tags.serialized) + ZSTR_LEN(process_tags.container_tags_hash); + unsigned char *combined = emalloc(total_len); + + memcpy(combined, ZSTR_VAL(process_tags.serialized), ZSTR_LEN(process_tags.serialized)); + memcpy(combined + ZSTR_LEN(process_tags.serialized), ZSTR_VAL(process_tags.container_tags_hash), ZSTR_LEN(process_tags.container_tags_hash)); + + hash_value = dd_fnv1_64(combined, total_len); + efree(combined); + } else { + hash_value = dd_fnv1_64((unsigned char *)ZSTR_VAL(process_tags.serialized), ZSTR_LEN(process_tags.serialized)); + } + + zend_string *hash_value_str = strpprintf(0, "%" PRIu64, hash_value); + if (!hash_value_str) { + return; + } + + process_tags.base_hash = zend_string_init(ZSTR_VAL(hash_value_str), ZSTR_LEN(hash_value_str), 1); + zend_string_release(hash_value_str); +} + static void serialize_process_tags(void) { if (!ddtrace_process_tags_enabled() || !process_tags.count) { return; @@ -202,6 +267,33 @@ static void serialize_process_tags(void) { (ddog_CharSlice) {.ptr = value, .len = strlen(value)} )); } + + recompute_base_hash(); +} + +static void init_process_tags(void) { + process_tags.capacity = 4; + process_tags.tag_list = pemalloc(process_tags.capacity * sizeof(process_tag_entry_t), 1); + if (!process_tags.tag_list) { + process_tags.capacity = 0; + return; + } + + collect_process_tags(); + serialize_process_tags(); +} + +void ddtrace_process_tags_set_container_tags_hash(zend_string *container_tags_hash) { + if (!container_tags_hash || !ddtrace_process_tags_enabled()) { + return; + } + + if (process_tags.container_tags_hash) { + zend_string_release(process_tags.container_tags_hash); + } + process_tags.container_tags_hash = zend_string_init(ZSTR_VAL(container_tags_hash), ZSTR_LEN(container_tags_hash), 1); + + recompute_base_hash(); } zend_string *ddtrace_process_tags_get_serialized(void) { @@ -220,38 +312,22 @@ const ddog_Vec_Tag *ddtrace_process_tags_get_vec(void) { return &empty_vec; } +zend_string *ddtrace_process_tags_get_base_hash(void) { + return (ddtrace_process_tags_enabled() && process_tags.base_hash) ? process_tags.base_hash : NULL; +} + bool ddtrace_process_tags_enabled(void){ return get_global_DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED(); } void ddtrace_process_tags_first_rinit(void) { - // process_tags struct initializations - process_tags.count = 0; - process_tags.capacity = 4; - process_tags.tag_list = pemalloc(process_tags.capacity * sizeof(process_tag_entry_t), 1); - - if (!process_tags.tag_list) { - process_tags.capacity = 0; - return; - } - - collect_process_tags(); - serialize_process_tags(); + init_process_tags(); } +void ddtrace_process_tags_reload(void) { + clear_process_tags(); + init_process_tags(); +} void ddtrace_process_tags_mshutdown(void) { - for (size_t i = 0; i < process_tags.count; i++) { - ddog_free_normalized_tag_value(process_tags.tag_list[i].value); - } - pefree(process_tags.tag_list, 1); - - if (process_tags.serialized) { - zend_string_release(process_tags.serialized); - } - - if (process_tags.vec.ptr) { - ddog_Vec_Tag_drop(process_tags.vec); - } - - memset(&process_tags, 0, sizeof(process_tags)); + clear_process_tags(); } diff --git a/ext/process_tags.h b/ext/process_tags.h index d2052675011..0840b6b951d 100644 --- a/ext/process_tags.h +++ b/ext/process_tags.h @@ -9,6 +9,8 @@ // Called at first RINIT to collect process tags void ddtrace_process_tags_first_rinit(void); +// Reload process tags in current request +void ddtrace_process_tags_reload(void); // Called at MSHUTDOWN to free resources void ddtrace_process_tags_mshutdown(void); @@ -24,4 +26,11 @@ DDTRACE_PUBLIC zend_string *ddtrace_process_tags_get_serialized(void); // Returns a pointer to an empty Vec if disabled or not yet collected const ddog_Vec_Tag *ddtrace_process_tags_get_vec(void); +// Set the container tags hash +void ddtrace_process_tags_set_container_tags_hash(zend_string *hash); + +// Get the base hash which is the hash of container_tags and process_tags +// Returns NULL if disabled or not yet computed +zend_string *ddtrace_process_tags_get_base_hash(void); + #endif // DD_PROCESS_TAGS_H diff --git a/libdatadog b/libdatadog index 7b8a805a570..7f861d8a6cb 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 7b8a805a5706592390a0b8d012e3777bcb33aa27 +Subproject commit 7f861d8a6cbc1f817598a7e758da868fe0db731f diff --git a/src/DDTrace/Integrations/DatabaseIntegrationHelper.php b/src/DDTrace/Integrations/DatabaseIntegrationHelper.php index 9a1dee33d6e..59a96f4870f 100644 --- a/src/DDTrace/Integrations/DatabaseIntegrationHelper.php +++ b/src/DDTrace/Integrations/DatabaseIntegrationHelper.php @@ -48,6 +48,14 @@ public static function injectDatabaseIntegrationData(HookData $hook, $backend, $ $dbName = $span->meta[Tag::DB_NAME] ?? $span->meta[Tag::DB_INSTANCE] ?? ''; $peerService = $span->meta['peer.service'] ?? ''; + // Inject base hash into span tags if enabled + if (dd_trace_env_config("DD_DBM_INJECT_SQL_BASEHASH")) { + $baseHash = \DDTrace\System\process_tags_base_hash(); + if ($baseHash !== null) { + $span->meta[Tag::PROPAGATED_HASH] = $baseHash; + } + } + $query = self::propagateViaSqlComments( $hook->args[$argNum], $span->service, @@ -127,6 +135,14 @@ public static function propagateViaSqlComments( } } + // Inject base hash into SQL comment if enabled + if (dd_trace_env_config("DD_DBM_INJECT_SQL_BASEHASH")) { + $baseHash = \DDTrace\System\process_tags_base_hash(); + if ($baseHash !== null) { + $tags["ddsh"] = $baseHash; + } + } + return self::injectSqlComment($query, $tags); } diff --git a/src/api/Tag.php b/src/api/Tag.php index 619882832de..f2cb6b7c1e4 100644 --- a/src/api/Tag.php +++ b/src/api/Tag.php @@ -59,6 +59,7 @@ class Tag const DB_ROW_COUNT = 'db.row_count'; const DB_STMT = 'sql.query'; const DB_USER = 'db.user'; + const PROPAGATED_HASH = '_dd.propagated_hash'; // Kafka const KAFKA_CLIENT_ID = 'messaging.kafka.client_id'; diff --git a/tests/Integration/DatabaseMonitoringTest.php b/tests/Integration/DatabaseMonitoringTest.php index df607d7347d..7225017575f 100644 --- a/tests/Integration/DatabaseMonitoringTest.php +++ b/tests/Integration/DatabaseMonitoringTest.php @@ -15,10 +15,15 @@ public function ddTearDown() parent::ddTearDown(); self::putenv('DD_TRACE_DEBUG_PRNG_SEED'); self::putenv('DD_DBM_PROPAGATION_MODE'); + self::putenv('DD_DBM_INJECT_SQL_BASEHASH'); + self::putenv('DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED'); self::putEnv("DD_ENV"); self::putEnv("DD_SERVICE"); self::putEnv("DD_SERVICE_MAPPING"); self::putEnv("DD_VERSION"); + + // Reload config to reset process tags + \dd_trace_internal_fn('reload_process_tags'); } public function instrumented($arg, $optionalArg = null) @@ -284,4 +289,116 @@ public function noInjectionWithUnsupportedDriver() \DDTrace\remove_hook($hook); } } + + public function testBaseHashInjection() + { + self::putEnv('DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED=true'); + self::putEnv('DD_DBM_INJECT_SQL_BASEHASH=true'); + self::putEnv('DD_DBM_PROPAGATION_MODE=full'); + self::putEnv('DD_TRACE_DEBUG_PRNG_SEED=42'); + + \dd_trace_internal_fn('reload_process_tags'); + + // we don't have access to the agent info endpoint in this test so we have to mock the container tags hash + \dd_trace_internal_fn('set_container_tags_hash', 'abc123'); + + try { + $hook = \DDTrace\install_hook(self::class . "::instrumented", function (HookData $hook) { + $hook->span()->service = "testdb"; + $hook->span()->name = "instrumented"; + DatabaseIntegrationHelper::injectDatabaseIntegrationData($hook, 'mysql', 1); + }); + + $this->assertNotNull(\DDTrace\System\process_tags_base_hash(), 'process_tags_base_hash() is null'); + + $traces = $this->isolateTracer(function () use (&$commentedQuery) { + \DDTrace\start_trace_span(); + $commentedQuery = $this->instrumented(0, "SELECT 1"); + \DDTrace\close_span(); + }); + } finally { + \DDTrace\remove_hook($hook); + } + + // SQL Comment should have ddsh tag + preg_match('/ddsh=\'([^\']+)\'/', $commentedQuery, $matches); + $this->assertNotEmpty($matches, 'ddsh not found in SQL comment'); + $ddshValue = $matches[1]; + + $propagatedHash = $traces[0][1]['meta']['_dd.propagated_hash'] ?? null; + $this->assertNotNull($propagatedHash, '_dd.propagated_hash not found in span'); + $this->assertSame($ddshValue, $propagatedHash, 'ddsh in SQL comment does not match _dd.propagated_hash in span'); + } + + public function testBaseHashInjectionWithoutContainerTagsHash() + { + self::putEnv('DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED=true'); + self::putEnv('DD_DBM_INJECT_SQL_BASEHASH=true'); + self::putEnv('DD_DBM_PROPAGATION_MODE=full'); + self::putEnv('DD_TRACE_DEBUG_PRNG_SEED=42'); + + \dd_trace_internal_fn('reload_process_tags'); + + try { + $hook = \DDTrace\install_hook(self::class . "::instrumented", function (HookData $hook) { + $hook->span()->service = "testdb"; + $hook->span()->name = "instrumented"; + DatabaseIntegrationHelper::injectDatabaseIntegrationData($hook, 'mysql', 1); + }); + + $this->assertNotNull(\DDTrace\System\process_tags_base_hash(), 'process_tags_base_hash() is null without container tags hash'); + + $traces = $this->isolateTracer(function () use (&$commentedQuery) { + \DDTrace\start_trace_span(); + $commentedQuery = $this->instrumented(0, "SELECT 1"); + \DDTrace\close_span(); + }); + } finally { + \DDTrace\remove_hook($hook); + } + + preg_match('/ddsh=\'([^\']+)\'/', $commentedQuery, $matches); + $this->assertNotEmpty($matches, 'ddsh not found in SQL comment'); + $ddshValue = $matches[1]; + + $propagatedHash = $traces[0][1]['meta']['_dd.propagated_hash'] ?? null; + $this->assertNotNull($propagatedHash, '_dd.propagated_hash not found in span'); + $this->assertSame($ddshValue, $propagatedHash, 'ddsh in SQL comment does not match _dd.propagated_hash in span'); + } + + public function testBaseHashNotInjectedWhenDisabled() + { + try { + $hook = \DDTrace\install_hook(self::class . "::instrumented", function (HookData $hook) { + $hook->span()->service = "testdb"; + $hook->span()->name = "instrumented"; + DatabaseIntegrationHelper::injectDatabaseIntegrationData($hook, 'mysql', 1); + }); + self::putEnv("DD_TRACE_DEBUG_PRNG_SEED=42"); + self::putEnv("DD_DBM_PROPAGATION_MODE=full"); + // DD_DBM_INJECT_SQL_BASEHASH is not set (defaults to false) + self::putEnv("DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED=true"); + + $traces = $this->isolateTracer(function () use (&$commentedQuery) { + \DDTrace\start_trace_span(); + $commentedQuery = $this->instrumented(0, "SELECT 1"); + \DDTrace\close_span(); + }); + } finally { + \DDTrace\remove_hook($hook); + } + + // The query should NOT contain the base hash + $this->assertDoesNotMatchRegularExpression('/ddsh=/', $commentedQuery); + + // The span should NOT have the _dd.propagated_hash tag + $this->assertFlameGraph($traces, [ + SpanAssertion::exists("phpunit")->withChildren([ + SpanAssertion::exists('instrumented')->withExactTags([ + "_dd.dbm_trace_injected" => "true", + "_dd.base_service" => "phpunit", + ]) + ]) + ]); + } } From ca616969cd45c2f8df58c0f8c6e253ba133e6bd9 Mon Sep 17 00:00:00 2001 From: Louis Tricot Date: Wed, 18 Mar 2026 19:03:22 +0100 Subject: [PATCH 2/6] fix tests --- ext/process_tags.c | 2 +- metadata/supported-configurations.json | 7 +++++++ tests/api/Unit/UserAvailableConstantsTest.php | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ext/process_tags.c b/ext/process_tags.c index 01953bf1891..c46751b2330 100644 --- a/ext/process_tags.c +++ b/ext/process_tags.c @@ -317,7 +317,7 @@ zend_string *ddtrace_process_tags_get_base_hash(void) { } bool ddtrace_process_tags_enabled(void){ - return get_global_DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED(); + return get_DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED(); } void ddtrace_process_tags_first_rinit(void) { diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index b20c2bf5858..bf3d14fd91c 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -284,6 +284,13 @@ "default": "true" } ], + "DD_DBM_INJECT_SQL_BASEHASH": [ + { + "implementation": "A", + "type": "boolean", + "default": "false" + } + ], "DD_DBM_PROPAGATION_MODE": [ { "implementation": "A", diff --git a/tests/api/Unit/UserAvailableConstantsTest.php b/tests/api/Unit/UserAvailableConstantsTest.php index 40f67f65067..0df908057d9 100644 --- a/tests/api/Unit/UserAvailableConstantsTest.php +++ b/tests/api/Unit/UserAvailableConstantsTest.php @@ -139,6 +139,7 @@ public function tags() [Tag::DB_ROW_COUNT, 'db.row_count'], [Tag::DB_STMT, 'sql.query'], [Tag::DB_USER, 'db.user'], + [Tag::PROPAGATED_HASH, '_dd.propagated_hash'], [Tag::KAFKA_CLIENT_ID, 'messaging.kafka.client_id'], [Tag::KAFKA_GROUP_ID, 'messaging.kafka.group_id'], [Tag::KAFKA_HOST_LIST, 'messaging.kafka.bootstrap.servers'], From 0534aa34c2b44913d1e6a7296901317ff1cb0c05 Mon Sep 17 00:00:00 2001 From: Louis Tricot Date: Thu, 19 Mar 2026 10:37:42 +0100 Subject: [PATCH 3/6] bwoebi review --- components-rs/ddtrace.h | 2 ++ components-rs/lib.rs | 18 ++++++++++++++++ config.m4 | 1 - config.w32 | 1 - ext/agent_info.c | 2 +- ext/fnv.c | 12 ----------- ext/fnv.h | 22 -------------------- ext/process_tags.c | 19 +++++++---------- tests/Integration/DatabaseMonitoringTest.php | 10 +++++++-- 9 files changed, 37 insertions(+), 50 deletions(-) delete mode 100644 ext/fnv.c delete mode 100644 ext/fnv.h diff --git a/components-rs/ddtrace.h b/components-rs/ddtrace.h index 0644a3fae84..a5dbe21a4f5 100644 --- a/components-rs/ddtrace.h +++ b/components-rs/ddtrace.h @@ -47,6 +47,8 @@ ddog_Configurator *ddog_library_configurator_new_dummy(bool debug_logs, ddog_Cha int posix_spawn_file_actions_addchdir_np(void *file_actions, const char *path); +uint64_t dd_fnv1a_64(const unsigned char *data, uintptr_t len); + const char *ddog_normalize_process_tag_value(ddog_CharSlice tag_value); void ddog_free_normalized_tag_value(const char *ptr); diff --git a/components-rs/lib.rs b/components-rs/lib.rs index d331ca1df1a..7c539641036 100644 --- a/components-rs/lib.rs +++ b/components-rs/lib.rs @@ -156,6 +156,24 @@ pub unsafe extern "C" fn posix_spawn_file_actions_addchdir_np( } const MAX_TAG_VALUE_LENGTH: usize = 100; +const DD_FNV_PRIME: u64 = 1_099_511_628_211; +const DD_FNV_OFFSET_BASIS: u64 = 14_695_981_039_346_656_037; + +#[no_mangle] +pub unsafe extern "C" fn dd_fnv1a_64(data: *const u8, len: usize) -> u64 { + if data.is_null() || len == 0 { + return DD_FNV_OFFSET_BASIS; + } + + let bytes = std::slice::from_raw_parts(data, len); + let mut hash = DD_FNV_OFFSET_BASIS; + for byte in bytes { + hash ^= u64::from(*byte); + hash = hash.wrapping_mul(DD_FNV_PRIME); + } + + hash +} #[no_mangle] pub extern "C" fn ddog_normalize_process_tag_value( diff --git a/config.m4 b/config.m4 index 0ad12a0c456..9eb5aaca874 100644 --- a/config.m4 +++ b/config.m4 @@ -184,7 +184,6 @@ if test "$PHP_DDTRACE" != "no"; then ext/engine_hooks.c \ ext/exception_serialize.c \ ext/excluded_modules.c \ - ext/fnv.c \ ext/git.c \ ext/handlers_api.c \ ext/handlers_exception.c \ diff --git a/config.w32 b/config.w32 index daef23f0f1f..06b1a0ff048 100644 --- a/config.w32 +++ b/config.w32 @@ -34,7 +34,6 @@ if (PHP_DDTRACE != 'no') { DDTRACE_EXT_SOURCES += " engine_hooks.c"; DDTRACE_EXT_SOURCES += " exception_serialize.c"; DDTRACE_EXT_SOURCES += " excluded_modules.c"; - DDTRACE_EXT_SOURCES += " fnv.c"; DDTRACE_EXT_SOURCES += " git.c"; DDTRACE_EXT_SOURCES += " handlers_api.c"; DDTRACE_EXT_SOURCES += " handlers_curl" + (version < 800 ? "_php7" : "") + ".c"; diff --git a/ext/agent_info.c b/ext/agent_info.c index 9fc3cc14b1f..645dabf8bde 100644 --- a/ext/agent_info.c +++ b/ext/agent_info.c @@ -30,7 +30,7 @@ void ddtrace_get_container_tags_hash(void) { &changed ); if (hash.len > 0) { - zend_string *hash_str = zend_string_init(hash.ptr, hash.len, 0); + zend_string *hash_str = zend_string_init(hash.ptr, hash.len, 1); ddtrace_process_tags_set_container_tags_hash(hash_str); zend_string_release(hash_str); } diff --git a/ext/fnv.c b/ext/fnv.c deleted file mode 100644 index 308c7c1d020..00000000000 --- a/ext/fnv.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "fnv.h" - -uint64_t dd_fnv1_64(const unsigned char *data, size_t len) { - uint64_t hash = DD_FNV_OFFSET_BASIS; - - for (size_t i = 0; i < len; i++) { - hash ^= (uint64_t)data[i]; - hash *= DD_FNV_PRIME; - } - - return hash; -} diff --git a/ext/fnv.h b/ext/fnv.h deleted file mode 100644 index ebb40edc8da..00000000000 --- a/ext/fnv.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef DD_FNV_H -#define DD_FNV_H - -#include -#include - -// FNV-1a 64-bit hash constants -// See: https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function -#define DD_FNV_PRIME 1099511628211ULL -#define DD_FNV_OFFSET_BASIS 14695981039346656037ULL - -/** - * FNV-1a 64-bit non-cryptographic hash function. - * - * @param data Pointer to the data to hash - * @param len Length of the data in bytes - * @return The 64-bit FNV-1a hash value - */ -uint64_t dd_fnv1_64(const unsigned char *data, size_t len); - -#endif // DD_FNV_H - diff --git a/ext/process_tags.c b/ext/process_tags.c index c46751b2330..60be49c36c2 100644 --- a/ext/process_tags.c +++ b/ext/process_tags.c @@ -9,7 +9,6 @@ #include "Zend/zend_smart_str.h" #include "components-rs/ddtrace.h" #include "SAPI.h" -#include "fnv.h" #ifndef PATH_MAX #define PATH_MAX 4096 @@ -218,19 +217,17 @@ static void recompute_base_hash(void) { memcpy(combined, ZSTR_VAL(process_tags.serialized), ZSTR_LEN(process_tags.serialized)); memcpy(combined + ZSTR_LEN(process_tags.serialized), ZSTR_VAL(process_tags.container_tags_hash), ZSTR_LEN(process_tags.container_tags_hash)); - hash_value = dd_fnv1_64(combined, total_len); + hash_value = dd_fnv1a_64(combined, total_len); efree(combined); } else { - hash_value = dd_fnv1_64((unsigned char *)ZSTR_VAL(process_tags.serialized), ZSTR_LEN(process_tags.serialized)); + hash_value = dd_fnv1a_64((const uint8_t *)ZSTR_VAL(process_tags.serialized), ZSTR_LEN(process_tags.serialized)); } - zend_string *hash_value_str = strpprintf(0, "%" PRIu64, hash_value); - if (!hash_value_str) { - return; - } - - process_tags.base_hash = zend_string_init(ZSTR_VAL(hash_value_str), ZSTR_LEN(hash_value_str), 1); - zend_string_release(hash_value_str); + smart_str hash_buf = {0}; + smart_str_alloc(&hash_buf, 21, 1); + smart_str_append_printf(&hash_buf, "%" PRIu64, hash_value); + smart_str_0(&hash_buf); + process_tags.base_hash = hash_buf.s; } static void serialize_process_tags(void) { @@ -291,7 +288,7 @@ void ddtrace_process_tags_set_container_tags_hash(zend_string *container_tags_ha if (process_tags.container_tags_hash) { zend_string_release(process_tags.container_tags_hash); } - process_tags.container_tags_hash = zend_string_init(ZSTR_VAL(container_tags_hash), ZSTR_LEN(container_tags_hash), 1); + process_tags.container_tags_hash = zend_string_copy(container_tags_hash); recompute_base_hash(); } diff --git a/tests/Integration/DatabaseMonitoringTest.php b/tests/Integration/DatabaseMonitoringTest.php index 7225017575f..d95539882c2 100644 --- a/tests/Integration/DatabaseMonitoringTest.php +++ b/tests/Integration/DatabaseMonitoringTest.php @@ -388,8 +388,14 @@ public function testBaseHashNotInjectedWhenDisabled() \DDTrace\remove_hook($hook); } - // The query should NOT contain the base hash - $this->assertDoesNotMatchRegularExpression('/ddsh=/', $commentedQuery); + + // Compatibility with older PHP Version + if (method_exists($this, 'assertDoesNotMatchRegularExpression')) { + // The query should NOT contain the base hash + $this->assertDoesNotMatchRegularExpression('/ddsh=/', $commentedQuery); + } else { + $this->assertNotRegExp('/ddsh=/', $commentedQuery); + } // The span should NOT have the _dd.propagated_hash tag $this->assertFlameGraph($traces, [ From d6552695d75641cd5bb1c112dca9df5634fd16ef Mon Sep 17 00:00:00 2001 From: Louis Tricot Date: Fri, 20 Mar 2026 10:52:42 +0100 Subject: [PATCH 4/6] bump libdatadog --- Cargo.lock | 34 +++++++++++++++++----------------- components-rs/ddtrace.h | 2 +- components-rs/sidecar.h | 10 ++++++++++ libdatadog | 2 +- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b735232ff7b..b5e4fe2b6c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1262,7 +1262,7 @@ dependencies = [ "glibc_version", "io-lifetimes", "libc 0.2.177", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-tinybytes", "memfd", "nix 0.29.0", @@ -1300,7 +1300,7 @@ dependencies = [ "constcat", "http", "http-body-util", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-data-pipeline", "percent-encoding 2.3.1", "regex", @@ -1319,7 +1319,7 @@ version = "0.0.1" dependencies = [ "build_common", "datadog-live-debugger", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-common-ffi", "log 0.4.25", "percent-encoding 2.3.1", @@ -1382,7 +1382,7 @@ dependencies = [ "http-body-util", "hyper 1.6.0", "hyper-util", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-trace-protobuf", "manual_future", "regex", @@ -1417,7 +1417,7 @@ dependencies = [ "http-body-util", "httpmock", "libc 0.2.177", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-common-ffi", "libdd-crashtracker", "libdd-crashtracker-ffi", @@ -1462,7 +1462,7 @@ dependencies = [ "datadog-sidecar", "http", "libc 0.2.177", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-common-ffi", "libdd-crashtracker-ffi", "libdd-dogstatsd-client", @@ -1505,7 +1505,7 @@ dependencies = [ "itertools 0.11.0", "lazy_static", "libc 0.2.177", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-common-ffi", "libdd-crashtracker-ffi", "libdd-library-config-ffi", @@ -2905,7 +2905,7 @@ dependencies = [ [[package]] name = "libdd-common" -version = "2.0.1" +version = "3.0.0" dependencies = [ "anyhow", "bytes", @@ -2957,7 +2957,7 @@ dependencies = [ "crossbeam-queue", "function_name", "hyper 1.6.0", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "serde", ] @@ -2975,7 +2975,7 @@ dependencies = [ "goblin", "http", "libc 0.2.177", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-libunwind-sys", "libdd-telemetry", "nix 0.29.0", @@ -3005,7 +3005,7 @@ dependencies = [ "build_common", "function_name", "libc 0.2.177", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-common-ffi", "libdd-crashtracker", "serde", @@ -3029,7 +3029,7 @@ dependencies = [ "http", "http-body-util", "httpmock", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-ddsketch", "libdd-dogstatsd-client", "libdd-log", @@ -3067,7 +3067,7 @@ dependencies = [ "anyhow", "cadence", "http", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "serde", "tokio", "tracing", @@ -3098,7 +3098,7 @@ dependencies = [ "anyhow", "build_common", "constcat", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-common-ffi", "libdd-library-config", "tempfile", @@ -3180,7 +3180,7 @@ dependencies = [ "http", "http-body-util", "libc 0.2.177", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-ddsketch", "serde", "serde_json", @@ -3200,7 +3200,7 @@ dependencies = [ "build_common", "function_name", "libc 0.2.177", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-common-ffi", "libdd-telemetry", "paste", @@ -3276,7 +3276,7 @@ dependencies = [ "httpmock", "hyper 1.6.0", "indexmap 2.12.1", - "libdd-common 2.0.1", + "libdd-common 3.0.0", "libdd-tinybytes", "libdd-trace-normalization", "libdd-trace-protobuf", diff --git a/components-rs/ddtrace.h b/components-rs/ddtrace.h index a5dbe21a4f5..b88aa97111d 100644 --- a/components-rs/ddtrace.h +++ b/components-rs/ddtrace.h @@ -47,7 +47,7 @@ ddog_Configurator *ddog_library_configurator_new_dummy(bool debug_logs, ddog_Cha int posix_spawn_file_actions_addchdir_np(void *file_actions, const char *path); -uint64_t dd_fnv1a_64(const unsigned char *data, uintptr_t len); +uint64_t dd_fnv1a_64(const uint8_t *data, uintptr_t len); const char *ddog_normalize_process_tag_value(ddog_CharSlice tag_value); diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 3439f7bc2b2..0b0f49e3023 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -92,6 +92,16 @@ void ddog_sidecar_transport_drop(struct ddog_SidecarTransport*); */ ddog_MaybeError ddog_sidecar_connect(struct ddog_SidecarTransport **connection); +ddog_MaybeError ddog_sidecar_connect_master(int32_t pid); + +ddog_MaybeError ddog_sidecar_connect_worker(int32_t pid, struct ddog_SidecarTransport **connection); + +ddog_MaybeError ddog_sidecar_shutdown_master_listener(void); + +bool ddog_sidecar_is_master_listener_active(int32_t pid); + +ddog_MaybeError ddog_sidecar_clear_inherited_listener(void); + ddog_MaybeError ddog_sidecar_ping(struct ddog_SidecarTransport **transport); ddog_MaybeError ddog_sidecar_flush_traces(struct ddog_SidecarTransport **transport); diff --git a/libdatadog b/libdatadog index 7f861d8a6cb..cc4a550bf60 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 7f861d8a6cbc1f817598a7e758da868fe0db731f +Subproject commit cc4a550bf6063f80e969332485df806e2c420ebf From 723ad04c0870ddb5eb64196569eee81c14d3d6b8 Mon Sep 17 00:00:00 2001 From: Louis Tricot Date: Fri, 20 Mar 2026 16:22:28 +0100 Subject: [PATCH 5/6] cargo lock --- Cargo.lock | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c19cc5e2aa..6048a3be0ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1280,9 +1280,9 @@ dependencies = [ "build_common 28.0.3", "datadog-live-debugger", "libdd-common 3.0.0", - "libdd-common-ffi", - "log 0.4.25", - "percent-encoding 2.3.1", + "libdd-common-ffi 28.0.3", + "log", + "percent-encoding", "serde_json", "tokio", "tokio-util", @@ -1343,7 +1343,7 @@ dependencies = [ "hyper", "hyper-util", "libdd-common 3.0.0", - "libdd-trace-protobuf", + "libdd-trace-protobuf 2.0.0", "manual_future", "regex", "serde", @@ -1378,7 +1378,7 @@ dependencies = [ "httpmock", "libc 0.2.177", "libdd-common 3.0.0", - "libdd-common-ffi", + "libdd-common-ffi 28.0.3", "libdd-crashtracker", "libdd-crashtracker-ffi", "libdd-data-pipeline", @@ -1423,7 +1423,7 @@ dependencies = [ "http", "libc 0.2.177", "libdd-common 3.0.0", - "libdd-common-ffi", + "libdd-common-ffi 28.0.3", "libdd-crashtracker-ffi", "libdd-dogstatsd-client", "libdd-telemetry", @@ -1466,7 +1466,7 @@ dependencies = [ "lazy_static", "libc 0.2.177", "libdd-common 3.0.0", - "libdd-common-ffi", + "libdd-common-ffi 28.0.3", "libdd-crashtracker-ffi", "libdd-library-config-ffi 0.0.2", "libdd-telemetry", @@ -2859,11 +2859,25 @@ dependencies = [ "chrono", "crossbeam-queue", "function_name", - "hyper 1.6.0", + "hyper", "libdd-common 3.0.0", "serde", ] +[[package]] +name = "libdd-common-ffi" +version = "28.0.3" +source = "git+https://github.com/DataDog/libdatadog?tag=v28.0.3#29b010af2f7556b6beb29d1b89ed54ce6ff86e1f" +dependencies = [ + "anyhow", + "build_common 28.0.3 (git+https://github.com/DataDog/libdatadog?tag=v28.0.3)", + "chrono", + "crossbeam-queue", + "hyper", + "libdd-common 2.0.0", + "serde", +] + [[package]] name = "libdd-crashtracker" version = "1.0.0" @@ -2909,7 +2923,7 @@ dependencies = [ "function_name", "libc 0.2.177", "libdd-common 3.0.0", - "libdd-common-ffi", + "libdd-common-ffi 28.0.3", "libdd-crashtracker", "serde", "serde_json", @@ -3019,8 +3033,8 @@ dependencies = [ "build_common 28.0.3", "constcat", "libdd-common 3.0.0", - "libdd-common-ffi", - "libdd-library-config", + "libdd-common-ffi 28.0.3", + "libdd-library-config 1.1.0", "tempfile", ] @@ -3136,7 +3150,7 @@ dependencies = [ "function_name", "libc 0.2.177", "libdd-common 3.0.0", - "libdd-common-ffi", + "libdd-common-ffi 28.0.3", "libdd-telemetry", "paste", "tempfile", From 2dda0628156e11cdb6d69b9324775528c8915a1b Mon Sep 17 00:00:00 2001 From: Louis Tricot Date: Fri, 20 Mar 2026 17:48:04 +0100 Subject: [PATCH 6/6] deactivate process tags for 8.3 as well --- .../groovy/com/datadog/appsec/php/docker/AppSecContainer.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/docker/AppSecContainer.groovy b/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/docker/AppSecContainer.groovy index 3287e6827bc..a0d5a230a9d 100644 --- a/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/docker/AppSecContainer.groovy +++ b/appsec/tests/integration/src/main/groovy/com/datadog/appsec/php/docker/AppSecContainer.groovy @@ -90,6 +90,7 @@ class AppSecContainer> extends GenericContain withEnv 'DD_TRACE_DEBUG', '1' withEnv 'DD_AUTOLOAD_NO_COMPILE', 'true' // must be exactly 'true' withEnv 'DD_TRACE_GIT_METADATA_ENABLED', '0' + withEnv 'DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED', '0' withEnv 'DD_INSTRUMENTATION_TELEMETRY_ENABLED', '1' // very verbose: withEnv '_DD_DEBUG_SIDECAR_LOG_METHOD', 'file:///tmp/logs/sidecar.log'