Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ext/configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ static bool dd_parse_dbm_mode(zai_str value, zval *decoded_value, bool persisten
ZVAL_LONG(decoded_value, DD_TRACE_DBM_PROPAGATION_SERVICE);
} else if (zai_str_eq_ci_cstr(value, "full")) {
ZVAL_LONG(decoded_value, DD_TRACE_DBM_PROPAGATION_FULL);
} else if (zai_str_eq_ci_cstr(value, "dynamic_service")) {
ZVAL_LONG(decoded_value, DD_TRACE_DBM_PROPAGATION_DYNAMIC_SERVICE);
} else {
return false;
}
Expand Down
1 change: 1 addition & 0 deletions ext/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum ddtrace_dbm_propagation_mode {
DD_TRACE_DBM_PROPAGATION_DISABLED,
DD_TRACE_DBM_PROPAGATION_SERVICE,
DD_TRACE_DBM_PROPAGATION_FULL,
DD_TRACE_DBM_PROPAGATION_DYNAMIC_SERVICE,
};

// To remove in 1.0
Expand Down
4 changes: 3 additions & 1 deletion ext/ddtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -3284,7 +3284,9 @@ PHP_FUNCTION(dd_trace_internal_fn) {
} 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));
zend_string *hash = zend_string_dup(Z_STR_P(container_tags_hash), 1);
ddtrace_process_tags_set_container_tags_hash(hash);
zend_string_release(hash);
RETVAL_TRUE;
} else {
RETVAL_FALSE;
Expand Down
6 changes: 6 additions & 0 deletions ext/ddtrace.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
*/
const DBM_PROPAGATION_FULL = UNKNOWN;

/**
* @var int
* @cvalue DD_TRACE_DBM_PROPAGATION_DYNAMIC_SERVICE
*/
const DBM_PROPAGATION_DYNAMIC_SERVICE = UNKNOWN;

/**
* @var int
* @cvalue DDTRACE_FFE_TYPE_STRING
Expand Down
3 changes: 2 additions & 1 deletion ext/ddtrace_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit ddtrace.stub.php instead.
* Stub hash: 8d552cbb5a25472ccb510275ab86276a29e85d7a */
* Stub hash: b3087c1f239d5aa8ea38f875b7236f47e56a1ca7 */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_trace_method, 0, 3, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, className, IS_STRING, 0)
Expand Down Expand Up @@ -593,6 +593,7 @@ static void register_ddtrace_symbols(int module_number)
REGISTER_LONG_CONSTANT("DDTrace\\DBM_PROPAGATION_DISABLED", DD_TRACE_DBM_PROPAGATION_DISABLED, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DDTrace\\DBM_PROPAGATION_SERVICE", DD_TRACE_DBM_PROPAGATION_SERVICE, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DDTrace\\DBM_PROPAGATION_FULL", DD_TRACE_DBM_PROPAGATION_FULL, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DDTrace\\DBM_PROPAGATION_DYNAMIC_SERVICE", DD_TRACE_DBM_PROPAGATION_DYNAMIC_SERVICE, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DDTrace\\FFE_STRING", DDTRACE_FFE_TYPE_STRING, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DDTrace\\FFE_INT", DDTRACE_FFE_TYPE_INT, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("DDTrace\\FFE_FLOAT", DDTRACE_FFE_TYPE_FLOAT, CONST_PERSISTENT);
Expand Down
6 changes: 4 additions & 2 deletions src/DDTrace/Integrations/DatabaseIntegrationHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ public static function injectDatabaseIntegrationData(HookData $hook, $backend, $
$peerService = $span->meta['peer.service'] ?? '';

// Inject base hash into span tags if enabled
if (dd_trace_env_config("DD_DBM_INJECT_SQL_BASEHASH")) {
if (dd_trace_env_config("DD_DBM_INJECT_SQL_BASEHASH")
|| $propagationMode == \DDTrace\DBM_PROPAGATION_DYNAMIC_SERVICE) {
$baseHash = \DDTrace\System\process_tags_base_hash();
if ($baseHash !== null) {
$span->meta[Tag::PROPAGATED_HASH] = $baseHash;
Expand Down Expand Up @@ -136,7 +137,8 @@ public static function propagateViaSqlComments(
}

// Inject base hash into SQL comment if enabled
if (dd_trace_env_config("DD_DBM_INJECT_SQL_BASEHASH")) {
if (dd_trace_env_config("DD_DBM_INJECT_SQL_BASEHASH")
|| $mode == \DDTrace\DBM_PROPAGATION_DYNAMIC_SERVICE) {
$baseHash = \DDTrace\System\process_tags_base_hash();
if ($baseHash !== null) {
$tags["ddsh"] = $baseHash;
Expand Down
45 changes: 45 additions & 0 deletions tests/Integration/DatabaseMonitoringTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -407,4 +407,49 @@ public function testBaseHashNotInjectedWhenDisabled()
])
]);
}

public function testDynamicServiceMode()
{
// dynamic_service is equivalent to service + DD_DBM_INJECT_SQL_BASEHASH=true:
// service-style comment (no traceparent) plus the base hash, even though
// DD_DBM_INJECT_SQL_BASEHASH is left unset.
self::putEnv('DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED=true');
self::putEnv('DD_DBM_PROPAGATION_MODE=dynamic_service');
self::putEnv('DD_TRACE_DEBUG_PRNG_SEED=42');

\dd_trace_internal_fn('reload_process_tags');
\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);
}

// service-style: a ddsh base hash is injected, but no traceparent
$this->assertRegularExpression(
'/^\/\*dddbs=\'testdb\',ddps=\'phpunit\',ddsh=\'[0-9a-f]+\'\*\/ SELECT 1$/',
$commentedQuery
);

$ddshValue = preg_replace('/^.*ddsh=\'([^\']+)\'.*$/', '$1', $commentedQuery);
$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');

// dynamic_service is not full mode, so the trace-injected marker must be absent
$this->assertArrayNotHasKey('_dd.dbm_trace_injected', $traces[0][1]['meta']);
}
}
Loading