Skip to content
Draft
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
3 changes: 2 additions & 1 deletion components-rs/ddtrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ bool ddog_remote_configs_service_env_change(struct ddog_RemoteConfigState *remot
ddog_CharSlice service,
ddog_CharSlice env,
ddog_CharSlice version,
const struct ddog_Vec_Tag *tags);
const struct ddog_Vec_Tag *tags,
const struct ddog_Vec_Tag *process_tags);

bool ddog_remote_config_alter_dynamic_config(struct ddog_RemoteConfigState *remote_config,
ddog_CharSlice config,
Expand Down
2 changes: 2 additions & 0 deletions components-rs/remote_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,12 +494,14 @@ pub extern "C" fn ddog_remote_configs_service_env_change(
env: CharSlice,
version: CharSlice,
tags: &libdd_common_ffi::Vec<Tag>,
process_tags: &libdd_common_ffi::Vec<Tag>,
) -> bool {
let new_target = Target {
service: service.to_utf8_lossy().to_string(),
env: env.to_utf8_lossy().to_string(),
app_version: version.to_utf8_lossy().to_string(),
tags: tags.as_slice().to_vec(),
process_tags: process_tags.as_slice().to_vec(),
};

if let Some(target) = remote_config.manager.get_target() {
Expand Down
29 changes: 29 additions & 0 deletions ext/process_tags.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ typedef struct {
size_t count;
size_t capacity;
zend_string *serialized;
ddog_Vec_Tag vec;
} process_tags_t;

static process_tags_t process_tags = {0};
Expand Down Expand Up @@ -190,12 +191,35 @@ static void serialize_process_tags(void) {
}

smart_str_free(&buf);

process_tags.vec = ddog_Vec_Tag_new();
for (size_t i = 0; i < process_tags.count; i++) {
const char* key = process_tags.tag_list[i].key;
const char* value = process_tags.tag_list[i].value;

UNUSED(ddog_Vec_Tag_push(&process_tags.vec,
(ddog_CharSlice) {.ptr = key, .len = strlen(key)},
(ddog_CharSlice) {.ptr = value, .len = strlen(value)}
));
}
}

zend_string *ddtrace_process_tags_get_serialized(void) {
return (ddtrace_process_tags_enabled() && process_tags.serialized) ? process_tags.serialized : ZSTR_EMPTY_ALLOC();
}

const ddog_Vec_Tag *ddtrace_process_tags_get_vec(void) {
if (ddtrace_process_tags_enabled()) {
return &process_tags.vec;
}

static ddog_Vec_Tag empty_vec;
if (!empty_vec.ptr) {
empty_vec = ddog_Vec_Tag_new();
}
return &empty_vec;
}

bool ddtrace_process_tags_enabled(void){
return get_global_DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED();
}
Expand Down Expand Up @@ -224,5 +248,10 @@ void ddtrace_process_tags_mshutdown(void) {
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));
}
6 changes: 6 additions & 0 deletions ext/process_tags.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <stdbool.h>
#include "Zend/zend_types.h"
#include "ddtrace_export.h"
#include "components-rs/common.h"


// Called at first RINIT to collect process tags
void ddtrace_process_tags_first_rinit(void);
Expand All @@ -18,4 +20,8 @@ bool ddtrace_process_tags_enabled(void);
// Returns NULL if disabled or not yet collected
DDTRACE_PUBLIC zend_string *ddtrace_process_tags_get_serialized(void);

// Get a pointer to the process tags Vec<Tag>
// Returns a pointer to an empty Vec if disabled or not yet collected
const ddog_Vec_Tag *ddtrace_process_tags_get_vec(void);

#endif // DD_PROCESS_TAGS_H
4 changes: 3 additions & 1 deletion ext/sidecar.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,9 +528,11 @@ void ddtrace_sidecar_submit_root_span_data_direct(ddog_SidecarTransport **transp
}
ddog_CharSlice version_slice = dd_zend_string_to_CharSlice(version_string);

const ddog_Vec_Tag *process_tags = ddtrace_process_tags_get_vec();

