Skip to content

Commit

Permalink
Collect agent info and apply the env for remote config
Browse files Browse the repository at this point in the history
Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
  • Loading branch information
bwoebi committed Nov 6, 2024
1 parent 73e9db0 commit cd70904
Show file tree
Hide file tree
Showing 14 changed files with 195 additions and 14 deletions.
63 changes: 59 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions components-rs/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,8 @@ typedef struct ddog_ContextKey {
enum ddog_MetricType _1;
} ddog_ContextKey;

typedef struct ddog_AgentInfoReader ddog_AgentInfoReader;

typedef struct ddog_AgentRemoteConfigReader ddog_AgentRemoteConfigReader;

typedef struct ddog_AgentRemoteConfigWriter_ShmHandle ddog_AgentRemoteConfigWriter_ShmHandle;
Expand Down
15 changes: 15 additions & 0 deletions components-rs/sidecar.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,19 @@ void ddog_sidecar_reconnect(struct ddog_SidecarTransport **transport,
*/
ddog_CharSlice ddog_sidecar_get_crashtracker_unix_socket_path(void);

/**
* Gets an agent info reader.
*/
struct ddog_AgentInfoReader *ddog_get_agent_info_reader(const struct ddog_Endpoint *endpoint);

/**
* Gets the current agent info environment (or empty if not existing)
*/
ddog_CharSlice ddog_get_agent_info_env(struct ddog_AgentInfoReader *reader, bool *changed);

/**
* Drops the agent info reader.
*/
void ddog_drop_agent_info_reader(struct ddog_AgentInfoReader*);

#endif /* DDOG_SIDECAR_H */
1 change: 1 addition & 0 deletions config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ if test "$PHP_DDTRACE" != "no"; then
dnl ddtrace.c comes first, then everything else alphabetically
DD_TRACE_PHP_SOURCES="$EXTRA_PHP_SOURCES \
ext/ddtrace.c \
ext/agent_info.c \
ext/arrays.c \
ext/auto_flush.c \
ext/autoload_php_files.c \
Expand Down
3 changes: 2 additions & 1 deletion config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ if (PHP_DDTRACE != 'no') {

var version = PHP_VERSION * 100 + PHP_MINOR_VERSION;

var DDTRACE_EXT_SOURCES = "arrays.c";
var DDTRACE_EXT_SOURCES = "agent_info.c";
DDTRACE_EXT_SOURCES += " arrays.c";
DDTRACE_EXT_SOURCES += " auto_flush.c";
DDTRACE_EXT_SOURCES += " autoload_php_files.c";
DDTRACE_EXT_SOURCES += " collect_backtrace.c";
Expand Down
18 changes: 16 additions & 2 deletions dockerfiles/services/request-replayer/src/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ function decodeDogStatsDMetrics($metrics)
define('REQUEST_RC_CONFIGS_FILE', getenv('REQUEST_RC_CONFIGS_FILE') ?: ("$temp_location/rc_configs.json"));
define('REQUEST_METRICS_FILE', getenv('REQUEST_METRICS_FILE') ?: ("$temp_location/metrics.json"));
define('REQUEST_METRICS_LOG_FILE', getenv('REQUEST_METRICS_LOG_FILE') ?: ("$temp_location/metrics-log.txt"));
define('REQUEST_AGENT_INFO_FILE', getenv('REQUEST_AGENT_INFO_FILE') ?: ("$temp_location/agent-info.txt"));

function logRequest($message, $data = '')
{
Expand All @@ -91,8 +92,8 @@ function logRequest($message, $data = '')
}

set_error_handler(function ($number, $message, $errfile, $errline) {
if (error_reporting() == 0) {
return;
if (!($number & error_reporting())) {
return true;
}
logRequest("Triggered error $number $message in $errfile on line $errline: " . (new \Exception)->getTraceAsString());
trigger_error($message, $number);
Expand Down Expand Up @@ -142,6 +143,9 @@ function logRequest($message, $data = '')
if (file_exists(REQUEST_NEXT_RESPONSE_FILE)) {
unlink(REQUEST_NEXT_RESPONSE_FILE);
}
if (file_exists(REQUEST_AGENT_INFO_FILE)) {
unlink(REQUEST_AGENT_INFO_FILE);
}
logRequest('Deleted request log');
break;
case '/next-response':
Expand Down Expand Up @@ -214,6 +218,16 @@ function logRequest($message, $data = '')
file_put_contents(REQUEST_METRICS_FILE, json_encode($allMetrics));
}
break;
case '/set-agent-info':
$raw = file_get_contents('php://input');
file_put_contents(REQUEST_AGENT_INFO_FILE, $raw);
break;
case '/info':
$file = @file_get_contents(REQUEST_AGENT_INFO_FILE) ?: "{}";
logRequest('Requested /info endpoint, returning ' . $file);
header("datadog-agent-state: " . sha1($file));
echo $file;
break;
default:
$headers = getallheaders();
if (isset($headers['X-Datadog-Diagnostic-Check']) || isset($headers['x-datadog-diagnostic-check'])) {
Expand Down
22 changes: 22 additions & 0 deletions ext/agent_info.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "agent_info.h"
#include "ddtrace.h"
#include "sidecar.h"
#include "configuration.h"

ZEND_EXTERN_MODULE_GLOBALS(ddtrace);

void ddtrace_check_agent_info_env() {
if (DDTRACE_G(agent_info_reader) && ZSTR_LEN(get_DD_ENV()) == 0) {
bool changed;
ddog_CharSlice env = ddog_get_agent_info_env(DDTRACE_G(agent_info_reader), &changed);
if (env.len) {
zend_alter_ini_entry_chars(zai_config_memoized_entries[DDTRACE_CONFIG_DD_ENV].ini_entries[0]->name, env.ptr, env.len, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
}
}
}

void ddtrace_agent_info_rinit() {
if (ddtrace_endpoint && !ZSTR_LEN(get_global_DD_ENV())) {
DDTRACE_G(agent_info_reader) = ddog_get_agent_info_reader(ddtrace_endpoint);
}
}
7 changes: 7 additions & 0 deletions ext/agent_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef DD_AGENT_INFO_H
#define DD_AGENT_INFO_H

void ddtrace_check_agent_info_env(void);
void ddtrace_agent_info_rinit(void);

#endif // DD_AGENT_INFO_H
17 changes: 16 additions & 1 deletion ext/ddtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
#include "ddtrace_arginfo.h"
#include "distributed_tracing_headers.h"
#include "live_debugger.h"
#include "agent_info.h"

#if PHP_VERSION_ID < 70200
#pragma pop_macro("ZVAL_EMPTY_STRING")
Expand Down Expand Up @@ -655,6 +656,9 @@ static PHP_GSHUTDOWN_FUNCTION(ddtrace) {
if (ddtrace_globals->remote_config_state) {
ddog_shutdown_remote_config(ddtrace_globals->remote_config_state);
}
if (ddtrace_globals->agent_info_reader) {
ddog_drop_agent_info_reader(ddtrace_globals->agent_info_reader);
}
zai_hook_gshutdown();
if (ddtrace_globals->telemetry_buffer) {
ddog_sidecar_telemetry_buffer_drop(ddtrace_globals->telemetry_buffer);
Expand Down Expand Up @@ -1497,7 +1501,6 @@ static void dd_rinit_once(void) {
static pthread_once_t dd_rinit_once_control = PTHREAD_ONCE_INIT;

static void dd_initialize_request(void) {
DDTRACE_G(request_initialized) = true;
DDTRACE_G(distributed_trace_id) = (ddtrace_trace_id){0};
DDTRACE_G(distributed_parent_trace_id) = 0;
DDTRACE_G(additional_global_tags) = zend_new_array(0);
Expand All @@ -1507,6 +1510,12 @@ static void dd_initialize_request(void) {
zend_hash_init(&DDTRACE_G(propagated_root_span_tags), 8, unused, ZVAL_PTR_DTOR, 0);
zend_hash_init(&DDTRACE_G(tracestate_unknown_dd_keys), 8, unused, ZVAL_PTR_DTOR, 0);

// Check for the env first, before the first RC
ddtrace_check_agent_info_env();

// Do after env check, so that RC data is not updated before RC init
DDTRACE_G(request_initialized) = true;

ddtrace_sidecar_rinit();

// Things that should only run on the first RINIT after each minit.
Expand Down Expand Up @@ -1546,6 +1555,8 @@ static void dd_initialize_request(void) {
}
#endif

ddtrace_agent_info_rinit();

// Reset compile time after request init hook has compiled
ddtrace_compile_time_reset();

Expand Down Expand Up @@ -2240,6 +2251,10 @@ void dd_internal_handle_fork(void) {
ddog_shutdown_remote_config(DDTRACE_G(remote_config_state));
DDTRACE_G(remote_config_state) = NULL;
}
if (DDTRACE_G(agent_info_reader)) {
ddog_drop_agent_info_reader(DDTRACE_G(agent_info_reader));
DDTRACE_G(agent_info_reader) = NULL;
}
ddtrace_seed_prng();
ddtrace_generate_runtime_id();
ddtrace_reset_sidecar_globals();
Expand Down
1 change: 1 addition & 0 deletions ext/ddtrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ ZEND_BEGIN_MODULE_GLOBALS(ddtrace)
ddog_QueueId sidecar_queue_id;
ddog_AgentRemoteConfigReader *agent_config_reader;
ddog_RemoteConfigState *remote_config_state;
ddog_AgentInfoReader *agent_info_reader;
zend_arena *debugger_capture_arena;
ddog_Vec_DebuggerPayload exception_debugger_buffer;
HashTable active_rc_hooks;
Expand Down
20 changes: 15 additions & 5 deletions ext/priority_sampling/priority_sampling.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "ddtrace.h"
#include "span.h"
#include "components/log/log.h"
#include "agent_info.h"

ZEND_EXTERN_MODULE_GLOBALS(ddtrace);

Expand Down Expand Up @@ -217,6 +218,9 @@ static void dd_decide_on_sampling(ddtrace_root_span_data *span) {
bool explicit_rule = true;

if (is_trace_root) {
// when we sample, we need to fetch the env first
ddtrace_check_agent_info_env();

double default_sample_rate = get_DD_TRACE_SAMPLE_RATE();
sample_rate = default_sample_rate >= 0 ? default_sample_rate : 1;

Expand All @@ -227,16 +231,22 @@ static void dd_decide_on_sampling(ddtrace_root_span_data *span) {
} else {
explicit_rule = false;

zval *env = zend_hash_str_find(ddtrace_property_array(&span->property_meta), ZEND_STRL("env"));
if (!env) {
env = &span->property_env;
}

ddtrace_try_read_agent_rate();
// if we have an empty env... we can default to the cluster env.
if (ZSTR_LEN(get_DD_ENV()) && Z_TYPE_P(env) == IS_STRING && Z_STRLEN_P(env) == 0) {
zval_ptr_dtor(env);
ZVAL_STR_COPY(env, get_DD_ENV());
}

if (DDTRACE_G(agent_rate_by_service)) {
zval *env = zend_hash_str_find(ddtrace_property_array(&span->property_meta), ZEND_STRL("env"));
if (!env) {
env = &span->property_env;
}
zval *sample_rate_zv = NULL;
zval *service = &span->property_service;
if (Z_TYPE_P(service) == IS_STRING && env && Z_TYPE_P(env) == IS_STRING) {
if (Z_TYPE_P(service) == IS_STRING && Z_TYPE_P(env) == IS_STRING) {
zend_string *sample_key = zend_strpprintf(0, "service:%.*s,env:%.*s", (int) Z_STRLEN_P(service), Z_STRVAL_P(service),
(int) Z_STRLEN_P(env), Z_STRVAL_P(env));
sample_rate_zv = zend_hash_find(DDTRACE_G(agent_rate_by_service), sample_key);
Expand Down
1 change: 1 addition & 0 deletions ext/serializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "sidecar.h"
#include "live_debugger.h"
#include "exception_serialize.h"
#include "agent_info.h"

ZEND_EXTERN_MODULE_GLOBALS(ddtrace);

Expand Down
2 changes: 1 addition & 1 deletion libdatadog
Submodule libdatadog updated 69 files
+9 −9 .github/workflows/test.yml
+849 −844 Cargo.lock
+1 −1 Cargo.toml
+5,529 −4,559 LICENSE-3rdparty.yml
+2 −4 bin_tests/Cargo.toml
+37 −42 bin_tests/src/bin/crashtracker_bin_test.rs
+0 −15 bin_tests/src/bin/crashtracker_unix_socket_receiver.rs
+3 −8 bin_tests/src/lib.rs
+91 −0 bin_tests/src/modes/behavior.rs
+5 −0 bin_tests/src/modes/mod.rs
+11 −0 bin_tests/src/modes/unix/mod.rs
+29 −0 bin_tests/src/modes/unix/test_000_donothing.rs
+142 −0 bin_tests/src/modes/unix/test_001_sigpipe.rs
+145 −0 bin_tests/src/modes/unix/test_002_sigchld.rs
+123 −0 bin_tests/src/modes/unix/test_003_sigchld_with_exec.rs
+31 −0 bin_tests/src/modes/unix/test_004_donothing_sigstack.rs
+134 −0 bin_tests/src/modes/unix/test_005_sigpipe_sigstack.rs
+138 −0 bin_tests/src/modes/unix/test_006_sigchld_sigstack.rs
+118 −0 bin_tests/src/modes/unix/test_007_chaining.rs
+78 −0 bin_tests/src/modes/unix/test_008_fork.rs
+76 −77 bin_tests/tests/crashtracker_bin_test.rs
+9 −4 crashtracker-ffi/src/collector/datatypes.rs
+4 −33 crashtracker-ffi/src/collector/mod.rs
+6 −1 crashtracker-ffi/src/crash_info/datatypes.rs
+1 −1 crashtracker/Cargo.toml
+11 −45 crashtracker/src/collector/api.rs
+1 −1 crashtracker/src/collector/counters.rs
+416 −237 crashtracker/src/collector/crash_handler.rs
+17 −5 crashtracker/src/collector/emitters.rs
+1 −0 crashtracker/src/collector/mod.rs
+86 −0 crashtracker/src/collector/saguard.rs
+3 −0 crashtracker/src/crash_info/mod.rs
+1 −1 crashtracker/src/crash_info/stacktrace.rs
+6 −1 crashtracker/src/crash_info/telemetry.rs
+16 −18 crashtracker/src/lib.rs
+2 −2 crashtracker/src/receiver.rs
+19 −3 crashtracker/src/shared/configuration.rs
+1 −0 crashtracker/src/shared/constants.rs
+5 −2 data-pipeline/src/agent_info/fetcher.rs
+1 −1 data-pipeline/src/agent_info/mod.rs
+3 −3 data-pipeline/src/agent_info/schema.rs
+23 −15 data-pipeline/src/trace_exporter.rs
+15 −3 ddcommon/src/connector/mod.rs
+216 −0 docs/RFCs/0003-crashtracker-design.md
+2 −0 dogstatsd/Cargo.toml
+29 −2 dogstatsd/src/dogstatsd.rs
+43 −34 dogstatsd/src/metric.rs
+1 −1 examples/ffi/crashtracking.c
+7 −7 examples/ffi/symbolizer.cpp
+1 −1 ipc/Cargo.toml
+12 −8 ipc/src/platform/unix/mem_handle.rs
+5 −1 ipc/src/platform/unix/mem_handle_macos.rs
+5 −1 ipc/src/platform/windows/mem_handle.rs
+5 −5 ruby/Rakefile
+1 −1 ruby/lib/libdatadog/version.rb
+3 −0 serverless/Cargo.toml
+27 −4 serverless/src/main.rs
+47 −1 sidecar-ffi/src/lib.rs
+1 −0 sidecar/Cargo.toml
+243 −0 sidecar/src/service/agent_info.rs
+1 −0 sidecar/src/service/mod.rs
+4 −0 sidecar/src/service/serialized_tracer_header_tags.rs
+4 −0 sidecar/src/service/session_info.rs
+8 −0 sidecar/src/service/sidecar_server.rs
+1 −1 symbolizer-ffi/Cargo.toml
+121 −60 symbolizer-ffi/src/blazesym.h
+2 −0 trace-utils/src/send_data/mod.rs
+42 −1 trace-utils/src/tracer_header_tags.rs
+1 −2 trace-utils/tests/test_send_data.rs
37 changes: 37 additions & 0 deletions tests/ext/request-replayer/dd_trace_agent_env.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
--TEST--
DDTrace\ExceptionSpanEvent serialization with overridden attributes
--SKIPIF--
<?php include __DIR__ . '/../includes/skipif_no_dev_env.inc'; ?>
<?php
echo "nocache\n";
$ctx = stream_context_create([
'http' => [
'method' => 'PUT',
"header" => [
"Content-Type: application/json",
"X-Datadog-Test-Session-Token: dd_trace_agent_env",
],
'content' => '{"config":{"default_env":"test_env"}}'
]
]);
file_get_contents("http://request-replayer/set-agent-info", false, $ctx);
?>
--ENV--
DD_AGENT_HOST=request-replayer
DD_TRACE_AGENT_PORT=80
DD_TRACE_AGENT_FLUSH_INTERVAL=333
DD_TRACE_GENERATE_ROOT_SPAN=0
--INI--
datadog.env=
datadog.trace.agent_test_session_token=dd_trace_agent_env
--FILE--
<?php

$span = \DDTrace\start_span();
usleep(500000);
\DDTrace\close_span();
var_dump($span->env);

?>
--EXPECTF--
string(8) "test_env"

0 comments on commit cd70904

Please sign in to comment.