From 893b467313673b60621773f5f438ccbe7a3c4ae4 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Fri, 12 Jun 2026 16:51:08 +0200 Subject: [PATCH 01/32] wip: first draft Signed-off-by: Alexandre Rulleau --- ext/signals.c | 1 + src/api/GlobalTracer.php | 3 + tracer/configuration.h | 1 - tracer/ddtrace.stub.php | 138 ++++++++++++++++---------------------- tracer/dogstatsd_client.c | 1 + tracer/span_stats.c | 42 +++--------- 6 files changed, 73 insertions(+), 113 deletions(-) diff --git a/ext/signals.c b/ext/signals.c index 2432234f896..61676ad0f55 100644 --- a/ext/signals.c +++ b/ext/signals.c @@ -261,6 +261,7 @@ void datadog_signals_first_rinit(void) { bool install_crashtracker = get_DD_INSTRUMENTATION_TELEMETRY_ENABLED() && get_DD_CRASHTRACKING_ENABLED(); bool install_backtrace_handler = get_DD_TRACE_HEALTH_METRICS_ENABLED(); + // TODO: Remove this since we have crashtracking now #if DATADOG_HAVE_BACKTRACE install_backtrace_handler |= get_DD_LOG_BACKTRACE(); #endif diff --git a/src/api/GlobalTracer.php b/src/api/GlobalTracer.php index a3bd94eb18a..339535b453e 100644 --- a/src/api/GlobalTracer.php +++ b/src/api/GlobalTracer.php @@ -9,6 +9,9 @@ use DDTrace\Contracts\Tracer as TracerInterface; +/* + * @deprecated This class is deprecated, you should use the Otel or the extension API instead. + */ final class GlobalTracer { /** diff --git a/tracer/configuration.h b/tracer/configuration.h index c6fb9dfe3fc..4bf4312f8da 100644 --- a/tracer/configuration.h +++ b/tracer/configuration.h @@ -117,7 +117,6 @@ CONFIG(BOOL, DD_TRACE_AGENT_DEBUG_VERBOSE_CURL, "false", .ini_change = zai_config_system_ini_change) \ CONFIG(BOOL, DD_TRACE_DEBUG_CURL_OUTPUT, "false", .ini_change = zai_config_system_ini_change) \ CONFIG(INT, DD_TRACE_BETA_HIGH_MEMORY_PRESSURE_PERCENT, "80", .ini_change = zai_config_system_ini_change) \ - CONFIG(BOOL, DD_TRACE_WARN_LEGACY_DD_TRACE, "true") \ CONFIG(BOOL, DD_TRACE_RETAIN_THREAD_CAPABILITIES, "false", .ini_change = zai_config_system_ini_change) \ CONFIG(STRING, DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP, DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP_DEFAULT) \ CONFIG(BOOL, DD_TRACE_MEMCACHED_OBFUSCATION, "true") \ diff --git a/tracer/ddtrace.stub.php b/tracer/ddtrace.stub.php index adac5b1f10c..84a26703f69 100644 --- a/tracer/ddtrace.stub.php +++ b/tracer/ddtrace.stub.php @@ -73,7 +73,7 @@ final class FfeResult { public ?int $configVersion = null; } - class SpanEvent implements \JsonSerializable { + class SpanEvent { /** * SpanEvent constructor. * @@ -97,11 +97,6 @@ public function __construct(string $name, array $attributes = [], ?int $timestam * @var int The event start time in nanoseconds, if not provided set the current Unix timestamp */ public int $timestamp; - - /** - * @return mixed - */ - public function jsonSerialize(): mixed {} } class ExceptionSpanEvent extends SpanEvent { @@ -119,7 +114,7 @@ public function __construct(\Throwable $exception, array $attributes = []) {} public \Throwable $exception; } - class SpanLink implements \JsonSerializable { + class SpanLink { /** * @var string $traceId A 32-character, lower-case hexadecimal encoded string of the linked trace ID. This field * shouldn't be directly assigned an id from SpanData. Use the SpanData::getLink() method instead. @@ -147,11 +142,6 @@ class SpanLink implements \JsonSerializable { */ public int $droppedAttributesCount; - /** - * @return mixed - */ - public function jsonSerialize(): mixed {} - /** * Consumes distributed tracing headers, from which a span link will be constructed. * @@ -173,6 +163,15 @@ class GitMetadata { public string $repositoryUrl = ""; } + class SpanKind { + const UNSPECIFIED = 0; + const INTERNAL = 1; + const SERVER = 2; + const CLIENT = 3; + const PRODUCER = 4; + const CONSUMER = 5; + } + class SpanData { /** * @var string|null The span name @@ -190,18 +189,6 @@ class SpanData { */ public string|null $service = ""; - /** - * @var string The environment you are tracing. Defaults to active environment at the time of span creation - * (i.e., the parent span), or datadog.env initialization settings if no parent exists - */ - public string $env = ""; - - /** - * @var string The version of the application you are tracing. Defaults to active version at the time of - * span creation (i.e., the parent span), or datadog.version initialization settings if no parent exists - */ - public string $version = ""; - /** * @var string[] Meta struct can be used to send any data to the backend. The peculiarity of meta struct is * that the values are encoded with msgpack when sent to the agent. The values are first encoded to msgpack @@ -296,6 +283,24 @@ public function hexId(): string {} * Baggage is a key-value store, which means it lets you propagate any data you like alongside context regardless of trace ids existence. */ public array $baggage = []; + + /** + * @var string The environment you are tracing. Defaults to active environment at the time of span creation + * (i.e., the parent span), or datadog.env initialization settings if no parent exists + */ + public string $env = ""; + + /** + * @var string The version of the application you are tracing. Defaults to active version at the time of + * span creation (i.e., the parent span), or datadog.version initialization settings if no parent exists + */ + public string $version = ""; + + public string $component = ""; + + public int $spanKind = 0; + + public array $attributes = []; } class InferredSpanData extends SpanData {} @@ -316,6 +321,8 @@ class RootSpanData extends SpanData { */ public int $samplingPriority = \DD_TRACE_PRIORITY_SAMPLING_UNKNOWN; + public int $samplingMechanism = 0; + /** * @var int The unmodified sampling priority as inherited directly through distributed tracing. */ @@ -353,6 +360,20 @@ class RootSpanData extends SpanData { public GitMetadata|null $gitMetadata = null; public InferredSpanData|null $inferredSpan = null; + + /** + * @var string The environment you are tracing. Defaults to active environment at the time of span creation + * (i.e., the parent span), or datadog.env initialization settings if no parent exists + */ + public string $env = ""; + + /** + * @var string The version of the application you are tracing. Defaults to active version at the time of + * span creation (i.e., the parent span), or datadog.version initialization settings if no parent exists + */ + public string $version = ""; + + public string $hostname = ""; } /** @@ -386,6 +407,8 @@ class SpanStack { * removal. */ public array $spanCreationObservers = []; + + public array $attributes = []; } interface Integration { @@ -537,7 +560,7 @@ function hook_method( // phpcs:enable Generic.Files.LineLength.TooLong /** - * Add a tag to be automatically applied to every span that is created, if tracing is enabled. + * Add a tag to be automatically applied to every spanStack that is created, if tracing is enabled. * * @param string $key Tag key * @param string $value Tag Value @@ -754,6 +777,7 @@ function startup_logs(): string {} /** * Return the id of the current trace * + * @deprecated This function is deprecated and should not be used. * @return string The id of the current trace */ function trace_id(): string {} @@ -773,6 +797,7 @@ function logs_correlation_trace_id(): string {} /** * Get information on the current context * + * @deprecated This function is deprecated and should not be used. * @return array{trace_id: string, span_id: string, version: string, env: string} */ function current_context(): array {} @@ -783,7 +808,7 @@ function current_context(): array {} * * The distributed tracing context can be reset by calling 'set_distributed_tracing_context("0", "0")' * - * @param string $traceId The unique integer (128-bit unsigned) ID of the trace containing this span + * @param string $traceId The unique integer (128-bit hex unsigned) ID of the trace containing this span * @param string $parentId The span integer ID of the parent span * @param string|null $origin The distributed tracing origin * @param array|string|null $propagated_tags If provided, propagated tags from the root span will be cleared and @@ -1177,31 +1202,6 @@ function dd_trace_env_config(string $envName): mixed {} */ function dd_trace_disable_in_request(): bool {} - /** - * (Noop/To do) Untrace traced functions and methods - * - * @internal - * @return bool 'true' if reset was successful, else 'false' - */ - function dd_trace_reset(): bool {} - - /** - * If tracing is enabled, serialize the trace into a string to send to the agent - * - * @internal - * @param array $traceArray Serialize values must be of type array, string, int, float, bool or null - * @return bool|string The serialized array, else 'false' if an error was encountered - */ - function dd_trace_serialize_msgpack(array $traceArray): bool|string {} - - /** - * Null function to easily breakpoint the execution at specific PHP line in GDB - * - * @internal - * @return bool Return 'true' if tracing is enabled, else 'false' - */ - function dd_trace_noop(mixed ...$args): bool {} - /** * Get the parsed value of the memory limit DD_TRACE_MEMORY_LIMIT in binary bytes * @@ -1219,6 +1219,7 @@ function dd_trace_check_memory_under_limit(): bool {} /** * Get the name of the app (DD_SERVICE) * + * @deprecated This function is deprecated and should not be used. * @param string|null $fallbackName Fallback name if the app's name wasn't set * @return string|null The app name, else the fallback name. Return 'null' if the app name isn't set and no * fallback name is provided. @@ -1228,6 +1229,7 @@ function ddtrace_config_app_name(?string $fallbackName = null): null|string {} /** * Check if distributed tracing is enabled (DD_DISTRIBUTED_TRACING) * + * @deprecated This function is deprecated and should not be used. * @return bool 'true' if distributed tracing is enabled, else 'false' */ function ddtrace_config_distributed_tracing_enabled(): bool {} @@ -1235,6 +1237,7 @@ function ddtrace_config_distributed_tracing_enabled(): bool {} /** * Check if tracing is enabled (DD_TRACE_ENABLED) * + * @deprecated This function is deprecated and should not be used. * @return bool 'true' is tracing is enabled, else 'false' */ function ddtrace_config_trace_enabled(): bool {} @@ -1247,35 +1250,6 @@ function ddtrace_config_trace_enabled(): bool {} */ function ddtrace_config_integration_enabled(string $integrationName): bool {} - /** - * Send payload to background sender's buffer - * - * @internal - * @param int $numTraces Trace count. Note that at the moment, the background sender is only capable of sending - * exactly one trace - * @param array $curlHeaders HTTP Headers - * @param string $payload HTTP Body - * @return bool 'true' if tracers were successfully sent or if the tracer is disabled, and 'false' if not exactly - * one trace was sent or if the procedure was unsuccessful - */ - function dd_trace_send_traces_via_thread(int $numTraces, array $curlHeaders, string $payload): bool {} - - /** - * Serializes and sends traces to the agent (in the format dd_trace_serialize_closed_spans() returns spans). - * - * @internal - * @param array $traceArray Array in the format returned by dd_trace_serialize_closed_spans() - */ - function dd_trace_buffer_span(array $traceArray): bool {} - - /** - * Used to send any already buffered spans to the agent - * - * @internal - * @return int - */ - function dd_trace_coms_trigger_writer_flush(): int {} - /** * Execute a given internal function * @@ -1293,6 +1267,7 @@ function dd_trace_internal_fn(string $functionName, mixed ...$args) {} /** * Set the distributed trace id * + * @deprecated This function is deprecated and should not be used. * @param string|null $traceId New trace id * @return bool 'true' if the change was properly applied, else 'false' */ @@ -1315,6 +1290,7 @@ function dd_trace_tracer_is_limited(): bool {} /** * Get the compiling time of all files compiled up to now (in µs) * + * @deprecated This function is deprecated and should not be used. * @return int Compile time */ function dd_trace_compile_time_microseconds(): int {} @@ -1342,11 +1318,13 @@ function dd_trace_peek_span_id(): string {} function dd_trace_close_all_spans_and_flush(): void {} /** + * @deprecated This function is deprecated and should not be used. * @alias DDTrace_trace_function */ function dd_trace_function(string $functionName, \Closure|array|null $tracingClosureOrConfigArray): bool {} /** + * @deprecated This function is deprecated and should not be used. * @alias DDTrace_trace_method */ function dd_trace_method( diff --git a/tracer/dogstatsd_client.c b/tracer/dogstatsd_client.c index 306e2ece05a..6574acce1fa 100644 --- a/tracer/dogstatsd_client.c +++ b/tracer/dogstatsd_client.c @@ -1,3 +1,4 @@ +// TODO: remove this file and put it in the sidecar. #include "dogstatsd_client.h" #include diff --git a/tracer/span_stats.c b/tracer/span_stats.c index cd7e6c93b2c..71dc81bf6d1 100644 --- a/tracer/span_stats.c +++ b/tracer/span_stats.c @@ -110,53 +110,31 @@ void ddtrace_precompute_span(ddtrace_span_data *span, ddtrace_span_precomputed * // Env: prefer deprecated meta["env"] (with a warning), else span property. pre->env = NULL; zval *meta_env = pre->meta ? zend_hash_str_find(pre->meta, ZEND_STRL("env")) : NULL; - if (meta_env) { - pre->env_deprecated = true; - LOG(DEPRECATED, "Using \"env\" in meta is deprecated. Instead specify the env property directly on the span."); - zend_string *str = datadog_convert_to_str(meta_env); + pre->env_deprecated = false; + zval *prop_env = &span->property_env; + ZVAL_DEREF(prop_env); + if (Z_TYPE_P(prop_env) > IS_NULL) { + zend_string *str = datadog_convert_to_str(prop_env); if (ZSTR_LEN(str) > 0) { pre->env = str; } else { zend_string_release(str); } - } else { - pre->env_deprecated = false; - zval *prop_env = &span->property_env; - ZVAL_DEREF(prop_env); - if (Z_TYPE_P(prop_env) > IS_NULL) { - zend_string *str = datadog_convert_to_str(prop_env); - if (ZSTR_LEN(str) > 0) { - pre->env = str; - } else { - zend_string_release(str); - } - } } // Version: prefer deprecated meta["version"] (with a warning), else the span's own property. pre->version = NULL; zval *meta_version = pre->meta ? zend_hash_str_find(pre->meta, ZEND_STRL("version")) : NULL; - if (meta_version) { - pre->version_deprecated = true; - LOG(DEPRECATED, "Using \"version\" in meta is deprecated. Instead specify the version property directly on the span."); - zend_string *str = datadog_convert_to_str(meta_version); + pre->version_deprecated = false; + zval *prop_version = &span->property_version; + ZVAL_DEREF(prop_version); + if (Z_TYPE_P(prop_version) > IS_NULL) { + zend_string *str = datadog_convert_to_str(prop_version); if (ZSTR_LEN(str) > 0) { pre->version = str; } else { zend_string_release(str); } - } else { - pre->version_deprecated = false; - zval *prop_version = &span->property_version; - ZVAL_DEREF(prop_version); - if (Z_TYPE_P(prop_version) > IS_NULL) { - zend_string *str = datadog_convert_to_str(prop_version); - if (ZSTR_LEN(str) > 0) { - pre->version = str; - } else { - zend_string_release(str); - } - } } // has_exception: used by dd_compute_span_is_error() for exception-based error detection. From 4ebccd946bf5df332b89553e3dd9b6e0ff11fda6 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Thu, 16 Jul 2026 14:11:08 +0200 Subject: [PATCH 02/32] chore: drop integration analytics Signed-off-by: Alexandre Rulleau --- tracer/ddtrace.stub.php | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/tracer/ddtrace.stub.php b/tracer/ddtrace.stub.php index 84a26703f69..be46d2c56b3 100644 --- a/tracer/ddtrace.stub.php +++ b/tracer/ddtrace.stub.php @@ -974,25 +974,6 @@ function container_id(): string|null {} function process_tags_base_hash(): string|null {} } -namespace DDTrace\Config { - - /** - * Check if the app analytics of an app is enabled for a given integration - * - * @param string $integrationName The name of the integration (e.g., mysqli) - * @return bool The status of the app analytics of the integration - */ - function integration_analytics_enabled(string $integrationName): bool {} - - /** - * Check the app analytics sample rate of a given integration - * - * @param string $integrationName The name of the integration (e.g., mysqli) - * @return float The sample rate of the app analytics of the integration - */ - function integration_analytics_sample_rate(string $integrationName): float {} -} - namespace DDTrace\UserRequest { /** * If there are any listeners of user request events. From 3c2c3c8e149369bab70f512ebc2420d8a0b6a0b5 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Fri, 17 Jul 2026 14:51:17 +0200 Subject: [PATCH 03/32] feat(tracer): align C span code with v1-compatible stub API Bring the tracer C code into consistency with the already-rewritten v1-compatible span stub (tracer/ddtrace.stub.php), keeping the v04 wire format byte-identical (libdatadog v1 FFI is not yet available). - Regenerate ddtrace_arginfo.h from the stub; reorder the ddtrace_span_properties / ddtrace_root_span_data / ddtrace_span_stack structs to match the new property declaration order (PHP property offsets are bound to these C struct fields). - Drop SpanEvent/SpanLink JsonSerializable + jsonSerialize(); relocate that logic into serializer.c so the _dd.span_links / events meta blobs are produced with identical bytes. - Make component/spanKind sourced from the new SpanData properties, translated back into meta (span.kind/component) at serialize time so the v04 wire is unchanged. Register the new SpanKind class. - Remove dead code for stub-removed functions and the DD_TRACE_WARN_LEGACY_DD_TRACE config key; complete the userland integration-analytics removal (Integration.php + call sites); delete tests orphaned by removed functions and rewrite the dd_trace_reset helper tests without gutting their coverage. Refs APMLP-1197. --- .../CakePHP/CakePHPIntegration.php | 9 - .../CodeIgniter/V2/CodeIgniterIntegration.php | 1 - .../Integrations/Curl/CurlIntegration.php | 1 - .../Integrations/Drupal/DrupalIntegration.php | 10 - .../V1/ElasticSearchIntegration.php | 29 +- .../V8/ElasticSearchIntegration.php | 1 - .../Frankenphp/FrankenphpIntegration.php | 9 - .../GoogleSpannerIntegration.php | 8 - src/DDTrace/Integrations/Integration.php | 19 - .../Laravel/LaravelIntegration.php | 11 - .../Integrations/Lumen/LumenIntegration.php | 9 - .../Memcache/MemcacheIntegration.php | 19 - .../Memcached/MemcachedIntegration.php | 26 -- .../Integrations/Mongo/MongoIntegration.php | 16 +- .../MongoDB/MongoDBIntegration.php | 1 - .../Integrations/Mysqli/MysqliIntegration.php | 7 - .../Integrations/Nette/NetteIntegration.php | 10 - .../Integrations/PDO/PDOIntegration.php | 3 - .../Integrations/Predis/PredisIntegration.php | 2 - .../Ratchet/RatchetIntegration.php | 9 - .../Roadrunner/RoadrunnerIntegration.php | 9 - .../Integrations/SQLSRV/SQLSRVIntegration.php | 2 - .../Integrations/Slim/SlimIntegration.php | 1 - .../Integrations/Swoole/SwooleIntegration.php | 9 - .../Symfony/SymfonyIntegration.php | 11 - .../WordPress/WordPressIntegration.php | 10 - .../WordPress/WordPressIntegrationLoader.php | 2 - .../Integrations/Yii/YiiIntegration.php | 9 - .../ZendFramework/V1/TraceRequest.php | 1 - .../ZendFrameworkIntegration.php | 9 - .../API/MessagePackSerializationBench.php | 41 -- tests/Unit/ConfigurationTest.php | 41 -- tests/ext/active_span.phpt | 33 +- .../agent_headers_ignore_userland.phpt | 49 -- ...ckground_sender_restores_capabilities.phpt | 79 ---- .../background_sender_survives_setuid.phpt | 77 --- .../dd_trace_send_traces_via_thread_001.phpt | 23 - .../dd_trace_send_traces_via_thread_002.phpt | 21 - tests/ext/dd_trace_serialize_msgpack.phpt | 40 -- .../ext/dd_trace_serialize_msgpack_error.phpt | 34 -- ...dd_trace_serialize_msgpack_id_in_meta.phpt | 36 -- .../dd_trace_serialize_msgpack_reference.phpt | 47 -- tests/ext/dd_trace_span_data_get_link.phpt | 2 +- ...ce_span_data_serialization_with_links.phpt | 33 +- ...http_endpoint_resource_renaming_basic.phpt | 1 - .../reset_configured_overrides.phpt | 9 +- tests/ext/sandbox/span_clone.phpt | 89 +++- .../dd_trace_send_traces_via_thread.phpt | 59 --- tracer/ddtrace.h | 1 + tracer/ddtrace.stub.php | 6 + tracer/ddtrace_arginfo.h | 442 ++++++++++-------- tracer/functions.c | 212 +-------- tracer/handlers_httpstreams.c | 10 +- tracer/serializer.c | 184 +++++++- tracer/span.c | 5 +- tracer/span.h | 10 +- tracer/tracer_telemetry.c | 12 +- 57 files changed, 588 insertions(+), 1271 deletions(-) delete mode 100644 tests/Benchmarks/API/MessagePackSerializationBench.php delete mode 100644 tests/ext/background-sender/agent_headers_ignore_userland.phpt delete mode 100644 tests/ext/background-sender/background_sender_restores_capabilities.phpt delete mode 100644 tests/ext/background-sender/background_sender_survives_setuid.phpt delete mode 100644 tests/ext/dd_trace_send_traces_via_thread_001.phpt delete mode 100644 tests/ext/dd_trace_send_traces_via_thread_002.phpt delete mode 100644 tests/ext/dd_trace_serialize_msgpack.phpt delete mode 100644 tests/ext/dd_trace_serialize_msgpack_error.phpt delete mode 100644 tests/ext/dd_trace_serialize_msgpack_id_in_meta.phpt delete mode 100644 tests/ext/dd_trace_serialize_msgpack_reference.phpt delete mode 100644 tests/ext/wrong-parameter-errors/dd_trace_send_traces_via_thread.phpt diff --git a/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php b/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php index 9adf7691128..f3eddb478fa 100644 --- a/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php +++ b/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php @@ -18,14 +18,6 @@ class CakePHPIntegration extends Integration public static $setStatusCodeFn; public static $parseRouteFn; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - public static function init(): int { self::$setRootSpanInfoFn = static function () { @@ -35,7 +27,6 @@ public static function init(): int } self::$appName = \ddtrace_config_app_name(CakePHPIntegration::NAME); - self::addTraceAnalyticsIfEnabled($rootSpan); $rootSpan->service = self::$appName; Integration::tagFrameworkServiceSource($rootSpan, CakePHPIntegration::NAME); if ('cli' === PHP_SAPI) { diff --git a/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php b/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php index 15c8f684f67..b2f5c1ba656 100644 --- a/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php +++ b/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php @@ -39,7 +39,6 @@ public static function init($router = null): int public static function registerIntegration(\CI_Router $router, SpanData $rootSpan, $service) { - self::addTraceAnalyticsIfEnabled($rootSpan); $rootSpan->name = 'codeigniter.request'; $rootSpan->service = $service; $rootSpan->type = Type::WEB_SERVLET; diff --git a/src/DDTrace/Integrations/Curl/CurlIntegration.php b/src/DDTrace/Integrations/Curl/CurlIntegration.php index e9880db1864..28bcaf69b42 100644 --- a/src/DDTrace/Integrations/Curl/CurlIntegration.php +++ b/src/DDTrace/Integrations/Curl/CurlIntegration.php @@ -294,7 +294,6 @@ public static function setup_curl_span($span) { $span->type = Type::HTTP_CLIENT; $span->service = 'curl'; Integration::handleInternalSpanServiceName($span, self::NAME); - self::addTraceAnalyticsIfEnabled($span); $span->meta[Tag::COMPONENT] = self::NAME; $span->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_CLIENT; } diff --git a/src/DDTrace/Integrations/Drupal/DrupalIntegration.php b/src/DDTrace/Integrations/Drupal/DrupalIntegration.php index 27cd7cffb05..539d1e76374 100644 --- a/src/DDTrace/Integrations/Drupal/DrupalIntegration.php +++ b/src/DDTrace/Integrations/Drupal/DrupalIntegration.php @@ -20,14 +20,6 @@ class DrupalIntegration extends Integration { const NAME = 'drupal'; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - public static function init(): int { ini_set('datadog.trace.spans_limit', max(1500, ini_get('datadog.trace.spans_limit'))); @@ -183,8 +175,6 @@ static function (HookData $fnHookData) use ($hook, $module, $functionName) { } ); - - // View Metrics /* install_hook( diff --git a/src/DDTrace/Integrations/ElasticSearch/V1/ElasticSearchIntegration.php b/src/DDTrace/Integrations/ElasticSearch/V1/ElasticSearchIntegration.php index aead9d43e22..2e9d95c0907 100644 --- a/src/DDTrace/Integrations/ElasticSearch/V1/ElasticSearchIntegration.php +++ b/src/DDTrace/Integrations/ElasticSearch/V1/ElasticSearchIntegration.php @@ -56,16 +56,16 @@ public static function init(): int self::traceClientMethod('existsScource'); self::traceClientMethod('explain'); self::traceClientMethod('fieldCaps'); - self::traceClientMethod('get', true); + self::traceClientMethod('get'); self::traceClientMethod('getScript'); self::traceClientMethod('getScriptContext'); self::traceClientMethod('getScriptLanguages'); self::traceClientMethod('getSource'); self::traceClientMethod('index'); - self::traceClientMethod('knnSearch', true); - self::traceClientMethod('mget', true); - self::traceClientMethod('msearch', true); - self::traceClientMethod('msearchTemplate', true); + self::traceClientMethod('knnSearch'); + self::traceClientMethod('mget'); + self::traceClientMethod('msearch'); + self::traceClientMethod('msearchTemplate'); self::traceClientMethod('mtermvectors'); self::traceClientMethod('openPointInTime'); self::traceClientMethod('ping'); @@ -76,11 +76,11 @@ public static function init(): int self::traceClientMethod('renderSearchTemplate'); self::traceClientMethod('scriptsPainlessExecute'); self::traceClientMethod('scroll'); - self::traceClientMethod('search', true); - self::traceClientMethod('searchMvt', true); - self::traceClientMethod('searchShards', true); - self::traceClientMethod('searchTemplate', true); - self::traceClientMethod('termsEnum', true); + self::traceClientMethod('search'); + self::traceClientMethod('searchMvt'); + self::traceClientMethod('searchShards'); + self::traceClientMethod('searchTemplate'); + self::traceClientMethod('termsEnum'); self::traceClientMethod('termvectors'); self::traceClientMethod('update'); self::traceClientMethod('updateByQuery'); @@ -136,9 +136,8 @@ public static function init(): int } /** * @param string $name - * @param bool $isTraceAnalyticsCandidate */ - public static function traceClientMethod($name, $isTraceAnalyticsCandidate = false) + public static function traceClientMethod($name) { $class = 'Elasticsearch\Client'; @@ -152,13 +151,9 @@ public static function traceClientMethod($name, $isTraceAnalyticsCandidate = fal $class, $name, [ - 'prehook' => static function (SpanData $span, $args) use ($name, $isTraceAnalyticsCandidate) { + 'prehook' => static function (SpanData $span, $args) use ($name) { $span->name = "Elasticsearch.Client.$name"; - if ($isTraceAnalyticsCandidate) { - self::addTraceAnalyticsIfEnabled($span); - } - $span->meta[Tag::SPAN_KIND] = 'client'; Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::ELASTICSEARCH; diff --git a/src/DDTrace/Integrations/ElasticSearch/V8/ElasticSearchIntegration.php b/src/DDTrace/Integrations/ElasticSearch/V8/ElasticSearchIntegration.php index 46ba22ca831..bd9eeff386d 100644 --- a/src/DDTrace/Integrations/ElasticSearch/V8/ElasticSearchIntegration.php +++ b/src/DDTrace/Integrations/ElasticSearch/V8/ElasticSearchIntegration.php @@ -132,7 +132,6 @@ public static function traceClientMethod($name, $isTraceAnalyticsCandidate = fal $span->name = "Elasticsearch.Client.$name"; if ($isTraceAnalyticsCandidate) { - self::addTraceAnalyticsIfEnabled($span); self::$logNextBody = true; } diff --git a/src/DDTrace/Integrations/Frankenphp/FrankenphpIntegration.php b/src/DDTrace/Integrations/Frankenphp/FrankenphpIntegration.php index 0c1226ead48..fb91221955f 100644 --- a/src/DDTrace/Integrations/Frankenphp/FrankenphpIntegration.php +++ b/src/DDTrace/Integrations/Frankenphp/FrankenphpIntegration.php @@ -19,14 +19,6 @@ class FrankenphpIntegration extends Integration public static $is_hooked; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - public static function init(): int { ini_set("datadog.trace.auto_flush_enabled", 1); @@ -55,7 +47,6 @@ static function (HookData $hook) use (&$blockingException, &$rootSpan) { $rootSpan->meta[Tag::COMPONENT] = self::NAME; $rootSpan->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_SERVER; unset($rootSpan->meta["closure.declaration"]); - self::addTraceAnalyticsIfEnabled($rootSpan); consume_distributed_tracing_headers(null); diff --git a/src/DDTrace/Integrations/GoogleSpanner/GoogleSpannerIntegration.php b/src/DDTrace/Integrations/GoogleSpanner/GoogleSpannerIntegration.php index afa11fb83d8..1d73d6f1bfd 100644 --- a/src/DDTrace/Integrations/GoogleSpanner/GoogleSpannerIntegration.php +++ b/src/DDTrace/Integrations/GoogleSpanner/GoogleSpannerIntegration.php @@ -23,7 +23,6 @@ public static function init(): int $span->meta[Tag::DB_INSTANCE] = $instanceName; GoogleSpannerIntegration::setDefaultAttributes($span, 'google_spanner.instance', $args[0]); ObjectKVStore::put($this, GoogleSpannerIntegration::KEY_INSTANCE_NAME, $instanceName); - GoogleSpannerIntegration::addTraceAnalyticsIfEnabled($span); }); \DDTrace\trace_method('Google\Cloud\Spanner\Instance', 'database', function (SpanData $span, $args) { @@ -31,38 +30,31 @@ public static function init(): int $span->meta[Tag::DB_NAME] = $dbName; GoogleSpannerIntegration::setDefaultAttributes($span, 'google_spanner.database', $args[0]); ObjectKVStore::put($this, GoogleSpannerIntegration::KEY_DATABASE_NAME, $dbName); - GoogleSpannerIntegration::addTraceAnalyticsIfEnabled($span); }); \DDTrace\trace_method('Google\Cloud\Spanner\Database', 'execute', function (SpanData $span, $args) { $span->meta[Tag::DB_NAME] = $this->name(); GoogleSpannerIntegration::setDefaultAttributes($span, 'google_spanner.execute', $args[0]); - GoogleSpannerIntegration::addTraceAnalyticsIfEnabled($span); }); \DDTrace\trace_method('Google\Cloud\Spanner\Database', 'runTransaction', static function (SpanData $span, $args) { self::setDefaultAttributes($span, 'google_spanner.run_transaction', 'transaction'); - self::addTraceAnalyticsIfEnabled($span); }); \DDTrace\trace_method('Google\Cloud\Spanner\Database', 'transaction', static function (SpanData $span, $args) { self::setDefaultAttributes($span, 'google_spanner.transaction', 'transaction'); - self::addTraceAnalyticsIfEnabled($span); }); \DDTrace\trace_method('Google\Cloud\Spanner\Transaction', 'commit', static function (SpanData $span) { self::setDefaultAttributes($span, 'google_spanner.commit', "commit"); - self::addTraceAnalyticsIfEnabled($span); }); \DDTrace\trace_method('Google\Cloud\Spanner\Transaction', 'executeUpdate', static function (SpanData $span, $args) { self::setDefaultAttributes($span, 'google_spanner.execute_update', $args[0]); - self::addTraceAnalyticsIfEnabled($span); }); \DDTrace\trace_method('Google\Cloud\Spanner\Transaction', 'executeUpdateBatch', static function (SpanData $span) { self::setDefaultAttributes($span, 'google_spanner.execute_update_batch', 'execute_update_batch'); - self::addTraceAnalyticsIfEnabled($span); }); return Integration::LOADED; diff --git a/src/DDTrace/Integrations/Integration.php b/src/DDTrace/Integrations/Integration.php index 2fe53f82c21..1a8ad52651a 100644 --- a/src/DDTrace/Integrations/Integration.php +++ b/src/DDTrace/Integrations/Integration.php @@ -16,25 +16,6 @@ public static function getName(): string return static::NAME; } - public static function addTraceAnalyticsIfEnabled(SpanData $span) - { - $name = static::NAME; - if (\DDTrace\Config\integration_analytics_enabled($name) - || (!static::requiresExplicitTraceAnalyticsEnabling() && \dd_trace_env_config("DD_TRACE_ANALYTICS_ENABLED"))) { - $span->metrics[Tag::ANALYTICS_KEY] = \DDTrace\Config\integration_analytics_sample_rate($name); - } - } - - /** - * Whether this integration trace analytics configuration is not enabled when DD_TRACE_ANALYTICS_ENABLED=1 is specified. - * - * Trace Analytics are generally enabled by default for top-level integrations, i.e. frameworks and webservers. - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return true; - } - /** * Tells whether the provided integration should be loaded. */ diff --git a/src/DDTrace/Integrations/Laravel/LaravelIntegration.php b/src/DDTrace/Integrations/Laravel/LaravelIntegration.php index 0f00a02b825..80d8f857cac 100644 --- a/src/DDTrace/Integrations/Laravel/LaravelIntegration.php +++ b/src/DDTrace/Integrations/Laravel/LaravelIntegration.php @@ -23,14 +23,6 @@ class LaravelIntegration extends Integration */ public static $serviceName; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - public static function isArtisanQueueCommand(): bool { $artisanCommand = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; @@ -54,7 +46,6 @@ public static function init(): int ini_set("datadog.trace.generate_root_span", 0); } - \DDTrace\trace_method( 'Illuminate\Foundation\Application', 'handle', @@ -70,7 +61,6 @@ static function (SpanData $span, $args, $response) { // Overwriting the default web integration $rootSpan->name = 'laravel.request'; - self::addTraceAnalyticsIfEnabled($rootSpan); if (\method_exists($response, 'getStatusCode')) { $rootSpan->meta[Tag::HTTP_STATUS_CODE] = $response->getStatusCode(); } @@ -120,7 +110,6 @@ static function ($This, $scope, $args, $route) { list($request) = $args; // Overwriting the default web integration - self::addTraceAnalyticsIfEnabled($rootSpan); $routeName = self::normalizeRouteName($route->getName()); if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { diff --git a/src/DDTrace/Integrations/Lumen/LumenIntegration.php b/src/DDTrace/Integrations/Lumen/LumenIntegration.php index aff0751cb2a..2ceb9f25eff 100644 --- a/src/DDTrace/Integrations/Lumen/LumenIntegration.php +++ b/src/DDTrace/Integrations/Lumen/LumenIntegration.php @@ -13,14 +13,6 @@ class LumenIntegration extends Integration { const NAME = 'lumen'; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - /** * @return int */ @@ -49,7 +41,6 @@ static function (SpanData $span, $args) { $rootSpan->name = 'lumen.request'; $rootSpan->service = \ddtrace_config_app_name(self::NAME); Integration::tagFrameworkServiceSource($rootSpan, LumenIntegration::NAME); - self::addTraceAnalyticsIfEnabled($rootSpan); if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { $rootSpan->meta[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($request->getUri()); } diff --git a/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php b/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php index 295cc066729..0706a599099 100644 --- a/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php +++ b/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php @@ -82,7 +82,6 @@ public static function init(): int \DDTrace\trace_method('Memcache', 'cas', $memcache_cas); \DDTrace\trace_function('memcache_cas', self::wrapClosureForTraceFunction($memcache_cas)); - return Integration::LOADED; } @@ -100,7 +99,6 @@ public static function traceCommand($command) $span->meta['memcache.query'] = $command . ' ' . $queryParams; } $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; - MemcacheIntegration::markForTraceAnalytics($span, $command); }; \DDTrace\trace_method('Memcache', $command, $trace); \DDTrace\trace_function("memcache_$command", self::wrapClosureForTraceFunction($trace)); @@ -160,21 +158,4 @@ public static function setServerTags(SpanData $span, \Memcache $memcache) } } - /** - * @param SpanData $span - * @param string $command - */ - public static function markForTraceAnalytics(SpanData $span, $command) - { - $commandsForAnalytics = [ - 'add', - 'delete', - 'get', - 'set', - ]; - - if (in_array($command, $commandsForAnalytics)) { - self::addTraceAnalyticsIfEnabled($span); - } - } } diff --git a/src/DDTrace/Integrations/Memcached/MemcachedIntegration.php b/src/DDTrace/Integrations/Memcached/MemcachedIntegration.php index cff131d05e8..2e431a51f63 100644 --- a/src/DDTrace/Integrations/Memcached/MemcachedIntegration.php +++ b/src/DDTrace/Integrations/Memcached/MemcachedIntegration.php @@ -111,7 +111,6 @@ function (SpanData $span, $args, $retval) use ($command) { } $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; - MemcachedIntegration::markForTraceAnalytics($span, $command); } ); } @@ -133,7 +132,6 @@ function (SpanData $span, $args, $retval) use ($command) { } $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; - MemcachedIntegration::markForTraceAnalytics($span, $command); } ); } @@ -151,7 +149,6 @@ function (SpanData $span, $args, $retval) use ($command) { MemcachedIntegration::setServerTags($span, $this); $span->meta['memcached.query'] = $command . ' ' . MemcachedIntegration::obfuscateIfNeeded($args[0], ','); $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; - MemcachedIntegration::markForTraceAnalytics($span, $command); } ); } @@ -171,7 +168,6 @@ function (SpanData $span, $args, $retval) use ($command) { $query = "$command " . MemcachedIntegration::obfuscateIfNeeded($args[1], ','); $span->meta['memcached.query'] = $query; $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; - MemcachedIntegration::markForTraceAnalytics($span, $command); } ); } @@ -221,28 +217,6 @@ public static function setServerTags(SpanData $span, \Memcached $memcached) } } - /** - * @param SpanData $span - * @param string $command - */ - public static function markForTraceAnalytics(SpanData $span, $command) - { - $commandsForAnalytics = [ - 'add', - 'addByKey', - 'delete', - 'deleteByKey', - 'get', - 'getByKey', - 'set', - 'setByKey', - ]; - - if (in_array($command, $commandsForAnalytics)) { - self::addTraceAnalyticsIfEnabled($span); - } - } - /* * Return either the obfuscated params or the params themselves, depending on the env var. */ diff --git a/src/DDTrace/Integrations/Mongo/MongoIntegration.php b/src/DDTrace/Integrations/Mongo/MongoIntegration.php index e4b3952ca4b..5bc2c000f54 100644 --- a/src/DDTrace/Integrations/Mongo/MongoIntegration.php +++ b/src/DDTrace/Integrations/Mongo/MongoIntegration.php @@ -116,7 +116,6 @@ static function (SpanData $span, $args, $return) { \DDTrace\trace_method('MongoCollection', 'distinct', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoCollection', 'distinct'); - self::addTraceAnalyticsIfEnabled($span); if (isset($args[1])) { $span->meta[Tag::MONGODB_QUERY] = json_encode($args[1]); } @@ -133,11 +132,11 @@ static function (SpanData $span, $args) { } ); - self::traceMongoQuery('MongoCollection', 'count', false); + self::traceMongoQuery('MongoCollection', 'count'); self::traceMongoQuery('MongoCollection', 'find'); self::traceMongoQuery('MongoCollection', 'findAndModify'); self::traceMongoQuery('MongoCollection', 'findOne'); - self::traceMongoQuery('MongoCollection', 'remove', false); + self::traceMongoQuery('MongoCollection', 'remove'); self::traceMongoQuery('MongoCollection', 'update'); self::traceMongoMethod('MongoCollection', 'aggregate'); @@ -253,23 +252,16 @@ public static function traceMongoMethod($class, $method) /** * Utility method to trace all query methods that have the query as the first argument. - * If the param {$isTraceAnalithicsCandidate} is set to true (default behavior) the span - * generated is also marked as trace analytics candidate. - * * @param string $class * @param string $method - * @param boolean $isTraceAnalyticsCandidate [default: `true`] */ - public static function traceMongoQuery($class, $method, $isTraceAnalyticsCandidate = true) + public static function traceMongoQuery($class, $method) { \DDTrace\trace_method( $class, $method, - static function (SpanData $span, $args) use ($class, $method, $isTraceAnalyticsCandidate) { + static function (SpanData $span, $args) use ($class, $method) { self::addSpanDefaultMetadata($span, $class, $method); - if ($isTraceAnalyticsCandidate) { - self::addTraceAnalyticsIfEnabled($span); - } if (isset($args[0])) { $span->meta[Tag::MONGODB_QUERY] = json_encode($args[0]); } diff --git a/src/DDTrace/Integrations/MongoDB/MongoDBIntegration.php b/src/DDTrace/Integrations/MongoDB/MongoDBIntegration.php index 27f715a2881..42b8be9fc65 100644 --- a/src/DDTrace/Integrations/MongoDB/MongoDBIntegration.php +++ b/src/DDTrace/Integrations/MongoDB/MongoDBIntegration.php @@ -616,6 +616,5 @@ public static function setMetadata( $span->meta[Tag::MONGODB_QUERY] = $serializedQuery; } $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; - self::addTraceAnalyticsIfEnabled($span); } } diff --git a/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php b/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php index bc5db373c90..01098dde873 100644 --- a/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php +++ b/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php @@ -108,7 +108,6 @@ function (SpanData $span, $args) { $span = $hook->span(); $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; self::setDefaultAttributes($span, 'mysqli_query', $query); - self::addTraceAnalyticsIfEnabled($span); self::setConnectionInfo($span, $mysqli); DatabaseIntegrationHelper::injectDatabaseIntegrationData($hook, 'mysql', 1); @@ -133,7 +132,6 @@ function (SpanData $span, $args) { $span = $hook->span(); $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; self::setDefaultAttributes($span, 'mysqli_real_query', $query); - self::addTraceAnalyticsIfEnabled($span); self::setConnectionInfo($span, $mysqli); DatabaseIntegrationHelper::injectDatabaseIntegrationData($hook, 'mysql', 1); @@ -178,7 +176,6 @@ function (SpanData $span, $args) { $span = $hook->span(); $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; MysqliIntegration::setDefaultAttributes($span, 'mysqli.query', $query); - MysqliIntegration::addTraceAnalyticsIfEnabled($span); MysqliIntegration::setConnectionInfo($span, $hook->instance); DatabaseIntegrationHelper::injectDatabaseIntegrationData($hook, 'mysql'); @@ -205,7 +202,6 @@ function (SpanData $span, $args) { $span = $hook->span(); $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; MysqliIntegration::setDefaultAttributes($span, 'mysqli.real_query', $query); - MysqliIntegration::addTraceAnalyticsIfEnabled($span); MysqliIntegration::setConnectionInfo($span, $hook->instance); DatabaseIntegrationHelper::injectDatabaseIntegrationData($hook, 'mysql'); @@ -262,7 +258,6 @@ function (SpanData $span, $args) { $span = $hook->span(); $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; self::setDefaultAttributes($span, 'mysqli_execute_query', $query); - self::addTraceAnalyticsIfEnabled($span); DatabaseIntegrationHelper::injectDatabaseIntegrationData($hook, 'mysql', 1); self::handleRasp($span); @@ -287,7 +282,6 @@ function (SpanData $span, $args) { $span = $hook->span(); $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; self::setDefaultAttributes($span, 'mysqli.execute_query', $query); - self::addTraceAnalyticsIfEnabled($span); DatabaseIntegrationHelper::injectDatabaseIntegrationData($hook, 'mysql'); self::handleRasp($span); @@ -366,7 +360,6 @@ static function (HookData $hook) { \DDTrace\trace_method('mysqli_stmt', 'execute', function (SpanData $span) { $resource = MysqliCommon::retrieveQuery($this, 'mysqli_stmt.execute'); MysqliIntegration::setDefaultAttributes($span, 'mysqli_stmt.execute', $resource); - MysqliIntegration::addTraceAnalyticsIfEnabled($span); MysqliIntegration::setConnectionInfo($span, ObjectKVStore::get($this, MysqliIntegration::KEY_MYSQLI_INSTANCE)); $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; }); diff --git a/src/DDTrace/Integrations/Nette/NetteIntegration.php b/src/DDTrace/Integrations/Nette/NetteIntegration.php index f6a7ef3e5a3..c748c14def7 100644 --- a/src/DDTrace/Integrations/Nette/NetteIntegration.php +++ b/src/DDTrace/Integrations/Nette/NetteIntegration.php @@ -11,14 +11,6 @@ class NetteIntegration extends Integration { const NAME = 'nette'; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - /** * {@inheritdoc} */ @@ -34,7 +26,6 @@ public static function init(): int $rootSpan->meta[Tag::SPAN_KIND] = 'server'; - self::addTraceAnalyticsIfEnabled($rootSpan); $rootSpan->service = $service; $rootSpan->meta[Tag::COMPONENT] = self::NAME; }; @@ -42,7 +33,6 @@ public static function init(): int \DDTrace\hook_method('Nette\Configurator', '__construct', $setRootSpanFn); \DDTrace\hook_method('Nette\Bootstrap\Configurator', '__construct', $setRootSpanFn); - \DDTrace\trace_method( 'Nette\Configurator', 'createRobotLoader', diff --git a/src/DDTrace/Integrations/PDO/PDOIntegration.php b/src/DDTrace/Integrations/PDO/PDOIntegration.php index 1c52378cf88..50207e64164 100644 --- a/src/DDTrace/Integrations/PDO/PDOIntegration.php +++ b/src/DDTrace/Integrations/PDO/PDOIntegration.php @@ -74,7 +74,6 @@ public static function init(): int $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; $instance = $hook->instance; PDOIntegration::setCommonSpanInfo($instance, $span); - PDOIntegration::addTraceAnalyticsIfEnabled($span); PDOIntegration::injectDBIntegration($instance, $hook); PDOIntegration::handleRasp($instance, $span); @@ -100,7 +99,6 @@ public static function init(): int $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; $instance = $hook->instance; PDOIntegration::setCommonSpanInfo($instance, $span); - PDOIntegration::addTraceAnalyticsIfEnabled($span); PDOIntegration::injectDBIntegration($instance, $hook); PDOIntegration::handleRasp($instance, $span); @@ -170,7 +168,6 @@ static function (HookData $hook) { } } PDOIntegration::setCommonSpanInfo($instance, $span); - PDOIntegration::addTraceAnalyticsIfEnabled($span); PDOIntegration::detectError($instance, $span); $span->resource = PDOIntegration::useQuestionMarkPlaceholders($span->resource); diff --git a/src/DDTrace/Integrations/Predis/PredisIntegration.php b/src/DDTrace/Integrations/Predis/PredisIntegration.php index b971b57ca7b..1c14c812715 100644 --- a/src/DDTrace/Integrations/Predis/PredisIntegration.php +++ b/src/DDTrace/Integrations/Predis/PredisIntegration.php @@ -52,7 +52,6 @@ public static function init(): int $span->name = 'Predis.Client.executeCommand'; $span->type = Type::REDIS; PredisIntegration::setMetaAndServiceFromConnection($this, $span); - PredisIntegration::addTraceAnalyticsIfEnabled($span); // We default resource name to 'Predis.Client.executeCommand', but if we are able below to extract the query // then we replace it with the query @@ -77,7 +76,6 @@ public static function init(): int $span->name = 'Predis.Client.executeRaw'; $span->type = Type::REDIS; PredisIntegration::setMetaAndServiceFromConnection($this, $span); - PredisIntegration::addTraceAnalyticsIfEnabled($span); // We default resource name to 'Predis.Client.executeRaw', but if we are able below to extract the query // then we replace it with the query diff --git a/src/DDTrace/Integrations/Ratchet/RatchetIntegration.php b/src/DDTrace/Integrations/Ratchet/RatchetIntegration.php index 2b1fcc30e68..6cf50c9085b 100644 --- a/src/DDTrace/Integrations/Ratchet/RatchetIntegration.php +++ b/src/DDTrace/Integrations/Ratchet/RatchetIntegration.php @@ -44,14 +44,6 @@ class RatchetIntegration extends Integration { const NAME = 'ratchet'; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - /** * @return int */ @@ -183,7 +175,6 @@ public static function init(): int $activeSpan->type = Type::WEB_SERVLET; $activeSpan->meta[Tag::COMPONENT] = self::NAME; $activeSpan->meta[Tag::SPAN_KIND] = 'server'; - RatchetIntegration::addTraceAnalyticsIfEnabled($activeSpan); ObjectKVStore::put($parentConn, "handshake", $activeSpan); diff --git a/src/DDTrace/Integrations/Roadrunner/RoadrunnerIntegration.php b/src/DDTrace/Integrations/Roadrunner/RoadrunnerIntegration.php index 314d17f9db1..9c012c5ccf9 100644 --- a/src/DDTrace/Integrations/Roadrunner/RoadrunnerIntegration.php +++ b/src/DDTrace/Integrations/Roadrunner/RoadrunnerIntegration.php @@ -17,14 +17,6 @@ class RoadrunnerIntegration extends Integration { const NAME = 'roadrunner'; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - public static function build_req_spec(\Spiral\RoadRunner\Http\Request $req) { $ret = array(); @@ -160,7 +152,6 @@ function (HookData $hook) use (&$activeSpan, &$suppressResponse, $service, &$rec $activeSpan->type = Type::WEB_SERVLET; $activeSpan->meta[Tag::COMPONENT] = RoadrunnerIntegration::NAME; $activeSpan->meta[Tag::SPAN_KIND] = 'server'; - RoadrunnerIntegration::addTraceAnalyticsIfEnabled($activeSpan); if ($hook->exception) { $activeSpan->exception = $hook->exception; \DDTrace\close_span(); diff --git a/src/DDTrace/Integrations/SQLSRV/SQLSRVIntegration.php b/src/DDTrace/Integrations/SQLSRV/SQLSRVIntegration.php index 929a860c005..9e65fa8af56 100644 --- a/src/DDTrace/Integrations/SQLSRV/SQLSRVIntegration.php +++ b/src/DDTrace/Integrations/SQLSRV/SQLSRVIntegration.php @@ -45,7 +45,6 @@ public static function init(): int $span = $hook->span(); self::setDefaultAttributes($conn, $span, 'sqlsrv_query', $query); - self::addTraceAnalyticsIfEnabled($span); $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; DatabaseIntegrationHelper::injectDatabaseIntegrationData($hook, 'sqlsrv', 1); @@ -99,7 +98,6 @@ public static function init(): int $query = resource_weak_get($stmt, self::QUERY_TAGS_KEY); } self::setDefaultAttributes($stmt, $span, 'sqlsrv_execute', $query ?? "", $retval); - self::addTraceAnalyticsIfEnabled($span); $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; if ($retval) { self::setMetrics($span, $args[0]); diff --git a/src/DDTrace/Integrations/Slim/SlimIntegration.php b/src/DDTrace/Integrations/Slim/SlimIntegration.php index d135e66d810..42c49213e78 100644 --- a/src/DDTrace/Integrations/Slim/SlimIntegration.php +++ b/src/DDTrace/Integrations/Slim/SlimIntegration.php @@ -30,7 +30,6 @@ function ($app) { // Overwrite root span info $rootSpan = \DDTrace\root_span(); - SlimIntegration::addTraceAnalyticsIfEnabled($rootSpan); $rootSpan->name = 'slim.request'; $rootSpan->service = \ddtrace_config_app_name(SlimIntegration::NAME); Integration::tagFrameworkServiceSource($rootSpan, SlimIntegration::NAME); diff --git a/src/DDTrace/Integrations/Swoole/SwooleIntegration.php b/src/DDTrace/Integrations/Swoole/SwooleIntegration.php index 7d7213795fd..7c470577316 100644 --- a/src/DDTrace/Integrations/Swoole/SwooleIntegration.php +++ b/src/DDTrace/Integrations/Swoole/SwooleIntegration.php @@ -19,14 +19,6 @@ class SwooleIntegration extends Integration { const NAME = 'swoole'; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - public static function instrumentRequestStart(callable $callback, Server $server) { $scheme = $server->ssl ? 'https://' : 'http://'; @@ -40,7 +32,6 @@ static function (HookData $hook) use ($server, $scheme) { $rootSpan->type = Type::WEB_SERVLET; $rootSpan->meta[Tag::COMPONENT] = self::NAME; $rootSpan->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_SERVER; - self::addTraceAnalyticsIfEnabled($rootSpan); $args = $hook->args; /** @var Request $request */ diff --git a/src/DDTrace/Integrations/Symfony/SymfonyIntegration.php b/src/DDTrace/Integrations/Symfony/SymfonyIntegration.php index d0540860fa5..bb4a0110e5b 100644 --- a/src/DDTrace/Integrations/Symfony/SymfonyIntegration.php +++ b/src/DDTrace/Integrations/Symfony/SymfonyIntegration.php @@ -22,14 +22,6 @@ class SymfonyIntegration extends Integration public static $kernel; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - /** * Load the integration * @@ -53,7 +45,6 @@ public static function init(): int Integration::tagFrameworkServiceSource($rootSpan, SymfonyIntegration::NAME); $rootSpan->meta[Tag::SPAN_KIND] = 'server'; $rootSpan->meta[Tag::COMPONENT] = SymfonyIntegration::NAME; - SymfonyIntegration::addTraceAnalyticsIfEnabled($rootSpan); $span->name = 'symfony.httpkernel.kernel.handle'; $span->resource = \get_class($this); @@ -479,7 +470,6 @@ static function(SpanData $span, $args, $response) use ($handle_http_route) { $rootSpan->meta[Tag::HTTP_METHOD] = $request->getMethod(); $rootSpan->meta[Tag::COMPONENT] = self::$frameworkPrefix; $rootSpan->meta[Tag::SPAN_KIND] = 'server'; - self::addTraceAnalyticsIfEnabled($rootSpan); if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { $rootSpan->meta[Tag::HTTP_URL] = Normalizer::urlSanitize($request->getUri()); @@ -631,7 +621,6 @@ static function(HookData $hook) use ($controllerName) { $span->meta[Tag::COMPONENT] = self::NAME; \DDTrace\root_span()->exception = $args[0]; - if (isset($retval) && \method_exists($retval, 'getStatusCode') && $retval->getStatusCode() < 500) { // It means that the exception event associated with the exception had a response, which certainly // means that the exception was handled. diff --git a/src/DDTrace/Integrations/WordPress/WordPressIntegration.php b/src/DDTrace/Integrations/WordPress/WordPressIntegration.php index 0f823c73b62..6643abf5ae8 100644 --- a/src/DDTrace/Integrations/WordPress/WordPressIntegration.php +++ b/src/DDTrace/Integrations/WordPress/WordPressIntegration.php @@ -8,14 +8,6 @@ class WordPressIntegration extends Integration { const NAME = 'wordpress'; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - /** * {@inheritdoc} */ @@ -109,7 +101,6 @@ static function ($args, $retval) { } ); - \DDTrace\hook_function( 'register_new_user', null, @@ -155,7 +146,6 @@ static function ($args, $retval) { } ); - return self::LOADED; } } diff --git a/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php b/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php index 4a9cd2a5178..a51b6b6ef82 100644 --- a/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php +++ b/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php @@ -204,7 +204,6 @@ public static function load() // Overwrite the default web integration $rootSpan = \DDTrace\root_span(); if ($rootSpan) { - WordPressIntegration::addTraceAnalyticsIfEnabled($rootSpan); $rootSpan->name = 'wordpress.request'; $rootSpan->service = \ddtrace_config_app_name(WordPressIntegration::NAME);; $rootSpan->meta[Tag::COMPONENT] = WordPressIntegration::NAME; @@ -232,7 +231,6 @@ static function (HookData $hook) { } }); - hook_function('wp_templating_constants', null, static function () { global $wp_theme_directories; if (empty($wp_theme_directories)) { diff --git a/src/DDTrace/Integrations/Yii/YiiIntegration.php b/src/DDTrace/Integrations/Yii/YiiIntegration.php index 91fa862d5f9..2d4e44063f1 100644 --- a/src/DDTrace/Integrations/Yii/YiiIntegration.php +++ b/src/DDTrace/Integrations/Yii/YiiIntegration.php @@ -13,14 +13,6 @@ class YiiIntegration extends Integration { const NAME = 'yii'; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - /** * {@inheritdoc} */ @@ -38,7 +30,6 @@ static function () { if ($rootSpan !== null) { $rootSpan->meta[Tag::COMPONENT] = self::NAME; $rootSpan->meta[Tag::SPAN_KIND] = 'server'; - self::addTraceAnalyticsIfEnabled($rootSpan); } } ); diff --git a/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php b/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php index cf4aa4a07a3..77989e5aaf7 100644 --- a/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php +++ b/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php @@ -21,7 +21,6 @@ public function preDispatch(Zend_Controller_Request_Abstract $request) return; } // Overwriting the default web integration - ZendFrameworkIntegration::addTraceAnalyticsIfEnabled($span); $controller = $request->getControllerName(); $action = $request->getActionName(); $route = Zend_Controller_Front::getInstance()->getRouter()->getCurrentRouteName(); diff --git a/src/DDTrace/Integrations/ZendFramework/ZendFrameworkIntegration.php b/src/DDTrace/Integrations/ZendFramework/ZendFrameworkIntegration.php index 89744136740..94a4ab1d921 100644 --- a/src/DDTrace/Integrations/ZendFramework/ZendFrameworkIntegration.php +++ b/src/DDTrace/Integrations/ZendFramework/ZendFrameworkIntegration.php @@ -15,14 +15,6 @@ class ZendFrameworkIntegration extends Integration { const NAME = 'zendframework'; - /** - * {@inheritdoc} - */ - public static function requiresExplicitTraceAnalyticsEnabling(): bool - { - return false; - } - /** * Loads the zend framework integration. * @@ -48,7 +40,6 @@ static function ($broker, $scope, $args) { try { /** @var Zend_Controller_Request_Abstract $request */ list($request) = $args; - self::addTraceAnalyticsIfEnabled($rootSpan); $rootSpan->name = self::getOperationName(); // For backward compatibility with the legacy API we are not using the integration // name 'zendframework', we are instead using the 'zf1' prefix. diff --git a/tests/Benchmarks/API/MessagePackSerializationBench.php b/tests/Benchmarks/API/MessagePackSerializationBench.php deleted file mode 100644 index 43220a80c93..00000000000 --- a/tests/Benchmarks/API/MessagePackSerializationBench.php +++ /dev/null @@ -1,41 +0,0 @@ -name = 'bench.trace_serialization'; - $span->meta['foo'] = 'bar'; - $span->metrics['bar'] = 1; - } - - for ($i = 0; $i < 100; $i++) { - \DDTrace\close_span(); - } - - $traceArray = \dd_trace_serialize_closed_spans(); - - return [ - [$traceArray], - ]; - } -} diff --git a/tests/Unit/ConfigurationTest.php b/tests/Unit/ConfigurationTest.php index f3129e5087b..520dddcbf08 100644 --- a/tests/Unit/ConfigurationTest.php +++ b/tests/Unit/ConfigurationTest.php @@ -117,47 +117,6 @@ public function testAllIntegrationsEnabledToggleConfig() self::assertTrue(\ddtrace_config_integration_enabled('foo_invalid')); } - public function testAllIntegrationsAnalyticsEnabledToggleConfig() - { - $integrations = self::getIntegrationsUpper(); - foreach ($integrations as $integration) { - $this->putEnvAndReloadConfig(["DD_TRACE_{$integration}_ANALYTICS_ENABLED=true"]); - - $lower = strtolower($integration); - self::assertTrue( - \DDTrace\Config\integration_analytics_enabled($lower), - "App analytics for '{$lower}' was expected to be enabled." . self::INTEGRATION_ERROR - ); - - // Reset - self::putenv("DD_TRACE_{$integration}_ANALYTICS_ENABLED"); - } - - // Make sure we're not testing the default fallback - self::assertFalse(\DDTrace\Config\integration_analytics_enabled('foo_invalid')); - } - - public function testAllIntegrationsAnalyticsSampleRateConfig() - { - $integrations = self::getIntegrationsUpper(); - foreach ($integrations as $integration) { - $this->putEnvAndReloadConfig(["DD_TRACE_{$integration}_ANALYTICS_SAMPLE_RATE=0.42"]); - - $lower = strtolower($integration); - self::assertSame( - 0.42, - \DDTrace\Config\integration_analytics_sample_rate($lower), - "Invalid app analytics sample rate for '{$lower}'." . self::INTEGRATION_ERROR - ); - - // Reset - self::putenv("DD_TRACE_{$integration}_ANALYTICS_SAMPLE_RATE"); - } - - // Make sure we're not testing the default fallback - self::assertSame(\DDTrace\Config\integration_analytics_sample_rate('foo_invalid'), 1.0); - } - private static function getIntegrationsUpper() { $dirs = glob(__DIR__ . '/../../src/DDTrace/Integrations/*', GLOB_ONLYDIR); diff --git a/tests/ext/active_span.phpt b/tests/ext/active_span.phpt index e08a13ea52b..af0319bf4a3 100644 --- a/tests/ext/active_span.phpt +++ b/tests/ext/active_span.phpt @@ -28,17 +28,13 @@ var_dump(DDTrace\active_span() == DDTrace\active_span()); Hello, Datadog. greet tracer. bool(true) -object(DDTrace\RootSpanData)#%d (24) { +object(DDTrace\RootSpanData)#%d (29) { ["name"]=> string(15) "active_span.php" ["resource"]=> string(0) "" ["service"]=> string(15) "active_span.php" - ["env"]=> - string(0) "" - ["version"]=> - string(0) "" ["meta_struct"]=> array(0) { } @@ -70,9 +66,9 @@ object(DDTrace\RootSpanData)#%d (24) { ["parent"]=> NULL ["stack"]=> - object(DDTrace\SpanStack)#%d (3) { + object(DDTrace\SpanStack)#%d (4) { ["parent"]=> - object(DDTrace\SpanStack)#%d (3) { + object(DDTrace\SpanStack)#%d (4) { ["parent"]=> NULL ["active"]=> @@ -80,24 +76,43 @@ object(DDTrace\RootSpanData)#%d (24) { ["spanCreationObservers"]=> array(0) { } + ["attributes"]=> + array(0) { + } } ["active"]=> *RECURSION* ["spanCreationObservers"]=> array(0) { } + ["attributes"]=> + array(0) { + } } ["onClose"]=> array(0) { } ["baggage"]=> array(0) { + } + ["env"]=> + string(0) "" + ["version"]=> + string(0) "" + ["component"]=> + string(0) "" + ["spanKind"]=> + int(0) + ["attributes"]=> + array(0) { }%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r ["propagatedTags"]=> array(0) { } ["samplingPriority"]=> - int(1073741824)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r + int(1073741824) + ["samplingMechanism"]=> + int(0)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r ["tracestateTags"]=> array(0) { }%r(\s*\["parentId"\]=>\s+uninitialized\(string\))?%r @@ -107,5 +122,7 @@ object(DDTrace\RootSpanData)#%d (24) { NULL ["inferredSpan"]=> NULL + ["hostname"]=> + string(0) "" } bool(true) diff --git a/tests/ext/background-sender/agent_headers_ignore_userland.phpt b/tests/ext/background-sender/agent_headers_ignore_userland.phpt deleted file mode 100644 index 224fcd64655..00000000000 --- a/tests/ext/background-sender/agent_headers_ignore_userland.phpt +++ /dev/null @@ -1,49 +0,0 @@ ---TEST-- -HTTP Agent headers are ignored from userland ---SKIPIF-- - ---ENV-- -DD_TRACE_LOG_LEVEL=info,startup=off -DD_AGENT_HOST=request-replayer -DD_TRACE_AGENT_PORT=80 -DD_TRACE_AGENT_FLUSH_AFTER_N_REQUESTS=1 -DD_TRACE_AGENT_FLUSH_INTERVAL=333 -DD_TRACE_GENERATE_ROOT_SPAN=0 -DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 ---INI-- -datadog.trace.agent_test_session_token=background-sender/agent_headers_ignore_userland ---FILE-- -replayHeaders([ - 'datadog-meta-lang', - 'this-should-be', -]); -foreach ($headers as $name => $value) { - echo $name . ': ' . $value . PHP_EOL; -} -echo PHP_EOL; - -echo 'Done.' . PHP_EOL; - -?> ---EXPECTF-- -bool(true) - -datadog-meta-lang: php - -Done. -[ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/background-sender/background_sender_restores_capabilities.phpt b/tests/ext/background-sender/background_sender_restores_capabilities.phpt deleted file mode 100644 index 81e76907ce8..00000000000 --- a/tests/ext/background-sender/background_sender_restores_capabilities.phpt +++ /dev/null @@ -1,79 +0,0 @@ ---TEST-- -background sender restores effective capabilities from permitted set ---DESCRIPTION-- -The effective set may be cleared, e.g. when prctl(PR_SET_KEEPCAPS), followed by setuid(2) has been used. -Hence we exec() ourselves on top of a process with no effective capabilities. ---SKIPIF-- - - - - - - - ---FILE-- - '-E', -1 => '--'] + $cmdAndArgs); -} - -$ffi = FFI::cdef(<<new("cap_user_header_t"); -$capheader->version = _LINUX_CAPABILITY_VERSION_1; - -$capdata = $ffi->new("cap_user_data_t"); -$capdata->inheritable = 0; -$capdata->effective = 0; -$capdata->permitted = 1 << CAP_SETGID; - -if (!getenv("BACKGROUND_SENDER_RESTORES_CAPABILITIES")) { - $ffi->capset(FFI::addr($capheader), FFI::addr($capdata)); - - putenv("BACKGROUND_SENDER_RESTORES_CAPABILITIES=1"); - $cmdAndArgs = explode("\0", file_get_contents("/proc/" . getmypid() . "/cmdline")); - pcntl_exec(array_shift($cmdAndArgs), $cmdAndArgs); - - die("exec failed?"); -} - -$capdata->effective = $capdata->permitted; -$ffi->capset(FFI::addr($capheader), FFI::addr($capdata)); - -$groups = $ffi->new("uint32_t"); -$groups->cdata = 1; -var_dump($ffi->setgroups(1, FFI::addr($groups))); - -// payload = [[]] -$payload = "\x91\x90"; - -var_dump(dd_trace_send_traces_via_thread(1, [], $payload)); - -echo "Done."; -?> ---EXPECT-- -int(0) -bool(true) -Done. diff --git a/tests/ext/background-sender/background_sender_survives_setuid.phpt b/tests/ext/background-sender/background_sender_survives_setuid.phpt deleted file mode 100644 index 9ebd6e70bb3..00000000000 --- a/tests/ext/background-sender/background_sender_survives_setuid.phpt +++ /dev/null @@ -1,77 +0,0 @@ ---TEST-- -background sender survives setuid ---DESCRIPTION-- -setuid() will reset the effective capabilities of the thread to zero when it's run. Ensure that we do not crash afterwards. -To test this we will issue a setgroups() via the libc wrapper (which distributes the setgroups() syscall to all threads of the process). ---SKIPIF-- - - - - - - - ---ENV-- -DD_TRACE_RETAIN_THREAD_CAPABILITIES=1 ---FILE-- - '-E', -1 => '--'] + $cmdAndArgs); -} - -$ffi = FFI::cdef(<<prctl(PR_SET_KEEPCAPS, 1); - -$ffi->setuid(1); // daemon user - -const _LINUX_CAPABILITY_VERSION_1 = 0x19980330; -const CAP_SETGID = 6; - -$capheader = $ffi->new("cap_user_header_t"); -$capheader->version = _LINUX_CAPABILITY_VERSION_1; - -$capdata = $ffi->new("cap_user_data_t"); -$capdata->inheritable = 0; -$capdata->effective = $capdata->permitted = 1 << CAP_SETGID; - -$ffi->capset(FFI::addr($capheader), FFI::addr($capdata)); - -$groups = $ffi->new("uint32_t"); -$groups->cdata = 1; -var_dump($ffi->setgroups(1, FFI::addr($groups))); - -// payload = [[]] -$payload = "\x91\x90"; - -var_dump(dd_trace_send_traces_via_thread(1, [], $payload)); - -echo "Done."; -?> ---EXPECT-- -int(0) -bool(true) -Done. diff --git a/tests/ext/dd_trace_send_traces_via_thread_001.phpt b/tests/ext/dd_trace_send_traces_via_thread_001.phpt deleted file mode 100644 index 085096d1c82..00000000000 --- a/tests/ext/dd_trace_send_traces_via_thread_001.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -background sender happy path ---SKIPIF-- - ---ENV-- -DD_TRACE_SIDECAR_TRACE_SENDER=0 ---FILE-- - 'php', -]; - -// payload = [[]] -$payload = "\x91\x90"; - -var_dump(dd_trace_send_traces_via_thread(1, $headers, $payload)); - -echo "Done."; -?> ---EXPECT-- -bool(true) -Done. diff --git a/tests/ext/dd_trace_send_traces_via_thread_002.phpt b/tests/ext/dd_trace_send_traces_via_thread_002.phpt deleted file mode 100644 index 71fe798761f..00000000000 --- a/tests/ext/dd_trace_send_traces_via_thread_002.phpt +++ /dev/null @@ -1,21 +0,0 @@ ---TEST-- -background sender should reject msgpack array prefix that does not match expected number of traces ---SKIPIF-- - ---FILE-- - 'php', -]; - -// payload = [] -$payload = "\x90"; - -var_dump(dd_trace_send_traces_via_thread(1, $headers, $payload)); - -echo "Done."; -?> ---EXPECT-- -bool(false) -Done. diff --git a/tests/ext/dd_trace_serialize_msgpack.phpt b/tests/ext/dd_trace_serialize_msgpack.phpt deleted file mode 100644 index f47738f2347..00000000000 --- a/tests/ext/dd_trace_serialize_msgpack.phpt +++ /dev/null @@ -1,40 +0,0 @@ ---TEST-- -Basic functionality of dd_trace_serialize_msgpack() ---DESCRIPTION-- -The "EXPECT" section was generated with the following tool: -https://github.com/ludocode/msgpack-tools -Example command: -$ echo '{"compact": true, "schema": 0}' | json2msgpack | hexdump ---SKIPIF-- - ---FILE-- - "1589331357723252209", - "span_id" => "1589331357723252210", - "name" => "test_name", - "resource" => "test_resource", - "service" => "test_service", - "start" => 1518038421211969000, - "error" => 0, - "meta" => [], - ], -]]; -echo json_encode($traces) . "\n"; - -$encoded = dd_trace_serialize_msgpack($traces); -echo dd_trace_unserialize_trace_hex($encoded) . "\n"; -?> ---EXPECT-- -[[{"trace_id":"1589331357723252209","span_id":"1589331357723252210","name":"test_name","resource":"test_resource","service":"test_service","start":1518038421211969000,"error":0,"meta":[]}]] -91 91 88 a8 74 72 61 63 65 5f 69 64 cf 16 0e 70 72 ff 7b d5 f1 a7 73 70 61 6e 5f 69 64 cf 16 0e 70 72 ff 7b d5 f2 a4 6e 61 6d 65 a9 74 65 73 74 5f 6e 61 6d 65 a8 72 65 73 6f 75 72 63 65 ad 74 65 73 74 5f 72 65 73 6f 75 72 63 65 a7 73 65 72 76 69 63 65 ac 74 65 73 74 5f 73 65 72 76 69 63 65 a5 73 74 61 72 74 cf 15 11 27 e6 b3 bb f5 e8 a5 65 72 72 6f 72 00 a4 6d 65 74 61 90 \ No newline at end of file diff --git a/tests/ext/dd_trace_serialize_msgpack_error.phpt b/tests/ext/dd_trace_serialize_msgpack_error.phpt deleted file mode 100644 index 871f5776d05..00000000000 --- a/tests/ext/dd_trace_serialize_msgpack_error.phpt +++ /dev/null @@ -1,34 +0,0 @@ ---TEST-- -dd_trace_serialize_msgpack() error conditions ---ENV-- -DD_TRACE_AUTO_FLUSH_ENABLED=0 -DD_TRACE_LOG_LEVEL=info,startup=off ---FILE-- - ---EXPECTF-- -[ddtrace] [warning] [%d] Serialize values must be of type array, string, int, float, bool or null -array(1) { - [0]=> - object(stdClass)#%d (0) { - } -} -bool(false) - -[ddtrace] [warning] [%d] Serialize values must be of type array, string, int, float, bool or null -array(2) { - [0]=> - string(3) "bar" - [1]=> - resource(%d) of type (stream-context) -} -bool(false) - -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s diff --git a/tests/ext/dd_trace_serialize_msgpack_id_in_meta.phpt b/tests/ext/dd_trace_serialize_msgpack_id_in_meta.phpt deleted file mode 100644 index a4aae4b3e8d..00000000000 --- a/tests/ext/dd_trace_serialize_msgpack_id_in_meta.phpt +++ /dev/null @@ -1,36 +0,0 @@ ---TEST-- -dd_trace_serialize_msgpack() properly handles span_id, trace_id and parent_id, but only outside of nested arrays ---SKIPIF-- - ---FILE-- - "1589331357723252209", - "parent_id" => "1589331357723252200", - "span_id" => "1589331357723252210", - "meta" => [ - "trace_id" => "1589331357723252209", - "parent_id" => "1589331357723252209", - "span_id" => "1589331357723252210", - "test" => "1234", - ], - ], -]]; -echo json_encode($traces) . "\n"; - -$encoded = dd_trace_serialize_msgpack($traces); -echo dd_trace_unserialize_trace_hex($encoded) . "\n"; -?> ---EXPECT-- -[[{"trace_id":"1589331357723252209","parent_id":"1589331357723252200","span_id":"1589331357723252210","meta":{"trace_id":"1589331357723252209","parent_id":"1589331357723252209","span_id":"1589331357723252210","test":"1234"}}]] -91 91 84 a8 74 72 61 63 65 5f 69 64 cf 16 0e 70 72 ff 7b d5 f1 a9 70 61 72 65 6e 74 5f 69 64 cf 16 0e 70 72 ff 7b d5 e8 a7 73 70 61 6e 5f 69 64 cf 16 0e 70 72 ff 7b d5 f2 a4 6d 65 74 61 84 a8 74 72 61 63 65 5f 69 64 b3 31 35 38 39 33 33 31 33 35 37 37 32 33 32 35 32 32 30 39 a9 70 61 72 65 6e 74 5f 69 64 b3 31 35 38 39 33 33 31 33 35 37 37 32 33 32 35 32 32 30 39 a7 73 70 61 6e 5f 69 64 b3 31 35 38 39 33 33 31 33 35 37 37 32 33 32 35 32 32 31 30 a4 74 65 73 74 a4 31 32 33 34 diff --git a/tests/ext/dd_trace_serialize_msgpack_reference.phpt b/tests/ext/dd_trace_serialize_msgpack_reference.phpt deleted file mode 100644 index 4b1a4306967..00000000000 --- a/tests/ext/dd_trace_serialize_msgpack_reference.phpt +++ /dev/null @@ -1,47 +0,0 @@ ---TEST-- -dd_trace_serialize_msgpack() with references ---DESCRIPTION-- -The "EXPECT" section was generated with the following tool: -https://github.com/ludocode/msgpack-tools -Example command: -$ echo '{"compact": true, "schema": 0}' | json2msgpack | hexdump ---SKIPIF-- - ---FILE-- - "1589331357723252209", - "span_id" => "1589331357723252210", - "name" => "test_name", - "resource" => "test_resource", - "service" => "test_service", - "start" => 1518038421211969000, - "error" => 0, - ], -]]; - -$globalTags = ['foo' => 'bar']; -foreach ($traces[0] as &$span) { - foreach ($globalTags as $globalTagName => $globalTagValue) { - $span['meta'][$globalTagName] = $globalTagValue; - } -} - -echo json_encode($traces) . "\n"; - -$encoded = dd_trace_serialize_msgpack($traces); -echo dd_trace_unserialize_trace_hex($encoded) . "\n"; -?> ---EXPECT-- -[[{"trace_id":"1589331357723252209","span_id":"1589331357723252210","name":"test_name","resource":"test_resource","service":"test_service","start":1518038421211969000,"error":0,"meta":{"foo":"bar"}}]] -91 91 88 a8 74 72 61 63 65 5f 69 64 cf 16 0e 70 72 ff 7b d5 f1 a7 73 70 61 6e 5f 69 64 cf 16 0e 70 72 ff 7b d5 f2 a4 6e 61 6d 65 a9 74 65 73 74 5f 6e 61 6d 65 a8 72 65 73 6f 75 72 63 65 ad 74 65 73 74 5f 72 65 73 6f 75 72 63 65 a7 73 65 72 76 69 63 65 ac 74 65 73 74 5f 73 65 72 76 69 63 65 a5 73 74 61 72 74 cf 15 11 27 e6 b3 bb f5 e8 a5 65 72 72 6f 72 00 a4 6d 65 74 61 81 a3 66 6f 6f a3 62 61 72 diff --git a/tests/ext/dd_trace_span_data_get_link.phpt b/tests/ext/dd_trace_span_data_get_link.phpt index de41d8f90ef..c577a332173 100644 --- a/tests/ext/dd_trace_span_data_get_link.phpt +++ b/tests/ext/dd_trace_span_data_get_link.phpt @@ -27,6 +27,6 @@ greet('Datadog'); --EXPECTF-- Hello, Datadog. greet tracer. -string(%d) "{"trace_id":"%s","span_id":"%s"}" +string(%d) "{"traceId":"%s","spanId":"%s"}" bool(true) bool(true) diff --git a/tests/ext/dd_trace_span_data_serialization_with_links.phpt b/tests/ext/dd_trace_span_data_serialization_with_links.phpt index 9edbb95974f..ba32b0ce973 100644 --- a/tests/ext/dd_trace_span_data_serialization_with_links.phpt +++ b/tests/ext/dd_trace_span_data_serialization_with_links.phpt @@ -16,6 +16,8 @@ DDTrace\trace_function('foo', $span->name = 'foo'; $firstLink = $span->getLink(); + // Drive the link through the real serialization path (produces meta["_dd.span_links"]). + $span->links = [$firstLink]; } ); @@ -24,6 +26,8 @@ DDTrace\trace_function('bar', $span->name = 'bar'; $secondLink = $span->getLink(); + // Drive the link through the real serialization path (produces meta["_dd.span_links"]). + $span->links = [$secondLink]; } ); @@ -39,28 +43,15 @@ foo(); bar(); baz(); -var_dump(json_encode($firstLink)); -var_dump($firstLink->jsonSerialize()); -var_dump(json_encode($secondLink)); -var_dump($secondLink->jsonSerialize()); -var_dump(dd_clean_spans()[0]); +$spans = dd_clean_spans(); +// baz carries both links; foo and bar each carry their own self-link. All are asserted through +// the actual span serialization (meta["_dd.span_links"]), which is the real wire path. +var_dump($spans[0]); +var_dump($spans[1]['name'], $spans[1]['meta']['_dd.span_links']); +var_dump($spans[2]['name'], $spans[2]['meta']['_dd.span_links']); ?> --EXPECTF-- -string(76) "{"trace_id":"%sc151df7d6ee5e2d6","span_id":"a3978fb9b92502a8"}" -array(5) { - ["trace_id"]=> - string(32) "%sc151df7d6ee5e2d6" - ["span_id"]=> - string(16) "a3978fb9b92502a8" -} -string(76) "{"trace_id":"%sc151df7d6ee5e2d6","span_id":"c08c967f0e5e7b0a"}" -array(5) { - ["trace_id"]=> - string(32) "%sc151df7d6ee5e2d6" - ["span_id"]=> - string(16) "c08c967f0e5e7b0a" -} array(10) { ["trace_id"]=> string(20) "13930160852258120406" @@ -86,3 +77,7 @@ array(10) { string(155) "[{"trace_id":"%sc151df7d6ee5e2d6","span_id":"a3978fb9b92502a8"},{"trace_id":"%sc151df7d6ee5e2d6","span_id":"c08c967f0e5e7b0a"}]" } } +string(3) "bar" +string(78) "[{"trace_id":"%sc151df7d6ee5e2d6","span_id":"c08c967f0e5e7b0a"}]" +string(3) "foo" +string(78) "[{"trace_id":"%sc151df7d6ee5e2d6","span_id":"a3978fb9b92502a8"}]" diff --git a/tests/ext/http_endpoint_resource_renaming_basic.phpt b/tests/ext/http_endpoint_resource_renaming_basic.phpt index 745924ce7ea..621354e1781 100644 --- a/tests/ext/http_endpoint_resource_renaming_basic.phpt +++ b/tests/ext/http_endpoint_resource_renaming_basic.phpt @@ -32,7 +32,6 @@ function test_endpoint($path) { } else { echo "Path: $path - No spans\n\n"; } - dd_trace_reset(); } // Test invalid inputs and root diff --git a/tests/ext/sandbox-regression/reset_configured_overrides.phpt b/tests/ext/sandbox-regression/reset_configured_overrides.phpt index 399b57d7551..085bc7b65ae 100644 --- a/tests/ext/sandbox-regression/reset_configured_overrides.phpt +++ b/tests/ext/sandbox-regression/reset_configured_overrides.phpt @@ -1,5 +1,5 @@ --TEST-- -[Sandbox regression] Traced functions and methods are untraced with reset +[Sandbox regression] Re-tracing a function/method adds an additional hook (hooks stack) --FILE-- m(); test(); -echo (dd_trace_reset() ? "TRUE": "FALSE") . PHP_EOL; - -// Cannot call a function while it is not traced and later expect it to trace -//$object->m(); -//test(); - DDTrace\trace_method("Test", "m", function(){ echo "METHOD HOOK2" . PHP_EOL; }); @@ -47,7 +41,6 @@ METHOD METHOD HOOK FUNCTION FUNCTION HOOK -TRUE METHOD METHOD HOOK2 METHOD HOOK diff --git a/tests/ext/sandbox/span_clone.phpt b/tests/ext/sandbox/span_clone.phpt index 0ce6e5ee728..0afae2b4bd9 100644 --- a/tests/ext/sandbox/span_clone.phpt +++ b/tests/ext/sandbox/span_clone.phpt @@ -27,17 +27,13 @@ var_dump(dd_clean_spans()); ?> --EXPECTF-- -object(DDTrace\RootSpanData)#%d (24) { +object(DDTrace\RootSpanData)#%d (29) { ["name"]=> string(3) "foo" ["resource"]=> string(3) "abc" ["service"]=> string(14) "span_clone.php" - ["env"]=> - string(0) "" - ["version"]=> - string(0) "" ["meta_struct"]=> array(0) { } @@ -69,9 +65,9 @@ object(DDTrace\RootSpanData)#%d (24) { ["parent"]=> NULL ["stack"]=> - object(DDTrace\SpanStack)#%d (3) { + object(DDTrace\SpanStack)#%d (4) { ["parent"]=> - object(DDTrace\SpanStack)#%d (3) { + object(DDTrace\SpanStack)#%d (4) { ["parent"]=> NULL ["active"]=> @@ -79,24 +75,43 @@ object(DDTrace\RootSpanData)#%d (24) { ["spanCreationObservers"]=> array(0) { } + ["attributes"]=> + array(0) { + } } ["active"]=> *RECURSION* ["spanCreationObservers"]=> array(0) { } + ["attributes"]=> + array(0) { + } } ["onClose"]=> array(0) { } ["baggage"]=> array(0) { + } + ["env"]=> + string(0) "" + ["version"]=> + string(0) "" + ["component"]=> + string(0) "" + ["spanKind"]=> + int(0) + ["attributes"]=> + array(0) { }%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r ["propagatedTags"]=> array(0) { } ["samplingPriority"]=> - int(1073741824)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r + int(1073741824) + ["samplingMechanism"]=> + int(0)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r ["tracestateTags"]=> array(0) { }%r(\s*\["parentId"\]=>\s+uninitialized\(string\))?%r @@ -106,18 +121,16 @@ object(DDTrace\RootSpanData)#%d (24) { NULL ["inferredSpan"]=> NULL + ["hostname"]=> + string(0) "" } -object(DDTrace\RootSpanData)#%d (24) { +object(DDTrace\RootSpanData)#%d (29) { ["name"]=> string(5) "dummy" ["resource"]=> string(3) "abc" ["service"]=> string(14) "span_clone.php" - ["env"]=> - string(0) "" - ["version"]=> - string(0) "" ["meta_struct"]=> array(0) { } @@ -149,9 +162,9 @@ object(DDTrace\RootSpanData)#%d (24) { ["parent"]=> NULL ["stack"]=> - object(DDTrace\SpanStack)#%d (3) { + object(DDTrace\SpanStack)#%d (4) { ["parent"]=> - object(DDTrace\SpanStack)#%d (3) { + object(DDTrace\SpanStack)#%d (4) { ["parent"]=> NULL ["active"]=> @@ -159,19 +172,18 @@ object(DDTrace\RootSpanData)#%d (24) { ["spanCreationObservers"]=> array(0) { } + ["attributes"]=> + array(0) { + } } ["active"]=> - object(DDTrace\RootSpanData)#%d (24) { + object(DDTrace\RootSpanData)#%d (29) { ["name"]=> string(3) "foo" ["resource"]=> string(3) "abc" ["service"]=> string(14) "span_clone.php" - ["env"]=> - string(0) "" - ["version"]=> - string(0) "" ["meta_struct"]=> array(0) { } @@ -209,12 +221,25 @@ object(DDTrace\RootSpanData)#%d (24) { } ["baggage"]=> array(0) { + } + ["env"]=> + string(0) "" + ["version"]=> + string(0) "" + ["component"]=> + string(0) "" + ["spanKind"]=> + int(0) + ["attributes"]=> + array(0) { }%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r ["propagatedTags"]=> array(0) { } ["samplingPriority"]=> - int(1073741824)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r + int(1073741824) + ["samplingMechanism"]=> + int(0)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r ["tracestateTags"]=> array(0) { }%r(\s*\["parentId"\]=>\s+uninitialized\(string\))?%r @@ -224,22 +249,40 @@ object(DDTrace\RootSpanData)#%d (24) { NULL ["inferredSpan"]=> NULL + ["hostname"]=> + string(0) "" } ["spanCreationObservers"]=> array(0) { } + ["attributes"]=> + array(0) { + } } ["onClose"]=> array(0) { } ["baggage"]=> array(0) { + } + ["env"]=> + string(0) "" + ["version"]=> + string(0) "" + ["component"]=> + string(0) "" + ["spanKind"]=> + int(0) + ["attributes"]=> + array(0) { }%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r ["propagatedTags"]=> array(0) { } ["samplingPriority"]=> - int(1073741824)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r + int(1073741824) + ["samplingMechanism"]=> + int(0)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r ["tracestateTags"]=> array(0) { }%r(\s*\["parentId"\]=>\s+uninitialized\(string\))?%r @@ -249,6 +292,8 @@ object(DDTrace\RootSpanData)#%d (24) { NULL ["inferredSpan"]=> NULL + ["hostname"]=> + string(0) "" } array(1) { [0]=> diff --git a/tests/ext/wrong-parameter-errors/dd_trace_send_traces_via_thread.phpt b/tests/ext/wrong-parameter-errors/dd_trace_send_traces_via_thread.phpt deleted file mode 100644 index ebd5f4b0137..00000000000 --- a/tests/ext/wrong-parameter-errors/dd_trace_send_traces_via_thread.phpt +++ /dev/null @@ -1,59 +0,0 @@ ---TEST-- -dd_trace_send_traces_via_thread is passed wrong parameters ---FILE-- - ---EXPECT-- -OK1 -OK2 -OK3 -OK4 -OK5 diff --git a/tracer/ddtrace.h b/tracer/ddtrace.h index 3a3bf90f9c3..7f24c17dbf5 100644 --- a/tracer/ddtrace.h +++ b/tracer/ddtrace.h @@ -16,6 +16,7 @@ extern zend_class_entry *ddtrace_ce_span_event; extern zend_class_entry *ddtrace_ce_exception_span_event; extern zend_class_entry *ddtrace_ce_integration; extern zend_class_entry *ddtrace_ce_git_metadata; +extern zend_class_entry *ddtrace_ce_span_kind; typedef struct ddtrace_span_ids_t ddtrace_span_ids_t; typedef struct ddtrace_span_data ddtrace_span_data; diff --git a/tracer/ddtrace.stub.php b/tracer/ddtrace.stub.php index be46d2c56b3..c0a8f95788f 100644 --- a/tracer/ddtrace.stub.php +++ b/tracer/ddtrace.stub.php @@ -164,11 +164,17 @@ class GitMetadata { } class SpanKind { + /** @var int */ const UNSPECIFIED = 0; + /** @var int */ const INTERNAL = 1; + /** @var int */ const SERVER = 2; + /** @var int */ const CLIENT = 3; + /** @var int */ const PRODUCER = 4; + /** @var int */ const CONSUMER = 5; } diff --git a/tracer/ddtrace_arginfo.h b/tracer/ddtrace_arginfo.h index afa0f62d9f7..a599fbd6549 100644 --- a/tracer/ddtrace_arginfo.h +++ b/tracer/ddtrace_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit ddtrace.stub.php instead. - * Stub hash: b3087c1f239d5aa8ea38f875b7236f47e56a1ca7 */ +/* This is a generated file, edit the .stub.php file instead. + * Stub hash: 6b003dc4618295571e977353c420aee061409aeb */ 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) @@ -184,31 +184,16 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_DDTrace_ffe_evaluate, 0, 4, DDTra ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, recordMetric, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_ffe_has_config, 0, 0, _IS_BOOL, 0) -ZEND_END_ARG_INFO() +#define arginfo_DDTrace_ffe_has_config arginfo_DDTrace_are_endpoints_collected ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_ffe_config_version, 0, 0, IS_LONG, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_Testing_ffe_load_config, 0, 1, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, json, IS_STRING, 0) -ZEND_END_ARG_INFO() - -#define arginfo_DDTrace_Testing_flush_ffe_exposures arginfo_DDTrace_are_endpoints_collected - 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() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_Config_integration_analytics_sample_rate, 0, 1, IS_DOUBLE, 0) - ZEND_ARG_TYPE_INFO(0, integrationName, IS_STRING, 0) -ZEND_END_ARG_INFO() - #define arginfo_DDTrace_UserRequest_has_listeners arginfo_DDTrace_are_endpoints_collected ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_UserRequest_notify_start, 0, 2, IS_ARRAY, 1) @@ -229,6 +214,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_UserRequest_set_blocking ZEND_ARG_TYPE_INFO(0, blockingFunction, IS_CALLABLE, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_Testing_ffe_load_config, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, json, IS_STRING, 0) +ZEND_END_ARG_INFO() + +#define arginfo_DDTrace_Testing_flush_ffe_exposures arginfo_DDTrace_are_endpoints_collected + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_Testing_trigger_error, 0, 2, IS_VOID, 0) ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, errorType, IS_LONG, 0) @@ -255,8 +246,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_Internal_record_ffe_eval ZEND_ARG_TYPE_INFO(0, allocationKey, IS_STRING, 1) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_Internal_flush_ffe_evaluation_metrics, 0, 0, _IS_BOOL, 0) -ZEND_END_ARG_INFO() +#define arginfo_DDTrace_Internal_flush_ffe_evaluation_metrics arginfo_DDTrace_are_endpoints_collected ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_datadog_appsec_v2_track_user_login_success, 0, 1, IS_VOID, 0) ZEND_ARG_TYPE_INFO(0, login, IS_STRING, 0) @@ -276,18 +266,7 @@ ZEND_END_ARG_INFO() #define arginfo_dd_trace_disable_in_request arginfo_DDTrace_are_endpoints_collected -#define arginfo_dd_trace_reset arginfo_DDTrace_are_endpoints_collected - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_dd_trace_serialize_msgpack, 0, 1, MAY_BE_BOOL|MAY_BE_STRING) - ZEND_ARG_TYPE_INFO(0, traceArray, IS_ARRAY, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dd_trace_noop, 0, 0, _IS_BOOL, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, args, IS_MIXED, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dd_trace_dd_get_memory_limit, 0, 0, IS_LONG, 0) -ZEND_END_ARG_INFO() +#define arginfo_dd_trace_dd_get_memory_limit arginfo_DDTrace_ffe_config_version #define arginfo_dd_trace_check_memory_under_limit arginfo_DDTrace_are_endpoints_collected @@ -299,20 +278,10 @@ ZEND_END_ARG_INFO() #define arginfo_ddtrace_config_trace_enabled arginfo_DDTrace_are_endpoints_collected -#define arginfo_ddtrace_config_integration_enabled arginfo_DDTrace_Config_integration_analytics_enabled - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dd_trace_send_traces_via_thread, 0, 3, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, numTraces, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, curlHeaders, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, payload, IS_STRING, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dd_trace_buffer_span, 0, 1, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, traceArray, IS_ARRAY, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ddtrace_config_integration_enabled, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, integrationName, IS_STRING, 0) ZEND_END_ARG_INFO() -#define arginfo_dd_trace_coms_trigger_writer_flush arginfo_dd_trace_dd_get_memory_limit - ZEND_BEGIN_ARG_INFO_EX(arginfo_dd_trace_internal_fn, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, functionName, IS_STRING, 0) ZEND_ARG_VARIADIC_TYPE_INFO(0, args, IS_MIXED, 0) @@ -322,11 +291,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dd_trace_set_trace_id, 0, 0, _IS ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, traceId, IS_STRING, 1, "null") ZEND_END_ARG_INFO() -#define arginfo_dd_trace_closed_spans_count arginfo_dd_trace_dd_get_memory_limit +#define arginfo_dd_trace_closed_spans_count arginfo_DDTrace_ffe_config_version #define arginfo_dd_trace_tracer_is_limited arginfo_DDTrace_are_endpoints_collected -#define arginfo_dd_trace_compile_time_microseconds arginfo_dd_trace_dd_get_memory_limit +#define arginfo_dd_trace_compile_time_microseconds arginfo_DDTrace_ffe_config_version #define arginfo_dd_trace_serialize_closed_spans arginfo_DDTrace_current_context @@ -357,30 +326,25 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DDTrace_SpanEvent___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timestamp, IS_LONG, 1, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DDTrace_SpanEvent_jsonSerialize, 0, 0, IS_MIXED, 0) -ZEND_END_ARG_INFO() - ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DDTrace_ExceptionSpanEvent___construct, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, exception, Throwable, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, attributes, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() -#define arginfo_class_DDTrace_SpanLink_jsonSerialize arginfo_class_DDTrace_SpanEvent_jsonSerialize - ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DDTrace_SpanLink_fromHeaders, 0, 1, DDTrace\\SpanLink, 0) ZEND_ARG_TYPE_MASK(0, headersOrCallback, MAY_BE_ARRAY|MAY_BE_CALLABLE, NULL) ZEND_END_ARG_INFO() -#define arginfo_class_DDTrace_SpanData_getDuration arginfo_dd_trace_dd_get_memory_limit +#define arginfo_class_DDTrace_SpanData_getDuration arginfo_DDTrace_ffe_config_version -#define arginfo_class_DDTrace_SpanData_getStartTime arginfo_dd_trace_dd_get_memory_limit +#define arginfo_class_DDTrace_SpanData_getStartTime arginfo_DDTrace_ffe_config_version ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DDTrace_SpanData_getLink, 0, 0, DDTrace\\SpanLink, 0) ZEND_END_ARG_INFO() #define arginfo_class_DDTrace_SpanData_hexId arginfo_DDTrace_startup_logs -#define arginfo_class_DDTrace_Integration_init arginfo_dd_trace_dd_get_memory_limit +#define arginfo_class_DDTrace_Integration_init arginfo_DDTrace_ffe_config_version ZEND_FUNCTION(DDTrace_trace_method); ZEND_FUNCTION(DDTrace_trace_function); @@ -428,16 +392,14 @@ ZEND_FUNCTION(DDTrace_flush_endpoints); ZEND_FUNCTION(DDTrace_ffe_evaluate); ZEND_FUNCTION(DDTrace_ffe_has_config); ZEND_FUNCTION(DDTrace_ffe_config_version); -ZEND_FUNCTION(DDTrace_Testing_ffe_load_config); -ZEND_FUNCTION(DDTrace_Testing_flush_ffe_exposures); 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); ZEND_FUNCTION(DDTrace_UserRequest_notify_start); ZEND_FUNCTION(DDTrace_UserRequest_notify_commit); ZEND_FUNCTION(DDTrace_UserRequest_set_blocking_function); +ZEND_FUNCTION(DDTrace_Testing_ffe_load_config); +ZEND_FUNCTION(DDTrace_Testing_flush_ffe_exposures); ZEND_FUNCTION(DDTrace_Testing_trigger_error); ZEND_FUNCTION(DDTrace_Testing_emit_asm_event); ZEND_FUNCTION(DDTrace_Testing_normalize_tag_value); @@ -449,18 +411,12 @@ ZEND_FUNCTION(datadog_appsec_v2_track_user_login_success); ZEND_FUNCTION(datadog_appsec_v2_track_user_login_failure); ZEND_FUNCTION(dd_trace_env_config); ZEND_FUNCTION(dd_trace_disable_in_request); -ZEND_FUNCTION(dd_trace_reset); -ZEND_FUNCTION(dd_trace_serialize_msgpack); -ZEND_FUNCTION(dd_trace_noop); ZEND_FUNCTION(dd_trace_dd_get_memory_limit); ZEND_FUNCTION(dd_trace_check_memory_under_limit); ZEND_FUNCTION(ddtrace_config_app_name); ZEND_FUNCTION(ddtrace_config_distributed_tracing_enabled); ZEND_FUNCTION(ddtrace_config_trace_enabled); ZEND_FUNCTION(ddtrace_config_integration_enabled); -ZEND_FUNCTION(dd_trace_send_traces_via_thread); -ZEND_FUNCTION(dd_trace_buffer_span); -ZEND_FUNCTION(dd_trace_coms_trigger_writer_flush); ZEND_FUNCTION(dd_trace_internal_fn); ZEND_FUNCTION(dd_trace_set_trace_id); ZEND_FUNCTION(dd_trace_closed_spans_count); @@ -474,9 +430,7 @@ ZEND_FUNCTION(DDTrace_trace_method); ZEND_FUNCTION(dd_untrace); ZEND_FUNCTION(dd_trace_synchronous_flush); ZEND_METHOD(DDTrace_SpanEvent, __construct); -ZEND_METHOD(DDTrace_SpanEvent, jsonSerialize); ZEND_METHOD(DDTrace_ExceptionSpanEvent, __construct); -ZEND_METHOD(DDTrace_SpanLink, jsonSerialize); ZEND_METHOD(DDTrace_SpanLink, fromHeaders); ZEND_METHOD(DDTrace_SpanData, getDuration); ZEND_METHOD(DDTrace_SpanData, getStartTime); @@ -532,8 +486,6 @@ static const zend_function_entry ext_functions[] = { ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "ffe_config_version"), zif_DDTrace_ffe_config_version, arginfo_DDTrace_ffe_config_version, 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) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\UserRequest", "notify_start"), zif_DDTrace_UserRequest_notify_start, arginfo_DDTrace_UserRequest_notify_start, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\UserRequest", "notify_commit"), zif_DDTrace_UserRequest_notify_commit, arginfo_DDTrace_UserRequest_notify_commit, 0, NULL, NULL) @@ -551,23 +503,17 @@ static const zend_function_entry ext_functions[] = { ZEND_RAW_FENTRY(ZEND_NS_NAME("datadog\\appsec\\v2", "track_user_login_failure"), zif_datadog_appsec_v2_track_user_login_failure, arginfo_datadog_appsec_v2_track_user_login_failure, 0, NULL, NULL) ZEND_FE(dd_trace_env_config, arginfo_dd_trace_env_config) ZEND_FE(dd_trace_disable_in_request, arginfo_dd_trace_disable_in_request) - ZEND_FE(dd_trace_reset, arginfo_dd_trace_reset) - ZEND_FE(dd_trace_serialize_msgpack, arginfo_dd_trace_serialize_msgpack) - ZEND_FE(dd_trace_noop, arginfo_dd_trace_noop) ZEND_FE(dd_trace_dd_get_memory_limit, arginfo_dd_trace_dd_get_memory_limit) ZEND_FE(dd_trace_check_memory_under_limit, arginfo_dd_trace_check_memory_under_limit) - ZEND_FE(ddtrace_config_app_name, arginfo_ddtrace_config_app_name) - ZEND_FE(ddtrace_config_distributed_tracing_enabled, arginfo_ddtrace_config_distributed_tracing_enabled) - ZEND_FE(ddtrace_config_trace_enabled, arginfo_ddtrace_config_trace_enabled) + ZEND_RAW_FENTRY("ddtrace_config_app_name", zif_ddtrace_config_app_name, arginfo_ddtrace_config_app_name, 0, NULL, NULL) + ZEND_RAW_FENTRY("ddtrace_config_distributed_tracing_enabled", zif_ddtrace_config_distributed_tracing_enabled, arginfo_ddtrace_config_distributed_tracing_enabled, 0, NULL, NULL) + ZEND_RAW_FENTRY("ddtrace_config_trace_enabled", zif_ddtrace_config_trace_enabled, arginfo_ddtrace_config_trace_enabled, 0, NULL, NULL) ZEND_FE(ddtrace_config_integration_enabled, arginfo_ddtrace_config_integration_enabled) - ZEND_FE(dd_trace_send_traces_via_thread, arginfo_dd_trace_send_traces_via_thread) - ZEND_FE(dd_trace_buffer_span, arginfo_dd_trace_buffer_span) - ZEND_FE(dd_trace_coms_trigger_writer_flush, arginfo_dd_trace_coms_trigger_writer_flush) ZEND_FE(dd_trace_internal_fn, arginfo_dd_trace_internal_fn) - ZEND_FE(dd_trace_set_trace_id, arginfo_dd_trace_set_trace_id) + ZEND_RAW_FENTRY("dd_trace_set_trace_id", zif_dd_trace_set_trace_id, arginfo_dd_trace_set_trace_id, 0, NULL, NULL) ZEND_FE(dd_trace_closed_spans_count, arginfo_dd_trace_closed_spans_count) ZEND_FE(dd_trace_tracer_is_limited, arginfo_dd_trace_tracer_is_limited) - ZEND_FE(dd_trace_compile_time_microseconds, arginfo_dd_trace_compile_time_microseconds) + ZEND_RAW_FENTRY("dd_trace_compile_time_microseconds", zif_dd_trace_compile_time_microseconds, arginfo_dd_trace_compile_time_microseconds, 0, NULL, NULL) ZEND_FE(dd_trace_serialize_closed_spans, arginfo_dd_trace_serialize_closed_spans) ZEND_FE(dd_trace_peek_span_id, arginfo_dd_trace_peek_span_id) ZEND_FE(dd_trace_close_all_spans_and_flush, arginfo_dd_trace_close_all_spans_and_flush) @@ -580,7 +526,6 @@ static const zend_function_entry ext_functions[] = { static const zend_function_entry class_DDTrace_SpanEvent_methods[] = { ZEND_ME(DDTrace_SpanEvent, __construct, arginfo_class_DDTrace_SpanEvent___construct, ZEND_ACC_PUBLIC) - ZEND_ME(DDTrace_SpanEvent, jsonSerialize, arginfo_class_DDTrace_SpanEvent_jsonSerialize, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -590,7 +535,6 @@ static const zend_function_entry class_DDTrace_ExceptionSpanEvent_methods[] = { }; static const zend_function_entry class_DDTrace_SpanLink_methods[] = { - ZEND_ME(DDTrace_SpanLink, jsonSerialize, arginfo_class_DDTrace_SpanLink_jsonSerialize, ZEND_ACC_PUBLIC) ZEND_ME(DDTrace_SpanLink, fromHeaders, arginfo_class_DDTrace_SpanLink_fromHeaders, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_FE_END }; @@ -639,39 +583,39 @@ static zend_class_entry *register_class_DDTrace_FfeResult(void) zval property_valueJson_default_value; ZVAL_NULL(&property_valueJson_default_value); - zend_string *property_valueJson_name = zend_string_init("valueJson", sizeof("valueJson") - 1, true); + zend_string *property_valueJson_name = zend_string_init("valueJson", sizeof("valueJson") - 1, 1); zend_declare_typed_property(class_entry, property_valueJson_name, &property_valueJson_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release_ex(property_valueJson_name, true); + zend_string_release(property_valueJson_name); zval property_variant_default_value; ZVAL_NULL(&property_variant_default_value); - zend_string *property_variant_name = zend_string_init("variant", sizeof("variant") - 1, true); + zend_string *property_variant_name = zend_string_init("variant", sizeof("variant") - 1, 1); zend_declare_typed_property(class_entry, property_variant_name, &property_variant_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release_ex(property_variant_name, true); + zend_string_release(property_variant_name); zval property_allocationKey_default_value; ZVAL_NULL(&property_allocationKey_default_value); - zend_string *property_allocationKey_name = zend_string_init("allocationKey", sizeof("allocationKey") - 1, true); + zend_string *property_allocationKey_name = zend_string_init("allocationKey", sizeof("allocationKey") - 1, 1); zend_declare_typed_property(class_entry, property_allocationKey_name, &property_allocationKey_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release_ex(property_allocationKey_name, true); + zend_string_release(property_allocationKey_name); zval property_reason_default_value; ZVAL_LONG(&property_reason_default_value, 0); - zend_string *property_reason_name = zend_string_init("reason", sizeof("reason") - 1, true); + zend_string *property_reason_name = zend_string_init("reason", sizeof("reason") - 1, 1); zend_declare_typed_property(class_entry, property_reason_name, &property_reason_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release_ex(property_reason_name, true); + zend_string_release(property_reason_name); zval property_errorCode_default_value; ZVAL_LONG(&property_errorCode_default_value, 0); - zend_string *property_errorCode_name = zend_string_init("errorCode", sizeof("errorCode") - 1, true); + zend_string *property_errorCode_name = zend_string_init("errorCode", sizeof("errorCode") - 1, 1); zend_declare_typed_property(class_entry, property_errorCode_name, &property_errorCode_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release_ex(property_errorCode_name, true); + zend_string_release(property_errorCode_name); zval property_doLog_default_value; ZVAL_FALSE(&property_doLog_default_value); - zend_string *property_doLog_name = zend_string_init("doLog", sizeof("doLog") - 1, true); + zend_string *property_doLog_name = zend_string_init("doLog", sizeof("doLog") - 1, 1); zend_declare_typed_property(class_entry, property_doLog_name, &property_doLog_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release_ex(property_doLog_name, true); + zend_string_release(property_doLog_name); zval property_serialId_default_value; ZVAL_NULL(&property_serialId_default_value); @@ -681,54 +625,55 @@ static zend_class_entry *register_class_DDTrace_FfeResult(void) zval property_providerState_default_value; ZVAL_EMPTY_ARRAY(&property_providerState_default_value); - zend_string *property_providerState_name = zend_string_init("providerState", sizeof("providerState") - 1, true); + zend_string *property_providerState_name = zend_string_init("providerState", sizeof("providerState") - 1, 1); zend_declare_typed_property(class_entry, property_providerState_name, &property_providerState_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_providerState_name, true); + zend_string_release(property_providerState_name); zval property_errorMessage_default_value; ZVAL_NULL(&property_errorMessage_default_value); - zend_string *property_errorMessage_name = zend_string_init("errorMessage", sizeof("errorMessage") - 1, true); + zend_string *property_errorMessage_name = zend_string_init("errorMessage", sizeof("errorMessage") - 1, 1); zend_declare_typed_property(class_entry, property_errorMessage_name, &property_errorMessage_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release_ex(property_errorMessage_name, true); + zend_string_release(property_errorMessage_name); zval property_hasConfig_default_value; ZVAL_NULL(&property_hasConfig_default_value); - zend_string *property_hasConfig_name = zend_string_init("hasConfig", sizeof("hasConfig") - 1, true); + zend_string *property_hasConfig_name = zend_string_init("hasConfig", sizeof("hasConfig") - 1, 1); zend_declare_typed_property(class_entry, property_hasConfig_name, &property_hasConfig_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL|MAY_BE_NULL)); - zend_string_release_ex(property_hasConfig_name, true); + zend_string_release(property_hasConfig_name); zval property_configVersion_default_value; ZVAL_NULL(&property_configVersion_default_value); - zend_string *property_configVersion_name = zend_string_init("configVersion", sizeof("configVersion") - 1, true); + zend_string *property_configVersion_name = zend_string_init("configVersion", sizeof("configVersion") - 1, 1); zend_declare_typed_property(class_entry, property_configVersion_name, &property_configVersion_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release_ex(property_configVersion_name, true); + zend_string_release(property_configVersion_name); return class_entry; } -static zend_class_entry *register_class_DDTrace_SpanEvent(zend_class_entry *class_entry_JsonSerializable) +static zend_class_entry *register_class_DDTrace_SpanEvent(void) { zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "DDTrace", "SpanEvent", class_DDTrace_SpanEvent_methods); class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); - zend_class_implements(class_entry, 1, class_entry_JsonSerializable); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); - zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_name_name); zval property_attributes_default_value; ZVAL_UNDEF(&property_attributes_default_value); - zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, true); + zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_attributes_name, true); + zend_string_release(property_attributes_name); zval property_timestamp_default_value; ZVAL_UNDEF(&property_timestamp_default_value); - zend_string *property_timestamp_name = zend_string_init("timestamp", sizeof("timestamp") - 1, true); + zend_string *property_timestamp_name = zend_string_init("timestamp", sizeof("timestamp") - 1, 1); zend_declare_typed_property(class_entry, property_timestamp_name, &property_timestamp_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release_ex(property_timestamp_name, true); + zend_string_release(property_timestamp_name); return class_entry; } @@ -742,51 +687,50 @@ static zend_class_entry *register_class_DDTrace_ExceptionSpanEvent(zend_class_en zval property_exception_default_value; ZVAL_UNDEF(&property_exception_default_value); - zend_string *property_exception_name = zend_string_init("exception", sizeof("exception") - 1, true); + zend_string *property_exception_name = zend_string_init("exception", sizeof("exception") - 1, 1); zend_string *property_exception_class_Throwable = zend_string_init("Throwable", sizeof("Throwable")-1, 1); zend_declare_typed_property(class_entry, property_exception_name, &property_exception_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_exception_class_Throwable, 0, 0)); - zend_string_release_ex(property_exception_name, true); + zend_string_release(property_exception_name); return class_entry; } -static zend_class_entry *register_class_DDTrace_SpanLink(zend_class_entry *class_entry_JsonSerializable) +static zend_class_entry *register_class_DDTrace_SpanLink(void) { zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "DDTrace", "SpanLink", class_DDTrace_SpanLink_methods); class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); - zend_class_implements(class_entry, 1, class_entry_JsonSerializable); zval property_traceId_default_value; ZVAL_UNDEF(&property_traceId_default_value); - zend_string *property_traceId_name = zend_string_init("traceId", sizeof("traceId") - 1, true); + zend_string *property_traceId_name = zend_string_init("traceId", sizeof("traceId") - 1, 1); zend_declare_typed_property(class_entry, property_traceId_name, &property_traceId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_traceId_name, true); + zend_string_release(property_traceId_name); zval property_spanId_default_value; ZVAL_UNDEF(&property_spanId_default_value); - zend_string *property_spanId_name = zend_string_init("spanId", sizeof("spanId") - 1, true); + zend_string *property_spanId_name = zend_string_init("spanId", sizeof("spanId") - 1, 1); zend_declare_typed_property(class_entry, property_spanId_name, &property_spanId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_spanId_name, true); + zend_string_release(property_spanId_name); zval property_traceState_default_value; ZVAL_UNDEF(&property_traceState_default_value); - zend_string *property_traceState_name = zend_string_init("traceState", sizeof("traceState") - 1, true); + zend_string *property_traceState_name = zend_string_init("traceState", sizeof("traceState") - 1, 1); zend_declare_typed_property(class_entry, property_traceState_name, &property_traceState_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_traceState_name, true); + zend_string_release(property_traceState_name); zval property_attributes_default_value; ZVAL_UNDEF(&property_attributes_default_value); - zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, true); + zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_attributes_name, true); + zend_string_release(property_attributes_name); zval property_droppedAttributesCount_default_value; ZVAL_UNDEF(&property_droppedAttributesCount_default_value); - zend_string *property_droppedAttributesCount_name = zend_string_init("droppedAttributesCount", sizeof("droppedAttributesCount") - 1, true); + zend_string *property_droppedAttributesCount_name = zend_string_init("droppedAttributesCount", sizeof("droppedAttributesCount") - 1, 1); zend_declare_typed_property(class_entry, property_droppedAttributesCount_name, &property_droppedAttributesCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release_ex(property_droppedAttributesCount_name, true); + zend_string_release(property_droppedAttributesCount_name); return class_entry; } @@ -800,15 +744,61 @@ static zend_class_entry *register_class_DDTrace_GitMetadata(void) zval property_commitSha_default_value; ZVAL_EMPTY_STRING(&property_commitSha_default_value); - zend_string *property_commitSha_name = zend_string_init("commitSha", sizeof("commitSha") - 1, true); + zend_string *property_commitSha_name = zend_string_init("commitSha", sizeof("commitSha") - 1, 1); zend_declare_typed_property(class_entry, property_commitSha_name, &property_commitSha_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_commitSha_name, true); + zend_string_release(property_commitSha_name); zval property_repositoryUrl_default_value; ZVAL_EMPTY_STRING(&property_repositoryUrl_default_value); - zend_string *property_repositoryUrl_name = zend_string_init("repositoryUrl", sizeof("repositoryUrl") - 1, true); + zend_string *property_repositoryUrl_name = zend_string_init("repositoryUrl", sizeof("repositoryUrl") - 1, 1); zend_declare_typed_property(class_entry, property_repositoryUrl_name, &property_repositoryUrl_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_repositoryUrl_name, true); + zend_string_release(property_repositoryUrl_name); + + return class_entry; +} + +static zend_class_entry *register_class_DDTrace_SpanKind(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "DDTrace", "SpanKind", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); + + zval const_UNSPECIFIED_value; + ZVAL_LONG(&const_UNSPECIFIED_value, 0); + zend_string *const_UNSPECIFIED_name = zend_string_init_interned("UNSPECIFIED", sizeof("UNSPECIFIED") - 1, 1); + zend_declare_class_constant_ex(class_entry, const_UNSPECIFIED_name, &const_UNSPECIFIED_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release(const_UNSPECIFIED_name); + + zval const_INTERNAL_value; + ZVAL_LONG(&const_INTERNAL_value, 1); + zend_string *const_INTERNAL_name = zend_string_init_interned("INTERNAL", sizeof("INTERNAL") - 1, 1); + zend_declare_class_constant_ex(class_entry, const_INTERNAL_name, &const_INTERNAL_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release(const_INTERNAL_name); + + zval const_SERVER_value; + ZVAL_LONG(&const_SERVER_value, 2); + zend_string *const_SERVER_name = zend_string_init_interned("SERVER", sizeof("SERVER") - 1, 1); + zend_declare_class_constant_ex(class_entry, const_SERVER_name, &const_SERVER_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release(const_SERVER_name); + + zval const_CLIENT_value; + ZVAL_LONG(&const_CLIENT_value, 3); + zend_string *const_CLIENT_name = zend_string_init_interned("CLIENT", sizeof("CLIENT") - 1, 1); + zend_declare_class_constant_ex(class_entry, const_CLIENT_name, &const_CLIENT_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release(const_CLIENT_name); + + zval const_PRODUCER_value; + ZVAL_LONG(&const_PRODUCER_value, 4); + zend_string *const_PRODUCER_name = zend_string_init_interned("PRODUCER", sizeof("PRODUCER") - 1, 1); + zend_declare_class_constant_ex(class_entry, const_PRODUCER_name, &const_PRODUCER_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release(const_PRODUCER_name); + + zval const_CONSUMER_value; + ZVAL_LONG(&const_CONSUMER_value, 5); + zend_string *const_CONSUMER_name = zend_string_init_interned("CONSUMER", sizeof("CONSUMER") - 1, 1); + zend_declare_class_constant_ex(class_entry, const_CONSUMER_name, &const_CONSUMER_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release(const_CONSUMER_name); return class_entry; } @@ -822,106 +812,132 @@ static zend_class_entry *register_class_DDTrace_SpanData(void) zval property_name_default_value; ZVAL_EMPTY_STRING(&property_name_default_value); - zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_string_release(property_name_name); zval property_resource_default_value; ZVAL_EMPTY_STRING(&property_resource_default_value); - zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_RESOURCE), &property_resource_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_string *property_resource_name = zend_string_init("resource", sizeof("resource") - 1, 1); + zend_declare_typed_property(class_entry, property_resource_name, &property_resource_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_string_release(property_resource_name); zval property_service_default_value; ZVAL_EMPTY_STRING(&property_service_default_value); - zend_string *property_service_name = zend_string_init("service", sizeof("service") - 1, true); + zend_string *property_service_name = zend_string_init("service", sizeof("service") - 1, 1); zend_declare_typed_property(class_entry, property_service_name, &property_service_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release_ex(property_service_name, true); - - zval property_env_default_value; - ZVAL_EMPTY_STRING(&property_env_default_value); - zend_string *property_env_name = zend_string_init("env", sizeof("env") - 1, true); - zend_declare_typed_property(class_entry, property_env_name, &property_env_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_env_name, true); - - zval property_version_default_value; - ZVAL_EMPTY_STRING(&property_version_default_value); - zend_string *property_version_name = zend_string_init("version", sizeof("version") - 1, true); - zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_version_name, true); + zend_string_release(property_service_name); zval property_meta_struct_default_value; ZVAL_EMPTY_ARRAY(&property_meta_struct_default_value); - zend_string *property_meta_struct_name = zend_string_init("meta_struct", sizeof("meta_struct") - 1, true); + zend_string *property_meta_struct_name = zend_string_init("meta_struct", sizeof("meta_struct") - 1, 1); zend_declare_typed_property(class_entry, property_meta_struct_name, &property_meta_struct_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_meta_struct_name, true); + zend_string_release(property_meta_struct_name); zval property_type_default_value; ZVAL_EMPTY_STRING(&property_type_default_value); - zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_TYPE), &property_type_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_string *property_type_name = zend_string_init("type", sizeof("type") - 1, 1); + zend_declare_typed_property(class_entry, property_type_name, &property_type_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_string_release(property_type_name); zval property_meta_default_value; ZVAL_EMPTY_ARRAY(&property_meta_default_value); - zend_string *property_meta_name = zend_string_init("meta", sizeof("meta") - 1, true); + zend_string *property_meta_name = zend_string_init("meta", sizeof("meta") - 1, 1); zend_declare_typed_property(class_entry, property_meta_name, &property_meta_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_meta_name, true); + zend_string_release(property_meta_name); zval property_metrics_default_value; ZVAL_EMPTY_ARRAY(&property_metrics_default_value); - zend_string *property_metrics_name = zend_string_init("metrics", sizeof("metrics") - 1, true); + zend_string *property_metrics_name = zend_string_init("metrics", sizeof("metrics") - 1, 1); zend_declare_typed_property(class_entry, property_metrics_name, &property_metrics_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_metrics_name, true); + zend_string_release(property_metrics_name); zval property_exception_default_value; ZVAL_NULL(&property_exception_default_value); - zend_string *property_exception_name = zend_string_init("exception", sizeof("exception") - 1, true); + zend_string *property_exception_name = zend_string_init("exception", sizeof("exception") - 1, 1); zend_string *property_exception_class_Throwable = zend_string_init("Throwable", sizeof("Throwable")-1, 1); zend_declare_typed_property(class_entry, property_exception_name, &property_exception_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_exception_class_Throwable, 0, MAY_BE_NULL)); - zend_string_release_ex(property_exception_name, true); + zend_string_release(property_exception_name); zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); - zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, true); + zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_id_name, true); + zend_string_release(property_id_name); zval property_links_default_value; ZVAL_EMPTY_ARRAY(&property_links_default_value); - zend_string *property_links_name = zend_string_init("links", sizeof("links") - 1, true); + zend_string *property_links_name = zend_string_init("links", sizeof("links") - 1, 1); zend_declare_typed_property(class_entry, property_links_name, &property_links_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_links_name, true); + zend_string_release(property_links_name); zval property_events_default_value; ZVAL_EMPTY_ARRAY(&property_events_default_value); - zend_string *property_events_name = zend_string_init("events", sizeof("events") - 1, true); + zend_string *property_events_name = zend_string_init("events", sizeof("events") - 1, 1); zend_declare_typed_property(class_entry, property_events_name, &property_events_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_events_name, true); + zend_string_release(property_events_name); zval property_peerServiceSources_default_value; ZVAL_EMPTY_ARRAY(&property_peerServiceSources_default_value); - zend_string *property_peerServiceSources_name = zend_string_init("peerServiceSources", sizeof("peerServiceSources") - 1, true); + zend_string *property_peerServiceSources_name = zend_string_init("peerServiceSources", sizeof("peerServiceSources") - 1, 1); zend_declare_typed_property(class_entry, property_peerServiceSources_name, &property_peerServiceSources_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_peerServiceSources_name, true); + zend_string_release(property_peerServiceSources_name); zval property_parent_default_value; ZVAL_UNDEF(&property_parent_default_value); + zend_string *property_parent_name = zend_string_init("parent", sizeof("parent") - 1, 1); zend_string *property_parent_class_DDTrace_SpanData = zend_string_init("DDTrace\\SpanData", sizeof("DDTrace\\SpanData")-1, 1); - zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_PARENT), &property_parent_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parent_class_DDTrace_SpanData, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parent_name, &property_parent_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parent_class_DDTrace_SpanData, 0, MAY_BE_NULL)); + zend_string_release(property_parent_name); zval property_stack_default_value; ZVAL_UNDEF(&property_stack_default_value); - zend_string *property_stack_name = zend_string_init("stack", sizeof("stack") - 1, true); + zend_string *property_stack_name = zend_string_init("stack", sizeof("stack") - 1, 1); zend_string *property_stack_class_DDTrace_SpanStack = zend_string_init("DDTrace\\SpanStack", sizeof("DDTrace\\SpanStack")-1, 1); zend_declare_typed_property(class_entry, property_stack_name, &property_stack_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_stack_class_DDTrace_SpanStack, 0, 0)); - zend_string_release_ex(property_stack_name, true); + zend_string_release(property_stack_name); zval property_onClose_default_value; ZVAL_EMPTY_ARRAY(&property_onClose_default_value); - zend_string *property_onClose_name = zend_string_init("onClose", sizeof("onClose") - 1, true); + zend_string *property_onClose_name = zend_string_init("onClose", sizeof("onClose") - 1, 1); zend_declare_typed_property(class_entry, property_onClose_name, &property_onClose_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_onClose_name, true); + zend_string_release(property_onClose_name); zval property_baggage_default_value; ZVAL_EMPTY_ARRAY(&property_baggage_default_value); - zend_string *property_baggage_name = zend_string_init("baggage", sizeof("baggage") - 1, true); + zend_string *property_baggage_name = zend_string_init("baggage", sizeof("baggage") - 1, 1); zend_declare_typed_property(class_entry, property_baggage_name, &property_baggage_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_baggage_name, true); + zend_string_release(property_baggage_name); + + zval property_env_default_value; + ZVAL_EMPTY_STRING(&property_env_default_value); + zend_string *property_env_name = zend_string_init("env", sizeof("env") - 1, 1); + zend_declare_typed_property(class_entry, property_env_name, &property_env_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_env_name); + + zval property_version_default_value; + ZVAL_EMPTY_STRING(&property_version_default_value); + zend_string *property_version_name = zend_string_init("version", sizeof("version") - 1, 1); + zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_version_name); + + zval property_component_default_value; + ZVAL_EMPTY_STRING(&property_component_default_value); + zend_string *property_component_name = zend_string_init("component", sizeof("component") - 1, 1); + zend_declare_typed_property(class_entry, property_component_name, &property_component_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_component_name); + + zval property_spanKind_default_value; + ZVAL_LONG(&property_spanKind_default_value, 0); + zend_string *property_spanKind_name = zend_string_init("spanKind", sizeof("spanKind") - 1, 1); + zend_declare_typed_property(class_entry, property_spanKind_name, &property_spanKind_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(property_spanKind_name); + + zval property_attributes_default_value; + ZVAL_EMPTY_ARRAY(&property_attributes_default_value); + zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); + zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); + zend_string_release(property_attributes_name); return class_entry; } @@ -945,65 +961,89 @@ static zend_class_entry *register_class_DDTrace_RootSpanData(zend_class_entry *c zval property_origin_default_value; ZVAL_UNDEF(&property_origin_default_value); - zend_string *property_origin_name = zend_string_init("origin", sizeof("origin") - 1, true); + zend_string *property_origin_name = zend_string_init("origin", sizeof("origin") - 1, 1); zend_declare_typed_property(class_entry, property_origin_name, &property_origin_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_origin_name, true); + zend_string_release(property_origin_name); zval property_propagatedTags_default_value; ZVAL_EMPTY_ARRAY(&property_propagatedTags_default_value); - zend_string *property_propagatedTags_name = zend_string_init("propagatedTags", sizeof("propagatedTags") - 1, true); + zend_string *property_propagatedTags_name = zend_string_init("propagatedTags", sizeof("propagatedTags") - 1, 1); zend_declare_typed_property(class_entry, property_propagatedTags_name, &property_propagatedTags_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_propagatedTags_name, true); + zend_string_release(property_propagatedTags_name); zval property_samplingPriority_default_value; ZVAL_LONG(&property_samplingPriority_default_value, DDTRACE_PRIORITY_SAMPLING_UNKNOWN); - zend_string *property_samplingPriority_name = zend_string_init("samplingPriority", sizeof("samplingPriority") - 1, true); + zend_string *property_samplingPriority_name = zend_string_init("samplingPriority", sizeof("samplingPriority") - 1, 1); zend_declare_typed_property(class_entry, property_samplingPriority_name, &property_samplingPriority_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release_ex(property_samplingPriority_name, true); + zend_string_release(property_samplingPriority_name); + + zval property_samplingMechanism_default_value; + ZVAL_LONG(&property_samplingMechanism_default_value, 0); + zend_string *property_samplingMechanism_name = zend_string_init("samplingMechanism", sizeof("samplingMechanism") - 1, 1); + zend_declare_typed_property(class_entry, property_samplingMechanism_name, &property_samplingMechanism_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(property_samplingMechanism_name); zval property_propagatedSamplingPriority_default_value; ZVAL_UNDEF(&property_propagatedSamplingPriority_default_value); - zend_string *property_propagatedSamplingPriority_name = zend_string_init("propagatedSamplingPriority", sizeof("propagatedSamplingPriority") - 1, true); + zend_string *property_propagatedSamplingPriority_name = zend_string_init("propagatedSamplingPriority", sizeof("propagatedSamplingPriority") - 1, 1); zend_declare_typed_property(class_entry, property_propagatedSamplingPriority_name, &property_propagatedSamplingPriority_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release_ex(property_propagatedSamplingPriority_name, true); + zend_string_release(property_propagatedSamplingPriority_name); zval property_tracestate_default_value; ZVAL_UNDEF(&property_tracestate_default_value); - zend_string *property_tracestate_name = zend_string_init("tracestate", sizeof("tracestate") - 1, true); + zend_string *property_tracestate_name = zend_string_init("tracestate", sizeof("tracestate") - 1, 1); zend_declare_typed_property(class_entry, property_tracestate_name, &property_tracestate_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_tracestate_name, true); + zend_string_release(property_tracestate_name); zval property_tracestateTags_default_value; ZVAL_EMPTY_ARRAY(&property_tracestateTags_default_value); - zend_string *property_tracestateTags_name = zend_string_init("tracestateTags", sizeof("tracestateTags") - 1, true); + zend_string *property_tracestateTags_name = zend_string_init("tracestateTags", sizeof("tracestateTags") - 1, 1); zend_declare_typed_property(class_entry, property_tracestateTags_name, &property_tracestateTags_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_tracestateTags_name, true); + zend_string_release(property_tracestateTags_name); zval property_parentId_default_value; ZVAL_UNDEF(&property_parentId_default_value); - zend_string *property_parentId_name = zend_string_init("parentId", sizeof("parentId") - 1, true); + zend_string *property_parentId_name = zend_string_init("parentId", sizeof("parentId") - 1, 1); zend_declare_typed_property(class_entry, property_parentId_name, &property_parentId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_parentId_name, true); + zend_string_release(property_parentId_name); zval property_traceId_default_value; ZVAL_EMPTY_STRING(&property_traceId_default_value); - zend_string *property_traceId_name = zend_string_init("traceId", sizeof("traceId") - 1, true); + zend_string *property_traceId_name = zend_string_init("traceId", sizeof("traceId") - 1, 1); zend_declare_typed_property(class_entry, property_traceId_name, &property_traceId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release_ex(property_traceId_name, true); + zend_string_release(property_traceId_name); zval property_gitMetadata_default_value; ZVAL_NULL(&property_gitMetadata_default_value); - zend_string *property_gitMetadata_name = zend_string_init("gitMetadata", sizeof("gitMetadata") - 1, true); + zend_string *property_gitMetadata_name = zend_string_init("gitMetadata", sizeof("gitMetadata") - 1, 1); zend_string *property_gitMetadata_class_DDTrace_GitMetadata = zend_string_init("DDTrace\\GitMetadata", sizeof("DDTrace\\GitMetadata")-1, 1); zend_declare_typed_property(class_entry, property_gitMetadata_name, &property_gitMetadata_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_gitMetadata_class_DDTrace_GitMetadata, 0, MAY_BE_NULL)); - zend_string_release_ex(property_gitMetadata_name, true); + zend_string_release(property_gitMetadata_name); zval property_inferredSpan_default_value; ZVAL_NULL(&property_inferredSpan_default_value); - zend_string *property_inferredSpan_name = zend_string_init("inferredSpan", sizeof("inferredSpan") - 1, true); + zend_string *property_inferredSpan_name = zend_string_init("inferredSpan", sizeof("inferredSpan") - 1, 1); zend_string *property_inferredSpan_class_DDTrace_InferredSpanData = zend_string_init("DDTrace\\InferredSpanData", sizeof("DDTrace\\InferredSpanData")-1, 1); zend_declare_typed_property(class_entry, property_inferredSpan_name, &property_inferredSpan_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_inferredSpan_class_DDTrace_InferredSpanData, 0, MAY_BE_NULL)); - zend_string_release_ex(property_inferredSpan_name, true); + zend_string_release(property_inferredSpan_name); + + zval property_env_default_value; + ZVAL_EMPTY_STRING(&property_env_default_value); + zend_string *property_env_name = zend_string_init("env", sizeof("env") - 1, 1); + zend_declare_typed_property(class_entry, property_env_name, &property_env_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_env_name); + + zval property_version_default_value; + ZVAL_EMPTY_STRING(&property_version_default_value); + zend_string *property_version_name = zend_string_init("version", sizeof("version") - 1, 1); + zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_version_name); + + zval property_hostname_default_value; + ZVAL_EMPTY_STRING(&property_hostname_default_value); + zend_string *property_hostname_name = zend_string_init("hostname", sizeof("hostname") - 1, 1); + zend_declare_typed_property(class_entry, property_hostname_name, &property_hostname_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_hostname_name); return class_entry; } @@ -1017,21 +1057,29 @@ static zend_class_entry *register_class_DDTrace_SpanStack(void) zval property_parent_default_value; ZVAL_UNDEF(&property_parent_default_value); + zend_string *property_parent_name = zend_string_init("parent", sizeof("parent") - 1, 1); zend_string *property_parent_class_DDTrace_SpanStack = zend_string_init("DDTrace\\SpanStack", sizeof("DDTrace\\SpanStack")-1, 1); - zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_PARENT), &property_parent_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parent_class_DDTrace_SpanStack, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parent_name, &property_parent_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parent_class_DDTrace_SpanStack, 0, MAY_BE_NULL)); + zend_string_release(property_parent_name); zval property_active_default_value; ZVAL_NULL(&property_active_default_value); - zend_string *property_active_name = zend_string_init("active", sizeof("active") - 1, true); + zend_string *property_active_name = zend_string_init("active", sizeof("active") - 1, 1); zend_string *property_active_class_DDTrace_SpanData = zend_string_init("DDTrace\\SpanData", sizeof("DDTrace\\SpanData")-1, 1); zend_declare_typed_property(class_entry, property_active_name, &property_active_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_active_class_DDTrace_SpanData, 0, MAY_BE_NULL)); - zend_string_release_ex(property_active_name, true); + zend_string_release(property_active_name); zval property_spanCreationObservers_default_value; ZVAL_EMPTY_ARRAY(&property_spanCreationObservers_default_value); - zend_string *property_spanCreationObservers_name = zend_string_init("spanCreationObservers", sizeof("spanCreationObservers") - 1, true); + zend_string *property_spanCreationObservers_name = zend_string_init("spanCreationObservers", sizeof("spanCreationObservers") - 1, 1); zend_declare_typed_property(class_entry, property_spanCreationObservers_name, &property_spanCreationObservers_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release_ex(property_spanCreationObservers_name, true); + zend_string_release(property_spanCreationObservers_name); + + zval property_attributes_default_value; + ZVAL_EMPTY_ARRAY(&property_attributes_default_value); + zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); + zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); + zend_string_release(property_attributes_name); return class_entry; } @@ -1045,21 +1093,21 @@ static zend_class_entry *register_class_DDTrace_Integration(void) zval const_NOT_LOADED_value; ZVAL_LONG(&const_NOT_LOADED_value, DD_TRACE_INTEGRATION_NOT_LOADED); - zend_string *const_NOT_LOADED_name = zend_string_init_interned("NOT_LOADED", sizeof("NOT_LOADED") - 1, true); + zend_string *const_NOT_LOADED_name = zend_string_init_interned("NOT_LOADED", sizeof("NOT_LOADED") - 1, 1); zend_declare_class_constant_ex(class_entry, const_NOT_LOADED_name, &const_NOT_LOADED_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release_ex(const_NOT_LOADED_name, true); + zend_string_release(const_NOT_LOADED_name); zval const_LOADED_value; ZVAL_LONG(&const_LOADED_value, DD_TRACE_INTEGRATION_LOADED); - zend_string *const_LOADED_name = zend_string_init_interned("LOADED", sizeof("LOADED") - 1, true); + zend_string *const_LOADED_name = zend_string_init_interned("LOADED", sizeof("LOADED") - 1, 1); zend_declare_class_constant_ex(class_entry, const_LOADED_name, &const_LOADED_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release_ex(const_LOADED_name, true); + zend_string_release(const_LOADED_name); zval const_NOT_AVAILABLE_value; ZVAL_LONG(&const_NOT_AVAILABLE_value, DD_TRACE_INTEGRATION_NOT_AVAILABLE); - zend_string *const_NOT_AVAILABLE_name = zend_string_init_interned("NOT_AVAILABLE", sizeof("NOT_AVAILABLE") - 1, true); + zend_string *const_NOT_AVAILABLE_name = zend_string_init_interned("NOT_AVAILABLE", sizeof("NOT_AVAILABLE") - 1, 1); zend_declare_class_constant_ex(class_entry, const_NOT_AVAILABLE_name, &const_NOT_AVAILABLE_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release_ex(const_NOT_AVAILABLE_name, true); + zend_string_release(const_NOT_AVAILABLE_name); return class_entry; } diff --git a/tracer/functions.c b/tracer/functions.c index 4fa26d489ca..d78380cce14 100644 --- a/tracer/functions.c +++ b/tracer/functions.c @@ -105,53 +105,6 @@ static void dd_span_event_construct(ddtrace_span_event *event, zend_string *name /* DDTrace\SpanEvent */ zend_class_entry *ddtrace_ce_span_event; -PHP_METHOD(DDTrace_SpanEvent, jsonSerialize) { - ddtrace_span_event *event = (ddtrace_span_event*)Z_OBJ_P(ZEND_THIS); - - zval array; - array_init(&array); - - Z_TRY_ADDREF(event->property_name); - add_assoc_zval_ex(&array, ZEND_STRL("name"), &event->property_name); - Z_TRY_ADDREF(event->property_timestamp); - add_assoc_zval_ex(&array, ZEND_STRL("time_unix_nano"), &event->property_timestamp); - - // Handle attributes dynamically - zval *attributes = &event->property_attributes; - zval combined_attributes; - array_init(&combined_attributes); - - if (instanceof_function(event->std.ce, ddtrace_ce_exception_span_event)) { - // Handle exception attributes dynamically if an exception property exists - ddtrace_exception_span_event *exception_event = (ddtrace_exception_span_event *) event; - zval *exception = &exception_event->property_exception; - if (Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), zend_ce_throwable)) { - // Get exception message, type, and stack trace directly - zend_string *message = zai_exception_message(Z_OBJ_P(exception)); - if (ZSTR_LEN(message)) { - add_assoc_str_ex(&combined_attributes, ZEND_STRL("exception.message"), zend_string_copy(message)); - } - add_assoc_str_ex(&combined_attributes, ZEND_STRL("exception.type"), zend_string_copy(Z_OBJCE_P(exception)->name)); - - // Get the exception stack trace using zai_get_trace_without_args_from_exception - zend_string *stacktrace = zai_get_trace_without_args_from_exception(Z_OBJ_P(exception)); - add_assoc_str_ex(&combined_attributes, ZEND_STRL("exception.stacktrace"), stacktrace); - } - } - - if (Z_TYPE_P(attributes) == IS_ARRAY) { - zend_hash_copy(Z_ARRVAL(combined_attributes), Z_ARRVAL_P(attributes), (copy_ctor_func_t)zval_add_ref); - } - - if (zend_hash_num_elements(Z_ARRVAL(combined_attributes)) > 0) { - add_assoc_zval_ex(&array, ZEND_STRL("attributes"), &combined_attributes); - } else { - zval_ptr_dtor(&combined_attributes); // Clean up if no elements - } - - RETURN_ARR(Z_ARR(array)); // Return the array -} - PHP_METHOD(DDTrace_SpanEvent, __construct) { UNUSED(return_value); @@ -205,37 +158,6 @@ PHP_METHOD(DDTrace_ExceptionSpanEvent, __construct) /* DDTrace\SpanLink */ zend_class_entry *ddtrace_ce_span_link; -PHP_METHOD(DDTrace_SpanLink, jsonSerialize) { - ddtrace_span_link *link = (ddtrace_span_link *)Z_OBJ_P(ZEND_THIS); - - zend_array *array = zend_new_array(5); - - zend_string *trace_id = zend_string_init("trace_id", sizeof("trace_id") - 1, 0); - zend_string *span_id = zend_string_init("span_id", sizeof("span_id") - 1, 0); - zend_string *trace_state = zend_string_init("trace_state", sizeof("trace_state") - 1, 0); - zend_string *attributes = zend_string_init("attributes", sizeof("attributes") - 1, 0); - zend_string *dropped_attributes_count = zend_string_init("dropped_attributes_count", sizeof("dropped_attributes_count") - 1, 0); - - Z_TRY_ADDREF(link->property_trace_id); - zend_hash_add(array, trace_id, &link->property_trace_id); - Z_TRY_ADDREF(link->property_span_id); - zend_hash_add(array, span_id, &link->property_span_id); - Z_TRY_ADDREF(link->property_trace_state); - zend_hash_add(array, trace_state, &link->property_trace_state); - Z_TRY_ADDREF(link->property_attributes); - zend_hash_add(array, attributes, &link->property_attributes); - Z_TRY_ADDREF(link->property_dropped_attributes_count); - zend_hash_add(array, dropped_attributes_count, &link->property_dropped_attributes_count); - - zend_string_release(trace_id); - zend_string_release(span_id); - zend_string_release(trace_state); - zend_string_release(attributes); - zend_string_release(dropped_attributes_count); - - RETURN_ARR(array); -} - void ddtrace_build_span_link_from_result(ddtrace_distributed_tracing_result *result, ddtrace_span_link *link) { ZVAL_STR(&link->property_trace_id, datadog_trace_id_as_hex_string(result->trace_id)); ZVAL_STR(&link->property_span_id, ddtrace_span_id_as_hex_string(result->parent_id)); @@ -804,6 +726,7 @@ static void dd_register_fatal_error_ce(void) { zend_class_entry *ddtrace_ce_integration; zend_class_entry *ddtrace_ce_git_metadata; +zend_class_entry *ddtrace_ce_span_kind; zend_object_handlers datadog_git_metadata_handlers; static zend_object *datadog_git_metadata_create(zend_class_entry *class_type) { @@ -824,9 +747,10 @@ void ddtrace_register_functions_and_classes(int module_number) { dd_register_fatal_error_ce(); ddtrace_ce_integration = register_class_DDTrace_Integration(); ddtrace_ce_ffe_result = register_class_DDTrace_FfeResult(); - ddtrace_ce_span_link = register_class_DDTrace_SpanLink(php_json_serializable_ce); - ddtrace_ce_span_event = register_class_DDTrace_SpanEvent(php_json_serializable_ce); + ddtrace_ce_span_link = register_class_DDTrace_SpanLink(); + ddtrace_ce_span_event = register_class_DDTrace_SpanEvent(); ddtrace_ce_exception_span_event = register_class_DDTrace_ExceptionSpanEvent(ddtrace_ce_span_event); + ddtrace_ce_span_kind = register_class_DDTrace_SpanKind(); ddtrace_ce_git_metadata = register_class_DDTrace_GitMetadata(); ddtrace_ce_git_metadata->create_object = datadog_git_metadata_create; @@ -1229,47 +1153,6 @@ PHP_FUNCTION(dd_trace_disable_in_request) { RETURN_BOOL(1); } -PHP_FUNCTION(dd_trace_reset) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } - - if (datadog_disable) { - RETURN_BOOL(0); - } - - // TODO ?? - RETURN_BOOL(1); -} - -/* {{{ proto string dd_trace_serialize_msgpack(array trace_array) */ -PHP_FUNCTION(dd_trace_serialize_msgpack) { - zval *trace_array; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &trace_array) == FAILURE) { - RETURN_THROWS(); - } - - if (!get_DD_TRACE_ENABLED()) { - RETURN_BOOL(0); - } - - if (ddtrace_serialize_simple_array(trace_array, return_value) != 1) { - RETURN_BOOL(0); - } -} /* }}} */ - -// method used to be able to easily breakpoint the execution at specific PHP line in GDB -PHP_FUNCTION(dd_trace_noop) { - UNUSED(execute_data); - - if (!get_DD_TRACE_ENABLED()) { - RETURN_BOOL(0); - } - - RETURN_BOOL(1); -} - /* {{{ proto int dd_trace_dd_get_memory_limit() */ PHP_FUNCTION(dd_trace_dd_get_memory_limit) { if (zend_parse_parameters_none() == FAILURE) { @@ -1334,30 +1217,6 @@ PHP_FUNCTION(ddtrace_config_integration_enabled) { RETVAL_BOOL(ddtrace_integrations[integration->name].is_enabled()); } -PHP_FUNCTION(DDTrace_Config_integration_analytics_enabled) { - zend_string *name; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) != SUCCESS) { - RETURN_NULL(); - } - ddtrace_integration *integration = ddtrace_get_integration_from_string(name); - if (integration == NULL) { - RETURN_FALSE; - } - RETVAL_BOOL(integration->is_analytics_enabled()); -} - -PHP_FUNCTION(DDTrace_Config_integration_analytics_sample_rate) { - zend_string *name; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) != SUCCESS) { - RETURN_NULL(); - } - ddtrace_integration *integration = ddtrace_get_integration_from_string(name); - if (integration == NULL) { - RETURN_DOUBLE(DD_INTEGRATION_ANALYTICS_SAMPLE_RATE_DEFAULT); - } - RETVAL_DOUBLE(integration->get_sample_rate()); -} - /* This is only exposed to serialize the container ID into an HTTP Agent header for the userland transport * (`DDTrace\Transport\Http`). The background sender (extension-level transport) is decoupled from userland * code to create any HTTP Agent headers. Once the dependency on the userland transport has been removed, @@ -1922,69 +1781,6 @@ PHP_FUNCTION(DDTrace_ffe_evaluate) { ddtrace_ffe_update_empty_array_property(return_value, ZEND_STRL("providerState")); } -PHP_FUNCTION(dd_trace_send_traces_via_thread) { - char *payload = NULL; - zend_long num_traces = 0; - size_t payload_len = 0; - zval *curl_headers = NULL; - - // Agent HTTP headers are now set at the extension level so 'curl_headers' from userland is ignored - if (zend_parse_parameters(ZEND_NUM_ARGS(), "las", &num_traces, &curl_headers, &payload, - &payload_len) == FAILURE) { - RETURN_THROWS(); - } -#ifndef _WIN32 - bool result = ddtrace_send_traces_via_thread(num_traces, payload, payload_len); - dd_prepare_for_new_trace(); - RETURN_BOOL(result); -#else - RETURN_FALSE; -#endif -} - -PHP_FUNCTION(dd_trace_buffer_span) { - zval *trace_array = NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &trace_array) == FAILURE) { - RETURN_THROWS(); - } - -#ifndef _WIN32 - if (!get_DD_TRACE_ENABLED() || get_global_DD_TRACE_SIDECAR_TRACE_SENDER()) { - RETURN_BOOL(0); - } - - char *data; - size_t size; - if (ddtrace_serialize_simple_array_into_c_string(trace_array, &data, &size)) { - RETVAL_BOOL(ddtrace_coms_buffer_data(DDTRACE_G(traces_group_id), data, size)); - - free(data); - return; - } else { - RETURN_FALSE; - } -#else - RETURN_BOOL(0); -#endif -} - -PHP_FUNCTION(dd_trace_coms_trigger_writer_flush) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } - -#ifndef _WIN32 - if (!get_DD_TRACE_ENABLED() || get_global_DD_TRACE_SIDECAR_TRACE_SENDER()) { - RETURN_LONG(0); - } - - RETURN_LONG(ddtrace_coms_trigger_writer_flush()); -#else - RETURN_BOOL(0); -#endif -} - #define FUNCTION_NAME_MATCHES(function) zend_string_equals_literal(function_val, function) PHP_FUNCTION(dd_trace_internal_fn) { diff --git a/tracer/handlers_httpstreams.c b/tracer/handlers_httpstreams.c index 23617d2eb1f..162eb0bc383 100644 --- a/tracer/handlers_httpstreams.c +++ b/tracer/handlers_httpstreams.c @@ -72,11 +72,11 @@ static php_stream *dd_stream_opener( zend_array *meta = ddtrace_property_array(&span->property_meta); zval zv; - ZVAL_STRING(&zv, "php.stream"); - zend_hash_str_update(meta, ZEND_STRL("component"), &zv); - - ZVAL_STRING(&zv, "client"); - zend_hash_str_update(meta, ZEND_STRL("span.kind"), &zv); + // component / span.kind are carried on the span properties; the serializer translates + // them back into meta["component"] / meta["span.kind"] at serialization time. + zval_ptr_dtor(&span->property_component); + ZVAL_STRING(&span->property_component, "php.stream"); + ZVAL_LONG(&span->property_span_kind, 3 /* DDTrace\SpanKind::CLIENT */); ZVAL_STRING(&zv, filename); zend_hash_str_update(meta, ZEND_STRL("http.url"), &zv); diff --git a/tracer/serializer.c b/tracer/serializer.c index e1fc3e71721..2828d5d0862 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -641,7 +641,9 @@ static void dd_set_entrypoint_root_span_props(struct superglob_equiv *data, ddtr zend_hash_str_add_new(meta, ZEND_STRL("http.method"), &http_method); // Mark HTTP server entry spans with span.kind=server for client-side stats aggregation. - // Only add if not already set (e.g. by an OTel or framework integration). + // Only add if not already set (e.g. by an OTel or framework integration). This span.kind + // is written straight to meta (add-if-absent): unlike the internal producers, the entry + // root must not clobber a value provided by userland, so it does not use the property. zval span_kind_server; ZVAL_STRING(&span_kind_server, "server"); if (!zend_hash_str_add(meta, ZEND_STRL("span.kind"), &span_kind_server)) { @@ -932,6 +934,177 @@ static void dd_serialize_json(zend_array *arr, smart_str *buf, int options) { smart_str_0(buf); } +// Maps the integer DDTrace\SpanKind constant to the string previously stored in meta["span.kind"]. +// Returns NULL for UNSPECIFIED (0) or unknown values, in which case no meta key is emitted. +static const char *dd_span_kind_to_meta_str(zend_long kind) { + switch (kind) { + case 1: return "internal"; // DDTrace\SpanKind::INTERNAL + case 2: return "server"; // DDTrace\SpanKind::SERVER + case 3: return "client"; // DDTrace\SpanKind::CLIENT + case 4: return "producer"; // DDTrace\SpanKind::PRODUCER + case 5: return "consumer"; // DDTrace\SpanKind::CONSUMER + default: return NULL; // DDTrace\SpanKind::UNSPECIFIED (0) or unknown + } +} + +// Translate the $span->component / $span->spanKind properties back into meta["component"] / +// meta["span.kind"] so that the wire meta stays byte-identical to the pre-property behaviour. +// The properties are the source of truth and supersede meta (clobber), matching the original +// producers which used zend_hash_str_update / add_assoc_string. Spans that do not set the +// properties (property empty / spanKind==0 — e.g. userland integrations, which write meta +// directly, and the entrypoint root span) are left untouched, so their meta is preserved. +static void dd_translate_span_kind_component_to_meta(ddtrace_span_data *span, zend_array *meta) { + zval *component = &span->property_component; + ZVAL_DEREF(component); + if (Z_TYPE_P(component) == IS_STRING && Z_STRLEN_P(component) > 0) { + zval zv; + ZVAL_STR_COPY(&zv, Z_STR_P(component)); + zend_hash_str_update(meta, ZEND_STRL("component"), &zv); + } + + zval *span_kind = &span->property_span_kind; + ZVAL_DEREF(span_kind); + if (Z_TYPE_P(span_kind) == IS_LONG) { + const char *kind_str = dd_span_kind_to_meta_str(Z_LVAL_P(span_kind)); + if (kind_str) { + zval zv; + ZVAL_STRING(&zv, kind_str); + zend_hash_str_update(meta, ZEND_STRL("span.kind"), &zv); + } + } +} + +// Serialize an array of DDTrace\SpanEvent objects to the exact JSON shape previously produced by +// DDTrace\SpanEvent::jsonSerialize() (invoked via json_encode over the array of objects). +static zend_array *dd_span_event_to_array(ddtrace_span_event *event) { + zval array; + array_init(&array); + + Z_TRY_ADDREF(event->property_name); + add_assoc_zval_ex(&array, ZEND_STRL("name"), &event->property_name); + Z_TRY_ADDREF(event->property_timestamp); + add_assoc_zval_ex(&array, ZEND_STRL("time_unix_nano"), &event->property_timestamp); + + // Handle attributes dynamically + zval *attributes = &event->property_attributes; + zval combined_attributes; + array_init(&combined_attributes); + + if (instanceof_function(event->std.ce, ddtrace_ce_exception_span_event)) { + // Handle exception attributes dynamically if an exception property exists + ddtrace_exception_span_event *exception_event = (ddtrace_exception_span_event *)event; + zval *exception = &exception_event->property_exception; + if (Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), zend_ce_throwable)) { + // Get exception message, type, and stack trace directly + zend_string *message = zai_exception_message(Z_OBJ_P(exception)); + if (ZSTR_LEN(message)) { + add_assoc_str_ex(&combined_attributes, ZEND_STRL("exception.message"), zend_string_copy(message)); + } + add_assoc_str_ex(&combined_attributes, ZEND_STRL("exception.type"), zend_string_copy(Z_OBJCE_P(exception)->name)); + + // Get the exception stack trace using zai_get_trace_without_args_from_exception + zend_string *stacktrace = zai_get_trace_without_args_from_exception(Z_OBJ_P(exception)); + add_assoc_str_ex(&combined_attributes, ZEND_STRL("exception.stacktrace"), stacktrace); + } + } + + if (Z_TYPE_P(attributes) == IS_ARRAY) { + zend_hash_copy(Z_ARRVAL(combined_attributes), Z_ARRVAL_P(attributes), (copy_ctor_func_t)zval_add_ref); + } + + if (zend_hash_num_elements(Z_ARRVAL(combined_attributes)) > 0) { + add_assoc_zval_ex(&array, ZEND_STRL("attributes"), &combined_attributes); + } else { + zval_ptr_dtor(&combined_attributes); // Clean up if no elements + } + + return Z_ARR(array); +} + +// Serialize a DDTrace\SpanLink object to the exact JSON shape previously produced by +// DDTrace\SpanLink::jsonSerialize() (invoked via json_encode over the array of objects). +static zend_array *dd_span_link_to_array(ddtrace_span_link *link) { + zend_array *array = zend_new_array(5); + + zend_string *trace_id = zend_string_init("trace_id", sizeof("trace_id") - 1, 0); + zend_string *span_id = zend_string_init("span_id", sizeof("span_id") - 1, 0); + zend_string *trace_state = zend_string_init("trace_state", sizeof("trace_state") - 1, 0); + zend_string *attributes = zend_string_init("attributes", sizeof("attributes") - 1, 0); + zend_string *dropped_attributes_count = zend_string_init("dropped_attributes_count", sizeof("dropped_attributes_count") - 1, 0); + + Z_TRY_ADDREF(link->property_trace_id); + zend_hash_add(array, trace_id, &link->property_trace_id); + Z_TRY_ADDREF(link->property_span_id); + zend_hash_add(array, span_id, &link->property_span_id); + Z_TRY_ADDREF(link->property_trace_state); + zend_hash_add(array, trace_state, &link->property_trace_state); + Z_TRY_ADDREF(link->property_attributes); + zend_hash_add(array, attributes, &link->property_attributes); + Z_TRY_ADDREF(link->property_dropped_attributes_count); + zend_hash_add(array, dropped_attributes_count, &link->property_dropped_attributes_count); + + zend_string_release(trace_id); + zend_string_release(span_id); + zend_string_release(trace_state); + zend_string_release(attributes); + zend_string_release(dropped_attributes_count); + + return array; +} + +// Build a JSON array from a list of span links, converting each SpanLink object into the array +// shape that DDTrace\SpanLink::jsonSerialize() used to return, then json-encode it. This preserves +// byte-identical output while removing the reliance on JsonSerializable. +static void dd_serialize_span_links(zend_array *links, smart_str *buf) { + zval tmp; + array_init_size(&tmp, zend_hash_num_elements(links)); + zend_ulong idx; + zend_string *key; + zval *val; + ZEND_HASH_FOREACH_KEY_VAL(links, idx, key, val) { + zval elem; + ZVAL_DEREF(val); + if (Z_TYPE_P(val) == IS_OBJECT && instanceof_function(Z_OBJCE_P(val), ddtrace_ce_span_link)) { + ZVAL_ARR(&elem, dd_span_link_to_array((ddtrace_span_link *)Z_OBJ_P(val))); + } else { + ZVAL_COPY(&elem, val); + } + if (key) { + zend_hash_add(Z_ARRVAL(tmp), key, &elem); + } else { + zend_hash_index_add(Z_ARRVAL(tmp), idx, &elem); + } + } ZEND_HASH_FOREACH_END(); + dd_serialize_json(Z_ARRVAL(tmp), buf, 0); + zval_ptr_dtor(&tmp); +} + +// Build a JSON array from a list of span events, converting each SpanEvent object into the array +// shape that DDTrace\SpanEvent::jsonSerialize() used to return, then json-encode it. +static void dd_serialize_span_events(zend_array *events, smart_str *buf) { + zval tmp; + array_init_size(&tmp, zend_hash_num_elements(events)); + zend_ulong idx; + zend_string *key; + zval *val; + ZEND_HASH_FOREACH_KEY_VAL(events, idx, key, val) { + zval elem; + ZVAL_DEREF(val); + if (Z_TYPE_P(val) == IS_OBJECT && instanceof_function(Z_OBJCE_P(val), ddtrace_ce_span_event)) { + ZVAL_ARR(&elem, dd_span_event_to_array((ddtrace_span_event *)Z_OBJ_P(val))); + } else { + ZVAL_COPY(&elem, val); + } + if (key) { + zend_hash_add(Z_ARRVAL(tmp), key, &elem); + } else { + zend_hash_index_add(Z_ARRVAL(tmp), idx, &elem); + } + } ZEND_HASH_FOREACH_END(); + dd_serialize_json(Z_ARRVAL(tmp), buf, 0); + zval_ptr_dtor(&tmp); +} + static void dd_serialize_array_recursively(ddog_SpanBytes *target, zend_string *str, zval *value, bool convert_to_double) { ZVAL_DEREF(value); @@ -1333,6 +1506,11 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo zend_array *meta = ddtrace_property_array(&span->property_meta); zend_array *metrics = ddtrace_property_array(&span->property_metrics); + // The component / span.kind properties are the source of truth (populated by the C producers). + // Translate them back into the meta blob (add-if-absent) so the wire meta is unchanged and any + // meta-based consumer (e.g. client-side stats via the precomputed span_kind) keeps working. + dd_translate_span_kind_component_to_meta(span, meta); + // Remap OTel's status code (metric, http.status_code) to DD's status code (meta, http.status_code) // OTel HTTP semantic conventions < 1.21.0 zval *http_status_code = zend_hash_str_find(metrics, ZEND_STRL("http.status_code")); @@ -1702,7 +1880,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo zend_object *current_exception = EG(exception); EG(exception) = NULL; smart_str buf = {0}; - dd_serialize_json(span_links, &buf, 0); + dd_serialize_span_links(span_links, &buf); ddog_add_str_span_meta_zstr(rust_span, "_dd.span_links", buf.s); smart_str_free(&buf); EG(exception) = current_exception; @@ -1713,7 +1891,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo zend_object *current_exception = EG(exception); EG(exception) = NULL; smart_str buf = {0}; - dd_serialize_json(span_events, &buf, 0); + dd_serialize_span_events(span_events, &buf); ddog_add_str_span_meta_zstr(rust_span, "events", buf.s); smart_str_free(&buf); EG(exception) = current_exception; diff --git a/tracer/span.c b/tracer/span.c index ff4653eea53..9b025155e66 100644 --- a/tracer/span.c +++ b/tracer/span.c @@ -247,7 +247,10 @@ ddtrace_inferred_span_data *ddtrace_open_inferred_span(ddtrace_inferred_proxy_re ZVAL_LONG(&zv, 1); zend_hash_str_add_new(ddtrace_property_array(&span->property_metrics), ZEND_STRL("_dd.inferred_span"), &zv); - add_assoc_string(&span->property_meta, "component", (char *)proxy_info->component); + // component is carried on the span property; the serializer translates it back into + // meta["component"] at serialization time. + zval_ptr_dtor(&span->property_component); + ZVAL_STRING(&span->property_component, (char *)proxy_info->component); ZVAL_STR(&span->property_type, zend_string_init(ZEND_STRL("web"), 0)); free_inferred_proxy_result(result); diff --git a/tracer/span.h b/tracer/span.h index 2cc2e5460a8..29301497cc1 100644 --- a/tracer/span.h +++ b/tracer/span.h @@ -51,8 +51,6 @@ typedef union ddtrace_span_properties { zval property_name; zval property_resource; zval property_service; - zval property_env; - zval property_version; zval property_meta_struct; zval property_type; zval property_meta; @@ -75,6 +73,11 @@ typedef union ddtrace_span_properties { }; zval property_on_close; zval property_baggage; + zval property_env; + zval property_version; + zval property_component; + zval property_span_kind; + zval property_attributes; }; } ddtrace_span_properties; @@ -148,6 +151,7 @@ struct ddtrace_root_span_data { zval property_origin; zval property_propagated_tags; zval property_sampling_priority; + zval property_sampling_mechanism; zval property_propagated_sampling_priority; zval property_tracestate; zval property_tracestate_tags; @@ -155,6 +159,7 @@ struct ddtrace_root_span_data { zval property_trace_id; zval property_git_metadata; zval property_inferred_span; + zval property_hostname; }; static inline ddtrace_root_span_data *ROOTSPANDATA(zend_object *obj) { @@ -175,6 +180,7 @@ struct ddtrace_span_stack { ddtrace_span_properties *active; }; zval property_span_creation_observers; + zval property_attributes; }; }; struct ddtrace_root_span_data *root_span; diff --git a/tracer/tracer_telemetry.c b/tracer/tracer_telemetry.c index eea6724ef1c..50ce8c2cf5d 100644 --- a/tracer/tracer_telemetry.c +++ b/tracer/tracer_telemetry.c @@ -191,13 +191,21 @@ void ddtrace_telemetry_notify_integration_version(const char *name, size_t name_ } void ddtrace_telemetry_inc_spans_created(ddtrace_span_data *span) { + // The $span->component property is the source of truth (the serializer mirrors it into + // meta["component"] at serialization time, which happens after this close-time hook). Fall + // back to meta["component"] for spans that still set it directly (e.g. userland integrations). + zval *component_prop = &span->property_component; + ZVAL_DEREF(component_prop); zval *component = NULL; - if (Z_TYPE(span->property_meta) == IS_ARRAY) { + if (!(Z_TYPE_P(component_prop) == IS_STRING && Z_STRLEN_P(component_prop) > 0) && + Z_TYPE(span->property_meta) == IS_ARRAY) { component = zend_hash_str_find(Z_ARRVAL(span->property_meta), ZEND_STRL("component")); } zend_string *integration = NULL; - if (component && Z_TYPE_P(component) == IS_STRING) { + if (Z_TYPE_P(component_prop) == IS_STRING && Z_STRLEN_P(component_prop) > 0) { + integration = zend_string_copy(Z_STR_P(component_prop)); + } else if (component && Z_TYPE_P(component) == IS_STRING) { integration = zend_string_copy(Z_STR_P(component)); } else if (span->flags & DDTRACE_SPAN_FLAG_OPENTELEMETRY) { integration = zend_string_init(ZEND_STRL("otel"), 0); From d4ff6547275bd094fd2f32b01f8bf38f6db9cc04 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 20 Jul 2026 17:43:28 +0200 Subject: [PATCH 04/32] fix(config): regenerate supported-configurations.json after dropping DD_TRACE_WARN_LEGACY_DD_TRACE The config key DD_TRACE_WARN_LEGACY_DD_TRACE was removed from tracer/configuration.h, but metadata/supported-configurations.json was not regenerated, causing the 'Configuration Consistency' CI job to fail. Ran tooling/generate-supported-configurations.sh to sync. --- metadata/supported-configurations.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index 20f598cbc02..1f27e844ae2 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -2525,13 +2525,6 @@ "default": "true" } ], - "DD_TRACE_WARN_LEGACY_DD_TRACE": [ - { - "implementation": "A", - "type": "boolean", - "default": "true" - } - ], "DD_TRACE_WEBSOCKET_MESSAGES_ENABLED": [ { "implementation": "A", From 222567d201bd244d0f05500a02924467b6b394e2 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 20 Jul 2026 20:38:58 +0200 Subject: [PATCH 05/32] fix(tracer): drop redundant env/version redeclaration on RootSpanData RootSpanData extends SpanData, which already declares $env and $version. The v1-stub alignment accidentally re-declared them on RootSpanData (they were never on RootSpanData on master, and the ddtrace_root_span_data C struct has no separate env/version slots -- they are inherited SpanData slots). On PHP < 8.1 this redundant child redeclaration corrupts the RootSpanData property table: env/version are var_dump'd twice and propagatedTags loses its default, breaking tests/ext/active_span.phpt and span_clone.phpt on 7.0-8.0 (they passed on 8.1+). Removing the redeclaration from the stub and arginfo aligns stub=arginfo=C struct and restores consistent output across all versions; env/version remain available on RootSpanData via inheritance. --- tracer/ddtrace.stub.php | 12 ------------ tracer/ddtrace_arginfo.h | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/tracer/ddtrace.stub.php b/tracer/ddtrace.stub.php index c0a8f95788f..b7342c60901 100644 --- a/tracer/ddtrace.stub.php +++ b/tracer/ddtrace.stub.php @@ -367,18 +367,6 @@ class RootSpanData extends SpanData { public InferredSpanData|null $inferredSpan = null; - /** - * @var string The environment you are tracing. Defaults to active environment at the time of span creation - * (i.e., the parent span), or datadog.env initialization settings if no parent exists - */ - public string $env = ""; - - /** - * @var string The version of the application you are tracing. Defaults to active version at the time of - * span creation (i.e., the parent span), or datadog.version initialization settings if no parent exists - */ - public string $version = ""; - public string $hostname = ""; } diff --git a/tracer/ddtrace_arginfo.h b/tracer/ddtrace_arginfo.h index a599fbd6549..2f422993431 100644 --- a/tracer/ddtrace_arginfo.h +++ b/tracer/ddtrace_arginfo.h @@ -1027,18 +1027,6 @@ static zend_class_entry *register_class_DDTrace_RootSpanData(zend_class_entry *c zend_declare_typed_property(class_entry, property_inferredSpan_name, &property_inferredSpan_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_inferredSpan_class_DDTrace_InferredSpanData, 0, MAY_BE_NULL)); zend_string_release(property_inferredSpan_name); - zval property_env_default_value; - ZVAL_EMPTY_STRING(&property_env_default_value); - zend_string *property_env_name = zend_string_init("env", sizeof("env") - 1, 1); - zend_declare_typed_property(class_entry, property_env_name, &property_env_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_env_name); - - zval property_version_default_value; - ZVAL_EMPTY_STRING(&property_version_default_value); - zend_string *property_version_name = zend_string_init("version", sizeof("version") - 1, 1); - zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_version_name); - zval property_hostname_default_value; ZVAL_EMPTY_STRING(&property_hostname_default_value); zend_string *property_hostname_name = zend_string_init("hostname", sizeof("hostname") - 1, 1); From ee993e9c938fa2558c472cd17da0552c71ea74d3 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 20 Jul 2026 21:08:00 +0200 Subject: [PATCH 06/32] fix(tracer): initialize SpanData/SpanStack attributes to empty array on PHP 7 The new `attributes` property (stub default `= []`) was not materialized at span/stack creation. On PHP < 8.0 array-typed property defaults become null (see the ZVAL_EMPTY_ARRAY shim in functions.c) and are only lazily turned into arrays when touched; since `attributes` is never touched during a plain span lifecycle it var_dump'd as NULL on 7.0-7.4 (array(0){} on 8.0+), breaking tests/ext/active_span.phpt and span_clone.phpt. Force-materialize it in ddtrace_init_span and dd_alloc_span_stack (guarded to PHP < 8.0) so it is a consistent empty array on every supported version, matching its stub default. --- tracer/span.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tracer/span.c b/tracer/span.c index 9b025155e66..174c554d0d6 100644 --- a/tracer/span.c +++ b/tracer/span.c @@ -166,6 +166,12 @@ static ddtrace_span_data *ddtrace_init_span(enum ddtrace_span_dataype type, zend object_init_ex(&fci_zv, ce); ddtrace_span_data *span = OBJ_SPANDATA(Z_OBJ(fci_zv)); span->type = type; +#if PHP_VERSION_ID < 80000 + // On PHP 7 array-typed properties default to null (see the ZVAL_EMPTY_ARRAY + // shim in functions.c); materialize `attributes` to an empty array so it is + // consistent with its `= []` stub default across all supported versions. + ddtrace_property_array(&span->property_attributes); +#endif return span; } @@ -637,6 +643,10 @@ static ddtrace_span_stack *dd_alloc_span_stack(void) { zval fci_zv; object_init_ex(&fci_zv, ddtrace_ce_span_stack); ddtrace_span_stack *span_stack = (ddtrace_span_stack *)Z_OBJ(fci_zv); +#if PHP_VERSION_ID < 80000 + // See ddtrace_init_span: materialize `attributes` to an empty array on PHP 7. + ddtrace_property_array(&span_stack->property_attributes); +#endif return span_stack; } From 45fad2e9b0db5d36171d48d89104f5c3d2e8c6ca Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 20 Jul 2026 21:22:01 +0200 Subject: [PATCH 07/32] test: align tests with per-integration analytics removal The chore that dropped integration (App Analytics) auto-tagging removed Integration::addTraceAnalyticsIfEnabled and the per-integration DD_TRACE__ANALYTICS_* config, so the _dd1.sr.eausr metric is no longer auto-added to integration spans. Align the tests: - Delete the 25 TraceSearchConfigTest.php files (Laravel, Lumen, Symfony, ZendFramework, Custom) whose sole subject was the removed per-integration trace-analytics config. - Drop the per-integration analytics setup + _dd1.sr.eausr metric assertions from the mixed PDO and SQLSRV integration tests, preserving all other span coverage. - Remove Curl's dedicated testTraceAnalytics method + its data provider (per-integration analytics config matrix) and the stale DD_CURL_ANALYTICS_ENABLED teardown-cleanup entries in Curl/Guzzle. The user-facing App Analytics API (Span::setMetric(Tag::ANALYTICS_KEY) -> TraceAnalyticsProcessor, Tag::ANALYTICS_KEY constant) is intentionally kept by this branch, so its tests (SpanTest, TraceAnalyticsProcessorTest, UserAvailableConstantsTest, OpenTelemetry, ext/test_special_attributes) are left intact. --- .../Integrations/Curl/CurlIntegrationTest.php | 104 ------------------ .../Autoloaded/TraceSearchConfigTest.php | 54 --------- .../Guzzle/V5/GuzzleIntegrationTest.php | 1 - .../Laravel/V4/TraceSearchConfigTest.php | 88 --------------- .../Laravel/V5_7/TraceSearchConfigTest.php | 85 -------------- .../Laravel/V5_8/TraceSearchConfigTest.php | 85 -------------- .../Laravel/V8_x/TraceSearchConfigTest.php | 84 -------------- .../Lumen/V10_0/TraceSearchConfigTest.php | 73 ------------ .../Lumen/V5_2/TraceSearchConfigTest.php | 73 ------------ .../Lumen/V5_6/TraceSearchConfigTest.php | 73 ------------ .../Lumen/V5_8/TraceSearchConfigTest.php | 73 ------------ .../Lumen/V8_1/TraceSearchConfigTest.php | 73 ------------ .../Lumen/V9_0/TraceSearchConfigTest.php | 73 ------------ tests/Integrations/PDO/PDOTest.php | 13 +-- tests/Integrations/SQLSRV/SQLSRVTest.php | 13 --- .../Symfony/Latest/TraceSearchConfigTest.php | 11 -- .../Symfony/V3_0/TraceSearchConfigTest.php | 73 ------------ .../Symfony/V3_3/TraceSearchConfigTest.php | 82 -------------- .../Symfony/V3_4/TraceSearchConfigTest.php | 84 -------------- .../Symfony/V4_0/TraceSearchConfigTest.php | 83 -------------- .../Symfony/V4_2/TraceSearchConfigTest.php | 84 -------------- .../Symfony/V4_4/TraceSearchConfigTest.php | 83 -------------- .../Symfony/V5_0/TraceSearchConfigTest.php | 83 -------------- .../Symfony/V5_1/TraceSearchConfigTest.php | 83 -------------- .../Symfony/V5_2/TraceSearchConfigTest.php | 81 -------------- .../Symfony/V6_2/TraceSearchConfigTest.php | 81 -------------- .../Symfony/V7_3/TraceSearchConfigTest.php | 11 -- .../V1/TraceSearchConfigTest.php | 57 ---------- .../V1_21/TraceSearchConfigTest.php | 57 ---------- 29 files changed, 1 insertion(+), 1917 deletions(-) delete mode 100644 tests/Integrations/Custom/Autoloaded/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Laravel/V4/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Laravel/V5_7/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Laravel/V5_8/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Laravel/V8_x/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Lumen/V10_0/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Lumen/V5_2/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Lumen/V5_6/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Lumen/V5_8/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Lumen/V8_1/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Lumen/V9_0/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/Latest/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/V3_0/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/V3_3/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/V3_4/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/V4_0/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/V4_2/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/V4_4/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/V5_0/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/V5_1/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/V5_2/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/V6_2/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/Symfony/V7_3/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/ZendFramework/V1/TraceSearchConfigTest.php delete mode 100644 tests/Integrations/ZendFramework/V1_21/TraceSearchConfigTest.php diff --git a/tests/Integrations/Curl/CurlIntegrationTest.php b/tests/Integrations/Curl/CurlIntegrationTest.php index e01c76154ae..a62f70bde0b 100644 --- a/tests/Integrations/Curl/CurlIntegrationTest.php +++ b/tests/Integrations/Curl/CurlIntegrationTest.php @@ -41,7 +41,6 @@ protected function envsToCleanUpAtTearDown() { return [ 'DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED', - 'DD_CURL_ANALYTICS_ENABLED', 'DD_DISTRIBUTED_TRACING', 'DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN', 'DD_TRACE_MEMORY_LIMIT', @@ -613,109 +612,6 @@ public function dataProviderWithAndWithoutRootSpan() { ]; } - /** - * @dataProvider dataProviderTestTraceAnalytics - */ - public function testTraceAnalytics($envsOverride, $expectedSampleRate) - { - $env = array_merge(['DD_SERVICE' => 'top_level_app', 'DD_TRACE_GENERATE_ROOT_SPAN' => 'true'], $envsOverride); - - $traces = $this->inWebServer( - function ($execute) { - $execute(GetSpec::create('GET', '/curl_in_web_request.php')); - }, - __DIR__ . '/curl_in_web_request.php', - $env - ); - - $metrics = []; - if (null !== $expectedSampleRate) { - $metrics = array_merge($metrics, [ '_dd1.sr.eausr' => $expectedSampleRate ]); - } - - $this->assertFlameGraph($traces, [ - SpanAssertion::build('web.request', 'top_level_app', 'web', 'GET /curl_in_web_request.php') - ->withExistingTagsNames(['http.method', 'http.url', 'http.status_code', 'span.kind']) - ->withExactMetrics(['_sampling_priority_v1' => 1, '_dd.agent_psr' => 1, 'process_id' => getmypid()]) - ->withChildren([ - SpanAssertion::build('curl_exec', 'curl', 'http', 'http://' . HTTPBIN_INTEGRATION . '/status/?') - ->withExactTags([ - 'http.url' => self::URL . '/status/200', - 'http.status_code' => '200', - 'span.kind' => 'client', - 'network.destination.name' => HTTPBIN_SERVICE_HOST, - Tag::COMPONENT => 'curl', - '_dd.svc_src' => 'curl', - '_dd.base_service' => 'top_level_app', - ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), - ]), - ]); - } - - public function dataProviderTestTraceAnalytics() - { - return [ - 'not set' => [ - [], - null, - ], - 'off no rate' => [ - [ - 'DD_TRACE_CURL_ANALYTICS_ENABLED' => false, - ], - null, - ], - 'off legacy name no rate' => [ - [ - 'DD_CURL_ANALYTICS_ENABLED' => false, - ], - null, - ], - 'off with rate' => [ - [ - 'DD_TRACE_CURL_ANALYTICS_ENABLED' => false, - 'DD_TRACE_CURL_ANALYTICS_SAMPLE_RATE' => 0.7, - ], - null, - ], - 'off legacy name with rate' => [ - [ - 'DD_CURL_ANALYTICS_ENABLED' => false, - 'DD_CURL_ANALYTICS_SAMPLE_RATE' => 0.7, - ], - null, - ], - 'enabled default rate' => [ - [ - 'DD_TRACE_CURL_ANALYTICS_ENABLED' => true, - ], - 1.0, - ], - 'enabled legacy name default rate' => [ - [ - 'DD_CURL_ANALYTICS_ENABLED' => true, - ], - 1.0, - ], - 'enabled specific rate' => [ - [ - 'DD_TRACE_CURL_ANALYTICS_ENABLED' => true, - 'DD_TRACE_CURL_ANALYTICS_SAMPLE_RATE' => 0.7, - ], - 0.7, - ], - 'enabled legacy name specific rate' => [ - [ - 'DD_CURL_ANALYTICS_ENABLED' => true, - 'DD_CURL_ANALYTICS_SAMPLE_RATE' => 0.7, - ], - 0.7, - ], - ]; - } - public function testPeerServiceEnabled() { $this->putEnvAndReloadConfig(['DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED=true']); diff --git a/tests/Integrations/Custom/Autoloaded/TraceSearchConfigTest.php b/tests/Integrations/Custom/Autoloaded/TraceSearchConfigTest.php deleted file mode 100644 index 717b6ddbc26..00000000000 --- a/tests/Integrations/Custom/Autoloaded/TraceSearchConfigTest.php +++ /dev/null @@ -1,54 +0,0 @@ - 'true', - 'DD_WEB_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertExpectedSpans( - $traces, - [ - SpanAssertion::build( - 'web.request', - 'web.request', - 'web', - 'GET /simple' - )->withExactTags([ - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - 'span.kind' => 'server', - ])->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Guzzle/V5/GuzzleIntegrationTest.php b/tests/Integrations/Guzzle/V5/GuzzleIntegrationTest.php index 8504ee23c4a..91cc5ce7bcd 100644 --- a/tests/Integrations/Guzzle/V5/GuzzleIntegrationTest.php +++ b/tests/Integrations/Guzzle/V5/GuzzleIntegrationTest.php @@ -46,7 +46,6 @@ protected function envsToCleanUpAtTearDown() { return [ 'DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED', - 'DD_CURL_ANALYTICS_ENABLED', 'DD_DISTRIBUTED_TRACING', 'DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN', 'DD_TRACE_MEMORY_LIMIT', diff --git a/tests/Integrations/Laravel/V4/TraceSearchConfigTest.php b/tests/Integrations/Laravel/V4/TraceSearchConfigTest.php deleted file mode 100644 index 3109b07ddeb..00000000000 --- a/tests/Integrations/Laravel/V4/TraceSearchConfigTest.php +++ /dev/null @@ -1,88 +0,0 @@ - 'true', - 'DD_LARAVEL_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build('laravel.request', 'laravel', 'web', 'HomeController@simple simple_route') - ->withExactTags([ - 'laravel.route.name' => 'simple_route', - 'laravel.route.action' => 'HomeController@simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - 'http.route' => 'simple', - TAG::SPAN_KIND => 'server', - Tag::COMPONENT => 'laravel', - '_dd.svc_src' => 'laravel', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) - ->withChildren([ - SpanAssertion::exists('laravel.application.handle') - ->withChildren([ - SpanAssertion::build('laravel.action', 'laravel', 'web', 'simple') - ->withExactTags([ - Tag::COMPONENT => 'laravel', - '_dd.svc_src' => 'laravel', - ]), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - ]), - SpanAssertion::exists( - 'laravel.provider.load', - 'Illuminate\Foundation\ProviderRepository::load' - )->withChildren([ - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - ]), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Laravel/V5_7/TraceSearchConfigTest.php b/tests/Integrations/Laravel/V5_7/TraceSearchConfigTest.php deleted file mode 100644 index 402c38eab84..00000000000 --- a/tests/Integrations/Laravel/V5_7/TraceSearchConfigTest.php +++ /dev/null @@ -1,85 +0,0 @@ - 'true', - 'DD_LARAVEL_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'laravel.request', - 'Laravel', - 'web', - 'App\Http\Controllers\CommonSpecsController@simple simple_route' - ) - ->withExactTags([ - 'laravel.route.name' => 'simple_route', - 'laravel.route.action' => 'App\Http\Controllers\CommonSpecsController@simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - 'http.route' => 'simple', - TAG::SPAN_KIND => 'server', - TAG::COMPONENT => 'laravel', - '_dd.svc_src' => 'laravel', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) - ->withChildren([ - SpanAssertion::exists('laravel.action'), - SpanAssertion::exists( - 'laravel.provider.load', - 'Illuminate\Foundation\ProviderRepository::load' - ), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Laravel/V5_8/TraceSearchConfigTest.php b/tests/Integrations/Laravel/V5_8/TraceSearchConfigTest.php deleted file mode 100644 index 3d8fd4681ef..00000000000 --- a/tests/Integrations/Laravel/V5_8/TraceSearchConfigTest.php +++ /dev/null @@ -1,85 +0,0 @@ - 'true', - 'DD_LARAVEL_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'laravel.request', - 'Laravel', - 'web', - 'App\Http\Controllers\CommonSpecsController@simple simple_route' - ) - ->withExactTags([ - 'laravel.route.name' => 'simple_route', - 'laravel.route.action' => 'App\Http\Controllers\CommonSpecsController@simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - 'http.route' => 'simple', - TAG::SPAN_KIND => 'server', - Tag::COMPONENT => 'laravel', - '_dd.svc_src' => 'laravel', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) - ->withChildren([ - SpanAssertion::exists('laravel.action'), - SpanAssertion::exists( - 'laravel.provider.load', - 'Illuminate\Foundation\ProviderRepository::load' - ), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Laravel/V8_x/TraceSearchConfigTest.php b/tests/Integrations/Laravel/V8_x/TraceSearchConfigTest.php deleted file mode 100644 index 0d76259fbcf..00000000000 --- a/tests/Integrations/Laravel/V8_x/TraceSearchConfigTest.php +++ /dev/null @@ -1,84 +0,0 @@ - 'true', - 'DD_LARAVEL_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'laravel.request', - 'Laravel', - 'web', - 'App\Http\Controllers\CommonSpecsController@simple simple_route' - ) - ->withExactTags([ - 'laravel.route.name' => 'simple_route', - 'laravel.route.action' => 'App\Http\Controllers\CommonSpecsController@simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - 'http.route' => 'simple', - TAG::SPAN_KIND => 'server', - TAG::COMPONENT => 'laravel', - '_dd.svc_src' => 'laravel', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - ]) - ->withChildren([ - SpanAssertion::exists('laravel.action'), - SpanAssertion::exists( - 'laravel.provider.load', - 'Illuminate\Foundation\ProviderRepository::load' - ), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - SpanAssertion::exists('laravel.event.handle'), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Lumen/V10_0/TraceSearchConfigTest.php b/tests/Integrations/Lumen/V10_0/TraceSearchConfigTest.php deleted file mode 100644 index bee744eaa16..00000000000 --- a/tests/Integrations/Lumen/V10_0/TraceSearchConfigTest.php +++ /dev/null @@ -1,73 +0,0 @@ - 'true', - 'DD_LUMEN_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'lumen.request', - 'lumen', - 'web', - 'GET /simple' - ) - ->withExactTags([ - 'lumen.route.name' => 'simple_route', - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) - ->withChildren([ - SpanAssertion::build( - 'Laravel\Lumen\Application.handleFoundRoute', - 'lumen', - 'web', - 'simple_route' - )->withExactTags([ - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - Tag::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Lumen/V5_2/TraceSearchConfigTest.php b/tests/Integrations/Lumen/V5_2/TraceSearchConfigTest.php deleted file mode 100644 index 962f268fbbb..00000000000 --- a/tests/Integrations/Lumen/V5_2/TraceSearchConfigTest.php +++ /dev/null @@ -1,73 +0,0 @@ - 'true', - 'DD_LUMEN_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'lumen.request', - 'lumen', - 'web', - 'GET /simple' - ) - ->withExactTags([ - 'lumen.route.name' => 'simple_route', - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - TAG::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) - ->withChildren([ - SpanAssertion::build( - 'Laravel\Lumen\Application.handleFoundRoute', - 'lumen', - 'web', - 'simple_route' - )->withExactTags([ - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - TAG::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]), - ]) - ] - ); - } -} diff --git a/tests/Integrations/Lumen/V5_6/TraceSearchConfigTest.php b/tests/Integrations/Lumen/V5_6/TraceSearchConfigTest.php deleted file mode 100644 index 8ed82832ffd..00000000000 --- a/tests/Integrations/Lumen/V5_6/TraceSearchConfigTest.php +++ /dev/null @@ -1,73 +0,0 @@ - 'true', - 'DD_LUMEN_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'lumen.request', - 'lumen', - 'web', - 'GET /simple' - ) - ->withExactTags([ - 'lumen.route.name' => 'simple_route', - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) - ->withChildren([ - SpanAssertion::build( - 'Laravel\Lumen\Application.handleFoundRoute', - 'lumen', - 'web', - 'simple_route' - )->withExactTags([ - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - Tag::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Lumen/V5_8/TraceSearchConfigTest.php b/tests/Integrations/Lumen/V5_8/TraceSearchConfigTest.php deleted file mode 100644 index dcefdc8bad3..00000000000 --- a/tests/Integrations/Lumen/V5_8/TraceSearchConfigTest.php +++ /dev/null @@ -1,73 +0,0 @@ - 'true', - 'DD_LUMEN_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'lumen.request', - 'lumen', - 'web', - 'GET /simple' - ) - ->withExactTags([ - 'lumen.route.name' => 'simple_route', - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) - ->withChildren([ - SpanAssertion::build( - 'Laravel\Lumen\Application.handleFoundRoute', - 'lumen', - 'web', - 'simple_route' - )->withExactTags([ - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - Tag::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Lumen/V8_1/TraceSearchConfigTest.php b/tests/Integrations/Lumen/V8_1/TraceSearchConfigTest.php deleted file mode 100644 index 5f2f141ed21..00000000000 --- a/tests/Integrations/Lumen/V8_1/TraceSearchConfigTest.php +++ /dev/null @@ -1,73 +0,0 @@ - 'true', - 'DD_LUMEN_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'lumen.request', - 'lumen', - 'web', - 'GET /simple' - ) - ->withExactTags([ - 'lumen.route.name' => 'simple_route', - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) - ->withChildren([ - SpanAssertion::build( - 'Laravel\Lumen\Application.handleFoundRoute', - 'lumen', - 'web', - 'simple_route' - )->withExactTags([ - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - Tag::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Lumen/V9_0/TraceSearchConfigTest.php b/tests/Integrations/Lumen/V9_0/TraceSearchConfigTest.php deleted file mode 100644 index 87675daa158..00000000000 --- a/tests/Integrations/Lumen/V9_0/TraceSearchConfigTest.php +++ /dev/null @@ -1,73 +0,0 @@ - 'true', - 'DD_LUMEN_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'lumen.request', - 'lumen', - 'web', - 'GET /simple' - ) - ->withExactTags([ - 'lumen.route.name' => 'simple_route', - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) - ->withChildren([ - SpanAssertion::build( - 'Laravel\Lumen\Application.handleFoundRoute', - 'lumen', - 'web', - 'simple_route' - )->withExactTags([ - 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', - Tag::COMPONENT => 'lumen', - '_dd.svc_src' => 'lumen', - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/PDO/PDOTest.php b/tests/Integrations/PDO/PDOTest.php index b2abb86e49d..1e0aa28dbdf 100644 --- a/tests/Integrations/PDO/PDOTest.php +++ b/tests/Integrations/PDO/PDOTest.php @@ -26,14 +26,12 @@ final class PDOTest extends IntegrationTestCase public static function ddSetUpBeforeClass() { - self::putenv('DD_PDO_ANALYTICS_ENABLED=true'); parent::ddSetUpBeforeClass(); } public static function ddTearDownAfterClass() { parent::ddTearDownAfterClass(); - self::putenv('DD_PDO_ANALYTICS_ENABLED'); } protected function ddSetUp() @@ -93,7 +91,6 @@ public function testCustomPDOPrepareWithStringableStatement() ->withExactTags($this->baseTags()) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]), @@ -238,7 +235,6 @@ public function testPDOExecOk() ->withExactTags($this->baseTags()) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]), @@ -305,7 +301,6 @@ public function testPDOQuery() ->withExactTags($this->baseTags()) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]), @@ -328,7 +323,6 @@ public function testPDOQueryPeerServiceEnabled() ->withExactTags($this->baseTags(true)) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]), @@ -445,7 +439,6 @@ public function testPDOStatementOk() ->withExactTags($this->baseTags()) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]), @@ -484,7 +477,6 @@ public function testPDOStatementOkPeerServiceEnabled() ->withExactTags($this->baseTags(true)) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]), @@ -522,7 +514,6 @@ public function testPDOStatementSplitByDomain() ->withExactTags($this->baseTags(false, 'opt.db_client_split_by_instance')) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]), @@ -561,7 +552,6 @@ public function testPDOStatementSplitByDomainAndServiceFlattening() ->withExactTags($this->baseTags(false, 'opt.db_client_split_by_instance')) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]), @@ -779,7 +769,6 @@ public function testDirectQueryHasNoParentIssues() ->withExactTags($this->baseTags()) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]), @@ -823,7 +812,7 @@ public function testNoFakeServices() SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.exec', 'configured_service', 'sql', $query) ->withExactTags($this->baseTags(false, null)) - ->withExactMetrics([Tag::DB_ROW_COUNT => 1.0, Tag::ANALYTICS_KEY => 1.0]), + ->withExactMetrics([Tag::DB_ROW_COUNT => 1.0]), SpanAssertion::exists('PDO.commit'), ], false); } diff --git a/tests/Integrations/SQLSRV/SQLSRVTest.php b/tests/Integrations/SQLSRV/SQLSRVTest.php index 70b85ff515d..f2965a0aace 100644 --- a/tests/Integrations/SQLSRV/SQLSRVTest.php +++ b/tests/Integrations/SQLSRV/SQLSRVTest.php @@ -33,7 +33,6 @@ private static function getArchitecture() public static function ddSetUpBeforeClass() { parent::ddSetUpBeforeClass(); - self::putenv('DD_SQLSRV_ANALYTICS_ENABLED=true'); self::waitForSqlServerReady(); } @@ -76,7 +75,6 @@ private static function waitForSqlServerReady() public static function ddTearDownAfterClass() { parent::ddTearDownAfterClass(); - self::putenv('DD_SQLSRV_ANALYTICS_ENABLED'); } protected function ddSetUp() @@ -147,7 +145,6 @@ public function testQueryOk() ->withExactTags(self::baseTags($query)) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]) @@ -171,7 +168,6 @@ public function testQueryOkPeerServiceEnabled() ->withExactTags(self::baseTags($query, true)) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]) @@ -196,7 +192,6 @@ public function testQueryError() 'SQLSRV error', self::getArchitecture() === 'x86_64' ? SQLSRVTest::ERROR_QUERY_17 : SQLSRVTest::ERROR_QUERY_18 )->withExactMetrics([ - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]) @@ -223,7 +218,6 @@ public function testQueryErrorPeerServiceEnabled() 'SQLSRV error', self::getArchitecture() === 'x86_64' ? SQLSRVTest::ERROR_QUERY_17 : SQLSRVTest::ERROR_QUERY_18 )->withExactMetrics([ - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]) @@ -248,7 +242,6 @@ public function testCommitOk() ->withExactTags(self::baseTags($query)) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]), @@ -275,7 +268,6 @@ public function testPrepareOk() ->withExactTags(self::baseTags($query)) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]) @@ -302,7 +294,6 @@ public function testPrepareOkPeerServiceEnabled() ->withExactTags(self::baseTags($query, true)) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]) @@ -328,7 +319,6 @@ public function testPrepareError() self::getArchitecture() === 'x86_64' ? SQLSRVTest::ERROR_QUERY_17 : SQLSRVTest::ERROR_QUERY_18 )->withExactTags(self::baseTags($query)) ->withExactMetrics([ - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]) @@ -356,7 +346,6 @@ public function testPrepareErrorPeerServiceEnabled() self::getArchitecture() === 'x86_64' ? SQLSRVTest::ERROR_QUERY_17 : SQLSRVTest::ERROR_QUERY_18 )->withExactTags(self::baseTags($query, true)) ->withExactMetrics([ - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]) @@ -503,7 +492,6 @@ public function testConnectPrepareStatement() ->withExactTags(self::baseTags($query)) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]) @@ -530,7 +518,6 @@ public function testNoFakeServices() ->withExactTags(self::baseTags($query, false, null)) ->withExactMetrics([ Tag::DB_ROW_COUNT => 1.0, - Tag::ANALYTICS_KEY => 1.0, '_dd.agent_psr' => 1.0, '_sampling_priority_v1' => 1.0, ]) diff --git a/tests/Integrations/Symfony/Latest/TraceSearchConfigTest.php b/tests/Integrations/Symfony/Latest/TraceSearchConfigTest.php deleted file mode 100644 index 9d36b4f5778..00000000000 --- a/tests/Integrations/Symfony/Latest/TraceSearchConfigTest.php +++ /dev/null @@ -1,11 +0,0 @@ - 'true', - 'DD_SYMFONY_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'symfony.request', - 'symfony', - 'web', - 'simple' - )->withExactTags([ - 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@simpleAction', - 'symfony.route.name' => 'simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ])->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ])->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.boot'), - SpanAssertion::exists('symfony.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.kernel.request')->withChildren([ - SpanAssertion::exists('symfony.security.authentication.success'), - ]), - SpanAssertion::exists('symfony.kernel.controller'), - SpanAssertion::exists('symfony.kernel.controller'), - SpanAssertion::exists('symfony.kernel.response'), - SpanAssertion::exists('symfony.kernel.finish_request'), - ]), - ]), - SpanAssertion::exists('symfony.kernel.terminate'), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Symfony/V3_3/TraceSearchConfigTest.php b/tests/Integrations/Symfony/V3_3/TraceSearchConfigTest.php deleted file mode 100644 index 5483d95fb44..00000000000 --- a/tests/Integrations/Symfony/V3_3/TraceSearchConfigTest.php +++ /dev/null @@ -1,82 +0,0 @@ - 'true', - 'DD_SYMFONY_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'symfony.request', - 'symfony', - 'web', - 'simple' - )->withExactTags([ - 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@simpleAction', - 'symfony.route.name' => 'simple', - - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ])->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ])->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.boot'), - SpanAssertion::exists('symfony.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.kernel.request')->withChildren([ - SpanAssertion::exists('symfony.security.authentication.success'), - ]), - SpanAssertion::exists('symfony.kernel.controller'), - SpanAssertion::exists('symfony.kernel.controller_arguments'),SpanAssertion::build( - 'symfony.controller', - 'symfony', - 'web', - 'AppBundle\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ]), - SpanAssertion::exists('symfony.kernel.response'), - SpanAssertion::exists('symfony.kernel.finish_request'), - ]), - ]), - SpanAssertion::exists('symfony.kernel.terminate'), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Symfony/V3_4/TraceSearchConfigTest.php b/tests/Integrations/Symfony/V3_4/TraceSearchConfigTest.php deleted file mode 100644 index e8691e90edc..00000000000 --- a/tests/Integrations/Symfony/V3_4/TraceSearchConfigTest.php +++ /dev/null @@ -1,84 +0,0 @@ - 'true', - 'DD_SYMFONY_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'symfony.request', - 'symfony', - 'web', - 'simple' - )->withExactTags([ - 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@simpleAction', - 'symfony.route.name' => 'simple', - - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ])->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ])->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.boot'), - SpanAssertion::exists('symfony.kernel.handle') - ->withChildren([ - SpanAssertion::exists('symfony.kernel.request')->withChildren([ - SpanAssertion::exists('symfony.security.authentication.success'), - ]), - SpanAssertion::exists('symfony.kernel.controller'), - SpanAssertion::exists('symfony.kernel.controller_arguments'), - SpanAssertion::build( - 'symfony.controller', - 'symfony', - 'web', - 'AppBundle\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ]), - SpanAssertion::exists('symfony.kernel.response'), - SpanAssertion::exists('symfony.kernel.finish_request'), - ]), - ]), - SpanAssertion::exists('symfony.kernel.terminate'), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Symfony/V4_0/TraceSearchConfigTest.php b/tests/Integrations/Symfony/V4_0/TraceSearchConfigTest.php deleted file mode 100644 index c92a93e9242..00000000000 --- a/tests/Integrations/Symfony/V4_0/TraceSearchConfigTest.php +++ /dev/null @@ -1,83 +0,0 @@ - 'true', - 'DD_SYMFONY_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'symfony.request', - 'symfony', - 'web', - 'simple' - )->withExactTags([ - 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', - 'symfony.route.name' => 'simple', - - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ])->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ])->withChildren([ - SpanAssertion::exists('symfony.kernel.terminate'), - SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.boot'), - SpanAssertion::exists('symfony.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.kernel.request')->withChildren([ - SpanAssertion::exists('symfony.security.authentication.success'), - ]), - SpanAssertion::exists('symfony.kernel.controller'), - SpanAssertion::exists('symfony.kernel.controller_arguments'), - SpanAssertion::build( - 'symfony.controller', - 'symfony', - 'web', - 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ]), - SpanAssertion::exists('symfony.kernel.response'), - SpanAssertion::exists('symfony.kernel.finish_request'), - ]), - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Symfony/V4_2/TraceSearchConfigTest.php b/tests/Integrations/Symfony/V4_2/TraceSearchConfigTest.php deleted file mode 100644 index 3e24e5bd015..00000000000 --- a/tests/Integrations/Symfony/V4_2/TraceSearchConfigTest.php +++ /dev/null @@ -1,84 +0,0 @@ - 'true', - 'DD_SYMFONY_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'symfony.request', - 'symfony', - 'web', - 'simple' - )->withExactTags([ - 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', - 'symfony.route.name' => 'simple', - - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ])->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) ->withChildren([ - SpanAssertion::exists('symfony.kernel.terminate'), - SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.boot'), - SpanAssertion::exists('symfony.kernel.handle') - ->withChildren([ - SpanAssertion::exists('symfony.kernel.request')->withChildren([ - SpanAssertion::exists('symfony.security.authentication.success'), - ]), - SpanAssertion::exists('symfony.kernel.controller'), - SpanAssertion::exists('symfony.kernel.controller_arguments'), - SpanAssertion::build( - 'symfony.controller', - 'symfony', - 'web', - 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ]), - SpanAssertion::exists('symfony.kernel.response'), - SpanAssertion::exists('symfony.kernel.finish_request'), - ]), - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Symfony/V4_4/TraceSearchConfigTest.php b/tests/Integrations/Symfony/V4_4/TraceSearchConfigTest.php deleted file mode 100644 index ccf749e2c2b..00000000000 --- a/tests/Integrations/Symfony/V4_4/TraceSearchConfigTest.php +++ /dev/null @@ -1,83 +0,0 @@ - 'true', - 'DD_SYMFONY_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'symfony.request', - 'symfony', - 'web', - 'simple' - )->withExactTags([ - 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', - 'symfony.route.name' => 'simple', - 'http.route' => '/simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ])->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ])->withChildren([ - SpanAssertion::exists('symfony.kernel.terminate'), - SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.boot'), - SpanAssertion::exists('symfony.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.kernel.request'), - SpanAssertion::exists('symfony.kernel.controller'), - SpanAssertion::exists('symfony.kernel.controller_arguments'), - SpanAssertion::build( - 'symfony.controller', - 'symfony', - 'web', - 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ]), - SpanAssertion::exists('symfony.kernel.response')->withChildren([ - SpanAssertion::exists('symfony.security.authentication.success') - ]), - SpanAssertion::exists('symfony.kernel.finish_request'), - ]), - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Symfony/V5_0/TraceSearchConfigTest.php b/tests/Integrations/Symfony/V5_0/TraceSearchConfigTest.php deleted file mode 100644 index 7c9cbfee07a..00000000000 --- a/tests/Integrations/Symfony/V5_0/TraceSearchConfigTest.php +++ /dev/null @@ -1,83 +0,0 @@ - 'true', - 'DD_SYMFONY_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'symfony.request', - 'symfony', - 'web', - 'simple' - )->withExactTags([ - 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', - 'symfony.route.name' => 'simple', - 'http.route' => '/simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ])->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ])->withChildren([ - SpanAssertion::exists('symfony.kernel.terminate'), - SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.boot'), - SpanAssertion::exists('symfony.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.kernel.request'), - SpanAssertion::exists('symfony.kernel.controller'), - SpanAssertion::exists('symfony.kernel.controller_arguments'), - SpanAssertion::build( - 'symfony.controller', - 'symfony', - 'web', - 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ]), - SpanAssertion::exists('symfony.kernel.response')->withChildren([ - SpanAssertion::exists('symfony.security.authentication.success') - ]), - SpanAssertion::exists('symfony.kernel.finish_request'), - ]), - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Symfony/V5_1/TraceSearchConfigTest.php b/tests/Integrations/Symfony/V5_1/TraceSearchConfigTest.php deleted file mode 100644 index 5044eafd656..00000000000 --- a/tests/Integrations/Symfony/V5_1/TraceSearchConfigTest.php +++ /dev/null @@ -1,83 +0,0 @@ - 'true', - 'DD_SYMFONY_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'symfony.request', - 'symfony', - 'web', - 'simple' - )->withExactTags([ - 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', - 'symfony.route.name' => 'simple', - 'http.route' => '/simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ])->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ])->withChildren([ - SpanAssertion::exists('symfony.kernel.terminate'), - SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.boot'), - SpanAssertion::exists('symfony.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.kernel.request'), - SpanAssertion::exists('symfony.kernel.controller'), - SpanAssertion::exists('symfony.kernel.controller_arguments'), - SpanAssertion::build( - 'symfony.controller', - 'symfony', - 'web', - 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ]), - SpanAssertion::exists('symfony.kernel.response')->withChildren([ - SpanAssertion::exists('symfony.security.authentication.success') - ]), - SpanAssertion::exists('symfony.kernel.finish_request'), - ]), - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Symfony/V5_2/TraceSearchConfigTest.php b/tests/Integrations/Symfony/V5_2/TraceSearchConfigTest.php deleted file mode 100644 index 1a622ae42b4..00000000000 --- a/tests/Integrations/Symfony/V5_2/TraceSearchConfigTest.php +++ /dev/null @@ -1,81 +0,0 @@ - 'true', - 'DD_SYMFONY_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'symfony.request', - 'symfony', - 'web', - 'simple' - )->withExactTags([ - 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', - 'symfony.route.name' => 'simple', - 'http.route' => '/simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ])->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ])->withChildren([ - SpanAssertion::exists('symfony.kernel.terminate'), - SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.boot'), - SpanAssertion::exists('symfony.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.kernel.request'), - SpanAssertion::exists('symfony.kernel.controller'), - SpanAssertion::exists('symfony.kernel.controller_arguments'), - SpanAssertion::build( - 'symfony.controller', - 'symfony', - 'web', - 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ]), - SpanAssertion::exists('symfony.kernel.response'), - SpanAssertion::exists('symfony.kernel.finish_request'), - ]), - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Symfony/V6_2/TraceSearchConfigTest.php b/tests/Integrations/Symfony/V6_2/TraceSearchConfigTest.php deleted file mode 100644 index aaf2f4acc85..00000000000 --- a/tests/Integrations/Symfony/V6_2/TraceSearchConfigTest.php +++ /dev/null @@ -1,81 +0,0 @@ - 'true', - 'DD_SYMFONY_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertFlameGraph( - $traces, - [ - SpanAssertion::build( - 'symfony.request', - 'symfony', - 'web', - 'simple' - )->withExactTags([ - 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', - 'symfony.route.name' => 'simple', - 'http.route' => '/simple', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ])->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ])->withChildren([ - SpanAssertion::exists('symfony.kernel.terminate'), - SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.httpkernel.kernel.boot'), - SpanAssertion::exists('symfony.kernel.handle')->withChildren([ - SpanAssertion::exists('symfony.kernel.request'), - SpanAssertion::exists('symfony.kernel.controller'), - SpanAssertion::exists('symfony.kernel.controller_arguments'), - SpanAssertion::build( - 'symfony.controller', - 'symfony', - 'web', - 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ - Tag::COMPONENT => 'symfony', - '_dd.svc_src' => 'symfony', - ]), - SpanAssertion::exists('symfony.kernel.response'), - SpanAssertion::exists('symfony.kernel.finish_request'), - ]), - ]), - ]), - ] - ); - } -} diff --git a/tests/Integrations/Symfony/V7_3/TraceSearchConfigTest.php b/tests/Integrations/Symfony/V7_3/TraceSearchConfigTest.php deleted file mode 100644 index 369f46a587e..00000000000 --- a/tests/Integrations/Symfony/V7_3/TraceSearchConfigTest.php +++ /dev/null @@ -1,11 +0,0 @@ - 'true', - 'DD_ZENDFRAMEWORK_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertExpectedSpans( - $traces, - [ - SpanAssertion::build('zf1.request', 'zf1', 'web', 'simple@index default') - ->withExactTags([ - 'zf1.controller' => 'simple', - 'zf1.action' => 'index', - 'zf1.route_name' => 'default', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'zendframework', - '_dd.svc_src' => 'zf1', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]), - ] - ); - } -} diff --git a/tests/Integrations/ZendFramework/V1_21/TraceSearchConfigTest.php b/tests/Integrations/ZendFramework/V1_21/TraceSearchConfigTest.php deleted file mode 100644 index d2dc2c12f05..00000000000 --- a/tests/Integrations/ZendFramework/V1_21/TraceSearchConfigTest.php +++ /dev/null @@ -1,57 +0,0 @@ - 'true', - 'DD_ZENDFRAMEWORK_ANALYTICS_SAMPLE_RATE' => '0.3', - ]); - } - - /** - * @throws \Exception - */ - public function testScenario() - { - $traces = $this->tracesFromWebRequest(function () { - $this->call(GetSpec::create('Testing trace analytics config metric', '/simple')); - }); - - $this->assertExpectedSpans( - $traces, - [ - SpanAssertion::build('zf1.request', 'zf1', 'web', 'simple@index default') - ->withExactTags([ - 'zf1.controller' => 'simple', - 'zf1.action' => 'index', - 'zf1.route_name' => 'default', - 'http.method' => 'GET', - 'http.url' => 'http://localhost/simple', - 'http.status_code' => '200', - Tag::SPAN_KIND => 'server', - Tag::COMPONENT => 'zendframework', - '_dd.svc_src' => 'zf1', - ]) - ->withExactMetrics([ - '_dd1.sr.eausr' => 0.3, - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]), - ] - ); - } -} From 32d4d082205e932d051e3f9dd69fc4fc2e0586b8 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Tue, 21 Jul 2026 14:17:37 +0200 Subject: [PATCH 08/32] chore(tracer): trim verbose comments added by span-consistency work Comment-only cleanup of the C span-consistency changes: trim the multi-line explanatory blocks in serializer.c, span.c, handlers_httpstreams.c and tracer_telemetry.c down to concise 1-2 line comments. No behavior change. --- tracer/handlers_httpstreams.c | 3 +-- tracer/serializer.c | 33 ++++++++++----------------------- tracer/span.c | 8 +++----- tracer/tracer_telemetry.c | 5 ++--- 4 files changed, 16 insertions(+), 33 deletions(-) diff --git a/tracer/handlers_httpstreams.c b/tracer/handlers_httpstreams.c index 162eb0bc383..91c5cb2d874 100644 --- a/tracer/handlers_httpstreams.c +++ b/tracer/handlers_httpstreams.c @@ -72,8 +72,7 @@ static php_stream *dd_stream_opener( zend_array *meta = ddtrace_property_array(&span->property_meta); zval zv; - // component / span.kind are carried on the span properties; the serializer translates - // them back into meta["component"] / meta["span.kind"] at serialization time. + // Set on the properties; the serializer mirrors them into meta at serialization time. zval_ptr_dtor(&span->property_component); ZVAL_STRING(&span->property_component, "php.stream"); ZVAL_LONG(&span->property_span_kind, 3 /* DDTrace\SpanKind::CLIENT */); diff --git a/tracer/serializer.c b/tracer/serializer.c index 2828d5d0862..75adbcd9f5e 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -641,9 +641,7 @@ static void dd_set_entrypoint_root_span_props(struct superglob_equiv *data, ddtr zend_hash_str_add_new(meta, ZEND_STRL("http.method"), &http_method); // Mark HTTP server entry spans with span.kind=server for client-side stats aggregation. - // Only add if not already set (e.g. by an OTel or framework integration). This span.kind - // is written straight to meta (add-if-absent): unlike the internal producers, the entry - // root must not clobber a value provided by userland, so it does not use the property. + // Written to meta add-if-absent (not via the property) so a userland/OTel value wins. zval span_kind_server; ZVAL_STRING(&span_kind_server, "server"); if (!zend_hash_str_add(meta, ZEND_STRL("span.kind"), &span_kind_server)) { @@ -934,8 +932,7 @@ static void dd_serialize_json(zend_array *arr, smart_str *buf, int options) { smart_str_0(buf); } -// Maps the integer DDTrace\SpanKind constant to the string previously stored in meta["span.kind"]. -// Returns NULL for UNSPECIFIED (0) or unknown values, in which case no meta key is emitted. +// Maps a DDTrace\SpanKind integer constant to its meta["span.kind"] string; NULL means emit nothing. static const char *dd_span_kind_to_meta_str(zend_long kind) { switch (kind) { case 1: return "internal"; // DDTrace\SpanKind::INTERNAL @@ -947,12 +944,8 @@ static const char *dd_span_kind_to_meta_str(zend_long kind) { } } -// Translate the $span->component / $span->spanKind properties back into meta["component"] / -// meta["span.kind"] so that the wire meta stays byte-identical to the pre-property behaviour. -// The properties are the source of truth and supersede meta (clobber), matching the original -// producers which used zend_hash_str_update / add_assoc_string. Spans that do not set the -// properties (property empty / spanKind==0 — e.g. userland integrations, which write meta -// directly, and the entrypoint root span) are left untouched, so their meta is preserved. +// Mirror the $span->component / $span->spanKind properties into meta (clobbering) so the wire meta +// matches the pre-property behaviour. Empty component / spanKind==0 is a no-op, leaving meta intact. static void dd_translate_span_kind_component_to_meta(ddtrace_span_data *span, zend_array *meta) { zval *component = &span->property_component; ZVAL_DEREF(component); @@ -974,8 +967,7 @@ static void dd_translate_span_kind_component_to_meta(ddtrace_span_data *span, ze } } -// Serialize an array of DDTrace\SpanEvent objects to the exact JSON shape previously produced by -// DDTrace\SpanEvent::jsonSerialize() (invoked via json_encode over the array of objects). +// Convert a DDTrace\SpanEvent to the array shape SpanEvent::jsonSerialize() used to return. static zend_array *dd_span_event_to_array(ddtrace_span_event *event) { zval array; array_init(&array); @@ -1021,8 +1013,7 @@ static zend_array *dd_span_event_to_array(ddtrace_span_event *event) { return Z_ARR(array); } -// Serialize a DDTrace\SpanLink object to the exact JSON shape previously produced by -// DDTrace\SpanLink::jsonSerialize() (invoked via json_encode over the array of objects). +// Convert a DDTrace\SpanLink to the array shape SpanLink::jsonSerialize() used to return. static zend_array *dd_span_link_to_array(ddtrace_span_link *link) { zend_array *array = zend_new_array(5); @@ -1052,9 +1043,8 @@ static zend_array *dd_span_link_to_array(ddtrace_span_link *link) { return array; } -// Build a JSON array from a list of span links, converting each SpanLink object into the array -// shape that DDTrace\SpanLink::jsonSerialize() used to return, then json-encode it. This preserves -// byte-identical output while removing the reliance on JsonSerializable. +// JSON-encode a list of span links, converting each SpanLink object via dd_span_link_to_array +// (replaces the former JsonSerializable path, byte-identical output). static void dd_serialize_span_links(zend_array *links, smart_str *buf) { zval tmp; array_init_size(&tmp, zend_hash_num_elements(links)); @@ -1079,8 +1069,7 @@ static void dd_serialize_span_links(zend_array *links, smart_str *buf) { zval_ptr_dtor(&tmp); } -// Build a JSON array from a list of span events, converting each SpanEvent object into the array -// shape that DDTrace\SpanEvent::jsonSerialize() used to return, then json-encode it. +// JSON-encode a list of span events, converting each SpanEvent object via dd_span_event_to_array. static void dd_serialize_span_events(zend_array *events, smart_str *buf) { zval tmp; array_init_size(&tmp, zend_hash_num_elements(events)); @@ -1506,9 +1495,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo zend_array *meta = ddtrace_property_array(&span->property_meta); zend_array *metrics = ddtrace_property_array(&span->property_metrics); - // The component / span.kind properties are the source of truth (populated by the C producers). - // Translate them back into the meta blob (add-if-absent) so the wire meta is unchanged and any - // meta-based consumer (e.g. client-side stats via the precomputed span_kind) keeps working. + // Mirror the component / span.kind properties into meta so meta-based consumers keep working. dd_translate_span_kind_component_to_meta(span, meta); // Remap OTel's status code (metric, http.status_code) to DD's status code (meta, http.status_code) diff --git a/tracer/span.c b/tracer/span.c index 174c554d0d6..853c90ab68d 100644 --- a/tracer/span.c +++ b/tracer/span.c @@ -167,9 +167,8 @@ static ddtrace_span_data *ddtrace_init_span(enum ddtrace_span_dataype type, zend ddtrace_span_data *span = OBJ_SPANDATA(Z_OBJ(fci_zv)); span->type = type; #if PHP_VERSION_ID < 80000 - // On PHP 7 array-typed properties default to null (see the ZVAL_EMPTY_ARRAY - // shim in functions.c); materialize `attributes` to an empty array so it is - // consistent with its `= []` stub default across all supported versions. + // PHP 7 array-typed properties default to null; materialize `attributes` to match its + // `= []` stub default (as on PHP 8). ddtrace_property_array(&span->property_attributes); #endif return span; @@ -253,8 +252,7 @@ ddtrace_inferred_span_data *ddtrace_open_inferred_span(ddtrace_inferred_proxy_re ZVAL_LONG(&zv, 1); zend_hash_str_add_new(ddtrace_property_array(&span->property_metrics), ZEND_STRL("_dd.inferred_span"), &zv); - // component is carried on the span property; the serializer translates it back into - // meta["component"] at serialization time. + // Set on the property; the serializer mirrors it into meta["component"] at serialization time. zval_ptr_dtor(&span->property_component); ZVAL_STRING(&span->property_component, (char *)proxy_info->component); ZVAL_STR(&span->property_type, zend_string_init(ZEND_STRL("web"), 0)); diff --git a/tracer/tracer_telemetry.c b/tracer/tracer_telemetry.c index 50ce8c2cf5d..1ddfc4652b2 100644 --- a/tracer/tracer_telemetry.c +++ b/tracer/tracer_telemetry.c @@ -191,9 +191,8 @@ void ddtrace_telemetry_notify_integration_version(const char *name, size_t name_ } void ddtrace_telemetry_inc_spans_created(ddtrace_span_data *span) { - // The $span->component property is the source of truth (the serializer mirrors it into - // meta["component"] at serialization time, which happens after this close-time hook). Fall - // back to meta["component"] for spans that still set it directly (e.g. userland integrations). + // Prefer the $span->component property; the meta mirror only happens later at serialization, + // so fall back to meta["component"] for spans (e.g. userland integrations) that set it directly. zval *component_prop = &span->property_component; ZVAL_DEREF(component_prop); zval *component = NULL; From 6f268b9610a30f33ff76c274c66208addec1a2bb Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Wed, 22 Jul 2026 16:00:19 +0200 Subject: [PATCH 09/32] chore(signals): drop stale TODO on legacy backtrace handler --- ext/signals.c | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/signals.c b/ext/signals.c index 61676ad0f55..2432234f896 100644 --- a/ext/signals.c +++ b/ext/signals.c @@ -261,7 +261,6 @@ void datadog_signals_first_rinit(void) { bool install_crashtracker = get_DD_INSTRUMENTATION_TELEMETRY_ENABLED() && get_DD_CRASHTRACKING_ENABLED(); bool install_backtrace_handler = get_DD_TRACE_HEALTH_METRICS_ENABLED(); - // TODO: Remove this since we have crashtracking now #if DATADOG_HAVE_BACKTRACE install_backtrace_handler |= get_DD_LOG_BACKTRACE(); #endif From 5f105bfc4a7bf265fce6b82c1c43cfda83e6c0aa Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 27 Jul 2026 14:30:30 +0200 Subject: [PATCH 10/32] feat(tracer): deprecate App Analytics API to a no-op The user-facing App Analytics API is now a deprecated no-op: it remains callable (Tag::ANALYTICS_KEY, TraceAnalyticsProcessor, DD_TRACE_ANALYTICS_ENABLED stay defined) but no longer applies any behavior nor emits the _dd1.sr.eausr metric in-process or on the wire. - serializer.c: drop the DD_TRACE_ANALYTICS_ENABLED/web-analytics emission, stop converting the analytics.event meta key to the metric (still consumed), and skip _dd1.sr.eausr in the metrics serialization loop. - TraceAnalyticsProcessor::normalizeAnalyticsValue is now an empty no-op; Tag::ANALYTICS_KEY, the processor, and the api stubs are marked @deprecated. - Tests rewritten to assert the API is callable and emits no _dd1.sr.eausr. --- .../Processing/TraceAnalyticsProcessor.php | 24 +++---- src/api/Tag.php | 1 + src/ddtrace_php_api.stubs.php | 9 +-- .../Integration/API/TracerTest.php | 46 +++++++------- .../Integration/InteroperabilityTest.php | 3 +- .../TraceAnalyticsProcessorTest.php | 31 ++++----- tests/Unit/SpanTest.php | 22 +++---- tests/ext/test_special_attributes.phpt | 7 +-- tests/ext/test_special_attributes_bis.phpt | 7 +-- tracer/serializer.c | 63 +------------------ 10 files changed, 65 insertions(+), 148 deletions(-) diff --git a/src/DDTrace/Processing/TraceAnalyticsProcessor.php b/src/DDTrace/Processing/TraceAnalyticsProcessor.php index 86c6b735bb1..cd78b9bafdf 100644 --- a/src/DDTrace/Processing/TraceAnalyticsProcessor.php +++ b/src/DDTrace/Processing/TraceAnalyticsProcessor.php @@ -2,29 +2,19 @@ namespace DDTrace\Processing; -use DDTrace\Data\Span as DataSpan; -use DDTrace\Tag; - /** - * A span processor in charge of adding the trace analytics client config metric when appropriate. - * - * NOTE: this may be transformer into a filter for consistency with other tracers, but for now we did not implement - * any filtering functionality so giving it such name as of now might be misleading. + * @deprecated App Analytics is deprecated and no longer has any effect. */ final class TraceAnalyticsProcessor { /** - * @param array $metrics - * @param bool|float $value - */ + * @deprecated App Analytics is deprecated. This is now a no-op and does not + * modify $metrics or emit the _dd1.sr.eausr metric. + * + * @param array $metrics + * @param bool|float $value + */ public static function normalizeAnalyticsValue(&$metrics, $value) { - if (true === $value) { - $metrics[Tag::ANALYTICS_KEY] = 1.0; - } elseif (false === $value) { - unset($metrics[Tag::ANALYTICS_KEY]); - } elseif (is_numeric($value) && 0 <= $value && $value <= 1) { - $metrics[Tag::ANALYTICS_KEY] = (float)$value; - } } } diff --git a/src/api/Tag.php b/src/api/Tag.php index f2cb6b7c1e4..4bfdecd1846 100644 --- a/src/api/Tag.php +++ b/src/api/Tag.php @@ -38,6 +38,7 @@ class Tag const TARGET_HOST = 'out.host'; const TARGET_PORT = 'out.port'; const BYTES_OUT = 'net.out.bytes'; + /** @deprecated App Analytics is deprecated; setting this metric no longer has any effect. */ const ANALYTICS_KEY = '_dd1.sr.eausr'; const HOSTNAME = '_dd.hostname'; const ORIGIN = '_dd.origin'; diff --git a/src/ddtrace_php_api.stubs.php b/src/ddtrace_php_api.stubs.php index 94661fca2eb..0b335dd6b17 100644 --- a/src/ddtrace_php_api.stubs.php +++ b/src/ddtrace_php_api.stubs.php @@ -301,14 +301,14 @@ public static function createFromLocalSpan(\DDTrace\SpanData $span, bool $sample } namespace DDTrace\Processing { /** - * A span processor in charge of adding the trace analytics client config metric when appropriate. - * - * NOTE: this may be transformer into a filter for consistency with other tracers, but for now we did not implement - * any filtering functionality so giving it such name as of now might be misleading. + * @deprecated App Analytics is deprecated and no longer has any effect. */ final class TraceAnalyticsProcessor { /** + * @deprecated App Analytics is deprecated. This is now a no-op and does not + * modify $metrics or emit the _dd1.sr.eausr metric. + * * @param array $metrics * @param bool|float $value */ @@ -2241,6 +2241,7 @@ class Tag const TARGET_HOST = 'out.host'; const TARGET_PORT = 'out.port'; const BYTES_OUT = 'net.out.bytes'; + /** @deprecated App Analytics is deprecated; setting this metric no longer has any effect. */ const ANALYTICS_KEY = '_dd1.sr.eausr'; const HOSTNAME = '_dd.hostname'; const ORIGIN = '_dd.origin'; diff --git a/tests/OpenTelemetry/Integration/API/TracerTest.php b/tests/OpenTelemetry/Integration/API/TracerTest.php index 025bc09539d..570b9ba4def 100644 --- a/tests/OpenTelemetry/Integration/API/TracerTest.php +++ b/tests/OpenTelemetry/Integration/API/TracerTest.php @@ -339,30 +339,33 @@ public function providerSpanKind() public function providerAnalyticsEvent() { return [ - ["true", 1], - ["TRUE", 1], - ["True", 1], - ["false", 0], - ["False", 0], - ["FALSE", 0], - ["something-else", null], - [True, 1], - [False, 0], - ['t', 1], - ['T', 1], - ['f', 0], - ['F', 0], - ['1', 1], - ['0', 0], - ['fAlse', null], - ['trUe', null] + ["true"], + ["TRUE"], + ["True"], + ["false"], + ["False"], + ["FALSE"], + ["something-else"], + [True], + [False], + ['t'], + ['T'], + ['f'], + ['F'], + ['1'], + ['0'], + ['fAlse'], + ['trUe'] ]; } /** + * App Analytics is deprecated and a no-op: analytics.event no longer emits the + * _dd1.sr.eausr metric, but setting it must remain callable without error. + * * @dataProvider providerAnalyticsEvent */ - public function testReservedAttributesOverridesAnalyticsEvent($analyticsEventValue, $expectedMetricValue) + public function testAnalyticsEventIsDeprecatedNoOp($analyticsEventValue) { $traces = $this->isolateTracer(function () use ($analyticsEventValue) { $tracer = self::getTracer(); @@ -374,12 +377,7 @@ public function testReservedAttributesOverridesAnalyticsEvent($analyticsEventVal }); $span = $traces[0][0]; - if ($expectedMetricValue !== null) { - $actualMetricValue = $span['metrics']['_dd1.sr.eausr']; - $this->assertEquals($expectedMetricValue, $actualMetricValue); - } else { - $this->assertArrayNotHasKey('_dd1.sr.eausr', $span['metrics']); - } + $this->assertArrayNotHasKey('_dd1.sr.eausr', $span['metrics']); } public function testSpanErrorStatus() diff --git a/tests/OpenTelemetry/Integration/InteroperabilityTest.php b/tests/OpenTelemetry/Integration/InteroperabilityTest.php index 96d4d6e3ab8..fd04dc82f63 100644 --- a/tests/OpenTelemetry/Integration/InteroperabilityTest.php +++ b/tests/OpenTelemetry/Integration/InteroperabilityTest.php @@ -920,7 +920,8 @@ public function testSpecialAttributes() $this->assertSame('new.name', $span['resource']); $this->assertSame('new.service.name', $span['service']); $this->assertSame('new.span.type', $span['type']); - $this->assertEquals(1.0, $span['metrics']['_dd1.sr.eausr']); + // App Analytics is deprecated and a no-op: analytics.event no longer emits _dd1.sr.eausr. + $this->assertArrayNotHasKey('_dd1.sr.eausr', $span['metrics']); } public function testHasEnded() diff --git a/tests/Unit/Processing/TraceAnalyticsProcessorTest.php b/tests/Unit/Processing/TraceAnalyticsProcessorTest.php index 1b8fd98cbca..57d6f898502 100644 --- a/tests/Unit/Processing/TraceAnalyticsProcessorTest.php +++ b/tests/Unit/Processing/TraceAnalyticsProcessorTest.php @@ -8,42 +8,35 @@ final class TraceAnalyticsProcessorTest extends BaseTestCase { - public function testTrueIs1() + public function testTrueIsNoOp() { - $metrics = [ - ]; + $metrics = []; TraceAnalyticsProcessor::normalizeAnalyticsValue($metrics, true); - $this->assertSame(1.0, $metrics[Tag::ANALYTICS_KEY]); + $this->assertArrayNotHasKey(Tag::ANALYTICS_KEY, $metrics); } - public function testFalseIsUnset() + public function testFalseIsNoOp() { $metrics = [ Tag::ANALYTICS_KEY => 0.2, ]; TraceAnalyticsProcessor::normalizeAnalyticsValue($metrics, false); - $this->assertArrayNotHasKey(Tag::ANALYTICS_KEY, $metrics); + $this->assertSame(0.2, $metrics[Tag::ANALYTICS_KEY]); } - public function testNumericValueBetweenZeroAndOne() - { - $metrics = [ - ]; - TraceAnalyticsProcessor::normalizeAnalyticsValue($metrics, 0.4); - $this->assertSame(0.4, $metrics[Tag::ANALYTICS_KEY]); - } - - public function testValueLessThan0() + public function testNumericValueIsNoOp() { $metrics = []; - TraceAnalyticsProcessor::normalizeAnalyticsValue($metrics, -0.1); + TraceAnalyticsProcessor::normalizeAnalyticsValue($metrics, 0.4); $this->assertArrayNotHasKey(Tag::ANALYTICS_KEY, $metrics); } - public function testValueGreaterThan1() + public function testDoesNotMutateExistingMetrics() { - $metrics = []; + $metrics = ['foo' => 1.0]; + TraceAnalyticsProcessor::normalizeAnalyticsValue($metrics, true); + TraceAnalyticsProcessor::normalizeAnalyticsValue($metrics, -0.1); TraceAnalyticsProcessor::normalizeAnalyticsValue($metrics, 1.1); - $this->assertArrayNotHasKey(Tag::ANALYTICS_KEY, $metrics); + $this->assertSame(['foo' => 1.0], $metrics); } } diff --git a/tests/Unit/SpanTest.php b/tests/Unit/SpanTest.php index f06e8902e63..d874b5c0491 100644 --- a/tests/Unit/SpanTest.php +++ b/tests/Unit/SpanTest.php @@ -273,45 +273,45 @@ public function testMetricsSetGet() $this->assertSame(1.0, $span->getMetrics()['exists']); } - public function testTraceAnalyticsConfigEnabledByTag() + public function testTraceAnalyticsByTagIsDeprecatedNoOp() { $span = $this->createSpan(); $span->setTag(Tag::ANALYTICS_KEY, 0.5); - $this->assertSame(0.5, $span->getMetrics()[Tag::ANALYTICS_KEY]); + $this->assertArrayNotHasKey(Tag::ANALYTICS_KEY, $span->getMetrics()); } - public function testTraceAnalyticsConfigEnabledByMetric() + public function testTraceAnalyticsByMetricIsDeprecatedNoOp() { $span = $this->createSpan(); $span->setMetric(Tag::ANALYTICS_KEY, 0.5); - $this->assertSame(0.5, $span->getMetrics()[Tag::ANALYTICS_KEY]); + $this->assertArrayNotHasKey(Tag::ANALYTICS_KEY, $span->getMetrics()); } - public function testTraceAnalyticsConfigEnabledTrueResultTo1() + public function testTraceAnalyticsTrueIsDeprecatedNoOp() { $span = $this->createSpan(); $span->setMetric(Tag::ANALYTICS_KEY, true); - $this->assertSame(1.0, $span->getMetrics()[Tag::ANALYTICS_KEY]); + $this->assertArrayNotHasKey(Tag::ANALYTICS_KEY, $span->getMetrics()); } - public function testTraceAnalyticsConfigDisabled() + public function testTraceAnalyticsFalseIsDeprecatedNoOp() { $span = $this->createSpan(); $span->setMetric(Tag::ANALYTICS_KEY, true); - $this->assertSame(1.0, $span->getMetrics()[Tag::ANALYTICS_KEY]); - $span->setMetric(Tag::ANALYTICS_KEY, false); + $this->assertArrayNotHasKey(Tag::ANALYTICS_KEY, $span->getMetrics()); } - public function testTraceAnalyticsConfigSpecificRate() + public function testTraceAnalyticsSpecificRateIsDeprecatedNoOp() { $span = $this->createSpan(); $span->setMetric(Tag::ANALYTICS_KEY, 0.3); - $this->assertSame(0.3, $span->getMetrics()[Tag::ANALYTICS_KEY]); + + $this->assertArrayNotHasKey(Tag::ANALYTICS_KEY, $span->getMetrics()); } public function testSpanCreationDoesNotInterfereWithDeterministicRandomness() diff --git a/tests/ext/test_special_attributes.phpt b/tests/ext/test_special_attributes.phpt index 1539e37ff7e..4c3ffffe823 100644 --- a/tests/ext/test_special_attributes.phpt +++ b/tests/ext/test_special_attributes.phpt @@ -33,7 +33,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(11) { + array(10) { ["trace_id"]=> string(%d) "%d" ["span_id"]=> @@ -59,10 +59,5 @@ array(1) { ["_dd.svc_src"]=> string(1) "m" } - ["metrics"]=> - array(1) { - ["_dd1.sr.eausr"]=> - float(1) - } } } diff --git a/tests/ext/test_special_attributes_bis.phpt b/tests/ext/test_special_attributes_bis.phpt index d08ff85c7bf..df5c18f7aba 100644 --- a/tests/ext/test_special_attributes_bis.phpt +++ b/tests/ext/test_special_attributes_bis.phpt @@ -34,7 +34,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(11) { + array(10) { ["trace_id"]=> string(%d) "%d" ["span_id"]=> @@ -60,10 +60,5 @@ array(1) { ["_dd.svc_src"]=> string(1) "m" } - ["metrics"]=> - array(1) { - ["_dd1.sr.eausr"]=> - float(1) - } } } diff --git a/tracer/serializer.c b/tracer/serializer.c index 75adbcd9f5e..fb718410d35 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -908,13 +908,6 @@ void ddtrace_set_root_span_properties(ddtrace_root_span_data *span) { DATADOG_G(asm_event_emitted) = false; // we attach this to the first root span after the asm event was detected (if there was none while emitted) } - ddtrace_integration *web_integration = &ddtrace_integrations[DDTRACE_INTEGRATION_WEB]; - if (get_DD_TRACE_ANALYTICS_ENABLED() || web_integration->is_analytics_enabled()) { - zval sample_rate; - ZVAL_DOUBLE(&sample_rate, web_integration->get_sample_rate()); - zend_hash_str_add_new(metrics, ZEND_STRL("_dd1.sr.eausr"), &sample_rate); - } - if (get_DD_TRACE_GIT_METADATA_ENABLED()) { ddtrace_inject_git_metadata(&span->property_git_metadata); } @@ -1431,46 +1424,6 @@ void ddtrace_shutdown_span_sampling_limiter(void) { zend_hash_destroy(&dd_span_sampling_limiters); } -// ParseBool returns the boolean value represented by the string. -// It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False. -// Any other value returns -1. -static zend_always_inline double strconv_parse_bool(zend_string *str) { - // See Go's strconv.ParseBool - // https://cs.opensource.google/go/go/+/refs/tags/go1.21.5:src/strconv/atob.go;drc=1f137052e4a20dbd302f947b1cf34cdf4b427d65;l=10 - size_t len = ZSTR_LEN(str); - if (len == 0) { - return -1; - } - - char *s = ZSTR_VAL(str); - switch (len) { - case 1: - switch (s[0]) { - case '1': - case 't': - case 'T': - return 1; - case '0': - case 'f': - case 'F': - return 0; - } - break; - case 4: - if (strcmp(s, "TRUE") == 0 || strcmp(s, "True") == 0 || strcmp(s, "true") == 0) { - return 1; - } - break; - case 5: - if (strcmp(s, "FALSE") == 0 || strcmp(s, "False") == 0 || strcmp(s, "false") == 0) { - return 0; - } - break; - } - - return -1; -} - void transfer_meta_data(ddog_SpanBytes *source, ddog_SpanBytes *destination, const char *key, bool delete_source) { ddog_CharSlice value = ddog_get_span_meta_str(source, key); if (value.len > 0) { @@ -1811,18 +1764,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo zend_hash_str_del(meta, ZEND_STRL("span.type")); } - zval *analytics_event = zend_hash_str_find(meta, ZEND_STRL("analytics.event")); - if (analytics_event) { - if (Z_TYPE_P(analytics_event) == IS_STRING) { - double parsed_analytics_event = strconv_parse_bool(Z_STR_P(analytics_event)); - if (parsed_analytics_event >= 0) { - ddog_add_span_metrics_str(rust_span, "_dd1.sr.eausr", parsed_analytics_event); - } - } else { - ddog_add_span_metrics_str(rust_span, "_dd1.sr.eausr", zval_get_double(analytics_event)); - } - zend_hash_str_del(meta, ZEND_STRL("analytics.event")); - } + zend_hash_str_del(meta, ZEND_STRL("analytics.event")); if (span_sampling_applied) { ddog_add_span_metrics_str(rust_span, "_dd.span_sampling.mechanism", 8.0); @@ -1984,7 +1926,8 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo zend_string *str_key; zval *val; ZEND_HASH_FOREACH_STR_KEY_VAL_IND(metrics, str_key, val) { - if (str_key && !ddog_has_span_metrics_zstr(rust_span, str_key)) { + if (str_key && !zend_string_equals_literal(str_key, "_dd1.sr.eausr") && + !ddog_has_span_metrics_zstr(rust_span, str_key)) { dd_serialize_array_metrics_recursively(rust_span, str_key, val); } } ZEND_HASH_FOREACH_END(); From a51a6a5f4e21365d4038150d58da81ef9d74da21 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 3 Aug 2026 16:03:59 +0200 Subject: [PATCH 11/32] chore(libdatadog): bump submodule to v1 sidecar (#2156) Bump the libdatadog submodule to PR #2156's head (938c110), which brings in the v1 sidecar span encoder/decoder (#2145, #2174) via its main base. Regenerate components-rs/{common,sidecar}.h with cbindgen (exposes the new ddog_sidecar_send_trace_v1_shm / _bytes entrypoints and the ASM_RAW_RESPONSE_BODY remote-config capability) and mirror libdatadog's consolidated [workspace.dependencies] into the root Cargo.toml so the path-dependency crates resolve their { workspace = true } inheritance. Wire format is unchanged: v04 remains the default send path. --- Cargo.toml | 3 ++- components-rs/sidecar.h | 21 +++++++++++++++++++++ libdatadog | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6b3b87141e4..299f6c06586 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,8 @@ inherits = "release" # inheritance against this manifest when built as path dependencies. Keep this # list in sync with libdatadog's own `[workspace.dependencies]`; libdatadog # #2253 consolidated `anyhow`, `serde`, `tokio` and `tracing` to the workspace -# level, so they are mirrored here too. +# level, and later work moved the rest of libdatadog's shared deps there too, so +# the full list is mirrored here. [workspace.dependencies] allocator-api2 = { version = "0.2.21", default-features = false } anyhow = { version = "1.0", default-features = false } diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 72ea5e9e020..f0145771642 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -307,6 +307,27 @@ ddog_MaybeError ddog_sidecar_send_trace_v04_bytes(struct ddog_SidecarTransport * ddog_CharSlice data, const struct ddog_TracerHeaderTags *tracer_header_tags); +/** + * Sends a V1-encoded trace to the sidecar via shared memory. The sidecar decodes the V1 + * `TracerPayload`, can inspect it, and re-encodes it as V1 msgpack on the way to the agent's + * `/v1.0/traces` endpoint. + */ +ddog_MaybeError ddog_sidecar_send_trace_v1_shm(struct ddog_SidecarTransport **transport, + const struct ddog_InstanceId *instance_id, + struct ddog_ShmHandle *shm_handle, + uintptr_t len, + const struct ddog_TracerHeaderTags *tracer_header_tags); + +/** + * Sends a V1-encoded trace as bytes to the sidecar. The sidecar decodes the V1 `TracerPayload`, + * can inspect it, and re-encodes it as V1 msgpack on the way to the agent's `/v1.0/traces` + * endpoint. + */ +ddog_MaybeError ddog_sidecar_send_trace_v1_bytes(struct ddog_SidecarTransport **transport, + const struct ddog_InstanceId *instance_id, + ddog_CharSlice data, + const struct ddog_TracerHeaderTags *tracer_header_tags); + ddog_MaybeError ddog_sidecar_send_debugger_data(struct ddog_SidecarTransport **transport, const struct ddog_InstanceId *instance_id, ddog_QueueId queue_id, diff --git a/libdatadog b/libdatadog index 378be45c30e..c5dc30175f5 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 378be45c30e9c62a1203c4cc2069aaaf8d1f4673 +Subproject commit c5dc30175f5b2d3e6f2e59b4bd3051337d137bef From e9635f907013f9b97480d7f2fdf8036e8d8f2dd8 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 3 Aug 2026 16:41:15 +0200 Subject: [PATCH 12/32] chore: bump libdatadog to v1 send FFI + regenerate headers --- components-rs/common.h | 20 ++++++++++++++++++++ components-rs/sidecar.h | 10 ++++++++++ 2 files changed, 30 insertions(+) diff --git a/components-rs/common.h b/components-rs/common.h index 516014cb992..4ffeb5b0377 100644 --- a/components-rs/common.h +++ b/components-rs/common.h @@ -1352,6 +1352,26 @@ typedef struct ddog_SenderParameters { ddog_CharSlice url; } ddog_SenderParameters; +/** + * Payload-level tracer metadata consumed by the V1 msgpack encoder. Each field mirrors the + * corresponding field on `libdd_trace_utils::tracer_metadata::TracerMetadata`; empty slices are + * tolerated (the encoder falls back to span meta / omits the field). + */ +typedef struct ddog_TracerMetadataV1 { + ddog_CharSlice hostname; + ddog_CharSlice env; + ddog_CharSlice app_version; + ddog_CharSlice runtime_id; + ddog_CharSlice service; + ddog_CharSlice tracer_version; + ddog_CharSlice language_name; + ddog_CharSlice language_version; + ddog_CharSlice language_interpreter; + ddog_CharSlice language_interpreter_vendor; + ddog_CharSlice git_commit_sha; + ddog_CharSlice process_tags; +} ddog_TracerMetadataV1; + typedef enum ddog_crasht_BuildIdType { DDOG_CRASHT_BUILD_ID_TYPE_GNU, DDOG_CRASHT_BUILD_ID_TYPE_GO, diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index f0145771642..22ae34b25e6 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -497,6 +497,16 @@ ddog_CharSlice ddog_get_agent_info_container_tags_hash(struct ddog_AgentInfoRead void ddog_send_traces_to_sidecar(ddog_TracesBytes *traces, struct ddog_SenderParameters *parameters); +/** + * Encodes `traces` as a V1 msgpack `TracerPayload` (using `metadata` for the payload-level + * fields) and sends it to the sidecar, which re-encodes it for the agent's `/v1.0/traces` + * endpoint. Mirrors `ddog_send_traces_to_sidecar` (v04) for the SHM allocation, per-span dedup, + * `size_hint` derivation and the shm→bytes send fallback. + */ +void ddog_send_traces_to_sidecar_v1(ddog_TracesBytes *traces, + struct ddog_SenderParameters *parameters, + const struct ddog_TracerMetadataV1 *metadata); + /** * Drops the agent info reader. */ From 22520b4c1b139fbbecc4d63f8abd911a4141a17d Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 3 Aug 2026 17:08:06 +0200 Subject: [PATCH 13/32] feat(tracer): gate trace flush on DD_TRACE_AGENT_PROTOCOL_VERSION for V1 wire Add DD_TRACE_AGENT_PROTOCOL_VERSION (default "0.4"). When set to "1"/"1.0", assemble ddog_TracerMetadataV1 and call ddog_send_traces_to_sidecar_v1; otherwise keep the unchanged V0.4 sidecar send. Hard gate; no /info negotiation. --- tracer/auto_flush.c | 30 +++++++++++++++++++++++++++++- tracer/configuration.h | 1 + 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/tracer/auto_flush.c b/tracer/auto_flush.c index e0985f2c116..c1d931e81bf 100644 --- a/tracer/auto_flush.c +++ b/tracer/auto_flush.c @@ -7,6 +7,8 @@ #include "coms.h" #endif #include "configuration.h" +#include +#include #include #include "serializer.h" #include "span.h" @@ -67,7 +69,33 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles .buffer_size = get_global_DD_TRACE_BUFFER_SIZE(), .url = (ddog_CharSlice) {.ptr = url, .len = strlen(url)}, }; - ddog_send_traces_to_sidecar(traces, ¶meters); + // Hard gate on DD_TRACE_AGENT_PROTOCOL_VERSION (no /info negotiation yet in this + // cut): "1"/"1.0" selects the V1 wire (POST /v1.0/traces); anything else (default + // "0.4") keeps the unchanged V0.4 path. + zend_string *protocol_version = get_global_DD_TRACE_AGENT_PROTOCOL_VERSION(); + if (zend_string_equals_literal(protocol_version, "1") || + zend_string_equals_literal(protocol_version, "1.0")) { + uint8_t formatted_runtime_id[36]; + datadog_format_runtime_id(&formatted_runtime_id); + zend_string *process_tags = datadog_process_tags_get_serialized(); + ddog_TracerMetadataV1 metadata = { + .hostname = dd_zend_string_to_CharSlice(get_DD_HOSTNAME()), + .env = dd_zend_string_to_CharSlice(get_DD_ENV()), + .app_version = dd_zend_string_to_CharSlice(get_DD_VERSION()), + .runtime_id = (ddog_CharSlice) {.ptr = (char *) formatted_runtime_id, .len = sizeof(formatted_runtime_id)}, + .service = dd_zend_string_to_CharSlice(get_DD_SERVICE()), + .tracer_version = DDOG_CHARSLICE_C_BARE(PHP_DDTRACE_VERSION), + .language_name = DDOG_CHARSLICE_C_BARE("php"), + .language_version = php_version_rt, + .language_interpreter = (ddog_CharSlice) {.ptr = sapi_module.name, .len = strlen(sapi_module.name)}, + .language_interpreter_vendor = DDOG_CHARSLICE_C_BARE(""), + .git_commit_sha = dd_zend_string_to_CharSlice(get_DD_GIT_COMMIT_SHA()), + .process_tags = dd_zend_string_to_CharSlice(process_tags), + }; + ddog_send_traces_to_sidecar_v1(traces, ¶meters, &metadata); + } else { + ddog_send_traces_to_sidecar(traces, ¶meters); + } } else { LOGEV(INFO, { log("Skipping flushing trace as connection to sidecar failed"); diff --git a/tracer/configuration.h b/tracer/configuration.h index 4bf4312f8da..d73a11201cd 100644 --- a/tracer/configuration.h +++ b/tracer/configuration.h @@ -113,6 +113,7 @@ CONFIG(INT, DD_TRACE_BGS_TIMEOUT, DD_CFG_EXPSTR(DD_TRACE_BGS_TIMEOUT_VAL), \ .ini_change = zai_config_system_ini_change) \ CONFIG(INT, DD_TRACE_AGENT_FLUSH_AFTER_N_REQUESTS, "0") \ + CONFIG(STRING, DD_TRACE_AGENT_PROTOCOL_VERSION, "0.4", .ini_change = zai_config_system_ini_change) \ CONFIG(INT, DD_TRACE_AGENT_RETRIES, "0", .ini_change = zai_config_system_ini_change) \ CONFIG(BOOL, DD_TRACE_AGENT_DEBUG_VERBOSE_CURL, "false", .ini_change = zai_config_system_ini_change) \ CONFIG(BOOL, DD_TRACE_DEBUG_CURL_OUTPUT, "false", .ini_change = zai_config_system_ini_change) \ From 8235cf289b11ea4b756c17e7f575e33b0f448cbf Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 3 Aug 2026 17:44:50 +0200 Subject: [PATCH 14/32] feat(tracer): emit native span links/events on the v1 path --- tracer/serializer.c | 152 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 144 insertions(+), 8 deletions(-) diff --git a/tracer/serializer.c b/tracer/serializer.c index fb718410d35..6bc7e165fdf 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -41,6 +41,7 @@ #include "ip_extraction.h" #include #include "priority_sampling/priority_sampling.h" +#include "random.h" #include "span.h" #include "uri_normalization.h" #include "user_request.h" @@ -1087,6 +1088,131 @@ static void dd_serialize_span_events(zend_array *events, smart_str *buf) { zval_ptr_dtor(&tmp); } +// --- Native V1 span links/events (DD_TRACE_AGENT_PROTOCOL_VERSION=1/1.0) --- +// On the V1 wire, links/events are emitted into libdatadog's native span structures +// (span_links field 11, span_events field 12) rather than the JSON-in-meta V0.4 form. + +static bool dd_v1_native_span_enabled(void) { + zend_string *pv = get_global_DD_TRACE_AGENT_PROTOCOL_VERSION(); + return zend_string_equals_literal(pv, "1") || zend_string_equals_literal(pv, "1.0"); +} + +// Emit each SpanLink into the native span. trace_id/span_id are hex strings; the V1 link +// wire has no flags source on the PHP side and no dropped_attributes_count field, so both +// are omitted. Link attributes are a string map. +static void dd_span_links_to_native(zend_array *links, ddog_SpanBytes *rust_span) { + zval *val; + ZEND_HASH_FOREACH_VAL(links, val) { + ZVAL_DEREF(val); + if (Z_TYPE_P(val) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(val), ddtrace_ce_span_link)) { + continue; + } + ddtrace_span_link *link = (ddtrace_span_link *)Z_OBJ_P(val); + ddog_SpanLinkBytes *rust_link = ddog_span_new_link(rust_span); + + zval *tid = &link->property_trace_id; + if (Z_TYPE_P(tid) == IS_STRING) { + datadog_trace_id id = ddtrace_parse_hex_trace_id(Z_STRVAL_P(tid), Z_STRLEN_P(tid)); + ddog_set_link_trace_id(rust_link, id.low); + ddog_set_link_trace_id_high(rust_link, id.high); + } + ddog_set_link_span_id(rust_link, ddtrace_parse_hex_span_id(&link->property_span_id)); + + zval *ts = &link->property_trace_state; + if (Z_TYPE_P(ts) == IS_STRING && Z_STRLEN_P(ts) > 0) { + ddog_set_link_tracestate(rust_link, dd_zend_string_to_CharSlice(Z_STR_P(ts))); + } + + zval *attrs = &link->property_attributes; + ZVAL_DEREF(attrs); + if (Z_TYPE_P(attrs) == IS_ARRAY) { + zend_ulong idx; + zend_string *key; + zval *aval; + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(attrs), idx, key, aval) { + char numbuf[24]; + ddog_CharSlice kslice = key + ? dd_zend_string_to_CharSlice(key) + : (ddog_CharSlice){ .ptr = numbuf, .len = snprintf(numbuf, sizeof(numbuf), ZEND_ULONG_FMT, idx) }; + ZVAL_DEREF(aval); + zend_string *sval = datadog_convert_to_str(aval); + ddog_add_link_attributes(rust_link, kslice, dd_zend_string_to_CharSlice(sval)); + zend_string_release(sval); + } ZEND_HASH_FOREACH_END(); + } + } ZEND_HASH_FOREACH_END(); +} + +// Dispatch a single event attribute to the typed native setter based on its zval type. +static void dd_event_attribute_to_native(ddog_SpanEventBytes *event, ddog_CharSlice key, zval *val) { + ZVAL_DEREF(val); + switch (Z_TYPE_P(val)) { + case IS_TRUE: ddog_add_event_attributes_bool(event, key, true); break; + case IS_FALSE: ddog_add_event_attributes_bool(event, key, false); break; + case IS_LONG: ddog_add_event_attributes_int(event, key, Z_LVAL_P(val)); break; + case IS_DOUBLE: ddog_add_event_attributes_float(event, key, Z_DVAL_P(val)); break; + default: { + zend_string *s = datadog_convert_to_str(val); + ddog_add_event_attributes_str(event, key, dd_zend_string_to_CharSlice(s)); + zend_string_release(s); + } + } +} + +// Emit each SpanEvent into the native span, dispatching attributes by type. ExceptionSpanEvent +// flattens exception.message/type/stacktrace as string attributes (mirrors dd_span_event_to_array). +static void dd_span_events_to_native(zend_array *events, ddog_SpanBytes *rust_span) { + zval *val; + ZEND_HASH_FOREACH_VAL(events, val) { + ZVAL_DEREF(val); + if (Z_TYPE_P(val) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(val), ddtrace_ce_span_event)) { + continue; + } + ddtrace_span_event *event = (ddtrace_span_event *)Z_OBJ_P(val); + ddog_SpanEventBytes *rust_event = ddog_span_new_event(rust_span); + + zval *name = &event->property_name; + if (Z_TYPE_P(name) == IS_STRING) { + ddog_set_event_name(rust_event, dd_zend_string_to_CharSlice(Z_STR_P(name))); + } + zval *time = &event->property_timestamp; + ZVAL_DEREF(time); + if (Z_TYPE_P(time) == IS_LONG) { + ddog_set_event_time(rust_event, (uint64_t)Z_LVAL_P(time)); + } + + if (instanceof_function(event->std.ce, ddtrace_ce_exception_span_event)) { + ddtrace_exception_span_event *exc_event = (ddtrace_exception_span_event *)event; + zval *exception = &exc_event->property_exception; + if (Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), zend_ce_throwable)) { + zend_string *message = zai_exception_message(Z_OBJ_P(exception)); + if (ZSTR_LEN(message)) { + ddog_add_event_attributes_str(rust_event, DDOG_CHARSLICE_C("exception.message"), dd_zend_string_to_CharSlice(message)); + } + ddog_add_event_attributes_str(rust_event, DDOG_CHARSLICE_C("exception.type"), dd_zend_string_to_CharSlice(Z_OBJCE_P(exception)->name)); + zend_string *stacktrace = zai_get_trace_without_args_from_exception(Z_OBJ_P(exception)); + ddog_add_event_attributes_str(rust_event, DDOG_CHARSLICE_C("exception.stacktrace"), dd_zend_string_to_CharSlice(stacktrace)); + zend_string_release(stacktrace); + } + } + + zval *attrs = &event->property_attributes; + ZVAL_DEREF(attrs); + if (Z_TYPE_P(attrs) == IS_ARRAY) { + zend_ulong idx; + zend_string *key; + zval *aval; + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(attrs), idx, key, aval) { + char numbuf[24]; + ddog_CharSlice kslice = key + ? dd_zend_string_to_CharSlice(key) + : (ddog_CharSlice){ .ptr = numbuf, .len = snprintf(numbuf, sizeof(numbuf), ZEND_ULONG_FMT, idx) }; + dd_event_attribute_to_native(rust_event, kslice, aval); + } ZEND_HASH_FOREACH_END(); + } + } ZEND_HASH_FOREACH_END(); +} + static void dd_serialize_array_recursively(ddog_SpanBytes *target, zend_string *str, zval *value, bool convert_to_double) { ZVAL_DEREF(value); @@ -1804,14 +1930,20 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo ddtrace_exception_to_meta(Z_OBJ_P(exception_zv), pre.service ? pre.service : ZSTR_EMPTY_ALLOC(), span->start, rust_span, exception_type); } + bool v1_native = dd_v1_native_span_enabled(); + zend_array *span_links = ddtrace_property_array(&span->property_links); if (zend_hash_num_elements(span_links) > 0) { zend_object *current_exception = EG(exception); EG(exception) = NULL; - smart_str buf = {0}; - dd_serialize_span_links(span_links, &buf); - ddog_add_str_span_meta_zstr(rust_span, "_dd.span_links", buf.s); - smart_str_free(&buf); + if (v1_native) { + dd_span_links_to_native(span_links, rust_span); + } else { + smart_str buf = {0}; + dd_serialize_span_links(span_links, &buf); + ddog_add_str_span_meta_zstr(rust_span, "_dd.span_links", buf.s); + smart_str_free(&buf); + } EG(exception) = current_exception; } @@ -1819,10 +1951,14 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo if (zend_hash_num_elements(span_events) > 0) { zend_object *current_exception = EG(exception); EG(exception) = NULL; - smart_str buf = {0}; - dd_serialize_span_events(span_events, &buf); - ddog_add_str_span_meta_zstr(rust_span, "events", buf.s); - smart_str_free(&buf); + if (v1_native) { + dd_span_events_to_native(span_events, rust_span); + } else { + smart_str buf = {0}; + dd_serialize_span_events(span_events, &buf); + ddog_add_str_span_meta_zstr(rust_span, "events", buf.s); + smart_str_free(&buf); + } EG(exception) = current_exception; } From 3191f429f0e36b3db8efdfac83c5a8328ec1ed2f Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 3 Aug 2026 18:24:12 +0200 Subject: [PATCH 15/32] feat(tracer): negotiate v1 via agent /info with v04 fallback --- components-rs/agent_info.rs | 27 ++++++++++++++++++++++++++- components-rs/datadog.h | 10 ++++++++++ tracer/auto_flush.c | 15 ++++++++++----- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/components-rs/agent_info.rs b/components-rs/agent_info.rs index b157922e3a2..13e2e92a218 100644 --- a/components-rs/agent_info.rs +++ b/components-rs/agent_info.rs @@ -10,7 +10,7 @@ use crate::stats::apply_concentrator_config; use datadog_sidecar::service::agent_info::AgentInfoReader; -use libdd_common_ffi::slice::CharSlice; +use libdd_common_ffi::slice::{AsBytes, CharSlice}; use libdd_data_pipeline::agent_info::schema::AgentInfoStruct; use std::ffi::c_char; use std::ffi::CString; @@ -96,6 +96,31 @@ pub extern "C" fn ddog_agent_info_json_free(ptr: *mut c_char) { } } +/// Returns true when the agent /info `endpoints` list advertises `endpoint` +/// (e.g. `/v1.0/traces`). Returns false when no info has been received yet, so the +/// caller safely treats "agent info unknown" as "endpoint not advertised". +/// +/// # Safety +/// `reader` must be a valid pointer to an `AgentInfoReader`. +#[no_mangle] +pub unsafe extern "C" fn ddog_agent_info_has_endpoint( + reader: &mut AgentInfoReader, + endpoint: CharSlice, +) -> bool { + let (changed, info) = reader.read(); + if let Some(info) = info { + if changed { + info_to_concentrator_config(info); + } + let endpoint = endpoint.as_bytes(); + return info + .endpoints + .as_deref() + .map_or(false, |eps| eps.iter().any(|e| e.as_bytes() == endpoint)); + } + false +} + /// Apply concentrator config changes from the agent /info SHM. /// /// Cheap no-op when the SHM has not changed (`changed == false`). Only applies when diff --git a/components-rs/datadog.h b/components-rs/datadog.h index 49cd76dd448..2cca38ca986 100644 --- a/components-rs/datadog.h +++ b/components-rs/datadog.h @@ -120,6 +120,16 @@ char *ddog_agent_info_as_json(struct ddog_AgentInfoReader *reader); void ddog_agent_info_json_free(char *ptr); +/** + * Returns true when the agent /info `endpoints` list advertises `endpoint` + * (e.g. `/v1.0/traces`). Returns false when no info has been received yet, so the + * caller safely treats "agent info unknown" as "endpoint not advertised". + * + * # Safety + * `reader` must be a valid pointer to an `AgentInfoReader`. + */ +bool ddog_agent_info_has_endpoint(struct ddog_AgentInfoReader *reader, ddog_CharSlice endpoint); + /** * Apply concentrator config changes from the agent /info SHM. * diff --git a/tracer/auto_flush.c b/tracer/auto_flush.c index c1d931e81bf..205f31fcf98 100644 --- a/tracer/auto_flush.c +++ b/tracer/auto_flush.c @@ -69,12 +69,17 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles .buffer_size = get_global_DD_TRACE_BUFFER_SIZE(), .url = (ddog_CharSlice) {.ptr = url, .len = strlen(url)}, }; - // Hard gate on DD_TRACE_AGENT_PROTOCOL_VERSION (no /info negotiation yet in this - // cut): "1"/"1.0" selects the V1 wire (POST /v1.0/traces); anything else (default - // "0.4") keeps the unchanged V0.4 path. + // V1 wire (POST /v1.0/traces) is used only when BOTH the config resolves to + // "1"/"1.0" AND the agent /info advertises "/v1.0/traces". Otherwise (default + // "0.4", explicit 1.0 but agent doesn't advertise it, or agent info not yet + // known) fall back to the unchanged V0.4 path -- the safe default. zend_string *protocol_version = get_global_DD_TRACE_AGENT_PROTOCOL_VERSION(); - if (zend_string_equals_literal(protocol_version, "1") || - zend_string_equals_literal(protocol_version, "1.0")) { + bool use_v1 = (zend_string_equals_literal(protocol_version, "1") || + zend_string_equals_literal(protocol_version, "1.0")) && + DATADOG_G(agent_info_reader) && + ddog_agent_info_has_endpoint(DATADOG_G(agent_info_reader), + DDOG_CHARSLICE_C("/v1.0/traces")); + if (use_v1) { uint8_t formatted_runtime_id[36]; datadog_format_runtime_id(&formatted_runtime_id); zend_string *process_tags = datadog_process_tags_get_serialized(); From afc4e4662bfc54eb64fd20a11f4bf28f569707e7 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Tue, 4 Aug 2026 12:23:31 +0200 Subject: [PATCH 16/32] chore: regenerate supported-configurations.json for DD_TRACE_AGENT_PROTOCOL_VERSION --- metadata/supported-configurations.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index 1f27e844ae2..feb1c0ecdd8 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -777,6 +777,13 @@ "default": "8126" } ], + "DD_TRACE_AGENT_PROTOCOL_VERSION": [ + { + "implementation": "A", + "type": "string", + "default": "0.4" + } + ], "DD_TRACE_AGENT_RETRIES": [ { "implementation": "A", From 318ff434f50284e1aa651e852e6e8d4c770c903f Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Wed, 5 Aug 2026 18:12:14 +0200 Subject: [PATCH 17/32] chore(tracer): tighten v1 comments --- components-rs/agent_info.rs | 5 ++--- tracer/auto_flush.c | 6 ++---- tracer/dogstatsd_client.c | 1 - tracer/serializer.c | 9 +++------ 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/components-rs/agent_info.rs b/components-rs/agent_info.rs index 13e2e92a218..aac5b1c4608 100644 --- a/components-rs/agent_info.rs +++ b/components-rs/agent_info.rs @@ -96,9 +96,8 @@ pub extern "C" fn ddog_agent_info_json_free(ptr: *mut c_char) { } } -/// Returns true when the agent /info `endpoints` list advertises `endpoint` -/// (e.g. `/v1.0/traces`). Returns false when no info has been received yet, so the -/// caller safely treats "agent info unknown" as "endpoint not advertised". +/// Returns whether the agent /info `endpoints` list advertises `endpoint` (e.g. `/v1.0/traces`); +/// false when no info has been received yet ("unknown" == "not advertised"). /// /// # Safety /// `reader` must be a valid pointer to an `AgentInfoReader`. diff --git a/tracer/auto_flush.c b/tracer/auto_flush.c index 205f31fcf98..b06a75107d6 100644 --- a/tracer/auto_flush.c +++ b/tracer/auto_flush.c @@ -69,10 +69,8 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles .buffer_size = get_global_DD_TRACE_BUFFER_SIZE(), .url = (ddog_CharSlice) {.ptr = url, .len = strlen(url)}, }; - // V1 wire (POST /v1.0/traces) is used only when BOTH the config resolves to - // "1"/"1.0" AND the agent /info advertises "/v1.0/traces". Otherwise (default - // "0.4", explicit 1.0 but agent doesn't advertise it, or agent info not yet - // known) fall back to the unchanged V0.4 path -- the safe default. + // Use the V1 wire only when the protocol config is "1"/"1.0" AND the agent /info + // advertises "/v1.0/traces"; otherwise fall back to the default V0.4 path. zend_string *protocol_version = get_global_DD_TRACE_AGENT_PROTOCOL_VERSION(); bool use_v1 = (zend_string_equals_literal(protocol_version, "1") || zend_string_equals_literal(protocol_version, "1.0")) && diff --git a/tracer/dogstatsd_client.c b/tracer/dogstatsd_client.c index 6574acce1fa..306e2ece05a 100644 --- a/tracer/dogstatsd_client.c +++ b/tracer/dogstatsd_client.c @@ -1,4 +1,3 @@ -// TODO: remove this file and put it in the sidecar. #include "dogstatsd_client.h" #include diff --git a/tracer/serializer.c b/tracer/serializer.c index 6bc7e165fdf..32f6aadb5bd 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -1089,17 +1089,15 @@ static void dd_serialize_span_events(zend_array *events, smart_str *buf) { } // --- Native V1 span links/events (DD_TRACE_AGENT_PROTOCOL_VERSION=1/1.0) --- -// On the V1 wire, links/events are emitted into libdatadog's native span structures -// (span_links field 11, span_events field 12) rather than the JSON-in-meta V0.4 form. +// On the V1 wire these go into libdatadog's native span structures, not the V0.4 JSON-in-meta form. static bool dd_v1_native_span_enabled(void) { zend_string *pv = get_global_DD_TRACE_AGENT_PROTOCOL_VERSION(); return zend_string_equals_literal(pv, "1") || zend_string_equals_literal(pv, "1.0"); } -// Emit each SpanLink into the native span. trace_id/span_id are hex strings; the V1 link -// wire has no flags source on the PHP side and no dropped_attributes_count field, so both -// are omitted. Link attributes are a string map. +// Emit each SpanLink into the native span. The V1 link wire omits flags and +// dropped_attributes_count (no PHP-side source); attributes are a string map. static void dd_span_links_to_native(zend_array *links, ddog_SpanBytes *rust_span) { zval *val; ZEND_HASH_FOREACH_VAL(links, val) { @@ -1143,7 +1141,6 @@ static void dd_span_links_to_native(zend_array *links, ddog_SpanBytes *rust_span } ZEND_HASH_FOREACH_END(); } -// Dispatch a single event attribute to the typed native setter based on its zval type. static void dd_event_attribute_to_native(ddog_SpanEventBytes *event, ddog_CharSlice key, zval *val) { ZVAL_DEREF(val); switch (Z_TYPE_P(val)) { From 0d3d03d6f715663273022f16a9540c01c30d69cd Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 24 Aug 2026 17:11:46 +0200 Subject: [PATCH 18/32] chore: regenerate cbindgen headers and Cargo.lock for libdatadog v1 FFI Regenerate components-rs/*.h and Cargo.lock against the rebased libdatadog submodule (v1 send FFI branch merged with libdatadog main). Picks up the RemoteConfig DEBUG product enum, the v1 FFI comment trims, the agent_info doc-comment tightening, and the zrip/ring lockfile additions. --- Cargo.lock | 40 ++++++++++++++++++++++++++++++++++++++++ components-rs/common.h | 5 ++--- components-rs/datadog.h | 5 ++--- components-rs/sidecar.h | 6 ++---- 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 057c1e06aa4..6d512f8c6cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2922,6 +2922,7 @@ dependencies = [ "tracing", "uuid", "web-time", + "zrip", "zstd", ] @@ -3129,6 +3130,7 @@ dependencies = [ "thiserror 2.0.18", "tokio", "tokio-util", + "zrip", "zstd", ] @@ -3151,6 +3153,7 @@ dependencies = [ "chrono", "futures", "futures-util", + "getrandom 0.2.15", "hashbrown 0.15.2", "http 1.4.2", "http-body-util", @@ -3165,6 +3168,7 @@ dependencies = [ "manual_future", "prost", "rand 0.8.5", + "ring", "serde", "serde_json", "serde_with", @@ -3375,6 +3379,7 @@ dependencies = [ "tokio", "tracing", "urlencoding", + "zrip", "zstd", ] @@ -7203,6 +7208,41 @@ version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +[[package]] +name = "zrip" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964fe9f1ea10a0d183fc143a7525266cbe16978883dbe304725da34b314c04cf" +dependencies = [ + "zrip-core", + "zrip-decode", + "zrip-encode", +] + +[[package]] +name = "zrip-core" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc201ba56175f86e67cc88bdaf1a7af9c061815c7dde719c7a6a1ed5aaa186b" + +[[package]] +name = "zrip-decode" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038f795e49887bdeaab197fff84c8165644484a98dc3f2354e5df3d2e5f4f978" +dependencies = [ + "zrip-core", +] + +[[package]] +name = "zrip-encode" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3dfdcbb503db2045716492d5ab31cd82f2852d0d93d8edf6a9235653d9da685" +dependencies = [ + "zrip-core", +] + [[package]] name = "zstd" version = "0.13.3" diff --git a/components-rs/common.h b/components-rs/common.h index 4ffeb5b0377..ef66412f790 100644 --- a/components-rs/common.h +++ b/components-rs/common.h @@ -437,6 +437,7 @@ typedef enum ddog_RemoteConfigProduct { DDOG_REMOTE_CONFIG_PRODUCT_FFE_FLAGS, DDOG_REMOTE_CONFIG_PRODUCT_LIVE_DEBUGGING, DDOG_REMOTE_CONFIG_PRODUCT_LIVE_DEBUGGING_SYMBOL_DB, + DDOG_REMOTE_CONFIG_PRODUCT_DEBUG, } ddog_RemoteConfigProduct; typedef enum ddog_SpanProbeTarget { @@ -1353,9 +1354,7 @@ typedef struct ddog_SenderParameters { } ddog_SenderParameters; /** - * Payload-level tracer metadata consumed by the V1 msgpack encoder. Each field mirrors the - * corresponding field on `libdd_trace_utils::tracer_metadata::TracerMetadata`; empty slices are - * tolerated (the encoder falls back to span meta / omits the field). + * Payload-level tracer metadata for the V1 msgpack encoder; mirrors `TracerMetadata`. */ typedef struct ddog_TracerMetadataV1 { ddog_CharSlice hostname; diff --git a/components-rs/datadog.h b/components-rs/datadog.h index 2cca38ca986..f1c63781b9c 100644 --- a/components-rs/datadog.h +++ b/components-rs/datadog.h @@ -121,9 +121,8 @@ char *ddog_agent_info_as_json(struct ddog_AgentInfoReader *reader); void ddog_agent_info_json_free(char *ptr); /** - * Returns true when the agent /info `endpoints` list advertises `endpoint` - * (e.g. `/v1.0/traces`). Returns false when no info has been received yet, so the - * caller safely treats "agent info unknown" as "endpoint not advertised". + * Returns whether the agent /info `endpoints` list advertises `endpoint` (e.g. `/v1.0/traces`); + * false when no info has been received yet ("unknown" == "not advertised"). * * # Safety * `reader` must be a valid pointer to an `AgentInfoReader`. diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 22ae34b25e6..31172086d67 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -498,10 +498,8 @@ void ddog_send_traces_to_sidecar(ddog_TracesBytes *traces, struct ddog_SenderParameters *parameters); /** - * Encodes `traces` as a V1 msgpack `TracerPayload` (using `metadata` for the payload-level - * fields) and sends it to the sidecar, which re-encodes it for the agent's `/v1.0/traces` - * endpoint. Mirrors `ddog_send_traces_to_sidecar` (v04) for the SHM allocation, per-span dedup, - * `size_hint` derivation and the shm→bytes send fallback. + * V1 counterpart of `ddog_send_traces_to_sidecar`: encodes `traces` as a V1 `TracerPayload` + * using `metadata`, then sends it to the sidecar for the agent's `/v1.0/traces` endpoint. */ void ddog_send_traces_to_sidecar_v1(ddog_TracesBytes *traces, struct ddog_SenderParameters *parameters, From 409a01afa20556f16dafa6f09a88a5bf52ff73f9 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Wed, 26 Aug 2026 17:37:52 +0200 Subject: [PATCH 19/32] feat(tracer): build & send native v1 traces on the sidecar path Stages 3+4 of the v1-native migration. The sidecar sender now always builds a native libdatadog v1 TracerPayload via the new builder FFI and sends it with ddog_send_traces_to_sidecar_v1; the sidecar negotiates v1-vs-v0.4 with the agent and downgrades as needed, so the tracer-side DD_TRACE_AGENT_PROTOCOL_VERSION gate is removed. - serializer.c: convert each fully-built v0.4 span into the v1 builder (fields and meta/metrics/meta_struct via the v0.4 read getters, native links/events from the still-alive PHP span). Promoted fields (env/version/component/ span.kind) use the dedicated setters and are excluded from the attribute map; chunk-level fields (sampling priority/origin/mechanism/128-bit trace-id/ dropped) are routed to the chunk. Array/object attribute values, which have no native v1 attribute variant, are preserved as a JSON string. The v0.4 build stays byte-identical for the in-process sender and functions.c introspection. - auto_flush.c: sidecar path always builds the v1 builder and sends v1; shrunk ddog_TracerMetadataV1 {hostname,env,app_version,runtime_id,git_commit_sha}. The in-process sender (PHP <= 8.2) stays on v0.4, unchanged. - Remove the now-dead DD_TRACE_AGENT_PROTOCOL_VERSION config key and the ddog_agent_info_has_endpoint getter; regenerate datadog.h and supported-configurations.json. - Bump libdatadog to the v1 send FFI (317c98d28) and regenerate cbindgen headers. Add a hand-written prototypes header (sidecar_v1_macro_ffi.h) for the macro-generated v1 setters that cbindgen cannot emit. - Update the request-replayer span-event tests to assert native span events. --- components-rs/agent_info.rs | 24 -- components-rs/common.h | 17 +- components-rs/datadog.h | 9 - components-rs/sidecar.h | 220 ++++++++++++++- components-rs/sidecar_v1_macro_ffi.h | 72 +++++ libdatadog | 2 +- metadata/supported-configurations.json | 7 - .../dd_trace_exception_span_event.phpt | 21 +- .../request-replayer/dd_trace_span_event.phpt | 18 +- tracer/auto_flush.c | 61 ++-- tracer/configuration.h | 1 - tracer/functions.c | 2 +- tracer/serializer.c | 266 ++++++++++++++---- tracer/serializer.h | 2 +- tracer/span.c | 11 +- tracer/span.h | 14 +- 16 files changed, 588 insertions(+), 159 deletions(-) create mode 100644 components-rs/sidecar_v1_macro_ffi.h diff --git a/components-rs/agent_info.rs b/components-rs/agent_info.rs index aac5b1c4608..dceffde6c11 100644 --- a/components-rs/agent_info.rs +++ b/components-rs/agent_info.rs @@ -96,30 +96,6 @@ pub extern "C" fn ddog_agent_info_json_free(ptr: *mut c_char) { } } -/// Returns whether the agent /info `endpoints` list advertises `endpoint` (e.g. `/v1.0/traces`); -/// false when no info has been received yet ("unknown" == "not advertised"). -/// -/// # Safety -/// `reader` must be a valid pointer to an `AgentInfoReader`. -#[no_mangle] -pub unsafe extern "C" fn ddog_agent_info_has_endpoint( - reader: &mut AgentInfoReader, - endpoint: CharSlice, -) -> bool { - let (changed, info) = reader.read(); - if let Some(info) = info { - if changed { - info_to_concentrator_config(info); - } - let endpoint = endpoint.as_bytes(); - return info - .endpoints - .as_deref() - .map_or(false, |eps| eps.iter().any(|e| e.as_bytes() == endpoint)); - } - false -} - /// Apply concentrator config changes from the agent /info SHM. /// /// Cheap no-op when the SHM has not changed (`changed == false`). Only applies when diff --git a/components-rs/common.h b/components-rs/common.h index ef66412f790..42b16ccef90 100644 --- a/components-rs/common.h +++ b/components-rs/common.h @@ -1209,6 +1209,11 @@ typedef struct ddog_RuntimeMetadata ddog_RuntimeMetadata; typedef struct ddog_ShmHandle ddog_ShmHandle; +/** + * Builds a native V1 [`TracerPayloadBytes`] while interning every string once. + */ +typedef struct ddog_TracerPayloadV1Builder ddog_TracerPayloadV1Builder; + typedef struct ddog_NativeFile { struct ddog_PlatformHandle_File *handle; } ddog_NativeFile; @@ -1354,21 +1359,17 @@ typedef struct ddog_SenderParameters { } ddog_SenderParameters; /** - * Payload-level tracer metadata for the V1 msgpack encoder; mirrors `TracerMetadata`. + * Payload-level tracer metadata for the V1 send path that is NOT already carried by the sender's + * `tracer_headers_tags`. The lang/lang_version/lang_interpreter/lang_vendor/tracer_version and + * container_id fields live in `SenderParameters::tracer_headers_tags` and are routed from there, + * so they are not duplicated here. */ typedef struct ddog_TracerMetadataV1 { ddog_CharSlice hostname; ddog_CharSlice env; ddog_CharSlice app_version; ddog_CharSlice runtime_id; - ddog_CharSlice service; - ddog_CharSlice tracer_version; - ddog_CharSlice language_name; - ddog_CharSlice language_version; - ddog_CharSlice language_interpreter; - ddog_CharSlice language_interpreter_vendor; ddog_CharSlice git_commit_sha; - ddog_CharSlice process_tags; } ddog_TracerMetadataV1; typedef enum ddog_crasht_BuildIdType { diff --git a/components-rs/datadog.h b/components-rs/datadog.h index f1c63781b9c..49cd76dd448 100644 --- a/components-rs/datadog.h +++ b/components-rs/datadog.h @@ -120,15 +120,6 @@ char *ddog_agent_info_as_json(struct ddog_AgentInfoReader *reader); void ddog_agent_info_json_free(char *ptr); -/** - * Returns whether the agent /info `endpoints` list advertises `endpoint` (e.g. `/v1.0/traces`); - * false when no info has been received yet ("unknown" == "not advertised"). - * - * # Safety - * `reader` must be a valid pointer to an `AgentInfoReader`. - */ -bool ddog_agent_info_has_endpoint(struct ddog_AgentInfoReader *reader, ddog_CharSlice endpoint); - /** * Apply concentrator config changes from the agent /info SHM. * diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 31172086d67..dad9982c73d 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -498,10 +498,16 @@ void ddog_send_traces_to_sidecar(ddog_TracesBytes *traces, struct ddog_SenderParameters *parameters); /** - * V1 counterpart of `ddog_send_traces_to_sidecar`: encodes `traces` as a V1 `TracerPayload` - * using `metadata`, then sends it to the sidecar for the agent's `/v1.0/traces` endpoint. + * V1 counterpart of `ddog_send_traces_to_sidecar`: encodes the native V1 `TracerPayload` built via + * the [`crate::span_v1`] builder (natively, without the v0.4→v1 upgrade converter), then sends it + * to the sidecar for the agent's `/v1.0/traces` endpoint. Consumes `builder`. + * + * Payload-level metadata is sourced at send time: the lang/lang_version/tracer_version and + * container_id come from `parameters.tracer_headers_tags`, while hostname/env/app_version/ + * runtime_id/git_commit_sha come from `metadata`. lang_interpreter/lang_vendor are forwarded to + * the sidecar as HTTP header tags (they are not part of the V1 wire payload). */ -void ddog_send_traces_to_sidecar_v1(ddog_TracesBytes *traces, +void ddog_send_traces_to_sidecar_v1(struct ddog_TracerPayloadV1Builder *builder, struct ddog_SenderParameters *parameters, const struct ddog_TracerMetadataV1 *metadata); @@ -671,4 +677,212 @@ void ddog_add_event_attributes_float(ddog_SpanEventBytes *event, ddog_CharSlice */ ddog_CharSlice ddog_serialize_trace_into_charslice(ddog_TraceBytes *trace); +/** + * Creates a new, empty V1 payload builder. Free it with [`ddog_v1_free_builder`], or hand it to + * `ddog_send_traces_to_sidecar_v1`, which consumes it. + */ +struct ddog_TracerPayloadV1Builder *ddog_v1_new_builder(void); + +/** + * Frees a V1 payload builder. + */ +void ddog_v1_free_builder(struct ddog_TracerPayloadV1Builder *_builder); + +/** + * Interns `string` into the builder's value-keyed table and returns its stable id. Equal strings + * (including across chunks/spans) always return the same id; the empty string is always id 0. + */ +uint32_t ddog_v1_intern_string(struct ddog_TracerPayloadV1Builder *builder, ddog_CharSlice string); + +/** + * Appends a new (empty) chunk with the given 128-bit trace id, returning its index. + * + * A chunk must be fully built (all its spans/links/events) before the next chunk is created: + * creating a chunk may reallocate the chunk vector and invalidate positions cached as raw + * pointers. Indices remain valid. + */ +uintptr_t ddog_v1_builder_new_chunk(struct ddog_TracerPayloadV1Builder *builder, + uint64_t trace_id_high, + uint64_t trace_id_low); + +/** + * Sets the chunk sampling priority (v0.4 `_sampling_priority_v1`). + */ +void ddog_v1_set_chunk_sampling_priority(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + int32_t priority); + +/** + * Sets the chunk origin (v0.4 `_dd.origin`) from an interned id. + */ +void ddog_v1_set_chunk_origin(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uint32_t origin_id); + +/** + * Sets the chunk sampling mechanism (v0.4 `_dd.p.dm`). + */ +void ddog_v1_set_chunk_sampling_mechanism(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uint32_t mechanism); + +/** + * Marks the chunk as a dropped (p0) trace. + */ +void ddog_v1_set_chunk_dropped_trace(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + bool dropped); + +/** + * Adds a string-valued chunk-level attribute (key and value are interned ids). + */ +void ddog_v1_add_chunk_attr_str(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uint32_t key_id, + uint32_t value_id); + +/** + * Appends a new (empty) span to `chunk`, returning its index within that chunk. + * + * A span must be fully built before the next span is created in the same chunk. + */ +uintptr_t ddog_v1_chunk_new_span(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk); + +/** + * Sets the span id. + */ +void ddog_v1_set_span_id(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint64_t value); + +/** + * Sets the span parent id. + */ +void ddog_v1_set_span_parent_id(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint64_t value); + +/** + * Sets the span start time (unix nanos; negative values are normalized at encode time). + */ +void ddog_v1_set_span_start(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + int64_t value); + +/** + * Sets the span duration (nanos). + */ +void ddog_v1_set_span_duration(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + int64_t value); + +/** + * Sets the span error flag. + */ +void ddog_v1_set_span_error(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + bool error); + +/** + * Sets the span kind (OTEL wire value; unset/unknown → Internal). + */ +void ddog_v1_set_span_kind(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t kind); + +/** + * Adds a bytes-valued span attribute. The key is an interned id; the value bytes are copied + * verbatim (not interned) and encoded as msgpack `bin`. + */ +void ddog_v1_add_span_attr_bytes(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t key_id, + ddog_CharSlice value); + +/** + * Appends a new (empty) link to a span, returning its index within that span. + */ +uintptr_t ddog_v1_span_new_link(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * Sets the link's 128-bit trace id (high/low halves). + */ +void ddog_v1_set_link_trace_id(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link, + uint64_t trace_id_high, + uint64_t trace_id_low); + +/** + * Sets the link span id. + */ +void ddog_v1_set_link_span_id(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link, + uint64_t value); + +/** + * Sets the link flags (W3C trace-flags plus the "set" sentinel bit). + */ +void ddog_v1_set_link_flags(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link, + uint32_t value); + +/** + * Sets the link tracestate (interned id). + */ +void ddog_v1_set_link_tracestate(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link, + uint32_t id); + +/** + * Adds a string-valued link attribute (key and value are interned ids). + */ +void ddog_v1_add_link_attr_str(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link, + uint32_t key_id, + uint32_t value_id); + +/** + * Appends a new (empty) event to a span, returning its index within that span. + */ +uintptr_t ddog_v1_span_new_event(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * Sets the event time (unix nanos). + */ +void ddog_v1_set_event_time(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uint64_t time_unix_nano); + +/** + * Sets the event name (interned id). + */ +void ddog_v1_set_event_name(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uint32_t id); + #endif /* DDOG_SIDECAR_H */ diff --git a/components-rs/sidecar_v1_macro_ffi.h b/components-rs/sidecar_v1_macro_ffi.h new file mode 100644 index 00000000000..2c577e21695 --- /dev/null +++ b/components-rs/sidecar_v1_macro_ffi.h @@ -0,0 +1,72 @@ +// Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +// Hand-written prototypes for the V1 payload-builder FFI functions that are +// generated by declarative macros (`span_str_setter!`, `span_attr_setter!`, +// `event_attr_setter!`) in libdatadog's `datadog-sidecar-ffi/src/span_v1.rs`. +// +// cbindgen does not expand macro invocations, so these `#[no_mangle] pub extern +// "C"` symbols exist in the compiled library but are absent from the generated +// `components-rs/sidecar.h`. They are declared here so the tracer can call them. +// Keep in sync with the macro invocations in span_v1.rs; the non-macro V1 FFI +// (new_builder, intern_string, chunk/span/link/event constructors, id/parent/ +// start/duration/error/kind setters, add_span_attr_bytes, ...) lives in the +// generated sidecar.h. + +#ifndef DDOG_SIDECAR_V1_MACRO_FFI_H +#define DDOG_SIDECAR_V1_MACRO_FFI_H + +#include +#include + +#include "common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// span_str_setter!: value is an interned string id (0 == empty). +void ddog_v1_set_span_service(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uint32_t id); +void ddog_v1_set_span_name(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uint32_t id); +void ddog_v1_set_span_resource(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uint32_t id); +void ddog_v1_set_span_type(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uint32_t id); +void ddog_v1_set_span_env(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uint32_t id); +void ddog_v1_set_span_version(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uint32_t id); +void ddog_v1_set_span_component(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uint32_t id); + +// span_attr_setter!: key_id is interned; value is interned id (str) or scalar. +void ddog_v1_add_span_attr_str(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uint32_t key_id, uint32_t value); +void ddog_v1_add_span_attr_int(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uint32_t key_id, int64_t value); +void ddog_v1_add_span_attr_double(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uint32_t key_id, double value); +void ddog_v1_add_span_attr_bool(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uint32_t key_id, bool value); + +// event_attr_setter!: key_id is interned; value is interned id (str) or scalar. +void ddog_v1_add_event_attr_str(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uintptr_t event, + uint32_t key_id, uint32_t value); +void ddog_v1_add_event_attr_int(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uintptr_t event, + uint32_t key_id, int64_t value); +void ddog_v1_add_event_attr_double(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uintptr_t event, + uint32_t key_id, double value); +void ddog_v1_add_event_attr_bool(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, uintptr_t span, uintptr_t event, + uint32_t key_id, bool value); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // DDOG_SIDECAR_V1_MACRO_FFI_H diff --git a/libdatadog b/libdatadog index c5dc30175f5..317c98d283c 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit c5dc30175f5b2d3e6f2e59b4bd3051337d137bef +Subproject commit 317c98d283cb7db1869b24502f6774afe55710c2 diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index feb1c0ecdd8..1f27e844ae2 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -777,13 +777,6 @@ "default": "8126" } ], - "DD_TRACE_AGENT_PROTOCOL_VERSION": [ - { - "implementation": "A", - "type": "string", - "default": "0.4" - } - ], "DD_TRACE_AGENT_RETRIES": [ { "implementation": "A", diff --git a/tests/ext/request-replayer/dd_trace_exception_span_event.phpt b/tests/ext/request-replayer/dd_trace_exception_span_event.phpt index 44d538e596f..6b555384391 100644 --- a/tests/ext/request-replayer/dd_trace_exception_span_event.phpt +++ b/tests/ext/request-replayer/dd_trace_exception_span_event.phpt @@ -49,8 +49,25 @@ $root = json_decode($replay["body"], true); $spans = $root["chunks"][0]["spans"] ?? $root[0]; $span = $spans[0]; -var_dump($span['meta']['events']); +// The sidecar sender now builds the native V1 payload, so span events are emitted as native span +// events (a V1 `span_events` array; downgraded to the native V0.4 `span_events` field when the +// agent is not V1-capable) instead of the legacy meta["events"] JSON blob. Native event attributes +// are OTEL AnyValue-typed maps ({"type":0,"string_value":...}); we assert them order-independently. +$event = $span['span_events'][0]; +$attrs = $event['attributes']; +var_dump($event['name']); +// The user-provided "exception.message" overrides the exception's own message (builder last-write-wins). +var_dump($attrs['exception.message']['string_value']); +var_dump($attrs['exception.type']['string_value']); +var_dump($attrs['custom.attribute']['string_value']); +var_dump($attrs['exception.stacktrace']['string_value']); ?> --EXPECTF-- Caught exception: Exception in method -string(%d) "[{"name":"exception","time_unix_nano":%d,"attributes":{"exception.message":"override message","exception.type":"Exception","exception.stacktrace":"#0 %s(%d): ExceptionClass->{%s}()\n#1 %s(%d): ExceptionClass->exceptionMethod()\n#2 {main}","custom.attribute":"custom value"}}]" +string(9) "exception" +string(16) "override message" +string(9) "Exception" +string(12) "custom value" +string(%d) "#0 %s(%d): ExceptionClass->{%s}() +#1 %s(%d): ExceptionClass->exceptionMethod() +#2 {main}" diff --git a/tests/ext/request-replayer/dd_trace_span_event.phpt b/tests/ext/request-replayer/dd_trace_span_event.phpt index 9516074caf1..08f4c4424d7 100644 --- a/tests/ext/request-replayer/dd_trace_span_event.phpt +++ b/tests/ext/request-replayer/dd_trace_span_event.phpt @@ -41,8 +41,22 @@ $replay = $rr->waitForDataAndReplay(); $root = json_decode($replay["body"], true); $spans = $root["chunks"][0]["spans"] ?? $root[0]; $span = $spans[0]; -var_dump($span['meta']['events']); +// The sidecar sender now builds the native V1 payload, so span events are emitted as native span +// events (a V1 `span_events` array; downgraded to the native V0.4 `span_events` field when the agent +// is not V1-capable) instead of the legacy meta["events"] JSON blob. Native event attributes are +// OTEL AnyValue-typed maps; we assert them order-independently. Array/object attribute values have +// no native V1 attribute variant, so they are preserved as a JSON string (recoverable). +$event = $span['span_events'][0]; +$attrs = $event['attributes']; +var_dump($event['name'], $event['time_unix_nano']); +var_dump($attrs['arg1']['string_value']); +var_dump($attrs['int_array']['string_value']); +var_dump($attrs['string_array']['string_value']); ?> --EXPECT-- In testMethod -string(134) "[{"name":"event-name","time_unix_nano":1720037568765201300,"attributes":{"arg1":"value1","int_array":[3,4],"string_array":["5","6"]}}]" +string(10) "event-name" +int(1720037568765201300) +string(6) "value1" +string(5) "[3,4]" +string(9) "["5","6"]" diff --git a/tracer/auto_flush.c b/tracer/auto_flush.c index b06a75107d6..0e4b1735211 100644 --- a/tracer/auto_flush.c +++ b/tracer/auto_flush.c @@ -25,22 +25,35 @@ ZEND_EXTERN_MODULE_GLOBALS(datadog); ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles, bool fast_shutdown) { bool success = true; + // The sidecar sender always emits the native V1 wire (the sidecar negotiates V1-vs-V0.4 with the + // agent and downgrades if needed). We build the native V1 payload alongside the V0.4 traces: the + // V0.4 ddog_SpanBytes serve as the intermediate representation that dd_v1_convert_span reads back. + bool use_sidecar = get_global_DD_TRACE_SIDECAR_TRACE_SENDER() && DATADOG_G(sidecar); + ddtrace_v1_ctx v1_ctx = {.builder = NULL, .chunk = DD_V1_CHUNK_NONE}; + ddtrace_v1_ctx *v1 = NULL; + if (use_sidecar) { + v1_ctx.builder = ddog_v1_new_builder(); + v1 = &v1_ctx; + } + ddog_TracesBytes *traces = ddog_get_traces(); if (collect_cycles) { - ddtrace_serialize_closed_spans_with_cycle(traces, fast_shutdown); + ddtrace_serialize_closed_spans_with_cycle(traces, v1, fast_shutdown); } else { - ddtrace_serialize_closed_spans(traces, fast_shutdown); + ddtrace_serialize_closed_spans(traces, v1, fast_shutdown); } // Prevent traces from requests not executing any PHP code: // PG(during_request_startup) will only be set to 0 upon execution of any PHP code. // e.g. php-fpm call with uri pointing to non-existing file, fpm status page, ... if (!force_on_startup && PG(during_request_startup)) { + if (v1) ddog_v1_free_builder(v1->builder); ddog_free_traces(traces); return SUCCESS; } if (!ddog_get_traces_size(traces)) { + if (v1) ddog_v1_free_builder(v1->builder); ddog_free_traces(traces); LOG(INFO, "No finished traces to be sent to the agent"); return SUCCESS; @@ -69,36 +82,20 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles .buffer_size = get_global_DD_TRACE_BUFFER_SIZE(), .url = (ddog_CharSlice) {.ptr = url, .len = strlen(url)}, }; - // Use the V1 wire only when the protocol config is "1"/"1.0" AND the agent /info - // advertises "/v1.0/traces"; otherwise fall back to the default V0.4 path. - zend_string *protocol_version = get_global_DD_TRACE_AGENT_PROTOCOL_VERSION(); - bool use_v1 = (zend_string_equals_literal(protocol_version, "1") || - zend_string_equals_literal(protocol_version, "1.0")) && - DATADOG_G(agent_info_reader) && - ddog_agent_info_has_endpoint(DATADOG_G(agent_info_reader), - DDOG_CHARSLICE_C("/v1.0/traces")); - if (use_v1) { - uint8_t formatted_runtime_id[36]; - datadog_format_runtime_id(&formatted_runtime_id); - zend_string *process_tags = datadog_process_tags_get_serialized(); - ddog_TracerMetadataV1 metadata = { - .hostname = dd_zend_string_to_CharSlice(get_DD_HOSTNAME()), - .env = dd_zend_string_to_CharSlice(get_DD_ENV()), - .app_version = dd_zend_string_to_CharSlice(get_DD_VERSION()), - .runtime_id = (ddog_CharSlice) {.ptr = (char *) formatted_runtime_id, .len = sizeof(formatted_runtime_id)}, - .service = dd_zend_string_to_CharSlice(get_DD_SERVICE()), - .tracer_version = DDOG_CHARSLICE_C_BARE(PHP_DDTRACE_VERSION), - .language_name = DDOG_CHARSLICE_C_BARE("php"), - .language_version = php_version_rt, - .language_interpreter = (ddog_CharSlice) {.ptr = sapi_module.name, .len = strlen(sapi_module.name)}, - .language_interpreter_vendor = DDOG_CHARSLICE_C_BARE(""), - .git_commit_sha = dd_zend_string_to_CharSlice(get_DD_GIT_COMMIT_SHA()), - .process_tags = dd_zend_string_to_CharSlice(process_tags), - }; - ddog_send_traces_to_sidecar_v1(traces, ¶meters, &metadata); - } else { - ddog_send_traces_to_sidecar(traces, ¶meters); - } + // The sidecar always receives the native V1 payload and negotiates/downgrades with the + // agent. Shrunk V1 metadata: lang/lang_version/tracer_version/container_id are sourced + // from parameters.tracer_headers_tags inside the FFI; process tags travel as the span + // meta "_dd.tags.process" emitted during serialization. + uint8_t formatted_runtime_id[36]; + datadog_format_runtime_id(&formatted_runtime_id); + ddog_TracerMetadataV1 metadata = { + .hostname = dd_zend_string_to_CharSlice(get_DD_HOSTNAME()), + .env = dd_zend_string_to_CharSlice(get_DD_ENV()), + .app_version = dd_zend_string_to_CharSlice(get_DD_VERSION()), + .runtime_id = (ddog_CharSlice) {.ptr = (char *) formatted_runtime_id, .len = sizeof(formatted_runtime_id)}, + .git_commit_sha = dd_zend_string_to_CharSlice(get_DD_GIT_COMMIT_SHA()), + }; + ddog_send_traces_to_sidecar_v1(v1->builder, ¶meters, &metadata); // consumes the builder } else { LOGEV(INFO, { log("Skipping flushing trace as connection to sidecar failed"); diff --git a/tracer/configuration.h b/tracer/configuration.h index d73a11201cd..4bf4312f8da 100644 --- a/tracer/configuration.h +++ b/tracer/configuration.h @@ -113,7 +113,6 @@ CONFIG(INT, DD_TRACE_BGS_TIMEOUT, DD_CFG_EXPSTR(DD_TRACE_BGS_TIMEOUT_VAL), \ .ini_change = zai_config_system_ini_change) \ CONFIG(INT, DD_TRACE_AGENT_FLUSH_AFTER_N_REQUESTS, "0") \ - CONFIG(STRING, DD_TRACE_AGENT_PROTOCOL_VERSION, "0.4", .ini_change = zai_config_system_ini_change) \ CONFIG(INT, DD_TRACE_AGENT_RETRIES, "0", .ini_change = zai_config_system_ini_change) \ CONFIG(BOOL, DD_TRACE_AGENT_DEBUG_VERBOSE_CURL, "false", .ini_change = zai_config_system_ini_change) \ CONFIG(BOOL, DD_TRACE_DEBUG_CURL_OUTPUT, "false", .ini_change = zai_config_system_ini_change) \ diff --git a/tracer/functions.c b/tracer/functions.c index d78380cce14..48c91d06021 100644 --- a/tracer/functions.c +++ b/tracer/functions.c @@ -1102,7 +1102,7 @@ PHP_FUNCTION(dd_trace_serialize_closed_spans) { ddtrace_mark_all_span_stacks_flushable(); ddog_TracesBytes *traces = ddog_get_traces(); - ddtrace_serialize_closed_spans_with_cycle(traces, false); + ddtrace_serialize_closed_spans_with_cycle(traces, NULL, false); zval traces_zv = dd_serialize_rust_traces_to_zval(traces); diff --git a/tracer/serializer.c b/tracer/serializer.c index 32f6aadb5bd..601b45c28fe 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -17,6 +17,7 @@ #include "zend_variables.h" #include #include +#include #include #include #include @@ -1088,17 +1089,61 @@ static void dd_serialize_span_events(zend_array *events, smart_str *buf) { zval_ptr_dtor(&tmp); } -// --- Native V1 span links/events (DD_TRACE_AGENT_PROTOCOL_VERSION=1/1.0) --- -// On the V1 wire these go into libdatadog's native span structures, not the V0.4 JSON-in-meta form. +// --- Native V1 payload build (sidecar path) --- +// The sidecar always sends the native V1 wire. We reuse the completed V0.4 ddog_SpanBytes (built by +// ddtrace_serialize_span_to_rust_span with all tag/business logic intact) as the intermediate +// representation and convert it into the V1 builder via the V0.4 read getters, plus read native +// links/events directly from the still-alive PHP span. This keeps the V0.4 wire (in-process sender +// + functions.c introspection) byte-for-byte unchanged and avoids duplicating the serializer. -static bool dd_v1_native_span_enabled(void) { - zend_string *pv = get_global_DD_TRACE_AGENT_PROTOCOL_VERSION(); - return zend_string_equals_literal(pv, "1") || zend_string_equals_literal(pv, "1.0"); +static inline bool dd_cs_eq_lit(ddog_CharSlice s, const char *lit, size_t len) { + return s.len == len && memcmp(s.ptr, lit, len) == 0; } +#define DD_CS_EQ(s, lit) dd_cs_eq_lit((s), "" lit, sizeof(lit) - 1) -// Emit each SpanLink into the native span. The V1 link wire omits flags and -// dropped_attributes_count (no PHP-side source); attributes are a string map. -static void dd_span_links_to_native(zend_array *links, ddog_SpanBytes *rust_span) { +// meta["span.kind"] string -> OTEL wire SpanKind value. DDTrace\SpanKind constants already match +// the OTEL wire values (INTERNAL=1, SERVER=2, CLIENT=3, PRODUCER=4, CONSUMER=5); 0 = unspecified. +static uint32_t dd_span_kind_meta_to_otel(ddog_CharSlice v) { + if (DD_CS_EQ(v, "internal")) return 1; + if (DD_CS_EQ(v, "server")) return 2; + if (DD_CS_EQ(v, "client")) return 3; + if (DD_CS_EQ(v, "producer")) return 4; + if (DD_CS_EQ(v, "consumer")) return 5; + return 0; +} + +// The builder interns by value (equal strings share an id; empty string is id 0), so a call per +// occurrence is correct; a per-request cache is unnecessary for the getter-sourced CharSlices used +// here (they are transient Rust allocations, not stable zend_string pointers). +static inline uint32_t dd_v1_intern(ddog_TracerPayloadV1Builder *b, ddog_CharSlice s) { + return ddog_v1_intern_string(b, s); +} +static inline uint32_t dd_v1_intern_zstr(ddog_TracerPayloadV1Builder *b, zend_string *s) { + return ddog_v1_intern_string(b, dd_zend_string_to_CharSlice(s)); +} + +// Interns a zval used as a string-valued attribute: scalars via the usual string conversion, +// arrays/objects JSON-encoded. The V1 attribute FFI has no native array/object variant, so JSON +// preserves the data (recoverable) instead of losing it to a bare "Array" cast. +static uint32_t dd_v1_intern_zval_str(ddog_TracerPayloadV1Builder *b, zval *val) { + ZVAL_DEREF(val); + if (Z_TYPE_P(val) == IS_ARRAY || Z_TYPE_P(val) == IS_OBJECT) { + smart_str buf = {0}; + zai_json_encode(&buf, val, 0); + smart_str_0(&buf); + uint32_t id = dd_v1_intern_zstr(b, buf.s ? buf.s : ZSTR_EMPTY_ALLOC()); + smart_str_free(&buf); + return id; + } + zend_string *s = datadog_convert_to_str(val); + uint32_t id = dd_v1_intern_zstr(b, s); + zend_string_release(s); + return id; +} + +// Emit each SpanLink into the V1 builder span, reading from the PHP link objects (attributes are a +// string map; dropped_attributes_count has no PHP-side source). +static void dd_span_links_to_v1(zend_array *links, ddog_TracerPayloadV1Builder *b, uintptr_t chunk, uintptr_t span) { zval *val; ZEND_HASH_FOREACH_VAL(links, val) { ZVAL_DEREF(val); @@ -1106,19 +1151,18 @@ static void dd_span_links_to_native(zend_array *links, ddog_SpanBytes *rust_span continue; } ddtrace_span_link *link = (ddtrace_span_link *)Z_OBJ_P(val); - ddog_SpanLinkBytes *rust_link = ddog_span_new_link(rust_span); + uintptr_t rust_link = ddog_v1_span_new_link(b, chunk, span); zval *tid = &link->property_trace_id; if (Z_TYPE_P(tid) == IS_STRING) { datadog_trace_id id = ddtrace_parse_hex_trace_id(Z_STRVAL_P(tid), Z_STRLEN_P(tid)); - ddog_set_link_trace_id(rust_link, id.low); - ddog_set_link_trace_id_high(rust_link, id.high); + ddog_v1_set_link_trace_id(b, chunk, span, rust_link, id.high, id.low); } - ddog_set_link_span_id(rust_link, ddtrace_parse_hex_span_id(&link->property_span_id)); + ddog_v1_set_link_span_id(b, chunk, span, rust_link, ddtrace_parse_hex_span_id(&link->property_span_id)); zval *ts = &link->property_trace_state; if (Z_TYPE_P(ts) == IS_STRING && Z_STRLEN_P(ts) > 0) { - ddog_set_link_tracestate(rust_link, dd_zend_string_to_CharSlice(Z_STR_P(ts))); + ddog_v1_set_link_tracestate(b, chunk, span, rust_link, dd_v1_intern_zstr(b, Z_STR_P(ts))); } zval *attrs = &link->property_attributes; @@ -1129,36 +1173,32 @@ static void dd_span_links_to_native(zend_array *links, ddog_SpanBytes *rust_span zval *aval; ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(attrs), idx, key, aval) { char numbuf[24]; - ddog_CharSlice kslice = key - ? dd_zend_string_to_CharSlice(key) - : (ddog_CharSlice){ .ptr = numbuf, .len = snprintf(numbuf, sizeof(numbuf), ZEND_ULONG_FMT, idx) }; - ZVAL_DEREF(aval); - zend_string *sval = datadog_convert_to_str(aval); - ddog_add_link_attributes(rust_link, kslice, dd_zend_string_to_CharSlice(sval)); - zend_string_release(sval); + uint32_t key_id = key + ? dd_v1_intern_zstr(b, key) + : dd_v1_intern(b, (ddog_CharSlice){ .ptr = numbuf, .len = snprintf(numbuf, sizeof(numbuf), ZEND_ULONG_FMT, idx) }); + ddog_v1_add_link_attr_str(b, chunk, span, rust_link, key_id, dd_v1_intern_zval_str(b, aval)); } ZEND_HASH_FOREACH_END(); } } ZEND_HASH_FOREACH_END(); } -static void dd_event_attribute_to_native(ddog_SpanEventBytes *event, ddog_CharSlice key, zval *val) { +static void dd_event_attribute_to_v1(ddog_TracerPayloadV1Builder *b, uintptr_t chunk, uintptr_t span, + uintptr_t event, uint32_t key_id, zval *val) { ZVAL_DEREF(val); switch (Z_TYPE_P(val)) { - case IS_TRUE: ddog_add_event_attributes_bool(event, key, true); break; - case IS_FALSE: ddog_add_event_attributes_bool(event, key, false); break; - case IS_LONG: ddog_add_event_attributes_int(event, key, Z_LVAL_P(val)); break; - case IS_DOUBLE: ddog_add_event_attributes_float(event, key, Z_DVAL_P(val)); break; - default: { - zend_string *s = datadog_convert_to_str(val); - ddog_add_event_attributes_str(event, key, dd_zend_string_to_CharSlice(s)); - zend_string_release(s); - } + case IS_TRUE: ddog_v1_add_event_attr_bool(b, chunk, span, event, key_id, true); break; + case IS_FALSE: ddog_v1_add_event_attr_bool(b, chunk, span, event, key_id, false); break; + case IS_LONG: ddog_v1_add_event_attr_int(b, chunk, span, event, key_id, Z_LVAL_P(val)); break; + case IS_DOUBLE: ddog_v1_add_event_attr_double(b, chunk, span, event, key_id, Z_DVAL_P(val)); break; + default: + ddog_v1_add_event_attr_str(b, chunk, span, event, key_id, dd_v1_intern_zval_str(b, val)); + break; } } -// Emit each SpanEvent into the native span, dispatching attributes by type. ExceptionSpanEvent +// Emit each SpanEvent into the V1 builder span, dispatching attributes by type. ExceptionSpanEvent // flattens exception.message/type/stacktrace as string attributes (mirrors dd_span_event_to_array). -static void dd_span_events_to_native(zend_array *events, ddog_SpanBytes *rust_span) { +static void dd_span_events_to_v1(zend_array *events, ddog_TracerPayloadV1Builder *b, uintptr_t chunk, uintptr_t span) { zval *val; ZEND_HASH_FOREACH_VAL(events, val) { ZVAL_DEREF(val); @@ -1166,16 +1206,16 @@ static void dd_span_events_to_native(zend_array *events, ddog_SpanBytes *rust_sp continue; } ddtrace_span_event *event = (ddtrace_span_event *)Z_OBJ_P(val); - ddog_SpanEventBytes *rust_event = ddog_span_new_event(rust_span); + uintptr_t rust_event = ddog_v1_span_new_event(b, chunk, span); zval *name = &event->property_name; if (Z_TYPE_P(name) == IS_STRING) { - ddog_set_event_name(rust_event, dd_zend_string_to_CharSlice(Z_STR_P(name))); + ddog_v1_set_event_name(b, chunk, span, rust_event, dd_v1_intern_zstr(b, Z_STR_P(name))); } zval *time = &event->property_timestamp; ZVAL_DEREF(time); if (Z_TYPE_P(time) == IS_LONG) { - ddog_set_event_time(rust_event, (uint64_t)Z_LVAL_P(time)); + ddog_v1_set_event_time(b, chunk, span, rust_event, (uint64_t)Z_LVAL_P(time)); } if (instanceof_function(event->std.ce, ddtrace_ce_exception_span_event)) { @@ -1184,11 +1224,14 @@ static void dd_span_events_to_native(zend_array *events, ddog_SpanBytes *rust_sp if (Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), zend_ce_throwable)) { zend_string *message = zai_exception_message(Z_OBJ_P(exception)); if (ZSTR_LEN(message)) { - ddog_add_event_attributes_str(rust_event, DDOG_CHARSLICE_C("exception.message"), dd_zend_string_to_CharSlice(message)); + ddog_v1_add_event_attr_str(b, chunk, span, rust_event, + dd_v1_intern(b, DDOG_CHARSLICE_C("exception.message")), dd_v1_intern_zstr(b, message)); } - ddog_add_event_attributes_str(rust_event, DDOG_CHARSLICE_C("exception.type"), dd_zend_string_to_CharSlice(Z_OBJCE_P(exception)->name)); + ddog_v1_add_event_attr_str(b, chunk, span, rust_event, + dd_v1_intern(b, DDOG_CHARSLICE_C("exception.type")), dd_v1_intern_zstr(b, Z_OBJCE_P(exception)->name)); zend_string *stacktrace = zai_get_trace_without_args_from_exception(Z_OBJ_P(exception)); - ddog_add_event_attributes_str(rust_event, DDOG_CHARSLICE_C("exception.stacktrace"), dd_zend_string_to_CharSlice(stacktrace)); + ddog_v1_add_event_attr_str(b, chunk, span, rust_event, + dd_v1_intern(b, DDOG_CHARSLICE_C("exception.stacktrace")), dd_v1_intern_zstr(b, stacktrace)); zend_string_release(stacktrace); } } @@ -1201,15 +1244,111 @@ static void dd_span_events_to_native(zend_array *events, ddog_SpanBytes *rust_sp zval *aval; ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(attrs), idx, key, aval) { char numbuf[24]; - ddog_CharSlice kslice = key - ? dd_zend_string_to_CharSlice(key) - : (ddog_CharSlice){ .ptr = numbuf, .len = snprintf(numbuf, sizeof(numbuf), ZEND_ULONG_FMT, idx) }; - dd_event_attribute_to_native(rust_event, kslice, aval); + uint32_t key_id = key + ? dd_v1_intern_zstr(b, key) + : dd_v1_intern(b, (ddog_CharSlice){ .ptr = numbuf, .len = snprintf(numbuf, sizeof(numbuf), ZEND_ULONG_FMT, idx) }); + dd_event_attribute_to_v1(b, chunk, span, rust_event, key_id, aval); } ZEND_HASH_FOREACH_END(); } } ZEND_HASH_FOREACH_END(); } +// Convert a fully-built V0.4 span (all tags/business logic already applied) into a new span in the +// V1 builder. Fields/meta/metrics/meta_struct are read back from the V0.4 span; native links/events +// are read from the still-alive PHP span. Promoted fields (env/version/component/span.kind) go to +// dedicated setters and are excluded from the attribute map; chunk-level fields (sampling priority, +// origin, sampling mechanism, 128-bit trace-id high) are routed to the chunk and excluded too. +static void dd_v1_convert_span(ddtrace_v1_ctx *v1, ddog_SpanBytes *v04, ddtrace_span_data *php_span) { + ddog_TracerPayloadV1Builder *b = v1->builder; + if (v1->chunk == DD_V1_CHUNK_NONE) { + v1->chunk = ddog_v1_builder_new_chunk(b, php_span->root->trace_id.high, php_span->root->trace_id.low); + bool p0 = ddtrace_fetch_priority_sampling_from_span(php_span->root) <= 0; + ddog_v1_set_chunk_dropped_trace(b, v1->chunk, p0); + } + uintptr_t chunk = v1->chunk; + uintptr_t sp = ddog_v1_chunk_new_span(b, chunk); + + ddog_v1_set_span_id(b, chunk, sp, ddog_get_span_id(v04)); + ddog_v1_set_span_parent_id(b, chunk, sp, ddog_get_span_parent_id(v04)); + ddog_v1_set_span_start(b, chunk, sp, ddog_get_span_start(v04)); + ddog_v1_set_span_duration(b, chunk, sp, ddog_get_span_duration(v04)); + ddog_v1_set_span_error(b, chunk, sp, ddog_get_span_error(v04) != 0); + +#define DD_V1_SET_FIELD(getter, setter) \ + do { \ + ddog_CharSlice _s = getter(v04); \ + if (_s.len) setter(b, chunk, sp, dd_v1_intern(b, _s)); \ + } while (0) + DD_V1_SET_FIELD(ddog_get_span_service, ddog_v1_set_span_service); + DD_V1_SET_FIELD(ddog_get_span_name, ddog_v1_set_span_name); + DD_V1_SET_FIELD(ddog_get_span_resource, ddog_v1_set_span_resource); + DD_V1_SET_FIELD(ddog_get_span_type, ddog_v1_set_span_type); +#undef DD_V1_SET_FIELD + + size_t meta_count = 0; + ddog_CharSlice *meta_keys = ddog_span_meta_get_keys(v04, &meta_count); + for (size_t k = 0; k < meta_count; k++) { + ddog_CharSlice key = meta_keys[k]; + ddog_CharSlice value = ddog_get_span_meta(v04, key); + // Promoted fields -> dedicated setters, excluded from the attribute map. + if (DD_CS_EQ(key, "env")) { ddog_v1_set_span_env(b, chunk, sp, dd_v1_intern(b, value)); continue; } + if (DD_CS_EQ(key, "version")) { ddog_v1_set_span_version(b, chunk, sp, dd_v1_intern(b, value)); continue; } + if (DD_CS_EQ(key, "component")) { ddog_v1_set_span_component(b, chunk, sp, dd_v1_intern(b, value)); continue; } + if (DD_CS_EQ(key, "span.kind")) { ddog_v1_set_span_kind(b, chunk, sp, dd_span_kind_meta_to_otel(value)); continue; } + // Links/events are emitted natively from the PHP span, not the V0.4 JSON-in-meta form. + if (DD_CS_EQ(key, "_dd.span_links") || DD_CS_EQ(key, "events")) { continue; } + // Chunk-level promotions (only present on the root/first span). + if (DD_CS_EQ(key, "_dd.origin")) { ddog_v1_set_chunk_origin(b, chunk, dd_v1_intern(b, value)); continue; } + if (DD_CS_EQ(key, "_dd.p.dm")) { + // v0.4 form is "-N"; the mechanism is the trailing unsigned integer. + const char *p = value.ptr; size_t n = value.len; + if (n && *p == '-') { p++; n--; } + uint32_t mech = 0; + for (size_t i = 0; i < n; i++) { if (p[i] < '0' || p[i] > '9') { mech = 0; break; } mech = mech * 10 + (uint32_t)(p[i] - '0'); } + ddog_v1_set_chunk_sampling_mechanism(b, chunk, mech); + continue; + } + // 128-bit trace-id high half is carried by the chunk trace id, not a span attribute. + if (DD_CS_EQ(key, "_dd.p.tid")) { continue; } + ddog_v1_add_span_attr_str(b, chunk, sp, dd_v1_intern(b, key), dd_v1_intern(b, value)); + } + ddog_span_free_keys_ptr(meta_keys, meta_count); + + size_t metrics_count = 0; + ddog_CharSlice *metrics_keys = ddog_span_metrics_get_keys(v04, &metrics_count); + for (size_t k = 0; k < metrics_count; k++) { + ddog_CharSlice key = metrics_keys[k]; + double value; + if (!ddog_get_span_metrics(v04, key, &value)) { + continue; + } + if (DD_CS_EQ(key, "_sampling_priority_v1")) { + ddog_v1_set_chunk_sampling_priority(b, chunk, (int32_t)value); + continue; + } + ddog_v1_add_span_attr_double(b, chunk, sp, dd_v1_intern(b, key), value); + } + ddog_span_free_keys_ptr(metrics_keys, metrics_count); + + size_t meta_struct_count = 0; + ddog_CharSlice *meta_struct_keys = ddog_span_meta_struct_get_keys(v04, &meta_struct_count); + for (size_t k = 0; k < meta_struct_count; k++) { + ddog_CharSlice key = meta_struct_keys[k]; + ddog_CharSlice value = ddog_get_span_meta_struct(v04, key); + ddog_v1_add_span_attr_bytes(b, chunk, sp, dd_v1_intern(b, key), value); + } + ddog_span_free_keys_ptr(meta_struct_keys, meta_struct_count); + + zend_array *span_links = ddtrace_property_array(&php_span->property_links); + if (zend_hash_num_elements(span_links) > 0) { + dd_span_links_to_v1(span_links, b, chunk, sp); + } + zend_array *span_events = ddtrace_property_array(&php_span->property_events); + if (zend_hash_num_elements(span_events) > 0) { + dd_span_events_to_v1(span_events, b, chunk, sp); + } +} + static void dd_serialize_array_recursively(ddog_SpanBytes *target, zend_string *str, zval *value, bool convert_to_double) { ZVAL_DEREF(value); @@ -1567,7 +1706,7 @@ void transfer_metrics_data(ddog_SpanBytes *source, ddog_SpanBytes *destination, } } -ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceBytes *trace) { +ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceBytes *trace, ddtrace_v1_ctx *v1) { zend_array *meta = ddtrace_property_array(&span->property_meta); zend_array *metrics = ddtrace_property_array(&span->property_metrics); @@ -1927,20 +2066,17 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo ddtrace_exception_to_meta(Z_OBJ_P(exception_zv), pre.service ? pre.service : ZSTR_EMPTY_ALLOC(), span->start, rust_span, exception_type); } - bool v1_native = dd_v1_native_span_enabled(); - + // Links/events are always serialized as V0.4 JSON-in-meta here (used by the in-process sender + // and functions.c introspection). The V1 sidecar path re-emits them natively from the PHP span + // in dd_v1_convert_span and skips these two meta keys. zend_array *span_links = ddtrace_property_array(&span->property_links); if (zend_hash_num_elements(span_links) > 0) { zend_object *current_exception = EG(exception); EG(exception) = NULL; - if (v1_native) { - dd_span_links_to_native(span_links, rust_span); - } else { - smart_str buf = {0}; - dd_serialize_span_links(span_links, &buf); - ddog_add_str_span_meta_zstr(rust_span, "_dd.span_links", buf.s); - smart_str_free(&buf); - } + smart_str buf = {0}; + dd_serialize_span_links(span_links, &buf); + ddog_add_str_span_meta_zstr(rust_span, "_dd.span_links", buf.s); + smart_str_free(&buf); EG(exception) = current_exception; } @@ -1948,14 +2084,10 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo if (zend_hash_num_elements(span_events) > 0) { zend_object *current_exception = EG(exception); EG(exception) = NULL; - if (v1_native) { - dd_span_events_to_native(span_events, rust_span); - } else { - smart_str buf = {0}; - dd_serialize_span_events(span_events, &buf); - ddog_add_str_span_meta_zstr(rust_span, "events", buf.s); - smart_str_free(&buf); - } + smart_str buf = {0}; + dd_serialize_span_events(span_events, &buf); + ddog_add_str_span_meta_zstr(rust_span, "events", buf.s); + smart_str_free(&buf); EG(exception) = current_exception; } @@ -2107,8 +2239,9 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo } } + ddog_SpanBytes *serialized_inferred_span = NULL; if (inferred_span) { - ddog_SpanBytes *serialized_inferred_span = ddtrace_serialize_span_to_rust_span(inferred_span, trace); + serialized_inferred_span = ddtrace_serialize_span_to_rust_span(inferred_span, trace, v1); rust_span = ddog_get_span(trace, rust_span_index); transfer_metrics_data(rust_span, serialized_inferred_span, "_dd.agent_psr", true); @@ -2147,6 +2280,15 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo ddog_del_span_meta_str(rust_span, "error.ignored"); + // Emit into the native V1 builder (sidecar path). Inferred spans are converted by their parent + // root span right after the read-back merge above, so their final V0.4 state is captured. + if (v1 && !is_inferred_span) { + dd_v1_convert_span(v1, rust_span, span); + if (serialized_inferred_span) { + dd_v1_convert_span(v1, serialized_inferred_span, inferred_span); + } + } + ddtrace_free_span_precomputed(&pre); return rust_span; } diff --git a/tracer/serializer.h b/tracer/serializer.h index 4be37e80184..5ddb413436d 100644 --- a/tracer/serializer.h +++ b/tracer/serializer.h @@ -6,7 +6,7 @@ int ddtrace_serialize_simple_array(zval *trace, zval *retval); int ddtrace_serialize_simple_array_into_c_string(zval *trace, char **data_p, size_t *size_p); -ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceBytes *trace); +ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceBytes *trace, ddtrace_v1_ctx *v1); zval dd_serialize_rust_traces_to_zval(ddog_TracesBytes *traces); void ddtrace_save_active_error_to_metadata(void); diff --git a/tracer/span.c b/tracer/span.c index 853c90ab68d..44aedd6a6d6 100644 --- a/tracer/span.c +++ b/tracer/span.c @@ -1160,7 +1160,7 @@ void ddtrace_drop_span(ddtrace_span_data *span) { dd_drop_span(span, false); } -void ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, bool fast_shutdown) { +void ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, ddtrace_v1_ctx *v1, bool fast_shutdown) { if (DDTRACE_G(top_closed_stack)) { ddtrace_span_stack *rootstack = DDTRACE_G(top_closed_stack); DDTRACE_G(top_closed_stack) = NULL; @@ -1175,6 +1175,9 @@ void ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, bool fast_shutdown next_stack = stack->next; } ddog_TraceBytes *trace = ddog_traces_new_trace(traces); + if (v1) { + v1->chunk = DD_V1_CHUNK_NONE; // one V1 chunk per V0.4 trace + } do { // Note this ->next: We always splice in new spans at next, so start at next to mostly preserve order @@ -1183,7 +1186,7 @@ void ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, bool fast_shutdown do { ddtrace_span_data *tmp = span; span = tmp->next; - ddtrace_serialize_span_to_rust_span(tmp, trace); + ddtrace_serialize_span_to_rust_span(tmp, trace, v1); #if PHP_VERSION_ID < 70400 // remove the artificially increased RC while closing again GC_SET_REFCOUNT(&tmp->std, GC_REFCOUNT(&tmp->std) - DD_RC_CLOSED_MARKER); @@ -1210,10 +1213,10 @@ void ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, bool fast_shutdown DDTRACE_G(dropped_spans_count) = 0; } -void ddtrace_serialize_closed_spans_with_cycle(ddog_TracesBytes *traces, bool fast_shutdown) { +void ddtrace_serialize_closed_spans_with_cycle(ddog_TracesBytes *traces, ddtrace_v1_ctx *v1, bool fast_shutdown) { // We need to loop here, as closing the last span root stack could add other spans here while (DDTRACE_G(top_closed_stack)) { - ddtrace_serialize_closed_spans(traces, fast_shutdown); + ddtrace_serialize_closed_spans(traces, v1, fast_shutdown); if (DDTRACE_G(open_spans_count)) { // Also flush possible cycles here, if there are remaining open spans gc_collect_cycles(); diff --git a/tracer/span.h b/tracer/span.h index 29301497cc1..94e87f55e1b 100644 --- a/tracer/span.h +++ b/tracer/span.h @@ -15,6 +15,16 @@ #include "otel_context.h" #endif +// Sidecar V1 payload build context. When non-NULL, span serialization also emits each finished +// span into the native V1 builder (built from the completed V0.4 span + the still-alive PHP span +// for native links/events). `chunk` is DD_V1_CHUNK_NONE until the first span of the current stack +// creates its chunk; ddtrace_serialize_closed_spans resets it per stack. +#define DD_V1_CHUNK_NONE ((uintptr_t)-1) +typedef struct { + struct ddog_TracerPayloadV1Builder *builder; + uintptr_t chunk; +} ddtrace_v1_ctx; + #define DDTRACE_DROPPED_SPAN (-1ull) #define DDTRACE_SILENTLY_DROPPED_SPAN (-2ull) @@ -279,8 +289,8 @@ void ddtrace_close_top_span_without_stack_swap(ddtrace_span_data *span); void ddtrace_close_all_open_spans(bool force_close_root_span); void ddtrace_drop_span(ddtrace_span_data *span); void ddtrace_mark_all_span_stacks_flushable(void); -void ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, bool fast_shutdown); -void ddtrace_serialize_closed_spans_with_cycle(ddog_TracesBytes *traces, bool fast_shutdown); +void ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, ddtrace_v1_ctx *v1, bool fast_shutdown); +void ddtrace_serialize_closed_spans_with_cycle(ddog_TracesBytes *traces, ddtrace_v1_ctx *v1, bool fast_shutdown); zend_string *ddtrace_span_id_as_string(uint64_t id); zend_string *datadog_trace_id_as_string(datadog_trace_id id); zend_string *ddtrace_span_id_as_hex_string(uint64_t id); From 24cdec1c27b060c5bb3da3c5745c91ed7453882a Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Wed, 26 Aug 2026 18:07:03 +0200 Subject: [PATCH 20/32] refactor(serializer): drop hand-written v1 macro FFI header libdatadog now defines the v1 builder setters as explicit fns instead of declarative-macro-generated ones, so cbindgen emits them into the generated components-rs/sidecar.h. Bump the libdatadog submodule, regenerate sidecar.h (now carries ddog_v1_set_span_* / ddog_v1_add_span_attr_* / ddog_v1_add_event_attr_*), and remove the interim components-rs/sidecar_v1_macro_ffi.h and its include in serializer.c. --- components-rs/sidecar.h | 132 +++++++++++++++++++++++++++ components-rs/sidecar_v1_macro_ffi.h | 72 --------------- libdatadog | 2 +- tracer/serializer.c | 1 - 4 files changed, 133 insertions(+), 74 deletions(-) delete mode 100644 components-rs/sidecar_v1_macro_ffi.h diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index dad9982c73d..95ad02436f7 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -748,6 +748,62 @@ void ddog_v1_add_chunk_attr_str(struct ddog_TracerPayloadV1Builder *builder, */ uintptr_t ddog_v1_chunk_new_span(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk); +/** + * Sets the span service (interned id). + */ +void ddog_v1_set_span_service(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t id); + +/** + * Sets the span name (interned id). + */ +void ddog_v1_set_span_name(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t id); + +/** + * Sets the span resource (interned id). + */ +void ddog_v1_set_span_resource(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t id); + +/** + * Sets the span type (interned id). + */ +void ddog_v1_set_span_type(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t id); + +/** + * Sets the span env (interned id). + */ +void ddog_v1_set_span_env(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t id); + +/** + * Sets the span version (interned id). + */ +void ddog_v1_set_span_version(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t id); + +/** + * Sets the span component (interned id). + */ +void ddog_v1_set_span_component(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t id); + /** * Sets the span id. */ @@ -796,6 +852,42 @@ void ddog_v1_set_span_kind(struct ddog_TracerPayloadV1Builder *builder, uintptr_t span, uint32_t kind); +/** + * Adds a string span attribute (key and value are interned ids). + */ +void ddog_v1_add_span_attr_str(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t key_id, + uint32_t value); + +/** + * Adds an integer span attribute (key is an interned id). + */ +void ddog_v1_add_span_attr_int(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t key_id, + int64_t value); + +/** + * Adds a double span attribute (key is an interned id). + */ +void ddog_v1_add_span_attr_double(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t key_id, + double value); + +/** + * Adds a boolean span attribute (key is an interned id). + */ +void ddog_v1_add_span_attr_bool(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uint32_t key_id, + bool value); + /** * Adds a bytes-valued span attribute. The key is an interned id; the value bytes are copied * verbatim (not interned) and encoded as msgpack `bin`. @@ -885,4 +977,44 @@ void ddog_v1_set_event_name(struct ddog_TracerPayloadV1Builder *builder, uintptr_t event, uint32_t id); +/** + * Adds a string event attribute (key and value are interned ids). + */ +void ddog_v1_add_event_attr_str(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uint32_t key_id, + uint32_t value); + +/** + * Adds an integer event attribute (key is an interned id). + */ +void ddog_v1_add_event_attr_int(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uint32_t key_id, + int64_t value); + +/** + * Adds a double event attribute (key is an interned id). + */ +void ddog_v1_add_event_attr_double(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uint32_t key_id, + double value); + +/** + * Adds a boolean event attribute (key is an interned id). + */ +void ddog_v1_add_event_attr_bool(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uint32_t key_id, + bool value); + #endif /* DDOG_SIDECAR_H */ diff --git a/components-rs/sidecar_v1_macro_ffi.h b/components-rs/sidecar_v1_macro_ffi.h deleted file mode 100644 index 2c577e21695..00000000000 --- a/components-rs/sidecar_v1_macro_ffi.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ -// SPDX-License-Identifier: Apache-2.0 - -// Hand-written prototypes for the V1 payload-builder FFI functions that are -// generated by declarative macros (`span_str_setter!`, `span_attr_setter!`, -// `event_attr_setter!`) in libdatadog's `datadog-sidecar-ffi/src/span_v1.rs`. -// -// cbindgen does not expand macro invocations, so these `#[no_mangle] pub extern -// "C"` symbols exist in the compiled library but are absent from the generated -// `components-rs/sidecar.h`. They are declared here so the tracer can call them. -// Keep in sync with the macro invocations in span_v1.rs; the non-macro V1 FFI -// (new_builder, intern_string, chunk/span/link/event constructors, id/parent/ -// start/duration/error/kind setters, add_span_attr_bytes, ...) lives in the -// generated sidecar.h. - -#ifndef DDOG_SIDECAR_V1_MACRO_FFI_H -#define DDOG_SIDECAR_V1_MACRO_FFI_H - -#include -#include - -#include "common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// span_str_setter!: value is an interned string id (0 == empty). -void ddog_v1_set_span_service(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uint32_t id); -void ddog_v1_set_span_name(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uint32_t id); -void ddog_v1_set_span_resource(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uint32_t id); -void ddog_v1_set_span_type(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uint32_t id); -void ddog_v1_set_span_env(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uint32_t id); -void ddog_v1_set_span_version(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uint32_t id); -void ddog_v1_set_span_component(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uint32_t id); - -// span_attr_setter!: key_id is interned; value is interned id (str) or scalar. -void ddog_v1_add_span_attr_str(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uint32_t key_id, uint32_t value); -void ddog_v1_add_span_attr_int(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uint32_t key_id, int64_t value); -void ddog_v1_add_span_attr_double(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uint32_t key_id, double value); -void ddog_v1_add_span_attr_bool(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uint32_t key_id, bool value); - -// event_attr_setter!: key_id is interned; value is interned id (str) or scalar. -void ddog_v1_add_event_attr_str(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uintptr_t event, - uint32_t key_id, uint32_t value); -void ddog_v1_add_event_attr_int(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uintptr_t event, - uint32_t key_id, int64_t value); -void ddog_v1_add_event_attr_double(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uintptr_t event, - uint32_t key_id, double value); -void ddog_v1_add_event_attr_bool(struct ddog_TracerPayloadV1Builder *builder, - uintptr_t chunk, uintptr_t span, uintptr_t event, - uint32_t key_id, bool value); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // DDOG_SIDECAR_V1_MACRO_FFI_H diff --git a/libdatadog b/libdatadog index 317c98d283c..53437b32e5e 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 317c98d283cb7db1869b24502f6774afe55710c2 +Subproject commit 53437b32e5e4ed4ad62af0779930fb386de5a4d7 diff --git a/tracer/serializer.c b/tracer/serializer.c index 601b45c28fe..52a4361d468 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -17,7 +17,6 @@ #include "zend_variables.h" #include #include -#include #include #include #include From 601fdce9e94ac0d0983b577edfe6d64fb6fba452 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Wed, 26 Aug 2026 19:27:01 +0200 Subject: [PATCH 21/32] chore(libdatadog): bump to v1 serialize-to-bytes FFI + regenerate cbindgen Bump the libdatadog submodule to 594d5c2ab (LIBDD_V1ONLY branch), which adds ddog_serialize_trace_v1_into_charslice for the in-process (PHP <= 8.2) sender, and regenerate components-rs/sidecar.h via cbindgen. The v1 builder/setter symbols were already present from Stage 1; this only adds the serialize-to-bytes entry point used by the coms.c in-process path. --- components-rs/sidecar.h | 21 +++++++++++++++++++++ libdatadog | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 95ad02436f7..8d5eba264b6 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -511,6 +511,27 @@ void ddog_send_traces_to_sidecar_v1(struct ddog_TracerPayloadV1Builder *builder, struct ddog_SenderParameters *parameters, const struct ddog_TracerMetadataV1 *metadata); +/** + * Serializes the native V1 `TracerPayload` built via the [`crate::span_v1`] builder into owned + * msgpack bytes for the in-process (non-sidecar) sender in `coms.c`, which POSTs them directly to + * the agent's `/v1.0/traces` endpoint (the PHP <= 8.2 path that never goes through the sidecar). + * Consumes `builder`. The V1 counterpart of [`crate::span::ddog_serialize_trace_into_charslice`]. + * + * Payload-level metadata is applied here exactly as the sidecar path does (via + * `populate_payload_metadata`): `container_id`/`language_name`/`language_version`/`tracer_version` + * come from the caller's tracer header tags and the rest from `metadata`, so the promoted V1 + * fields are identical to the sidecar-encoded payload. + * + * The returned slice is an owned allocation that must be freed with + * [`crate::span::ddog_free_charslice`]. + */ +ddog_CharSlice ddog_serialize_trace_v1_into_charslice(struct ddog_TracerPayloadV1Builder *builder, + const struct ddog_TracerMetadataV1 *metadata, + ddog_CharSlice container_id, + ddog_CharSlice language_name, + ddog_CharSlice language_version, + ddog_CharSlice tracer_version); + /** * Drops the agent info reader. */ diff --git a/libdatadog b/libdatadog index 53437b32e5e..594d5c2abac 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 53437b32e5e4ed4ad62af0779930fb386de5a4d7 +Subproject commit 594d5c2abac76f3ad0f8bf28a680b87e93696c77 From 6c57076b9692d8961d00436b23e896770b501cbf Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 31 Aug 2026 14:43:17 +0200 Subject: [PATCH 22/32] feat(tracer): build native v1 payload directly on the sidecar path Port span finalization to populate the native v1 TracerPayload builder directly for the sidecar sender, with no v0.4 intermediate, and reflect the v1 model in introspection. The in-process (<=8.2) background sender keeps its v0.4 build behind an isolated, removable v0.4->v1 transcode layer. - serializer.c: route the single finalization body of ddtrace_serialize_span_to_rust_span through a dd_span_sink that targets either the v0.4 ddog_SpanBytes or the v1 builder chunk/span. Promoted fields (env/version/component/span.kind) go to dedicated v1 setters and chunk-level fields (_dd.origin/_dd.p.dm/_sampling_priority_v1) to the chunk, excluded from the attribute map; _dd.p.tid is carried by the chunk 128-bit trace id. Links/events are emitted natively on v1 (JSON-in -meta only on v0.4). The inferred->root merge uses the typed ddog_v1_transfer_span_attr. Removed dd_v1_convert_span and the removed ddog_v1_intern_string usage (setters now take CharSlice). - exception_serialize.c: error.message/type/stack and exception-replay debug meta write through the sink (v1 span attributes on the sidecar path). - functions.c/serializer.c: dd_trace_serialize_closed_spans reads the v1 builder via the new getters on the sidecar path (dd_serialize_rust_v1_to _zval), reflecting the v1 model (promoted + chunk fields, typed attributes, native links/events); v0.4 introspection unchanged. - auto_flush.c/coms.c/agent_info.c: removable v0.4->v1 bolt-on for the in-process sender: ddtrace_agent_supports_v1_traces() gates transcoding the v0.4 collection via ddog_serialize_trace_v04_as_v1_into_charslice and POSTing to /v1.0/traces; otherwise the existing v0.4 path to /v0.4/traces. - libdatadog: bump to fef26d167 (mutable v1 span-attr FFI); regenerate cbindgen headers. --- components-rs/common.h | 21 +- components-rs/sidecar.h | 557 +++++++++++++++++++++--- ext/agent_info.c | 15 + ext/agent_info.h | 4 + libdatadog | 2 +- tracer/auto_flush.c | 87 +++- tracer/coms.c | 12 +- tracer/coms.h | 4 + tracer/exception_serialize.c | 28 +- tracer/exception_serialize.h | 2 +- tracer/functions.c | 18 +- tracer/serializer.c | 822 +++++++++++++++++++++++------------ tracer/serializer.h | 11 +- tracer/span.h | 11 + 14 files changed, 1212 insertions(+), 382 deletions(-) diff --git a/components-rs/common.h b/components-rs/common.h index 42b16ccef90..da63fdf557b 100644 --- a/components-rs/common.h +++ b/components-rs/common.h @@ -1175,6 +1175,25 @@ typedef struct ddog_AttributeAnyValueBytes ddog_AttributeAnyValueBytes; typedef struct ddog_AttributeArrayValueBytes ddog_AttributeArrayValueBytes; +/** + * Attribute value type tags returned by the `ddog_v1_get_*_attr_type` getters. They let a C caller + * pick the matching typed value getter (`_attr_str`/`_attr_int`/`_attr_double`/`_attr_bool`/ + * `_attr_bytes`) for a given attribute index. + */ +#define ddog_DDOG_V1_ATTR_STRING 0 + +#define ddog_DDOG_V1_ATTR_INT 1 + +#define ddog_DDOG_V1_ATTR_DOUBLE 2 + +#define ddog_DDOG_V1_ATTR_BOOL 3 + +#define ddog_DDOG_V1_ATTR_BYTES 4 + +#define ddog_DDOG_V1_ATTR_KEYVALUE 5 + +#define ddog_DDOG_V1_ATTR_LIST 6 + typedef enum ddog_DynamicInstrumentationConfigState { DDOG_DYNAMIC_INSTRUMENTATION_CONFIG_STATE_ENABLED, DDOG_DYNAMIC_INSTRUMENTATION_CONFIG_STATE_DISABLED, @@ -1210,7 +1229,7 @@ typedef struct ddog_RuntimeMetadata ddog_RuntimeMetadata; typedef struct ddog_ShmHandle ddog_ShmHandle; /** - * Builds a native V1 [`TracerPayloadBytes`] while interning every string once. + * Builds a native V1 [`TracerPayloadBytes`] holding readable strings. */ typedef struct ddog_TracerPayloadV1Builder ddog_TracerPayloadV1Builder; diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 8d5eba264b6..90ab96b494e 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -532,6 +532,29 @@ ddog_CharSlice ddog_serialize_trace_v1_into_charslice(struct ddog_TracerPayloadV ddog_CharSlice language_version, ddog_CharSlice tracer_version); +/** + * Transcodes an existing v0.4 trace collection (built with the v0.4 [`crate::span`] builder) into + * owned V1 msgpack bytes, for the in-process (non-sidecar) sender in `coms.c`. That sender builds + * v0.4 today; this lets it emit V1 to the agent's `/v1.0/traces` endpoint without a second builder, + * by upgrading the already-built v0.4 payload via [`msgpack_encoder::v1::to_vec_from_v04`]. When the + * agent isn't V1-capable, the caller sends its v0.4 bytes directly instead of calling this — so the + * V1 upgrade is an isolated, removable bolt-on gated by that endpoint check. + * + * The V1 wire payload carries tracer metadata inline (v0.4 sends it as HTTP headers), so the + * promoted fields are supplied here exactly as the V1 sidecar path applies them: + * `container_id`/`language_name`/`language_version`/`tracer_version` from the caller's tracer header + * tags and `hostname`/`env`/`app_version`/`runtime_id`/`git_commit_sha` from `metadata`. + * + * Consumes nothing; `traces` is deduped in place (as the v0.4 shm sender does) before encoding. The + * returned slice is an owned allocation that must be freed with [`crate::span::ddog_free_charslice`]. + */ +ddog_CharSlice ddog_serialize_trace_v04_as_v1_into_charslice(ddog_TracesBytes *traces, + const struct ddog_TracerMetadataV1 *metadata, + ddog_CharSlice container_id, + ddog_CharSlice language_name, + ddog_CharSlice language_version, + ddog_CharSlice tracer_version); + /** * Drops the agent info reader. */ @@ -709,18 +732,8 @@ struct ddog_TracerPayloadV1Builder *ddog_v1_new_builder(void); */ void ddog_v1_free_builder(struct ddog_TracerPayloadV1Builder *_builder); -/** - * Interns `string` into the builder's value-keyed table and returns its stable id. Equal strings - * (including across chunks/spans) always return the same id; the empty string is always id 0. - */ -uint32_t ddog_v1_intern_string(struct ddog_TracerPayloadV1Builder *builder, ddog_CharSlice string); - /** * Appends a new (empty) chunk with the given 128-bit trace id, returning its index. - * - * A chunk must be fully built (all its spans/links/events) before the next chunk is created: - * creating a chunk may reallocate the chunk vector and invalidate positions cached as raw - * pointers. Indices remain valid. */ uintptr_t ddog_v1_builder_new_chunk(struct ddog_TracerPayloadV1Builder *builder, uint64_t trace_id_high, @@ -734,11 +747,11 @@ void ddog_v1_set_chunk_sampling_priority(struct ddog_TracerPayloadV1Builder *bui int32_t priority); /** - * Sets the chunk origin (v0.4 `_dd.origin`) from an interned id. + * Sets the chunk origin (v0.4 `_dd.origin`). */ void ddog_v1_set_chunk_origin(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, - uint32_t origin_id); + ddog_CharSlice origin); /** * Sets the chunk sampling mechanism (v0.4 `_dd.p.dm`). @@ -755,75 +768,73 @@ void ddog_v1_set_chunk_dropped_trace(struct ddog_TracerPayloadV1Builder *builder bool dropped); /** - * Adds a string-valued chunk-level attribute (key and value are interned ids). + * Adds a string-valued chunk-level attribute. */ void ddog_v1_add_chunk_attr_str(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, - uint32_t key_id, - uint32_t value_id); + ddog_CharSlice key, + ddog_CharSlice value); /** * Appends a new (empty) span to `chunk`, returning its index within that chunk. - * - * A span must be fully built before the next span is created in the same chunk. */ uintptr_t ddog_v1_chunk_new_span(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk); /** - * Sets the span service (interned id). + * Sets the span service. */ void ddog_v1_set_span_service(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t id); + ddog_CharSlice value); /** - * Sets the span name (interned id). + * Sets the span name. */ void ddog_v1_set_span_name(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t id); + ddog_CharSlice value); /** - * Sets the span resource (interned id). + * Sets the span resource. */ void ddog_v1_set_span_resource(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t id); + ddog_CharSlice value); /** - * Sets the span type (interned id). + * Sets the span type. */ void ddog_v1_set_span_type(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t id); + ddog_CharSlice value); /** - * Sets the span env (interned id). + * Sets the span env. */ void ddog_v1_set_span_env(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t id); + ddog_CharSlice value); /** - * Sets the span version (interned id). + * Sets the span version. */ void ddog_v1_set_span_version(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t id); + ddog_CharSlice value); /** - * Sets the span component (interned id). + * Sets the span component. */ void ddog_v1_set_span_component(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t id); + ddog_CharSlice value); /** * Sets the span id. @@ -874,51 +885,91 @@ void ddog_v1_set_span_kind(struct ddog_TracerPayloadV1Builder *builder, uint32_t kind); /** - * Adds a string span attribute (key and value are interned ids). + * Adds a string span attribute. */ void ddog_v1_add_span_attr_str(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t key_id, - uint32_t value); + ddog_CharSlice key, + ddog_CharSlice value); /** - * Adds an integer span attribute (key is an interned id). + * Adds an integer span attribute. */ void ddog_v1_add_span_attr_int(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t key_id, + ddog_CharSlice key, int64_t value); /** - * Adds a double span attribute (key is an interned id). + * Adds a double span attribute. */ void ddog_v1_add_span_attr_double(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t key_id, + ddog_CharSlice key, double value); /** - * Adds a boolean span attribute (key is an interned id). + * Adds a boolean span attribute. */ void ddog_v1_add_span_attr_bool(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t key_id, + ddog_CharSlice key, bool value); /** - * Adds a bytes-valued span attribute. The key is an interned id; the value bytes are copied - * verbatim (not interned) and encoded as msgpack `bin`. + * Adds a bytes-valued span attribute. The value bytes are copied verbatim and encoded as msgpack + * `bin`. */ void ddog_v1_add_span_attr_bytes(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, - uint32_t key_id, + ddog_CharSlice key, ddog_CharSlice value); +/** + * Returns whether the span carries an attribute under `key`. Mirrors the v0.4 + * `ddog_has_span_meta`/`ddog_has_span_metrics` existence checks used to avoid overwriting a value + * business logic already set (the span-array flatteners only add a key when it is absent). + */ +bool ddog_v1_has_span_attr(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + ddog_CharSlice key); + +/** + * Removes the attribute under `key` from the span, returning whether it was present. Mirrors the + * v0.4 `ddog_del_span_meta_str`/`ddog_del_span_metrics_str` deletes (e.g. dropping `error.ignored` + * after finalization). + */ +bool ddog_v1_del_span_attr(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + ddog_CharSlice key); + +/** + * Copies the attribute under `key` from `from_span` onto `to_span` (both within `chunk`), returning + * whether the source carried it. When `delete_source` is set, the attribute is also removed from + * `from_span`. Replicates the v0.4 `transfer_meta_data`/`transfer_metrics_data` helpers used in the + * inferred-span merge (data moves from the root span into the inferred/proxy span); the unified V1 + * attribute map subsumes both the string `meta` and numeric `metrics` cases with a single, + * type-preserving copy. + * + * The read (clone of the source value) completes before any mutable borrow, so the whole operation + * is routed through the single `&mut TracerPayloadV1Builder` without aliasing. A missing source key + * or a missing destination span is a no-op returning `false` (nothing is deleted from the source in + * that case). + */ +bool ddog_v1_transfer_span_attr(struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t from_span, + uintptr_t to_span, + ddog_CharSlice key, + bool delete_source); + /** * Appends a new (empty) link to a span, returning its index within that span. */ @@ -955,23 +1006,23 @@ void ddog_v1_set_link_flags(struct ddog_TracerPayloadV1Builder *builder, uint32_t value); /** - * Sets the link tracestate (interned id). + * Sets the link tracestate. */ void ddog_v1_set_link_tracestate(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, uintptr_t link, - uint32_t id); + ddog_CharSlice value); /** - * Adds a string-valued link attribute (key and value are interned ids). + * Adds a string-valued link attribute. */ void ddog_v1_add_link_attr_str(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, uintptr_t link, - uint32_t key_id, - uint32_t value_id); + ddog_CharSlice key, + ddog_CharSlice value); /** * Appends a new (empty) event to a span, returning its index within that span. @@ -990,52 +1041,440 @@ void ddog_v1_set_event_time(struct ddog_TracerPayloadV1Builder *builder, uint64_t time_unix_nano); /** - * Sets the event name (interned id). + * Sets the event name. */ void ddog_v1_set_event_name(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, uintptr_t event, - uint32_t id); + ddog_CharSlice value); /** - * Adds a string event attribute (key and value are interned ids). + * Adds a string event attribute. */ void ddog_v1_add_event_attr_str(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, uintptr_t event, - uint32_t key_id, - uint32_t value); + ddog_CharSlice key, + ddog_CharSlice value); /** - * Adds an integer event attribute (key is an interned id). + * Adds an integer event attribute. */ void ddog_v1_add_event_attr_int(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, uintptr_t event, - uint32_t key_id, + ddog_CharSlice key, int64_t value); /** - * Adds a double event attribute (key is an interned id). + * Adds a double event attribute. */ void ddog_v1_add_event_attr_double(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, uintptr_t event, - uint32_t key_id, + ddog_CharSlice key, double value); /** - * Adds a boolean event attribute (key is an interned id). + * Adds a boolean event attribute. */ void ddog_v1_add_event_attr_bool(struct ddog_TracerPayloadV1Builder *builder, uintptr_t chunk, uintptr_t span, uintptr_t event, - uint32_t key_id, + ddog_CharSlice key, bool value); +/** + * Number of chunks in the builder. + */ +uintptr_t ddog_v1_get_chunk_count(const struct ddog_TracerPayloadV1Builder *builder); + +/** + * Number of spans in `chunk`. + */ +uintptr_t ddog_v1_get_span_count(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk); + +/** + * Number of links on a span. + */ +uintptr_t ddog_v1_get_link_count(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * Number of events on a span. + */ +uintptr_t ddog_v1_get_event_count(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * High 64 bits of the chunk's 128-bit trace id. + */ +uint64_t ddog_v1_get_chunk_trace_id_high(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk); + +/** + * Low 64 bits of the chunk's 128-bit trace id. + */ +uint64_t ddog_v1_get_chunk_trace_id_low(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk); + +/** + * Reads the chunk sampling priority; returns `false` (and leaves `out` untouched) when unset. + */ +bool ddog_v1_get_chunk_sampling_priority(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + int32_t *out); + +/** + * Reads the chunk sampling mechanism; returns `false` (and leaves `out` untouched) when unset. + */ +bool ddog_v1_get_chunk_sampling_mechanism(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uint32_t *out); + +/** + * The chunk origin (empty if unset). + */ +ddog_CharSlice ddog_v1_get_chunk_origin(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk); + +/** + * Whether the chunk is a dropped (p0) trace. + */ +bool ddog_v1_get_chunk_dropped_trace(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk); + +/** + * Number of chunk-level attributes. + */ +uintptr_t ddog_v1_get_chunk_attr_count(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk); + +/** + * Key of the chunk attribute at `idx`. + */ +ddog_CharSlice ddog_v1_get_chunk_attr_key(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t idx); + +/** + * [`DDOG_V1_ATTR_*`] type tag of the chunk attribute at `idx`. + */ +uint32_t ddog_v1_get_chunk_attr_type(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t idx); + +/** + * String value of the chunk attribute at `idx` (empty unless it is a string). + */ +ddog_CharSlice ddog_v1_get_chunk_attr_str(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t idx); + +/** + * The span service (empty if unset). + */ +ddog_CharSlice ddog_v1_get_span_service(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span name (empty if unset). + */ +ddog_CharSlice ddog_v1_get_span_name(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span resource (empty if unset). + */ +ddog_CharSlice ddog_v1_get_span_resource(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span type (empty if unset). + */ +ddog_CharSlice ddog_v1_get_span_type(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span env (empty if unset). + */ +ddog_CharSlice ddog_v1_get_span_env(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span version (empty if unset). + */ +ddog_CharSlice ddog_v1_get_span_version(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span component (empty if unset). + */ +ddog_CharSlice ddog_v1_get_span_component(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span id. + */ +uint64_t ddog_v1_get_span_id(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span parent id. + */ +uint64_t ddog_v1_get_span_parent_id(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span start time (unix nanos). + */ +int64_t ddog_v1_get_span_start(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span duration (nanos). + */ +int64_t ddog_v1_get_span_duration(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span error flag. + */ +bool ddog_v1_get_span_error(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * The span kind as its OTEL wire value. + */ +uint32_t ddog_v1_get_span_kind(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * Number of attributes on a span. + */ +uintptr_t ddog_v1_get_span_attr_count(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + +/** + * Key of the span attribute at `idx`. + */ +ddog_CharSlice ddog_v1_get_span_attr_key(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t idx); + +/** + * [`DDOG_V1_ATTR_*`] type tag of the span attribute at `idx`. + */ +uint32_t ddog_v1_get_span_attr_type(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t idx); + +/** + * String value of the span attribute at `idx` (empty unless it is a string). + */ +ddog_CharSlice ddog_v1_get_span_attr_str(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t idx); + +/** + * Integer value of the span attribute at `idx` (0 unless it is an int). + */ +int64_t ddog_v1_get_span_attr_int(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t idx); + +/** + * Double value of the span attribute at `idx` (0.0 unless it is a double). + */ +double ddog_v1_get_span_attr_double(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t idx); + +/** + * Boolean value of the span attribute at `idx` (false unless it is a true bool). + */ +bool ddog_v1_get_span_attr_bool(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t idx); + +/** + * Bytes value of the span attribute at `idx` (empty unless it is a bytes value). + */ +ddog_CharSlice ddog_v1_get_span_attr_bytes(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t idx); + +/** + * High 64 bits of the link's 128-bit trace id. + */ +uint64_t ddog_v1_get_link_trace_id_high(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link); + +/** + * Low 64 bits of the link's 128-bit trace id. + */ +uint64_t ddog_v1_get_link_trace_id_low(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link); + +/** + * The link span id. + */ +uint64_t ddog_v1_get_link_span_id(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link); + +/** + * The link flags. + */ +uint32_t ddog_v1_get_link_flags(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link); + +/** + * The link tracestate (empty if unset). + */ +ddog_CharSlice ddog_v1_get_link_tracestate(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link); + +/** + * Number of attributes on a link. + */ +uintptr_t ddog_v1_get_link_attr_count(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link); + +/** + * Key of the link attribute at `idx`. + */ +ddog_CharSlice ddog_v1_get_link_attr_key(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link, + uintptr_t idx); + +/** + * String value of the link attribute at `idx` (empty unless it is a string). + */ +ddog_CharSlice ddog_v1_get_link_attr_str(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t link, + uintptr_t idx); + +/** + * The event time (unix nanos). + */ +uint64_t ddog_v1_get_event_time(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event); + +/** + * The event name (empty if unset). + */ +ddog_CharSlice ddog_v1_get_event_name(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event); + +/** + * Number of attributes on an event. + */ +uintptr_t ddog_v1_get_event_attr_count(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event); + +/** + * Key of the event attribute at `idx`. + */ +ddog_CharSlice ddog_v1_get_event_attr_key(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uintptr_t idx); + +/** + * [`DDOG_V1_ATTR_*`] type tag of the event attribute at `idx`. + */ +uint32_t ddog_v1_get_event_attr_type(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uintptr_t idx); + +/** + * String value of the event attribute at `idx` (empty unless it is a string). + */ +ddog_CharSlice ddog_v1_get_event_attr_str(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uintptr_t idx); + +/** + * Integer value of the event attribute at `idx` (0 unless it is an int). + */ +int64_t ddog_v1_get_event_attr_int(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uintptr_t idx); + +/** + * Double value of the event attribute at `idx` (0.0 unless it is a double). + */ +double ddog_v1_get_event_attr_double(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uintptr_t idx); + +/** + * Boolean value of the event attribute at `idx` (false unless it is a true bool). + */ +bool ddog_v1_get_event_attr_bool(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span, + uintptr_t event, + uintptr_t idx); + #endif /* DDOG_SIDECAR_H */ diff --git a/ext/agent_info.c b/ext/agent_info.c index 4bea66668df..871fef24164 100644 --- a/ext/agent_info.c +++ b/ext/agent_info.c @@ -29,3 +29,18 @@ void datadog_apply_agent_info(void) { zend_string_release(hash_str); } } + +bool ddtrace_agent_supports_v1_traces(void) { + if (!DATADOG_G(agent_info_reader)) { + return false; + } + // The agent /info payload lists supported endpoints (e.g. "endpoints":["/v0.4/traces", + // "/v1.0/traces",...]); a substring probe of that JSON is sufficient to gate the transcode. + char *json = ddog_agent_info_as_json(DATADOG_G(agent_info_reader)); + if (!json) { + return false; + } + bool supported = strstr(json, "/v1.0/traces") != NULL; + ddog_agent_info_json_free(json); + return supported; +} diff --git a/ext/agent_info.h b/ext/agent_info.h index 476248ef587..b137639a8b0 100644 --- a/ext/agent_info.h +++ b/ext/agent_info.h @@ -7,4 +7,8 @@ void datadog_agent_info_rinit(void); void datadog_apply_agent_info(void); +// Removable v0.4->v1 bolt-on for the in-process (<=8.2) sender: true when the agent advertises the +// /v1.0/traces endpoint in its /info payload. Deleting the V1 in-process transcode == deleting this. +bool ddtrace_agent_supports_v1_traces(void); + #endif // DATADOG_AGENT_INFO_H diff --git a/libdatadog b/libdatadog index 594d5c2abac..fef26d167fa 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 594d5c2abac76f3ad0f8bf28a680b87e93696c77 +Subproject commit fef26d167fabf8f70e0f194a9ef1a7c6fc8dcbdf diff --git a/tracer/auto_flush.c b/tracer/auto_flush.c index 0e4b1735211..8518dc68189 100644 --- a/tracer/auto_flush.c +++ b/tracer/auto_flush.c @@ -7,6 +7,7 @@ #include "coms.h" #endif #include "configuration.h" +#include #include #include #include @@ -26,8 +27,8 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles bool success = true; // The sidecar sender always emits the native V1 wire (the sidecar negotiates V1-vs-V0.4 with the - // agent and downgrades if needed). We build the native V1 payload alongside the V0.4 traces: the - // V0.4 ddog_SpanBytes serve as the intermediate representation that dd_v1_convert_span reads back. + // agent and downgrades if needed). On this path serialization builds the native V1 payload + // directly into the builder (no V0.4 intermediate); the in-process (<=8.2) path builds V0.4. bool use_sidecar = get_global_DD_TRACE_SIDECAR_TRACE_SENDER() && DATADOG_G(sidecar); ddtrace_v1_ctx v1_ctx = {.builder = NULL, .chunk = DD_V1_CHUNK_NONE}; ddtrace_v1_ctx *v1 = NULL; @@ -52,7 +53,10 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles return SUCCESS; } - if (!ddog_get_traces_size(traces)) { + // On the V1 path spans are built into the builder, not the (empty) V0.4 traces, so gate on the + // builder's chunk count instead. + size_t payload_count = v1 ? ddog_v1_get_chunk_count(v1->builder) : ddog_get_traces_size(traces); + if (!payload_count) { if (v1) ddog_v1_free_builder(v1->builder); ddog_free_traces(traces); LOG(INFO, "No finished traces to be sent to the agent"); @@ -103,30 +107,67 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles } } else { #ifndef _WIN32 - success = true; - size_t length = ddog_get_traces_size(traces); - for (size_t i = 0; i < length; i++) { - ddog_TraceBytes *trace = ddog_get_trace(traces, i); - ddog_CharSlice serialized_trace = ddog_serialize_trace_into_charslice(trace); - - if (serialized_trace.len > 0) { - if (serialized_trace.len > limit) { - LOG(ERROR, "Agent request payload of %zu bytes exceeds configured %zu byte limit; dropping request", serialized_trace.len, limit); - success = false; - } else { - success = ddtrace_send_traces_via_thread(1, serialized_trace.ptr, serialized_trace.len); - if (success) { - LOGEV(INFO, { - log("Flushing trace of size %d to send-queue for %s", ddog_get_trace_size(trace), url); - }); - } - dd_prepare_for_new_trace(); + // Removable v0.4->v1 bolt-on: the in-process (<=8.2) sender builds V0.4 (above); if the agent + // advertises /v1.0/traces we transcode the already-built V0.4 collection into a single native + // V1 payload and POST it to /v1.0/traces, otherwise we POST the V0.4 bytes to /v0.4/traces. + // Deleting this whole `if (send_v1)` branch + the endpoint flag reverts to V0.4-only. + bool send_v1 = ddtrace_agent_supports_v1_traces(); + ddtrace_coms_set_v1_traces_endpoint(send_v1); + if (send_v1) { + uint8_t formatted_runtime_id[36]; + datadog_format_runtime_id(&formatted_runtime_id); + ddog_TracerMetadataV1 metadata = { + .hostname = dd_zend_string_to_CharSlice(get_DD_HOSTNAME()), + .env = dd_zend_string_to_CharSlice(get_DD_ENV()), + .app_version = dd_zend_string_to_CharSlice(get_DD_VERSION()), + .runtime_id = (ddog_CharSlice) {.ptr = (char *) formatted_runtime_id, .len = sizeof(formatted_runtime_id)}, + .git_commit_sha = dd_zend_string_to_CharSlice(get_DD_GIT_COMMIT_SHA()), + }; + ddog_CharSlice container_id = ddtrace_get_container_id(); + ddog_CharSlice payload = ddog_serialize_trace_v04_as_v1_into_charslice( + traces, &metadata, container_id, DDOG_CHARSLICE_C("php"), php_version_rt, + DDOG_CHARSLICE_C(PHP_DDTRACE_VERSION)); + if (payload.len > 0 && payload.len <= limit) { + success = ddtrace_send_traces_via_thread(ddog_get_traces_size(traces), payload.ptr, payload.len); + if (success) { + LOGEV(INFO, { + log("Flushing V1 payload of %zu bytes to send-queue for %s/v1.0/traces", payload.len, url); + }); } - - ddog_free_charslice(serialized_trace); + dd_prepare_for_new_trace(); } else { + if (payload.len > limit) { + LOG(ERROR, "Agent request payload of %zu bytes exceeds configured %zu byte limit; dropping request", payload.len, limit); + } success = false; } + ddog_free_charslice(payload); + } else { + success = true; + size_t length = ddog_get_traces_size(traces); + for (size_t i = 0; i < length; i++) { + ddog_TraceBytes *trace = ddog_get_trace(traces, i); + ddog_CharSlice serialized_trace = ddog_serialize_trace_into_charslice(trace); + + if (serialized_trace.len > 0) { + if (serialized_trace.len > limit) { + LOG(ERROR, "Agent request payload of %zu bytes exceeds configured %zu byte limit; dropping request", serialized_trace.len, limit); + success = false; + } else { + success = ddtrace_send_traces_via_thread(1, serialized_trace.ptr, serialized_trace.len); + if (success) { + LOGEV(INFO, { + log("Flushing trace of size %d to send-queue for %s", ddog_get_trace_size(trace), url); + }); + } + dd_prepare_for_new_trace(); + } + + ddog_free_charslice(serialized_trace); + } else { + success = false; + } + } } #else success = false; diff --git a/tracer/coms.c b/tracer/coms.c index 28aa5a375dc..4afdc651b3b 100644 --- a/tracer/coms.c +++ b/tracer/coms.c @@ -750,6 +750,15 @@ static ddtrace_coms_stack_t *dd_coms_attempt_acquire_stack(void) { } #define TRACE_PATH_STR "/v0.4/traces" +#define TRACE_PATH_V1_STR "/v1.0/traces" + +// Removable v0.4->v1 bolt-on: when set, the writer POSTs the (transcoded) V1 payload to /v1.0/traces +// instead of /v0.4/traces. Toggled per flush by auto_flush from the agent-capability check. +static _Atomic(bool) dd_coms_use_v1_traces_endpoint = ATOMIC_VAR_INIT(false); + +void ddtrace_coms_set_v1_traces_endpoint(bool enabled) { + atomic_store(&dd_coms_use_v1_traces_endpoint, enabled); +} static struct curl_slist *dd_agent_curl_headers = NULL; @@ -891,7 +900,8 @@ static void ddtrace_curl_set_hostname_generic(CURL *curl, const char *path) { } void ddtrace_curl_set_hostname(CURL *curl) { - ddtrace_curl_set_hostname_generic(curl, TRACE_PATH_STR); + const char *path = atomic_load(&dd_coms_use_v1_traces_endpoint) ? TRACE_PATH_V1_STR : TRACE_PATH_STR; + ddtrace_curl_set_hostname_generic(curl, path); } void ddtrace_curl_set_telemetry_url(CURL *curl) { diff --git a/tracer/coms.h b/tracer/coms.h index b8080f3c69f..ae150916dfd 100644 --- a/tracer/coms.h +++ b/tracer/coms.h @@ -82,6 +82,10 @@ uint32_t ddtrace_coms_test_consumer(void); uint32_t ddtrace_coms_test_msgpack_consumer(void); /* }}} */ +// Removable v0.4->v1 bolt-on: selects the agent trace endpoint the in-process writer POSTs to +// (/v1.0/traces when true, else /v0.4/traces). Set per flush from the agent-capability check. +void ddtrace_coms_set_v1_traces_endpoint(bool enabled); + /* exposed for diagnostics {{{ */ void ddtrace_curl_set_hostname(CURL *curl); void ddtrace_curl_set_telemetry_url(CURL *curl); diff --git a/tracer/exception_serialize.c b/tracer/exception_serialize.c index 738dd4e9174..0093823ac03 100644 --- a/tracer/exception_serialize.c +++ b/tracer/exception_serialize.c @@ -16,7 +16,7 @@ ZEND_EXTERN_MODULE_GLOBALS(datadog); -static void dd_exception_to_error_msg(zend_object *exception, ddog_SpanBytes *span, enum dd_exception exception_state) { +static void dd_exception_to_error_msg(zend_object *exception, dd_span_sink *span, enum dd_exception exception_state) { zend_string *msg = zai_exception_message(exception); zend_long line = zval_get_long(zai_exception_read_property(exception, ZSTR_KNOWN(ZEND_STR_LINE))); zend_string *file = datadog_convert_to_str(zai_exception_read_property(exception, ZSTR_KNOWN(ZEND_STR_FILE))); @@ -42,14 +42,14 @@ static void dd_exception_to_error_msg(zend_object *exception, ddog_SpanBytes *sp ZSTR_VAL(exception->ce->name), status_line ? status_line : "", ZSTR_LEN(msg) > 0 ? ": " : "", ZSTR_VAL(msg), ZSTR_VAL(file), line); - ddog_add_str_span_meta_CharSlice(span, "error.message", (ddog_CharSlice){.ptr = error_text, .len = len}); + dd_sink_meta_str_cs(span, "error.message", (ddog_CharSlice){.ptr = error_text, .len = len}); zend_string_release(file); free(error_text); free(status_line); } -static void dd_exception_to_error_type(zend_object *exception, ddog_SpanBytes *span) { +static void dd_exception_to_error_type(zend_object *exception, dd_span_sink *span) { if (instanceof_function(exception->ce, ddtrace_ce_fatal_error)) { zval *code = zai_exception_read_property(exception, ZSTR_KNOWN(ZEND_STR_CODE)); const char *error_type_string = "{unknown error}"; @@ -76,14 +76,14 @@ static void dd_exception_to_error_type(zend_object *exception, ddog_SpanBytes *s LOG_UNREACHABLE("Exception was a DDTrace\\FatalError but failed to get an exception code"); } - ddog_add_str_span_meta_str(span, "error.type", error_type_string); + dd_sink_meta_str_str(span, "error.type", error_type_string); } else { - ddog_add_str_span_meta_zstr(span, "error.type", exception->ce->name); + dd_sink_meta_str_zstr(span, "error.type", exception->ce->name); } } -static void dd_exception_trace_to_error_stack(zend_string *trace, ddog_SpanBytes *span) { - ddog_add_str_span_meta_zstr(span, "error.stack", trace); +static void dd_exception_trace_to_error_stack(zend_string *trace, dd_span_sink *span) { + dd_sink_meta_str_zstr(span, "error.stack", trace); zend_string_release(trace); } @@ -309,13 +309,13 @@ void ddtrace_create_capture_value(zval *zv, struct ddog_CaptureValue *value, con #define uuid_len 36 #define hash_len 16 -static ddog_DebuggerCapture *dd_create_frame_and_collect_locals(char *exception_id, char *exception_hash, int frame_num, ddog_CharSlice class_slice, ddog_CharSlice func_slice, zval *locals, zend_string *service_name, const ddog_CaptureConfiguration *capture_config, uint64_t time, ddog_SpanBytes *span) { +static ddog_DebuggerCapture *dd_create_frame_and_collect_locals(char *exception_id, char *exception_hash, int frame_num, ddog_CharSlice class_slice, ddog_CharSlice func_slice, zval *locals, zend_string *service_name, const ddog_CaptureConfiguration *capture_config, uint64_t time, dd_span_sink *span) { char *snapshot_id = zend_arena_alloc(&DDTRACE_G(debugger_capture_arena).arena, uuid_len); ddog_snapshot_format_new_uuid((uint8_t(*)[uuid_len])snapshot_id); char *msg = zend_arena_alloc(&DDTRACE_G(debugger_capture_arena).arena, 40); int len = sprintf(msg, "_dd.debug.error.%d.snapshot_id", frame_num); - ddog_add_span_meta(span, (ddog_CharSlice){.ptr = msg, .len = len}, (ddog_CharSlice){.ptr = snapshot_id, .len = uuid_len}); + dd_sink_meta_cs_cs(span, (ddog_CharSlice){.ptr = msg, .len = len}, (ddog_CharSlice){.ptr = snapshot_id, .len = uuid_len}); ddog_DebuggerCapture *capture = ddog_create_exception_snapshot(&DDTRACE_G(exception_debugger_buffer), (ddog_CharSlice){ .ptr = ZSTR_VAL(service_name), .len = ZSTR_LEN(service_name) }, @@ -388,7 +388,7 @@ static bool ddtrace_exception_debugging_is_active(void) { return DATADOG_G(sidecar) && datadog_sidecar_instance_id && get_DD_EXCEPTION_REPLAY_ENABLED(); } -static void ddtrace_collect_exception_debug_data(zend_object *exception, zend_object *throwable, zend_string *service_name, uint64_t time, ddog_SpanBytes *span) { +static void ddtrace_collect_exception_debug_data(zend_object *exception, zend_object *throwable, zend_string *service_name, uint64_t time, dd_span_sink *span) { if (!ddtrace_exception_debugging_is_active()) { return; } @@ -412,8 +412,8 @@ static void ddtrace_collect_exception_debug_data(zend_object *exception, zend_ob zend_ulong exception_long_hash = ddtrace_compute_exception_hash(exception); php_hash_bin2hex(exception_hash, (unsigned char *)&exception_long_hash, sizeof(exception_long_hash)); - ddog_add_str_span_meta_str(span, "error.debug_info_captured", "true"); - ddog_add_str_span_meta_CharSlice(span, "_dd.debug.error.exception_hash", (ddog_CharSlice){.ptr = exception_hash, .len = hash_len}); + dd_sink_meta_str_str(span, "error.debug_info_captured", "true"); + dd_sink_meta_str_cs(span, "_dd.debug.error.exception_hash", (ddog_CharSlice){.ptr = exception_hash, .len = hash_len}); if (!ddog_exception_hash_limiter_inc(DATADOG_G(sidecar), (uint64_t)exception_long_hash, get_DD_EXCEPTION_REPLAY_CAPTURE_INTERVAL_SECONDS())) { LOG(TRACE, "Skipping exception replay capture due to hash %.*s already recently hit", hash_len, exception_hash); @@ -423,7 +423,7 @@ static void ddtrace_collect_exception_debug_data(zend_object *exception, zend_ob char *exception_id = zend_arena_alloc(&DDTRACE_G(debugger_capture_arena).arena, uuid_len); ddog_snapshot_format_new_uuid((uint8_t(*)[uuid_len])exception_id); - ddog_add_str_span_meta_CharSlice(span, "_dd.debug.error.exception_id", (ddog_CharSlice){.ptr = exception_id, .len = uuid_len}); + dd_sink_meta_str_cs(span, "_dd.debug.error.exception_id", (ddog_CharSlice){.ptr = exception_id, .len = uuid_len}); memset(&DDTRACE_G(exception_debugger_buffer), 0, sizeof(DDTRACE_G(exception_debugger_buffer))); @@ -536,7 +536,7 @@ static void ddtrace_collect_exception_debug_data(zend_object *exception, zend_ob } // Guarantees that tag will only be added once, will stop trying to add tags if it fails. -void ddtrace_exception_to_meta(zend_object *exception, zend_string *service_name, uint64_t time, ddog_SpanBytes *span, enum dd_exception exception_state) { +void ddtrace_exception_to_meta(zend_object *exception, zend_string *service_name, uint64_t time, dd_span_sink *span, enum dd_exception exception_state) { zend_object *exception_root = exception; zend_string *full_trace = zai_get_trace_without_args_from_exception(exception); diff --git a/tracer/exception_serialize.h b/tracer/exception_serialize.h index 38f1a1fb3f0..d66f4dd8051 100644 --- a/tracer/exception_serialize.h +++ b/tracer/exception_serialize.h @@ -9,7 +9,7 @@ enum dd_exception { DD_EXCEPTION_UNCAUGHT, }; -void ddtrace_exception_to_meta(zend_object *exception, zend_string *service_name, uint64_t time, ddog_SpanBytes *context, enum dd_exception exception_state); +void ddtrace_exception_to_meta(zend_object *exception, zend_string *service_name, uint64_t time, dd_span_sink *context, enum dd_exception exception_state); void ddtrace_create_capture_value(zval *zv, struct ddog_CaptureValue *value, const ddog_CaptureConfiguration *config, int remaining_nesting); #endif // DD_EXCEPTION_REPLAY_H diff --git a/tracer/functions.c b/tracer/functions.c index 48c91d06021..0097c19a113 100644 --- a/tracer/functions.c +++ b/tracer/functions.c @@ -12,6 +12,7 @@ #ifdef __linux__ #include "otel_context.h" #include +#include #endif #include "random.h" #include "serializer.h" @@ -1101,10 +1102,23 @@ PHP_FUNCTION(dd_trace_serialize_closed_spans) { ddtrace_mark_all_span_stacks_flushable(); + // Mirror the send path: on the sidecar/V1 path spans are finalized directly into the native V1 + // builder and introspected via the V1 getters (V1-shaped array); otherwise use the V0.4 model. + bool use_sidecar = get_global_DD_TRACE_SIDECAR_TRACE_SENDER() && DATADOG_G(sidecar); + ddtrace_v1_ctx v1_ctx = {.builder = NULL, .chunk = DD_V1_CHUNK_NONE}; + ddtrace_v1_ctx *v1 = NULL; + if (use_sidecar) { + v1_ctx.builder = ddog_v1_new_builder(); + v1 = &v1_ctx; + } + ddog_TracesBytes *traces = ddog_get_traces(); - ddtrace_serialize_closed_spans_with_cycle(traces, NULL, false); + ddtrace_serialize_closed_spans_with_cycle(traces, v1, false); - zval traces_zv = dd_serialize_rust_traces_to_zval(traces); + zval traces_zv = v1 ? dd_serialize_rust_v1_to_zval(v1->builder) : dd_serialize_rust_traces_to_zval(traces); + if (v1) { + ddog_v1_free_builder(v1->builder); + } if (zend_hash_num_elements(Z_ARR(traces_zv)) == 1) { ZVAL_COPY(return_value, zend_hash_get_current_data(Z_ARR(traces_zv))); diff --git a/tracer/serializer.c b/tracer/serializer.c index 52a4361d468..94cbffa8ae6 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -328,7 +328,11 @@ static void dd_add_header_to_meta(zend_array *meta, const char *type, zend_strin } } -static void dd_add_header_to_rust_span(ddog_SpanBytes *span, const char *type, zend_string *lowerheader, +// Sink write ops (defined below) used by helpers that precede the sink-ops section. +void dd_sink_meta_str_zstr(dd_span_sink *s, const char *key, zend_string *val); +static inline void dd_sink_meta_zstr_zstr(dd_span_sink *s, zend_string *key, zend_string *val); + +static void dd_add_header_to_rust_span(dd_span_sink *span, const char *type, zend_string *lowerheader, zend_string *headerval) { zval *header_config = zend_hash_find(get_DD_TRACE_HEADER_TAGS(), lowerheader); if (header_config != NULL && Z_TYPE_P(header_config) == IS_STRING) { @@ -345,7 +349,7 @@ static void dd_add_header_to_rust_span(ddog_SpanBytes *span, const char *type, z headertag = zend_string_copy(header_config_str); } - ddog_add_span_meta_zstr(span, headertag, headerval); + dd_sink_meta_zstr_zstr(span, headertag, headerval); zend_string_release(headertag); } } @@ -576,7 +580,7 @@ static zend_string *dd_get_referrer_host(zend_array *_server) { return ZSTR_EMPTY_ALLOC(); } -static bool dd_set_mapped_peer_service(ddog_SpanBytes *span, zend_string *peer_service) { +static bool dd_set_mapped_peer_service(dd_span_sink *span, zend_string *peer_service) { zend_array *peer_service_mapping = get_DD_TRACE_PEER_SERVICE_MAPPING(); if (zend_hash_num_elements(peer_service_mapping) == 0 || !peer_service) { return false; @@ -585,8 +589,8 @@ static bool dd_set_mapped_peer_service(ddog_SpanBytes *span, zend_string *peer_s zval* mapped_service_zv = zend_hash_find(peer_service_mapping, peer_service); if (mapped_service_zv) { zend_string *mapped_service = zval_get_string(mapped_service_zv); - ddog_add_str_span_meta_zstr(span, "peer.service.remapped_from", peer_service); - ddog_add_str_span_meta_zstr(span, "peer.service", mapped_service); + dd_sink_meta_str_zstr(span, "peer.service.remapped_from", peer_service); + dd_sink_meta_str_zstr(span, "peer.service", mapped_service); zend_string_release(mapped_service); return true; } @@ -1088,12 +1092,14 @@ static void dd_serialize_span_events(zend_array *events, smart_str *buf) { zval_ptr_dtor(&tmp); } -// --- Native V1 payload build (sidecar path) --- -// The sidecar always sends the native V1 wire. We reuse the completed V0.4 ddog_SpanBytes (built by -// ddtrace_serialize_span_to_rust_span with all tag/business logic intact) as the intermediate -// representation and convert it into the V1 builder via the V0.4 read getters, plus read native -// links/events directly from the still-alive PHP span. This keeps the V0.4 wire (in-process sender -// + functions.c introspection) byte-for-byte unchanged and avoids duplicating the serializer. +// --- Span finalization sink (v0.4 vs native V1) --- +// ddtrace_serialize_span_to_rust_span runs one finalization body and routes every field/meta/metrics +// write through a dd_span_sink. On the in-process (<=8.2) path the sink targets a V0.4 ddog_SpanBytes +// (also read back by functions.c introspection); on the sidecar path it targets the native V1 builder +// chunk/span directly, with no V0.4 intermediate. The V1 routing promotes env/version/component/ +// span.kind to dedicated span setters and _dd.origin/_dd.p.dm/_sampling_priority_v1 to chunk-level +// fields (excluding them from the attribute map), and drops _dd.p.tid (carried by the chunk's 128-bit +// trace id) and the _dd.span_links/events JSON (emitted natively from the PHP span). static inline bool dd_cs_eq_lit(ddog_CharSlice s, const char *lit, size_t len) { return s.len == len && memcmp(s.ptr, lit, len) == 0; @@ -1111,35 +1117,188 @@ static uint32_t dd_span_kind_meta_to_otel(ddog_CharSlice v) { return 0; } -// The builder interns by value (equal strings share an id; empty string is id 0), so a call per -// occurrence is correct; a per-request cache is unnecessary for the getter-sourced CharSlices used -// here (they are transient Rust allocations, not stable zend_string pointers). -static inline uint32_t dd_v1_intern(ddog_TracerPayloadV1Builder *b, ddog_CharSlice s) { - return ddog_v1_intern_string(b, s); +// Route a meta (string) key to its V1 destination. Returns true when the key is consumed as a +// promoted span field or a chunk-level attribute (and therefore must NOT be added to the span +// attribute map). Mirrors the V0.4->V1 routing that dd_v1_convert_span used to apply post-hoc. +static bool dd_v1_route_meta(dd_span_sink *s, ddog_CharSlice key, ddog_CharSlice value) { + ddog_TracerPayloadV1Builder *b = s->builder; + if (DD_CS_EQ(key, "env")) { ddog_v1_set_span_env(b, s->chunk, s->span, value); return true; } + if (DD_CS_EQ(key, "version")) { ddog_v1_set_span_version(b, s->chunk, s->span, value); return true; } + if (DD_CS_EQ(key, "component")) { ddog_v1_set_span_component(b, s->chunk, s->span, value); return true; } + if (DD_CS_EQ(key, "span.kind")) { ddog_v1_set_span_kind(b, s->chunk, s->span, dd_span_kind_meta_to_otel(value)); return true; } + // Links/events are emitted natively from the PHP span, never as JSON-in-meta on the V1 path. + if (DD_CS_EQ(key, "_dd.span_links") || DD_CS_EQ(key, "events")) { return true; } + if (DD_CS_EQ(key, "_dd.origin")) { ddog_v1_set_chunk_origin(b, s->chunk, value); return true; } + if (DD_CS_EQ(key, "_dd.p.dm")) { + // v0.4 form is "-N"; the mechanism is the trailing unsigned integer. + const char *p = value.ptr; size_t n = value.len; + if (n && *p == '-') { p++; n--; } + uint32_t mech = 0; + for (size_t i = 0; i < n; i++) { if (p[i] < '0' || p[i] > '9') { mech = 0; break; } mech = mech * 10 + (uint32_t)(p[i] - '0'); } + ddog_v1_set_chunk_sampling_mechanism(b, s->chunk, mech); + return true; + } + // 128-bit trace-id high half is carried by the chunk trace id, not a span attribute. + if (DD_CS_EQ(key, "_dd.p.tid")) { return true; } + return false; +} + +// --- Sink write ops: dispatch each finalization write to the V0.4 span or the native V1 builder --- + +// The four meta-string sink ops below have external linkage: exception_serialize.c writes span meta +// through the same routing (declared in serializer.h). +void dd_sink_meta_cs_cs(dd_span_sink *s, ddog_CharSlice key, ddog_CharSlice val) { + if (s->builder) { + if (!dd_v1_route_meta(s, key, val)) ddog_v1_add_span_attr_str(s->builder, s->chunk, s->span, key, val); + } else { + ddog_add_span_meta(s->v04, key, val); + } +} +void dd_sink_meta_str_cs(dd_span_sink *s, const char *key, ddog_CharSlice val) { + if (s->builder) { + dd_sink_meta_cs_cs(s, (ddog_CharSlice){ .ptr = key, .len = strlen(key) }, val); + } else { + ddog_add_str_span_meta_CharSlice(s->v04, key, val); + } +} +void dd_sink_meta_str_str(dd_span_sink *s, const char *key, const char *val) { + if (s->builder) { + dd_sink_meta_cs_cs(s, (ddog_CharSlice){ .ptr = key, .len = strlen(key) }, (ddog_CharSlice){ .ptr = val, .len = strlen(val) }); + } else { + ddog_add_str_span_meta_str(s->v04, key, val); + } +} +void dd_sink_meta_str_zstr(dd_span_sink *s, const char *key, zend_string *val) { + if (s->builder) { + dd_sink_meta_cs_cs(s, (ddog_CharSlice){ .ptr = key, .len = strlen(key) }, dd_zend_string_to_CharSlice(val)); + } else { + ddog_add_str_span_meta_zstr(s->v04, key, val); + } } -static inline uint32_t dd_v1_intern_zstr(ddog_TracerPayloadV1Builder *b, zend_string *s) { - return ddog_v1_intern_string(b, dd_zend_string_to_CharSlice(s)); +static inline void dd_sink_meta_zstr_str(dd_span_sink *s, zend_string *key, const char *val) { + if (s->builder) { + dd_sink_meta_cs_cs(s, dd_zend_string_to_CharSlice(key), (ddog_CharSlice){ .ptr = val, .len = strlen(val) }); + } else { + ddog_add_zstr_span_meta_str(s->v04, key, val); + } +} +static inline void dd_sink_meta_zstr_zstr(dd_span_sink *s, zend_string *key, zend_string *val) { + if (s->builder) { + dd_sink_meta_cs_cs(s, dd_zend_string_to_CharSlice(key), dd_zend_string_to_CharSlice(val)); + } else { + ddog_add_span_meta_zstr(s->v04, key, val); + } +} +static inline bool dd_sink_has_meta_zstr(dd_span_sink *s, zend_string *key) { + return s->builder ? ddog_v1_has_span_attr(s->builder, s->chunk, s->span, dd_zend_string_to_CharSlice(key)) + : ddog_has_span_meta_zstr(s->v04, key); +} +static inline void dd_sink_del_meta_str(dd_span_sink *s, const char *key) { + if (s->builder) ddog_v1_del_span_attr(s->builder, s->chunk, s->span, (ddog_CharSlice){ .ptr = key, .len = strlen(key) }); + else ddog_del_span_meta_str(s->v04, key); } -// Interns a zval used as a string-valued attribute: scalars via the usual string conversion, -// arrays/objects JSON-encoded. The V1 attribute FFI has no native array/object variant, so JSON -// preserves the data (recoverable) instead of losing it to a bare "Array" cast. -static uint32_t dd_v1_intern_zval_str(ddog_TracerPayloadV1Builder *b, zval *val) { - ZVAL_DEREF(val); - if (Z_TYPE_P(val) == IS_ARRAY || Z_TYPE_P(val) == IS_OBJECT) { - smart_str buf = {0}; - zai_json_encode(&buf, val, 0); - smart_str_0(&buf); - uint32_t id = dd_v1_intern_zstr(b, buf.s ? buf.s : ZSTR_EMPTY_ALLOC()); - smart_str_free(&buf); - return id; +static inline void dd_sink_metrics_cs(dd_span_sink *s, ddog_CharSlice key, double val) { + if (s->builder) { + if (DD_CS_EQ(key, "_sampling_priority_v1")) { + ddog_v1_set_chunk_sampling_priority(s->builder, s->chunk, (int32_t)val); + } else { + ddog_v1_add_span_attr_double(s->builder, s->chunk, s->span, key, val); + } } - zend_string *s = datadog_convert_to_str(val); - uint32_t id = dd_v1_intern_zstr(b, s); - zend_string_release(s); - return id; +} +static inline void dd_sink_metrics_str(dd_span_sink *s, const char *key, double val) { + if (s->builder) dd_sink_metrics_cs(s, (ddog_CharSlice){ .ptr = key, .len = strlen(key) }, val); + else ddog_add_span_metrics_str(s->v04, key, val); +} +static inline void dd_sink_metrics_zstr(dd_span_sink *s, zend_string *key, double val) { + if (s->builder) dd_sink_metrics_cs(s, dd_zend_string_to_CharSlice(key), val); + else ddog_add_span_metrics_zstr(s->v04, key, val); +} +static inline bool dd_sink_has_metrics_zstr(dd_span_sink *s, zend_string *key) { + return s->builder ? ddog_v1_has_span_attr(s->builder, s->chunk, s->span, dd_zend_string_to_CharSlice(key)) + : ddog_has_span_metrics_zstr(s->v04, key); } +static inline void dd_sink_meta_struct_zstr_cs(dd_span_sink *s, zend_string *key, ddog_CharSlice val) { + if (s->builder) ddog_v1_add_span_attr_bytes(s->builder, s->chunk, s->span, dd_zend_string_to_CharSlice(key), val); + else ddog_add_zstr_span_meta_struct_CharSlice(s->v04, key, val); +} + +static inline void dd_sink_set_name_zstr(dd_span_sink *s, zend_string *v) { + if (s->builder) ddog_v1_set_span_name(s->builder, s->chunk, s->span, dd_zend_string_to_CharSlice(v)); + else ddog_set_span_name_zstr(s->v04, v); +} +static inline void dd_sink_set_resource_zstr(dd_span_sink *s, zend_string *v) { + if (s->builder) ddog_v1_set_span_resource(s->builder, s->chunk, s->span, dd_zend_string_to_CharSlice(v)); + else ddog_set_span_resource_zstr(s->v04, v); +} +static inline void dd_sink_set_service_zstr(dd_span_sink *s, zend_string *v) { + if (s->builder) ddog_v1_set_span_service(s->builder, s->chunk, s->span, dd_zend_string_to_CharSlice(v)); + else ddog_set_span_service_zstr(s->v04, v); +} +static inline void dd_sink_set_type_zstr(dd_span_sink *s, zend_string *v) { + if (s->builder) ddog_v1_set_span_type(s->builder, s->chunk, s->span, dd_zend_string_to_CharSlice(v)); + else ddog_set_span_type_zstr(s->v04, v); +} +static inline void dd_sink_set_error(dd_span_sink *s, int error) { + if (s->builder) ddog_v1_set_span_error(s->builder, s->chunk, s->span, error != 0); + else ddog_set_span_error(s->v04, error); +} +static inline int dd_sink_get_error(dd_span_sink *s) { + return s->builder ? (ddog_v1_get_span_error(s->builder, s->chunk, s->span) ? 1 : 0) + : ddog_get_span_error(s->v04); +} + +// Copies attribute `key` from `src` onto `dst` (both spans in the same trace); when delete_source is +// set, removes it from the source. Replicates the V0.4 transfer_meta/metrics helpers used in the +// inferred-span merge; on V1 the unified attribute map subsumes both cases in one typed op. +void transfer_span_attr(dd_span_sink *src, dd_span_sink *dst, const char *key, bool delete_source) { + if (src->builder) { + ddog_v1_transfer_span_attr(src->builder, src->chunk, src->span, dst->span, + (ddog_CharSlice){ .ptr = key, .len = strlen(key) }, delete_source); + } else { + ddog_CharSlice value = ddog_get_span_meta_str(src->v04, key); + if (value.len > 0) { + ddog_add_str_span_meta_CharSlice(dst->v04, key, value); + if (delete_source) ddog_del_span_meta_str(src->v04, key); + } + } +} +void transfer_span_metric(dd_span_sink *src, dd_span_sink *dst, const char *key, bool delete_source) { + if (src->builder) { + ddog_v1_transfer_span_attr(src->builder, src->chunk, src->span, dst->span, + (ddog_CharSlice){ .ptr = key, .len = strlen(key) }, delete_source); + } else { + double metric; + if (ddog_get_span_metrics_str(src->v04, key, &metric)) { + ddog_add_span_metrics_str(dst->v04, key, metric); + if (delete_source) ddog_del_span_metrics_str(src->v04, key); + } + } +} + +// Adds a string-valued V1 attribute from a zval: scalars via the usual string conversion, +// arrays/objects JSON-encoded (the V1 attribute FFI has no array/object variant, so JSON preserves +// the data instead of losing it to a bare "Array" cast). `add(b, chunk, span, extra, key, val)` is +// the target FFI (span or link attribute), `extra` its extra index (unused for spans). +#define DD_V1_ADD_ZVAL_STR(add_call, val_zv) \ + do { \ + zval *_v = (val_zv); \ + ZVAL_DEREF(_v); \ + if (Z_TYPE_P(_v) == IS_ARRAY || Z_TYPE_P(_v) == IS_OBJECT) { \ + smart_str _buf = {0}; \ + zai_json_encode(&_buf, _v, 0); \ + smart_str_0(&_buf); \ + add_call(dd_zend_string_to_CharSlice(_buf.s ? _buf.s : ZSTR_EMPTY_ALLOC())); \ + smart_str_free(&_buf); \ + } else { \ + zend_string *_s = datadog_convert_to_str(_v); \ + add_call(dd_zend_string_to_CharSlice(_s)); \ + zend_string_release(_s); \ + } \ + } while (0) + // Emit each SpanLink into the V1 builder span, reading from the PHP link objects (attributes are a // string map; dropped_attributes_count has no PHP-side source). static void dd_span_links_to_v1(zend_array *links, ddog_TracerPayloadV1Builder *b, uintptr_t chunk, uintptr_t span) { @@ -1161,7 +1320,7 @@ static void dd_span_links_to_v1(zend_array *links, ddog_TracerPayloadV1Builder * zval *ts = &link->property_trace_state; if (Z_TYPE_P(ts) == IS_STRING && Z_STRLEN_P(ts) > 0) { - ddog_v1_set_link_tracestate(b, chunk, span, rust_link, dd_v1_intern_zstr(b, Z_STR_P(ts))); + ddog_v1_set_link_tracestate(b, chunk, span, rust_link, dd_zend_string_to_CharSlice(Z_STR_P(ts))); } zval *attrs = &link->property_attributes; @@ -1172,26 +1331,31 @@ static void dd_span_links_to_v1(zend_array *links, ddog_TracerPayloadV1Builder * zval *aval; ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(attrs), idx, key, aval) { char numbuf[24]; - uint32_t key_id = key - ? dd_v1_intern_zstr(b, key) - : dd_v1_intern(b, (ddog_CharSlice){ .ptr = numbuf, .len = snprintf(numbuf, sizeof(numbuf), ZEND_ULONG_FMT, idx) }); - ddog_v1_add_link_attr_str(b, chunk, span, rust_link, key_id, dd_v1_intern_zval_str(b, aval)); + ddog_CharSlice key_cs = key + ? dd_zend_string_to_CharSlice(key) + : (ddog_CharSlice){ .ptr = numbuf, .len = snprintf(numbuf, sizeof(numbuf), ZEND_ULONG_FMT, idx) }; +#define DD_V1_ADD_LINK_ATTR(val_cs) ddog_v1_add_link_attr_str(b, chunk, span, rust_link, key_cs, (val_cs)) + DD_V1_ADD_ZVAL_STR(DD_V1_ADD_LINK_ATTR, aval); +#undef DD_V1_ADD_LINK_ATTR } ZEND_HASH_FOREACH_END(); } } ZEND_HASH_FOREACH_END(); } static void dd_event_attribute_to_v1(ddog_TracerPayloadV1Builder *b, uintptr_t chunk, uintptr_t span, - uintptr_t event, uint32_t key_id, zval *val) { + uintptr_t event, ddog_CharSlice key, zval *val) { ZVAL_DEREF(val); switch (Z_TYPE_P(val)) { - case IS_TRUE: ddog_v1_add_event_attr_bool(b, chunk, span, event, key_id, true); break; - case IS_FALSE: ddog_v1_add_event_attr_bool(b, chunk, span, event, key_id, false); break; - case IS_LONG: ddog_v1_add_event_attr_int(b, chunk, span, event, key_id, Z_LVAL_P(val)); break; - case IS_DOUBLE: ddog_v1_add_event_attr_double(b, chunk, span, event, key_id, Z_DVAL_P(val)); break; - default: - ddog_v1_add_event_attr_str(b, chunk, span, event, key_id, dd_v1_intern_zval_str(b, val)); + case IS_TRUE: ddog_v1_add_event_attr_bool(b, chunk, span, event, key, true); break; + case IS_FALSE: ddog_v1_add_event_attr_bool(b, chunk, span, event, key, false); break; + case IS_LONG: ddog_v1_add_event_attr_int(b, chunk, span, event, key, Z_LVAL_P(val)); break; + case IS_DOUBLE: ddog_v1_add_event_attr_double(b, chunk, span, event, key, Z_DVAL_P(val)); break; + default: { +#define DD_V1_ADD_EVENT_ATTR(val_cs) ddog_v1_add_event_attr_str(b, chunk, span, event, key, (val_cs)) + DD_V1_ADD_ZVAL_STR(DD_V1_ADD_EVENT_ATTR, val); +#undef DD_V1_ADD_EVENT_ATTR break; + } } } @@ -1209,7 +1373,7 @@ static void dd_span_events_to_v1(zend_array *events, ddog_TracerPayloadV1Builder zval *name = &event->property_name; if (Z_TYPE_P(name) == IS_STRING) { - ddog_v1_set_event_name(b, chunk, span, rust_event, dd_v1_intern_zstr(b, Z_STR_P(name))); + ddog_v1_set_event_name(b, chunk, span, rust_event, dd_zend_string_to_CharSlice(Z_STR_P(name))); } zval *time = &event->property_timestamp; ZVAL_DEREF(time); @@ -1224,13 +1388,13 @@ static void dd_span_events_to_v1(zend_array *events, ddog_TracerPayloadV1Builder zend_string *message = zai_exception_message(Z_OBJ_P(exception)); if (ZSTR_LEN(message)) { ddog_v1_add_event_attr_str(b, chunk, span, rust_event, - dd_v1_intern(b, DDOG_CHARSLICE_C("exception.message")), dd_v1_intern_zstr(b, message)); + DDOG_CHARSLICE_C("exception.message"), dd_zend_string_to_CharSlice(message)); } ddog_v1_add_event_attr_str(b, chunk, span, rust_event, - dd_v1_intern(b, DDOG_CHARSLICE_C("exception.type")), dd_v1_intern_zstr(b, Z_OBJCE_P(exception)->name)); + DDOG_CHARSLICE_C("exception.type"), dd_zend_string_to_CharSlice(Z_OBJCE_P(exception)->name)); zend_string *stacktrace = zai_get_trace_without_args_from_exception(Z_OBJ_P(exception)); ddog_v1_add_event_attr_str(b, chunk, span, rust_event, - dd_v1_intern(b, DDOG_CHARSLICE_C("exception.stacktrace")), dd_v1_intern_zstr(b, stacktrace)); + DDOG_CHARSLICE_C("exception.stacktrace"), dd_zend_string_to_CharSlice(stacktrace)); zend_string_release(stacktrace); } } @@ -1243,112 +1407,16 @@ static void dd_span_events_to_v1(zend_array *events, ddog_TracerPayloadV1Builder zval *aval; ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(attrs), idx, key, aval) { char numbuf[24]; - uint32_t key_id = key - ? dd_v1_intern_zstr(b, key) - : dd_v1_intern(b, (ddog_CharSlice){ .ptr = numbuf, .len = snprintf(numbuf, sizeof(numbuf), ZEND_ULONG_FMT, idx) }); - dd_event_attribute_to_v1(b, chunk, span, rust_event, key_id, aval); + ddog_CharSlice key_cs = key + ? dd_zend_string_to_CharSlice(key) + : (ddog_CharSlice){ .ptr = numbuf, .len = snprintf(numbuf, sizeof(numbuf), ZEND_ULONG_FMT, idx) }; + dd_event_attribute_to_v1(b, chunk, span, rust_event, key_cs, aval); } ZEND_HASH_FOREACH_END(); } } ZEND_HASH_FOREACH_END(); } -// Convert a fully-built V0.4 span (all tags/business logic already applied) into a new span in the -// V1 builder. Fields/meta/metrics/meta_struct are read back from the V0.4 span; native links/events -// are read from the still-alive PHP span. Promoted fields (env/version/component/span.kind) go to -// dedicated setters and are excluded from the attribute map; chunk-level fields (sampling priority, -// origin, sampling mechanism, 128-bit trace-id high) are routed to the chunk and excluded too. -static void dd_v1_convert_span(ddtrace_v1_ctx *v1, ddog_SpanBytes *v04, ddtrace_span_data *php_span) { - ddog_TracerPayloadV1Builder *b = v1->builder; - if (v1->chunk == DD_V1_CHUNK_NONE) { - v1->chunk = ddog_v1_builder_new_chunk(b, php_span->root->trace_id.high, php_span->root->trace_id.low); - bool p0 = ddtrace_fetch_priority_sampling_from_span(php_span->root) <= 0; - ddog_v1_set_chunk_dropped_trace(b, v1->chunk, p0); - } - uintptr_t chunk = v1->chunk; - uintptr_t sp = ddog_v1_chunk_new_span(b, chunk); - - ddog_v1_set_span_id(b, chunk, sp, ddog_get_span_id(v04)); - ddog_v1_set_span_parent_id(b, chunk, sp, ddog_get_span_parent_id(v04)); - ddog_v1_set_span_start(b, chunk, sp, ddog_get_span_start(v04)); - ddog_v1_set_span_duration(b, chunk, sp, ddog_get_span_duration(v04)); - ddog_v1_set_span_error(b, chunk, sp, ddog_get_span_error(v04) != 0); - -#define DD_V1_SET_FIELD(getter, setter) \ - do { \ - ddog_CharSlice _s = getter(v04); \ - if (_s.len) setter(b, chunk, sp, dd_v1_intern(b, _s)); \ - } while (0) - DD_V1_SET_FIELD(ddog_get_span_service, ddog_v1_set_span_service); - DD_V1_SET_FIELD(ddog_get_span_name, ddog_v1_set_span_name); - DD_V1_SET_FIELD(ddog_get_span_resource, ddog_v1_set_span_resource); - DD_V1_SET_FIELD(ddog_get_span_type, ddog_v1_set_span_type); -#undef DD_V1_SET_FIELD - - size_t meta_count = 0; - ddog_CharSlice *meta_keys = ddog_span_meta_get_keys(v04, &meta_count); - for (size_t k = 0; k < meta_count; k++) { - ddog_CharSlice key = meta_keys[k]; - ddog_CharSlice value = ddog_get_span_meta(v04, key); - // Promoted fields -> dedicated setters, excluded from the attribute map. - if (DD_CS_EQ(key, "env")) { ddog_v1_set_span_env(b, chunk, sp, dd_v1_intern(b, value)); continue; } - if (DD_CS_EQ(key, "version")) { ddog_v1_set_span_version(b, chunk, sp, dd_v1_intern(b, value)); continue; } - if (DD_CS_EQ(key, "component")) { ddog_v1_set_span_component(b, chunk, sp, dd_v1_intern(b, value)); continue; } - if (DD_CS_EQ(key, "span.kind")) { ddog_v1_set_span_kind(b, chunk, sp, dd_span_kind_meta_to_otel(value)); continue; } - // Links/events are emitted natively from the PHP span, not the V0.4 JSON-in-meta form. - if (DD_CS_EQ(key, "_dd.span_links") || DD_CS_EQ(key, "events")) { continue; } - // Chunk-level promotions (only present on the root/first span). - if (DD_CS_EQ(key, "_dd.origin")) { ddog_v1_set_chunk_origin(b, chunk, dd_v1_intern(b, value)); continue; } - if (DD_CS_EQ(key, "_dd.p.dm")) { - // v0.4 form is "-N"; the mechanism is the trailing unsigned integer. - const char *p = value.ptr; size_t n = value.len; - if (n && *p == '-') { p++; n--; } - uint32_t mech = 0; - for (size_t i = 0; i < n; i++) { if (p[i] < '0' || p[i] > '9') { mech = 0; break; } mech = mech * 10 + (uint32_t)(p[i] - '0'); } - ddog_v1_set_chunk_sampling_mechanism(b, chunk, mech); - continue; - } - // 128-bit trace-id high half is carried by the chunk trace id, not a span attribute. - if (DD_CS_EQ(key, "_dd.p.tid")) { continue; } - ddog_v1_add_span_attr_str(b, chunk, sp, dd_v1_intern(b, key), dd_v1_intern(b, value)); - } - ddog_span_free_keys_ptr(meta_keys, meta_count); - - size_t metrics_count = 0; - ddog_CharSlice *metrics_keys = ddog_span_metrics_get_keys(v04, &metrics_count); - for (size_t k = 0; k < metrics_count; k++) { - ddog_CharSlice key = metrics_keys[k]; - double value; - if (!ddog_get_span_metrics(v04, key, &value)) { - continue; - } - if (DD_CS_EQ(key, "_sampling_priority_v1")) { - ddog_v1_set_chunk_sampling_priority(b, chunk, (int32_t)value); - continue; - } - ddog_v1_add_span_attr_double(b, chunk, sp, dd_v1_intern(b, key), value); - } - ddog_span_free_keys_ptr(metrics_keys, metrics_count); - - size_t meta_struct_count = 0; - ddog_CharSlice *meta_struct_keys = ddog_span_meta_struct_get_keys(v04, &meta_struct_count); - for (size_t k = 0; k < meta_struct_count; k++) { - ddog_CharSlice key = meta_struct_keys[k]; - ddog_CharSlice value = ddog_get_span_meta_struct(v04, key); - ddog_v1_add_span_attr_bytes(b, chunk, sp, dd_v1_intern(b, key), value); - } - ddog_span_free_keys_ptr(meta_struct_keys, meta_struct_count); - - zend_array *span_links = ddtrace_property_array(&php_span->property_links); - if (zend_hash_num_elements(span_links) > 0) { - dd_span_links_to_v1(span_links, b, chunk, sp); - } - zend_array *span_events = ddtrace_property_array(&php_span->property_events); - if (zend_hash_num_elements(span_events) > 0) { - dd_span_events_to_v1(span_events, b, chunk, sp); - } -} - -static void dd_serialize_array_recursively(ddog_SpanBytes *target, zend_string *str, zval *value, bool convert_to_double) { +static void dd_serialize_array_recursively(dd_span_sink *target, zend_string *str, zval *value, bool convert_to_double) { ZVAL_DEREF(value); if (Z_TYPE_P(value) == IS_ARRAY || Z_TYPE_P(value) == IS_OBJECT) { @@ -1385,9 +1453,9 @@ static void dd_serialize_array_recursively(ddog_SpanBytes *target, zend_string * GC_UNPROTECT_RECURSION(arr); } else if (convert_to_double) { - ddog_add_span_metrics_zstr(target, str, 0.0); + dd_sink_metrics_zstr(target, str, 0.0); } else { - ddog_add_zstr_span_meta_str(target, str, ""); + dd_sink_meta_zstr_str(target, str, ""); } #if PHP_VERSION_ID >= 70400 @@ -1396,24 +1464,24 @@ static void dd_serialize_array_recursively(ddog_SpanBytes *target, zend_string * } #endif } else if (convert_to_double) { - ddog_add_span_metrics_zstr(target, str, zval_get_double(value)); + dd_sink_metrics_zstr(target, str, zval_get_double(value)); } else { zval val_as_string; datadog_convert_to_string(&val_as_string, value); - ddog_add_span_meta_zstr(target, str, Z_STR_P(&val_as_string)); + dd_sink_meta_zstr_zstr(target, str, Z_STR_P(&val_as_string)); zval_ptr_dtor(&val_as_string); } } -static void dd_serialize_array_meta_recursively(ddog_SpanBytes *target, zend_string *str, zval *value) { +static void dd_serialize_array_meta_recursively(dd_span_sink *target, zend_string *str, zval *value) { dd_serialize_array_recursively(target, str, value, false); } -static void dd_serialize_array_metrics_recursively(ddog_SpanBytes *target, zend_string *str, zval *value) { +static void dd_serialize_array_metrics_recursively(dd_span_sink *target, zend_string *str, zval *value) { dd_serialize_array_recursively(target, str, value, true); } -static void dd_serialize_array_meta_struct_recursively(ddog_SpanBytes *target, zend_string *str, zval *value) { +static void dd_serialize_array_meta_struct_recursively(dd_span_sink *target, zend_string *str, zval *value) { char *data; size_t size; @@ -1427,7 +1495,7 @@ static void dd_serialize_array_meta_struct_recursively(ddog_SpanBytes *target, z return; } - ddog_add_zstr_span_meta_struct_CharSlice(target, str, (ddog_CharSlice){.ptr = data, .len = size}); + dd_sink_meta_struct_zstr_cs(target, str, (ddog_CharSlice){.ptr = data, .len = size}); free(data); } @@ -1620,7 +1688,7 @@ static void dd_set_entrypoint_root_span_props_end(zend_array *meta, int status, } } -static void dd_set_entrypoint_root_rust_span_props_end(ddog_SpanBytes *span, struct iter *headers) { +static void dd_set_entrypoint_root_rust_span_props_end(dd_span_sink *span, struct iter *headers) { for (zend_string *lowerheader, *headerval; headers->next(headers, &lowerheader, &headerval);) { dd_add_header_to_rust_span(span, "response", lowerheader, headerval); zend_string_release(lowerheader); @@ -1685,27 +1753,7 @@ void ddtrace_shutdown_span_sampling_limiter(void) { zend_hash_destroy(&dd_span_sampling_limiters); } -void transfer_meta_data(ddog_SpanBytes *source, ddog_SpanBytes *destination, const char *key, bool delete_source) { - ddog_CharSlice value = ddog_get_span_meta_str(source, key); - if (value.len > 0) { - ddog_add_str_span_meta_CharSlice(destination, key, value); - if (delete_source) { - ddog_del_span_meta_str(source, key); - } - } -} - -void transfer_metrics_data(ddog_SpanBytes *source, ddog_SpanBytes *destination, const char* key, bool delete_source) { - double metric; - if (ddog_get_span_metrics_str(source, key, &metric)) { - ddog_add_span_metrics_str(destination, key, metric); - if (delete_source) { - ddog_del_span_metrics_str(source, key); - } - } -} - -ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceBytes *trace, ddtrace_v1_ctx *v1) { +dd_span_sink ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceBytes *trace, ddtrace_v1_ctx *v1) { zend_array *meta = ddtrace_property_array(&span->property_meta); zend_array *metrics = ddtrace_property_array(&span->property_metrics); @@ -1743,7 +1791,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo } if (!ddtrace_trace_passes_filter(span)) { ddtrace_free_span_precomputed(&pre); - return NULL; + return (dd_span_sink){0}; } } @@ -1921,18 +1969,44 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo } ddtrace_feed_span_to_concentrator(span, &pre); ddtrace_free_span_precomputed(&pre); - return NULL; + return (dd_span_sink){0}; + } + + // On the sidecar path the span is built directly into the native V1 builder (no V0.4 span); on + // the in-process (<=8.2) path it is built into a V0.4 ddog_SpanBytes. Exactly one backend is set + // on the sink; every field/meta/metrics write below routes through it. + dd_span_sink sink = {0}; + uintptr_t rust_span_index = 0; + bool is_first_span; + ddog_SpanBytes *rust_span = NULL; + if (v1) { + if (v1->chunk == DD_V1_CHUNK_NONE) { + v1->chunk = ddog_v1_builder_new_chunk(v1->builder, span->root->trace_id.high, span->root->trace_id.low); + ddog_v1_set_chunk_dropped_trace(v1->builder, v1->chunk, p0_trace); + } + is_first_span = ddog_v1_get_span_count(v1->builder, v1->chunk) == 0; + sink.builder = v1->builder; + sink.chunk = v1->chunk; + sink.span = ddog_v1_chunk_new_span(v1->builder, v1->chunk); + } else { + rust_span_index = ddog_get_trace_size(trace); + is_first_span = rust_span_index == 0; + rust_span = ddog_trace_new_span(trace); + sink.v04 = rust_span; } - uintptr_t rust_span_index = ddog_get_trace_size(trace); - bool is_first_span = rust_span_index == 0; - ddog_SpanBytes *rust_span = ddog_trace_new_span(trace); - - ddog_set_span_trace_id(rust_span, span->root->trace_id.low); - ddog_set_span_id(rust_span, span->span_id); + // trace_id: V1 carries the 128-bit trace id on the chunk (set at chunk creation), so this is a + // V0.4-only field. + if (!v1) { + ddog_set_span_trace_id(rust_span, span->root->trace_id.low); + } + if (v1) ddog_v1_set_span_id(sink.builder, sink.chunk, sink.span, span->span_id); + else ddog_set_span_id(rust_span, span->span_id); + uint64_t parent_id_set = 0; + bool has_parent_id = false; if (inferred_span) { - ddog_set_span_parent_id(rust_span, inferred_span->span_id); + parent_id_set = inferred_span->span_id; has_parent_id = true; } else if (span->parent) { // handle dropped spans ddtrace_span_data *parent = SPANDATA(span->parent); // Ensure the parent id is the root span if everything else was dropped @@ -1940,16 +2014,25 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo parent = SPANDATA(parent->parent); } if (parent) { - ddog_set_span_parent_id(rust_span, parent->span_id); + parent_id_set = parent->span_id; has_parent_id = true; } } else if (is_root_span) { - ddog_set_span_parent_id(rust_span, ROOTSPANDATA(&span->std)->parent_id); + parent_id_set = ROOTSPANDATA(&span->std)->parent_id; has_parent_id = true; } else if (is_inferred_span) { - ddog_set_span_parent_id(rust_span, span->root->parent_id); + parent_id_set = span->root->parent_id; has_parent_id = true; + } + if (has_parent_id) { + if (v1) ddog_v1_set_span_parent_id(sink.builder, sink.chunk, sink.span, parent_id_set); + else ddog_set_span_parent_id(rust_span, parent_id_set); } - ddog_set_span_start(rust_span, span->start); - ddog_set_span_duration(rust_span, span->duration); + if (v1) { + ddog_v1_set_span_start(sink.builder, sink.chunk, sink.span, span->start); + ddog_v1_set_span_duration(sink.builder, sink.chunk, sink.span, span->duration); + } else { + ddog_set_span_start(rust_span, span->start); + ddog_set_span_duration(rust_span, span->duration); + } if (is_first_span) { zend_string *process_tags = datadog_process_tags_get_serialized(); @@ -1981,10 +2064,10 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo smart_str_appends(&combined, normalized_default); } smart_str_0(&combined); - ddog_add_str_span_meta_zstr(rust_span, "_dd.tags.process", combined.s); + dd_sink_meta_str_zstr(&sink, "_dd.tags.process", combined.s); smart_str_free(&combined); } else { - ddog_add_str_span_meta_zstr(rust_span, "_dd.tags.process", process_tags); + dd_sink_meta_str_zstr(&sink, "_dd.tags.process", process_tags); } if (normalized_default) { @@ -1995,7 +2078,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo // SpanData::$name defaults to fully qualified called name (set at span close) if (pre.name) { - ddog_set_span_name_zstr(rust_span, pre.name); + dd_sink_set_name_zstr(&sink, pre.name); } if (pre.name_from_meta) { zend_hash_str_del(meta, ZEND_STRL("operation.name")); @@ -2003,7 +2086,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo // SpanData::$resource defaults to SpanData::$name if (pre.resource) { - ddog_set_span_resource_zstr(rust_span, pre.resource); + dd_sink_set_resource_zstr(&sink, pre.resource); } if (pre.resource_from_meta) { zend_hash_str_del(meta, ZEND_STRL("resource.name")); @@ -2011,7 +2094,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo // TODO: SpanData::$service defaults to parent SpanData::$service or DD_SERVICE if root span if (pre.service) { - ddog_set_span_service_zstr(rust_span, pre.service); + dd_sink_set_service_zstr(&sink, pre.service); } if (pre.service_from_meta) { zend_hash_str_del(meta, ZEND_STRL("service.name")); @@ -2019,7 +2102,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo // SpanData::$type is optional and defaults to 'custom' at the Agent level if (pre.type) { - ddog_set_span_type_zstr(rust_span, pre.type); + dd_sink_set_type_zstr(&sink, pre.type); } if (pre.type_from_meta) { zend_hash_str_del(meta, ZEND_STRL("span.type")); @@ -2028,10 +2111,10 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo zend_hash_str_del(meta, ZEND_STRL("analytics.event")); if (span_sampling_applied) { - ddog_add_span_metrics_str(rust_span, "_dd.span_sampling.mechanism", 8.0); - ddog_add_span_metrics_str(rust_span, "_dd.span_sampling.rule_rate", span_sampling_rate); + dd_sink_metrics_str(&sink, "_dd.span_sampling.mechanism", 8.0); + dd_sink_metrics_str(&sink, "_dd.span_sampling.rule_rate", span_sampling_rate); if (span_sampling_has_max) { - ddog_add_span_metrics_str(rust_span, "_dd.span_sampling.max_per_second", span_sampling_max_per_second); + dd_sink_metrics_str(&sink, "_dd.span_sampling.max_per_second", span_sampling_max_per_second); } } @@ -2040,8 +2123,8 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo zval *orig_val; ZEND_HASH_FOREACH_STR_KEY_VAL_IND(meta, meta_str_key, orig_val) { if (meta_str_key) { - if (!ddog_has_span_meta_zstr(rust_span, meta_str_key)) { - dd_serialize_array_meta_recursively(rust_span, meta_str_key, orig_val); + if (!dd_sink_has_meta_zstr(&sink, meta_str_key)) { + dd_serialize_array_meta_recursively(&sink, meta_str_key, orig_val); } } } @@ -2050,10 +2133,10 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo // Avoid adding it twice to meta if (!pre.env_deprecated && pre.env) { - ddog_add_str_span_meta_zstr(rust_span, "env", pre.env); + dd_sink_meta_str_zstr(&sink, "env", pre.env); } if (!pre.version_deprecated && pre.version) { - ddog_add_str_span_meta_zstr(rust_span, "version", pre.version); + dd_sink_meta_str_zstr(&sink, "version", pre.version); } zval *exception_zv = &span->property_exception; @@ -2062,32 +2145,40 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo if (is_root_span) { exception_type = Z_PROP_FLAG_P(exception_zv) == 2 ? DD_EXCEPTION_CAUGHT : DD_EXCEPTION_UNCAUGHT; } - ddtrace_exception_to_meta(Z_OBJ_P(exception_zv), pre.service ? pre.service : ZSTR_EMPTY_ALLOC(), span->start, rust_span, exception_type); + ddtrace_exception_to_meta(Z_OBJ_P(exception_zv), pre.service ? pre.service : ZSTR_EMPTY_ALLOC(), span->start, &sink, exception_type); } - // Links/events are always serialized as V0.4 JSON-in-meta here (used by the in-process sender - // and functions.c introspection). The V1 sidecar path re-emits them natively from the PHP span - // in dd_v1_convert_span and skips these two meta keys. + // Links/events: on the in-process (<=8.2) V0.4 path they are serialized as JSON-in-meta (read by + // the in-process sender and functions.c introspection); on the V1 sidecar path they are emitted + // natively from the PHP span (and the _dd.span_links/events meta keys are never produced). zend_array *span_links = ddtrace_property_array(&span->property_links); if (zend_hash_num_elements(span_links) > 0) { - zend_object *current_exception = EG(exception); - EG(exception) = NULL; - smart_str buf = {0}; - dd_serialize_span_links(span_links, &buf); - ddog_add_str_span_meta_zstr(rust_span, "_dd.span_links", buf.s); - smart_str_free(&buf); - EG(exception) = current_exception; + if (v1) { + dd_span_links_to_v1(span_links, sink.builder, sink.chunk, sink.span); + } else { + zend_object *current_exception = EG(exception); + EG(exception) = NULL; + smart_str buf = {0}; + dd_serialize_span_links(span_links, &buf); + ddog_add_str_span_meta_zstr(rust_span, "_dd.span_links", buf.s); + smart_str_free(&buf); + EG(exception) = current_exception; + } } zend_array *span_events = ddtrace_property_array(&span->property_events); if (zend_hash_num_elements(span_events) > 0) { - zend_object *current_exception = EG(exception); - EG(exception) = NULL; - smart_str buf = {0}; - dd_serialize_span_events(span_events, &buf); - ddog_add_str_span_meta_zstr(rust_span, "events", buf.s); - smart_str_free(&buf); - EG(exception) = current_exception; + if (v1) { + dd_span_events_to_v1(span_events, sink.builder, sink.chunk, sink.span); + } else { + zend_object *current_exception = EG(exception); + EG(exception) = NULL; + smart_str buf = {0}; + dd_serialize_span_events(span_events, &buf); + ddog_add_str_span_meta_zstr(rust_span, "events", buf.s); + smart_str_free(&buf); + EG(exception) = current_exception; + } } zval *git_metadata = &span->root->property_git_metadata; @@ -2096,12 +2187,12 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo if (is_root_span) { if (Z_TYPE(metadata->property_commit) == IS_STRING) { zend_string *commit_sha = datadog_convert_to_str(&metadata->property_commit); - ddog_add_str_span_meta_zstr(rust_span, "_dd.git.commit.sha", commit_sha); + dd_sink_meta_str_zstr(&sink, "_dd.git.commit.sha", commit_sha); zend_string_release(commit_sha); } if (Z_TYPE(metadata->property_repository) == IS_STRING) { zend_string *repository_url = datadog_convert_to_str(&metadata->property_repository); - ddog_add_str_span_meta_zstr(rust_span, "_dd.git.repository_url", repository_url); + dd_sink_meta_str_zstr(&sink, "_dd.git.repository_url", repository_url); zend_string_release(repository_url); } } @@ -2111,18 +2202,18 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo zend_array *peer_service_sources = ddtrace_property_array(&span->property_peer_service_sources); zval *peer_service_tag = meta ? zend_hash_str_find(meta, ZEND_STRL("peer.service")) : NULL; if (peer_service_tag && Z_TYPE_P(peer_service_tag) == IS_STRING) { - ddog_add_str_span_meta_str(rust_span, "_dd.peer.service.source", "peer.service"); - dd_set_mapped_peer_service(rust_span, Z_STR_P(peer_service_tag)); + dd_sink_meta_str_str(&sink, "_dd.peer.service.source", "peer.service"); + dd_set_mapped_peer_service(&sink, Z_STR_P(peer_service_tag)); } else if (zend_hash_num_elements(peer_service_sources) > 0) { zval *tag; ZEND_HASH_FOREACH_VAL(peer_service_sources, tag) { if (Z_TYPE_P(tag) == IS_STRING) { zval *found_peer_service = meta ? zend_hash_find(meta, Z_STR_P(tag)) : NULL; if (found_peer_service && Z_TYPE_P(found_peer_service) == IS_STRING) { - ddog_add_str_span_meta_zstr(rust_span, "_dd.peer.service.source", Z_STR_P(tag)); + dd_sink_meta_str_zstr(&sink, "_dd.peer.service.source", Z_STR_P(tag)); zend_string *peer = zval_get_string(found_peer_service); - if (!dd_set_mapped_peer_service(rust_span, peer)) { - ddog_add_str_span_meta_zstr(rust_span, "peer.service", peer); + if (!dd_set_mapped_peer_service(&sink, peer)) { + dd_sink_meta_str_zstr(&sink, "peer.service", peer); } zend_string_release(peer); break; @@ -2134,18 +2225,18 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo if (ddtrace_span_is_entrypoint_root(span) || is_inferred_span) { struct iter *headers = dd_iterate_sapi_headers(); - dd_set_entrypoint_root_rust_span_props_end(rust_span, headers); + dd_set_entrypoint_root_rust_span_props_end(&sink, headers); efree(headers); } zval *origin = &span->root->property_origin; if (Z_TYPE_P(origin) > IS_NULL && (Z_TYPE_P(origin) != IS_STRING || Z_STRLEN_P(origin))) { - ddog_add_str_span_meta_zstr(rust_span, "_dd.origin", Z_STR_P(origin)); + dd_sink_meta_str_zstr(&sink, "_dd.origin", Z_STR_P(origin)); } bool error = dd_compute_span_is_error(&pre); if (error) { - ddog_set_span_error(rust_span, 1); + dd_sink_set_error(&sink, 1); if (Z_TYPE(span->property_exception) == IS_OBJECT) { zend_object *exception = Z_OBJ(span->property_exception); ddtrace_span_data *current = span; @@ -2153,7 +2244,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo do { should_track = should_track_error(exception, current); if (!should_track) { - ddog_add_str_span_meta_str(rust_span, "track_error", "false"); + dd_sink_meta_str_str(&sink, "track_error", "false"); break; } current = current->parent ? SPANDATA(current->parent) : NULL; @@ -2163,7 +2254,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo if (is_inferred_span || (span->root->trace_id.high && is_root_span && !inferred_span)) { zend_string *trace_id_str = zend_strpprintf(0, "%" PRIx64, span->root->trace_id.high); - ddog_add_str_span_meta_zstr(rust_span, "_dd.p.tid", trace_id_str); + dd_sink_meta_str_zstr(&sink, "_dd.p.tid", trace_id_str); zend_string_release(trace_id_str); } @@ -2178,7 +2269,7 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo ZVAL_COPY(&prop_root_service_as_string, new_root_name); } if (!is_inferred_span && !zend_string_equals_ci(Z_STR(prop_service_as_string), Z_STR(prop_root_service_as_string))) { - ddog_add_str_span_meta_zstr(rust_span, "_dd.base_service", Z_STR_P(&prop_root_service_as_string)); + dd_sink_meta_str_zstr(&sink, "_dd.base_service", Z_STR_P(&prop_root_service_as_string)); } zend_string_release(Z_STR(prop_root_service_as_string)); zend_string_release(Z_STR(prop_service_as_string)); @@ -2191,8 +2282,8 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo zval *val; ZEND_HASH_FOREACH_STR_KEY_VAL_IND(metrics, str_key, val) { if (str_key && !zend_string_equals_literal(str_key, "_dd1.sr.eausr") && - !ddog_has_span_metrics_zstr(rust_span, str_key)) { - dd_serialize_array_metrics_recursively(rust_span, str_key, val); + !dd_sink_has_metrics_zstr(&sink, str_key)) { + dd_serialize_array_metrics_recursively(&sink, str_key, val); } } ZEND_HASH_FOREACH_END(); @@ -2202,12 +2293,12 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo if (!get_global_DD_APM_TRACING_ENABLED() && !ddtrace_trace_source_is_meta_asm_sourced(meta)) { sampling_priority = MIN(PRIORITY_SAMPLING_AUTO_KEEP, sampling_priority); } - ddog_add_span_metrics_str(rust_span, "_sampling_priority_v1", sampling_priority); + dd_sink_metrics_str(&sink, "_sampling_priority_v1", sampling_priority); } } if (!get_global_DD_APM_TRACING_ENABLED()) { - ddog_add_span_metrics_str(rust_span, "_dd.apm.enabled", 0); + dd_sink_metrics_str(&sink, "_dd.apm.enabled", 0); } if (DATADOG_G(sidecar) && get_DD_TRACE_STATS_COMPUTATION_ENABLED() && !is_inferred_span) { @@ -2224,72 +2315,245 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo } } if (is_top_level_span) { - ddog_add_span_metrics_str(rust_span, "_dd.top_level", 1); + dd_sink_metrics_str(&sink, "_dd.top_level", 1); } } if (ddtrace_span_is_entrypoint_root(span)) { if (get_DD_TRACE_MEASURE_COMPILE_TIME()) { - ddog_add_span_metrics_str(rust_span, "php.compilation.total_time_ms", ddtrace_compile_time_get() / 1000.); + dd_sink_metrics_str(&sink, "php.compilation.total_time_ms", ddtrace_compile_time_get() / 1000.); } if (get_DD_TRACE_MEASURE_PEAK_MEMORY_USAGE()) { - ddog_add_span_metrics_str(rust_span, "php.memory.peak_usage_bytes", zend_memory_peak_usage(false)); - ddog_add_span_metrics_str(rust_span, "php.memory.peak_real_usage_bytes", zend_memory_peak_usage(true)); + dd_sink_metrics_str(&sink, "php.memory.peak_usage_bytes", zend_memory_peak_usage(false)); + dd_sink_metrics_str(&sink, "php.memory.peak_real_usage_bytes", zend_memory_peak_usage(true)); } } - ddog_SpanBytes *serialized_inferred_span = NULL; + dd_span_sink inferred_sink = {0}; if (inferred_span) { - serialized_inferred_span = ddtrace_serialize_span_to_rust_span(inferred_span, trace, v1); - rust_span = ddog_get_span(trace, rust_span_index); + inferred_sink = ddtrace_serialize_span_to_rust_span(inferred_span, trace, v1); + // The inferred recursion may have appended to the V0.4 trace, invalidating rust_span; the V1 + // builder addresses spans by stable index, so only the V0.4 pointer needs re-fetching. + if (sink.v04) { + sink.v04 = ddog_get_span(trace, rust_span_index); + } - transfer_metrics_data(rust_span, serialized_inferred_span, "_dd.agent_psr", true); - transfer_metrics_data(rust_span, serialized_inferred_span, "_dd.rule_psr", true); - transfer_metrics_data(rust_span, serialized_inferred_span, "_dd.limit_psr", true); + transfer_span_metric(&sink, &inferred_sink, "_dd.agent_psr", true); + transfer_span_metric(&sink, &inferred_sink, "_dd.rule_psr", true); + transfer_span_metric(&sink, &inferred_sink, "_dd.limit_psr", true); - transfer_meta_data(rust_span, serialized_inferred_span, "error.message", false); - transfer_meta_data(rust_span, serialized_inferred_span, "error.type", false); - transfer_meta_data(rust_span, serialized_inferred_span, "error.stack", false); - transfer_meta_data(rust_span, serialized_inferred_span, "track_error", false); - transfer_meta_data(rust_span, serialized_inferred_span, "_dd.p.dm", true); - transfer_meta_data(rust_span, serialized_inferred_span, "_dd.p.ksr", false); - transfer_meta_data(rust_span, serialized_inferred_span, "_dd.p.tid", true); - transfer_meta_data(rust_span, serialized_inferred_span, "_dd.svc_src", false); - transfer_meta_data(rust_span, serialized_inferred_span, DD_TAG_HTTP_REQH_ENDPOINT_SCAN, false); - transfer_meta_data(rust_span, serialized_inferred_span, DD_TAG_HTTP_REQH_SECURITY_TEST, false); + transfer_span_attr(&sink, &inferred_sink, "error.message", false); + transfer_span_attr(&sink, &inferred_sink, "error.type", false); + transfer_span_attr(&sink, &inferred_sink, "error.stack", false); + transfer_span_attr(&sink, &inferred_sink, "track_error", false); + transfer_span_attr(&sink, &inferred_sink, "_dd.p.dm", true); + transfer_span_attr(&sink, &inferred_sink, "_dd.p.ksr", false); + transfer_span_attr(&sink, &inferred_sink, "_dd.p.tid", true); + transfer_span_attr(&sink, &inferred_sink, "_dd.svc_src", false); + transfer_span_attr(&sink, &inferred_sink, DD_TAG_HTTP_REQH_ENDPOINT_SCAN, false); + transfer_span_attr(&sink, &inferred_sink, DD_TAG_HTTP_REQH_SECURITY_TEST, false); - ddog_set_span_error(serialized_inferred_span, ddog_get_span_error(rust_span)); + dd_sink_set_error(&inferred_sink, dd_sink_get_error(&sink)); } - LOGEV(SPAN, { - ddog_CharSlice span_log = ddog_span_debug_log(rust_span); - log("Encoding span: %s", span_log.ptr); - ddog_free_charslice(span_log); - }); + if (sink.v04) { + LOGEV(SPAN, { + ddog_CharSlice span_log = ddog_span_debug_log(sink.v04); + log("Encoding span: %s", span_log.ptr); + ddog_free_charslice(span_log); + }); + } zend_array *meta_struct = ddtrace_property_array(&span->property_meta_struct); zend_string *ms_str_key; zval *ms_val; ZEND_HASH_FOREACH_STR_KEY_VAL_IND(meta_struct, ms_str_key, ms_val) { if (ms_str_key) { - dd_serialize_array_meta_struct_recursively(rust_span, ms_str_key, ms_val); + dd_serialize_array_meta_struct_recursively(&sink, ms_str_key, ms_val); } } ZEND_HASH_FOREACH_END(); - ddog_del_span_meta_str(rust_span, "error.ignored"); + dd_sink_del_meta_str(&sink, "error.ignored"); + + ddtrace_free_span_precomputed(&pre); + return sink; +} + +// Reads a native V1 span attribute at index `idx` into a zval, typed per its DDOG_V1_ATTR_* tag. +static void dd_v1_attr_value_to_zval(ddog_TracerPayloadV1Builder *b, uintptr_t c, uintptr_t sp, uintptr_t idx, zval *out) { + switch (ddog_v1_get_span_attr_type(b, c, sp, idx)) { + case ddog_DDOG_V1_ATTR_INT: + ZVAL_LONG(out, ddog_v1_get_span_attr_int(b, c, sp, idx)); + break; + case ddog_DDOG_V1_ATTR_DOUBLE: + ZVAL_DOUBLE(out, ddog_v1_get_span_attr_double(b, c, sp, idx)); + break; + case ddog_DDOG_V1_ATTR_BOOL: + ZVAL_BOOL(out, ddog_v1_get_span_attr_bool(b, c, sp, idx)); + break; + case ddog_DDOG_V1_ATTR_BYTES: + ZVAL_STR(out, dd_CharSlice_to_zend_string(ddog_v1_get_span_attr_bytes(b, c, sp, idx))); + break; + default: // STRING (and any list/keyvalue that has no scalar accessor) + ZVAL_STR(out, dd_CharSlice_to_zend_string(ddog_v1_get_span_attr_str(b, c, sp, idx))); + break; + } +} + +// Introspection reader for the native V1 builder (sidecar path). Mirrors dd_serialize_rust_traces_to_zval +// but reflects the V1 model: promoted fields (env/version/component/span_kind) and chunk-level fields +// (origin/sampling_priority/sampling_mechanism) are surfaced directly, and the unified typed attribute +// map is exposed under "attributes"; links and events are surfaced natively. +zval dd_serialize_rust_v1_to_zval(ddog_TracerPayloadV1Builder *b) { + zval traces_zv; + array_init(&traces_zv); + + for (size_t c = 0; c < ddog_v1_get_chunk_count(b); c++) { + zval trace_zv; + array_init(&trace_zv); + + uint64_t tid_high = ddog_v1_get_chunk_trace_id_high(b, c); + uint64_t tid_low = ddog_v1_get_chunk_trace_id_low(b, c); + // Chunk-level fields (shared by every span of the chunk) are reflected onto each span. + int32_t chunk_priority; + bool has_priority = ddog_v1_get_chunk_sampling_priority(b, c, &chunk_priority); + uint32_t chunk_mechanism; + bool has_mechanism = ddog_v1_get_chunk_sampling_mechanism(b, c, &chunk_mechanism); + ddog_CharSlice chunk_origin = ddog_v1_get_chunk_origin(b, c); + bool chunk_dropped = ddog_v1_get_chunk_dropped_trace(b, c); + + for (size_t j = 0; j < ddog_v1_get_span_count(b, c); j++) { + zval span_zv; + array_init(&span_zv); + + add_assoc_str(&span_zv, KEY_TRACE_ID, ddtrace_span_id_as_string(tid_low)); + if (tid_high) { + add_assoc_str(&span_zv, "trace_id_high", ddtrace_span_id_as_hex_string(tid_high)); + } + add_assoc_str(&span_zv, KEY_SPAN_ID, ddtrace_span_id_as_string(ddog_v1_get_span_id(b, c, j))); + uint64_t parent_id = ddog_v1_get_span_parent_id(b, c, j); + if (parent_id) { + add_assoc_str(&span_zv, KEY_PARENT_ID, ddtrace_span_id_as_string(parent_id)); + } + add_assoc_long(&span_zv, "start", ddog_v1_get_span_start(b, c, j)); + add_assoc_long(&span_zv, "duration", ddog_v1_get_span_duration(b, c, j)); + add_assoc_str(&span_zv, "name", dd_CharSlice_to_zend_string(ddog_v1_get_span_name(b, c, j))); + add_assoc_str(&span_zv, "resource", dd_CharSlice_to_zend_string(ddog_v1_get_span_resource(b, c, j))); + add_assoc_str(&span_zv, "service", dd_CharSlice_to_zend_string(ddog_v1_get_span_service(b, c, j))); + add_assoc_str(&span_zv, "type", dd_CharSlice_to_zend_string(ddog_v1_get_span_type(b, c, j))); + if (ddog_v1_get_span_error(b, c, j)) { + add_assoc_long(&span_zv, "error", 1); + } + +#define DD_V1_ZVAL_PROMOTED(field, getter) \ + do { \ + ddog_CharSlice _v = getter(b, c, j); \ + if (_v.len) add_assoc_str(&span_zv, field, dd_CharSlice_to_zend_string(_v)); \ + } while (0) + DD_V1_ZVAL_PROMOTED("env", ddog_v1_get_span_env); + DD_V1_ZVAL_PROMOTED("version", ddog_v1_get_span_version); + DD_V1_ZVAL_PROMOTED("component", ddog_v1_get_span_component); +#undef DD_V1_ZVAL_PROMOTED + uint32_t span_kind = ddog_v1_get_span_kind(b, c, j); + if (span_kind) { + add_assoc_long(&span_zv, "span_kind", span_kind); + } + if (has_priority) { + add_assoc_long(&span_zv, "sampling_priority", chunk_priority); + } + if (has_mechanism) { + add_assoc_long(&span_zv, "sampling_mechanism", chunk_mechanism); + } + if (chunk_origin.len) { + add_assoc_str(&span_zv, "origin", dd_CharSlice_to_zend_string(chunk_origin)); + } + if (chunk_dropped) { + add_assoc_bool(&span_zv, "dropped_trace", 1); + } - // Emit into the native V1 builder (sidecar path). Inferred spans are converted by their parent - // root span right after the read-back merge above, so their final V0.4 state is captured. - if (v1 && !is_inferred_span) { - dd_v1_convert_span(v1, rust_span, span); - if (serialized_inferred_span) { - dd_v1_convert_span(v1, serialized_inferred_span, inferred_span); + size_t attr_count = ddog_v1_get_span_attr_count(b, c, j); + if (attr_count > 0) { + zval attrs_zv; + array_init(&attrs_zv); + for (size_t k = 0; k < attr_count; k++) { + ddog_CharSlice key = ddog_v1_get_span_attr_key(b, c, j, k); + zval value_zv; + dd_v1_attr_value_to_zval(b, c, j, k, &value_zv); + zend_hash_str_update(Z_ARR(attrs_zv), key.ptr, key.len, &value_zv); + } + add_assoc_zval(&span_zv, "attributes", &attrs_zv); + } + + size_t link_count = ddog_v1_get_link_count(b, c, j); + if (link_count > 0) { + zval links_zv; + array_init(&links_zv); + for (size_t l = 0; l < link_count; l++) { + zval link_zv; + array_init(&link_zv); + add_assoc_str(&link_zv, KEY_TRACE_ID, ddtrace_span_id_as_string(ddog_v1_get_link_trace_id_low(b, c, j, l))); + add_assoc_str(&link_zv, KEY_SPAN_ID, ddtrace_span_id_as_string(ddog_v1_get_link_span_id(b, c, j, l))); + ddog_CharSlice tracestate = ddog_v1_get_link_tracestate(b, c, j, l); + if (tracestate.len) { + add_assoc_str(&link_zv, "trace_state", dd_CharSlice_to_zend_string(tracestate)); + } + add_assoc_long(&link_zv, "flags", ddog_v1_get_link_flags(b, c, j, l)); + size_t lattr_count = ddog_v1_get_link_attr_count(b, c, j, l); + if (lattr_count > 0) { + zval lattrs_zv; + array_init(&lattrs_zv); + for (size_t k = 0; k < lattr_count; k++) { + ddog_CharSlice key = ddog_v1_get_link_attr_key(b, c, j, l, k); + zval v; + ZVAL_STR(&v, dd_CharSlice_to_zend_string(ddog_v1_get_link_attr_str(b, c, j, l, k))); + zend_hash_str_update(Z_ARR(lattrs_zv), key.ptr, key.len, &v); + } + add_assoc_zval(&link_zv, "attributes", &lattrs_zv); + } + zend_hash_next_index_insert_new(Z_ARR(links_zv), &link_zv); + } + add_assoc_zval(&span_zv, "span_links", &links_zv); + } + + size_t event_count = ddog_v1_get_event_count(b, c, j); + if (event_count > 0) { + zval events_zv; + array_init(&events_zv); + for (size_t e = 0; e < event_count; e++) { + zval event_zv; + array_init(&event_zv); + add_assoc_str(&event_zv, "name", dd_CharSlice_to_zend_string(ddog_v1_get_event_name(b, c, j, e))); + add_assoc_long(&event_zv, "time_unix_nano", ddog_v1_get_event_time(b, c, j, e)); + size_t eattr_count = ddog_v1_get_event_attr_count(b, c, j, e); + if (eattr_count > 0) { + zval eattrs_zv; + array_init(&eattrs_zv); + for (size_t k = 0; k < eattr_count; k++) { + ddog_CharSlice key = ddog_v1_get_event_attr_key(b, c, j, e, k); + zval v; + switch (ddog_v1_get_event_attr_type(b, c, j, e, k)) { + case ddog_DDOG_V1_ATTR_INT: ZVAL_LONG(&v, ddog_v1_get_event_attr_int(b, c, j, e, k)); break; + case ddog_DDOG_V1_ATTR_DOUBLE: ZVAL_DOUBLE(&v, ddog_v1_get_event_attr_double(b, c, j, e, k)); break; + case ddog_DDOG_V1_ATTR_BOOL: ZVAL_BOOL(&v, ddog_v1_get_event_attr_bool(b, c, j, e, k)); break; + default: ZVAL_STR(&v, dd_CharSlice_to_zend_string(ddog_v1_get_event_attr_str(b, c, j, e, k))); break; + } + zend_hash_str_update(Z_ARR(eattrs_zv), key.ptr, key.len, &v); + } + add_assoc_zval(&event_zv, "attributes", &eattrs_zv); + } + zend_hash_next_index_insert_new(Z_ARR(events_zv), &event_zv); + } + add_assoc_zval(&span_zv, "span_events", &events_zv); + } + + zend_hash_next_index_insert_new(Z_ARR_P(&trace_zv), &span_zv); } + + zend_hash_next_index_insert_new(Z_ARR_P(&traces_zv), &trace_zv); } - ddtrace_free_span_precomputed(&pre); - return rust_span; + return traces_zv; } zval dd_serialize_rust_traces_to_zval(ddog_TracesBytes *traces) { diff --git a/tracer/serializer.h b/tracer/serializer.h index 5ddb413436d..4dcf23d2b02 100644 --- a/tracer/serializer.h +++ b/tracer/serializer.h @@ -6,8 +6,17 @@ int ddtrace_serialize_simple_array(zval *trace, zval *retval); int ddtrace_serialize_simple_array_into_c_string(zval *trace, char **data_p, size_t *size_p); -ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceBytes *trace, ddtrace_v1_ctx *v1); +dd_span_sink ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceBytes *trace, ddtrace_v1_ctx *v1); zval dd_serialize_rust_traces_to_zval(ddog_TracesBytes *traces); +zval dd_serialize_rust_v1_to_zval(struct ddog_TracerPayloadV1Builder *builder); + +// Span-meta sink ops with external linkage (routing shared with exception_serialize.c). Each writes +// to the sink's active backend: V0.4 SpanBytes meta, or a native V1 span attribute (with promoted / +// chunk-level key routing). +void dd_sink_meta_cs_cs(dd_span_sink *s, ddog_CharSlice key, ddog_CharSlice val); +void dd_sink_meta_str_cs(dd_span_sink *s, const char *key, ddog_CharSlice val); +void dd_sink_meta_str_str(dd_span_sink *s, const char *key, const char *val); +void dd_sink_meta_str_zstr(dd_span_sink *s, const char *key, zend_string *val); void ddtrace_save_active_error_to_metadata(void); void ddtrace_set_global_span_properties(ddtrace_span_data *span); diff --git a/tracer/span.h b/tracer/span.h index 94e87f55e1b..f02fff4d9aa 100644 --- a/tracer/span.h +++ b/tracer/span.h @@ -25,6 +25,17 @@ typedef struct { uintptr_t chunk; } ddtrace_v1_ctx; +// Write target for span finalization. Exactly one backend is active at a time: the v0.4 SpanBytes +// (in-process <=8.2 background sender + functions.c introspection), or the native v1 builder +// chunk/span (sidecar path, built directly with no v0.4 intermediate). A zero-initialized sink +// (both pointers NULL) is the "no span" sentinel returned for dropped spans. +typedef struct { + struct ddog_SpanBytes *v04; // non-NULL on the v0.4 path + struct ddog_TracerPayloadV1Builder *builder; // non-NULL on the v1 path + uintptr_t chunk; + uintptr_t span; +} dd_span_sink; + #define DDTRACE_DROPPED_SPAN (-1ull) #define DDTRACE_SILENTLY_DROPPED_SPAN (-2ull) From 134be51b6fe61b58b1dedf557972b4ced65678b5 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 31 Aug 2026 15:28:53 +0200 Subject: [PATCH 23/32] feat(tracer): wire v1 span debug-log on the sidecar path Bump libdatadog to 3fb12c2c8 (adds ddog_v1_span_debug_log for the V1 builder) and regenerate components-rs/sidecar.h. On the v1 (sidecar) serialization path, emit the DD_TRACE_DEBUG "Encoding span:" diagnostic via ddog_v1_span_debug_log(builder, chunk, span) so the span-encoding log exists on both the v0.4 and v1 paths. Freed with ddog_free_charslice, mirroring the v0.4 branch. --- components-rs/sidecar.h | 14 ++++++++++++++ libdatadog | 2 +- tracer/serializer.c | 6 ++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 90ab96b494e..c56c4b0285c 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -1477,4 +1477,18 @@ bool ddog_v1_get_event_attr_bool(const struct ddog_TracerPayloadV1Builder *build uintptr_t event, uintptr_t idx); +/** + * Renders the span at index `chunk`/`span` as a human-readable diagnostic string, mirroring the + * v0.4 [`crate::span::ddog_span_debug_log`] used by dd-trace-php to emit the `DD_TRACE_DEBUG` + * "[span] Encoding span: …" line on the V1 path. Unlike the v0.4 variant it is index-addressed (the + * V1 builder never hands out `&mut`/`&` span handles to C); an out-of-range index yields an empty + * slice. + * + * The returned slice is an owned allocation that must be freed with the very same free function as + * the v0.4 variant, [`crate::span::ddog_free_charslice`]. + */ +ddog_CharSlice ddog_v1_span_debug_log(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t chunk, + uintptr_t span); + #endif /* DDOG_SIDECAR_H */ diff --git a/libdatadog b/libdatadog index fef26d167fa..3fb12c2c80f 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit fef26d167fabf8f70e0f194a9ef1a7c6fc8dcbdf +Subproject commit 3fb12c2c80f4190dfce72597876f2c04bfd14027 diff --git a/tracer/serializer.c b/tracer/serializer.c index 94cbffa8ae6..2713310fb50 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -2362,6 +2362,12 @@ dd_span_sink ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_T log("Encoding span: %s", span_log.ptr); ddog_free_charslice(span_log); }); + } else if (sink.builder) { + LOGEV(SPAN, { + ddog_CharSlice span_log = ddog_v1_span_debug_log(sink.builder, sink.chunk, sink.span); + log("Encoding span: %s", span_log.ptr); + ddog_free_charslice(span_log); + }); } zend_array *meta_struct = ddtrace_property_array(&span->property_meta_struct); From 15776f5425c7edca903e95b20e88111059b20889 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 31 Aug 2026 16:22:32 +0200 Subject: [PATCH 24/32] fix(tracer): surface v1 meta_struct in serialize introspection On the v1 (sidecar) path, meta_struct entries are written to the unified V1 attribute map as bytes attributes (ddog_v1_add_span_attr_bytes) and reach the wire correctly, but dd_serialize_rust_v1_to_zval folded them into the generic "attributes" array as opaque strings, so dd_trace_serialize_closed_spans no longer exposed a "meta_struct" key (appsec data appeared missing on introspection). Route bytes-typed span attributes (the only source of bytes attrs on this path) into a dedicated "meta_struct" key, mirroring the v0.4 reader, so meta_struct is visible again with its raw msgpack bytes and meta_struct.phpt passes on both the v0.4 and v1 paths unchanged. Bumps libdatadog to include the v1 attribute-map pre-encode dedup fix. --- libdatadog | 2 +- tracer/serializer.c | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/libdatadog b/libdatadog index 3fb12c2c80f..6e09e18daac 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 3fb12c2c80f4190dfce72597876f2c04bfd14027 +Subproject commit 6e09e18daac66e81810710e17b0dfcd393bac330 diff --git a/tracer/serializer.c b/tracer/serializer.c index 2713310fb50..293825cd475 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -2480,15 +2480,33 @@ zval dd_serialize_rust_v1_to_zval(ddog_TracerPayloadV1Builder *b) { size_t attr_count = ddog_v1_get_span_attr_count(b, c, j); if (attr_count > 0) { - zval attrs_zv; + zval attrs_zv, meta_struct_zv; array_init(&attrs_zv); + array_init(&meta_struct_zv); for (size_t k = 0; k < attr_count; k++) { ddog_CharSlice key = ddog_v1_get_span_attr_key(b, c, j, k); zval value_zv; dd_v1_attr_value_to_zval(b, c, j, k, &value_zv); - zend_hash_str_update(Z_ARR(attrs_zv), key.ptr, key.len, &value_zv); + // Bytes-typed attributes are v0.4 meta_struct entries (the only source of + // bytes attrs on this path). Surface them under a dedicated "meta_struct" key, + // mirroring the v0.4 reader, instead of mixing raw msgpack blobs into the + // readable attribute map. + if (ddog_v1_get_span_attr_type(b, c, j, k) == ddog_DDOG_V1_ATTR_BYTES) { + zend_hash_str_update(Z_ARR(meta_struct_zv), key.ptr, key.len, &value_zv); + } else { + zend_hash_str_update(Z_ARR(attrs_zv), key.ptr, key.len, &value_zv); + } + } + if (zend_hash_num_elements(Z_ARR(attrs_zv))) { + add_assoc_zval(&span_zv, "attributes", &attrs_zv); + } else { + zval_ptr_dtor(&attrs_zv); + } + if (zend_hash_num_elements(Z_ARR(meta_struct_zv))) { + add_assoc_zval(&span_zv, "meta_struct", &meta_struct_zv); + } else { + zval_ptr_dtor(&meta_struct_zv); } - add_assoc_zval(&span_zv, "attributes", &attrs_zv); } size_t link_count = ddog_v1_get_link_count(b, c, j); From b8b8b76838174e16adcb2bc6dfb19caef0f24343 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 31 Aug 2026 16:31:29 +0200 Subject: [PATCH 25/32] test: update .phpt expectations for v1 serialization shape (batch 1: sandbox/exceptions, single-span_sampling, client_side_stats) Relocate meta/metrics array access to the unified attributes map introduced by the v1 introspection shape. attributes preserves insertion order (not the old alphabetical meta ordering), which required reordering safe_to_string_metadata's EXPECTF. Filtered iteration to arg.* keys in safe_to_string_metrics/metadata and accept-single-span, since attributes now also carries entrypoint-only tags (_dd.tags.process) that used to live outside meta/metrics. --- tests/ext/client_side_stats_top_level.phpt | 2 +- .../sandbox-prehook/exception_handling.phpt | 12 +-- ...tion_from_user_error_handler_internal.phpt | 6 +- ...ption_handled_for_correct_catch_block.phpt | 2 +- ...eption_handled_in_correct_catch_frame.phpt | 4 +- .../exception_handled_in_multicatch.phpt | 2 +- .../exception_handled_with_finally.phpt | 2 +- tests/ext/sandbox/exception_handling.phpt | 12 +-- ...ons_are_passed_to_the_tracing_closure.phpt | 4 +- ...inal_call_rethrown_in_tracing_closure.phpt | 2 +- .../sandbox/fatal_errors_are_tracked_001.phpt | 6 +- .../sandbox/fatal_errors_are_tracked_002.phpt | 6 +- .../sandbox/fatal_errors_are_tracked_003.phpt | 6 +- .../sandbox/fatal_errors_are_tracked_004.phpt | 6 +- .../sandbox/fatal_errors_are_tracked_005.phpt | 6 +- .../ext/sandbox/generator_with_exception.phpt | 2 +- .../ext/sandbox/safe_to_string_metadata.phpt | 77 ++++++++++--------- tests/ext/sandbox/safe_to_string_metrics.phpt | 5 +- .../accept-single-span.phpt | 6 +- .../check-sample-rate.phpt | 8 +- .../limited-single-span-with-match.phpt | 6 +- .../limited-single-span.phpt | 4 +- .../name-matching-single-span.phpt | 4 +- ...single-span-sampling-config-from-file.phpt | 4 +- 24 files changed, 102 insertions(+), 92 deletions(-) diff --git a/tests/ext/client_side_stats_top_level.phpt b/tests/ext/client_side_stats_top_level.phpt index 36f4b38ba60..3f00ce01ed3 100644 --- a/tests/ext/client_side_stats_top_level.phpt +++ b/tests/ext/client_side_stats_top_level.phpt @@ -33,7 +33,7 @@ $child_diff->service = "other-service"; $spans = dd_trace_serialize_closed_spans(); foreach ($spans as $span) { - $has_top_level = isset($span["metrics"]["_dd.top_level"]); + $has_top_level = isset($span["attributes"]["_dd.top_level"]); echo $span["name"] . ": _dd.top_level=" . ($has_top_level ? "1" : "not set") . "\n"; } diff --git a/tests/ext/sandbox-prehook/exception_handling.phpt b/tests/ext/sandbox-prehook/exception_handling.phpt index ac99ec932b1..07750c9d578 100644 --- a/tests/ext/sandbox-prehook/exception_handling.phpt +++ b/tests/ext/sandbox-prehook/exception_handling.phpt @@ -24,15 +24,15 @@ try { $span = $stack[0]; echo "error: ", $span['error'], "\n"; - echo "Exception type: ", $span['meta']['error.type'], "\n"; - echo "Exception msg: ", $span['meta']['error.message'], "\n"; - echo "Exception stack:\n", $span['meta']['error.stack'], "\n"; + echo "Exception type: ", $span['attributes']['error.type'], "\n"; + echo "Exception msg: ", $span['attributes']['error.message'], "\n"; + echo "Exception stack:\n", $span['attributes']['error.stack'], "\n"; $span = $stack[1]; echo "error: ", $span['error'], "\n"; - echo "Exception type: ", $span['meta']['error.type'], "\n"; - echo "Exception msg: ", $span['meta']['error.message'], "\n"; - echo "Exception stack:\n", $span['meta']['error.stack'], "\n"; + echo "Exception type: ", $span['attributes']['error.type'], "\n"; + echo "Exception msg: ", $span['attributes']['error.message'], "\n"; + echo "Exception stack:\n", $span['attributes']['error.stack'], "\n"; } ?> diff --git a/tests/ext/sandbox/exception_from_user_error_handler_internal.phpt b/tests/ext/sandbox/exception_from_user_error_handler_internal.phpt index 1984f816f1a..e132c514600 100644 --- a/tests/ext/sandbox/exception_from_user_error_handler_internal.phpt +++ b/tests/ext/sandbox/exception_from_user_error_handler_internal.phpt @@ -22,9 +22,9 @@ try { $span = $spans[0]; echo 'error: ' . $span['error'] . PHP_EOL; - echo 'error.type: ' . $span['meta']['error.type'] . PHP_EOL; - echo 'error.message: ' . $span['meta']['error.message'] . PHP_EOL; - echo 'Has error.stack: ' . isset($span['meta']['error.stack']) . PHP_EOL; + echo 'error.type: ' . $span['attributes']['error.type'] . PHP_EOL; + echo 'error.message: ' . $span['attributes']['error.message'] . PHP_EOL; + echo 'Has error.stack: ' . isset($span['attributes']['error.stack']) . PHP_EOL; } ?> --EXPECTF-- diff --git a/tests/ext/sandbox/exception_handled_for_correct_catch_block.phpt b/tests/ext/sandbox/exception_handled_for_correct_catch_block.phpt index 87eb037f2e0..41d88ebc614 100644 --- a/tests/ext/sandbox/exception_handled_for_correct_catch_block.phpt +++ b/tests/ext/sandbox/exception_handled_for_correct_catch_block.phpt @@ -63,7 +63,7 @@ echo embeddedCatch() . PHP_EOL; array_map(function($span) { echo $span['name']; echo isset($span['resource']) ? ', ' . $span['resource'] : ''; - echo isset($span['meta']['error.message']) ? ', ' . $span['meta']['error.message'] : ''; + echo isset($span['attributes']['error.message']) ? ', ' . $span['attributes']['error.message'] : ''; echo PHP_EOL; }, dd_trace_serialize_closed_spans()); ?> diff --git a/tests/ext/sandbox/exception_handled_in_correct_catch_frame.phpt b/tests/ext/sandbox/exception_handled_in_correct_catch_frame.phpt index 1b0e458bec2..d1ff9421f33 100644 --- a/tests/ext/sandbox/exception_handled_in_correct_catch_frame.phpt +++ b/tests/ext/sandbox/exception_handled_in_correct_catch_frame.phpt @@ -67,8 +67,8 @@ array_map(function($span) { if (isset($span['resource'])) { echo '-' . $span['resource']; } - if (isset($span['meta']['error.message'])) { - echo ' (' . $span['meta']['error.message'] . ')'; + if (isset($span['attributes']['error.message'])) { + echo ' (' . $span['attributes']['error.message'] . ')'; } echo PHP_EOL; }, dd_trace_serialize_closed_spans()); diff --git a/tests/ext/sandbox/exception_handled_in_multicatch.phpt b/tests/ext/sandbox/exception_handled_in_multicatch.phpt index 4bafe494a93..30c1e5b09bc 100644 --- a/tests/ext/sandbox/exception_handled_in_multicatch.phpt +++ b/tests/ext/sandbox/exception_handled_in_multicatch.phpt @@ -38,7 +38,7 @@ echo multiCatch() . PHP_EOL; array_map(function($span) { echo $span['name']; echo isset($span['resource']) ? ', ' . $span['resource'] : ''; - echo isset($span['meta']['error.message']) ? ', ' . $span['meta']['error.message'] : ''; + echo isset($span['attributes']['error.message']) ? ', ' . $span['attributes']['error.message'] : ''; echo PHP_EOL; }, dd_trace_serialize_closed_spans()); ?> diff --git a/tests/ext/sandbox/exception_handled_with_finally.phpt b/tests/ext/sandbox/exception_handled_with_finally.phpt index d1cd2259f03..ba7f5ee028b 100644 --- a/tests/ext/sandbox/exception_handled_with_finally.phpt +++ b/tests/ext/sandbox/exception_handled_with_finally.phpt @@ -37,7 +37,7 @@ echo doCatchWithFinally() . PHP_EOL; array_map(function($span) { echo $span['name']; echo isset($span['resource']) ? ', ' . $span['resource'] : ''; - echo isset($span['meta']['error.message']) ? ', ' . $span['meta']['error.message'] : ''; + echo isset($span['attributes']['error.message']) ? ', ' . $span['attributes']['error.message'] : ''; echo PHP_EOL; }, dd_trace_serialize_closed_spans()); ?> diff --git a/tests/ext/sandbox/exception_handling.phpt b/tests/ext/sandbox/exception_handling.phpt index 32b43000e19..1be3557dc21 100644 --- a/tests/ext/sandbox/exception_handling.phpt +++ b/tests/ext/sandbox/exception_handling.phpt @@ -30,15 +30,15 @@ try { $span = $stack[0]; echo "error: ", $span['error'], "\n"; - echo "Exception type: ", $span['meta']['error.type'], "\n"; - echo "Exception msg: ", $span['meta']['error.message'], "\n"; - echo "Exception stack:\n", $span['meta']['error.stack'], "\n"; + echo "Exception type: ", $span['attributes']['error.type'], "\n"; + echo "Exception msg: ", $span['attributes']['error.message'], "\n"; + echo "Exception stack:\n", $span['attributes']['error.stack'], "\n"; $span = $stack[1]; echo "error: ", $span['error'], "\n"; - echo "Exception type: ", $span['meta']['error.type'], "\n"; - echo "Exception msg: ", $span['meta']['error.message'], "\n"; - echo "Exception stack:\n", $span['meta']['error.stack'], "\n"; + echo "Exception type: ", $span['attributes']['error.type'], "\n"; + echo "Exception msg: ", $span['attributes']['error.message'], "\n"; + echo "Exception stack:\n", $span['attributes']['error.stack'], "\n"; } ?> diff --git a/tests/ext/sandbox/exceptions_are_passed_to_the_tracing_closure.phpt b/tests/ext/sandbox/exceptions_are_passed_to_the_tracing_closure.phpt index 71c6c5d8eee..c8280926148 100644 --- a/tests/ext/sandbox/exceptions_are_passed_to_the_tracing_closure.phpt +++ b/tests/ext/sandbox/exceptions_are_passed_to_the_tracing_closure.phpt @@ -34,8 +34,8 @@ try { array_map(function($span) { echo $span['name']; - if (isset($span['meta']['error.message'])) { - echo ' with exception: ' . $span['meta']['error.message']; + if (isset($span['attributes']['error.message'])) { + echo ' with exception: ' . $span['attributes']['error.message']; } echo PHP_EOL; }, dd_trace_serialize_closed_spans()); diff --git a/tests/ext/sandbox/exceptions_in_original_call_rethrown_in_tracing_closure.phpt b/tests/ext/sandbox/exceptions_in_original_call_rethrown_in_tracing_closure.phpt index facb68382c9..885df67cca9 100644 --- a/tests/ext/sandbox/exceptions_in_original_call_rethrown_in_tracing_closure.phpt +++ b/tests/ext/sandbox/exceptions_in_original_call_rethrown_in_tracing_closure.phpt @@ -23,7 +23,7 @@ array_map(function($span) { printf( "%s with exception: %s\n", $span['name'], - $span['meta']['error.message'] + $span['attributes']['error.message'] ); }, dd_trace_serialize_closed_spans()); ?> diff --git a/tests/ext/sandbox/fatal_errors_are_tracked_001.phpt b/tests/ext/sandbox/fatal_errors_are_tracked_001.phpt index 069bf90c60a..2555674c1e9 100644 --- a/tests/ext/sandbox/fatal_errors_are_tracked_001.phpt +++ b/tests/ext/sandbox/fatal_errors_are_tracked_001.phpt @@ -11,9 +11,9 @@ register_shutdown_function(function () { foreach (dd_trace_serialize_closed_spans() as $span) { echo $span['name'] . PHP_EOL; if (isset($span['error']) && $span['error'] === 1) { - echo $span['meta']['error.type'] . PHP_EOL; - echo $span['meta']['error.message'] . PHP_EOL; - echo $span['meta']['error.stack'] . PHP_EOL; + echo $span['attributes']['error.type'] . PHP_EOL; + echo $span['attributes']['error.message'] . PHP_EOL; + echo $span['attributes']['error.stack'] . PHP_EOL; } } }); diff --git a/tests/ext/sandbox/fatal_errors_are_tracked_002.phpt b/tests/ext/sandbox/fatal_errors_are_tracked_002.phpt index f60eeabc176..d8944d0042b 100644 --- a/tests/ext/sandbox/fatal_errors_are_tracked_002.phpt +++ b/tests/ext/sandbox/fatal_errors_are_tracked_002.phpt @@ -14,9 +14,9 @@ register_shutdown_function(function () { foreach (dd_trace_serialize_closed_spans() as $span) { echo $span['name'] . PHP_EOL; if (isset($span['error']) && $span['error'] === 1) { - echo $span['meta']['error.type'] . PHP_EOL; - echo $span['meta']['error.message'] . PHP_EOL; - echo $span['meta']['error.stack'] . PHP_EOL; + echo $span['attributes']['error.type'] . PHP_EOL; + echo $span['attributes']['error.message'] . PHP_EOL; + echo $span['attributes']['error.stack'] . PHP_EOL; } } }); diff --git a/tests/ext/sandbox/fatal_errors_are_tracked_003.phpt b/tests/ext/sandbox/fatal_errors_are_tracked_003.phpt index 7561b0f1534..b1b3d85020f 100644 --- a/tests/ext/sandbox/fatal_errors_are_tracked_003.phpt +++ b/tests/ext/sandbox/fatal_errors_are_tracked_003.phpt @@ -14,9 +14,9 @@ register_shutdown_function(function () { foreach (dd_trace_serialize_closed_spans() as $span) { echo $span['name'] . PHP_EOL; if (isset($span['error']) && $span['error'] === 1) { - echo $span['meta']['error.type'] . PHP_EOL; - echo $span['meta']['error.message'] . PHP_EOL; - echo $span['meta']['error.stack'] . PHP_EOL; + echo $span['attributes']['error.type'] . PHP_EOL; + echo $span['attributes']['error.message'] . PHP_EOL; + echo $span['attributes']['error.stack'] . PHP_EOL; } } }); diff --git a/tests/ext/sandbox/fatal_errors_are_tracked_004.phpt b/tests/ext/sandbox/fatal_errors_are_tracked_004.phpt index 7d3e2f56cd7..2acb184131b 100644 --- a/tests/ext/sandbox/fatal_errors_are_tracked_004.phpt +++ b/tests/ext/sandbox/fatal_errors_are_tracked_004.phpt @@ -11,9 +11,9 @@ register_shutdown_function(function () { foreach (dd_trace_serialize_closed_spans() as $span) { echo $span['name'] . PHP_EOL; if (isset($span['error']) && $span['error'] === 1) { - echo $span['meta']['error.type'] . PHP_EOL; - echo $span['meta']['error.message'] . PHP_EOL; - echo $span['meta']['error.stack'] . PHP_EOL; + echo $span['attributes']['error.type'] . PHP_EOL; + echo $span['attributes']['error.message'] . PHP_EOL; + echo $span['attributes']['error.stack'] . PHP_EOL; } } }); diff --git a/tests/ext/sandbox/fatal_errors_are_tracked_005.phpt b/tests/ext/sandbox/fatal_errors_are_tracked_005.phpt index 886b2d8f4fa..db6036d6805 100644 --- a/tests/ext/sandbox/fatal_errors_are_tracked_005.phpt +++ b/tests/ext/sandbox/fatal_errors_are_tracked_005.phpt @@ -11,9 +11,9 @@ register_shutdown_function(function () { foreach (dd_trace_serialize_closed_spans() as $span) { echo $span['name'] . PHP_EOL; if (isset($span['error']) && $span['error'] === 1) { - echo $span['meta']['error.type'] . PHP_EOL; - echo $span['meta']['error.message'] . PHP_EOL; - echo $span['meta']['error.stack'] . PHP_EOL; + echo $span['attributes']['error.type'] . PHP_EOL; + echo $span['attributes']['error.message'] . PHP_EOL; + echo $span['attributes']['error.stack'] . PHP_EOL; } } }); diff --git a/tests/ext/sandbox/generator_with_exception.phpt b/tests/ext/sandbox/generator_with_exception.phpt index 2ecb9930d21..5a42c8b606b 100644 --- a/tests/ext/sandbox/generator_with_exception.phpt +++ b/tests/ext/sandbox/generator_with_exception.phpt @@ -42,7 +42,7 @@ echo doSomething() . PHP_EOL; array_map(function($span) { echo $span['name']; echo isset($span['resource']) ? ', ' . $span['resource'] : ''; - echo isset($span['meta']['error.message']) ? ', ' . $span['meta']['error.message'] : ''; + echo isset($span['attributes']['error.message']) ? ', ' . $span['attributes']['error.message'] : ''; echo PHP_EOL; }, dd_trace_serialize_closed_spans()); ?> diff --git a/tests/ext/sandbox/safe_to_string_metadata.phpt b/tests/ext/sandbox/safe_to_string_metadata.phpt index 0a6cc5c60a4..0f8675b596e 100644 --- a/tests/ext/sandbox/safe_to_string_metadata.phpt +++ b/tests/ext/sandbox/safe_to_string_metadata.phpt @@ -57,9 +57,12 @@ $allTheTypes[0][1] = &$allTheTypes[0]; call_user_func_array('meta_to_string', $allTheTypes); list($span) = dd_trace_serialize_closed_spans(); -unset($span['meta']['process_id'], $span['meta']['_dd.tags.process']); +unset($span['attributes']['process_id'], $span['attributes']['_dd.tags.process']); $last = -1; -foreach ($span['meta'] as $key => $value) { +foreach ($span['attributes'] as $key => $value) { + if (strpos($key, 'arg.') !== 0) { + continue; + } $index = (int)substr($key, 4); if ($last != $index) { echo PHP_EOL; @@ -85,39 +88,6 @@ arg.0.1: string(0) "" string(16) "already a string" arg.1: string(16) "already a string" -array(1) { - ["foo"]=> - int(0) -} -arg.10.foo: string(1) "0" - -array(1) { - ["bar"]=> - array(2) { - [0]=> - int(1) - ["key"]=> - int(2) - } -} -arg.11.bar.0: string(1) "1" -arg.11.bar.key: string(1) "2" - -resource(%d) of type (stream) -arg.12: string(%d) "Resource id #%d" - -string(17) "string from const" -arg.13: string(17) "string from const" - -int(42) -arg.14: string(2) "42" - -bool(true) -arg.15: string(4) "true" - -float(4.2) -arg.16: string(3) "4.2" - int(42) arg.2: string(2) "42" @@ -146,8 +116,8 @@ object(DateTime)#%d (3) { string(3) "UTC" } arg.8.date: string(26) "2019-09-10 00:00:00.000000" -arg.8.timezone: string(3) "UTC" arg.8.timezone_type: string(1) "3" +arg.8.timezone: string(3) "UTC" object(MyDt)#%d (3) { ["date"]=> @@ -158,5 +128,38 @@ object(MyDt)#%d (3) { string(3) "UTC" } arg.9.date: string(26) "2019-09-10 00:00:00.000000" -arg.9.timezone: string(3) "UTC" arg.9.timezone_type: string(1) "3" +arg.9.timezone: string(3) "UTC" + +array(1) { + ["foo"]=> + int(0) +} +arg.10.foo: string(1) "0" + +array(1) { + ["bar"]=> + array(2) { + [0]=> + int(1) + ["key"]=> + int(2) + } +} +arg.11.bar.0: string(1) "1" +arg.11.bar.key: string(1) "2" + +resource(%d) of type (stream) +arg.12: string(%d) "Resource id #%d" + +string(17) "string from const" +arg.13: string(17) "string from const" + +int(42) +arg.14: string(2) "42" + +bool(true) +arg.15: string(4) "true" + +float(4.2) +arg.16: string(3) "4.2" diff --git a/tests/ext/sandbox/safe_to_string_metrics.phpt b/tests/ext/sandbox/safe_to_string_metrics.phpt index c3f1ee325b8..c5b26d2445c 100644 --- a/tests/ext/sandbox/safe_to_string_metrics.phpt +++ b/tests/ext/sandbox/safe_to_string_metrics.phpt @@ -33,7 +33,10 @@ call_user_func_array('metrics_to_string', $allTheTypes); list($span) = dd_trace_serialize_closed_spans(); $last = -1; -foreach ($span['metrics'] as $key => $value) { +foreach ($span['attributes'] as $key => $value) { + if (strpos($key, 'arg.') !== 0) { + continue; + } $index = (int)substr($key, 4); if ($last != $index) { echo PHP_EOL; diff --git a/tests/ext/single-span_sampling/accept-single-span.phpt b/tests/ext/single-span_sampling/accept-single-span.phpt index 85f3f5014f1..a101cf2f429 100644 --- a/tests/ext/single-span_sampling/accept-single-span.phpt +++ b/tests/ext/single-span_sampling/accept-single-span.phpt @@ -9,7 +9,11 @@ DD_SPAN_SAMPLING_RULES=[{"sample_rate":1}] DDTrace\start_span(); DDTrace\close_span(); -var_dump(dd_trace_serialize_closed_spans()[0]["metrics"]); +$attributes = dd_trace_serialize_closed_spans()[0]["attributes"]; +var_dump([ + "_dd.span_sampling.mechanism" => $attributes["_dd.span_sampling.mechanism"], + "_dd.span_sampling.rule_rate" => $attributes["_dd.span_sampling.rule_rate"], +]); ?> --EXPECT-- diff --git a/tests/ext/single-span_sampling/check-sample-rate.phpt b/tests/ext/single-span_sampling/check-sample-rate.phpt index 569ff40bc7b..03104991a16 100644 --- a/tests/ext/single-span_sampling/check-sample-rate.phpt +++ b/tests/ext/single-span_sampling/check-sample-rate.phpt @@ -14,7 +14,7 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DDTrace\start_span(); DDTrace\close_span(); -$last = dd_trace_serialize_closed_spans()[0]["metrics"]; +$last = dd_trace_serialize_closed_spans()[0]["attributes"]; print "First span: rule_rate={$last["_dd.span_sampling.rule_rate"]}\n"; $droppedCount = 0; @@ -22,7 +22,7 @@ for ($i = 0; $i < 7; ++$i) { DDTrace\start_span(); DDTrace\close_span(); - $last = dd_trace_serialize_closed_spans()[0]["metrics"]; + $last = dd_trace_serialize_closed_spans()[0]["attributes"]; $droppedCount += !isset($last["_dd.span_sampling.mechanism"]); } echo "$droppedCount dropped out of 7\n"; @@ -32,7 +32,7 @@ for ($i = 0; $i < 3; ++$i) { DDTrace\start_span(); DDTrace\close_span(); - $last = dd_trace_serialize_closed_spans()[0]["metrics"]; + $last = dd_trace_serialize_closed_spans()[0]["attributes"]; $droppedCount += !isset($last["_dd.span_sampling.mechanism"]); } echo "$droppedCount dropped out of 3\n"; @@ -42,7 +42,7 @@ usleep(350000); DDTrace\start_span(); DDTrace\close_span(); -$last = dd_trace_serialize_closed_spans()[0]["metrics"]; +$last = dd_trace_serialize_closed_spans()[0]["attributes"]; echo "11th span: rule_rate={$last["_dd.span_sampling.rule_rate"]}\n"; ?> diff --git a/tests/ext/single-span_sampling/limited-single-span-with-match.phpt b/tests/ext/single-span_sampling/limited-single-span-with-match.phpt index 20df9b9f211..1efa9984856 100644 --- a/tests/ext/single-span_sampling/limited-single-span-with-match.phpt +++ b/tests/ext/single-span_sampling/limited-single-span-with-match.phpt @@ -16,7 +16,7 @@ for ($i = 0; $i < 5; ++$i) { DDTrace\active_span()->service = "a"; DDTrace\close_span(); - $last = dd_trace_serialize_closed_spans()[0]["metrics"]; + $last = dd_trace_serialize_closed_spans()[0]["attributes"]; $droppedCount += !isset($last["_dd.span_sampling.mechanism"]); } @@ -28,7 +28,7 @@ for ($i = 0; $i < 5; ++$i) { DDTrace\active_span()->name = "b"; DDTrace\close_span(); - $last = dd_trace_serialize_closed_spans()[0]["metrics"]; + $last = dd_trace_serialize_closed_spans()[0]["attributes"]; $droppedCount += !isset($last["_dd.span_sampling.mechanism"]); } @@ -41,7 +41,7 @@ for ($i = 0; $i < 5; ++$i) { DDTrace\active_span()->name = "b"; DDTrace\close_span(); - $last = dd_trace_serialize_closed_spans()[0]["metrics"]; + $last = dd_trace_serialize_closed_spans()[0]["attributes"]; $droppedCount += !isset($last["_dd.span_sampling.mechanism"]); } diff --git a/tests/ext/single-span_sampling/limited-single-span.phpt b/tests/ext/single-span_sampling/limited-single-span.phpt index fae36301037..1c2dacae456 100644 --- a/tests/ext/single-span_sampling/limited-single-span.phpt +++ b/tests/ext/single-span_sampling/limited-single-span.phpt @@ -14,7 +14,7 @@ for ($i = 0; $i < 3; ++$i) { DDTrace\start_span(); DDTrace\close_span(); - $last = dd_trace_serialize_closed_spans()[0]["metrics"]; + $last = dd_trace_serialize_closed_spans()[0]["attributes"]; } echo "mechanism after 3: ", $last["_dd.span_sampling.mechanism"], "\n"; @@ -23,7 +23,7 @@ for ($i = 0; $i < 12; ++$i) { DDTrace\start_span(); DDTrace\close_span(); - $last = dd_trace_serialize_closed_spans()[0]["metrics"]; + $last = dd_trace_serialize_closed_spans()[0]["attributes"]; } echo "sampling present after 12: "; diff --git a/tests/ext/single-span_sampling/name-matching-single-span.phpt b/tests/ext/single-span_sampling/name-matching-single-span.phpt index 713dd552a2d..0b93c97006e 100644 --- a/tests/ext/single-span_sampling/name-matching-single-span.phpt +++ b/tests/ext/single-span_sampling/name-matching-single-span.phpt @@ -27,14 +27,14 @@ foreach ($tests as list($pattern, $service)) { DDTrace\start_span()->service = $service; DDTrace\close_span(); echo "$pattern matches $service (service): "; - var_dump((dd_trace_serialize_closed_spans()[0]["metrics"]["_dd.span_sampling.mechanism"] ?? 0) == 8); + var_dump((dd_trace_serialize_closed_spans()[0]["attributes"]["_dd.span_sampling.mechanism"] ?? 0) == 8); ini_set("datadog.span_sampling_rules", '[{"name":"' . $pattern . '","sample_rate":1}]'); DDTrace\start_span()->name = $service; DDTrace\close_span(); echo "$pattern matches $service (name): "; - var_dump((dd_trace_serialize_closed_spans()[0]["metrics"]["_dd.span_sampling.mechanism"] ?? 0) == 8); + var_dump((dd_trace_serialize_closed_spans()[0]["attributes"]["_dd.span_sampling.mechanism"] ?? 0) == 8); } ?> diff --git a/tests/ext/single-span_sampling/read-single-span-sampling-config-from-file.phpt b/tests/ext/single-span_sampling/read-single-span-sampling-config-from-file.phpt index 235bb2cdf80..4c9d625460e 100644 --- a/tests/ext/single-span_sampling/read-single-span-sampling-config-from-file.phpt +++ b/tests/ext/single-span_sampling/read-single-span-sampling-config-from-file.phpt @@ -12,14 +12,14 @@ ini_set("datadog.span_sampling_rules_file", __DIR__ . "/read-single-span-samplin DDTrace\start_span(); DDTrace\close_span(); -$last = dd_trace_serialize_closed_spans()[0]["metrics"]; +$last = dd_trace_serialize_closed_spans()[0]["attributes"]; echo "sampling present after simple span: "; var_dump(isset($last["_dd.span_sampling.mechanism"])); $a = DDTrace\start_span(); $a->service = "a"; DDTrace\close_span(); -$last = dd_trace_serialize_closed_spans()[0]["metrics"]; +$last = dd_trace_serialize_closed_spans()[0]["attributes"]; echo "sampling present after span of service a: "; var_dump(isset($last["_dd.span_sampling.mechanism"])); From 71dfa8ee1e56073678ea5faf9354f7d6f65967db Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 31 Aug 2026 16:35:29 +0200 Subject: [PATCH 26/32] test: update .phpt expectations for v1 serialization shape (batch 2: root_span_url/http/referrer, extract_*) Relocate meta -> attributes for root_span_url_*, root_span_http_*, security-headers, referrer_extraction_*, and extract_server_values / extract_ip_private_01 / ip_collection_03. span.kind moves to the top-level int span_kind field. Full-array meta dumps are replaced with targeted key/absence checks: the unified attributes map now also carries entrypoint-only telemetry (process_id, php.compilation.total_time_ms, php.memory.*) whose float values are non-deterministic across runs, so dumping the whole map would make these tests flaky. The targeted checks preserve each test's original intent (URL/referrer/post-data extraction) without asserting on unrelated telemetry noise. --- tests/ext/extract_ip_private_01.phpt | 2 +- tests/ext/extract_server_values.phpt | 17 +++--------- .../security_headers_forwarded.phpt | 8 +++--- tests/ext/ip_collection_03.phpt | 2 +- tests/ext/referrer_extraction_01.phpt | 23 +++------------- tests/ext/referrer_extraction_02.phpt | 25 +++-------------- tests/ext/referrer_extraction_03.phpt | 23 +++------------- tests/ext/referrer_extraction_04.phpt | 23 +++------------- tests/ext/referrer_extraction_05.phpt | 25 +++-------------- tests/ext/root_span_http_client_ip.phpt | 2 +- ...oot_span_http_client_ip_custom_header.phpt | 2 +- ...n_http_client_ip_duplicate_ip_headers.phpt | 14 +++++----- ...t_span_http_client_ip_x_forwarded_for.phpt | 2 +- tests/ext/root_span_http_useragent.phpt | 2 +- .../root_span_security_testing_headers.phpt | 4 +-- ..._span_security_testing_headers_absent.phpt | 4 +-- .../ext/root_span_url_as_resource_names.phpt | 27 ++++++------------- ...ot_span_url_as_resource_names_no_host.phpt | 27 ++++++------------- tests/ext/root_span_url_with_post_array.phpt | 8 +++--- ...root_span_url_with_post_array_allowed.phpt | 6 ++--- tests/ext/root_span_url_with_post_fields.phpt | 12 ++++----- ...span_url_with_post_implicit_array_key.phpt | 4 +-- .../ext/root_span_url_with_post_no_param.phpt | 17 +++++------- .../root_span_url_with_post_no_param_set.phpt | 17 +++++------- ...pan_url_with_post_only_allowed_params.phpt | 8 +++--- ...t_span_url_with_post_simple_whitelist.phpt | 6 ++--- .../ext/root_span_url_with_query_params.phpt | 2 +- ...pan_url_with_query_params_obfuscation.phpt | 2 +- ...l_with_query_params_obfuscation_empty.phpt | 2 +- ..._span_url_with_query_params_whitelist.phpt | 2 +- .../root_span_url_without_query_params.phpt | 2 +- 31 files changed, 94 insertions(+), 226 deletions(-) diff --git a/tests/ext/extract_ip_private_01.phpt b/tests/ext/extract_ip_private_01.phpt index 4362f7ecae9..435145953da 100644 --- a/tests/ext/extract_ip_private_01.phpt +++ b/tests/ext/extract_ip_private_01.phpt @@ -11,7 +11,7 @@ DD_TRACE_CLIENT_IP_ENABLED=true DDTrace\start_span(); DDTrace\close_span(0); $span = dd_trace_serialize_closed_spans(); -var_dump($span[0]["meta"]["http.client_ip"]); +var_dump($span[0]["attributes"]["http.client_ip"]); ?> --EXPECTF-- string(7) "7.7.7.7" diff --git a/tests/ext/extract_server_values.phpt b/tests/ext/extract_server_values.phpt index 102f24d2d89..c6af6b80ce9 100644 --- a/tests/ext/extract_server_values.phpt +++ b/tests/ext/extract_server_values.phpt @@ -20,19 +20,8 @@ if (!isset($_SERVER[0])) { DDTrace\start_span(); DDTrace\close_span(); -var_dump(dd_trace_serialize_closed_spans()[0]["meta"]); +var_dump(dd_trace_serialize_closed_spans()[0]["attributes"]["http.request.headers.0"]); ?> ---EXPECTF-- -array(5) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.tags.process"]=> - string(%d) "%s" - ["http.request.headers.0"]=> - string(16) "http_zero_header" - ["runtime-id"]=> - string(36) "%s" -} +--EXPECT-- +string(16) "http_zero_header" diff --git a/tests/ext/inferred_proxy/security_headers_forwarded.phpt b/tests/ext/inferred_proxy/security_headers_forwarded.phpt index bb960336295..e901d01e4c4 100644 --- a/tests/ext/inferred_proxy/security_headers_forwarded.phpt +++ b/tests/ext/inferred_proxy/security_headers_forwarded.phpt @@ -37,11 +37,11 @@ foreach ($spans as $span) { } // Tags must be present on the PHP service-entry span -var_dump($rootSpan['meta']['http.request.headers.x-datadog-endpoint-scan'] ?? 'NOT SET'); -var_dump($rootSpan['meta']['http.request.headers.x-datadog-security-test'] ?? 'NOT SET'); +var_dump($rootSpan['attributes']['http.request.headers.x-datadog-endpoint-scan'] ?? 'NOT SET'); +var_dump($rootSpan['attributes']['http.request.headers.x-datadog-security-test'] ?? 'NOT SET'); // And forwarded to the inferred proxy span -var_dump($inferredSpan['meta']['http.request.headers.x-datadog-endpoint-scan'] ?? 'NOT SET'); -var_dump($inferredSpan['meta']['http.request.headers.x-datadog-security-test'] ?? 'NOT SET'); +var_dump($inferredSpan['attributes']['http.request.headers.x-datadog-endpoint-scan'] ?? 'NOT SET'); +var_dump($inferredSpan['attributes']['http.request.headers.x-datadog-security-test'] ?? 'NOT SET'); ?> --EXPECT-- string(18) "endpoint-scan-uuid" diff --git a/tests/ext/ip_collection_03.phpt b/tests/ext/ip_collection_03.phpt index 3c55dc4be12..22462f9fd41 100644 --- a/tests/ext/ip_collection_03.phpt +++ b/tests/ext/ip_collection_03.phpt @@ -10,7 +10,7 @@ DD_TRACE_CLIENT_IP_ENABLED=true DDTrace\start_span(); DDTrace\close_span(0); $span = dd_trace_serialize_closed_spans(); -var_dump($span[0]["meta"]["http.client_ip"]); +var_dump($span[0]["attributes"]["http.client_ip"]); ?> --EXPECTF-- string(9) "127.0.0.1" diff --git a/tests/ext/referrer_extraction_01.phpt b/tests/ext/referrer_extraction_01.phpt index e5dd8112877..8700749fc79 100644 --- a/tests/ext/referrer_extraction_01.phpt +++ b/tests/ext/referrer_extraction_01.phpt @@ -15,24 +15,7 @@ foo=bar DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']); +var_dump($spans[0]['attributes']['http.referrer_hostname'] ?? 'NOT SET'); ?> ---EXPECTF-- -array(8) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.tags.process"]=> - string(%d) "%s" - ["http.method"]=> - string(3) "GET" - ["http.status_code"]=> - string(3) "200" - ["http.url"]=> - string(25) "http://localhost:8888/foo" - ["runtime-id"]=> - string(36) "%s" - ["span.kind"]=> - string(6) "server" -} \ No newline at end of file +--EXPECT-- +string(7) "NOT SET" \ No newline at end of file diff --git a/tests/ext/referrer_extraction_02.phpt b/tests/ext/referrer_extraction_02.phpt index b1bd2435941..22a532c96b3 100644 --- a/tests/ext/referrer_extraction_02.phpt +++ b/tests/ext/referrer_extraction_02.phpt @@ -15,26 +15,7 @@ foo=bar DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']); +var_dump($spans[0]['attributes']['http.referrer_hostname'] ?? 'NOT SET'); ?> ---EXPECTF-- -array(9) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.tags.process"]=> - string(%d) "%s" - ["http.method"]=> - string(3) "GET" - ["http.referrer_hostname"]=> - string(11) "example.com" - ["http.status_code"]=> - string(3) "200" - ["http.url"]=> - string(25) "http://localhost:8888/foo" - ["runtime-id"]=> - string(36) "%s" - ["span.kind"]=> - string(6) "server" -} \ No newline at end of file +--EXPECT-- +string(11) "example.com" \ No newline at end of file diff --git a/tests/ext/referrer_extraction_03.phpt b/tests/ext/referrer_extraction_03.phpt index 466b388c86c..9176baf68df 100644 --- a/tests/ext/referrer_extraction_03.phpt +++ b/tests/ext/referrer_extraction_03.phpt @@ -15,24 +15,7 @@ foo=bar DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']); +var_dump($spans[0]['attributes']['http.referrer_hostname'] ?? 'NOT SET'); ?> ---EXPECTF-- -array(8) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.tags.process"]=> - string(%d) "%s" - ["http.method"]=> - string(3) "GET" - ["http.status_code"]=> - string(3) "200" - ["http.url"]=> - string(25) "http://localhost:8888/foo" - ["runtime-id"]=> - string(36) "%s" - ["span.kind"]=> - string(6) "server" -} \ No newline at end of file +--EXPECT-- +string(7) "NOT SET" \ No newline at end of file diff --git a/tests/ext/referrer_extraction_04.phpt b/tests/ext/referrer_extraction_04.phpt index 18fe177d5a9..d27be1eee20 100644 --- a/tests/ext/referrer_extraction_04.phpt +++ b/tests/ext/referrer_extraction_04.phpt @@ -15,24 +15,7 @@ foo=bar DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']); +var_dump($spans[0]['attributes']['http.referrer_hostname'] ?? 'NOT SET'); ?> ---EXPECTF-- -array(8) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.tags.process"]=> - string(%d) "%s" - ["http.method"]=> - string(3) "GET" - ["http.status_code"]=> - string(3) "200" - ["http.url"]=> - string(25) "http://localhost:8888/foo" - ["runtime-id"]=> - string(36) "%s" - ["span.kind"]=> - string(6) "server" -} \ No newline at end of file +--EXPECT-- +string(7) "NOT SET" \ No newline at end of file diff --git a/tests/ext/referrer_extraction_05.phpt b/tests/ext/referrer_extraction_05.phpt index 85abb9c4484..9a56d6ce400 100644 --- a/tests/ext/referrer_extraction_05.phpt +++ b/tests/ext/referrer_extraction_05.phpt @@ -15,26 +15,7 @@ foo=bar DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']); +var_dump($spans[0]['attributes']['http.referrer_hostname'] ?? 'NOT SET'); ?> ---EXPECTF-- -array(9) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.tags.process"]=> - string(%d) "%s" - ["http.method"]=> - string(3) "GET" - ["http.referrer_hostname"]=> - string(13) "[2001:db8::1]" - ["http.status_code"]=> - string(3) "200" - ["http.url"]=> - string(25) "http://localhost:8888/foo" - ["runtime-id"]=> - string(36) "%s" - ["span.kind"]=> - string(6) "server" -} \ No newline at end of file +--EXPECT-- +string(13) "[2001:db8::1]" \ No newline at end of file diff --git a/tests/ext/root_span_http_client_ip.phpt b/tests/ext/root_span_http_client_ip.phpt index 8789981f693..e9bd1cd3ac6 100644 --- a/tests/ext/root_span_http_client_ip.phpt +++ b/tests/ext/root_span_http_client_ip.phpt @@ -10,7 +10,7 @@ DD_TRACE_CLIENT_IP_ENABLED=true DDTrace\start_span(); DDTrace\close_span(0); $span = dd_trace_serialize_closed_spans(); -var_dump($span[0]["meta"]["http.client_ip"]); +var_dump($span[0]["attributes"]["http.client_ip"]); ?> --EXPECTF-- string(9) "127.0.0.1" diff --git a/tests/ext/root_span_http_client_ip_custom_header.phpt b/tests/ext/root_span_http_client_ip_custom_header.phpt index 3182c9aa6f2..1c3aee84f20 100644 --- a/tests/ext/root_span_http_client_ip_custom_header.phpt +++ b/tests/ext/root_span_http_client_ip_custom_header.phpt @@ -11,7 +11,7 @@ DD_TRACE_CLIENT_IP_ENABLED=true DDTrace\start_span(); DDTrace\close_span(0); $span = dd_trace_serialize_closed_spans(); -var_dump($span[0]["meta"]["http.client_ip"]); +var_dump($span[0]["attributes"]["http.client_ip"]); ?> --EXPECTF-- string(7) "7.7.7.7" diff --git a/tests/ext/root_span_http_client_ip_duplicate_ip_headers.phpt b/tests/ext/root_span_http_client_ip_duplicate_ip_headers.phpt index 26155009606..c2ba58361d1 100644 --- a/tests/ext/root_span_http_client_ip_duplicate_ip_headers.phpt +++ b/tests/ext/root_span_http_client_ip_duplicate_ip_headers.phpt @@ -17,13 +17,13 @@ DD_TRACE_CLIENT_IP_ENABLED=true DDTrace\start_span(); DDTrace\close_span(0); $span = dd_trace_serialize_closed_spans(); -var_dump(isset($span[0]["meta"]['http.request.headers.x-forwarded-for'])); -var_dump(isset($span[0]["meta"]['http.request.headers.x-real-ip'])); -var_dump(isset($span[0]["meta"]['http.request.headers.x-forwarded'])); -var_dump(isset($span[0]["meta"]['http.request.headers.x-cluster-client-ip'])); -var_dump(isset($span[0]["meta"]['http.request.headers.forwarded-for'])); -var_dump(isset($span[0]["meta"]['http.request.headers.true-client-ip'])); -var_dump($span[0]["meta"]["http.client_ip"]); +var_dump(isset($span[0]["attributes"]['http.request.headers.x-forwarded-for'])); +var_dump(isset($span[0]["attributes"]['http.request.headers.x-real-ip'])); +var_dump(isset($span[0]["attributes"]['http.request.headers.x-forwarded'])); +var_dump(isset($span[0]["attributes"]['http.request.headers.x-cluster-client-ip'])); +var_dump(isset($span[0]["attributes"]['http.request.headers.forwarded-for'])); +var_dump(isset($span[0]["attributes"]['http.request.headers.true-client-ip'])); +var_dump($span[0]["attributes"]["http.client_ip"]); ?> --EXPECTF-- bool(false) diff --git a/tests/ext/root_span_http_client_ip_x_forwarded_for.phpt b/tests/ext/root_span_http_client_ip_x_forwarded_for.phpt index f368665db62..6bd647289c4 100644 --- a/tests/ext/root_span_http_client_ip_x_forwarded_for.phpt +++ b/tests/ext/root_span_http_client_ip_x_forwarded_for.phpt @@ -10,7 +10,7 @@ DD_TRACE_CLIENT_IP_ENABLED=true DDTrace\start_span(); DDTrace\close_span(0); $span = dd_trace_serialize_closed_spans(); -var_dump($span[0]["meta"]["http.client_ip"]); +var_dump($span[0]["attributes"]["http.client_ip"]); ?> --EXPECTF-- string(7) "7.7.7.7" diff --git a/tests/ext/root_span_http_useragent.phpt b/tests/ext/root_span_http_useragent.phpt index 4c60e34cde4..73fc5bcc1e6 100644 --- a/tests/ext/root_span_http_useragent.phpt +++ b/tests/ext/root_span_http_useragent.phpt @@ -9,7 +9,7 @@ HTTP_USER_AGENT=dd_trace_user_agent DDTrace\start_span(); DDTrace\close_span(0); $span = dd_trace_serialize_closed_spans(); -var_dump($span[0]["meta"]["http.useragent"]); +var_dump($span[0]["attributes"]["http.useragent"]); ?> --EXPECTF-- string(19) "dd_trace_user_agent" diff --git a/tests/ext/root_span_security_testing_headers.phpt b/tests/ext/root_span_security_testing_headers.phpt index 2f8a9a9cc09..911e8834d78 100644 --- a/tests/ext/root_span_security_testing_headers.phpt +++ b/tests/ext/root_span_security_testing_headers.phpt @@ -11,8 +11,8 @@ HTTP_X_DATADOG_SECURITY_TEST=security-test-uuid DDTrace\start_span(); DDTrace\close_span(0); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']['http.request.headers.x-datadog-endpoint-scan']); -var_dump($spans[0]['meta']['http.request.headers.x-datadog-security-test']); +var_dump($spans[0]['attributes']['http.request.headers.x-datadog-endpoint-scan']); +var_dump($spans[0]['attributes']['http.request.headers.x-datadog-security-test']); ?> --EXPECT-- string(18) "endpoint-scan-uuid" diff --git a/tests/ext/root_span_security_testing_headers_absent.phpt b/tests/ext/root_span_security_testing_headers_absent.phpt index c80ae66215d..160a09909b2 100644 --- a/tests/ext/root_span_security_testing_headers_absent.phpt +++ b/tests/ext/root_span_security_testing_headers_absent.phpt @@ -8,8 +8,8 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DDTrace\start_span(); DDTrace\close_span(0); $spans = dd_trace_serialize_closed_spans(); -var_dump(array_key_exists('http.request.headers.x-datadog-endpoint-scan', $spans[0]['meta'])); -var_dump(array_key_exists('http.request.headers.x-datadog-security-test', $spans[0]['meta'])); +var_dump(array_key_exists('http.request.headers.x-datadog-endpoint-scan', $spans[0]['attributes'])); +var_dump(array_key_exists('http.request.headers.x-datadog-security-test', $spans[0]['attributes'])); ?> --EXPECT-- bool(false) diff --git a/tests/ext/root_span_url_as_resource_names.phpt b/tests/ext/root_span_url_as_resource_names.phpt index 9840f0d8ac4..4224d657dfb 100644 --- a/tests/ext/root_span_url_as_resource_names.phpt +++ b/tests/ext/root_span_url_as_resource_names.phpt @@ -17,24 +17,13 @@ foo=bar DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']); +var_dump($spans[0]['span_kind']); +var_dump($spans[0]['attributes']['http.method']); +var_dump($spans[0]['attributes']['http.status_code']); +var_dump($spans[0]['attributes']['http.url']); ?> --EXPECTF-- -array(8) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.tags.process"]=> - string(%d) "%s" - ["http.method"]=> - string(3) "GET" - ["http.status_code"]=> - string(3) "200" - ["http.url"]=> - string(26) "https://localhost:9999/foo" - ["runtime-id"]=> - string(36) "%s" - ["span.kind"]=> - string(6) "server" -} +int(2) +string(3) "GET" +string(3) "200" +string(26) "https://localhost:9999/foo" diff --git a/tests/ext/root_span_url_as_resource_names_no_host.phpt b/tests/ext/root_span_url_as_resource_names_no_host.phpt index eec467b9242..780267e7812 100644 --- a/tests/ext/root_span_url_as_resource_names_no_host.phpt +++ b/tests/ext/root_span_url_as_resource_names_no_host.phpt @@ -16,24 +16,13 @@ foo=bar DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']); +var_dump($spans[0]['span_kind']); +var_dump($spans[0]['attributes']['http.method']); +var_dump($spans[0]['attributes']['http.status_code']); +var_dump($spans[0]['attributes']['http.url']); ?> --EXPECTF-- -array(8) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.tags.process"]=> - string(%d) "%s" - ["http.method"]=> - string(3) "GET" - ["http.status_code"]=> - string(3) "200" - ["http.url"]=> - string(25) "http://localhost:8888/foo" - ["runtime-id"]=> - string(36) "%s" - ["span.kind"]=> - string(6) "server" -} +int(2) +string(3) "GET" +string(3) "200" +string(25) "http://localhost:8888/foo" diff --git a/tests/ext/root_span_url_with_post_array.phpt b/tests/ext/root_span_url_with_post_array.phpt index 61b849504af..4f2d37532d9 100644 --- a/tests/ext/root_span_url_with_post_array.phpt +++ b/tests/ext/root_span_url_with_post_array.phpt @@ -14,10 +14,10 @@ password=should_redact&foo[bar][baz]=qux&foo[baz][bar]=quz&foo[bar][password]=sh DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']['http.request.post.password']); -var_dump($spans[0]['meta']['http.request.post.foo.bar.baz']); -var_dump($spans[0]['meta']['http.request.post.foo.baz.bar']); -var_dump($spans[0]['meta']['http.request.post.foo.bar.password']); +var_dump($spans[0]['attributes']['http.request.post.password']); +var_dump($spans[0]['attributes']['http.request.post.foo.bar.baz']); +var_dump($spans[0]['attributes']['http.request.post.foo.baz.bar']); +var_dump($spans[0]['attributes']['http.request.post.foo.bar.password']); ?> --EXPECT-- string(10) "" diff --git a/tests/ext/root_span_url_with_post_array_allowed.phpt b/tests/ext/root_span_url_with_post_array_allowed.phpt index b8d925b89a9..10c6d72861f 100644 --- a/tests/ext/root_span_url_with_post_array_allowed.phpt +++ b/tests/ext/root_span_url_with_post_array_allowed.phpt @@ -14,9 +14,9 @@ foo[baz]=bar&foo[bar][key]=baz&foo[bar][baz]=quz DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']['http.request.post.foo.baz']); -var_dump($spans[0]['meta']['http.request.post.foo.bar.key']); -var_dump($spans[0]['meta']['http.request.post.foo.bar.baz']); +var_dump($spans[0]['attributes']['http.request.post.foo.baz']); +var_dump($spans[0]['attributes']['http.request.post.foo.bar.key']); +var_dump($spans[0]['attributes']['http.request.post.foo.bar.baz']); ?> --EXPECT-- string(3) "bar" diff --git a/tests/ext/root_span_url_with_post_fields.phpt b/tests/ext/root_span_url_with_post_fields.phpt index b38e1745b5a..32653c2cd0b 100644 --- a/tests/ext/root_span_url_with_post_fields.phpt +++ b/tests/ext/root_span_url_with_post_fields.phpt @@ -15,12 +15,12 @@ DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); var_dump($spans[0]['resource']); -var_dump($spans[0]['meta']['http.method']); -var_dump($spans[0]['meta']['http.request.post.foo']); -var_dump($spans[0]['meta']['http.request.post.password']); -var_dump($spans[0]['meta']['http.request.post.username']); -var_dump($spans[0]['meta']['http.request.post.token']); -var_dump($spans[0]['meta']['http.request.post.key']); +var_dump($spans[0]['attributes']['http.method']); +var_dump($spans[0]['attributes']['http.request.post.foo']); +var_dump($spans[0]['attributes']['http.request.post.password']); +var_dump($spans[0]['attributes']['http.request.post.username']); +var_dump($spans[0]['attributes']['http.request.post.token']); +var_dump($spans[0]['attributes']['http.request.post.key']); ?> --EXPECT-- string(4) "POST" diff --git a/tests/ext/root_span_url_with_post_implicit_array_key.phpt b/tests/ext/root_span_url_with_post_implicit_array_key.phpt index e73150fc9ef..9feba6f17ac 100644 --- a/tests/ext/root_span_url_with_post_implicit_array_key.phpt +++ b/tests/ext/root_span_url_with_post_implicit_array_key.phpt @@ -14,8 +14,8 @@ foo[]=a&foo[]=b DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']['http.request.post.foo.0']); -var_dump($spans[0]['meta']['http.request.post.foo.1']); +var_dump($spans[0]['attributes']['http.request.post.foo.0']); +var_dump($spans[0]['attributes']['http.request.post.foo.1']); ?> --EXPECT-- string(1) "a" diff --git a/tests/ext/root_span_url_with_post_no_param.phpt b/tests/ext/root_span_url_with_post_no_param.phpt index 8553f5f4ef0..b50f7f317cc 100644 --- a/tests/ext/root_span_url_with_post_no_param.phpt +++ b/tests/ext/root_span_url_with_post_no_param.phpt @@ -15,16 +15,11 @@ METHOD=POST DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']); +$postKeys = array_filter(array_keys($spans[0]['attributes']), function ($key) { + return strpos($key, 'http.request.post') === 0; +}); +var_dump($postKeys); ?> ---EXPECTF-- -array(4) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.tags.process"]=> - string(%d) "%s" - ["runtime-id"]=> - string(36) "%s" +--EXPECT-- +array(0) { } diff --git a/tests/ext/root_span_url_with_post_no_param_set.phpt b/tests/ext/root_span_url_with_post_no_param_set.phpt index 21c0c516765..db1a56f9d0d 100644 --- a/tests/ext/root_span_url_with_post_no_param_set.phpt +++ b/tests/ext/root_span_url_with_post_no_param_set.phpt @@ -14,16 +14,11 @@ METHOD=POST DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']); +$postKeys = array_filter(array_keys($spans[0]['attributes']), function ($key) { + return strpos($key, 'http.request.post') === 0; +}); +var_dump($postKeys); ?> ---EXPECTF-- -array(4) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.tags.process"]=> - string(%d) "%s" - ["runtime-id"]=> - string(36) "%s" +--EXPECT-- +array(0) { } diff --git a/tests/ext/root_span_url_with_post_only_allowed_params.phpt b/tests/ext/root_span_url_with_post_only_allowed_params.phpt index 1fe141ced9e..0e9383bf4f6 100644 --- a/tests/ext/root_span_url_with_post_only_allowed_params.phpt +++ b/tests/ext/root_span_url_with_post_only_allowed_params.phpt @@ -14,10 +14,10 @@ username=should_redact&foo[bar]=should_not_redact&foo[baz]=should_redact&bar[foo DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']['http.request.post.username']); -var_dump($spans[0]['meta']['http.request.post.foo.bar']); -var_dump($spans[0]['meta']['http.request.post.foo.baz']); -var_dump($spans[0]['meta']['http.request.post.bar.foo']); +var_dump($spans[0]['attributes']['http.request.post.username']); +var_dump($spans[0]['attributes']['http.request.post.foo.bar']); +var_dump($spans[0]['attributes']['http.request.post.foo.baz']); +var_dump($spans[0]['attributes']['http.request.post.bar.foo']); ?> --EXPECT-- string(10) "" diff --git a/tests/ext/root_span_url_with_post_simple_whitelist.phpt b/tests/ext/root_span_url_with_post_simple_whitelist.phpt index c294d2741e0..a488f11d1e9 100644 --- a/tests/ext/root_span_url_with_post_simple_whitelist.phpt +++ b/tests/ext/root_span_url_with_post_simple_whitelist.phpt @@ -14,9 +14,9 @@ foo=bar&password=should_not_redact&username=should_redact DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']['http.request.post.foo']); -var_dump($spans[0]['meta']['http.request.post.password']); -var_dump($spans[0]['meta']['http.request.post.username']); +var_dump($spans[0]['attributes']['http.request.post.foo']); +var_dump($spans[0]['attributes']['http.request.post.password']); +var_dump($spans[0]['attributes']['http.request.post.username']); ?> --EXPECT-- string(3) "bar" diff --git a/tests/ext/root_span_url_with_query_params.phpt b/tests/ext/root_span_url_with_query_params.phpt index 33f86a772bb..1331fd27b37 100644 --- a/tests/ext/root_span_url_with_query_params.phpt +++ b/tests/ext/root_span_url_with_query_params.phpt @@ -20,7 +20,7 @@ DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); var_dump($spans[0]['resource']); -var_dump($spans[0]['meta']["http.url"]); +var_dump($spans[0]['attributes']["http.url"]); ?> --EXPECT-- string(14) "GET /foo?param" diff --git a/tests/ext/root_span_url_with_query_params_obfuscation.phpt b/tests/ext/root_span_url_with_query_params_obfuscation.phpt index db6133a6db6..7f66e030a9e 100644 --- a/tests/ext/root_span_url_with_query_params_obfuscation.phpt +++ b/tests/ext/root_span_url_with_query_params_obfuscation.phpt @@ -16,7 +16,7 @@ key1=val1&token=a0b21ce2-006f-4cc6-95d5-d7b550698482&key2=val2&password=somethin DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']["http.url"]); +var_dump($spans[0]['attributes']["http.url"]); ?> --EXPECT-- string(104) "https://localhost:9999/foo?key1=val1&&key2=val2&&key=%7B%20%7D&other=value" diff --git a/tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt b/tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt index fd83693e72c..7075915fe88 100644 --- a/tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt +++ b/tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt @@ -17,7 +17,7 @@ application_key=123 DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']["http.url"]); +var_dump($spans[0]['attributes']["http.url"]); ?> --EXPECT-- string(48) "https://localhost:9999/users?application_key=123" diff --git a/tests/ext/root_span_url_with_query_params_whitelist.phpt b/tests/ext/root_span_url_with_query_params_whitelist.phpt index 00d83c900c6..edcc9425b0b 100644 --- a/tests/ext/root_span_url_with_query_params_whitelist.phpt +++ b/tests/ext/root_span_url_with_query_params_whitelist.phpt @@ -16,7 +16,7 @@ password=value&some=query¶m&eters DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']["http.url"]); +var_dump($spans[0]['attributes']["http.url"]); ?> --EXPECT-- string(41) "https://localhost:9999/foo?password=value" diff --git a/tests/ext/root_span_url_without_query_params.phpt b/tests/ext/root_span_url_without_query_params.phpt index 94ee21e5944..087a9326c58 100644 --- a/tests/ext/root_span_url_without_query_params.phpt +++ b/tests/ext/root_span_url_without_query_params.phpt @@ -16,7 +16,7 @@ some=query¶m&eters DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']["http.url"]); +var_dump($spans[0]['attributes']["http.url"]); ?> --EXPECT-- string(26) "https://localhost:9999/foo" From 8fdc5242f0630f0307cd1e567a3ff33912de0b4b Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 31 Aug 2026 16:38:05 +0200 Subject: [PATCH 27/32] test: update .phpt expectations for v1 serialization shape (batch 3: distributed_tracing) Relocate meta -> attributes for the asm_standalone _dd.p.ts checks. distributed_trace_overwrite_active_span needed more than a rename: _dd.origin and the 128-bit trace id high bits are now promoted to dedicated top-level fields (origin, trace_id_high) instead of living in meta/attributes, and trace_id_high is now populated on every span of a 128-bit trace (consistent with trace_id itself being duplicated per span), not only the root. Also filter out the newly-visible per-span telemetry noise (_dd.agent_psr, php.compilation/memory.*) that the unified attributes map now carries. --- .../distributed_trace_asm_standalone_03.phpt | 2 +- .../distributed_trace_asm_standalone_04.phpt | 2 +- .../distributed_trace_asm_standalone_05.phpt | 2 +- .../distributed_trace_asm_standalone_06.phpt | 6 +++--- .../distributed_trace_asm_standalone_07.phpt | 4 ++-- .../distributed_trace_asm_standalone_08.phpt | 2 +- .../distributed_trace_asm_standalone_09.phpt | 2 +- ...stributed_trace_overwrite_active_span.phpt | 21 ++++++++++++++++--- 8 files changed, 28 insertions(+), 13 deletions(-) diff --git a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_03.phpt b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_03.phpt index 30ea476e07c..df4a71554c1 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_03.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_03.phpt @@ -18,7 +18,7 @@ DDTrace\close_span(); $traces = dd_trace_serialize_closed_spans(); -var_dump($traces[0]['meta']['_dd.p.ts']); +var_dump($traces[0]['attributes']['_dd.p.ts']); ?> --EXPECTF-- diff --git a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_04.phpt b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_04.phpt index 1a589559b3e..86700f64ac8 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_04.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_04.phpt @@ -18,7 +18,7 @@ DDTrace\close_span(); $traces = dd_trace_serialize_closed_spans(); -var_dump($traces[0]['meta']['_dd.p.ts']); +var_dump($traces[0]['attributes']['_dd.p.ts']); ?> --EXPECTF-- diff --git a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_05.phpt b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_05.phpt index 70046cb2b2e..eb5f2c44dea 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_05.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_05.phpt @@ -18,7 +18,7 @@ DDTrace\close_span(); $traces = dd_trace_serialize_closed_spans(); -var_dump($traces[0]['meta']['_dd.p.ts']); +var_dump($traces[0]['attributes']['_dd.p.ts']); ?> --EXPECTF-- diff --git a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_06.phpt b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_06.phpt index 2b75385f956..cb92e2e7921 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_06.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_06.phpt @@ -26,11 +26,11 @@ DDTrace\close_span(); $traces = dd_trace_serialize_closed_spans(); var_dump($traces[0]['name']); -var_dump(isset($traces[0]['meta']['_dd.p.ts'])); +var_dump(isset($traces[0]['attributes']['_dd.p.ts'])); var_dump($traces[1]['name']); -var_dump($traces[1]['meta']['_dd.p.ts']); +var_dump($traces[1]['attributes']['_dd.p.ts']); var_dump($traces[2]['name']); -var_dump($traces[2]['meta']['_dd.p.ts']); +var_dump($traces[2]['attributes']['_dd.p.ts']); ?> --EXPECTF-- diff --git a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_07.phpt b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_07.phpt index e9285c55484..25a2bd7a14e 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_07.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_07.phpt @@ -22,9 +22,9 @@ DDTrace\close_span(); $traces = dd_trace_serialize_closed_spans(); var_dump($traces[0]['name']); -var_dump($traces[0]['meta']['_dd.p.ts']); +var_dump($traces[0]['attributes']['_dd.p.ts']); var_dump($traces[1]['name']); -var_dump($traces[1]['meta']['_dd.p.ts']); +var_dump($traces[1]['attributes']['_dd.p.ts']); ?> --EXPECTF-- diff --git a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_08.phpt b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_08.phpt index acb15dea0dd..96e9fb8ad4d 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_08.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_08.phpt @@ -18,7 +18,7 @@ DDTrace\close_span(); $traces = dd_trace_serialize_closed_spans(); -var_dump($traces[0]['meta']['_dd.p.ts']); +var_dump($traces[0]['attributes']['_dd.p.ts']); ?> --EXPECTF-- diff --git a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_09.phpt b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_09.phpt index e02e2fef6a1..9dec29edb76 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_09.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_09.phpt @@ -17,7 +17,7 @@ DDTrace\close_span(); $traces = dd_trace_serialize_closed_spans(); -var_dump($traces[0]['meta']['_dd.p.ts']); +var_dump($traces[0]['attributes']['_dd.p.ts']); ?> --EXPECTF-- diff --git a/tests/ext/distributed_tracing/distributed_trace_overwrite_active_span.phpt b/tests/ext/distributed_tracing/distributed_trace_overwrite_active_span.phpt index f2e7b34f194..78ff7779524 100644 --- a/tests/ext/distributed_tracing/distributed_trace_overwrite_active_span.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_overwrite_active_span.phpt @@ -41,8 +41,23 @@ function largeBaseConvert($numString, $fromBase, $toBase) function dump_spans() { foreach (dd_trace_serialize_closed_spans() as $span) { - unset($span["meta"]["process_id"], $span["meta"]["runtime-id"], $span["meta"]["_dd.p.dm"], $span["meta"]["_dd.tags.process"]); - echo "parent: ", $span["parent_id"] ?? 0, ", trace: {$span["trace_id"]}, meta: " . json_encode($span["meta"] ?? []) . "\n"; + $meta = $span["attributes"] ?? []; + unset( + $meta["process_id"], $meta["runtime-id"], $meta["_dd.p.dm"], $meta["_dd.tags.process"], + $meta["_dd.agent_psr"], $meta["php.compilation.total_time_ms"], + $meta["php.memory.peak_usage_bytes"], $meta["php.memory.peak_real_usage_bytes"] + ); + // origin and the 128-bit trace id high bits are promoted to dedicated top-level + // fields in the v1 shape rather than living in attributes. + $promoted = []; + if (isset($span["origin"])) { + $promoted["_dd.origin"] = $span["origin"]; + } + if (isset($span["trace_id_high"])) { + $promoted["_dd.p.tid"] = $span["trace_id_high"]; + } + $meta = array_merge($promoted, $meta); + echo "parent: ", $span["parent_id"] ?? 0, ", trace: {$span["trace_id"]}, meta: " . json_encode($meta) . "\n"; } return $span; } @@ -116,5 +131,5 @@ array(5) { bool(true) bool(true) parent: 0, trace: %d, meta: {"_dd.p.tid":"%s"} -parent: %d, trace: %d, meta: [] +parent: %d, trace: %d, meta: {"_dd.p.tid":"%s"} all spans trace_id updated: bool(true) From 0811097b361dea1c290b4d105e7c308c29de9974 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 31 Aug 2026 16:55:53 +0200 Subject: [PATCH 28/32] test: update .phpt expectations for v1 serialization shape (batch 4: svc_*, limiter, debug-log format, misc) Relocate meta/metrics -> attributes across the remaining tests (dd_trace_serialize_header_to_meta, http_endpoint_resource_renaming_*, svc_*, process_tags, git_metadata_injection_from_valid_files). env/version are promoted to dedicated top-level fields (not nested in attributes), fixed in ust_precedence_over_ddtags/ust_via_ddtags and inherit_meta_from_parent. _dd.p.tid is fully replaced by the top-level trace_id_high field (generate_128_bit_trace_id). Rewrote the "Encoding span: Span { ... }" debug-log EXPECTF blocks to the new v1 shape ("Encoding span: trace_id=... kind=... attributes= {...} links=n events=n") and "Flushing trace" -> "Flushing v1 trace" in close_spans_until, die_in_sandbox, span_on_close, force_flush_traces, telemetry/broken_pipe. limiter/002-limiter-reached and limiter/003-limiter-with-asm-standalone initially looked like a real regression (_dd.limit_psr computed ~50x too low): isset($span["attributes"]["_sampling_priority_v1"]) was always false because that metric is now promoted to the top-level int "sampling_priority" field, same relocation pattern as span_kind/env/ version/origin, so the test's sample-counting loop ran to its 1000- iteration safety cap instead of stopping at 20 samples. Verified against git merge-base (8d9060c96): unmodified test passes there 5/5, and fails deterministically 5/5 at this branch's HEAD with the old metrics-key access - confirming the fix is the missed relocation, not a product regression, once sampling_priority is read from the top-level field. --- tests/ext/close_spans_until.phpt | 16 ++++++++-------- tests/ext/dd_trace_serialize_header_to_meta.phpt | 8 ++++---- tests/ext/force_flush_traces.phpt | 2 +- tests/ext/generate_128_bit_trace_id.phpt | 4 ++-- ...oint_resource_renaming_always_simplified.phpt | 8 ++++---- .../http_endpoint_resource_renaming_basic.phpt | 8 ++++---- tests/ext/inherit_meta_from_parent.phpt | 9 +++++---- .../git_metadata_injection_from_valid_files.phpt | 4 ++-- tests/ext/limiter/002-limiter-reached.phpt | 4 ++-- .../limiter/003-limiter-with-asm-standalone.phpt | 2 +- tests/ext/process_tags.phpt | 6 +++--- tests/ext/sandbox/die_in_sandbox.phpt | 6 +++--- tests/ext/span_on_close.phpt | 6 +++--- tests/ext/svc_auto_tag_cli.phpt | 2 +- tests/ext/svc_auto_tag_otel.phpt | 2 +- tests/ext/svc_runtime_change.phpt | 2 +- tests/ext/svc_src_inheritance.phpt | 4 ++-- tests/ext/svc_src_manual_override.phpt | 4 ++-- tests/ext/svc_user_tag.phpt | 2 +- tests/ext/telemetry/broken_pipe.phpt | 2 +- tests/ext/ust_precedence_over_ddtags.phpt | 8 ++++---- tests/ext/ust_via_ddtags.phpt | 8 ++++---- 22 files changed, 59 insertions(+), 58 deletions(-) diff --git a/tests/ext/close_spans_until.phpt b/tests/ext/close_spans_until.phpt index f2247f99c5b..56cdf5f4ddf 100644 --- a/tests/ext/close_spans_until.phpt +++ b/tests/ext/close_spans_until.phpt @@ -48,11 +48,11 @@ int(2) [ddtrace] [span] [%d] Switching to different SpanStack: %d int(1) int(0) -[ddtrace] [span] [%d] Encoding span: Span { service: close_spans_until.php, name: close_spans_until.php, resource: close_spans_until.php, type: cli, trace_id: %d, span_id: %d, parent_id: 0, start: %d, duration: %d, error: 0, meta: %s, metrics: %s, meta_struct: %s, span_links: [], span_events: [] } -[ddtrace] [span] [%d] Encoding span: Span { service: close_spans_until.php, name: traced, resource: traced, type: cli, trace_id: %d, span_id: %d, parent_id: %d, start: %d, duration: %d, error: %d, meta: %s, metrics: %s, meta_struct: %s, span_links: %s, span_events: %s } -[ddtrace] [span] [%d] Encoding span: Span { service: close_spans_until.php, name: , resource: , type: cli, trace_id: %d, span_id: %d, parent_id: %d, start: %d, duration: %d, error: %d, meta: %s, metrics: %s, meta_struct: %s, span_links: %s, span_events: %s } -[ddtrace] [span] [%d] Encoding span: Span { service: close_spans_until.php, name: , resource: , type: cli, trace_id: %d, span_id: %d, parent_id: %d, start: %d, duration: %d, error: %d, meta: %s, metrics: %s, meta_struct: %s, span_links: %s, span_events: %s } -[ddtrace] [span] [%d] Encoding span: Span { service: close_spans_until.php, name: , resource: , type: cli, trace_id: %d, span_id: %d, parent_id: %d, start: %d, duration: %d, error: %d, meta: %s, metrics: %s, meta_struct: %s, span_links: %s, span_events: %s } -[ddtrace] [span] [%d] Encoding span: Span { service: close_spans_until.php, name: , resource: , type: cli, trace_id: %d, span_id: %d, parent_id: %d, start: %d, duration: %d, error: %d, meta: %s, metrics: %s, meta_struct: %s, span_links: %s, span_events: %s } -[ddtrace] [span] [%d] Encoding span: Span { service: close_spans_until.php, name: , resource: , type: cli, trace_id: %d, span_id: %d, parent_id: %d, start: %d, duration: %d, error: %d, meta: %s, metrics: %s, meta_struct: %s, span_links: %s, span_events: %s } -[ddtrace] [info] [%d] Flushing trace of size 7 to send-queue for %s +[ddtrace] [span] [%d] Encoding span: trace_id=%s service="close_spans_until.php" name="close_spans_until.php" resource="close_spans_until.php" type="cli" span_id=%d parent_id=0 start=%d duration=%d error=false kind=%s env="" version="" component="" attributes={%S} links=0 events=0 +[ddtrace] [span] [%d] Encoding span: trace_id=%s service="close_spans_until.php" name="traced" resource="traced" type="cli" span_id=%d parent_id=%d start=%d duration=%d error=%s kind=%s env="" version="" component="" attributes={%S} links=%d events=%d +[ddtrace] [span] [%d] Encoding span: trace_id=%s service="close_spans_until.php" name="" resource="" type="cli" span_id=%d parent_id=%d start=%d duration=%d error=%s kind=%s env="" version="" component="" attributes={%S} links=%d events=%d +[ddtrace] [span] [%d] Encoding span: trace_id=%s service="close_spans_until.php" name="" resource="" type="cli" span_id=%d parent_id=%d start=%d duration=%d error=%s kind=%s env="" version="" component="" attributes={%S} links=%d events=%d +[ddtrace] [span] [%d] Encoding span: trace_id=%s service="close_spans_until.php" name="" resource="" type="cli" span_id=%d parent_id=%d start=%d duration=%d error=%s kind=%s env="" version="" component="" attributes={%S} links=%d events=%d +[ddtrace] [span] [%d] Encoding span: trace_id=%s service="close_spans_until.php" name="" resource="" type="cli" span_id=%d parent_id=%d start=%d duration=%d error=%s kind=%s env="" version="" component="" attributes={%S} links=%d events=%d +[ddtrace] [span] [%d] Encoding span: trace_id=%s service="close_spans_until.php" name="" resource="" type="cli" span_id=%d parent_id=%d start=%d duration=%d error=%s kind=%s env="" version="" component="" attributes={%S} links=%d events=%d +[ddtrace] [info] [%d] Flushing v1 trace of size 7 to send-queue for %s diff --git a/tests/ext/dd_trace_serialize_header_to_meta.phpt b/tests/ext/dd_trace_serialize_header_to_meta.phpt index f8e548765aa..2a83dc5dbb9 100644 --- a/tests/ext/dd_trace_serialize_header_to_meta.phpt +++ b/tests/ext/dd_trace_serialize_header_to_meta.phpt @@ -14,10 +14,10 @@ application_key=123 DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump($spans[0]['meta']['http.request.headers.content-type']); -var_dump($spans[0]['meta']['custom-HeaderKey']); -var_dump($spans[0]['meta']['t a g']); -var_dump($spans[0]['meta']['tag']); +var_dump($spans[0]['attributes']['http.request.headers.content-type']); +var_dump($spans[0]['attributes']['custom-HeaderKey']); +var_dump($spans[0]['attributes']['t a g']); +var_dump($spans[0]['attributes']['tag']); ?> --EXPECT-- string(10) "text/plain" diff --git a/tests/ext/force_flush_traces.phpt b/tests/ext/force_flush_traces.phpt index a5cb2dd776b..1ae1dc98fbc 100644 --- a/tests/ext/force_flush_traces.phpt +++ b/tests/ext/force_flush_traces.phpt @@ -43,5 +43,5 @@ var_dump(dd_trace_serialize_closed_spans()); // Spans should be flushed, so this --EXPECTF-- tracing process process -[ddtrace] [info] [%d] Flushing trace of size %r2.*\n.*1|3%r to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size %r2.*\n.*1|3%r to send-queue for %s kill%r\n*(Killed\n*)?(Termsig=9)?%r diff --git a/tests/ext/generate_128_bit_trace_id.phpt b/tests/ext/generate_128_bit_trace_id.phpt index ccad1e18a0c..f0246e5adfa 100644 --- a/tests/ext/generate_128_bit_trace_id.phpt +++ b/tests/ext/generate_128_bit_trace_id.phpt @@ -26,8 +26,8 @@ var_dump(\DDTrace\trace_id() < 2 ** 64); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -var_dump(!isset($spans[0]["meta"]["_dd.p.tid"])); -var_dump(hexdec($spans[1]["meta"]["_dd.p.tid"]) == floor($spans[1]["start"] / 1000000000) * (1 << 32)); +var_dump(!isset($spans[0]["trace_id_high"])); +var_dump(hexdec($spans[1]["trace_id_high"]) == floor($spans[1]["start"] / 1000000000) * (1 << 32)); ?> --EXPECT-- diff --git a/tests/ext/http_endpoint_resource_renaming_always_simplified.phpt b/tests/ext/http_endpoint_resource_renaming_always_simplified.phpt index 475f420dd3b..b4e38dc14f9 100644 --- a/tests/ext/http_endpoint_resource_renaming_always_simplified.phpt +++ b/tests/ext/http_endpoint_resource_renaming_always_simplified.phpt @@ -30,13 +30,13 @@ function test_endpoint_with_route($path, $route) { } else { echo "Path: ", $path, ", No Route\n"; } - if (isset($span_data['meta']['http.endpoint'])) { - echo "Endpoint: ", $span_data['meta']['http.endpoint'], "\n"; + if (isset($span_data['attributes']['http.endpoint'])) { + echo "Endpoint: ", $span_data['attributes']['http.endpoint'], "\n"; } else { echo "Endpoint: (not set)\n"; } - if (isset($span_data['meta']['http.route'])) { - echo "Route: ", $span_data['meta']['http.route'], "\n"; + if (isset($span_data['attributes']['http.route'])) { + echo "Route: ", $span_data['attributes']['http.route'], "\n"; } else { echo "Route: (not set)\n"; } diff --git a/tests/ext/http_endpoint_resource_renaming_basic.phpt b/tests/ext/http_endpoint_resource_renaming_basic.phpt index 621354e1781..90632a5089e 100644 --- a/tests/ext/http_endpoint_resource_renaming_basic.phpt +++ b/tests/ext/http_endpoint_resource_renaming_basic.phpt @@ -23,8 +23,8 @@ function test_endpoint($path) { if (count($spans) > 0) { $span_data = $spans[0]; echo "Path: $path\n"; - if (isset($span_data['meta']['http.endpoint'])) { - echo "Endpoint: " . $span_data['meta']['http.endpoint'] . "\n"; + if (isset($span_data['attributes']['http.endpoint'])) { + echo "Endpoint: " . $span_data['attributes']['http.endpoint'] . "\n"; } else { echo "Endpoint: (not set)\n"; } @@ -94,8 +94,8 @@ function test_endpoint_with_route($path, $route) { if (count($spans) > 0) { $span_data = $spans[0]; echo "Path: $path, Route: $route\n"; - if (isset($span_data['meta']['http.endpoint'])) { - echo "Endpoint: " . $span_data['meta']['http.endpoint'] . "\n"; + if (isset($span_data['attributes']['http.endpoint'])) { + echo "Endpoint: " . $span_data['attributes']['http.endpoint'] . "\n"; } else { echo "Endpoint: (not set)\n"; } diff --git a/tests/ext/inherit_meta_from_parent.phpt b/tests/ext/inherit_meta_from_parent.phpt index 46db2d7ef06..d49fd52fe98 100644 --- a/tests/ext/inherit_meta_from_parent.phpt +++ b/tests/ext/inherit_meta_from_parent.phpt @@ -18,10 +18,11 @@ $span->meta["env"] = "goodenv"; \DDTrace\close_span(); -var_dump(array_intersect_key(dd_trace_serialize_closed_spans()[1]["meta"], [ - "env" => 1, - "version" => 1, -])); +$span = dd_trace_serialize_closed_spans()[1]; +var_dump([ + "env" => $span["env"], + "version" => $span["version"], +]); ?> --EXPECT-- diff --git a/tests/ext/integrations/source_code/001/git_metadata_injection_from_valid_files.phpt b/tests/ext/integrations/source_code/001/git_metadata_injection_from_valid_files.phpt index 7bfdb7b9f2c..01943f8d28c 100644 --- a/tests/ext/integrations/source_code/001/git_metadata_injection_from_valid_files.phpt +++ b/tests/ext/integrations/source_code/001/git_metadata_injection_from_valid_files.phpt @@ -27,7 +27,7 @@ function makeRequest() { $closedSpans = dd_trace_serialize_closed_spans(); - $rootMeta = $closedSpans[0]['meta']; + $rootMeta = $closedSpans[0]['attributes']; echo $rootMeta['_dd.git.repository_url'] . PHP_EOL; echo $rootMeta['_dd.git.commit.sha'] . PHP_EOL; @@ -35,7 +35,7 @@ function makeRequest() { \DDTrace\close_span(); $closedRoot = dd_trace_serialize_closed_spans(); - $rootMeta2 = $closedRoot[0]['meta']; + $rootMeta2 = $closedRoot[0]['attributes']; echo $rootMeta2['_dd.git.repository_url'] . PHP_EOL; echo $rootMeta2['_dd.git.commit.sha'] . PHP_EOL; diff --git a/tests/ext/limiter/002-limiter-reached.phpt b/tests/ext/limiter/002-limiter-reached.phpt index b26685d4031..aa95978352f 100644 --- a/tests/ext/limiter/002-limiter-reached.phpt +++ b/tests/ext/limiter/002-limiter-reached.phpt @@ -21,7 +21,7 @@ while (true) { $sampled = 0; foreach ($spans as $span) { - if (isset($span["metrics"]["_sampling_priority_v1"])) { + if (isset($span["sampling_priority"])) { $sampled++; } } @@ -38,7 +38,7 @@ while (true) { $end = $spans[\count($spans)-1]; -if (\round($end["metrics"]["_dd.limit_psr"], 1) != 0.5) { +if (\round($end["attributes"]["_dd.limit_psr"], 1) != 0.5) { echo "Fail\n"; var_dump($spans); exit; diff --git a/tests/ext/limiter/003-limiter-with-asm-standalone.phpt b/tests/ext/limiter/003-limiter-with-asm-standalone.phpt index 95997cccb52..5923e9b7419 100644 --- a/tests/ext/limiter/003-limiter-with-asm-standalone.phpt +++ b/tests/ext/limiter/003-limiter-with-asm-standalone.phpt @@ -22,7 +22,7 @@ while (true) { $sampled = 0; foreach ($spans as $span) { - if (isset($span["metrics"]["_sampling_priority_v1"])) { + if (isset($span["sampling_priority"])) { $sampled++; } } diff --git a/tests/ext/process_tags.phpt b/tests/ext/process_tags.phpt index 7e532482c0f..23be23085a5 100644 --- a/tests/ext/process_tags.phpt +++ b/tests/ext/process_tags.phpt @@ -20,8 +20,8 @@ $child_span->service = 'test_service'; $spans = dd_trace_serialize_closed_spans(); // Check if process tags are present -if (isset($spans[0]['meta']['_dd.tags.process'])) { - $processTags = $spans[0]['meta']['_dd.tags.process']; +if (isset($spans[0]['attributes']['_dd.tags.process'])) { + $processTags = $spans[0]['attributes']['_dd.tags.process']; echo "Process tags present in root span: YES\n"; echo "Process tags: $processTags\n"; @@ -39,7 +39,7 @@ if (isset($spans[0]['meta']['_dd.tags.process'])) { echo "Process tags present in root span: NO\n"; } -if (isset($spans[1]['meta']['_dd.process_tags'])) { +if (isset($spans[1]['attributes']['_dd.process_tags'])) { echo "Process tags present in child span: YES\n"; } else { echo "Process tags present in child span: NO\n"; diff --git a/tests/ext/sandbox/die_in_sandbox.phpt b/tests/ext/sandbox/die_in_sandbox.phpt index dea8d53cc7c..05f7ddfdd62 100644 --- a/tests/ext/sandbox/die_in_sandbox.phpt +++ b/tests/ext/sandbox/die_in_sandbox.phpt @@ -18,7 +18,7 @@ x(); ?> --EXPECTF-- [ddtrace] [warning] [%d] UnwindExit thrown in ddtrace's closure defined at %s:%d for x(): in Unknown on line 0 -[ddtrace] [span] [%d] Encoding span: Span { service: die_in_sandbox.php, name: die_in_sandbox.php, resource: die_in_sandbox.php, type: cli, trace_id: %d, span_id: %d, parent_id: %d, start: %d, duration: %d, error: %d, meta: %s, metrics: %s, meta_struct: %s, span_links: %s, span_events: %s } -[ddtrace] [span] [%d] Encoding span: Span { service: die_in_sandbox.php, name: x, resource: x, type: cli, trace_id: %d, span_id: %d, parent_id: %d, start: %d, duration: %d, error: %d, meta: %s, metrics: %s, meta_struct: %s, span_links: %s, span_events: %s } -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [span] [%d] Encoding span: trace_id=%s service="die_in_sandbox.php" name="die_in_sandbox.php" resource="die_in_sandbox.php" type="cli" span_id=%d parent_id=%d start=%d duration=%d error=%s kind=%s env="" version="" component="" attributes={%S} links=%d events=%d +[ddtrace] [span] [%d] Encoding span: trace_id=%s service="die_in_sandbox.php" name="x" resource="x" type="cli" span_id=%d parent_id=%d start=%d duration=%d error=%s kind=%s env="" version="" component="" attributes={%S} links=%d events=%d +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s diff --git a/tests/ext/span_on_close.phpt b/tests/ext/span_on_close.phpt index a58461fa4e3..b3fde9cff0a 100644 --- a/tests/ext/span_on_close.phpt +++ b/tests/ext/span_on_close.phpt @@ -26,8 +26,8 @@ $span->onClose = [ --EXPECTF-- Second First -[ddtrace] [span] [%d] Encoding span: Span { service: %s, name: root span, resource: root span, type: cli, trace_id: %d, span_id: %d, parent_id: %d, start: %d, duration: %d, error: %d, meta: %s, metrics: %s, meta_struct: %s, span_links: %s, span_events: %s } -[ddtrace] [span] [%d] Encoding span: Span { service: %s, name: inner span, resource: datadogs are awesome, type: cli, trace_id: %d, span_id: %d, parent_id: %d, start: %d, duration: %d, error: %d, meta: %s, metrics: %s, meta_struct: %s, span_links: %s, span_events: %s } -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [span] [%d] Encoding span: trace_id=%s service="%s" name="root span" resource="root span" type="cli" span_id=%d parent_id=%d start=%d duration=%d error=%s kind=%s env="" version="" component="" attributes={%S} links=%d events=%d +[ddtrace] [span] [%d] Encoding span: trace_id=%s service="%s" name="inner span" resource="datadogs are awesome" type="cli" span_id=%d parent_id=%d start=%d duration=%d error=%s kind=%s env="" version="" component="" attributes={%S} links=%d events=%d +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s [ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/svc_auto_tag_cli.phpt b/tests/ext/svc_auto_tag_cli.phpt index a46ee44b268..bffef820c92 100644 --- a/tests/ext/svc_auto_tag_cli.phpt +++ b/tests/ext/svc_auto_tag_cli.phpt @@ -11,7 +11,7 @@ $span->name = 'op'; \DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -$processTags = $spans[0]['meta']['_dd.tags.process']; +$processTags = $spans[0]['attributes']['_dd.tags.process']; echo "has svc.user: " . (strpos($processTags, 'svc.user') !== false ? 'YES' : 'NO') . "\n"; echo "has svc.auto: " . (strpos($processTags, 'svc.auto:') !== false ? 'YES' : 'NO') . "\n"; diff --git a/tests/ext/svc_auto_tag_otel.phpt b/tests/ext/svc_auto_tag_otel.phpt index 7c05ce2ff5e..a5b19cf02ff 100644 --- a/tests/ext/svc_auto_tag_otel.phpt +++ b/tests/ext/svc_auto_tag_otel.phpt @@ -12,7 +12,7 @@ $span->name = 'op'; \DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -$processTags = $spans[0]['meta']['_dd.tags.process']; +$processTags = $spans[0]['attributes']['_dd.tags.process']; echo "DD_SERVICE resolved to: " . ini_get('datadog.service') . "\n"; echo "has svc.user:true: " . (strpos($processTags, 'svc.user:true') !== false ? 'YES' : 'NO') . "\n"; diff --git a/tests/ext/svc_runtime_change.phpt b/tests/ext/svc_runtime_change.phpt index 7a06cbf7a08..244049d066f 100644 --- a/tests/ext/svc_runtime_change.phpt +++ b/tests/ext/svc_runtime_change.phpt @@ -8,7 +8,7 @@ DD_TRACE_AUTO_FLUSH_ENABLED=0 name = 'child'; $byName = []; foreach (dd_trace_serialize_closed_spans() as $s) { $byName[$s['name']] = $s; } -echo "root svc_src: " . ($byName['root']['meta']['_dd.svc_src'] ?? '(unset)') . "\n"; -echo "child svc_src: " . ($byName['child']['meta']['_dd.svc_src'] ?? '(unset)') . "\n"; +echo "root svc_src: " . ($byName['root']['attributes']['_dd.svc_src'] ?? '(unset)') . "\n"; +echo "child svc_src: " . ($byName['child']['attributes']['_dd.svc_src'] ?? '(unset)') . "\n"; ?> --EXPECT-- root svc_src: redis diff --git a/tests/ext/svc_src_manual_override.phpt b/tests/ext/svc_src_manual_override.phpt index 07527277bfe..f27a58c91ca 100644 --- a/tests/ext/svc_src_manual_override.phpt +++ b/tests/ext/svc_src_manual_override.phpt @@ -18,8 +18,8 @@ $child->service = 'overridden'; $byName = []; foreach (dd_trace_serialize_closed_spans() as $s) { $byName[$s['name']] = $s; } -echo "root svc_src: " . ($byName['root']['meta']['_dd.svc_src'] ?? '(unset)') . "\n"; -echo "child svc_src: " . ($byName['child']['meta']['_dd.svc_src'] ?? '(unset)') . "\n"; +echo "root svc_src: " . ($byName['root']['attributes']['_dd.svc_src'] ?? '(unset)') . "\n"; +echo "child svc_src: " . ($byName['child']['attributes']['_dd.svc_src'] ?? '(unset)') . "\n"; ?> --EXPECT-- root svc_src: m diff --git a/tests/ext/svc_user_tag.phpt b/tests/ext/svc_user_tag.phpt index cd673e65e31..e5641d1101a 100644 --- a/tests/ext/svc_user_tag.phpt +++ b/tests/ext/svc_user_tag.phpt @@ -12,7 +12,7 @@ $span->name = 'op'; \DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); -$processTags = $spans[0]['meta']['_dd.tags.process']; +$processTags = $spans[0]['attributes']['_dd.tags.process']; echo "has svc.user:true: " . (strpos($processTags, 'svc.user:true') !== false ? 'YES' : 'NO') . "\n"; echo "has svc.auto: : " . (strpos($processTags, 'svc.auto:') !== false ? 'YES' : 'NO') . "\n"; diff --git a/tests/ext/telemetry/broken_pipe.phpt b/tests/ext/telemetry/broken_pipe.phpt index 9bd666c7b43..73ab1163d6c 100644 --- a/tests/ext/telemetry/broken_pipe.phpt +++ b/tests/ext/telemetry/broken_pipe.phpt @@ -73,7 +73,7 @@ if ($i == 300) { ?> --EXPECTF-- -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %sbroken_pipe-telemetry.out%A +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %sbroken_pipe-telemetry.out%A [ddtrace] [datadog_sidecar::service::blocking] [%d] The sidecar transport is closed. Reconnecting... This generally indicates a problem with the sidecar, most likely a crash. Check the logs / core dump locations and possibly report a bug. string(11) "app-started" string(25) "broken_pipe-telemetry-app" diff --git a/tests/ext/ust_precedence_over_ddtags.phpt b/tests/ext/ust_precedence_over_ddtags.phpt index 116999116fd..f456a6060ed 100644 --- a/tests/ext/ust_precedence_over_ddtags.phpt +++ b/tests/ext/ust_precedence_over_ddtags.phpt @@ -27,14 +27,14 @@ if (count($spans) >= 2) { 'span1' => [ 'name' => $spans[0]['name'], 'service' => $spans[0]['service'], - 'version' => $spans[0]['meta']['version'], - 'env' => $spans[0]['meta']['env'] + 'version' => $spans[0]['version'], + 'env' => $spans[0]['env'] ], 'span2' => [ 'name' => $spans[1]['name'], 'service' => $spans[1]['service'], - 'version' => $spans[1]['meta']['version'], - 'env' => $spans[1]['meta']['env'] + 'version' => $spans[1]['version'], + 'env' => $spans[1]['env'] ] ]); } diff --git a/tests/ext/ust_via_ddtags.phpt b/tests/ext/ust_via_ddtags.phpt index 4502567e329..4436c1efffc 100644 --- a/tests/ext/ust_via_ddtags.phpt +++ b/tests/ext/ust_via_ddtags.phpt @@ -27,14 +27,14 @@ if (count($spans) >= 2) { 'span1' => [ 'name' => $spans[0]['name'], 'service' => $spans[0]['service'], - 'version' => $spans[0]['meta']['version'], - 'env' => $spans[0]['meta']['env'] + 'version' => $spans[0]['version'], + 'env' => $spans[0]['env'] ], 'span2' => [ 'name' => $spans[1]['name'], 'service' => $spans[1]['service'], - 'version' => $spans[1]['meta']['version'], - 'env' => $spans[1]['meta']['env'] + 'version' => $spans[1]['version'], + 'env' => $spans[1]['env'] ] ]); } From 4f79c793ff758578d9a4fab94c5368b8e589fe61 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 31 Aug 2026 17:30:09 +0200 Subject: [PATCH 29/32] test(request-replayer): decode v1 (/v1.0/traces) wire to the v0.4 span view Add a PHP v1 msgpack decoder (msgpack_v1_decoder.php) so the deferred PHPUnit integration tests can assert the v1 wire. The decoder resolves the streaming string table, maps integer proto field-number keys back to names, and decodes typed AnyValue values, normalizing a v1 payload back to the canonical {"chunks":[{"spans":[...]}]} v0.4 per-span shape TracerTestTrait reads: - un-promotes span env/version/component and span.kind (int->string) into meta; - reconstructs per-span trace_id (chunk 128-bit low 64 decimal) + meta._dd.p.tid (high 64 hex), meta._dd.origin, meta._dd.p.dm ("-N"), and metrics._sampling_priority_v1 from the chunk-level fields onto the local root; - splits the unified attributes map into meta (String), metrics (Int/Double), meta_struct (Bytes); native span_links/span_events -> meta._dd.span_links / meta.events JSON (the prior v0.4 contract). index.php dispatches /v1.0/traces to the new decoder and keeps the existing v0.4 path for /v0.4/traces; /info now advertises /v1.0/traces by default so the sidecar (8.3+) and in-process (<=8.2) senders negotiate v1, while /set-agent-info overrides still win. --- .../services/request-replayer/src/index.php | 30 +- .../src/msgpack_v1_decoder.php | 620 ++++++++++++++++++ 2 files changed, 647 insertions(+), 3 deletions(-) create mode 100644 dockerfiles/services/request-replayer/src/msgpack_v1_decoder.php diff --git a/dockerfiles/services/request-replayer/src/index.php b/dockerfiles/services/request-replayer/src/index.php index ff7de4a3adc..841529b3074 100644 --- a/dockerfiles/services/request-replayer/src/index.php +++ b/dockerfiles/services/request-replayer/src/index.php @@ -47,6 +47,9 @@ function decodeDogStatsDMetrics($metrics) return $decodedMetrics; } +// v1 (`/v1.0/traces`) msgpack decoder, normalizing to the v0.4 per-span view. +require __DIR__ . '/msgpack_v1_decoder.php'; + $uri = explode("?", $_SERVER['REQUEST_URI'])[0]; $temp_location = sys_get_temp_dir(); @@ -260,7 +263,22 @@ function logRequest($message, $data = '') file_put_contents(REQUEST_AGENT_INFO_FILE, $raw); break; case '/info': - $file = @file_get_contents(REQUEST_AGENT_INFO_FILE) ?: "{}"; + // Default advertises /v1.0/traces so the sidecar (8.3+) and the in-process (<=8.2) sender + // both negotiate the v1 wire. Tests that need a specific /info still override it via + // /set-agent-info (the written file is served verbatim, untouched by this default). + $default_info = json_encode([ + "endpoints" => [ + "/v0.4/traces", + "/v0.6/stats", + "/v0.7/config", + "/v1.0/traces", + "/telemetry/proxy/", + "/evp_proxy/v2/", + ], + "client_drop_p0s" => false, + "version" => "7.66.0", + ], JSON_UNESCAPED_SLASHES); + $file = @file_get_contents(REQUEST_AGENT_INFO_FILE) ?: $default_info; logRequest('Requested /info endpoint, returning ' . $file); header("datadog-agent-state: " . sha1($file)); echo $file; @@ -317,8 +335,14 @@ function logRequest($message, $data = '') } } else { $raw = file_get_contents('php://input'); - if ((isset($headers['Content-Type']) && $headers['Content-Type'] === 'application/msgpack') - || (isset($headers['content-type']) && $headers['content-type'] === 'application/msgpack')) { + $isMsgpack = (isset($headers['Content-Type']) && $headers['Content-Type'] === 'application/msgpack') + || (isset($headers['content-type']) && $headers['content-type'] === 'application/msgpack'); + if ($isMsgpack && substr($uri, -strlen('/v1.0/traces')) === '/v1.0/traces') { + // v1 (`/v1.0/traces`) wire: integer keys, streaming string table, typed AnyValue. + // Normalize it back to the canonical v0.4 per-span view the PHPUnit tests read. + $decoder = new V1TraceDecoder($raw); + $body = json_encode($decoder->decode()); + } elseif ($isMsgpack) { // We unpack in two phases: // 1) using UnpackOptions::BIGINT_AS_GMP and only asserting that trace_id, span_id and parent_id are either // integers (when <= PHP_INT_MAX) or GMP (when > PHP_INT_MAX); diff --git a/dockerfiles/services/request-replayer/src/msgpack_v1_decoder.php b/dockerfiles/services/request-replayer/src/msgpack_v1_decoder.php new file mode 100644 index 00000000000..95d526e8355 --- /dev/null +++ b/dockerfiles/services/request-replayer/src/msgpack_v1_decoder.php @@ -0,0 +1,620 @@ + ]}]}` (the shape + * TracerTestTrait::parseRawDumpedTraces07 reads), un-promoting: + * - span env/version/component -> meta; span kind (uint) -> meta['span.kind'] (Internal/1 dropped, + * matching v0.4 where an unset span.kind produces no meta entry); + * - chunk 128-bit trace_id -> per-span trace_id (low 64 bits, decimal) + meta['_dd.p.tid'] (high 64 + * bits, hex) on the local-root span; chunk origin -> meta['_dd.origin']; chunk sampling_mechanism + * -> meta['_dd.p.dm'] (v0.4 "-N" form); chunk sampling_priority -> metrics['_sampling_priority_v1']; + * - the unified attributes map back into meta (String), metrics (Int/Double) and meta_struct (Bytes); + * - native span_links/span_events back into the meta['_dd.span_links'] / meta['events'] JSON strings + * the v0.4 wire carried. + */ +class V1TraceDecoder +{ + private $buf; + private $pos = 0; + private $len; + /** @var string[] streaming intern table; index 0 is the empty string */ + private $table = ['']; + + // Integer map keys, kept in sync with the libdatadog v1 encoder/decoder. + const TRACE_ATTRIBUTES = 10, TRACE_CHUNKS = 11; + const CHUNK_PRIORITY = 1, CHUNK_ORIGIN = 2, CHUNK_ATTRIBUTES = 3, CHUNK_SPANS = 4, + CHUNK_DROPPED_TRACE = 5, CHUNK_TRACE_ID = 6, CHUNK_SAMPLING_MECHANISM = 7; + const SPAN_SERVICE = 1, SPAN_NAME = 2, SPAN_RESOURCE = 3, SPAN_SPAN_ID = 4, SPAN_PARENT_ID = 5, + SPAN_START = 6, SPAN_DURATION = 7, SPAN_ERROR = 8, SPAN_ATTRIBUTES = 9, SPAN_TYPE = 10, + SPAN_LINKS = 11, SPAN_EVENTS = 12, SPAN_ENV = 13, SPAN_VERSION = 14, SPAN_COMPONENT = 15, + SPAN_KIND = 16; + const LINK_TRACE_ID = 1, LINK_SPAN_ID = 2, LINK_ATTRIBUTES = 3, LINK_TRACE_STATE = 4, LINK_FLAGS = 5; + const EVENT_TIME = 1, EVENT_NAME = 2, EVENT_ATTRIBUTES = 3; + const ANY_STRING = 1, ANY_BOOL = 2, ANY_DOUBLE = 3, ANY_INT64 = 4, ANY_BYTES = 5, ANY_ARRAY = 6, + ANY_KEY_VALUE_LIST = 7; + + public function __construct($buf) + { + $this->buf = $buf; + $this->len = strlen($buf); + } + + /** Decodes the whole payload into the v0.4-shaped `{"chunks":[...]}` PHP array. */ + public function decode() + { + $chunks = []; + $mapLen = $this->readMapLen(); + for ($i = 0; $i < $mapLen; $i++) { + $key = $this->readUint(); + switch ($key) { + case self::TRACE_CHUNKS: + $count = $this->readArrayLen(); + for ($c = 0; $c < $count; $c++) { + $chunks[] = $this->decodeChunk(); + } + break; + case self::TRACE_ATTRIBUTES: + // Payload-level attributes (e.g. _dd.apm_mode) are not part of the per-span view. + $this->readAttributesMap(); + break; + default: + // container_id/language/version/runtime_id/env/hostname/app_version and any + // future/unknown key: interned string or arbitrary value, skip it. + $this->skipValue(); + break; + } + } + return ['chunks' => $chunks]; + } + + private function decodeChunk() + { + $traceIdBytes = null; + $origin = null; + $priority = null; + $samplingMechanism = null; + $spans = []; + + $mapLen = $this->readMapLen(); + for ($i = 0; $i < $mapLen; $i++) { + $key = $this->readUint(); + switch ($key) { + case self::CHUNK_TRACE_ID: + $traceIdBytes = $this->readBin(); + break; + case self::CHUNK_SPANS: + $count = $this->readArrayLen(); + for ($s = 0; $s < $count; $s++) { + $spans[] = $this->decodeSpan(); + } + break; + case self::CHUNK_ORIGIN: + $origin = $this->readInterned(); + break; + case self::CHUNK_PRIORITY: + $priority = $this->readInt(); + break; + case self::CHUNK_SAMPLING_MECHANISM: + $samplingMechanism = $this->readUint(); + break; + case self::CHUNK_ATTRIBUTES: + // Chunk-level attributes have no per-span v0.4 home; drain them. + $this->readAttributesMap(); + break; + case self::CHUNK_DROPPED_TRACE: + $this->readBool(); + break; + default: + $this->skipValue(); + break; + } + } + + // Reconstruct the 128-bit trace id. The low 64 bits go on every span; the high 64 bits, when + // non-zero, become meta['_dd.p.tid'] (hex) on the local-root span, mirroring the v0.4 wire. + $traceIdLow = "0"; + $traceIdTidHex = null; + if ($traceIdBytes !== null && strlen($traceIdBytes) === 16) { + $high = substr($traceIdBytes, 0, 8); + $low = substr($traceIdBytes, 8, 8); + $traceIdLow = $this->bytesToDecimal($low); + if ($high !== "\0\0\0\0\0\0\0\0") { + $traceIdTidHex = bin2hex($high); + } + } + + foreach ($spans as &$span) { + $span['trace_id'] = $traceIdLow; + } + unset($span); + + // Place the chunk-level, root-scoped propagation fields on the local-root span (the span with + // no parent, else the one flagged _dd.top_level, else the first span) — the v0.4 layout. + if (!empty($spans)) { + $rootIdx = $this->findRootSpanIndex($spans); + if ($traceIdTidHex !== null) { + $spans[$rootIdx]['meta']['_dd.p.tid'] = $traceIdTidHex; + } + if ($origin !== null) { + $spans[$rootIdx]['meta']['_dd.origin'] = $origin; + } + if ($samplingMechanism !== null) { + // v0.4 stores the decision maker as "-". + $spans[$rootIdx]['meta']['_dd.p.dm'] = "-" . $samplingMechanism; + } + if ($priority !== null) { + $spans[$rootIdx]['metrics']['_sampling_priority_v1'] = $priority; + } + } + + // Drop empty meta/metrics/meta_struct so json_encode matches the v0.4 shape (absent, not {}). + foreach ($spans as &$span) { + foreach (['meta', 'metrics', 'meta_struct'] as $k) { + if (isset($span[$k]) && count($span[$k]) === 0) { + unset($span[$k]); + } + } + } + unset($span); + + return ['spans' => $spans]; + } + + private function findRootSpanIndex(array $spans) + { + foreach ($spans as $idx => $span) { + if (!isset($span['parent_id']) || $span['parent_id'] === "0") { + return $idx; + } + } + foreach ($spans as $idx => $span) { + if (isset($span['metrics']['_dd.top_level']) && (float)$span['metrics']['_dd.top_level'] == 1.0) { + return $idx; + } + } + return 0; + } + + private function decodeSpan() + { + $span = [ + 'trace_id' => "0", + 'span_id' => "0", + 'parent_id' => "0", + 'name' => "", + 'resource' => "", + 'service' => "", + 'error' => 0, + 'meta' => [], + 'metrics' => [], + ]; + $metaStruct = []; + $kind = null; + $links = null; + $events = null; + + $mapLen = $this->readMapLen(); + for ($i = 0; $i < $mapLen; $i++) { + $key = $this->readUint(); + switch ($key) { + case self::SPAN_SERVICE: $span['service'] = $this->readInterned(); break; + case self::SPAN_NAME: $span['name'] = $this->readInterned(); break; + case self::SPAN_RESOURCE: $span['resource'] = $this->readInterned(); break; + case self::SPAN_SPAN_ID: $span['span_id'] = (string)$this->readUint(); break; + case self::SPAN_PARENT_ID:$span['parent_id'] = (string)$this->readUint(); break; + case self::SPAN_START: $span['start'] = $this->readUint(); break; + case self::SPAN_DURATION: $span['duration'] = $this->readUint(); break; + case self::SPAN_ERROR: $span['error'] = $this->readBool() ? 1 : 0; break; + case self::SPAN_TYPE: $span['type'] = $this->readInterned(); break; + case self::SPAN_ATTRIBUTES: + $this->readSpanAttributes($span['meta'], $span['metrics'], $metaStruct); + break; + case self::SPAN_LINKS: $links = $this->readSpanLinks(); break; + case self::SPAN_EVENTS: $events = $this->readSpanEvents(); break; + case self::SPAN_ENV: $span['meta']['env'] = $this->readInterned(); break; + case self::SPAN_VERSION: $span['meta']['version'] = $this->readInterned(); break; + case self::SPAN_COMPONENT:$span['meta']['component'] = $this->readInterned(); break; + case self::SPAN_KIND: $kind = $this->readUint(); break; + default: $this->skipValue(); break; + } + } + + // span.kind (uint) -> meta['span.kind']; Internal(1)/unspecified(0) leave no meta entry, so an + // absent-in-v0.4 span.kind stays absent (the OTEL default is emitted unconditionally on v1). + if ($kind !== null) { + $kindStr = $this->spanKindToStr($kind); + if ($kindStr !== null) { + $span['meta']['span.kind'] = $kindStr; + } + } + + if ($links !== null && !empty($links)) { + $span['meta']['_dd.span_links'] = json_encode($links, JSON_UNESCAPED_SLASHES); + } + if ($events !== null && !empty($events)) { + $span['meta']['events'] = json_encode($events, JSON_UNESCAPED_SLASHES); + } + + if (!empty($metaStruct)) { + $span['meta_struct'] = $metaStruct; + } + + return $span; + } + + private function spanKindToStr($kind) + { + switch ($kind) { + case 2: return "server"; + case 3: return "client"; + case 4: return "producer"; + case 5: return "consumer"; + // 1 (Internal) and 0 (Unspecified): no v0.4 meta entry. + default: return null; + } + } + + /** Splits the unified v1 attributes map into v0.4 meta (String), metrics (Int/Double) and + * meta_struct (Bytes). Bool/Array/KeyValueList (not emitted by the PHP tracer) fall back to a + * JSON string in meta so nothing is silently dropped. */ + private function readSpanAttributes(&$meta, &$metrics, &$metaStruct) + { + $n = $this->readArrayLen(); + if ($n % 3 !== 0) { + throw new \RuntimeException("v1 attributes flat array length $n is not a multiple of 3"); + } + $entries = intdiv($n, 3); + for ($i = 0; $i < $entries; $i++) { + $key = $this->readInterned(); + list($type, $value) = $this->readTypedValue(); + switch ($type) { + case self::ANY_STRING: + $meta[$key] = $value; + break; + case self::ANY_INT64: + case self::ANY_DOUBLE: + $metrics[$key] = $value; + break; + case self::ANY_BYTES: + $metaStruct[$key] = $value; + break; + case self::ANY_BOOL: + case self::ANY_ARRAY: + case self::ANY_KEY_VALUE_LIST: + default: + $meta[$key] = is_scalar($value) ? (string)$value : json_encode($value, JSON_UNESCAPED_SLASHES); + break; + } + } + } + + /** Reads a v1 attributes map into a plain associative array (used for link/event attributes). */ + private function readAttributesMap() + { + $out = []; + $n = $this->readArrayLen(); + if ($n % 3 !== 0) { + throw new \RuntimeException("v1 attributes flat array length $n is not a multiple of 3"); + } + $entries = intdiv($n, 3); + for ($i = 0; $i < $entries; $i++) { + $key = $this->readInterned(); + list(, $value) = $this->readTypedValue(); + $out[$key] = $value; + } + return $out; + } + + /** Reads `[type_uint8, value]`, returning [$type, $phpValue]. */ + private function readTypedValue() + { + $type = $this->readUint(); + switch ($type) { + case self::ANY_STRING: return [$type, $this->readInterned()]; + case self::ANY_BOOL: return [$type, $this->readBool()]; + case self::ANY_DOUBLE: return [$type, $this->readDouble()]; + case self::ANY_INT64: return [$type, $this->readInt()]; + case self::ANY_BYTES: return [$type, $this->readBin()]; + case self::ANY_ARRAY: + $n = $this->readArrayLen(); + if ($n % 2 !== 0) { + throw new \RuntimeException("v1 typed array length $n is not a multiple of 2"); + } + $items = []; + for ($i = 0, $c = intdiv($n, 2); $i < $c; $i++) { + list(, $v) = $this->readTypedValue(); + $items[] = $v; + } + return [$type, $items]; + case self::ANY_KEY_VALUE_LIST: + return [$type, $this->readAttributesMap()]; + default: + throw new \RuntimeException("Unknown v1 AnyValue type discriminant: $type"); + } + } + + /** Native v1 span links -> the v0.4 `_dd.span_links` JSON element shape (trace_id 32-hex, + * span_id 16-hex, trace_state, attributes). */ + private function readSpanLinks() + { + $out = []; + $count = $this->readArrayLen(); + for ($i = 0; $i < $count; $i++) { + $link = []; + $traceIdHex = str_repeat("0", 32); + $spanIdHex = str_repeat("0", 16); + $traceState = ""; + $attributes = []; + $mapLen = $this->readMapLen(); + for ($j = 0; $j < $mapLen; $j++) { + $key = $this->readUint(); + switch ($key) { + case self::LINK_TRACE_ID: + $b = $this->readBin(); + $traceIdHex = str_pad(bin2hex($b), 32, "0", STR_PAD_LEFT); + break; + case self::LINK_SPAN_ID: + $spanIdHex = str_pad(dechex_gmp($this->readUint()), 16, "0", STR_PAD_LEFT); + break; + case self::LINK_ATTRIBUTES: + $attributes = $this->readAttributesMap(); + break; + case self::LINK_TRACE_STATE: + $traceState = $this->readInterned(); + break; + case self::LINK_FLAGS: + $this->readUint(); + break; + default: + $this->skipValue(); + break; + } + } + $link['trace_id'] = $traceIdHex; + $link['span_id'] = $spanIdHex; + if ($traceState !== "") { + $link['trace_state'] = $traceState; + } + if (!empty($attributes)) { + $link['attributes'] = $attributes; + } + $out[] = $link; + } + return $out; + } + + /** Native v1 span events -> the v0.4 `events` JSON element shape (name, time_unix_nano, + * attributes). */ + private function readSpanEvents() + { + $out = []; + $count = $this->readArrayLen(); + for ($i = 0; $i < $count; $i++) { + $event = []; + $mapLen = $this->readMapLen(); + for ($j = 0; $j < $mapLen; $j++) { + $key = $this->readUint(); + switch ($key) { + case self::EVENT_TIME: $event['time_unix_nano'] = $this->readUint(); break; + case self::EVENT_NAME: $event['name'] = $this->readInterned(); break; + case self::EVENT_ATTRIBUTES: $event['attributes'] = $this->readAttributesMap(); break; + default: $this->skipValue(); break; + } + } + $out[] = $event; + } + return $out; + } + + // --- streaming msgpack primitives ------------------------------------------------------------- + + private function peek() + { + if ($this->pos >= $this->len) { + throw new \RuntimeException("v1 decode: unexpected end of buffer"); + } + return ord($this->buf[$this->pos]); + } + + private function take($n) + { + if ($this->pos + $n > $this->len) { + throw new \RuntimeException("v1 decode: buffer truncated"); + } + $s = substr($this->buf, $this->pos, $n); + $this->pos += $n; + return $s; + } + + private function readMapLen() + { + $m = ord($this->take(1)); + if ($m >= 0x80 && $m <= 0x8f) return $m & 0x0f; + if ($m === 0xde) return $this->beUint($this->take(2)); + if ($m === 0xdf) return $this->beUint($this->take(4)); + throw new \RuntimeException(sprintf("v1 decode: expected map marker, got 0x%02x", $m)); + } + + private function readArrayLen() + { + $m = ord($this->take(1)); + if ($m >= 0x90 && $m <= 0x9f) return $m & 0x0f; + if ($m === 0xdc) return $this->beUint($this->take(2)); + if ($m === 0xdd) return $this->beUint($this->take(4)); + throw new \RuntimeException(sprintf("v1 decode: expected array marker, got 0x%02x", $m)); + } + + /** Reads an unsigned integer; returns an int when it fits in PHP_INT, else a decimal string. */ + private function readUint() + { + $m = ord($this->take(1)); + if ($m <= 0x7f) return $m; // positive fixint + if ($m === 0xcc) return $this->beUint($this->take(1)); + if ($m === 0xcd) return $this->beUint($this->take(2)); + if ($m === 0xce) return $this->beUint($this->take(4)); + if ($m === 0xcf) return $this->beUint($this->take(8)); + throw new \RuntimeException(sprintf("v1 decode: expected uint marker, got 0x%02x", $m)); + } + + /** Reads a signed integer (any int marker). */ + private function readInt() + { + $m = $this->peek(); + if ($m <= 0x7f || ($m >= 0xcc && $m <= 0xcf)) { + return $this->readUint(); + } + $this->take(1); + if ($m >= 0xe0) return $m - 0x100; // negative fixint + switch ($m) { + case 0xd0: $v = ord($this->take(1)); return $v < 0x80 ? $v : $v - 0x100; + case 0xd1: $v = $this->beUint($this->take(2)); return $v < 0x8000 ? $v : $v - 0x10000; + case 0xd2: $v = $this->beUint($this->take(4)); return $v < 0x80000000 ? $v : $v - 0x100000000; + case 0xd3: + $bytes = $this->take(8); + $u = gmp_import($bytes, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); + if (gmp_testbit($u, 63)) { + $u = gmp_sub($u, gmp_pow(2, 64)); + } + return $this->gmpToScalar($u); + } + throw new \RuntimeException(sprintf("v1 decode: expected int marker, got 0x%02x", $m)); + } + + private function readDouble() + { + $m = ord($this->take(1)); + if ($m === 0xcb) { + $v = unpack("E", $this->take(8)); + return $v[1]; + } + if ($m === 0xca) { + $v = unpack("G", $this->take(4)); + return $v[1]; + } + throw new \RuntimeException(sprintf("v1 decode: expected float marker, got 0x%02x", $m)); + } + + private function readBool() + { + $m = ord($this->take(1)); + if ($m === 0xc3) return true; + if ($m === 0xc2) return false; + throw new \RuntimeException(sprintf("v1 decode: expected bool marker, got 0x%02x", $m)); + } + + private function readStr() + { + $m = ord($this->take(1)); + if ($m >= 0xa0 && $m <= 0xbf) return $this->take($m & 0x1f); + if ($m === 0xd9) return $this->take(ord($this->take(1))); + if ($m === 0xda) return $this->take($this->beUint($this->take(2))); + if ($m === 0xdb) return $this->take($this->beUint($this->take(4))); + throw new \RuntimeException(sprintf("v1 decode: expected str marker, got 0x%02x", $m)); + } + + private function readBin() + { + $m = ord($this->take(1)); + if ($m === 0xc4) return $this->take(ord($this->take(1))); + if ($m === 0xc5) return $this->take($this->beUint($this->take(2))); + if ($m === 0xc6) return $this->take($this->beUint($this->take(4))); + throw new \RuntimeException(sprintf("v1 decode: expected bin marker, got 0x%02x", $m)); + } + + /** Reads a string-or-reference: inline `str` (recorded into the table) or a `uint` table index. */ + private function readInterned() + { + $m = $this->peek(); + if (($m >= 0xa0 && $m <= 0xbf) || $m === 0xd9 || $m === 0xda || $m === 0xdb) { + $s = $this->readStr(); + $this->table[] = $s; + return $s; + } + if ($m <= 0x7f || ($m >= 0xcc && $m <= 0xcf)) { + $id = $this->readUint(); + if (!isset($this->table[$id])) { + throw new \RuntimeException("v1 decode: string table reference out of range: $id"); + } + return $this->table[$id]; + } + throw new \RuntimeException(sprintf("v1 decode: unexpected marker 0x%02x for interned string", $m)); + } + + /** Skips one arbitrary msgpack value, recording any inline string it contains into the table + * (so back-references in later known fields stay in sync). */ + private function skipValue() + { + $m = $this->peek(); + // str: record into the table + if (($m >= 0xa0 && $m <= 0xbf) || $m === 0xd9 || $m === 0xda || $m === 0xdb) { + $s = $this->readStr(); + $this->table[] = $s; + return; + } + if ($m >= 0x80 && $m <= 0x8f || $m === 0xde || $m === 0xdf) { + $n = $this->readMapLen(); + for ($i = 0; $i < $n; $i++) { $this->skipValue(); $this->skipValue(); } + return; + } + if ($m >= 0x90 && $m <= 0x9f || $m === 0xdc || $m === 0xdd) { + $n = $this->readArrayLen(); + for ($i = 0; $i < $n; $i++) { $this->skipValue(); } + return; + } + if ($m === 0xc4 || $m === 0xc5 || $m === 0xc6) { $this->readBin(); return; } + if ($m === 0xc0) { $this->take(1); return; } // nil + if ($m === 0xc2 || $m === 0xc3) { $this->take(1); return; } // bool + if ($m === 0xca) { $this->take(5); return; } // float32 + if ($m === 0xcb) { $this->take(9); return; } // float64 + if ($m <= 0x7f || $m >= 0xe0) { $this->take(1); return; } // fixint + if ($m >= 0xcc && $m <= 0xcf) { $this->readUint(); return; } // uint + if ($m >= 0xd0 && $m <= 0xd3) { $this->readInt(); return; } // int + throw new \RuntimeException(sprintf("v1 decode: cannot skip marker 0x%02x", $m)); + } + + /** Big-endian unsigned from up to 8 bytes; returns int when it fits, else a decimal string. */ + private function beUint($bytes) + { + $n = strlen($bytes); + if ($n <= 4) { + $v = 0; + for ($i = 0; $i < $n; $i++) { $v = ($v << 8) | ord($bytes[$i]); } + return $v; + } + return $this->gmpToScalar(gmp_import($bytes, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN)); + } + + private function bytesToDecimal($bytes) + { + return gmp_strval(gmp_import($bytes, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN)); + } + + private function gmpToScalar($g) + { + // Keep small values as native ints (so json_encode emits `1`, not `"1"`); overflow -> string. + if (gmp_cmp($g, PHP_INT_MAX) <= 0 && gmp_cmp($g, PHP_INT_MIN) >= 0) { + return gmp_intval($g); + } + return gmp_strval($g); + } +} + +/** dechex() that also handles values returned as decimal strings (uint64 > PHP_INT_MAX). */ +function dechex_gmp($v) +{ + if (is_int($v)) { + return dechex($v); + } + return gmp_strval(gmp_init((string)$v, 10), 16); +} From 8a40a2919de455c7f0de0591e09eb83f658583cf Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Tue, 1 Sep 2026 13:22:34 +0200 Subject: [PATCH 30/32] fix(tracer): make serialize introspection uniformly v1-shape dd_trace_serialize_closed_spans() previously read the native V1 builder only when the sidecar sender was active (PHP 8.3+) and the V0.4 model otherwise, so its output shape depended on the active sender / PHP version. Introspection is a debug view: always finalize spans into the in-memory V1 builder and read them back via the V1 getters, regardless of which sender performs the wire flush. The V1 builder needs no active sidecar, so this is version-independent; the <=8.2 wire flush stays on the V0.4 background sender. --- tracer/functions.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/tracer/functions.c b/tracer/functions.c index 0097c19a113..186951755a2 100644 --- a/tracer/functions.c +++ b/tracer/functions.c @@ -1102,23 +1102,18 @@ PHP_FUNCTION(dd_trace_serialize_closed_spans) { ddtrace_mark_all_span_stacks_flushable(); - // Mirror the send path: on the sidecar/V1 path spans are finalized directly into the native V1 - // builder and introspected via the V1 getters (V1-shaped array); otherwise use the V0.4 model. - bool use_sidecar = get_global_DD_TRACE_SIDECAR_TRACE_SENDER() && DATADOG_G(sidecar); - ddtrace_v1_ctx v1_ctx = {.builder = NULL, .chunk = DD_V1_CHUNK_NONE}; - ddtrace_v1_ctx *v1 = NULL; - if (use_sidecar) { - v1_ctx.builder = ddog_v1_new_builder(); - v1 = &v1_ctx; - } + // Introspection is a debug view and must be uniformly V1-shaped on ALL PHP versions, + // independent of which sender performs the actual wire flush. The native V1 builder is an + // in-memory structure and does not require an active sidecar, so we always finalize spans into + // it and read them back via the V1 getters. The wire flush stays sender-gated elsewhere. + ddtrace_v1_ctx v1_ctx = {.builder = ddog_v1_new_builder(), .chunk = DD_V1_CHUNK_NONE}; + ddtrace_v1_ctx *v1 = &v1_ctx; ddog_TracesBytes *traces = ddog_get_traces(); ddtrace_serialize_closed_spans_with_cycle(traces, v1, false); - zval traces_zv = v1 ? dd_serialize_rust_v1_to_zval(v1->builder) : dd_serialize_rust_traces_to_zval(traces); - if (v1) { - ddog_v1_free_builder(v1->builder); - } + zval traces_zv = dd_serialize_rust_v1_to_zval(v1->builder); + ddog_v1_free_builder(v1->builder); if (zend_hash_num_elements(Z_ARR(traces_zv)) == 1) { ZVAL_COPY(return_value, zend_hash_get_current_data(Z_ARR(traces_zv))); From 6ada4ed722b6b5234b7355ea0b331d15aaff6b9d Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Tue, 1 Sep 2026 13:22:42 +0200 Subject: [PATCH 31/32] refactor: drop dead deprecated env/version handling and unused import The meta["env"]/meta["version"] deprecation path was already removed from ddtrace_precompute_span (env/version now come from the span property only), but left behind: two unused meta lookups, the env_deprecated/version_deprecated precomputed fields (permanently false), and the now always-true guards gating them in the serializer. Remove all of it. Also drop the unused AsBytes import in components-rs/agent_info.rs. --- components-rs/agent_info.rs | 2 +- tracer/serializer.c | 5 ++--- tracer/span_stats.c | 8 ++------ tracer/span_stats.h | 4 ---- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/components-rs/agent_info.rs b/components-rs/agent_info.rs index dceffde6c11..b157922e3a2 100644 --- a/components-rs/agent_info.rs +++ b/components-rs/agent_info.rs @@ -10,7 +10,7 @@ use crate::stats::apply_concentrator_config; use datadog_sidecar::service::agent_info::AgentInfoReader; -use libdd_common_ffi::slice::{AsBytes, CharSlice}; +use libdd_common_ffi::slice::CharSlice; use libdd_data_pipeline::agent_info::schema::AgentInfoStruct; use std::ffi::c_char; use std::ffi::CString; diff --git a/tracer/serializer.c b/tracer/serializer.c index 293825cd475..2de4e1552d5 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -2131,11 +2131,10 @@ dd_span_sink ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_T ZEND_HASH_FOREACH_END(); } - // Avoid adding it twice to meta - if (!pre.env_deprecated && pre.env) { + if (pre.env) { dd_sink_meta_str_zstr(&sink, "env", pre.env); } - if (!pre.version_deprecated && pre.version) { + if (pre.version) { dd_sink_meta_str_zstr(&sink, "version", pre.version); } diff --git a/tracer/span_stats.c b/tracer/span_stats.c index 71dc81bf6d1..337c30a78ae 100644 --- a/tracer/span_stats.c +++ b/tracer/span_stats.c @@ -107,10 +107,8 @@ void ddtrace_precompute_span(ddtrace_span_data *span, ddtrace_span_precomputed * pre->type = datadog_convert_to_str(prop_type); } - // Env: prefer deprecated meta["env"] (with a warning), else span property. + // Env: taken from the span's own property. pre->env = NULL; - zval *meta_env = pre->meta ? zend_hash_str_find(pre->meta, ZEND_STRL("env")) : NULL; - pre->env_deprecated = false; zval *prop_env = &span->property_env; ZVAL_DEREF(prop_env); if (Z_TYPE_P(prop_env) > IS_NULL) { @@ -122,10 +120,8 @@ void ddtrace_precompute_span(ddtrace_span_data *span, ddtrace_span_precomputed * } } - // Version: prefer deprecated meta["version"] (with a warning), else the span's own property. + // Version: taken from the span's own property. pre->version = NULL; - zval *meta_version = pre->meta ? zend_hash_str_find(pre->meta, ZEND_STRL("version")) : NULL; - pre->version_deprecated = false; zval *prop_version = &span->property_version; ZVAL_DEREF(prop_version); if (Z_TYPE_P(prop_version) > IS_NULL) { diff --git a/tracer/span_stats.h b/tracer/span_stats.h index b33e068672c..7a85f026e81 100644 --- a/tracer/span_stats.h +++ b/tracer/span_stats.h @@ -35,10 +35,6 @@ typedef struct { bool resource_from_meta; bool type_from_meta; - /* True when the span's meta hash contains a deprecated "env"/"version" key */ - bool env_deprecated; - bool version_deprecated; - bool has_exception; /* when span->property_exception holds a Throwable */ bool ignore_error; From 65c1b40af2f6aea5a3dfbfb7702ffc3c8ebd6070 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Tue, 1 Sep 2026 13:22:56 +0200 Subject: [PATCH 32/32] test: sweep tests/ext expectations to v1 serialization shape With introspection now uniformly V1-shaped, update the remaining tests/ext .phpt expectations that still asserted the V0.4 shape. Bodies read the unified attributes map (old meta + metrics merged); var_dump/JSON blocks gain top-level trace_id_high and span_kind, rename meta->attributes with real v1 insertion order, use native span_links/span_events arrays, and surface meta_struct under its own key. _dd.p.tid meta is dropped (now top-level trace_id_high) and the trace-flush debug log reads 'Flushing v1 trace'. The shared dd_dumper.inc / fake_tracer.inc helpers read attributes (string-valued only, preserving the historic meta-only view). tests/ext is fully green on the default config. --- ...al_tag_on_userland_and_internal_spans.phpt | 16 ++- .../dd_init_open_basedir.phpt | 2 +- .../error_get_last_is_unaffected.phpt | 2 +- .../autoload-php-files/file_not_found.phpt | 2 +- .../ignores_exceptions.phpt | 2 +- .../ignores_fatal_errors.phpt | 2 +- tests/ext/base_service.phpt | 12 +- ...ce_span_data_serialization_with_links.phpt | 64 +++++++-- .../distributed_trace_asm_standalone_01.phpt | 50 +++---- .../distributed_trace_asm_standalone_02.phpt | 46 ++++--- .../distributed_trace_bogus_ids.phpt | 33 +++-- .../distributed_trace_inherit.phpt | 48 +++---- tests/ext/fibers/fiber_observer_bailout.phpt | 6 +- tests/ext/fibers/fiber_stack_switch.phpt | 6 +- tests/ext/flush-autofinish.phpt | 4 +- tests/ext/includes/fake_tracer.inc | 4 +- tests/ext/inferred_proxy/alter_service.phpt | 52 +++---- tests/ext/inferred_proxy/basic_test.phpt | 54 ++++---- .../consume_distributed_tracing_headers.phpt | 47 ++++--- .../inferred_proxy/distributed_tracing.phpt | 57 ++++---- .../ext/inferred_proxy/error_propagated.phpt | 54 ++++---- .../inferred_proxy/fallback_service_name.phpt | 54 ++++---- .../inferred_proxy/incomplete_headers.phpt | 40 +++--- tests/ext/inferred_proxy/multiple_traces.phpt | 78 +++++------ .../propagated_tags_after_span_start.phpt | 54 ++++---- .../propagated_tags_before_span_start.phpt | 50 ++++--- tests/ext/inferred_proxy/sampling_rules.phpt | 40 +++--- ...metadata_injection_from_invalid_files.phpt | 78 +++++++---- .../source_code/commit_sha_env_var.phpt | 43 +++--- .../git_metadata_injection_from_env.phpt | 47 ++++--- ...t_metadata_injection_from_global_tags.phpt | 55 ++++---- ...injection_remove_credentials_from_env.phpt | 45 ++++--- .../source_code/repository_url_env_var.phpt | 45 ++++--- tests/ext/nested_exceptions.phpt | 12 +- ...l_http_response_status_code_remapping.phpt | 8 +- ...onse_status_code_remapping_precedence.phpt | 8 +- .../ext/otel_http_status_code_remapping.phpt | 8 +- .../pcntl_fork_long_running_autoflush.phpt | 8 +- tests/ext/peer_service_disabled_default.phpt | 14 +- tests/ext/peer_service_honor_user_value.phpt | 26 ++-- tests/ext/peer_service_remapping.phpt | 38 +++--- ...rvice_sources_not_serialized_when_set.phpt | 6 +- ...ice_sources_not_serialized_when_unset.phpt | 6 +- .../peer_service_use_first_available_tag.phpt | 38 ++++-- tests/ext/peer_service_wrong_values.phpt | 26 ++-- .../ext/sandbox-prehook/dd_trace_method.phpt | 82 +++++------ .../sandbox-prehook/exception_error_log.phpt | 2 +- .../class_resolver_bailout_hook.phpt | 2 +- .../limiter_reset_flush_with_open_spans.phpt | 8 +- .../nested_dropped_spans.phpt | 2 - tests/ext/sandbox/auto_flush.phpt | 6 +- .../sandbox/auto_flush_attach_exception.phpt | 2 +- .../sandbox/auto_flush_disables_tracing.phpt | 6 +- .../sandbox/auto_flush_sandbox_exception.phpt | 2 +- .../auto_flush_userland_root_span.phpt | 6 +- tests/ext/sandbox/dd_dumper.inc | 28 ++-- .../ext/sandbox/dd_trace_function_alias.phpt | 2 - .../sandbox/dd_trace_function_complex.phpt | 127 ++++++++++-------- .../sandbox/dd_trace_function_internal.phpt | 29 ++-- .../sandbox/dd_trace_function_userland.phpt | 6 +- tests/ext/sandbox/dd_trace_method.phpt | 90 +++++++------ tests/ext/sandbox/dd_trace_method_alias.phpt | 2 - .../ext/sandbox/default_span_properties.phpt | 6 +- .../default_span_properties_method.phpt | 2 - .../deferred_load_attempt_loading_once.phpt | 2 +- .../errors_are_flagged_from_userland.phpt | 33 +++-- tests/ext/sandbox/exception_error_log.phpt | 2 +- tests/ext/sandbox/hook_function/03.phpt | 2 +- .../hook_does_not_leak_error.phpt | 2 +- .../hook_function/posthook_error_02.phpt | 2 +- .../hook_function/posthook_exceptions_04.phpt | 2 +- .../hook_function/prehook_error_02.phpt | 2 +- .../hook_function/prehook_exceptions_02.phpt | 2 +- .../hook_function/prehook_exceptions_04.phpt | 2 +- tests/ext/sandbox/hook_method/03.phpt | 2 +- .../ext/sandbox/hook_method/posthook_07.phpt | 2 +- .../hook_method/posthook_error_02.phpt | 2 +- .../sandbox/hook_method/prehook_error_02.phpt | 2 +- .../hook_method/prehook_exceptions_02.phpt | 2 +- .../install_hook/hook_scoped_file.phpt | 2 - .../sandbox/install_hook/trace_callable.phpt | 3 - .../sandbox/install_hook/trace_closure.phpt | 8 -- .../trace_closure_from_callable.phpt | 6 +- .../ext/sandbox/install_hook/trace_file.phpt | 4 - .../sandbox/install_hook/trace_function.phpt | 2 - .../sandbox/install_hook/trace_generator.phpt | 1 - tests/ext/sandbox/manual_flush.phpt | 4 +- .../retval_is_null_with_exception.phpt | 2 +- ...to_string_metadata_drops_invalid_keys.phpt | 4 +- tests/ext/sandbox/span_clone.phpt | 29 ++-- ...c_tracing_closures_will_not_bind_this.phpt | 2 +- tests/ext/span_stack/span_stack_clone.phpt | 10 -- tests/ext/span_stack/span_stack_swap.phpt | 4 - .../span_stack_swap_traced_function.phpt | 2 - .../span_trace_stack_autoclose.phpt | 2 - tests/ext/span_stack/span_trace_swap.phpt | 4 - .../ext/span_stack/start_span_new_trace.phpt | 4 - tests/ext/span_stack/start_span_stack.phpt | 2 - .../start_top_level_span_stack.phpt | 2 - tests/ext/start_span_with_all_properties.phpt | 66 +++++---- tests/ext/start_span_without_closing.phpt | 29 ++-- ...start_span_without_closing_autofinish.phpt | 12 +- tests/ext/test_special_attributes.phpt | 12 +- tests/ext/test_special_attributes_bis.phpt | 12 +- tests/ext/traced_attribute.phpt | 22 ++- tests/ext/traced_attribute_delayed.phpt | 4 - tests/ext/ust.phpt | 64 +++++---- 107 files changed, 1164 insertions(+), 1015 deletions(-) diff --git a/tests/ext/add_global_tag_on_userland_and_internal_spans.phpt b/tests/ext/add_global_tag_on_userland_and_internal_spans.phpt index 9018f175f47..da6b3630bf8 100644 --- a/tests/ext/add_global_tag_on_userland_and_internal_spans.phpt +++ b/tests/ext/add_global_tag_on_userland_and_internal_spans.phpt @@ -30,9 +30,11 @@ var_dump(dd_clean_spans()); HOOK METHOD arg array(2) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -49,7 +51,9 @@ array(2) { string(49) "add_global_tag_on_userland_and_internal_spans.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(2) { ["alone"]=> string(2) "no" @@ -58,9 +62,11 @@ array(2) { } } [1]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -77,7 +83,9 @@ array(2) { string(49) "add_global_tag_on_userland_and_internal_spans.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(2) { ["alone"]=> string(2) "no" diff --git a/tests/ext/autoload-php-files/dd_init_open_basedir.phpt b/tests/ext/autoload-php-files/dd_init_open_basedir.phpt index c05c7d9f547..f999e4d7611 100644 --- a/tests/ext/autoload-php-files/dd_init_open_basedir.phpt +++ b/tests/ext/autoload-php-files/dd_init_open_basedir.phpt @@ -18,4 +18,4 @@ echo 'Done.' . PHP_EOL; [ddtrace] [warning] [%d] Error raised in autoloaded file %s_files_tracer.php: %s(): Failed opening '%s_files_tracer.php' for inclusion %s on line %d [ddtrace] [warning] [%d] Error raised in autoloaded file %sDDTrace/OpenBaseDir.php: %s(): Failed opening '%sDDTrace/OpenBaseDir.php' for inclusion %s on line %d Done. -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/autoload-php-files/error_get_last_is_unaffected.phpt b/tests/ext/autoload-php-files/error_get_last_is_unaffected.phpt index bf86e43f422..a40262b3fd6 100644 --- a/tests/ext/autoload-php-files/error_get_last_is_unaffected.phpt +++ b/tests/ext/autoload-php-files/error_get_last_is_unaffected.phpt @@ -17,4 +17,4 @@ var_dump(error_get_last()); [ddtrace] [warning] [%d] Error raised in autoloaded file %s_files_api.php: %s(): Failed opening '%s_files_api.php' for inclusion %s on line %d [ddtrace] [warning] [%d] Error raised in autoloaded file %sRaisesNotice.php: Notice? in %s on line %d NULL -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/autoload-php-files/file_not_found.phpt b/tests/ext/autoload-php-files/file_not_found.phpt index a6454617206..94de72c536e 100644 --- a/tests/ext/autoload-php-files/file_not_found.phpt +++ b/tests/ext/autoload-php-files/file_not_found.phpt @@ -18,4 +18,4 @@ echo "Request start" . PHP_EOL; [ddtrace] [warning] [%d] Error raised in autoloaded file %s_files_api.php: %s(): Failed opening '%s_files_api.php' for inclusion %s on line %d [ddtrace] [warning] [%d] Error raised in autoloaded file %s_files_tracer.php: %s(): Failed opening '%s_files_tracer.php' for inclusion %s on line %d Request start -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/autoload-php-files/ignores_exceptions.phpt b/tests/ext/autoload-php-files/ignores_exceptions.phpt index b77c513da8b..e36e7bf9716 100644 --- a/tests/ext/autoload-php-files/ignores_exceptions.phpt +++ b/tests/ext/autoload-php-files/ignores_exceptions.phpt @@ -19,4 +19,4 @@ echo "Request start" . PHP_EOL; Throwing an exception... [ddtrace] [warning] [%d] Exception thrown in autoloaded file %sRaisesException.php: Oops! Request start -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/autoload-php-files/ignores_fatal_errors.phpt b/tests/ext/autoload-php-files/ignores_fatal_errors.phpt index 1e5f7a8826f..905c079ea41 100644 --- a/tests/ext/autoload-php-files/ignores_fatal_errors.phpt +++ b/tests/ext/autoload-php-files/ignores_fatal_errors.phpt @@ -21,4 +21,4 @@ echo "Request start" . PHP_EOL; Calling a function that does not exist... [ddtrace] [warning] [%d] Error raised in autoloaded file %s: Allowed memory size of 20971520 bytes exhausted %s on line %d Request start -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/base_service.phpt b/tests/ext/base_service.phpt index a775ec2358f..5542dd1f48f 100644 --- a/tests/ext/base_service.phpt +++ b/tests/ext/base_service.phpt @@ -18,9 +18,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -37,12 +39,14 @@ array(1) { string(7) "changed" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(2) { - ["_dd.base_service"]=> - string(16) "base_service.php" ["_dd.svc_src"]=> string(1) "m" + ["_dd.base_service"]=> + string(16) "base_service.php" } } } diff --git a/tests/ext/dd_trace_span_data_serialization_with_links.phpt b/tests/ext/dd_trace_span_data_serialization_with_links.phpt index ba32b0ce973..b033522d036 100644 --- a/tests/ext/dd_trace_span_data_serialization_with_links.phpt +++ b/tests/ext/dd_trace_span_data_serialization_with_links.phpt @@ -16,7 +16,7 @@ DDTrace\trace_function('foo', $span->name = 'foo'; $firstLink = $span->getLink(); - // Drive the link through the real serialization path (produces meta["_dd.span_links"]). + // Drive the link through the real serialization path (produces native span_links). $span->links = [$firstLink]; } ); @@ -26,7 +26,7 @@ DDTrace\trace_function('bar', $span->name = 'bar'; $secondLink = $span->getLink(); - // Drive the link through the real serialization path (produces meta["_dd.span_links"]). + // Drive the link through the real serialization path (produces native span_links). $span->links = [$secondLink]; } ); @@ -45,16 +45,18 @@ baz(); $spans = dd_clean_spans(); // baz carries both links; foo and bar each carry their own self-link. All are asserted through -// the actual span serialization (meta["_dd.span_links"]), which is the real wire path. +// the actual span serialization (native top-level span_links), which is the real wire path. var_dump($spans[0]); -var_dump($spans[1]['name'], $spans[1]['meta']['_dd.span_links']); -var_dump($spans[2]['name'], $spans[2]['meta']['_dd.span_links']); +var_dump($spans[1]['name'], $spans[1]['span_links']); +var_dump($spans[2]['name'], $spans[2]['span_links']); ?> --EXPECTF-- -array(10) { +array(12) { ["trace_id"]=> string(20) "13930160852258120406" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(19) "2513787319205155662" ["parent_id"]=> @@ -71,13 +73,51 @@ array(10) { string(47) "dd_trace_span_data_serialization_with_links.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(1) { - ["_dd.span_links"]=> - string(155) "[{"trace_id":"%sc151df7d6ee5e2d6","span_id":"a3978fb9b92502a8"},{"trace_id":"%sc151df7d6ee5e2d6","span_id":"c08c967f0e5e7b0a"}]" + ["span_kind"]=> + int(1) + ["span_links"]=> + array(2) { + [0]=> + array(3) { + ["trace_id"]=> + string(20) "13930160852258120406" + ["span_id"]=> + string(20) "11788048577503494824" + ["flags"]=> + int(0) + } + [1]=> + array(3) { + ["trace_id"]=> + string(20) "13930160852258120406" + ["span_id"]=> + string(20) "13874630024467741450" + ["flags"]=> + int(0) + } } } string(3) "bar" -string(78) "[{"trace_id":"%sc151df7d6ee5e2d6","span_id":"c08c967f0e5e7b0a"}]" +array(1) { + [0]=> + array(3) { + ["trace_id"]=> + string(20) "13930160852258120406" + ["span_id"]=> + string(20) "13874630024467741450" + ["flags"]=> + int(0) + } +} string(3) "foo" -string(78) "[{"trace_id":"%sc151df7d6ee5e2d6","span_id":"a3978fb9b92502a8"}]" +array(1) { + [0]=> + array(3) { + ["trace_id"]=> + string(20) "13930160852258120406" + ["span_id"]=> + string(20) "11788048577503494824" + ["flags"]=> + int(0) + } +} diff --git a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_01.phpt b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_01.phpt index db324e84c9d..b8be6562943 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_01.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_01.phpt @@ -28,7 +28,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(11) { + array(14) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -47,39 +47,38 @@ array(2) { string(39) "distributed_trace_asm_standalone_01.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(6) { - ["_dd.origin"]=> - string(7) "datadog" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["origin"]=> + string(7) "datadog" + ["attributes"]=> + array(9) { ["_dd.p.custom_tag"]=> string(9) "inherited" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.other_tag"]=> - string(4) "also" ["_dd.propagation_error"]=> string(14) "decoding_error" + ["_dd.p.other_tag"]=> + string(4) "also" ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.apm.enabled"]=> float(0) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } [1]=> - array(11) { + array(14) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -98,12 +97,15 @@ array(2) { string(39) "distributed_trace_asm_standalone_01.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(1) { - ["_dd.origin"]=> - string(7) "datadog" - } - ["metrics"]=> + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["origin"]=> + string(7) "datadog" + ["attributes"]=> array(1) { ["_dd.apm.enabled"]=> float(0) diff --git a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_02.phpt b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_02.phpt index 98300bf291d..59360368174 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_02.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_02.phpt @@ -28,7 +28,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(11) { + array(14) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -47,35 +47,34 @@ array(2) { string(39) "distributed_trace_asm_standalone_02.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(4) { - ["_dd.origin"]=> - string(7) "datadog" - ["_dd.p.dm"]=> - string(2) "-0" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(3) + ["sampling_mechanism"]=> + int(0) + ["origin"]=> + string(7) "datadog" + ["attributes"]=> + array(7) { ["_dd.p.ts"]=> string(2) "02" ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.apm.enabled"]=> float(0) - ["_sampling_priority_v1"]=> - float(3) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } [1]=> - array(11) { + array(14) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -94,12 +93,15 @@ array(2) { string(39) "distributed_trace_asm_standalone_02.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(1) { - ["_dd.origin"]=> - string(7) "datadog" - } - ["metrics"]=> + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(3) + ["sampling_mechanism"]=> + int(0) + ["origin"]=> + string(7) "datadog" + ["attributes"]=> array(1) { ["_dd.apm.enabled"]=> float(0) diff --git a/tests/ext/distributed_tracing/distributed_trace_bogus_ids.phpt b/tests/ext/distributed_tracing/distributed_trace_bogus_ids.phpt index b5b61f87fce..26ae0ccad7a 100644 --- a/tests/ext/distributed_tracing/distributed_trace_bogus_ids.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_bogus_ids.phpt @@ -21,9 +21,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(10) { + array(14) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -38,30 +40,27 @@ array(1) { string(31) "distributed_trace_bogus_ids.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(4) { - ["_dd.origin"]=> - string(7) "datadog" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["origin"]=> + string(7) "datadog" + ["attributes"]=> + array(6) { ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } diff --git a/tests/ext/distributed_tracing/distributed_trace_inherit.phpt b/tests/ext/distributed_tracing/distributed_trace_inherit.phpt index 433d4c1ef84..cfba9ccdd1b 100644 --- a/tests/ext/distributed_tracing/distributed_trace_inherit.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_inherit.phpt @@ -27,7 +27,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(11) { + array(14) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -46,37 +46,36 @@ array(2) { string(29) "distributed_trace_inherit.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(6) { - ["_dd.origin"]=> - string(7) "datadog" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(3) + ["sampling_mechanism"]=> + int(0) + ["origin"]=> + string(7) "datadog" + ["attributes"]=> + array(8) { ["_dd.p.custom_tag"]=> string(9) "inherited" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.other_tag"]=> - string(4) "also" ["_dd.propagation_error"]=> string(14) "decoding_error" + ["_dd.p.other_tag"]=> + string(4) "also" ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(5) { - ["_sampling_priority_v1"]=> - float(3) - ["php.compilation.total_time_ms"]=> + ["process_id"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> + ["php.compilation.total_time_ms"]=> float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } [1]=> - array(10) { + array(13) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -95,10 +94,13 @@ array(2) { string(29) "distributed_trace_inherit.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(1) { - ["_dd.origin"]=> - string(7) "datadog" - } + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(3) + ["sampling_mechanism"]=> + int(0) + ["origin"]=> + string(7) "datadog" } } diff --git a/tests/ext/fibers/fiber_observer_bailout.phpt b/tests/ext/fibers/fiber_observer_bailout.phpt index 277de4a684c..244566b792d 100644 --- a/tests/ext/fibers/fiber_observer_bailout.phpt +++ b/tests/ext/fibers/fiber_observer_bailout.phpt @@ -46,22 +46,20 @@ Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d inFiber posthook spans(\DDTrace\SpanData) (1) { fiber_observer_bailout.php (fiber_observer_bailout.php, fiber_observer_bailout.php, cli) (error: Allowed memory size of %d bytes exhausted %s) - _dd.p.dm => -0 - _dd.p.tid => %s + error.type => E_ERROR error.message => Allowed memory size of %d bytes exhausted %s error.stack => #0 %s(%d): str_repeat() #1 [internal function]: inFiber() #2 %s(%d): Fiber->resume() #3 %s(%d): outer() #4 {main} - error.type => E_ERROR inFiber (fiber_observer_bailout.php, inFiber, cli) (error: Allowed memory size of %d bytes exhausted %s) + error.type => E_ERROR error.message => Allowed memory size of %d bytes exhausted %s error.stack => #0 %s(%d): str_repeat() #1 [internal function]: inFiber() #2 %s(%d): Fiber->resume() #3 %s(%d): outer() #4 {main} - error.type => E_ERROR outer (fiber_observer_bailout.php, outer, cli) } diff --git a/tests/ext/fibers/fiber_stack_switch.phpt b/tests/ext/fibers/fiber_stack_switch.phpt index 5c2118eccee..189e9a1d118 100644 --- a/tests/ext/fibers/fiber_stack_switch.phpt +++ b/tests/ext/fibers/fiber_stack_switch.phpt @@ -79,23 +79,21 @@ Hook: Fiber->resume Caught ex spans(\DDTrace\SpanData) (1) { fiber_stack_switch.php (fiber_stack_switch.php, fiber_stack_switch.php, cli) - _dd.p.dm => -0 - _dd.p.tid => %s Fiber.start (fiber_stack_switch.php, Fiber.start, cli) inFiber (fiber_stack_switch.php, inFiber, cli) otherFiber (fiber_stack_switch.php, otherFiber, cli) (error: Thrown Exception: ex in %s:%d) error.message => Thrown Exception: ex in %s:%d + error.type => Exception error.stack => #0 [internal function]: otherFiber() #1 %s(%d): Fiber->resume() #2 {main} - error.type => Exception Fiber.suspend (fiber_stack_switch.php, Fiber.suspend, cli) Fiber.suspend (fiber_stack_switch.php, Fiber.suspend, cli) Fiber.resume (fiber_stack_switch.php, Fiber.resume, cli) Fiber.resume (fiber_stack_switch.php, Fiber.resume, cli) (error: Thrown Exception: ex in %s:%d) error.message => Thrown Exception: ex in %s:%d + error.type => Exception error.stack => #0 [internal function]: otherFiber() #1 %s(%d): Fiber->resume() #2 {main} - error.type => Exception } \ No newline at end of file diff --git a/tests/ext/flush-autofinish.phpt b/tests/ext/flush-autofinish.phpt index e890e936475..a7595aa10a0 100644 --- a/tests/ext/flush-autofinish.phpt +++ b/tests/ext/flush-autofinish.phpt @@ -17,7 +17,7 @@ var_dump(DDTrace\active_span() != null); ?> --EXPECTF-- -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s bool(true) bool(true) -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/includes/fake_tracer.inc b/tests/ext/includes/fake_tracer.inc index e9a98bf25b5..a3f080ee955 100644 --- a/tests/ext/includes/fake_tracer.inc +++ b/tests/ext/includes/fake_tracer.inc @@ -26,8 +26,8 @@ class Tracer if (!empty($values)) { $valuesString .= ' (' . implode(', ', $values) . ')'; } - if (isset($span['meta']['error.message'])) { - $valuesString .= ' (error: ' . $span['meta']['error.message'] . ')'; + if (isset($span['attributes']['error.message'])) { + $valuesString .= ' (error: ' . $span['attributes']['error.message'] . ')'; } $valuesString .= PHP_EOL; if (strlen($valuesString) > 0) { diff --git a/tests/ext/inferred_proxy/alter_service.phpt b/tests/ext/inferred_proxy/alter_service.phpt index 419335cf093..b953cc9582f 100644 --- a/tests/ext/inferred_proxy/alter_service.phpt +++ b/tests/ext/inferred_proxy/alter_service.phpt @@ -43,6 +43,7 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); [ { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13930160852258120406", "parent_id": "11788048577503494824", "start": 120000000, @@ -51,24 +52,25 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "aws-server", "type": "web", - "meta": { - "env": "local-prod", + "env": "local-prod", + "version": "1.0", + "span_kind": 2, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { + "process_id": %d, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "11788048577503494824", "start": 100000000, "duration": %d, @@ -76,25 +78,24 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/test", "service": "example.com", "type": "web", - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "%s", - "component": "aws-apigateway", - "env": "local-prod", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { "http.method": "GET", - "http.status_code": "200", "http.url": "example.com\/test", "stage": "aws-prod", - "version": "1.0" - }, - "metrics": { - "_dd.agent_psr": 1, + "http.status_code": "200", "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "_dd.agent_psr": 1 } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13874630024467741450", "parent_id": "13930160852258120406", "start": 130000000, @@ -103,9 +104,10 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "child", "service": "aws-server", "type": "web", - "meta": { - "env": "local-prod", - "version": "1.0" - } + "env": "local-prod", + "version": "1.0", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0 } ] \ No newline at end of file diff --git a/tests/ext/inferred_proxy/basic_test.phpt b/tests/ext/inferred_proxy/basic_test.phpt index b8fc62939ff..b76643661ba 100644 --- a/tests/ext/inferred_proxy/basic_test.phpt +++ b/tests/ext/inferred_proxy/basic_test.phpt @@ -60,6 +60,7 @@ if ($percentageDifference > 0.01) { // 0.01% difference for the sake of the test [ { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13930160852258120406", "parent_id": "11788048577503494824", "start": %d, @@ -68,25 +69,26 @@ if ($percentageDifference > 0.01) { // 0.01% difference for the sake of the test "resource": "GET \/foo", "service": "aws-server", "type": "web", - "meta": { - "env": "local-prod", - "foo": "bar", + "env": "local-prod", + "version": "1.0", + "span_kind": 2, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "foo": "bar", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { + "process_id": %d, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "11788048577503494824", "start": 1742285908783000000, "duration": %d, @@ -94,25 +96,24 @@ if ($percentageDifference > 0.01) { // 0.01% difference for the sake of the test "resource": "GET \/test", "service": "example.com", "type": "web", - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "%s", - "component": "aws-apigateway", - "env": "local-prod", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { "http.method": "GET", - "http.status_code": "200", "http.url": "example.com\/test", "stage": "aws-prod", - "version": "1.0" - }, - "metrics": { - "_dd.agent_psr": 1, + "http.status_code": "200", "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "_dd.agent_psr": 1 } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13874630024467741450", "parent_id": "13930160852258120406", "start": %d, @@ -121,9 +122,10 @@ if ($percentageDifference > 0.01) { // 0.01% difference for the sake of the test "resource": "child", "service": "aws-server", "type": "web", - "meta": { - "env": "local-prod", - "version": "1.0" - } + "env": "local-prod", + "version": "1.0", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0 } ]Duration is within 0.01% of expected duration \ No newline at end of file diff --git a/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt b/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt index 4023bf9f6b2..7c9f2b2d885 100644 --- a/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt +++ b/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt @@ -48,6 +48,7 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); [ { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13930160852258120406", "parent_id": "11788048577503494824", "start": 120000000, @@ -56,21 +57,23 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "consume_distributed_tracing_headers.php", "service": "aws-server", "type": "cli", - "meta": { - "env": "local-prod", - "http.url": "http:\/\/localhost:8888\/foo", + "env": "local-prod", + "version": "1.0", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { "runtime-id": "%s", - "version": "1.0" - }, - "metrics": { + "http.url": "http:\/\/localhost:8888\/foo", + "process_id": %d, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "11788048577503494824", "start": %d, "duration": %d, @@ -78,24 +81,23 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/test", "service": "example.com", "type": "web", - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "%s", - "component": "aws-apigateway", - "env": "local-prod", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { "http.method": "GET", "http.url": "example.com\/test", "stage": "aws-prod", - "version": "1.0" - }, - "metrics": { - "_dd.agent_psr": 1, "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "_dd.agent_psr": 1 } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13874630024467741450", "parent_id": "13930160852258120406", "start": 130000000, @@ -104,9 +106,10 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "child", "service": "aws-server", "type": "cli", - "meta": { - "env": "local-prod", - "version": "1.0" - } + "env": "local-prod", + "version": "1.0", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0 } ] \ No newline at end of file diff --git a/tests/ext/inferred_proxy/distributed_tracing.phpt b/tests/ext/inferred_proxy/distributed_tracing.phpt index be481d60c10..3800c510f9d 100644 --- a/tests/ext/inferred_proxy/distributed_tracing.phpt +++ b/tests/ext/inferred_proxy/distributed_tracing.phpt @@ -58,22 +58,22 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "aws-server", "type": "web", - "meta": { - "_dd.origin": "rum", - "env": "local-prod", - "foo": "bar", + "env": "local-prod", + "version": "1.0", + "span_kind": 2, + "sampling_priority": 2, + "sampling_mechanism": 0, + "origin": "rum", + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "foo": "bar", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { + "process_id": %d, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { @@ -86,21 +86,19 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/test", "service": "example.com", "type": "web", - "meta": { - "_dd.origin": "rum", - "_dd.p.dm": "-0", - "_dd.p.tid": "0", - "component": "aws-apigateway", - "env": "local-prod", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "span_kind": 1, + "sampling_priority": 2, + "sampling_mechanism": 0, + "origin": "rum", + "attributes": { "http.method": "GET", - "http.status_code": "200", "http.url": "example.com\/test", "stage": "aws-prod", - "version": "1.0" - }, - "metrics": { - "_dd.inferred_span": 1, - "_sampling_priority_v1": 2 + "http.status_code": "200", + "_dd.inferred_span": 1 } }, { @@ -113,10 +111,11 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "child", "service": "aws-server", "type": "web", - "meta": { - "_dd.origin": "rum", - "env": "local-prod", - "version": "1.0" - } + "env": "local-prod", + "version": "1.0", + "span_kind": 1, + "sampling_priority": 2, + "sampling_mechanism": 0, + "origin": "rum" } ] \ No newline at end of file diff --git a/tests/ext/inferred_proxy/error_propagated.phpt b/tests/ext/inferred_proxy/error_propagated.phpt index 7d7c98d39b4..b8025ef7fac 100644 --- a/tests/ext/inferred_proxy/error_propagated.phpt +++ b/tests/ext/inferred_proxy/error_propagated.phpt @@ -52,6 +52,7 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); [ { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13930160852258120406", "parent_id": "11788048577503494824", "start": %d, @@ -61,27 +62,28 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "service": "aws-server", "type": "web", "error": 1, - "meta": { - "env": "local-prod", - "error.message": "Uncaught Exception (500): An exception occurred in %serror_propagated.php:%d", - "error.stack": "#0 %serror_propagated.php(%d): oops()\n#1 {main}", - "error.type": "Exception", + "env": "local-prod", + "version": "1.0", + "span_kind": 2, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", "http.status_code": "500", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { + "error.type": "Exception", + "error.message": "Uncaught Exception (500): An exception occurred in %serror_propagated.php:%d", + "error.stack": "#0 %serror_propagated.php(%d): oops()\n#1 {main}", + "process_id": %d, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "11788048577503494824", "start": 100000000, "duration": %d, @@ -90,24 +92,22 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "service": "example.com", "type": "web", "error": 1, - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "%s", - "component": "aws-apigateway", - "env": "local-prod", - "error.message": "Uncaught Exception (500): An exception occurred in %serror_propagated.php:%d", - "error.stack": "#0 %serror_propagated.php(%d): oops()\n#1 {main}", - "error.type": "Exception", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { "http.method": "GET", - "http.status_code": "500", "http.url": "example.com\/test", "stage": "aws-prod", - "version": "1.0" - }, - "metrics": { - "_dd.agent_psr": 1, + "http.status_code": "500", + "error.type": "Exception", "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "_dd.agent_psr": 1, + "error.message": "Uncaught Exception (500): An exception occurred in %serror_propagated.php:%d", + "error.stack": "#0 %serror_propagated.php(%d): oops()\n#1 {main}" } } ] \ No newline at end of file diff --git a/tests/ext/inferred_proxy/fallback_service_name.phpt b/tests/ext/inferred_proxy/fallback_service_name.phpt index 8b9cfe1d244..25e06870719 100644 --- a/tests/ext/inferred_proxy/fallback_service_name.phpt +++ b/tests/ext/inferred_proxy/fallback_service_name.phpt @@ -44,6 +44,7 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); [ { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13930160852258120406", "parent_id": "11788048577503494824", "start": 120000000, @@ -52,25 +53,26 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "aws-server", "type": "web", - "meta": { - "env": "local-prod", - "foo": "bar", + "env": "local-prod", + "version": "1.0", + "span_kind": 2, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "foo": "bar", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { + "process_id": %d, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "11788048577503494824", "start": 100000000, "duration": %d, @@ -78,24 +80,23 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/test", "service": "aws-server", "type": "web", - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "%s", - "component": "aws-apigateway", - "env": "local-prod", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { "http.method": "GET", - "http.status_code": "200", "stage": "aws-prod", - "version": "1.0" - }, - "metrics": { - "_dd.agent_psr": 1, + "http.status_code": "200", "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "_dd.agent_psr": 1 } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13874630024467741450", "parent_id": "13930160852258120406", "start": 130000000, @@ -104,9 +105,10 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "child", "service": "aws-server", "type": "web", - "meta": { - "env": "local-prod", - "version": "1.0" - } + "env": "local-prod", + "version": "1.0", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0 } ] \ No newline at end of file diff --git a/tests/ext/inferred_proxy/incomplete_headers.phpt b/tests/ext/inferred_proxy/incomplete_headers.phpt index 2ca50170b25..83f7356ffd0 100644 --- a/tests/ext/inferred_proxy/incomplete_headers.phpt +++ b/tests/ext/inferred_proxy/incomplete_headers.phpt @@ -37,6 +37,7 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); [ { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13930160852258120406", "start": 120000000, "duration": %d, @@ -44,31 +45,29 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "aws-server", "type": "web", - "meta": { + "env": "local-prod", + "version": "1.0", + "span_kind": 2, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", + "http.method": "GET", + "_dd.code_origin.type": "entry", "_dd.code_origin.frames.0.file": "%sincomplete_headers.php", "_dd.code_origin.frames.0.line": "1", - "_dd.code_origin.type": "entry", - "_dd.p.dm": "-0", - "_dd.p.tid": "%s", - "env": "local-prod", - "http.method": "GET", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { + "process_id": %d, "_dd.agent_psr": 1, - "_sampling_priority_v1": 1, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "11788048577503494824", "parent_id": "13930160852258120406", "start": 130000000, @@ -77,9 +76,10 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "child", "service": "aws-server", "type": "web", - "meta": { - "env": "local-prod", - "version": "1.0" - } + "env": "local-prod", + "version": "1.0", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0 } -] \ No newline at end of file +] diff --git a/tests/ext/inferred_proxy/multiple_traces.phpt b/tests/ext/inferred_proxy/multiple_traces.phpt index 8038c2de489..4675a432319 100644 --- a/tests/ext/inferred_proxy/multiple_traces.phpt +++ b/tests/ext/inferred_proxy/multiple_traces.phpt @@ -47,6 +47,7 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); [ { "trace_id": "2513787319205155662", + "trace_id_high": "%s", "span_id": "2513787319205155662", "start": %d, "duration": %d, @@ -54,28 +55,26 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "aws-server", "type": "web", - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "%s", - "env": "local-prod", + "env": "local-prod", + "version": "1.0", + "span_kind": 2, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { + "process_id": %d, "_dd.agent_psr": 1, - "_sampling_priority_v1": 1, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13930160852258120406", "parent_id": "11788048577503494824", "start": 120000000, @@ -84,24 +83,25 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "aws-server", "type": "web", - "meta": { - "env": "local-prod", + "env": "local-prod", + "version": "1.0", + "span_kind": 2, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { + "process_id": %d, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "11788048577503494824", "start": 100000000, "duration": %d, @@ -109,25 +109,24 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/test", "service": "example.com", "type": "web", - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "%s", - "component": "aws-apigateway", - "env": "local-prod", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { "http.method": "GET", - "http.status_code": "200", "http.url": "example.com\/test", "stage": "aws-prod", - "version": "1.0" - }, - "metrics": { - "_dd.agent_psr": 1, + "http.status_code": "200", "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "_dd.agent_psr": 1 } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13874630024467741450", "parent_id": "13930160852258120406", "start": 130000000, @@ -136,9 +135,10 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "child", "service": "aws-server", "type": "web", - "meta": { - "env": "local-prod", - "version": "1.0" - } + "env": "local-prod", + "version": "1.0", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 0 } -] \ No newline at end of file +] diff --git a/tests/ext/inferred_proxy/propagated_tags_after_span_start.phpt b/tests/ext/inferred_proxy/propagated_tags_after_span_start.phpt index 60bca935664..df81b450f9c 100644 --- a/tests/ext/inferred_proxy/propagated_tags_after_span_start.phpt +++ b/tests/ext/inferred_proxy/propagated_tags_after_span_start.phpt @@ -55,23 +55,23 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "aws-server", "type": "web", - "meta": { - "_dd.origin": "rum", - "_dd.p.usr.id": "12345", - "_dd.parent_id": "00000000000000bb", - "env": "local-prod", + "env": "local-prod", + "version": "1.0", + "span_kind": 2, + "sampling_priority": 1, + "sampling_mechanism": 4, + "origin": "rum", + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "_dd.parent_id": "00000000000000bb", + "_dd.p.usr.id": "12345", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { + "process_id": %d, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { @@ -84,23 +84,21 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/test", "service": "example.com", "type": "web", - "meta": { - "_dd.origin": "rum", - "_dd.p.dm": "-4", - "_dd.p.tid": "0", - "_dd.p.usr.id": "12345", - "_dd.parent_id": "00000000000000bb", - "component": "aws-apigateway", - "env": "local-prod", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 4, + "origin": "rum", + "attributes": { "http.method": "GET", - "http.status_code": "200", "http.url": "example.com\/test", "stage": "aws-prod", - "version": "1.0" - }, - "metrics": { - "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "_dd.parent_id": "00000000000000bb", + "_dd.p.usr.id": "12345", + "http.status_code": "200", + "_dd.inferred_span": 1 } } -] \ No newline at end of file +] diff --git a/tests/ext/inferred_proxy/propagated_tags_before_span_start.phpt b/tests/ext/inferred_proxy/propagated_tags_before_span_start.phpt index 4ec56b8f433..e36ec03a653 100644 --- a/tests/ext/inferred_proxy/propagated_tags_before_span_start.phpt +++ b/tests/ext/inferred_proxy/propagated_tags_before_span_start.phpt @@ -54,23 +54,23 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "aws-server", "type": "web", - "meta": { - "_dd.origin": "rum", - "_dd.p.usr.id": "12345", + "env": "local-prod", + "version": "1.0", + "span_kind": 2, + "sampling_priority": 1, + "sampling_mechanism": 4, + "origin": "rum", + "attributes": { "_dd.parent_id": "00000000000000bb", - "env": "local-prod", + "_dd.p.usr.id": "12345", + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { + "process_id": %d, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { @@ -83,23 +83,21 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/test", "service": "example.com", "type": "web", - "meta": { - "_dd.origin": "rum", - "_dd.p.dm": "-4", - "_dd.p.tid": "0", - "_dd.p.usr.id": "12345", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "span_kind": 1, + "sampling_priority": 1, + "sampling_mechanism": 4, + "origin": "rum", + "attributes": { "_dd.parent_id": "00000000000000bb", - "component": "aws-apigateway", - "env": "local-prod", + "_dd.p.usr.id": "12345", "http.method": "GET", - "http.status_code": "200", "http.url": "example.com\/test", "stage": "aws-prod", - "version": "1.0" - }, - "metrics": { - "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "http.status_code": "200", + "_dd.inferred_span": 1 } } -] \ No newline at end of file +] diff --git a/tests/ext/inferred_proxy/sampling_rules.phpt b/tests/ext/inferred_proxy/sampling_rules.phpt index ec95d80ce1a..90266e66b86 100644 --- a/tests/ext/inferred_proxy/sampling_rules.phpt +++ b/tests/ext/inferred_proxy/sampling_rules.phpt @@ -40,6 +40,7 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); [ { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "13930160852258120406", "parent_id": "11788048577503494824", "start": 120000000, @@ -48,23 +49,24 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "foo", "type": "web", - "meta": { - "_dd.p.ksr": "0.3", + "span_kind": 2, + "sampling_priority": 2, + "sampling_mechanism": 3, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "_dd.p.ksr": "0.3", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server" - }, - "metrics": { + "process_id": %d, "php.compilation.total_time_ms": %f, - "php.memory.peak_real_usage_bytes": %d, "php.memory.peak_usage_bytes": %d, - "process_id": %d + "php.memory.peak_real_usage_bytes": %d } }, { "trace_id": "13930160852258120406", + "trace_id_high": "%s", "span_id": "11788048577503494824", "start": 100000000, "duration": %d, @@ -72,20 +74,18 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/test", "service": "example.com", "type": "web", - "meta": { - "_dd.p.dm": "-3", - "_dd.p.ksr": "0.3", - "_dd.p.tid": "%s", - "component": "aws-apigateway", + "component": "aws-apigateway", + "span_kind": 1, + "sampling_priority": 2, + "sampling_mechanism": 3, + "attributes": { "http.method": "GET", - "http.status_code": "200", "http.url": "example.com\/test", - "stage": "aws-prod" - }, - "metrics": { + "stage": "aws-prod", + "http.status_code": "200", "_dd.inferred_span": 1, "_dd.rule_psr": 0.3, - "_sampling_priority_v1": 2 + "_dd.p.ksr": "0.3" } } -] \ No newline at end of file +] diff --git a/tests/ext/integrations/source_code/002/git_metadata_injection_from_invalid_files.phpt b/tests/ext/integrations/source_code/002/git_metadata_injection_from_invalid_files.phpt index de22c60be6d..d5e7c729658 100644 --- a/tests/ext/integrations/source_code/002/git_metadata_injection_from_invalid_files.phpt +++ b/tests/ext/integrations/source_code/002/git_metadata_injection_from_invalid_files.phpt @@ -28,14 +28,14 @@ function makeRequest() { \DDTrace\close_span(); $closedSpans = dd_clean_spans(); - $rootMeta = $closedSpans[0]['meta']; + $rootMeta = $closedSpans[0]['attributes']; var_dump($rootMeta); \DDTrace\start_span(); \DDTrace\close_span(); $closedRoot = dd_clean_spans(); - $rootMeta2 = $closedRoot[0]['meta']; + $rootMeta2 = $closedRoot[0]['attributes']; var_dump($rootMeta2); } @@ -55,43 +55,67 @@ function rm_rf($dir) { rm_rf(__DIR__ . '/.git'); ?> --EXPECTF-- -array(4) { - ["_dd.git.repository_url"]=> - string(32) "https://github.com/user/repo_new" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" +array(7) { ["runtime-id"]=> string(%d) "%s" -} -array(4) { ["_dd.git.repository_url"]=> string(32) "https://github.com/user/repo_new" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) + ["php.compilation.total_time_ms"]=> + float(%f) + ["php.memory.peak_usage_bytes"]=> + float(%f) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) +} +array(7) { ["runtime-id"]=> string(%d) "%s" -} -array(4) { ["_dd.git.repository_url"]=> string(32) "https://github.com/user/repo_new" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) + ["php.compilation.total_time_ms"]=> + float(%f) + ["php.memory.peak_usage_bytes"]=> + float(%f) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) +} +array(7) { ["runtime-id"]=> string(%d) "%s" -} -array(4) { ["_dd.git.repository_url"]=> string(32) "https://github.com/user/repo_new" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) + ["php.compilation.total_time_ms"]=> + float(%f) + ["php.memory.peak_usage_bytes"]=> + float(%f) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) +} +array(7) { ["runtime-id"]=> string(%d) "%s" + ["_dd.git.repository_url"]=> + string(32) "https://github.com/user/repo_new" + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) + ["php.compilation.total_time_ms"]=> + float(%f) + ["php.memory.peak_usage_bytes"]=> + float(%f) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) } diff --git a/tests/ext/integrations/source_code/commit_sha_env_var.phpt b/tests/ext/integrations/source_code/commit_sha_env_var.phpt index 907bf033afe..8b969136ef7 100644 --- a/tests/ext/integrations/source_code/commit_sha_env_var.phpt +++ b/tests/ext/integrations/source_code/commit_sha_env_var.phpt @@ -23,9 +23,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -40,37 +42,36 @@ array(2) { string(22) "commit_sha_env_var.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(4) { - ["_dd.git.commit.sha"]=> - string(6) "123456" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(7) { ["runtime-id"]=> string(%d) "%s" - } - ["metrics"]=> - array(6) { + ["_dd.git.commit.sha"]=> + string(6) "123456" + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } [1]=> - array(9) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -87,5 +88,11 @@ array(2) { string(22) "commit_sha_env_var.php" ["type"]=> string(3) "cli" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) } } diff --git a/tests/ext/integrations/source_code/git_metadata_injection_from_env.phpt b/tests/ext/integrations/source_code/git_metadata_injection_from_env.phpt index d420f7f4b7b..97060949363 100644 --- a/tests/ext/integrations/source_code/git_metadata_injection_from_env.phpt +++ b/tests/ext/integrations/source_code/git_metadata_injection_from_env.phpt @@ -24,9 +24,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -41,39 +43,38 @@ array(2) { string(35) "git_metadata_injection_from_env.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(5) { + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(8) { + ["runtime-id"]=> + string(%d) "%s" ["_dd.git.commit.sha"]=> string(6) "123456" ["_dd.git.repository_url"]=> string(24) "github.com/user/env_repo" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["runtime-id"]=> - string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> - float(%d) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) } } [1]=> - array(9) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -90,5 +91,11 @@ array(2) { string(35) "git_metadata_injection_from_env.php" ["type"]=> string(3) "cli" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) } -} \ No newline at end of file +} diff --git a/tests/ext/integrations/source_code/git_metadata_injection_from_global_tags.phpt b/tests/ext/integrations/source_code/git_metadata_injection_from_global_tags.phpt index f7a0669b129..5e0711f4b29 100644 --- a/tests/ext/integrations/source_code/git_metadata_injection_from_global_tags.phpt +++ b/tests/ext/integrations/source_code/git_metadata_injection_from_global_tags.phpt @@ -23,9 +23,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -40,43 +42,42 @@ array(2) { string(43) "git_metadata_injection_from_global_tags.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(7) { - ["_dd.git.commit.sha"]=> - string(6) "123456" - ["_dd.git.repository_url"]=> - string(24) "github.com/user/env_repo" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(10) { + ["runtime-id"]=> + string(%d) "%s" ["git.commit.sha"]=> string(6) "123456" ["git.repository_url"]=> string(24) "github.com/user/env_repo" - ["runtime-id"]=> - string(36) "%s" - } - ["metrics"]=> - array(6) { + ["_dd.git.commit.sha"]=> + string(6) "123456" + ["_dd.git.repository_url"]=> + string(24) "github.com/user/env_repo" + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> - float(%d) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) } } [1]=> - array(10) { + array(14) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -93,7 +94,13 @@ array(2) { string(43) "git_metadata_injection_from_global_tags.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> array(2) { ["git.commit.sha"]=> string(6) "123456" diff --git a/tests/ext/integrations/source_code/git_metadata_injection_remove_credentials_from_env.phpt b/tests/ext/integrations/source_code/git_metadata_injection_remove_credentials_from_env.phpt index 6e735807c4a..13f4722ea74 100644 --- a/tests/ext/integrations/source_code/git_metadata_injection_remove_credentials_from_env.phpt +++ b/tests/ext/integrations/source_code/git_metadata_injection_remove_credentials_from_env.phpt @@ -24,9 +24,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -41,39 +43,38 @@ array(2) { string(54) "git_metadata_injection_remove_credentials_from_env.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(5) { + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(8) { + ["runtime-id"]=> + string(%d) "%s" ["_dd.git.commit.sha"]=> string(6) "123456" ["_dd.git.repository_url"]=> string(32) "https://github.com/user/repo_new" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["runtime-id"]=> - string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> - float(%d) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) } } [1]=> - array(9) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -90,5 +91,11 @@ array(2) { string(54) "git_metadata_injection_remove_credentials_from_env.php" ["type"]=> string(3) "cli" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) } } diff --git a/tests/ext/integrations/source_code/repository_url_env_var.phpt b/tests/ext/integrations/source_code/repository_url_env_var.phpt index b7f4fa91086..6751628e61c 100644 --- a/tests/ext/integrations/source_code/repository_url_env_var.phpt +++ b/tests/ext/integrations/source_code/repository_url_env_var.phpt @@ -23,9 +23,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -40,37 +42,36 @@ array(2) { string(26) "repository_url_env_var.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(4) { - ["_dd.git.repository_url"]=> - string(24) "github.com/user/env_repo" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(7) { ["runtime-id"]=> string(%d) "%s" - } - ["metrics"]=> - array(6) { + ["_dd.git.repository_url"]=> + string(24) "github.com/user/env_repo" + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> - float(%d) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) } } [1]=> - array(9) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -87,5 +88,11 @@ array(2) { string(26) "repository_url_env_var.php" ["type"]=> string(3) "cli" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) } } diff --git a/tests/ext/nested_exceptions.phpt b/tests/ext/nested_exceptions.phpt index cf79fb27e80..a764e6822c7 100644 --- a/tests/ext/nested_exceptions.phpt +++ b/tests/ext/nested_exceptions.phpt @@ -18,9 +18,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(11) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -39,10 +41,14 @@ array(1) { string(3) "cli" ["error"]=> int(1) - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(3) { ["error.message"]=> string(%d) "Thrown RuntimeException: Some kind of message in %s:%d" + ["error.type"]=> + string(16) "RuntimeException" ["error.stack"]=> string(%d) "#0 {main} @@ -53,8 +59,6 @@ Stack trace: Next Exception: This is a generic exception message in %s:%d Stack trace: #0 {main}" - ["error.type"]=> - string(16) "RuntimeException" } } } diff --git a/tests/ext/otel_http_response_status_code_remapping.phpt b/tests/ext/otel_http_response_status_code_remapping.phpt index 88b2d3cb5ae..1296f35a4e7 100644 --- a/tests/ext/otel_http_response_status_code_remapping.phpt +++ b/tests/ext/otel_http_response_status_code_remapping.phpt @@ -14,9 +14,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -33,7 +35,9 @@ array(1) { string(44) "otel_http_response_status_code_remapping.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(1) { ["http.status_code"]=> string(3) "300" diff --git a/tests/ext/otel_http_response_status_code_remapping_precedence.phpt b/tests/ext/otel_http_response_status_code_remapping_precedence.phpt index 386ef0492e7..c09495d1dc6 100644 --- a/tests/ext/otel_http_response_status_code_remapping_precedence.phpt +++ b/tests/ext/otel_http_response_status_code_remapping_precedence.phpt @@ -15,9 +15,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -34,7 +36,9 @@ array(1) { string(55) "otel_http_response_status_code_remapping_precedence.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(1) { ["http.status_code"]=> string(3) "300" diff --git a/tests/ext/otel_http_status_code_remapping.phpt b/tests/ext/otel_http_status_code_remapping.phpt index 4b3886711ef..6dff16a4eee 100644 --- a/tests/ext/otel_http_status_code_remapping.phpt +++ b/tests/ext/otel_http_status_code_remapping.phpt @@ -14,9 +14,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -33,7 +35,9 @@ array(1) { string(35) "otel_http_status_code_remapping.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(1) { ["http.status_code"]=> string(3) "200" diff --git a/tests/ext/pcntl/pcntl_fork_long_running_autoflush.phpt b/tests/ext/pcntl/pcntl_fork_long_running_autoflush.phpt index 2431d43fa11..2650487d0bc 100644 --- a/tests/ext/pcntl/pcntl_fork_long_running_autoflush.phpt +++ b/tests/ext/pcntl/pcntl_fork_long_running_autoflush.phpt @@ -53,13 +53,13 @@ function long_running_entry_point() --EXPECTF-- [ddtrace] [warning] [%d] Error loading deferred integration DDTrace\Integrations\Pcntl\PcntlIntegration: Class not loaded and not autoloadable child is enabled -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s [ddtrace] [info] [%d] No finished traces to be sent to the agent parent is enabled -[ddtrace] [info] [%d] Flushing trace of size 3 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 3 to send-queue for %s child is enabled -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s [ddtrace] [info] [%d] No finished traces to be sent to the agent parent is enabled -[ddtrace] [info] [%d] Flushing trace of size 3 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 3 to send-queue for %s [ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/peer_service_disabled_default.phpt b/tests/ext/peer_service_disabled_default.phpt index c4252574948..a1798cd58e5 100644 --- a/tests/ext/peer_service_disabled_default.phpt +++ b/tests/ext/peer_service_disabled_default.phpt @@ -23,9 +23,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -42,14 +44,16 @@ array(1) { string(33) "peer_service_disabled_default.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(3) { ["db.instance"]=> string(3) "db1" - ["foo"]=> - string(3) "bar" ["net.peer.name"]=> string(3) "xyz" + ["foo"]=> + string(3) "bar" } } -} \ No newline at end of file +} diff --git a/tests/ext/peer_service_honor_user_value.phpt b/tests/ext/peer_service_honor_user_value.phpt index 9551bda918c..190ea473483 100644 --- a/tests/ext/peer_service_honor_user_value.phpt +++ b/tests/ext/peer_service_honor_user_value.phpt @@ -29,9 +29,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -48,20 +50,24 @@ array(2) { string(33) "peer_service_honor_user_value.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(3) { - ["_dd.peer.service.source"]=> - string(12) "peer.service" ["db.instance"]=> string(3) "db1" ["peer.service"]=> string(3) "xyz" + ["_dd.peer.service.source"]=> + string(12) "peer.service" } } [1]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -78,14 +84,16 @@ array(2) { string(33) "peer_service_honor_user_value.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(3) { - ["_dd.peer.service.source"]=> - string(12) "peer.service" ["db.instance"]=> string(3) "db1" ["peer.service"]=> string(3) "xyz" + ["_dd.peer.service.source"]=> + string(12) "peer.service" } } -} \ No newline at end of file +} diff --git a/tests/ext/peer_service_remapping.phpt b/tests/ext/peer_service_remapping.phpt index ab7e0e6b5a6..e08f6c2fe6d 100644 --- a/tests/ext/peer_service_remapping.phpt +++ b/tests/ext/peer_service_remapping.phpt @@ -34,9 +34,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -53,26 +55,30 @@ array(2) { string(26) "peer_service_remapping.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(6) { - ["_dd.peer.service.source"]=> - string(12) "peer.service" ["db.instance"]=> string(3) "db1" - ["foo"]=> - string(3) "bar" ["net.peer.name"]=> string(3) "xyz" + ["foo"]=> + string(3) "bar" ["peer.service"]=> string(3) "net" + ["_dd.peer.service.source"]=> + string(12) "peer.service" ["peer.service.remapped_from"]=> string(13) "net.peer.name" } } [1]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -89,20 +95,22 @@ array(2) { string(26) "peer_service_remapping.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(6) { - ["_dd.peer.service.source"]=> - string(11) "db.instance" ["db.instance"]=> string(3) "db1" - ["foo"]=> - string(3) "bar" ["net.peer.name"]=> string(3) "xyz" - ["peer.service"]=> - string(8) "database" + ["foo"]=> + string(3) "bar" + ["_dd.peer.service.source"]=> + string(11) "db.instance" ["peer.service.remapped_from"]=> string(3) "db1" + ["peer.service"]=> + string(8) "database" } } -} \ No newline at end of file +} diff --git a/tests/ext/peer_service_sources_not_serialized_when_set.phpt b/tests/ext/peer_service_sources_not_serialized_when_set.phpt index aa21c183cff..b8d8e270941 100644 --- a/tests/ext/peer_service_sources_not_serialized_when_set.phpt +++ b/tests/ext/peer_service_sources_not_serialized_when_set.phpt @@ -24,9 +24,11 @@ var_dump(dd_clean_spans()); HOOK METHOD arg array(1) { [0]=> - array(9) { + array(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -43,5 +45,7 @@ array(1) { string(48) "peer_service_sources_not_serialized_when_set.php" ["type"]=> string(3) "cli" + ["span_kind"]=> + int(1) } } diff --git a/tests/ext/peer_service_sources_not_serialized_when_unset.phpt b/tests/ext/peer_service_sources_not_serialized_when_unset.phpt index c9b3ea26d3a..05e7673ecc1 100644 --- a/tests/ext/peer_service_sources_not_serialized_when_unset.phpt +++ b/tests/ext/peer_service_sources_not_serialized_when_unset.phpt @@ -23,9 +23,11 @@ var_dump(dd_clean_spans()); HOOK METHOD arg array(1) { [0]=> - array(9) { + array(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -42,5 +44,7 @@ array(1) { string(50) "peer_service_sources_not_serialized_when_unset.php" ["type"]=> string(3) "cli" + ["span_kind"]=> + int(1) } } diff --git a/tests/ext/peer_service_use_first_available_tag.phpt b/tests/ext/peer_service_use_first_available_tag.phpt index 06999a9cc80..5c88dea73f1 100644 --- a/tests/ext/peer_service_use_first_available_tag.phpt +++ b/tests/ext/peer_service_use_first_available_tag.phpt @@ -36,9 +36,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(3) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -55,20 +57,24 @@ array(3) { string(40) "peer_service_use_first_available_tag.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(3) { - ["_dd.peer.service.source"]=> - string(13) "net.peer.name" ["net.peer.name"]=> string(15) "db1.example.com" + ["_dd.peer.service.source"]=> + string(13) "net.peer.name" ["peer.service"]=> string(15) "db1.example.com" } } [1]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -85,22 +91,26 @@ array(3) { string(40) "peer_service_use_first_available_tag.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(4) { - ["_dd.peer.service.source"]=> - string(11) "db.instance" ["db.instance"]=> string(3) "db1" ["net.peer.name"]=> string(15) "db1.example.com" + ["_dd.peer.service.source"]=> + string(11) "db.instance" ["peer.service"]=> string(3) "db1" } } [2]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -117,14 +127,16 @@ array(3) { string(40) "peer_service_use_first_available_tag.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(3) { - ["_dd.peer.service.source"]=> - string(11) "db.instance" ["db.instance"]=> string(3) "db1" + ["_dd.peer.service.source"]=> + string(11) "db.instance" ["peer.service"]=> string(3) "db1" } } -} \ No newline at end of file +} diff --git a/tests/ext/peer_service_wrong_values.phpt b/tests/ext/peer_service_wrong_values.phpt index fda0ae4ec8d..f34b3d9af53 100644 --- a/tests/ext/peer_service_wrong_values.phpt +++ b/tests/ext/peer_service_wrong_values.phpt @@ -29,9 +29,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -48,20 +50,24 @@ array(2) { string(29) "peer_service_wrong_values.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(3) { - ["_dd.peer.service.source"]=> - string(11) "db.instance" ["db.instance"]=> string(8) "only_tag" + ["_dd.peer.service.source"]=> + string(11) "db.instance" ["peer.service"]=> string(8) "only_tag" } } [1]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -78,14 +84,16 @@ array(2) { string(29) "peer_service_wrong_values.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(3) { - ["_dd.peer.service.source"]=> - string(11) "db.instance" ["db.instance"]=> string(3) "foo" + ["_dd.peer.service.source"]=> + string(11) "db.instance" ["peer.service"]=> string(3) "foo" } } -} \ No newline at end of file +} diff --git a/tests/ext/sandbox-prehook/dd_trace_method.phpt b/tests/ext/sandbox-prehook/dd_trace_method.phpt index e7ea5c45418..5406d7c5047 100644 --- a/tests/ext/sandbox-prehook/dd_trace_method.phpt +++ b/tests/ext/sandbox-prehook/dd_trace_method.phpt @@ -95,9 +95,11 @@ array(3) { --- array(3) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -112,43 +114,42 @@ array(3) { string(10) "FooService" ["type"]=> string(7) "FooType" - ["meta"]=> - array(5) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(10) { + ["runtime-id"]=> + string(36) "%s" ["_dd.svc_src"]=> string(1) "m" ["args.0"]=> string(18) "tracing is awesome" - ["runtime-id"]=> - string(36) "%s" - } - ["metrics"]=> - array(8) { - ["_dd.agent_psr"]=> - float(1) - ["_sampling_priority_v1"]=> - float(1) - ["bar"]=> - float(0) + ["process_id"]=> + float(%f) ["foo"]=> float(100) + ["bar"]=> + float(0) + ["_dd.agent_psr"]=> + float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } [1]=> - array(10) { + array(14) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -165,16 +166,24 @@ array(3) { string(10) "FooService" ["type"]=> string(7) "FooType" - ["meta"]=> + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> array(1) { ["rand.range"]=> string(8) "42 - 999" } } [2]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -189,28 +198,25 @@ array(3) { string(19) "dd_trace_method.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(3) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(6) { ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } diff --git a/tests/ext/sandbox-prehook/exception_error_log.phpt b/tests/ext/sandbox-prehook/exception_error_log.phpt index d7aded0ecc8..9b7cb226fa7 100644 --- a/tests/ext/sandbox-prehook/exception_error_log.phpt +++ b/tests/ext/sandbox-prehook/exception_error_log.phpt @@ -15,4 +15,4 @@ var_dump($sum); --EXPECTF-- [ddtrace] [warning] [%d] RuntimeException thrown in ddtrace's closure defined at %s:%d for array_sum(): This exception is expected in %s on line %d int(9) -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s diff --git a/tests/ext/sandbox-regression/class_resolver_bailout_hook.phpt b/tests/ext/sandbox-regression/class_resolver_bailout_hook.phpt index 35251dd8993..b3c7149deb7 100644 --- a/tests/ext/sandbox-regression/class_resolver_bailout_hook.phpt +++ b/tests/ext/sandbox-regression/class_resolver_bailout_hook.phpt @@ -29,4 +29,4 @@ class A extends B {} --EXPECTF-- [ddtrace] [warning] [%d] Error raised in ddtrace's closure defined at %s:%d for x(): No D in %s Leaving Autoloader -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s diff --git a/tests/ext/sandbox-regression/limiter_reset_flush_with_open_spans.phpt b/tests/ext/sandbox-regression/limiter_reset_flush_with_open_spans.phpt index ab6883b1770..48ffd2fc75d 100644 --- a/tests/ext/sandbox-regression/limiter_reset_flush_with_open_spans.phpt +++ b/tests/ext/sandbox-regression/limiter_reset_flush_with_open_spans.phpt @@ -68,7 +68,7 @@ baz() called bar() called string(28) "current :2513787319205155662" string(28) "closing :2513787319205155662" -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s string(34) "newly active :13874630024467741450" string(28) "initial :1735254072534978428" string(29) "started :10598951352238613536" @@ -78,7 +78,7 @@ baz() called bar() called string(29) "current :10598951352238613536" string(29) "closing :10598951352238613536" -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s string(33) "newly active :1735254072534978428" string(28) "initial :5052085463162682550" string(28) "started :7199227068870524257" @@ -88,8 +88,8 @@ baz() called bar() called string(28) "current :7199227068870524257" string(28) "closing :7199227068870524257" -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s string(33) "newly active :5052085463162682550" foo() called -[ddtrace] [info] [%d] Flushing trace of size 5 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 5 to send-queue for %s [ddtrace] [info] [%d] No finished traces to be sent to the agent \ No newline at end of file diff --git a/tests/ext/sandbox-regression/nested_dropped_spans.phpt b/tests/ext/sandbox-regression/nested_dropped_spans.phpt index 8a52ce75161..bdf7cc982be 100644 --- a/tests/ext/sandbox-regression/nested_dropped_spans.phpt +++ b/tests/ext/sandbox-regression/nested_dropped_spans.phpt @@ -30,7 +30,5 @@ dd_dump_spans(); --EXPECTF-- spans(\DDTrace\SpanData) (1) { root span (nested_dropped_spans.php, root span, cli) - _dd.p.dm => -0 - _dd.p.tid => %s inner span (nested_dropped_spans.php, inner span, cli) } diff --git a/tests/ext/sandbox/auto_flush.phpt b/tests/ext/sandbox/auto_flush.phpt index 146c5f22bba..3c95454513c 100644 --- a/tests/ext/sandbox/auto_flush.phpt +++ b/tests/ext/sandbox/auto_flush.phpt @@ -32,14 +32,14 @@ echo PHP_EOL; --EXPECTF-- 3 6 -[ddtrace] [info] [%d] Flushing trace of size 3 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 3 to send-queue for %s 10 15 -[ddtrace] [info] [%d] Flushing trace of size 3 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 3 to send-queue for %s 21 28 -[ddtrace] [info] [%d] Flushing trace of size 3 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 3 to send-queue for %s [ddtrace] [info] [%d] No finished traces to be sent to the agent \ No newline at end of file diff --git a/tests/ext/sandbox/auto_flush_attach_exception.phpt b/tests/ext/sandbox/auto_flush_attach_exception.phpt index 762675d7d3a..cb8ca1e7d8d 100644 --- a/tests/ext/sandbox/auto_flush_attach_exception.phpt +++ b/tests/ext/sandbox/auto_flush_attach_exception.phpt @@ -34,5 +34,5 @@ try { ?> --EXPECTF-- Caught exception: Oops! -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s [ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/sandbox/auto_flush_disables_tracing.phpt b/tests/ext/sandbox/auto_flush_disables_tracing.phpt index 33a1771d804..ae0edd7b6c1 100644 --- a/tests/ext/sandbox/auto_flush_disables_tracing.phpt +++ b/tests/ext/sandbox/auto_flush_disables_tracing.phpt @@ -37,14 +37,14 @@ echo PHP_EOL; --EXPECTF-- 3 6 -[ddtrace] [info] [%d] Flushing trace of size 3 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 3 to send-queue for %s 10 15 -[ddtrace] [info] [%d] Flushing trace of size 3 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 3 to send-queue for %s 21 28 -[ddtrace] [info] [%d] Flushing trace of size 3 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 3 to send-queue for %s [ddtrace] [info] [%d] No finished traces to be sent to the agent \ No newline at end of file diff --git a/tests/ext/sandbox/auto_flush_sandbox_exception.phpt b/tests/ext/sandbox/auto_flush_sandbox_exception.phpt index d74f8562373..3bd840abccb 100644 --- a/tests/ext/sandbox/auto_flush_sandbox_exception.phpt +++ b/tests/ext/sandbox/auto_flush_sandbox_exception.phpt @@ -32,6 +32,6 @@ try { } ?> --EXPECTF-- -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s Caught exception: Oops! [ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/sandbox/auto_flush_userland_root_span.phpt b/tests/ext/sandbox/auto_flush_userland_root_span.phpt index 07812fc0cdd..3a43828a1eb 100644 --- a/tests/ext/sandbox/auto_flush_userland_root_span.phpt +++ b/tests/ext/sandbox/auto_flush_userland_root_span.phpt @@ -32,16 +32,16 @@ echo PHP_EOL; 3 6 Has not flushed yet. -[ddtrace] [info] [%d] Flushing trace of size 3 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 3 to send-queue for %s 10 15 Has not flushed yet. -[ddtrace] [info] [%d] Flushing trace of size 3 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 3 to send-queue for %s 21 28 Has not flushed yet. -[ddtrace] [info] [%d] Flushing trace of size 3 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 3 to send-queue for %s [ddtrace] [info] [%d] No finished traces to be sent to the agent \ No newline at end of file diff --git a/tests/ext/sandbox/dd_dumper.inc b/tests/ext/sandbox/dd_dumper.inc index 9558dac9080..48d3cd71f26 100644 --- a/tests/ext/sandbox/dd_dumper.inc +++ b/tests/ext/sandbox/dd_dumper.inc @@ -31,17 +31,23 @@ function dd_dump_spans($skipMeta = false) if (!empty($values)) { echo ' (' . implode(', ', $values) . ')'; } - if (isset($span['meta']['error.message'])) { - echo ' (error: ' . $span['meta']['error.message'] . ')'; + if (isset($span['attributes']['error.message'])) { + echo ' (error: ' . $span['attributes']['error.message'] . ')'; } - if (isset($span['meta'])) { + if (isset($span['attributes'])) { if ($skipMeta) { - unset($span['meta']['_dd.p.dm']); + unset($span['attributes']['_dd.p.dm']); } echo PHP_EOL; - unset($span["meta"]["runtime-id"]); - unset($span["meta"]["_dd.tags.process"]); - foreach ($span['meta'] as $k => $v) { + unset($span["attributes"]["runtime-id"]); + unset($span["attributes"]["_dd.tags.process"]); + // The v1 introspection shape merges the old meta (strings) and metrics + // (numbers) into a single attributes map. This dumper historically showed + // only string meta, so keep string-valued attributes to preserve its view. + foreach ($span['attributes'] as $k => $v) { + if (!is_string($v)) { + continue; + } echo str_repeat(' ', $indent) . ' ' . $k . ' => ' . $v . PHP_EOL; } } else { @@ -80,10 +86,10 @@ function dd_dump_spans($skipMeta = false) function dd_clean_spans() { $spans = dd_trace_serialize_closed_spans(); foreach ($spans as &$span) { - if (isset($span['meta'])) { - unset($span['meta']['_dd.tags.process']); - if (empty($span['meta'])) { - unset($span['meta']); + if (isset($span['attributes'])) { + unset($span['attributes']['_dd.tags.process']); + if (empty($span['attributes'])) { + unset($span['attributes']); } } } diff --git a/tests/ext/sandbox/dd_trace_function_alias.phpt b/tests/ext/sandbox/dd_trace_function_alias.phpt index c1930fcd475..3e93ca1402c 100644 --- a/tests/ext/sandbox/dd_trace_function_alias.phpt +++ b/tests/ext/sandbox/dd_trace_function_alias.phpt @@ -27,7 +27,5 @@ dd_dump_spans(); bar(hello) spans(\DDTrace\SpanData) (1) { bar (alias, bar, cli) - _dd.p.dm => -0 - _dd.p.tid => %s _dd.svc_src => m } diff --git a/tests/ext/sandbox/dd_trace_function_complex.phpt b/tests/ext/sandbox/dd_trace_function_complex.phpt index 2de41a7c64c..503e5b1631b 100644 --- a/tests/ext/sandbox/dd_trace_function_complex.phpt +++ b/tests/ext/sandbox/dd_trace_function_complex.phpt @@ -96,9 +96,11 @@ array(3) { --- array(5) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -113,49 +115,48 @@ array(5) { string(10) "BarService" ["type"]=> string(7) "BarType" - ["meta"]=> - array(8) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(13) { + ["runtime-id"]=> + string(36) "%s" ["_dd.svc_src"]=> string(1) "m" ["args.0"]=> string(18) "tracing is awesome" + ["retval.thoughts"]=> + string(18) "tracing is awesome" ["retval.first"]=> string(5) "first" ["retval.rand"]=> string(%d) "%d" - ["retval.thoughts"]=> - string(18) "tracing is awesome" - ["runtime-id"]=> - string(36) "%s" - } - ["metrics"]=> - array(8) { - ["_dd.agent_psr"]=> - float(1) - ["_sampling_priority_v1"]=> - float(1) - ["bar"]=> - float(25) + ["process_id"]=> + float(%f) ["foo"]=> float(1.2) + ["bar"]=> + float(25) + ["_dd.agent_psr"]=> + float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } [1]=> - array(10) { + array(14) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -172,16 +173,24 @@ array(5) { string(29) "dd_trace_function_complex.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> array(1) { ["_dd.base_service"]=> string(10) "BarService" } } [2]=> - array(10) { + array(14) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -198,16 +207,24 @@ array(5) { string(29) "dd_trace_function_complex.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> array(1) { ["_dd.base_service"]=> string(10) "BarService" } } [3]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -222,35 +239,34 @@ array(5) { string(29) "dd_trace_function_complex.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(3) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(6) { ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } [4]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -265,28 +281,25 @@ array(5) { string(29) "dd_trace_function_complex.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(3) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(6) { ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } diff --git a/tests/ext/sandbox/dd_trace_function_internal.phpt b/tests/ext/sandbox/dd_trace_function_internal.phpt index f7af2063f72..7681f4f006f 100644 --- a/tests/ext/sandbox/dd_trace_function_internal.phpt +++ b/tests/ext/sandbox/dd_trace_function_internal.phpt @@ -27,9 +27,11 @@ int(9) --- array(1) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -44,28 +46,25 @@ array(1) { string(30) "dd_trace_function_internal.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(3) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(6) { ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } diff --git a/tests/ext/sandbox/dd_trace_function_userland.phpt b/tests/ext/sandbox/dd_trace_function_userland.phpt index 4995090b888..c3fd652a124 100644 --- a/tests/ext/sandbox/dd_trace_function_userland.phpt +++ b/tests/ext/sandbox/dd_trace_function_userland.phpt @@ -39,9 +39,11 @@ array ( --- array(1) { [0]=> - array(9) { + array(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -58,6 +60,8 @@ array(1) { string(30) "dd_trace_function_userland.php" ["type"]=> string(3) "cli" + ["span_kind"]=> + int(1) } } array(0) { diff --git a/tests/ext/sandbox/dd_trace_method.phpt b/tests/ext/sandbox/dd_trace_method.phpt index 16762177c00..65b4a1a2f72 100644 --- a/tests/ext/sandbox/dd_trace_method.phpt +++ b/tests/ext/sandbox/dd_trace_method.phpt @@ -104,9 +104,11 @@ array(3) { --- array(3) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -121,49 +123,48 @@ array(3) { string(10) "FooService" ["type"]=> string(7) "FooType" - ["meta"]=> - array(8) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(13) { + ["runtime-id"]=> + string(36) "%s" ["_dd.svc_src"]=> string(1) "m" ["args.0"]=> string(18) "tracing is awesome" + ["retval.thoughts"]=> + string(18) "tracing is awesome" ["retval.first"]=> string(5) "first" ["retval.rand"]=> string(%d) "%d" - ["retval.thoughts"]=> - string(18) "tracing is awesome" - ["runtime-id"]=> - string(36) "%s" - } - ["metrics"]=> - array(8) { - ["_dd.agent_psr"]=> - float(1) - ["_sampling_priority_v1"]=> - float(1) - ["bar"]=> - float(0) + ["process_id"]=> + float(%f) ["foo"]=> float(100) + ["bar"]=> + float(0) + ["_dd.agent_psr"]=> + float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } [1]=> - array(10) { + array(14) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -180,20 +181,28 @@ array(3) { string(19) "dd_trace_method.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> array(3) { - ["_dd.base_service"]=> - string(10) "FooService" ["rand.range"]=> string(8) "42 - 999" ["rand.value"]=> string(%d) "%d" + ["_dd.base_service"]=> + string(10) "FooService" } } [2]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -208,28 +217,25 @@ array(3) { string(19) "dd_trace_method.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(3) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(6) { ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } diff --git a/tests/ext/sandbox/dd_trace_method_alias.phpt b/tests/ext/sandbox/dd_trace_method_alias.phpt index 931b038444a..66a074eed7b 100644 --- a/tests/ext/sandbox/dd_trace_method_alias.phpt +++ b/tests/ext/sandbox/dd_trace_method_alias.phpt @@ -31,7 +31,5 @@ dd_dump_spans(); Foo::bar(hello) spans(\DDTrace\SpanData) (1) { Foo.bar (alias, Foo.bar, cli) - _dd.p.dm => -0 - _dd.p.tid => %s _dd.svc_src => m } diff --git a/tests/ext/sandbox/default_span_properties.phpt b/tests/ext/sandbox/default_span_properties.phpt index 47ff97370f6..a2ff04faf69 100644 --- a/tests/ext/sandbox/default_span_properties.phpt +++ b/tests/ext/sandbox/default_span_properties.phpt @@ -35,15 +35,13 @@ dd_dump_spans(); 28 spans(\DDTrace\SpanData) (1) { main (default_span_properties.php, main, cli) + max => 6 + _dd.code_origin.type => entry _dd.code_origin.frames.0.file => %sdefault_span_properties.php _dd.code_origin.frames.0.line => 16 _dd.code_origin.frames.0.method => main _dd.code_origin.frames.1.file => %sdefault_span_properties.php _dd.code_origin.frames.1.line => 21 - _dd.code_origin.type => entry - _dd.p.dm => -0 - _dd.p.tid => %s - max => 6 MyRange (default_span_properties.php, MyRange, cli) array_sum (default_span_properties.php, array_sum, cli) retval => 21 diff --git a/tests/ext/sandbox/default_span_properties_method.phpt b/tests/ext/sandbox/default_span_properties_method.phpt index 0fd4226144a..0a63f431dde 100644 --- a/tests/ext/sandbox/default_span_properties_method.phpt +++ b/tests/ext/sandbox/default_span_properties_method.phpt @@ -43,8 +43,6 @@ dd_dump_spans(); 06 spans(\DDTrace\SpanData) (1) { Foo.main (default_span_properties_method.php, Foo.main, cli) - _dd.p.dm => -0 - _dd.p.tid => %s year => 2020 DateTime.__construct (default_span_properties_method.php, DateTime.__construct, cli) date => 2020-06-15 diff --git a/tests/ext/sandbox/deferred_load_attempt_loading_once.phpt b/tests/ext/sandbox/deferred_load_attempt_loading_once.phpt index 1d2c442da52..0048f1e73b2 100644 --- a/tests/ext/sandbox/deferred_load_attempt_loading_once.phpt +++ b/tests/ext/sandbox/deferred_load_attempt_loading_once.phpt @@ -37,4 +37,4 @@ namespace autoload_attempted PUBLIC STATIC METHOD PUBLIC STATIC METHOD -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/errors_are_flagged_from_userland.phpt b/tests/ext/sandbox/errors_are_flagged_from_userland.phpt index 9839c6dc576..893b3c10d6f 100644 --- a/tests/ext/sandbox/errors_are_flagged_from_userland.phpt +++ b/tests/ext/sandbox/errors_are_flagged_from_userland.phpt @@ -27,9 +27,11 @@ var_dump(dd_clean_spans()); testErrorFromUserland() array(1) { [0]=> - array(11) { + array(14) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -46,30 +48,27 @@ array(1) { string(3) "cli" ["error"]=> int(1) - ["meta"]=> - array(4) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["error.message"]=> - string(9) "Foo error" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(7) { ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["error.message"]=> + string(9) "Foo error" + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } diff --git a/tests/ext/sandbox/exception_error_log.phpt b/tests/ext/sandbox/exception_error_log.phpt index 6da3f0d707e..c86e8a636cd 100644 --- a/tests/ext/sandbox/exception_error_log.phpt +++ b/tests/ext/sandbox/exception_error_log.phpt @@ -15,4 +15,4 @@ var_dump($sum); --EXPECTF-- [ddtrace] [warning] [%d] RuntimeException thrown in ddtrace's closure defined at %s:%d for array_sum(): This exception is expected in %s on line %d int(9) -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s diff --git a/tests/ext/sandbox/hook_function/03.phpt b/tests/ext/sandbox/hook_function/03.phpt index bc2bc069910..14886e2aebb 100644 --- a/tests/ext/sandbox/hook_function/03.phpt +++ b/tests/ext/sandbox/hook_function/03.phpt @@ -20,4 +20,4 @@ greet('Datadog'); [ddtrace] [warning] [%d] DDTrace\hook_function was given neither prehook nor posthook in %s on line %d; This message is only displayed once. Specify DD_TRACE_ONCE_LOGS=0 to show all messages. bool(false) Hello, Datadog. -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/hook_function/hook_does_not_leak_error.phpt b/tests/ext/sandbox/hook_function/hook_does_not_leak_error.phpt index cd26d5d5238..519039c3cb9 100644 --- a/tests/ext/sandbox/hook_function/hook_does_not_leak_error.phpt +++ b/tests/ext/sandbox/hook_function/hook_does_not_leak_error.phpt @@ -33,4 +33,4 @@ foo int(200) foo [ddtrace] [warning] [%d] Error raised in ddtrace's closure defined at %s:%d for foo(): Fatal in %s on line %d -[ddtrace] [info] [%d] Flushing trace of size %s +[ddtrace] [info] [%d] Flushing v1 trace of size %s diff --git a/tests/ext/sandbox/hook_function/posthook_error_02.phpt b/tests/ext/sandbox/hook_function/posthook_error_02.phpt index ebc2ecd55a7..84b2afd37d2 100644 --- a/tests/ext/sandbox/hook_function/posthook_error_02.phpt +++ b/tests/ext/sandbox/hook_function/posthook_error_02.phpt @@ -28,4 +28,4 @@ greet('Datadog'); Hello, Datadog. greet hooked. [ddtrace] [warning] [%d] %s in ddtrace's closure defined at %s:%d for greet(): Undefined variable%sthis_normally_raises_an_%s -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/hook_function/posthook_exceptions_04.phpt b/tests/ext/sandbox/hook_function/posthook_exceptions_04.phpt index 1b345fcfde8..399b3e5910c 100644 --- a/tests/ext/sandbox/hook_function/posthook_exceptions_04.phpt +++ b/tests/ext/sandbox/hook_function/posthook_exceptions_04.phpt @@ -32,4 +32,4 @@ try { array_sum hooked. [ddtrace] [warning] [%d] Exception thrown in ddtrace's closure defined at %s:%d for array_sum(): ! in %s on line %d Sum = 4. -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/hook_function/prehook_error_02.phpt b/tests/ext/sandbox/hook_function/prehook_error_02.phpt index 5b07a34fea6..2b4533a6bf8 100644 --- a/tests/ext/sandbox/hook_function/prehook_error_02.phpt +++ b/tests/ext/sandbox/hook_function/prehook_error_02.phpt @@ -27,4 +27,4 @@ greet('Datadog'); greet hooked. [ddtrace] [warning] [%d] %s in ddtrace's closure defined at %s:%d for greet(): Undefined variable%sthis_normally_raises_an_%s Hello, Datadog. -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/hook_function/prehook_exceptions_02.phpt b/tests/ext/sandbox/hook_function/prehook_exceptions_02.phpt index c4eca6d7586..028ed204988 100644 --- a/tests/ext/sandbox/hook_function/prehook_exceptions_02.phpt +++ b/tests/ext/sandbox/hook_function/prehook_exceptions_02.phpt @@ -35,4 +35,4 @@ greet hooked. [ddtrace] [warning] [%d] Exception thrown in ddtrace's closure defined at %s:%d for greet(): ! in %s on line %d Hello, Datadog. Done. -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/hook_function/prehook_exceptions_04.phpt b/tests/ext/sandbox/hook_function/prehook_exceptions_04.phpt index b643afd6661..18096f11ffc 100644 --- a/tests/ext/sandbox/hook_function/prehook_exceptions_04.phpt +++ b/tests/ext/sandbox/hook_function/prehook_exceptions_04.phpt @@ -30,4 +30,4 @@ try { array_sum hooked. [ddtrace] [warning] [%d] Exception thrown in ddtrace's closure defined at %s:%d for array_sum(): ! in %s on line %d Sum = 4. -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/hook_method/03.phpt b/tests/ext/sandbox/hook_method/03.phpt index 2f47e493ca9..82657699976 100644 --- a/tests/ext/sandbox/hook_method/03.phpt +++ b/tests/ext/sandbox/hook_method/03.phpt @@ -23,4 +23,4 @@ Greeter::greet('Datadog'); [ddtrace] [warning] [%d] DDTrace\hook_method was given neither prehook nor posthook in %s on line %d; This message is only displayed once. Specify DD_TRACE_ONCE_LOGS=0 to show all messages. bool(false) Hello, Datadog. -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/hook_method/posthook_07.phpt b/tests/ext/sandbox/hook_method/posthook_07.phpt index aa1f72f0bb2..ca4e45c2274 100644 --- a/tests/ext/sandbox/hook_method/posthook_07.phpt +++ b/tests/ext/sandbox/hook_method/posthook_07.phpt @@ -57,4 +57,4 @@ $app->run(); App::__construct hooked. App::run App::run traced. -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s diff --git a/tests/ext/sandbox/hook_method/posthook_error_02.phpt b/tests/ext/sandbox/hook_method/posthook_error_02.phpt index b206252922a..c6edb3f1572 100644 --- a/tests/ext/sandbox/hook_method/posthook_error_02.phpt +++ b/tests/ext/sandbox/hook_method/posthook_error_02.phpt @@ -31,4 +31,4 @@ Greeter::greet('Datadog'); Hello, Datadog. Greeter::greet hooked. [ddtrace] [warning] [%d] %s in ddtrace's closure defined at %s:%d for Greeter::greet(): Undefined variable%sthis_normally_raises_an_%s -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/hook_method/prehook_error_02.phpt b/tests/ext/sandbox/hook_method/prehook_error_02.phpt index 8560f29d75b..4e8163a710a 100644 --- a/tests/ext/sandbox/hook_method/prehook_error_02.phpt +++ b/tests/ext/sandbox/hook_method/prehook_error_02.phpt @@ -31,4 +31,4 @@ Greeter::greet('Datadog'); Greeter::greet hooked. [ddtrace] [warning] [%d] %s in ddtrace's closure defined at %s:%d for Greeter::greet(): Undefined variable%sthis_normally_raises_an_%s Hello, Datadog. -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/hook_method/prehook_exceptions_02.phpt b/tests/ext/sandbox/hook_method/prehook_exceptions_02.phpt index cad41da9e1b..44ce172c86a 100644 --- a/tests/ext/sandbox/hook_method/prehook_exceptions_02.phpt +++ b/tests/ext/sandbox/hook_method/prehook_exceptions_02.phpt @@ -36,4 +36,4 @@ Greeter::greet hooked. [ddtrace] [warning] [%d] Exception thrown in ddtrace's closure defined at %s:%d for Greeter::greet(): ! in %s on line %d Hello, Datadog. Done. -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/install_hook/hook_scoped_file.phpt b/tests/ext/sandbox/install_hook/hook_scoped_file.phpt index f2936e1074a..c2e0695a6ae 100644 --- a/tests/ext/sandbox/install_hook/hook_scoped_file.phpt +++ b/tests/ext/sandbox/install_hook/hook_scoped_file.phpt @@ -32,7 +32,5 @@ dd_dump_spans(); test spans(\DDTrace\SpanData) (1) { A.include (hook_scoped_file.php, A.include, cli) - _dd.p.dm => -0 - _dd.p.tid => %s %stestinclude.inc (hook_scoped_file.php, %stestinclude.inc, cli) } diff --git a/tests/ext/sandbox/install_hook/trace_callable.phpt b/tests/ext/sandbox/install_hook/trace_callable.phpt index 805ebd8bd44..d4002c46ebc 100644 --- a/tests/ext/sandbox/install_hook/trace_callable.phpt +++ b/tests/ext/sandbox/install_hook/trace_callable.phpt @@ -63,13 +63,10 @@ include __DIR__ . '/../dd_dumper.inc'; --EXPECTF-- spans(\DDTrace\SpanData) (3) { test\foo (trace_callable.php, 0, cli) - _dd.p.tid => %s result => 1 test\bar.foo (trace_callable.php, 1, cli) - _dd.p.tid => %s result => 2 test\closure.{closure} (trace_callable.php, 2, cli) - _dd.p.tid => %s closure.declaration => %s:%d result => 3 } diff --git a/tests/ext/sandbox/install_hook/trace_closure.phpt b/tests/ext/sandbox/install_hook/trace_closure.phpt index 671c9ddb026..c0dcede6bed 100644 --- a/tests/ext/sandbox/install_hook/trace_closure.phpt +++ b/tests/ext/sandbox/install_hook/trace_closure.phpt @@ -72,33 +72,25 @@ include __DIR__ . '/../dd_dumper.inc'; --EXPECTF-- spans(\DDTrace\SpanData) (8) { intval (trace_closure.php, 0, cli) - _dd.p.tid => %s result => 0 test\trace_closure.php:7\{%s} (trace_closure.php, 1, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure.php:7 result => 1 test\foo.{closure} (trace_closure.php, 2, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure.php:12 result => 2 test\bar.foo.{closure} (trace_closure.php, 3, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure.php:19 result => 3 intval (trace_closure.php, 0, cli) - _dd.p.tid => %s result => 1 test\trace_closure.php:7\{%s} (trace_closure.php, 1, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure.php:7 result => 2 test\foo.{closure} (trace_closure.php, 2, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure.php:12 result => 3 test\bar.foo.{closure} (trace_closure.php, 3, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure.php:19 result => 4 } diff --git a/tests/ext/sandbox/install_hook/trace_closure_from_callable.phpt b/tests/ext/sandbox/install_hook/trace_closure_from_callable.phpt index 079728fa30a..ff5f05b47a7 100644 --- a/tests/ext/sandbox/install_hook/trace_closure_from_callable.phpt +++ b/tests/ext/sandbox/install_hook/trace_closure_from_callable.phpt @@ -37,16 +37,12 @@ include __DIR__ . '/../dd_dumper.inc'; --EXPECTF-- spans(\DDTrace\SpanData) (4) { foo (trace_closure_from_callable.php, foo, cli) - _dd.p.tid => %s global => 1 foo (trace_closure_from_callable.php, foo, cli) - _dd.p.tid => %s - fake => 1 global => 1 + fake => 1 foo (trace_closure_from_callable.php, foo, cli) - _dd.p.tid => %s global => 1 foo (trace_closure_from_callable.php, foo, cli) - _dd.p.tid => %s global => 1 } diff --git a/tests/ext/sandbox/install_hook/trace_file.phpt b/tests/ext/sandbox/install_hook/trace_file.phpt index 382f4531e42..101c89ad005 100644 --- a/tests/ext/sandbox/install_hook/trace_file.phpt +++ b/tests/ext/sandbox/install_hook/trace_file.phpt @@ -25,9 +25,5 @@ test test spans(\DDTrace\SpanData) (2) { %stestinclude.inc (trace_file.php, %sinstall_hook%ctestinclude.inc, cli) - _dd.p.dm => -0 - _dd.p.tid => %s %stestinclude.inc (trace_file.php, %sinstall_hook%ctestinclude.inc, cli) - _dd.p.dm => -0 - _dd.p.tid => %s } diff --git a/tests/ext/sandbox/install_hook/trace_function.phpt b/tests/ext/sandbox/install_hook/trace_function.phpt index 664e0a6494a..ac8e4cb34ab 100644 --- a/tests/ext/sandbox/install_hook/trace_function.phpt +++ b/tests/ext/sandbox/install_hook/trace_function.phpt @@ -49,9 +49,7 @@ include __DIR__ . '/../dd_dumper.inc'; --EXPECTF-- spans(\DDTrace\SpanData) (2) { test\foo (trace_function.php, 0, cli) - _dd.p.tid => %s result => 1 test\bar.foo (trace_function.php, 1, cli) - _dd.p.tid => %s result => 2 } diff --git a/tests/ext/sandbox/install_hook/trace_generator.phpt b/tests/ext/sandbox/install_hook/trace_generator.phpt index d1223a0204c..b9fd082052f 100644 --- a/tests/ext/sandbox/install_hook/trace_generator.phpt +++ b/tests/ext/sandbox/install_hook/trace_generator.phpt @@ -39,7 +39,6 @@ include __DIR__ . '/../dd_dumper.inc'; --EXPECTF-- spans(\DDTrace\SpanData) (1) { test\trace_generator.php:%d\{%s} (trace_generator.php, test\trace_generator.php:%d\{%s}, cli) - _dd.p.tid => %s closure.declaration => %s:%d result => 3 (trace_generator.php, cli) diff --git a/tests/ext/sandbox/manual_flush.phpt b/tests/ext/sandbox/manual_flush.phpt index ba000554ff8..ff6ad4d6320 100644 --- a/tests/ext/sandbox/manual_flush.phpt +++ b/tests/ext/sandbox/manual_flush.phpt @@ -21,5 +21,5 @@ main(); ?> --EXPECTF-- -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 1 to send-queue for %s diff --git a/tests/ext/sandbox/retval_is_null_with_exception.phpt b/tests/ext/sandbox/retval_is_null_with_exception.phpt index be69b90dbb6..50cf0c568b7 100644 --- a/tests/ext/sandbox/retval_is_null_with_exception.phpt +++ b/tests/ext/sandbox/retval_is_null_with_exception.phpt @@ -31,4 +31,4 @@ try { bool(true) NULL Oops! -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s diff --git a/tests/ext/sandbox/safe_to_string_metadata_drops_invalid_keys.phpt b/tests/ext/sandbox/safe_to_string_metadata_drops_invalid_keys.phpt index db07b28e3a9..900eb8dc58f 100644 --- a/tests/ext/sandbox/safe_to_string_metadata_drops_invalid_keys.phpt +++ b/tests/ext/sandbox/safe_to_string_metadata_drops_invalid_keys.phpt @@ -20,8 +20,8 @@ DDTrace\trace_function('meta_to_string', function (SpanData $span) { meta_to_string(); list($span) = dd_clean_spans(); -unset($span['meta']['process_id']); -var_dump($span['meta']); +unset($span['attributes']['process_id']); +var_dump($span['attributes']); ?> --EXPECT-- array(2) { diff --git a/tests/ext/sandbox/span_clone.phpt b/tests/ext/sandbox/span_clone.phpt index 0afae2b4bd9..99cacbb7547 100644 --- a/tests/ext/sandbox/span_clone.phpt +++ b/tests/ext/sandbox/span_clone.phpt @@ -297,9 +297,11 @@ object(DDTrace\RootSpanData)#%d (29) { } array(1) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -314,28 +316,25 @@ array(1) { string(14) "span_clone.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(3) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(6) { ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } diff --git a/tests/ext/sandbox/static_tracing_closures_will_not_bind_this.phpt b/tests/ext/sandbox/static_tracing_closures_will_not_bind_this.phpt index a7061957653..07d092f1c08 100644 --- a/tests/ext/sandbox/static_tracing_closures_will_not_bind_this.phpt +++ b/tests/ext/sandbox/static_tracing_closures_will_not_bind_this.phpt @@ -25,4 +25,4 @@ $foo->test(); --EXPECTF-- Foo::test() TRACED Foo::test() -[ddtrace] [info] [%d] Flushing trace of size 2 to send-queue for %s +[ddtrace] [info] [%d] Flushing v1 trace of size 2 to send-queue for %s diff --git a/tests/ext/span_stack/span_stack_clone.phpt b/tests/ext/span_stack/span_stack_clone.phpt index 0fac818cd88..09fb6a70892 100644 --- a/tests/ext/span_stack/span_stack_clone.phpt +++ b/tests/ext/span_stack/span_stack_clone.phpt @@ -53,18 +53,8 @@ A clone of the primary trace has the root stack as parent: bool(true) Switching to an initial stacks parent has no effect: bool(true) spans(\DDTrace\SpanData) (5) { primary (span_stack_clone.php, primary, cli) - _dd.p.dm => -0 - _dd.p.tid => %s root (span_stack_clone.php, root, cli) - _dd.p.dm => -0 - _dd.p.tid => %s root clone (span_stack_clone.php, root clone, cli) - _dd.p.dm => -0 - _dd.p.tid => %s primary clone (span_stack_clone.php, primary clone, cli) - _dd.p.dm => -0 - _dd.p.tid => %s initial clone (span_stack_clone.php, initial clone, cli) - _dd.p.dm => -0 - _dd.p.tid => %s } diff --git a/tests/ext/span_stack/span_stack_swap.phpt b/tests/ext/span_stack/span_stack_swap.phpt index 6265967c55a..13583bca433 100644 --- a/tests/ext/span_stack/span_stack_swap.phpt +++ b/tests/ext/span_stack/span_stack_swap.phpt @@ -81,12 +81,8 @@ But we can still swap to stacks started before that: bool(true) We closed the active stack after all other stacks were closed. No other span is active right now: bool(true) spans(\DDTrace\SpanData) (2) { span_stack_swap.php (span_stack_swap.php, span_stack_swap.php, cli) - _dd.p.dm => -0 - _dd.p.tid => %s (span_stack_swap.php, cli) (span_stack_swap.php, cli) (span_stack_swap.php, cli) other root (span_stack_swap.php, other root, cli) - _dd.p.dm => -0 - _dd.p.tid => %s } diff --git a/tests/ext/span_stack/span_stack_swap_traced_function.phpt b/tests/ext/span_stack/span_stack_swap_traced_function.phpt index 8906df1d6ca..45bb78d1a16 100644 --- a/tests/ext/span_stack/span_stack_swap_traced_function.phpt +++ b/tests/ext/span_stack/span_stack_swap_traced_function.phpt @@ -59,8 +59,6 @@ Now, we have explicitly closed it: bool(true) We closed the active stack after all other stacks were closed. No other span is active right now: bool(true) spans(\DDTrace\SpanData) (1) { span_stack_swap_traced_function.php (span_stack_swap_traced_function.php, span_stack_swap_traced_function.php, cli) - _dd.p.dm => -0 - _dd.p.tid => %s outer (span_stack_swap_traced_function.php, outer, cli) creates_span_stack (span_stack_swap_traced_function.php, creates_span_stack, cli) inner (span_stack_swap_traced_function.php, inner, cli) diff --git a/tests/ext/span_stack/span_trace_stack_autoclose.phpt b/tests/ext/span_stack/span_trace_stack_autoclose.phpt index 92283b61b4e..03a54c0d0e6 100644 --- a/tests/ext/span_stack/span_trace_stack_autoclose.phpt +++ b/tests/ext/span_stack/span_trace_stack_autoclose.phpt @@ -36,7 +36,5 @@ We are back on our primary stack: bool(true) Having lost all references to the that span stacks objects, it is autoclosed: bool(true) spans(\DDTrace\SpanData) (1) { span_trace_stack_autoclose.php (span_trace_stack_autoclose.php, span_trace_stack_autoclose.php, cli) - _dd.p.dm => -0 - _dd.p.tid => %s (span_trace_stack_autoclose.php, cli) } diff --git a/tests/ext/span_stack/span_trace_swap.phpt b/tests/ext/span_stack/span_trace_swap.phpt index c7378ee6337..8d584b80cfa 100644 --- a/tests/ext/span_stack/span_trace_swap.phpt +++ b/tests/ext/span_stack/span_trace_swap.phpt @@ -42,9 +42,5 @@ We closed the active stack after all other stacks were closed. No other span is This automatically switches back to the parent stack: bool(true) spans(\DDTrace\SpanData) (2) { span_trace_swap.php (span_trace_swap.php, span_trace_swap.php, cli) - _dd.p.dm => -0 - _dd.p.tid => %s other root (span_trace_swap.php, other root, cli) - _dd.p.dm => -0 - _dd.p.tid => %s } diff --git a/tests/ext/span_stack/start_span_new_trace.phpt b/tests/ext/span_stack/start_span_new_trace.phpt index 8975ff2d70d..12eb653bd3a 100644 --- a/tests/ext/span_stack/start_span_new_trace.phpt +++ b/tests/ext/span_stack/start_span_new_trace.phpt @@ -61,12 +61,8 @@ After closing the trace root, we swap back to the previously active stack: bool( With the trace root also accordingly updated: bool(true) spans(\DDTrace\SpanData) (2) { start_span_new_trace.php (start_span_new_trace.php, start_span_new_trace.php, cli) - _dd.p.dm => -0 - _dd.p.tid => %s (start_span_new_trace.php, cli) (start_span_new_trace.php, cli) other root (start_span_new_trace.php, other root, cli) - _dd.p.dm => -0 - _dd.p.tid => %s (start_span_new_trace.php, cli) } diff --git a/tests/ext/span_stack/start_span_stack.phpt b/tests/ext/span_stack/start_span_stack.phpt index 39ee073d445..77a08041bb2 100644 --- a/tests/ext/span_stack/start_span_stack.phpt +++ b/tests/ext/span_stack/start_span_stack.phpt @@ -55,8 +55,6 @@ Active stack is swapped back when a span below the current span stack is closed: The stack still retains its direct parent as active: bool(true) spans(\DDTrace\SpanData) (1) { start_span_stack.php (start_span_stack.php, start_span_stack.php, cli) - _dd.p.dm => -0 - _dd.p.tid => %s (start_span_stack.php, cli) (start_span_stack.php, cli) } diff --git a/tests/ext/span_stack/start_top_level_span_stack.phpt b/tests/ext/span_stack/start_top_level_span_stack.phpt index 4552b54f28f..b52ef5cf99d 100644 --- a/tests/ext/span_stack/start_top_level_span_stack.phpt +++ b/tests/ext/span_stack/start_top_level_span_stack.phpt @@ -46,6 +46,4 @@ Now, we are back on the global span stack: bool(true) Impliying we also have no active span: bool(true) spans(\DDTrace\SpanData) (1) { start_top_level_span_stack.php (start_top_level_span_stack.php, start_top_level_span_stack.php, cli) - _dd.p.dm => -0 - _dd.p.tid => %s } diff --git a/tests/ext/start_span_with_all_properties.phpt b/tests/ext/start_span_with_all_properties.phpt index 4ce1682c97a..f2af40f805f 100644 --- a/tests/ext/start_span_with_all_properties.phpt +++ b/tests/ext/start_span_with_all_properties.phpt @@ -58,9 +58,11 @@ bool(true) float(2000000000) array(2) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -75,35 +77,34 @@ array(2) { string(34) "start_span_with_all_properties.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(3) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(6) { ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } [1]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -118,34 +119,31 @@ array(2) { string(4) "test" ["type"]=> string(6) "runner" - ["meta"]=> - array(5) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(9) { + ["runtime-id"]=> + string(36) "%s" ["_dd.svc_src"]=> string(1) "m" ["aa"]=> string(2) "bb" - ["runtime-id"]=> - string(36) "%s" - } - ["metrics"]=> - array(7) { - ["_dd.agent_psr"]=> - float(1) - ["_sampling_priority_v1"]=> - float(1) + ["process_id"]=> + float(%f) ["cc"]=> float(0) + ["_dd.agent_psr"]=> + float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } diff --git a/tests/ext/start_span_without_closing.phpt b/tests/ext/start_span_without_closing.phpt index b0d3a73e8ad..05619173f59 100644 --- a/tests/ext/start_span_without_closing.phpt +++ b/tests/ext/start_span_without_closing.phpt @@ -30,9 +30,11 @@ var_dump(dd_clean_spans()); [ddtrace] [warning] [%d] Found unfinished span while automatically closing spans with name 'my precious span' array(1) { [0]=> - array(10) { + array(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -47,28 +49,25 @@ array(1) { string(30) "start_span_without_closing.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(3) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(6) { ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } diff --git a/tests/ext/start_span_without_closing_autofinish.phpt b/tests/ext/start_span_without_closing_autofinish.phpt index a0d14033fed..14551d00f30 100644 --- a/tests/ext/start_span_without_closing_autofinish.phpt +++ b/tests/ext/start_span_without_closing_autofinish.phpt @@ -28,9 +28,11 @@ var_dump(dd_clean_spans()); [ddtrace] [warning] [%d] Found unfinished span while automatically closing spans with name 'my precious span' array(2) { [0]=> - array(9) { + array(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -47,11 +49,15 @@ array(2) { string(41) "start_span_without_closing_autofinish.php" ["type"]=> string(3) "cli" + ["span_kind"]=> + int(1) } [1]=> - array(9) { + array(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -68,6 +74,8 @@ array(2) { string(41) "start_span_without_closing_autofinish.php" ["type"]=> string(3) "cli" + ["span_kind"]=> + int(1) } } [ddtrace] [error] [%d] There is no user-span on the top of the stack. Cannot close. diff --git a/tests/ext/test_special_attributes.phpt b/tests/ext/test_special_attributes.phpt index 4c3ffffe823..ca462d2c313 100644 --- a/tests/ext/test_special_attributes.phpt +++ b/tests/ext/test_special_attributes.phpt @@ -33,9 +33,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -52,12 +54,14 @@ array(1) { string(11) "new.service" ["type"]=> string(8) "new.type" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(2) { - ["_dd.base_service"]=> - string(27) "test_special_attributes.php" ["_dd.svc_src"]=> string(1) "m" + ["_dd.base_service"]=> + string(27) "test_special_attributes.php" } } } diff --git a/tests/ext/test_special_attributes_bis.phpt b/tests/ext/test_special_attributes_bis.phpt index df5c18f7aba..adf037b1a86 100644 --- a/tests/ext/test_special_attributes_bis.phpt +++ b/tests/ext/test_special_attributes_bis.phpt @@ -34,9 +34,11 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -53,12 +55,14 @@ array(1) { string(14) "mapped.service" ["type"]=> string(8) "new.type" - ["meta"]=> + ["span_kind"]=> + int(1) + ["attributes"]=> array(2) { - ["_dd.base_service"]=> - string(31) "test_special_attributes_bis.php" ["_dd.svc_src"]=> string(1) "m" + ["_dd.base_service"]=> + string(31) "test_special_attributes_bis.php" } } } diff --git a/tests/ext/traced_attribute.phpt b/tests/ext/traced_attribute.phpt index cbc2dfafd50..99e6e1b45d6 100644 --- a/tests/ext/traced_attribute.phpt +++ b/tests/ext/traced_attribute.phpt @@ -59,16 +59,17 @@ dd_dump_spans(); --EXPECTF-- spans(\DDTrace\SpanData) (3) { bar (traced_attribute.php, bar, cli) + _dd.code_origin.type => entry _dd.code_origin.frames.0.file => %s _dd.code_origin.frames.0.line => 22 _dd.code_origin.frames.0.method => bar _dd.code_origin.frames.1.file => %s _dd.code_origin.frames.1.line => 40 - _dd.code_origin.type => entry - _dd.p.dm => -0 - _dd.p.tid => %s simplename (test, rsrc, typeee) - _dd.base_service => traced_attribute.php + _dd.svc_src => m + a => b + data => dog + _dd.code_origin.type => exit _dd.code_origin.frames.0.file => %s _dd.code_origin.frames.0.line => 7 _dd.code_origin.frames.0.method => simple @@ -78,28 +79,21 @@ spans(\DDTrace\SpanData) (3) { _dd.code_origin.frames.1.method => bar _dd.code_origin.frames.2.file => %s _dd.code_origin.frames.2.line => 40 - _dd.code_origin.type => exit - _dd.svc_src => m - a => b - data => dog + _dd.base_service => traced_attribute.php recursion (traced_attribute.php, recursion, cli) + _dd.code_origin.type => entry _dd.code_origin.frames.0.file => %s _dd.code_origin.frames.0.line => 27 _dd.code_origin.frames.0.method => recursion _dd.code_origin.frames.1.file => %s _dd.code_origin.frames.1.line => 45 - _dd.code_origin.type => entry - _dd.p.dm => -0 - _dd.p.tid => %s recursion (traced_attribute.php, recursion, cli) recursion (traced_attribute.php, recursion, cli) noRecursion (traced_attribute.php, noRecursion, cli) + _dd.code_origin.type => entry _dd.code_origin.frames.0.file => %s _dd.code_origin.frames.0.line => 34 _dd.code_origin.frames.0.method => noRecursion _dd.code_origin.frames.1.file => %s _dd.code_origin.frames.1.line => 46 - _dd.code_origin.type => entry - _dd.p.dm => -0 - _dd.p.tid => %s } diff --git a/tests/ext/traced_attribute_delayed.phpt b/tests/ext/traced_attribute_delayed.phpt index d14f68bdd00..fb704e74eca 100644 --- a/tests/ext/traced_attribute_delayed.phpt +++ b/tests/ext/traced_attribute_delayed.phpt @@ -51,9 +51,5 @@ int(1) int(1) spans(\DDTrace\SpanData) (2) { simpleclass (traced_attribute_delayed.php, simpleclass, cli) - _dd.p.dm => -0 - _dd.p.tid => %s simplefunc (traced_attribute_delayed.php, simplefunc, cli) - _dd.p.dm => -0 - _dd.p.tid => %s } diff --git a/tests/ext/ust.phpt b/tests/ext/ust.phpt index 08e02f7387f..566b998af67 100644 --- a/tests/ext/ust.phpt +++ b/tests/ext/ust.phpt @@ -30,6 +30,8 @@ array(2) { array(%d) { ["trace_id"]=> string(%d) "%s" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%s" ["start"]=> @@ -44,32 +46,29 @@ array(2) { string(12) "version_test" ["type"]=> string(3) "cli" - ["meta"]=> + ["env"]=> + string(8) "env_test" + ["version"]=> + string(5) "5.2.0" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> array(%d) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["env"]=> - string(8) "env_test" ["runtime-id"]=> string(36) "%s" - ["version"]=> - string(5) "5.2.0" - } - ["metrics"]=> - array(%d) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) ["php.compilation.total_time_ms"]=> float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) ["php.memory.peak_usage_bytes"]=> float(%f) - ["process_id"]=> + ["php.memory.peak_real_usage_bytes"]=> float(%f) } } @@ -77,6 +76,8 @@ array(2) { array(%d) { ["trace_id"]=> string(%d) "%s" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%s" ["start"]=> @@ -91,27 +92,24 @@ array(2) { string(13) "no dd_service" ["type"]=> string(3) "cli" - ["meta"]=> + ["env"]=> + string(8) "env_test" + ["span_kind"]=> + int(1) + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> array(%d) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.svc_src"]=> - string(1) "m" - ["env"]=> - string(8) "env_test" ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(%d) { - ["_dd.agent_psr"]=> - float(1) - ["_sampling_priority_v1"]=> - float(1) + ["_dd.svc_src"]=> + string(1) "m" ["process_id"]=> float(%f) + ["_dd.agent_psr"]=> + float(1) } } }