From b9cdb0ab9e30c9482e3dfc13e0b7336e52d34b2a Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 15 Nov 2024 17:31:07 +0100 Subject: [PATCH] Collect agent info and apply the env for remote config (#2930) * Collect agent info and apply the env for remote config Signed-off-by: Bob Weinand * Adapt to latest libdatadog * Fix double alloc Signed-off-by: Bob Weinand * Fix tests Signed-off-by: Bob Weinand * Exclude PHP 7.2 and 7.3 from tests for agent_env Signed-off-by: Bob Weinand --------- Signed-off-by: Bob Weinand --- Cargo.lock | 92 ++++++++++++++----- Makefile | 2 +- components-rs/common.h | 15 ++- components-rs/crashtracker.h | 16 ++-- components-rs/sidecar.h | 19 ++++ config.m4 | 1 + config.w32 | 3 +- .../services/request-replayer/src/index.php | 18 +++- ext/agent_info.c | 22 +++++ ext/agent_info.h | 7 ++ ext/ddtrace.c | 17 +++- ext/ddtrace.h | 1 + ext/priority_sampling/priority_sampling.c | 20 +++- ext/serializer.c | 1 + ext/signals.c | 10 +- libdatadog | 2 +- .../request-replayer/dd_trace_agent_env.phpt | 44 +++++++++ 17 files changed, 241 insertions(+), 49 deletions(-) create mode 100644 ext/agent_info.c create mode 100644 ext/agent_info.h create mode 100644 tests/ext/request-replayer/dd_trace_agent_env.phpt diff --git a/Cargo.lock b/Cargo.lock index e36762670e..68e1cb81ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ - "gimli 0.31.1", + "gimli", ] [[package]] @@ -127,6 +127,12 @@ version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "arrayref" version = "0.3.7" @@ -583,14 +589,15 @@ checksum = "a1d084b0137aaa901caf9f1e8b21daa6aa24d41cd806e111335541eff9683bd6" [[package]] name = "blazesym" -version = "0.2.0-rc.0" +version = "0.2.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "519a0f9df086d6c4f44576558523a777c984454daeb124bee79bde69227360c4" +checksum = "deb42921128af76c2ced7c723edfb0411695a96d2bfcdda21c3a6543f98b715a" dependencies = [ "cpp_demangle", - "gimli 0.30.0", + "gimli", "libc 0.2.159", - "miniz_oxide 0.7.2", + "memmap2", + "miniz_oxide 0.8.0", "rustc-demangle", ] @@ -855,9 +862,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.28" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "jobserver", "libc 0.2.159", @@ -1119,6 +1126,7 @@ dependencies = [ "ciborium", "clap", "criterion-plot", + "csv", "is-terminal", "itertools 0.10.5", "num-traits", @@ -1284,6 +1292,35 @@ dependencies = [ "syn 2.0.71", ] +[[package]] +name = "data-pipeline" +version = "0.0.1" +dependencies = [ + "anyhow", + "arc-swap", + "bytes", + "criterion", + "datadog-ddsketch", + "datadog-trace-normalization", + "datadog-trace-obfuscation", + "datadog-trace-protobuf", + "datadog-trace-utils", + "ddcommon 0.0.1", + "dogstatsd-client", + "either", + "futures", + "httpmock", + "hyper 0.14.28", + "log", + "rand 0.8.5", + "rmp-serde", + "serde", + "serde_json", + "tokio", + "tokio-util", + "uuid", +] + [[package]] name = "datadog-alloc" version = "10.0.0" @@ -1532,6 +1569,7 @@ dependencies = [ "cadence", "chrono", "console-subscriber", + "data-pipeline", "datadog-crashtracker", "datadog-dynamic-configuration", "datadog-ipc", @@ -1624,6 +1662,24 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "datadog-trace-obfuscation" +version = "0.0.1" +dependencies = [ + "anyhow", + "criterion", + "datadog-trace-protobuf", + "datadog-trace-utils", + "ddcommon 0.0.1", + "duplicate", + "log", + "percent-encoding", + "regex", + "serde", + "serde_json", + "url", +] + [[package]] name = "datadog-trace-protobuf" version = "0.0.1" @@ -1676,6 +1732,7 @@ name = "ddcommon" version = "0.0.1" dependencies = [ "anyhow", + "cc", "futures", "futures-core", "futures-util", @@ -1926,7 +1983,6 @@ dependencies = [ "datadog-trace-protobuf", "ddcommon 0.0.1", "http 0.2.11", - "hyper 0.14.28", "serde", "tracing", ] @@ -1961,9 +2017,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "ena" @@ -2326,21 +2382,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.30.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e1d97fbe9722ba9bbd0c97051c2956e726562b61f86a25a4360398a40edfc9" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" dependencies = [ "fallible-iterator", "indexmap 2.2.6", "stable_deref_trait", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "glibc_version" version = "0.1.2" @@ -3215,7 +3265,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", - "simd-adler32", ] [[package]] @@ -3225,6 +3274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -5648,9 +5698,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.7.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom", "serde", diff --git a/Makefile b/Makefile index ce91214992..1037ea3bf2 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ RUN_TESTS_CMD := REPORT_EXIT_STATUS=1 TEST_PHP_SRCDIR=$(PROJECT_ROOT) USE_TRACKE C_FILES = $(shell find components components-rs ext src/dogstatsd zend_abstract_interface -name '*.c' -o -name '*.h' | awk '{ printf "$(BUILD_DIR)/%s\n", $$1 }' ) TEST_FILES = $(shell find tests/ext -name '*.php*' -o -name '*.inc' -o -name '*.json' -o -name 'CONFLICTS' | awk '{ printf "$(BUILD_DIR)/%s\n", $$1 }' ) -RUST_FILES = $(BUILD_DIR)/Cargo.toml $(BUILD_DIR)/Cargo.lock $(shell find components-rs -name '*.c' -o -name '*.rs' -o -name 'Cargo.toml' | awk '{ printf "$(BUILD_DIR)/%s\n", $$1 }' ) $(shell find libdatadog/{alloc,build-common,crashtracker,crashtracker-ffi,ddcommon,ddcommon-ffi,ddsketch,ddtelemetry,ddtelemetry-ffi,dogstatsd-client,dynamic-configuration,ipc,live-debugger,live-debugger-ffi,remote-config,sidecar,sidecar-ffi,spawn_worker,tinybytes,tools/{cc_utils,sidecar_mockgen},trace-*,Cargo.toml} -type f \( -path "*/src*" -o -path "*/examples*" -o -path "*Cargo.toml" -o -path "*/build.rs" -o -path "*/tests/dataservice.rs" -o -path "*/tests/service_functional.rs" \) -not -path "*/ipc/build.rs" -not -path "*/sidecar-ffi/build.rs") +RUST_FILES = $(BUILD_DIR)/Cargo.toml $(BUILD_DIR)/Cargo.lock $(shell find components-rs -name '*.c' -o -name '*.rs' -o -name 'Cargo.toml' | awk '{ printf "$(BUILD_DIR)/%s\n", $$1 }' ) $(shell find libdatadog/{alloc,build-common,crashtracker,crashtracker-ffi,data-pipeline,ddcommon,ddcommon-ffi,ddsketch,ddtelemetry,ddtelemetry-ffi,dogstatsd-client,dynamic-configuration,ipc,live-debugger,live-debugger-ffi,remote-config,sidecar,sidecar-ffi,spawn_worker,tinybytes,tools/{cc_utils,sidecar_mockgen},trace-*,Cargo.toml} -type f \( -path "*/src*" -o -path "*/examples*" -o -path "*Cargo.toml" -o -path "*/build.rs" -o -path "*/tests/dataservice.rs" -o -path "*/tests/service_functional.rs" \) -not -path "*/ipc/build.rs" -not -path "*/sidecar-ffi/build.rs") ALL_OBJECT_FILES = $(C_FILES) $(RUST_FILES) $(BUILD_DIR)/Makefile TEST_OPCACHE_FILES = $(shell find tests/opcache -name '*.php*' -o -name '.gitkeep' | awk '{ printf "$(BUILD_DIR)/%s\n", $$1 }' ) TEST_STUB_FILES = $(shell find tests/ext -type d -name 'stubs' -exec find '{}' -type f \; | awk '{ printf "$(BUILD_DIR)/%s\n", $$1 }' ) diff --git a/components-rs/common.h b/components-rs/common.h index 99d9c66a7c..bedd9cb5f2 100644 --- a/components-rs/common.h +++ b/components-rs/common.h @@ -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; @@ -957,14 +959,23 @@ typedef struct ddog_crasht_Slice_CharSlice { typedef struct ddog_crasht_Config { struct ddog_crasht_Slice_CharSlice additional_files; bool create_alt_stack; + bool use_alt_stack; /** * The endpoint to send the crash report to (can be a file://). * If None, the crashtracker will infer the agent host from env variables. */ const struct ddog_Endpoint *endpoint; enum ddog_crasht_StacktraceCollection resolve_frames; - uint64_t timeout_secs; - bool wait_for_receiver; + /** + * Timeout in milliseconds before the signal handler starts tearing things down to return. + * This is given as a uint32_t, but the actual timeout needs to fit inside of an i32 (max + * 2^31-1). This is a limitation of the various interfaces used to guarantee the timeout. + */ + uint32_t timeout_ms; + /** + * Optional filename for a unix domain socket if the receiver is used asynchonously + */ + ddog_CharSlice optional_unix_socket_filename; } ddog_crasht_Config; typedef struct ddog_crasht_EnvVar { diff --git a/components-rs/crashtracker.h b/components-rs/crashtracker.h index 42c18798c3..a3053affaa 100644 --- a/components-rs/crashtracker.h +++ b/components-rs/crashtracker.h @@ -39,8 +39,7 @@ DDOG_CHECK_RETURN struct ddog_crasht_Result ddog_crasht_shutdown(void); * Reinitialize the crash-tracking infrastructure after a fork. * This should be one of the first things done after a fork, to minimize the * chance that a crash occurs between the fork, and this call. - * In particular, reset the counters that track the profiler state machine, - * and start a new receiver to collect data from this fork. + * In particular, reset the counters that track the profiler state machine. * NOTE: An alternative design would be to have a 1:many sidecar listening on a * socket instead of 1:1 receiver listening on a pipe, but the only real * advantage would be to have fewer processes in `ps -a`. @@ -73,15 +72,15 @@ struct ddog_crasht_Result ddog_crasht_update_on_fork(struct ddog_crasht_Config c * unexpected crash-handling behaviour. */ DDOG_CHECK_RETURN -struct ddog_crasht_Result ddog_crasht_init_with_receiver(struct ddog_crasht_Config config, - struct ddog_crasht_ReceiverConfig receiver_config, - struct ddog_crasht_Metadata metadata); +struct ddog_crasht_Result ddog_crasht_init(struct ddog_crasht_Config config, + struct ddog_crasht_ReceiverConfig receiver_config, + struct ddog_crasht_Metadata metadata); /** - * Initialize the crash-tracking infrastructure, writing to an unix socket in case of crash. + * Initialize the crash-tracking infrastructure without launching the receiver. * * # Preconditions - * None. + * Requires `config` to be given with a `unix_socket_path`, which is normally optional. * # Safety * Crash-tracking functions are not reentrant. * No other crash-handler functions should be called concurrently. @@ -90,8 +89,7 @@ struct ddog_crasht_Result ddog_crasht_init_with_receiver(struct ddog_crasht_Conf * unexpected crash-handling behaviour. */ DDOG_CHECK_RETURN -struct ddog_crasht_Result ddog_crasht_init_with_unix_socket(struct ddog_crasht_Config config, - ddog_CharSlice socket_path, +struct ddog_crasht_Result ddog_crasht_init_without_receiver(struct ddog_crasht_Config config, struct ddog_crasht_Metadata metadata); /** diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index d68d2d4901..248113edbc 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -33,6 +33,10 @@ void ddog_ph_file_drop(struct ddog_NativeFile ph); ddog_MaybeError ddog_alloc_anon_shm_handle(uintptr_t size, struct ddog_ShmHandle **handle); +ddog_MaybeError ddog_alloc_anon_shm_handle_named(uintptr_t size, + struct ddog_ShmHandle **handle, + ddog_CharSlice name); + ddog_MaybeError ddog_map_shm(struct ddog_ShmHandle *handle, struct ddog_MappedMem_ShmHandle **mapped, void **pointer, @@ -306,4 +310,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 */ diff --git a/config.m4 b/config.m4 index 88ea035020..0ea4e1ef2f 100644 --- a/config.m4 +++ b/config.m4 @@ -162,6 +162,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 \ diff --git a/config.w32 b/config.w32 index 9f37c9ef8f..5c00f88e32 100644 --- a/config.w32 +++ b/config.w32 @@ -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"; diff --git a/dockerfiles/services/request-replayer/src/index.php b/dockerfiles/services/request-replayer/src/index.php index 5afba6fb99..9fe8eaff56 100644 --- a/dockerfiles/services/request-replayer/src/index.php +++ b/dockerfiles/services/request-replayer/src/index.php @@ -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 = '') { @@ -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); @@ -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': @@ -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'])) { diff --git a/ext/agent_info.c b/ext/agent_info.c new file mode 100644 index 0000000000..4c2f8d6e3f --- /dev/null +++ b/ext/agent_info.c @@ -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 && !DDTRACE_G(agent_info_reader) && !ZSTR_LEN(get_global_DD_ENV())) { + DDTRACE_G(agent_info_reader) = ddog_get_agent_info_reader(ddtrace_endpoint); + } +} diff --git a/ext/agent_info.h b/ext/agent_info.h new file mode 100644 index 0000000000..e0c4e10fb1 --- /dev/null +++ b/ext/agent_info.h @@ -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 diff --git a/ext/ddtrace.c b/ext/ddtrace.c index bd97d6115d..3e54a71422 100644 --- a/ext/ddtrace.c +++ b/ext/ddtrace.c @@ -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") @@ -662,6 +663,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); @@ -1526,7 +1530,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); @@ -1536,6 +1539,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. @@ -1575,6 +1584,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(); @@ -2269,6 +2280,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(); diff --git a/ext/ddtrace.h b/ext/ddtrace.h index 8f1c14b2f2..481acc43ba 100644 --- a/ext/ddtrace.h +++ b/ext/ddtrace.h @@ -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; diff --git a/ext/priority_sampling/priority_sampling.c b/ext/priority_sampling/priority_sampling.c index b1cb69d6ca..efff1f4800 100644 --- a/ext/priority_sampling/priority_sampling.c +++ b/ext/priority_sampling/priority_sampling.c @@ -13,6 +13,7 @@ #include "ddtrace.h" #include "span.h" #include "components/log/log.h" +#include "agent_info.h" ZEND_EXTERN_MODULE_GLOBALS(ddtrace); @@ -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; @@ -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); diff --git a/ext/serializer.c b/ext/serializer.c index 328e140ed8..b4cdac6cdf 100644 --- a/ext/serializer.c +++ b/ext/serializer.c @@ -44,6 +44,7 @@ #include "sidecar.h" #include "live_debugger.h" #include "exception_serialize.h" +#include "agent_info.h" ZEND_EXTERN_MODULE_GLOBALS(ddtrace); diff --git a/ext/signals.c b/ext/signals.c index 4c9e6512b7..c5d85406f0 100644 --- a/ext/signals.c +++ b/ext/signals.c @@ -120,11 +120,10 @@ static void ddtrace_init_crashtracker() { ddog_crasht_Config config = { .endpoint = agent_endpoint, - .timeout_secs = 5, + .timeout_ms = 5000, .resolve_frames = DDOG_CRASHT_STACKTRACE_COLLECTION_ENABLED_WITH_INPROCESS_SYMBOLS, - // Likely running in a container, so wait until the report is uploaded. - // Otherwise, the container shutdown may stop the sidecar before it has finished uploading the crash report. - .wait_for_receiver = getpid() == 1, + .optional_unix_socket_filename = socket_path, + .additional_files = {0}, }; ddog_Vec_Tag tags = ddog_Vec_Tag_new(); @@ -151,9 +150,8 @@ static void ddtrace_init_crashtracker() { }; ddtrace_crashtracker_check_result( - ddog_crasht_init_with_unix_socket( + ddog_crasht_init_without_receiver( config, - socket_path, metadata ), "Cannot initialize CrashTracker" diff --git a/libdatadog b/libdatadog index 356f76a818..75b1ab55b8 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 356f76a818d164c954d2a09e54e2e8c41537a053 +Subproject commit 75b1ab55b84f1fa22165e73241e7f0ec4cd12228 diff --git a/tests/ext/request-replayer/dd_trace_agent_env.phpt b/tests/ext/request-replayer/dd_trace_agent_env.phpt new file mode 100644 index 0000000000..0861febcfc --- /dev/null +++ b/tests/ext/request-replayer/dd_trace_agent_env.phpt @@ -0,0 +1,44 @@ +--TEST-- +Assert that the default environment can be read from agent info +--SKIPIF-- + += 80100) { + 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-- +env); + +?> +--EXPECTF-- +string(8) "test_env"