bool changed = true;
if (DDTRACE_G(remote_config_state)) {
changed = ddog_remote_configs_service_env_change(DDTRACE_G(remote_config_state), service_slice, env_slice, version_slice, &DDTRACE_G(active_global_tags));
changed = ddog_remote_configs_service_env_change(DDTRACE_G(remote_config_state), service_slice, env_slice, version_slice, &DDTRACE_G(active_global_tags), process_tags);
if (!changed && root) {
// ddog_remote_configs_service_env_change() generally only processes configs if they changed. However, upon request initialization it may be identical to the previous request.
// However, at request shutdown some configs are unloaded. Explicitly forcing a processing step ensures these are re-loaded.
Expand Down
2 changes: 1 addition & 1 deletion libdatadog
Submodule libdatadog updated 166 files
2 changes: 1 addition & 1 deletion tests/ext/crashtracker_segfault.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ $rr->waitForRequest(function ($request) {
if (!isset($payload["message"]["metadata"])) {
break;
}
if (($payload["message"]["kind"] ?? "") == "Crash ping") {
if (($payload["is_crash"] ?? false) !== true) {
continue;
}

Expand Down
29 changes: 29 additions & 0 deletions tests/ext/includes/request_replayer.inc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,26 @@ class RequestReplayer
} while (true);
}

public function waitForRcRequest($matcher)
{
$i = 0;
do {
if ($i++ == $this->maxIteration) {
throw new Exception("wait for replay timeout");
}
usleep($this->flushInterval);

$requests = $this->replayAllRcRequests();
if (is_array($requests)) {
foreach ($requests as $request) {
if ($matcher($request)) {
return $request;
}
}
}
} while (true);
}

public function waitForDataAndReplay($ignoreTelemetry = true)
{
$i = 0;
Expand Down Expand Up @@ -104,6 +124,15 @@ class RequestReplayer
])), true);
}

public function replayAllRcRequests()
{
return json_decode(file_get_contents($this->endpoint . '/replay-rc-requests', false, stream_context_create([
"http" => [
"header" => "X-Datadog-Test-Session-Token: " . ini_get("datadog.trace.agent_test_session_token"),
],
])), true);
}

public function clearDumpedData()
{
file_get_contents($this->endpoint . '/clear-dumped-data', false, stream_context_create([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ array(2) {
["_dd.di.ret.probe_id"]=>
string(1) "3"
}
string(%d) "/debugger/v1/input?ddtags=debugger_version:1.%s,env:none,version:,runtime_id:%s-%s-%s-%s-%s,host_name:%s"
string(%d) "/debugger/v1/diagnostics?ddtags=debugger_version:1.%s,env:none,version:,runtime_id:%s-%s-%s-%s-%s,host_name:%s"
array(1) {
[0]=>
array(6) {
Expand Down
68 changes: 68 additions & 0 deletions tests/ext/remote_config/process_tags.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
--TEST--
Test remote config request payload
--SKIPIF--
<?php include __DIR__ . '/../includes/skipif_no_dev_env.inc'; ?>
--ENV--
DD_AGENT_HOST=request-replayer
DD_TRACE_AGENT_PORT=80
DD_TRACE_GENERATE_ROOT_SPAN=0
DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS=0.01
DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED=1
--INI--
datadog.trace.agent_test_session_token=remote-config/check_payload
--FILE--
<?php

require __DIR__ . "/remote_config.inc";
include __DIR__ . '/../includes/request_replayer.inc';

reset_request_replayer();
$rr = new RequestReplayer();

// Start a span to trigger RC
\DDTrace\start_span();

$path = put_dynamic_config_file([
"log_injection_enabled" => true,
]);

try {
$request = $rr->waitForRcRequest(function($req) {
if (strpos($req["uri"], '/v0.7/config') === false) {
return false;
}

$body = json_decode($req["body"], true);
return isset($body["client"]["client_tracer"]["process_tags"])
&& !empty($body["client"]["client_tracer"]["process_tags"]);
});
$body = json_decode($request["body"], true);
} catch (Exception $e) {
echo "ERROR: No RC request found\n";
exit(1);
}

if (!isset($body["client"]["client_tracer"]["process_tags"])) {
echo "ERROR: Missing 'process_tags' field\n";
exit(1);
}

$process_tags = $body["client"]["client_tracer"]["process_tags"];
foreach ($process_tags as $tag) {
echo $tag . PHP_EOL;
}

del_rc_file($path);

?>
--CLEAN--
<?php
require __DIR__ . "/remote_config.inc";
reset_request_replayer();
?>
--EXPECTF--
entrypoint.basedir:remote_config
entrypoint.name:process_tags
entrypoint.type:script
entrypoint.workdir:%s
runtime.sapi:cli
14 changes: 12 additions & 2 deletions tests/ext/telemetry/process_tags.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,18 @@ for ($i = 0; $i < 300; ++$i) {
foreach (file(__DIR__ . '/process-tags-telemetry.out') as $l) {
if ($l) {
$json = json_decode($l, true);
var_dump($json["application"]["process_tags"]);
break 2;
if (!is_array($json)) {
continue;
}
$batch = (isset($json["request_type"]) && $json["request_type"] == "message-batch")
? $json["payload"]
: [$json];
foreach ($batch as $json) {
if (isset($json["application"]["process_tags"])) {
var_dump($json["application"]["process_tags"]);
break 3;
}
}
}
}
}
Expand Down
Loading