From 40bced598e31c46c0fecbd4426a2e75503b9f278 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Thu, 1 Oct 2026 18:01:47 +0200 Subject: [PATCH 01/11] feat(tracer): send traces as V1 payloads through the libdatadog builder FFI Serialize closed spans into a libdatadog TracerPayloadV1Builder (Box-per-node pointer handles) and send them to the sidecar as /v1.0/traces, with the sidecar negotiating /info and downgrading to v0.4 for agents that lack it. The in-process sender keeps the v0.4 wire, transcoded from the same builder. Span tags live in a single typed attributes store; SpanData::$meta and $metrics are views onto it. Process tags and the OTLP export marker are TracerPayload attributes (the v0.4 downgrade puts them on each chunk's first span), and span links and events carry native attributes. DD_TRACE_AGENT_PROTOCOL_VERSION=0.4 forces v0.4. Bump libdatadog to the V1 FFI branch and port components-rs to the new rate limiter API. --- Cargo.lock | 1 + Cargo.toml | 1 + Makefile | 2 +- appsec/src/extension/tracer_bridge.c | 38 +- appsec/src/extension/tracer_bridge.h | 4 +- components-rs/common.h | 66 + components-rs/datadog.h | 141 +- components-rs/sidecar.h | 633 +++++++- components-rs/tracer_runtime/bytes.rs | 728 +++++++--- config.m4 | 1 + config.w32 | 1 + ext/agent_info.h | 1 + ext/compatibility.h | 12 +- ext/configuration.h | 7 + ext/ffi_utils.h | 7 +- ext/sidecar.c | 3 +- libdatadog | 2 +- metadata/supported-configurations.json | 18 +- tooling/generate-supported-configurations.sh | 4 - tracer/auto_flush.c | 86 +- tracer/code_origins.c | 16 +- tracer/coms.c | 1 + tracer/configuration.h | 7 +- tracer/configuration_dependencies.h | 13 + tracer/ddtrace.h | 1 + tracer/ddtrace.stub.php | 171 +-- tracer/ddtrace_arginfo.h | 240 +-- tracer/distributed_tracing_headers.c | 9 +- tracer/endpoint_guessing.c | 11 +- tracer/exception_serialize.c | 28 +- tracer/exception_serialize.h | 2 +- tracer/functions.c | 254 +--- tracer/handlers_http.h | 2 +- tracer/handlers_httpstreams.c | 13 +- tracer/hook/uhook_attributes.c | 58 +- tracer/integrations/exec_integration.c | 9 +- tracer/live_debugger.c | 4 +- tracer/priority_sampling/priority_sampling.c | 47 +- tracer/serializer.c | 1286 +++++++++++------ tracer/serializer.h | 14 +- tracer/span.c | 50 +- tracer/span.h | 34 +- tracer/span_stats.c | 145 +- tracer/span_stats.h | 18 +- tracer/span_tags_view.c | 520 +++++++ tracer/span_tags_view.h | 19 + tracer/trace_filter.c | 40 +- tracer/trace_source.c | 4 +- .../tracer_tag_propagation.c | 12 +- .../tracer_tag_propagation.h | 2 + tracer/tracer_telemetry.c | 12 +- 51 files changed, 3320 insertions(+), 1478 deletions(-) create mode 100644 tracer/span_tags_view.c create mode 100644 tracer/span_tags_view.h diff --git a/Cargo.lock b/Cargo.lock index fea7f2da817..e6e1ea964f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1257,6 +1257,7 @@ dependencies = [ "rand_distr", "regex", "regex-automata", + "rmpv", "rustc-hash", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index de6edc48434..4875be3d47b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,6 +159,7 @@ cc = { version = "1.0", optional = true } [dev-dependencies] tempfile = "3.3" static_assertions = "1" +rmpv = "1.3.0" [profile.dev] debug = 2 diff --git a/Makefile b/Makefile index 5fe55011192..4befe027549 100644 --- a/Makefile +++ b/Makefile @@ -1342,7 +1342,7 @@ define run_composer_with_retry endef define run_tests_without_coverage - $(TEST_EXTRA_ENV) $(ENV_OVERRIDE) php $(TEST_EXTRA_INI) -d datadog.instrumentation_telemetry_enabled=$(shell (test $(TELEMETRY_ENABLED) && echo 1) || (test $(PHP_MAJOR_MINOR) -ge 83 && echo 1) || echo 0) -d datadog.trace.sidecar_trace_sender=$(shell test $(PHP_MAJOR_MINOR) -ge 83 && echo 1 || echo 0) $(TRACER_SOURCES_INI) $(PHPUNIT) $(1) --filter=$(FILTER) + $(TEST_EXTRA_ENV) $(ENV_OVERRIDE) php $(TEST_EXTRA_INI) -d datadog.instrumentation_telemetry_enabled=$(shell (test $(TELEMETRY_ENABLED) && echo 1) || (test $(PHP_MAJOR_MINOR) -ge 83 && echo 1) || echo 0) $(TRACER_SOURCES_INI) $(PHPUNIT) $(1) --filter=$(FILTER) endef define run_tests_with_coverage diff --git a/appsec/src/extension/tracer_bridge.c b/appsec/src/extension/tracer_bridge.c index d8b55bb128e..939ed48a6f7 100644 --- a/appsec/src/extension/tracer_bridge.c +++ b/appsec/src/extension/tracer_bridge.c @@ -29,6 +29,7 @@ # include "test_mock_transport.h" #endif +static zend_string *_attributes_propname; static zend_string *_meta_propname; static zend_string *_metrics_propname; static zend_string *_meta_struct_propname; @@ -38,6 +39,7 @@ static void _register_testing_objects(void); void dd_trace_startup(void) { + _attributes_propname = zend_string_init_interned(LSTRARG("attributes"), 1); _meta_propname = zend_string_init_interned(LSTRARG("meta"), 1); _metrics_propname = zend_string_init_interned(LSTRARG("metrics"), 1); _meta_struct_propname = @@ -160,14 +162,30 @@ static zval *_get_span_modifiable_array_property( return res; } +// $meta and $metrics are views onto $attributes, the span's single tag store. zval *nullable dd_trace_span_get_meta(zend_object *nonnull zobj) { - return _get_span_modifiable_array_property(zobj, _meta_propname); + return _get_span_modifiable_array_property(zobj, _attributes_propname); } zval *nullable dd_trace_span_get_metrics(zend_object *nonnull zobj) { - return _get_span_modifiable_array_property(zobj, _metrics_propname); + return _get_span_modifiable_array_property(zobj, _attributes_propname); +} + +// Reads $meta/$metrics through the span's handlers: an array of that bucket. +static zval *_read_span_property( + zend_object *nonnull zobj, zend_string *nonnull propname, zval *nonnull rv) +{ +#if PHP_VERSION_ID >= 80000 + return zobj->handlers->read_property(zobj, propname, BP_VAR_R, NULL, rv); +#else + zval obj; + ZVAL_OBJ(&obj, zobj); + zval prop; + ZVAL_STR(&prop, propname); + return zobj->handlers->read_property(&obj, &prop, BP_VAR_R, NULL, rv); +#endif } zval *nullable dd_trace_span_get_meta_struct(zend_object *nonnull zobj) @@ -364,9 +382,11 @@ static PHP_FUNCTION(datadog_appsec_testing_root_span_get_meta) // NOLINT RETURN_NULL(); } - zval *meta_zv = dd_trace_span_get_meta(root_span); - if (meta_zv) { - RETURN_ZVAL(meta_zv, 1 /* copy */, 0 /* no destroy original */); + zval rv; + zval *meta_zv = _read_span_property(root_span, _meta_propname, &rv); + RETVAL_ZVAL(meta_zv, 1 /* copy */, 0 /* no destroy original */); + if (meta_zv == &rv) { + zval_ptr_dtor(&rv); } } @@ -398,9 +418,11 @@ static PHP_FUNCTION(datadog_appsec_testing_root_span_get_metrics) // NOLINT RETURN_NULL(); } - zval *metrics_zv = dd_trace_span_get_metrics(root_span); - if (metrics_zv) { - RETURN_ZVAL(metrics_zv, 1 /* copy */, 0 /* no destroy original */); + zval rv; + zval *metrics_zv = _read_span_property(root_span, _metrics_propname, &rv); + RETVAL_ZVAL(metrics_zv, 1 /* copy */, 0 /* no destroy original */); + if (metrics_zv == &rv) { + zval_ptr_dtor(&rv); } } diff --git a/appsec/src/extension/tracer_bridge.h b/appsec/src/extension/tracer_bridge.h index 5e506287126..b0727dd8314 100644 --- a/appsec/src/extension/tracer_bridge.h +++ b/appsec/src/extension/tracer_bridge.h @@ -41,8 +41,8 @@ void dd_trace_close_all_spans_and_flush(void); void dd_trace_emit_asm_event(void); -// Provides the array zval representing $root_span->meta, if any. -// It is ready for modification, with refcount == 1 +// Provides the array zval representing $root_span->attributes (which $meta +// and $metrics are views onto), if any. Ready for modification, refcount == 1 zval *nullable dd_trace_span_get_meta(zend_object *nonnull); zval *nullable dd_trace_span_get_metrics(zend_object *nonnull); zval *nullable dd_trace_span_get_meta_struct(zend_object *nonnull); diff --git a/components-rs/common.h b/components-rs/common.h index 2b0d6132307..84f9ca34a77 100644 --- a/components-rs/common.h +++ b/components-rs/common.h @@ -1246,6 +1246,24 @@ typedef struct ddog_AttributeAnyValueBytes ddog_AttributeAnyValueBytes; typedef struct ddog_AttributeArrayValueBytes ddog_AttributeArrayValueBytes; +/** + * Attribute value type tags from [`ddog_v1_value_type`], so a C caller picks the matching typed + * value getter. + */ +#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, @@ -1294,6 +1312,33 @@ typedef struct ddog_AgentRemoteConfigWriter_ShmHandle ddog_AgentRemoteConfigWrit typedef struct ddog_Arc_Target ddog_Arc_Target; +/** + * An owned `List` attribute value under construction. Opaque to C. + */ +typedef struct ddog_AttrList ddog_AttrList; + +/** + * An owned `KeyValue` attribute value under construction. Opaque to C. + */ +typedef struct ddog_AttrMap ddog_AttrMap; + +/** + * Opaque handle to one attribute value inside an [`Attributes`] map or a list. + */ +typedef struct ddog_AttrValue ddog_AttrValue; + +/** + * Opaque handle to an attribute map: the payload's, a chunk's, span's, link's or event's + * (`ddog_*_get_attributes`), or an owned nested map's ([`ddog_attr_map_get_attributes`]). + */ +typedef struct ddog_Attributes ddog_Attributes; + +/** + * A chunk node in the builder: its own heap allocation, so a `*mut ChunkNode` handed to C stays + * valid across sibling chunk pushes. Its spans live as separate `Box` allocations. + */ +typedef struct ddog_ChunkNode ddog_ChunkNode; + /** * Fundamental configuration of the RC client, which always must be set. */ @@ -1328,6 +1373,19 @@ typedef struct ddog_RuntimeMetadata ddog_RuntimeMetadata; typedef struct ddog_ShmHandle ddog_ShmHandle; +/** + * A span node in the builder: its own heap allocation, so a held `*mut SpanNode` stays valid + * across sibling span pushes into the same chunk (the inferred-span case). Links/events are + * likewise separate `Box` allocations. + */ +typedef struct ddog_SpanNode ddog_SpanNode; + +/** + * Builds a native V1 [`TracerPayloadBytes`] holding readable strings. Each node is its own heap + * allocation (see the module docs); the builder owns the top-level chunk pointers. + */ +typedef struct ddog_TracerPayloadV1Builder ddog_TracerPayloadV1Builder; + typedef struct ddog_NativeFile { struct ddog_PlatformHandle_File *handle; } ddog_NativeFile; @@ -1496,6 +1554,14 @@ typedef struct ddog_SenderParameters { ddog_CharSlice url; } ddog_SenderParameters; +/** + * Payload-level tracer metadata for the V1 send path not already carried by the sender's + * `tracer_headers_tags` (lang, tracer_version, container_id live there and are routed from there). + */ +typedef struct ddog_TracerMetadataV1 { + ddog_CharSlice runtime_id; +} ddog_TracerMetadataV1; + /** * Raw AppSec response returned by the AppSec message functions. * diff --git a/components-rs/datadog.h b/components-rs/datadog.h index 2f88c19f238..23eaa6c4327 100644 --- a/components-rs/datadog.h +++ b/components-rs/datadog.h @@ -45,6 +45,10 @@ ddog_ZendResult ddog_php_prof_post_deactivate(void); void ddog_php_prof_zend_activate(void); #endif +#if defined(DDTRACE_PROFILING) +void ddog_php_prof_zend_deactivate(void); +#endif + #if defined(DDTRACE_PROFILING) ddog_ZendResult ddog_php_prof_rinit(int _type, int _module_number); #endif @@ -78,6 +82,28 @@ void ddog_php_prof_zend_shutdown(ddog_ZendExtension *extension); bool ddog_php_prof_is_enabled(void); #endif +/** + * Check that a configuration value can be represented as a UTF-8 PHP string. + * + * # Safety + * `bytes` must point to `len` readable bytes unless `len` is zero. + */ +bool datadog_bytes_are_valid_utf8(const uint8_t *bytes, uintptr_t len); + +ddog_Configurator *ddog_library_configurator_new_dummy(bool debug_logs, ddog_CharSlice language); + +bool ddog_shall_log(enum ddog_Log category); + +void ddog_set_error_log_level(bool once); + +void ddog_set_log_level(ddog_CharSlice level, bool once); + +void ddog_log(enum ddog_Log category, bool once, ddog_CharSlice msg); + +void ddog_reset_logger(void); + +uint32_t ddog_get_logs_count(ddog_CharSlice level); + /** * Read all agent /info data in one SHM read and apply env, container-hash and concentrator * config atomically. @@ -123,59 +149,66 @@ void ddog_init_span_func(void (*free_func)(ddog_OwnedZendString), void (*addref_func)(struct _zend_string*), ddog_OwnedZendString (*init_func)(ddog_CharSlice)); -void ddog_set_span_service_zstr(ddog_SpanBytes *ptr, struct _zend_string *str); - -void ddog_set_span_name_zstr(ddog_SpanBytes *ptr, struct _zend_string *str); - -void ddog_set_span_resource_zstr(ddog_SpanBytes *ptr, struct _zend_string *str); - -void ddog_set_span_type_zstr(ddog_SpanBytes *ptr, struct _zend_string *str); - -void ddog_add_span_meta_zstr(ddog_SpanBytes *ptr, - struct _zend_string *key, - struct _zend_string *val); - -void ddog_add_CharSlice_span_meta_zstr(ddog_SpanBytes *ptr, - ddog_CharSlice key, - struct _zend_string *val); - -void ddog_add_zstr_span_meta_str(ddog_SpanBytes *ptr, struct _zend_string *key, const char *val); - -void ddog_add_str_span_meta_str(ddog_SpanBytes *ptr, const char *key, const char *val); - -void ddog_add_str_span_meta_zstr(ddog_SpanBytes *ptr, const char *key, struct _zend_string *val); - -void ddog_add_str_span_meta_CharSlice(ddog_SpanBytes *ptr, const char *key, ddog_CharSlice val); - -void ddog_del_span_meta_zstr(ddog_SpanBytes *ptr, struct _zend_string *key); - -void ddog_del_span_meta_str(ddog_SpanBytes *ptr, const char *key); - -bool ddog_has_span_meta_zstr(ddog_SpanBytes *ptr, struct _zend_string *key); - -bool ddog_has_span_meta_str(ddog_SpanBytes *ptr, const char *key); - -ddog_CharSlice ddog_get_span_meta_str(ddog_SpanBytes *span, const char *key); - -void ddog_add_span_metrics_zstr(ddog_SpanBytes *ptr, struct _zend_string *key, double val); +/** + * # Safety + * `span` must be a live span node pointer from `ddog_new_span` (every `*_zstr` span setter). + */ +void ddog_set_span_service_zstr(ddog_SpanNode *span, struct _zend_string *str); -bool ddog_has_span_metrics_zstr(ddog_SpanBytes *ptr, struct _zend_string *key); +/** + * # Safety + * See [`ddog_set_span_service_zstr`]. + */ +void ddog_set_span_name_zstr(ddog_SpanNode *span, struct _zend_string *str); -void ddog_del_span_metrics_zstr(ddog_SpanBytes *ptr, struct _zend_string *key); +/** + * # Safety + * See [`ddog_set_span_service_zstr`]. + */ +void ddog_set_span_resource_zstr(ddog_SpanNode *span, struct _zend_string *str); -void ddog_add_span_metrics_str(ddog_SpanBytes *ptr, const char *key, double val); +/** + * # Safety + * See [`ddog_set_span_service_zstr`]. + */ +void ddog_set_span_type_zstr(ddog_SpanNode *span, struct _zend_string *str); -bool ddog_get_span_metrics_str(ddog_SpanBytes *ptr, const char *key, double *result); +/** + * String attribute under a static C literal key. + * + * # Safety + * `attrs` must be a live `Attributes` handle and `key` a static NUL-terminated string (applies + * to every attribute adder below). + */ +void ddog_attributes_add_lit(ddog_Attributes *attrs, const char *key, ddog_CharSlice value); -void ddog_del_span_metrics_str(ddog_SpanBytes *ptr, const char *key); +/** + * String attribute sharing both zend strings (zero-copy). + * + * # Safety + * See [`ddog_attributes_add_lit`]. + */ +void ddog_attributes_add_zstr(ddog_Attributes *attrs, + struct _zend_string *key, + struct _zend_string *value); -void ddog_add_span_meta_struct_zstr(ddog_SpanBytes *ptr, - struct _zend_string *key, - struct _zend_string *val); +/** + * Double attribute under a static C literal key. + * + * # Safety + * See [`ddog_attributes_add_lit`]. + */ +void ddog_attributes_add_double_lit(ddog_Attributes *attrs, const char *key, double value); -void ddog_add_zstr_span_meta_struct_CharSlice(ddog_SpanBytes *ptr, - struct _zend_string *key, - ddog_CharSlice val); +/** + * Double attribute under a shared zend string key (zero-copy). + * + * # Safety + * See [`ddog_attributes_add_lit`]. + */ +void ddog_attributes_add_double_zstr(ddog_Attributes *attrs, + struct _zend_string *key, + double value); bool ddog_ffe_load_config(ddog_CharSlice json); @@ -189,18 +222,6 @@ struct ddog_FfeResult ddog_ffe_evaluate(ddog_CharSlice flag_key, const struct ddog_FfeAttribute *attributes, uintptr_t attributes_count); -bool ddog_shall_log(enum ddog_Log category); - -void ddog_set_error_log_level(bool once); - -void ddog_set_log_level(ddog_CharSlice level, bool once); - -void ddog_log(enum ddog_Log category, bool once, ddog_CharSlice msg); - -void ddog_reset_logger(void); - -uint32_t ddog_get_logs_count(ddog_CharSlice level); - void ddog_init_remote_config(struct ddog_RemoteConfigFlags flags); struct ddog_RemoteConfigState *ddog_init_remote_config_state(const struct ddog_Endpoint *endpoint, @@ -554,8 +575,6 @@ void datadog_generate_session_id(void); void datadog_format_runtime_id(uint8_t (*buf)[36]); -bool datadog_bytes_are_valid_utf8(const uint8_t *bytes, uintptr_t len); - #if defined(__linux__) /** * Publish or update dd-trace-php's standard Linux OTel Process Context. @@ -598,8 +617,6 @@ ddog_MaybeError datadog_crashtracker_init(const struct ddog_Endpoint *endpoint, ddog_crasht_Metadata metadata, int32_t master_pid); -ddog_Configurator *ddog_library_configurator_new_dummy(bool debug_logs, ddog_CharSlice language); - uint64_t dd_fnv1a_64(const uint8_t *data, uintptr_t len); /** diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 8b51abd62e5..dc7409516b0 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -236,7 +236,8 @@ ddog_MaybeError ddog_sidecar_set_connection_config(struct ddog_SidecarTransport ddog_CharSlice hostname, ddog_CharSlice root_service, ddog_CharSlice root_session_id, - ddog_CharSlice parent_session_id); + ddog_CharSlice parent_session_id, + bool force_v04_traces); /** * Updates the process_tags of the connection. @@ -496,6 +497,25 @@ 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); +/** + * V1 counterpart of `ddog_send_traces_to_sidecar`: sends the [`crate::span`] builder's native V1 + * payload to the agent's `/v1.0/traces`. Consumes `builder`. Payload metadata comes at send time + * from `parameters.tracer_headers_tags` and `metadata`; lang_interpreter/lang_vendor go as + * headers. + */ +void ddog_send_traces_to_sidecar_v1(struct ddog_TracerPayloadV1Builder *builder, + struct ddog_SenderParameters *parameters, + const struct ddog_TracerMetadataV1 *metadata); + +/** + * Downgrades a native V1 builder to the in-memory v0.4 collection for the in-process `coms.c` + * sender (PHP <= 8.2). Consumes `builder`. Returns the collection (not one whole-payload + * CharSlice) so `auto_flush` can frame each trace individually; a single CharSlice would drop + * extra traces of a multi-trace payload. Empty collection on error; free with + * [`crate::span_v04::ddog_free_traces`]. + */ +ddog_TracesBytes *ddog_downgrade_v1_builder_to_v04_traces(struct ddog_TracerPayloadV1Builder *builder); + /** * Drops the agent info reader. */ @@ -651,162 +671,615 @@ void ddog_sidecar_signal_flush_drop(struct ddog_SignalFlush *flush); int32_t ddog_sidecar_signal_flush_run(const struct ddog_SignalFlush *flush); #endif -ddog_TracesBytes *ddog_get_traces(void); +/** + * 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); -void ddog_free_traces(ddog_TracesBytes *_traces); +/** + * Frees a V1 payload builder. + */ +void ddog_v1_free_builder(struct ddog_TracerPayloadV1Builder *_builder); -uintptr_t ddog_get_traces_size(const ddog_TracesBytes *traces); +/** + * Sets the payload `env` / `app_version` / `hostname` fields (empty = unset). + */ +void ddog_set_payload_metadata(struct ddog_TracerPayloadV1Builder *builder, + ddog_CharSlice env, + ddog_CharSlice app_version, + ddog_CharSlice hostname); -ddog_TraceBytes *ddog_get_trace(ddog_TracesBytes *traces, uintptr_t index); +/** + * Appends a chunk carrying the 128-bit trace id (high/low halves), returning its node pointer. + */ +struct ddog_ChunkNode *ddog_new_chunk(struct ddog_TracerPayloadV1Builder *builder, + uint64_t trace_id_high, + uint64_t trace_id_low); -ddog_TraceBytes *ddog_traces_new_trace(ddog_TracesBytes *traces); +/** + * Number of spans already in `chunk`. + * + * # Safety + * `chunk` must be a live chunk node pointer from [`ddog_new_chunk`] (applies to every chunk fn). + */ +uintptr_t ddog_chunk_span_count(struct ddog_ChunkNode *chunk); -uintptr_t ddog_get_trace_size(const ddog_TraceBytes *trace); +/** + * Appends an empty span to `chunk`, returning its node pointer. + * + * # Safety + * See [`ddog_chunk_span_count`]. + */ +struct ddog_SpanNode *ddog_new_span(struct ddog_ChunkNode *chunk); -ddog_SpanBytes *ddog_get_span(ddog_TraceBytes *trace, uintptr_t index); +/** + * Appends an empty link to `span`, returning its node pointer. + * + * # Safety + * `span` must be a live span node pointer from [`ddog_new_span`] (applies to every span fn). + */ +ddog_SpanLinkBytes *ddog_new_link(struct ddog_SpanNode *span); -ddog_SpanBytes *ddog_trace_new_span(ddog_TraceBytes *trace); +/** + * Appends an empty event to `span`, returning its node pointer. + * + * # Safety + * See [`ddog_new_link`]. + */ +ddog_SpanEventBytes *ddog_new_event(struct ddog_SpanNode *span); -ddog_SpanBytes *ddog_trace_new_span_with_capacities(ddog_TraceBytes *trace, - uintptr_t meta_size, - uintptr_t metrics_size); +/** + * # Safety + * See [`ddog_new_link`] (applies to every `ddog_span_set_*` / `ddog_set_span_*`). + */ +void ddog_span_set_id(struct ddog_SpanNode *span, uint64_t value); /** - * The returned slice is an owned allocation that must be properly freed using - * [`ddog_free_charslice`]. + * # Safety + * See [`ddog_span_set_id`]. */ -ddog_CharSlice ddog_span_debug_log(const ddog_SpanBytes *span); +void ddog_span_set_parent_id(struct ddog_SpanNode *span, uint64_t value); /** - * Frees an owned [`CharSlice`]. Note that some functions of this API return borrowed slices that - * must NOT be freed. Only a few selected functions return slices that must be freed, and this is - * mentioned explicitly in their documentation. + * # Safety + * See [`ddog_span_set_id`]. + */ +void ddog_span_set_start(struct ddog_SpanNode *span, int64_t value); + +/** + * # Safety + * See [`ddog_span_set_id`]. + */ +void ddog_span_set_duration(struct ddog_SpanNode *span, int64_t value); + +/** + * # Safety + * See [`ddog_span_set_id`]. + */ +void ddog_span_set_error(struct ddog_SpanNode *span, bool error); + +/** + * Reads the span error flag (e.g. to mirror it onto an inferred span). * * # Safety + * See [`ddog_new_link`]. + */ +bool ddog_span_get_error(struct ddog_SpanNode *span); + +/** + * # Safety + * See [`ddog_span_get_error`]. + */ +void ddog_set_span_service(struct ddog_SpanNode *span, ddog_CharSlice value); + +/** + * # Safety + * See [`ddog_span_get_error`]. + */ +void ddog_set_span_name(struct ddog_SpanNode *span, ddog_CharSlice value); + +/** + * # Safety + * See [`ddog_span_get_error`]. + */ +void ddog_set_span_resource(struct ddog_SpanNode *span, ddog_CharSlice value); + +/** + * # Safety + * See [`ddog_span_get_error`]. + */ +void ddog_set_span_type(struct ddog_SpanNode *span, ddog_CharSlice value); + +/** + * # Safety + * See [`ddog_span_get_error`]. + */ +void ddog_set_span_env(struct ddog_SpanNode *span, ddog_CharSlice value); + +/** + * # Safety + * See [`ddog_span_get_error`]. + */ +void ddog_set_span_version(struct ddog_SpanNode *span, ddog_CharSlice value); + +/** + * # Safety + * See [`ddog_span_get_error`]. + */ +void ddog_set_span_component(struct ddog_SpanNode *span, ddog_CharSlice value); + +/** + * Sets the span kind from an OTEL wire value (unset/unknown → Unspecified). * - * `slice` must be an owned char slice that has been returned by one of the functions of this API. + * # Safety + * See [`ddog_new_link`]. */ -void ddog_free_charslice(ddog_CharSlice slice); +void ddog_set_span_kind(struct ddog_SpanNode *span, uint32_t kind); + +/** + * Sets the span kind from a v0.4 `span.kind` string. Returns `false` for a non-canonical kind, + * which has no wire slot, so the caller keeps it as a plain attribute. + * + * # Safety + * See [`ddog_new_link`]. + */ +bool ddog_set_span_kind_str(struct ddog_SpanNode *span, ddog_CharSlice value); + +/** + * # Safety + * See [`ddog_chunk_span_count`] (applies to every `ddog_set_chunk_*`). + */ +void ddog_set_chunk_origin(struct ddog_ChunkNode *chunk, ddog_CharSlice origin); + +/** + * # Safety + * See [`ddog_set_chunk_origin`]. + */ +void ddog_set_chunk_sampling_priority(struct ddog_ChunkNode *chunk, int32_t priority); + +/** + * # Safety + * See [`ddog_set_chunk_origin`]. + */ +void ddog_set_chunk_sampling_mechanism(struct ddog_ChunkNode *chunk, uint32_t mechanism); + +/** + * # Safety + * `link` must be a live link node pointer from [`ddog_new_link`] (applies to every + * `ddog_link_*`). + */ +void ddog_link_set_trace_id(ddog_SpanLinkBytes *link, + uint64_t trace_id_high, + uint64_t trace_id_low); + +/** + * # Safety + * See [`ddog_link_set_trace_id`]. + */ +void ddog_link_set_span_id(ddog_SpanLinkBytes *link, uint64_t value); + +/** + * # Safety + * See [`ddog_link_set_trace_id`]. + */ +void ddog_link_set_flags(ddog_SpanLinkBytes *link, uint32_t value); + +/** + * # Safety + * See [`ddog_link_set_trace_id`]. + */ +void ddog_link_set_tracestate(ddog_SpanLinkBytes *link, ddog_CharSlice value); + +/** + * # Safety + * `event` must be a live event node pointer from [`ddog_new_event`] (applies to every + * `ddog_event_*`). + */ +void ddog_event_set_name(ddog_SpanEventBytes *event, ddog_CharSlice value); + +/** + * # Safety + * See [`ddog_event_set_name`]. + */ +void ddog_event_set_time(ddog_SpanEventBytes *event, uint64_t time_unix_nano); + +/** + * The payload's attribute map. + * + * # Safety + * `builder` must be a live builder from [`ddog_v1_new_builder`]. + */ +struct ddog_Attributes *ddog_payload_get_attributes(struct ddog_TracerPayloadV1Builder *builder); + +/** + * # Safety + * See [`ddog_chunk_span_count`]. + */ +struct ddog_Attributes *ddog_chunk_get_attributes(struct ddog_ChunkNode *chunk); + +/** + * # Safety + * See [`ddog_new_link`]. + */ +struct ddog_Attributes *ddog_span_get_attributes(struct ddog_SpanNode *span); + +/** + * # Safety + * See [`ddog_link_set_trace_id`]. + */ +struct ddog_Attributes *ddog_link_get_attributes(ddog_SpanLinkBytes *link); + +/** + * # Safety + * See [`ddog_event_set_name`]. + */ +struct ddog_Attributes *ddog_event_get_attributes(ddog_SpanEventBytes *event); + +/** + * # Safety + * `attrs` must be a live [`Attributes`] handle (applies to every `ddog_attributes_add_*`). + */ +void ddog_attributes_add_str(struct ddog_Attributes *attrs, + ddog_CharSlice key, + ddog_CharSlice value); -void ddog_set_span_service(ddog_SpanBytes *span, ddog_CharSlice slice); +/** + * # Safety + * See [`ddog_attributes_add_str`]. + */ +void ddog_attributes_add_int(struct ddog_Attributes *attrs, ddog_CharSlice key, int64_t value); -ddog_CharSlice ddog_get_span_service(ddog_SpanBytes *span); +/** + * # Safety + * See [`ddog_attributes_add_str`]. + */ +void ddog_attributes_add_double(struct ddog_Attributes *attrs, ddog_CharSlice key, double value); -void ddog_set_span_name(ddog_SpanBytes *span, ddog_CharSlice slice); +/** + * # Safety + * See [`ddog_attributes_add_str`]. + */ +void ddog_attributes_add_bool(struct ddog_Attributes *attrs, ddog_CharSlice key, bool value); -ddog_CharSlice ddog_get_span_name(ddog_SpanBytes *span); +/** + * Bytes attribute (v0.4 `meta_struct`), copied verbatim. + * + * # Safety + * See [`ddog_attributes_add_str`]. + */ +void ddog_attributes_add_bytes(struct ddog_Attributes *attrs, + ddog_CharSlice key, + ddog_CharSlice value); -void ddog_set_span_resource(ddog_SpanBytes *span, ddog_CharSlice slice); +/** + * Sets `attrs[key]` to `list`, which is consumed. + * + * # Safety + * See [`ddog_attributes_add_str`]; `list` must be a live list from [`ddog_attr_list_new`]. + */ +void ddog_attributes_add_list(struct ddog_Attributes *attrs, + ddog_CharSlice key, + struct ddog_AttrList *list); -ddog_CharSlice ddog_get_span_resource(ddog_SpanBytes *span); +/** + * Sets `attrs[key]` to `map`, which is consumed. + * + * # Safety + * See [`ddog_attributes_add_str`]; `map` must be a live map from [`ddog_attr_map_new`], other than + * the one `attrs` belongs to. + */ +void ddog_attributes_add_map(struct ddog_Attributes *attrs, + ddog_CharSlice key, + struct ddog_AttrMap *map); -void ddog_set_span_type(ddog_SpanBytes *span, ddog_CharSlice slice); +/** + * Copies the attribute `key` from `from_span` onto `to_span`, returning whether the source had it; + * removes it from the source when `delete_source` is set. Type-preserving. + * + * # Safety + * `from_span`/`to_span` must be live, distinct span node pointers from [`ddog_new_span`]; `key` + * a static NUL-terminated string. + */ +bool ddog_transfer_span_attr(struct ddog_SpanNode *from_span, + struct ddog_SpanNode *to_span, + const char *key, + bool delete_source); -ddog_CharSlice ddog_get_span_type(ddog_SpanBytes *span); +/** + * Allocates an empty list with room for `capacity` elements, owned by C until it is consumed. + */ +struct ddog_AttrList *ddog_attr_list_new(uintptr_t capacity); -void ddog_set_span_trace_id(ddog_SpanBytes *span, uint64_t value); +/** + * Allocates an empty map with room for `capacity` members, owned by C until it is consumed. + */ +struct ddog_AttrMap *ddog_attr_map_new(uintptr_t capacity); -uint64_t ddog_get_span_trace_id(ddog_SpanBytes *span); +/** + * The attribute map of an owned nested `map`, filled with the `ddog_attributes_add_*` family. + * + * # Safety + * `map` must be a live map from [`ddog_attr_map_new`]. + */ +struct ddog_Attributes *ddog_attr_map_get_attributes(struct ddog_AttrMap *map); -void ddog_set_span_id(ddog_SpanBytes *span, uint64_t value); +/** + * # Safety + * `list` must be a live list from [`ddog_attr_list_new`] (applies to every `ddog_attr_list_*`); + * a `child` is consumed. + */ +void ddog_attr_list_push_str(struct ddog_AttrList *list, ddog_CharSlice value); -uint64_t ddog_get_span_id(ddog_SpanBytes *span); +/** + * # Safety + * See [`ddog_attr_list_push_str`]. + */ +void ddog_attr_list_push_int(struct ddog_AttrList *list, int64_t value); -void ddog_set_span_parent_id(ddog_SpanBytes *span, uint64_t value); +/** + * # Safety + * See [`ddog_attr_list_push_str`]. + */ +void ddog_attr_list_push_double(struct ddog_AttrList *list, double value); -uint64_t ddog_get_span_parent_id(ddog_SpanBytes *span); +/** + * # Safety + * See [`ddog_attr_list_push_str`]. + */ +void ddog_attr_list_push_bool(struct ddog_AttrList *list, bool value); -void ddog_set_span_start(ddog_SpanBytes *span, int64_t value); +/** + * # Safety + * See [`ddog_attr_list_push_str`]. + */ +void ddog_attr_list_push_bytes(struct ddog_AttrList *list, ddog_CharSlice value); -int64_t ddog_get_span_start(ddog_SpanBytes *span); +/** + * # Safety + * See [`ddog_attr_list_push_str`]. + */ +void ddog_attr_list_push_list(struct ddog_AttrList *list, struct ddog_AttrList *child); -void ddog_set_span_duration(ddog_SpanBytes *span, int64_t value); +/** + * # Safety + * See [`ddog_attr_list_push_str`]. + */ +void ddog_attr_list_push_map(struct ddog_AttrList *list, struct ddog_AttrMap *child); -int64_t ddog_get_span_duration(ddog_SpanBytes *span); +/** + * The builder's chunk node pointers; `len` receives their count. + */ +struct ddog_ChunkNode *const *ddog_v1_get_chunks(const struct ddog_TracerPayloadV1Builder *builder, + uintptr_t *len); -void ddog_set_span_error(ddog_SpanBytes *span, int32_t value); +/** + * Number of chunks in the builder. + */ +uintptr_t ddog_v1_get_chunk_count(const struct ddog_TracerPayloadV1Builder *builder); + +/** + * The chunk's span node pointers; `len` receives their count. + */ +struct ddog_SpanNode *const *ddog_v1_get_spans(const struct ddog_ChunkNode *chunk, uintptr_t *len); -int32_t ddog_get_span_error(ddog_SpanBytes *span); +/** + * The chunk's local-root span, as the v0.4 wire picks it (`local_root_idx`), or null if empty. + * Chunk-level trace tags (trace_id_high, sampling priority/mechanism, origin) belong on it only. + */ +struct ddog_SpanNode *ddog_v1_get_chunk_root_span(const struct ddog_ChunkNode *chunk); + +/** + * The span's link node pointers; `len` receives their count. + */ +ddog_SpanLinkBytes *const *ddog_v1_get_links(const struct ddog_SpanNode *span, uintptr_t *len); -void ddog_add_span_meta(ddog_SpanBytes *span, ddog_CharSlice key, ddog_CharSlice value); +/** + * The span's event node pointers; `len` receives their count. + */ +ddog_SpanEventBytes *const *ddog_v1_get_events(const struct ddog_SpanNode *span, uintptr_t *len); -void ddog_del_span_meta(ddog_SpanBytes *span, ddog_CharSlice key); +uint64_t ddog_v1_get_chunk_trace_id_high(const struct ddog_ChunkNode *chunk); -ddog_CharSlice ddog_get_span_meta(ddog_SpanBytes *span, ddog_CharSlice key); +uint64_t ddog_v1_get_chunk_trace_id_low(const struct ddog_ChunkNode *chunk); -bool ddog_has_span_meta(ddog_SpanBytes *span, ddog_CharSlice key); +/** + * Reads the chunk sampling priority; returns `false` (and leaves `out` untouched) when unset. + */ +bool ddog_v1_get_chunk_sampling_priority(const struct ddog_ChunkNode *chunk, int32_t *out); /** - * The return value is an owned array of slices (`Box<[CharSlice]>`) that must be freed explicitly - * through [`ddog_span_free_keys_ptr`]. + * Reads the chunk sampling mechanism; returns `false` (and leaves `out` untouched) when unset. */ -ddog_CharSlice *ddog_span_meta_get_keys(ddog_SpanBytes *span, uintptr_t *out_count); +bool ddog_v1_get_chunk_sampling_mechanism(const struct ddog_ChunkNode *chunk, uint32_t *out); + +ddog_CharSlice ddog_v1_get_chunk_origin(const struct ddog_ChunkNode *chunk); + +ddog_CharSlice ddog_v1_get_span_service(const struct ddog_SpanNode *span); + +ddog_CharSlice ddog_v1_get_span_name(const struct ddog_SpanNode *span); + +ddog_CharSlice ddog_v1_get_span_resource(const struct ddog_SpanNode *span); -void ddog_add_span_metrics(ddog_SpanBytes *span, ddog_CharSlice key, double val); +ddog_CharSlice ddog_v1_get_span_type(const struct ddog_SpanNode *span); -void ddog_del_span_metrics(ddog_SpanBytes *span, ddog_CharSlice key); +ddog_CharSlice ddog_v1_get_span_env(const struct ddog_SpanNode *span); -bool ddog_get_span_metrics(ddog_SpanBytes *span, ddog_CharSlice key, double *result); +ddog_CharSlice ddog_v1_get_span_version(const struct ddog_SpanNode *span); -bool ddog_has_span_metrics(ddog_SpanBytes *span, ddog_CharSlice key); +ddog_CharSlice ddog_v1_get_span_component(const struct ddog_SpanNode *span); -ddog_CharSlice *ddog_span_metrics_get_keys(ddog_SpanBytes *span, uintptr_t *out_count); +uint64_t ddog_v1_get_span_id(const struct ddog_SpanNode *span); -void ddog_add_span_meta_struct(ddog_SpanBytes *span, ddog_CharSlice key, ddog_CharSlice val); +uint64_t ddog_v1_get_span_parent_id(const struct ddog_SpanNode *span); -void ddog_del_span_meta_struct(ddog_SpanBytes *span, ddog_CharSlice key); +int64_t ddog_v1_get_span_start(const struct ddog_SpanNode *span); -ddog_CharSlice ddog_get_span_meta_struct(ddog_SpanBytes *span, ddog_CharSlice key); +int64_t ddog_v1_get_span_duration(const struct ddog_SpanNode *span); -bool ddog_has_span_meta_struct(ddog_SpanBytes *span, ddog_CharSlice key); +bool ddog_v1_get_span_error(const struct ddog_SpanNode *span); /** - * The return value is an array of slices (`Box<[CharSlice]>`) that must be freed explicitly - * through [`ddog_span_free_keys_ptr`]. + * The span kind as its OTEL wire value. */ -ddog_CharSlice *ddog_span_meta_struct_get_keys(ddog_SpanBytes *span, uintptr_t *out_count); +uint32_t ddog_v1_get_span_kind(const struct ddog_SpanNode *span); + +uint64_t ddog_v1_get_link_trace_id_high(const ddog_SpanLinkBytes *link); + +uint64_t ddog_v1_get_link_trace_id_low(const ddog_SpanLinkBytes *link); + +uint64_t ddog_v1_get_link_span_id(const ddog_SpanLinkBytes *link); + +uint32_t ddog_v1_get_link_flags(const ddog_SpanLinkBytes *link); + +ddog_CharSlice ddog_v1_get_link_tracestate(const ddog_SpanLinkBytes *link); + +uint64_t ddog_v1_get_event_time(const ddog_SpanEventBytes *event); + +ddog_CharSlice ddog_v1_get_event_name(const ddog_SpanEventBytes *event); /** + * Number of entries in `attrs`, including not-yet-deduped repeated keys (the last one wins). + * * # Safety + * `attrs` must be a live [`Attributes`] handle (applies to every `ddog_v1_attributes_*`). + */ +uintptr_t ddog_v1_attributes_len(const struct ddog_Attributes *attrs); + +/** + * Key of the entry at `idx` (empty if out of range). * - * `keys_ptr` must have been returned by one of the `ddog_xxx_get_keys()` functions, and must not - * have been already freed. + * # Safety + * See [`ddog_v1_attributes_len`]. */ -void ddog_span_free_keys_ptr(ddog_CharSlice *keys_ptr, uintptr_t count); +ddog_CharSlice ddog_v1_attributes_key(const struct ddog_Attributes *attrs, uintptr_t idx); -ddog_SpanLinkBytes *ddog_span_new_link(ddog_SpanBytes *span); +/** + * Value of the entry at `idx` (null if out of range). + * + * # Safety + * See [`ddog_v1_attributes_len`]. + */ +const struct ddog_AttrValue *ddog_v1_attributes_value(const struct ddog_Attributes *attrs, + uintptr_t idx); -void ddog_set_link_tracestate(ddog_SpanLinkBytes *link, ddog_CharSlice slice); +/** + * Value of `key` (null if absent). + * + * # Safety + * See [`ddog_v1_attributes_len`]. + */ +const struct ddog_AttrValue *ddog_v1_attributes_get(const struct ddog_Attributes *attrs, + ddog_CharSlice key); + +/** + * [`DDOG_V1_ATTR_*`] type tag of `value`. + * + * # Safety + * `value` must be a live [`AttrValue`] handle (applies to every `ddog_v1_value_*`). + */ +uint32_t ddog_v1_value_type(const struct ddog_AttrValue *value); + +/** + * The string (empty unless a `String`). + * + * # Safety + * See [`ddog_v1_value_type`]. + */ +ddog_CharSlice ddog_v1_value_str(const struct ddog_AttrValue *value); -void ddog_set_link_trace_id(ddog_SpanLinkBytes *link, uint64_t value); +/** + * The bytes (empty unless `Bytes`). + * + * # Safety + * See [`ddog_v1_value_type`]. + */ +ddog_CharSlice ddog_v1_value_bytes(const struct ddog_AttrValue *value); -void ddog_set_link_trace_id_high(ddog_SpanLinkBytes *link, uint64_t value); +/** + * The integer (0 unless an `Int`). + * + * # Safety + * See [`ddog_v1_value_type`]. + */ +int64_t ddog_v1_value_int(const struct ddog_AttrValue *value); -void ddog_set_link_span_id(ddog_SpanLinkBytes *link, uint64_t value); +/** + * The double (0.0 unless a `Float`). + * + * # Safety + * See [`ddog_v1_value_type`]. + */ +double ddog_v1_value_double(const struct ddog_AttrValue *value); -void ddog_set_link_flags(ddog_SpanLinkBytes *link, uint32_t value); +/** + * The boolean (false unless a true `Bool`). + * + * # Safety + * See [`ddog_v1_value_type`]. + */ +bool ddog_v1_value_bool(const struct ddog_AttrValue *value); -void ddog_add_link_attributes(ddog_SpanLinkBytes *link, ddog_CharSlice key, ddog_CharSlice val); +/** + * Number of elements (0 unless a `List`). + * + * # Safety + * See [`ddog_v1_value_type`]. + */ +uintptr_t ddog_v1_value_list_len(const struct ddog_AttrValue *value); -ddog_SpanEventBytes *ddog_span_new_event(ddog_SpanBytes *span); +/** + * Element `idx` (null unless a `List` with that element). + * + * # Safety + * See [`ddog_v1_value_type`]. + */ +const struct ddog_AttrValue *ddog_v1_value_list_get(const struct ddog_AttrValue *value, + uintptr_t idx); -void ddog_set_event_name(ddog_SpanEventBytes *event, ddog_CharSlice slice); +/** + * The members of a `KeyValue`, read with the `ddog_v1_attributes_*` family (null otherwise). + * + * # Safety + * See [`ddog_v1_value_type`]. + */ +const struct ddog_Attributes *ddog_v1_value_map(const struct ddog_AttrValue *value); -void ddog_set_event_time(ddog_SpanEventBytes *event, uint64_t val); +/** + * Renders a span for dd-trace-php's `DD_TRACE_DEBUG` "Encoding span" line. Takes the owning + * chunk/span node pointers (the outer frame's still-live handles), so it works mid-build before + * the nodes are folded into the inline payload. The returned owned slice must be freed with + * [`ddog_free_charslice`]. + * + * # Safety + * `chunk`/`span` must be live node pointers previously returned by + * `ddog_new_chunk`/`ddog_new_span` (with `span` a span of `chunk`). + */ +ddog_CharSlice ddog_v1_span_debug_log(struct ddog_ChunkNode *chunk, struct ddog_SpanNode *span); -void ddog_add_event_attributes_str(ddog_SpanEventBytes *event, - ddog_CharSlice key, - ddog_CharSlice val); +/** + * Frees an owned [`CharSlice`]. Only the few functions that document it return owned slices (the + * V1 [`ddog_v1_span_debug_log`] and the v0.4 + * [`crate::span_v04::ddog_serialize_trace_into_charslice`]); borrowed slices must NOT be passed + * here. An owned slice allocates `len + 1` bytes (payload + NUL), reclaimed here with that exact + * shape; a zero-length slice is always borrowed and owns nothing. + * + * # Safety + * + * `slice` must be an owned char slice that has been returned by one of the functions of this API. + */ +void ddog_free_charslice(ddog_CharSlice slice); -void ddog_add_event_attributes_bool(ddog_SpanEventBytes *event, ddog_CharSlice key, bool val); +void ddog_free_traces(ddog_TracesBytes *_traces); -void ddog_add_event_attributes_int(ddog_SpanEventBytes *event, ddog_CharSlice key, int64_t val); +uintptr_t ddog_get_traces_size(const ddog_TracesBytes *traces); -void ddog_add_event_attributes_float(ddog_SpanEventBytes *event, ddog_CharSlice key, double val); +ddog_TraceBytes *ddog_get_trace(ddog_TracesBytes *traces, uintptr_t index); /** - * The returned slice is an owned allocation that must be properly freed using - * [`ddog_free_charslice`]. + * Serializes one v0.4 trace as a msgpack array-of-1, the framing the background sender + * (`ddtrace_send_traces_via_thread`) expects. Returns an owned slice; free with + * [`crate::span::ddog_free_charslice`]. */ ddog_CharSlice ddog_serialize_trace_into_charslice(ddog_TraceBytes *trace); diff --git a/components-rs/tracer_runtime/bytes.rs b/components-rs/tracer_runtime/bytes.rs index 01e46de90b8..c3a67b8b516 100644 --- a/components-rs/tracer_runtime/bytes.rs +++ b/components-rs/tracer_runtime/bytes.rs @@ -1,8 +1,8 @@ -use libdd_common_ffi::slice::{AsBytes, CharSlice}; +use datadog_sidecar_ffi::span::{attrs_mut, bytes_string_from_literal, Attributes, SpanNode}; +use libdd_common_ffi::slice::CharSlice; use libdd_tinybytes::{Bytes, BytesString, RefCountedCell, RefCountedCellVTable}; -use libdd_trace_utils::span::v04::SpanBytes; +use libdd_trace_utils::span::v1::AttributeValueBytes; use std::borrow::Cow; -use std::ffi::CStr; use std::os::raw::c_char; use std::ptr::NonNull; @@ -132,212 +132,616 @@ fn convert_zend_to_bytes_string(zend_str: &mut ZendString) -> BytesString { } } -fn convert_char_slice_to_bytes_string(slice: CharSlice) -> BytesString { - match String::from_utf8_lossy(slice.as_bytes().as_ref()) { - Cow::Owned(s) => s.into(), - Cow::Borrowed(_) => unsafe { - BytesString::from_bytes_unchecked(slice.as_bytes().to_vec().into()) - }, - } -} - -fn convert_literal_to_bytes_string(string: *const c_char) -> BytesString { - unsafe { - let cstring = CStr::from_ptr(string); - - match String::from_utf8_lossy(cstring.to_bytes()) { - Cow::Owned(s) => s.into(), - Cow::Borrowed(s) => BytesString::from_static(s), - } - } -} +// PHP-specific additions to the V1 builder FFI (`datadog_sidecar_ffi::span`): zero-copy +// zend_string fields and static C-literal keys. +/// # Safety +/// `span` must be a live span node pointer from `ddog_new_span` (every `*_zstr` span setter). #[no_mangle] -pub extern "C" fn ddog_set_span_service_zstr(ptr: &mut SpanBytes, str: &mut ZendString) { - ptr.service = convert_zend_to_bytes_string(str); +pub unsafe extern "C" fn ddog_set_span_service_zstr(span: *mut SpanNode, str: &mut ZendString) { + (*span).span_mut().service = convert_zend_to_bytes_string(str); } +/// # Safety +/// See [`ddog_set_span_service_zstr`]. #[no_mangle] -pub extern "C" fn ddog_set_span_name_zstr(ptr: &mut SpanBytes, str: &mut ZendString) { - ptr.name = convert_zend_to_bytes_string(str); +pub unsafe extern "C" fn ddog_set_span_name_zstr(span: *mut SpanNode, str: &mut ZendString) { + (*span).span_mut().name = convert_zend_to_bytes_string(str); } +/// # Safety +/// See [`ddog_set_span_service_zstr`]. #[no_mangle] -pub extern "C" fn ddog_set_span_resource_zstr(ptr: &mut SpanBytes, str: &mut ZendString) { - ptr.resource = convert_zend_to_bytes_string(str); +pub unsafe extern "C" fn ddog_set_span_resource_zstr(span: *mut SpanNode, str: &mut ZendString) { + (*span).span_mut().resource = convert_zend_to_bytes_string(str); } +/// # Safety +/// See [`ddog_set_span_service_zstr`]. #[no_mangle] -pub extern "C" fn ddog_set_span_type_zstr(ptr: &mut SpanBytes, str: &mut ZendString) { - ptr.r#type = convert_zend_to_bytes_string(str); +pub unsafe extern "C" fn ddog_set_span_type_zstr(span: *mut SpanNode, str: &mut ZendString) { + (*span).span_mut().r#type = convert_zend_to_bytes_string(str); } +/// String attribute under a static C literal key. +/// +/// # Safety +/// `attrs` must be a live `Attributes` handle and `key` a static NUL-terminated string (applies +/// to every attribute adder below). #[no_mangle] -pub extern "C" fn ddog_add_span_meta_zstr( - ptr: &mut SpanBytes, - key: &mut ZendString, - val: &mut ZendString, +pub unsafe extern "C" fn ddog_attributes_add_lit( + attrs: *mut Attributes, + key: *const c_char, + value: CharSlice, ) { - ptr.meta.insert( - convert_zend_to_bytes_string(key), - convert_zend_to_bytes_string(val), - ); + let value = AttributeValueBytes::String(datadog_sidecar_ffi::span::bytes_string_from_slice(value)); + attrs_mut(attrs).insert(bytes_string_from_literal(key), value); } +/// String attribute sharing both zend strings (zero-copy). +/// +/// # Safety +/// See [`ddog_attributes_add_lit`]. #[no_mangle] -pub extern "C" fn ddog_add_CharSlice_span_meta_zstr( - ptr: &mut SpanBytes, - key: CharSlice, - val: &mut ZendString, -) { - ptr.meta.insert( - convert_char_slice_to_bytes_string(key), - convert_zend_to_bytes_string(val), - ); -} - -#[no_mangle] -pub extern "C" fn ddog_add_zstr_span_meta_str( - ptr: &mut SpanBytes, +pub unsafe extern "C" fn ddog_attributes_add_zstr( + attrs: *mut Attributes, key: &mut ZendString, - val: *const c_char, + value: &mut ZendString, ) { - ptr.meta.insert( + attrs_mut(attrs).insert( convert_zend_to_bytes_string(key), - convert_literal_to_bytes_string(val), + AttributeValueBytes::String(convert_zend_to_bytes_string(value)), ); } +/// Double attribute under a static C literal key. +/// +/// # Safety +/// See [`ddog_attributes_add_lit`]. #[no_mangle] -pub extern "C" fn ddog_add_str_span_meta_str( - ptr: &mut SpanBytes, +pub unsafe extern "C" fn ddog_attributes_add_double_lit( + attrs: *mut Attributes, key: *const c_char, - val: *const c_char, + value: f64, ) { - ptr.meta.insert( - convert_literal_to_bytes_string(key), - convert_literal_to_bytes_string(val), - ); + attrs_mut(attrs).insert(bytes_string_from_literal(key), AttributeValueBytes::Float(value)); } +/// Double attribute under a shared zend string key (zero-copy). +/// +/// # Safety +/// See [`ddog_attributes_add_lit`]. #[no_mangle] -pub extern "C" fn ddog_add_str_span_meta_zstr( - ptr: &mut SpanBytes, - key: *const c_char, - val: &mut ZendString, +pub unsafe extern "C" fn ddog_attributes_add_double_zstr( + attrs: *mut Attributes, + key: &mut ZendString, + value: f64, ) { - ptr.meta.insert( - convert_literal_to_bytes_string(key), - convert_zend_to_bytes_string(val), - ); -} + attrs_mut(attrs).insert(convert_zend_to_bytes_string(key), AttributeValueBytes::Float(value)); +} + +#[cfg(test)] +mod v04_parity_tests { + // Wire-safety gate: the v0.4 downgrade of a NATIVE nested attribute carries the SAME dotted + // `meta` / `metrics` keys+values (and same meta-vs-metrics bucketing) the OLD C dotted flatten + // produced. Each case builds both shapes through the FFI, encodes both to v0.4, and compares the + // decoded `meta` / `metrics` maps order-insensitively — msgpack map key order is not significant + // for v0.4 consumers, and it is the only byte-level difference between the two encodings (it + // stems from `VecMap::dedup` reversing entries, which reorders nested vs flat topologies + // differently; list indices / map members are encoded in the dotted keys, so no data changes). + use datadog_sidecar_ffi::span::*; + use libdd_common_ffi::slice::CharSlice; + use libdd_trace_utils::msgpack_encoder::v04::to_vec_from_v1; + use libdd_trace_utils::span::v1::SpanKind; + use rmpv::Value; + + fn cs(s: &str) -> CharSlice<'_> { + CharSlice::from_bytes(s.as_bytes()) + } -#[no_mangle] -pub extern "C" fn ddog_add_str_span_meta_CharSlice( - ptr: &mut SpanBytes, - key: *const c_char, - val: CharSlice, -) { - ptr.meta.insert( - convert_literal_to_bytes_string(key), - convert_char_slice_to_bytes_string(val), - ); -} + fn one_span_builder() -> (TracerPayloadV1Builder, *mut SpanNode) { + let mut b = TracerPayloadV1Builder::default(); + let c = b.push_chunk(0, 1); + // Safety: `c` is the live chunk node just pushed. + let s = unsafe { (*c).push_span() }; + (b, s) + } -#[no_mangle] -pub extern "C" fn ddog_del_span_meta_zstr(ptr: &mut SpanBytes, key: &mut ZendString) { - ptr.meta.remove_slow(&convert_zend_to_bytes_string(key)); -} + /// Decodes v0.4 bytes (`[[span,...],...]`) and returns the first span's map. + fn first_span(bytes: &[u8]) -> Value { + match rmpv::decode::read_value(&mut &bytes[..]).expect("valid msgpack") { + Value::Array(traces) => match traces.into_iter().next().expect("one trace") { + Value::Array(spans) => spans.into_iter().next().expect("one span"), + other => panic!("trace not an array: {other:?}"), + }, + other => panic!("payload not an array: {other:?}"), + } + } -#[no_mangle] -pub extern "C" fn ddog_del_span_meta_str(ptr: &mut SpanBytes, key: *const c_char) { - ptr.meta.remove_slow(&convert_literal_to_bytes_string(key)); -} + /// Extracts `span[key]` (a `meta`/`metrics` map) as `(key, value)` pairs sorted by key, so two + /// encodings can be compared independently of msgpack map serialization order. + fn sorted_bucket(span: &Value, key: &str) -> Vec<(String, Value)> { + let entries = match span { + Value::Map(entries) => entries, + other => panic!("span not a map: {other:?}"), + }; + let mut out = Vec::new(); + if let Some((_, Value::Map(bucket))) = + entries.iter().find(|(k, _)| k.as_str() == Some(key)) + { + for (k, v) in bucket { + out.push((k.as_str().expect("string key").to_string(), v.clone())); + } + } + out.sort_by(|a, b| a.0.cmp(&b.0)); + out + } -#[no_mangle] -pub extern "C" fn ddog_has_span_meta_zstr(ptr: &mut SpanBytes, key: &mut ZendString) -> bool { - ptr.meta.contains_key(&convert_zend_to_bytes_string(key)) -} + #[test] + fn meta_nested_matches_old_flat_v04() { + // NEW: meta attr "m" = { bar: [ "1", { key: "2" }, "" ], "5": "v" } + // (String leaves, as the meta path stringifies — mirrors the old convert_to_double=false). + let (newb, s) = one_span_builder(); + unsafe { + let bar = ddog_attr_list_new(3); + ddog_attr_list_push_str(bar, cs("1")); + let e = ddog_attr_map_new(1); + ddog_attributes_add_str(ddog_attr_map_get_attributes(e), cs("key"), cs("2")); + ddog_attr_list_push_map(bar, e); + ddog_attr_list_push_str(bar, cs("")); // empty/recursive placeholder equivalent + let m = ddog_attr_map_new(2); + ddog_attributes_add_list(ddog_attr_map_get_attributes(m), cs("bar"), bar); + ddog_attributes_add_str(ddog_attr_map_get_attributes(m), cs("5"), cs("v")); // numeric-keyed member -> "m.5" + ddog_attributes_add_map(ddog_span_get_attributes(s), cs("m"), m); + } -#[no_mangle] -pub extern "C" fn ddog_has_span_meta_str(ptr: &mut SpanBytes, key: *const c_char) -> bool { - ptr.meta.contains_key(&convert_literal_to_bytes_string(key)) -} + // OLD: the identical dotted keys the C flatten wrote, in traversal order. + let (oldb, s) = one_span_builder(); + unsafe { + ddog_attributes_add_str(ddog_span_get_attributes(s), cs("m.bar.0"), cs("1")); + ddog_attributes_add_str(ddog_span_get_attributes(s), cs("m.bar.1.key"), cs("2")); + ddog_attributes_add_str(ddog_span_get_attributes(s), cs("m.bar.2"), cs("")); + ddog_attributes_add_str(ddog_span_get_attributes(s), cs("m.5"), cs("v")); + } -#[no_mangle] -pub extern "C" fn ddog_get_span_meta_str( - span: &mut SpanBytes, - key: *const c_char, -) -> CharSlice<'static> { - match span.meta.get(&convert_literal_to_bytes_string(key)) { - Some(value) => unsafe { - let string_value = value.as_str(); - CharSlice::from_raw_parts(string_value.as_ptr().cast(), string_value.len()) - }, - None => CharSlice::empty(), + let new_span = first_span(&to_vec_from_v1(&newb.into_payload())); + let old_span = first_span(&to_vec_from_v1(&oldb.into_payload())); + assert_eq!( + sorted_bucket(&new_span, "meta"), + sorted_bucket(&old_span, "meta"), + "v0.4 meta keys+values of native nesting must match the old flat dotted meta" + ); + assert_eq!(sorted_bucket(&new_span, "metrics"), sorted_bucket(&old_span, "metrics")); } -} -#[no_mangle] -pub extern "C" fn ddog_add_span_metrics_zstr(ptr: &mut SpanBytes, key: &mut ZendString, val: f64) { - ptr.metrics.insert(convert_zend_to_bytes_string(key), val); -} + #[test] + fn metrics_nested_matches_old_flat_v04() { + // NEW: metrics attr "mm" = { nums: [ 1.0, 2.5 ], deep: { x: 0.0 } } + // (Float leaves, as the metrics path uses zval_get_double -> convert_to_double=true.) + let (newb, s) = one_span_builder(); + unsafe { + let mm = ddog_attr_map_new(2); + let nums = ddog_attr_list_new(2); + ddog_attr_list_push_double(nums, 1.0); + ddog_attr_list_push_double(nums, 2.5); + ddog_attributes_add_list(ddog_attr_map_get_attributes(mm), cs("nums"), nums); + let deep = ddog_attr_map_new(1); + ddog_attributes_add_double(ddog_attr_map_get_attributes(deep), cs("x"), 0.0); // empty/recursive placeholder equivalent + ddog_attributes_add_map(ddog_attr_map_get_attributes(mm), cs("deep"), deep); + ddog_attributes_add_map(ddog_span_get_attributes(s), cs("mm"), mm); + } -#[no_mangle] -pub extern "C" fn ddog_has_span_metrics_zstr(ptr: &mut SpanBytes, key: &mut ZendString) -> bool { - ptr.metrics.contains_key(&convert_zend_to_bytes_string(key)) -} + let (oldb, s) = one_span_builder(); + unsafe { + ddog_attributes_add_double(ddog_span_get_attributes(s), cs("mm.nums.0"), 1.0); + ddog_attributes_add_double(ddog_span_get_attributes(s), cs("mm.nums.1"), 2.5); + ddog_attributes_add_double(ddog_span_get_attributes(s), cs("mm.deep.x"), 0.0); + } -#[no_mangle] -pub extern "C" fn ddog_del_span_metrics_zstr(ptr: &mut SpanBytes, key: &mut ZendString) { - ptr.metrics.remove_slow(&convert_zend_to_bytes_string(key)); -} + let new_span = first_span(&to_vec_from_v1(&newb.into_payload())); + let old_span = first_span(&to_vec_from_v1(&oldb.into_payload())); + assert_eq!( + sorted_bucket(&new_span, "metrics"), + sorted_bucket(&old_span, "metrics"), + "v0.4 metrics keys+values of native nesting must match the old flat dotted metrics" + ); + assert_eq!(sorted_bucket(&new_span, "meta"), sorted_bucket(&old_span, "meta")); + } -#[no_mangle] -pub extern "C" fn ddog_add_span_metrics_str(ptr: &mut SpanBytes, key: *const c_char, val: f64) { - ptr.metrics - .insert(convert_literal_to_bytes_string(key), val); -} + /// `span[key]` (a msgpack map field) as a borrowed value. + fn field<'a>(v: &'a Value, key: &str) -> Option<&'a Value> { + match v { + Value::Map(m) => m.iter().find(|(k, _)| k.as_str() == Some(key)).map(|(_, v)| v), + _ => None, + } + } -#[no_mangle] -pub extern "C" fn ddog_get_span_metrics_str( - ptr: &mut SpanBytes, - key: *const c_char, - result: &mut f64, -) -> bool { - match ptr.metrics.get(&convert_literal_to_bytes_string(key)) { - Some(&value) => { - *result = value; - true + #[test] + fn link_nested_attr_matches_old_json_string_v04() { + // NEW: native nested link attr `nums = [3, 4]` built through the container FFI. + let (newb, s) = one_span_builder(); + unsafe { + let link = ddog_new_link(s); + let nums = ddog_attr_list_new(2); + ddog_attr_list_push_int(nums, 3); + ddog_attr_list_push_int(nums, 4); + ddog_attributes_add_list(ddog_link_get_attributes(link), cs("nums"), nums); + } + // OLD: the JSON string the pre-native serializer produced (json_encode([3,4])). + let (oldb, s) = one_span_builder(); + unsafe { + let link = ddog_new_link(s); + ddog_attributes_add_str(ddog_link_get_attributes(link), cs("nums"), cs("[3,4]")); } - None => false, + + let new_span = first_span(&to_vec_from_v1(&newb.into_payload())); + let old_span = first_span(&to_vec_from_v1(&oldb.into_payload())); + // v0.4 links are native `span_links` with String attributes: the nested value carries the + // old json_encode string. + let nums = |sp: &Value| { + let link = &field(sp, "span_links").unwrap().as_array().unwrap()[0]; + field(field(link, "attributes").unwrap(), "nums").unwrap().clone() + }; + assert_eq!(nums(&new_span).as_str(), Some("[3,4]")); + assert_eq!(nums(&new_span), nums(&old_span)); } -} -#[no_mangle] -pub extern "C" fn ddog_del_span_metrics_str(ptr: &mut SpanBytes, key: *const c_char) { - ptr.metrics - .remove_slow(&convert_literal_to_bytes_string(key)); -} + #[test] + fn event_nested_attr_downgrades_to_legacy_events_meta_native_array() { + // Native nested event attr `nums = [3, 4]` built through the container FFI. On the v0.4 + // downgrade it lands in the legacy `events` meta as a REAL JSON array (event attributes + // keep native JSON types, matching master's json_encode of the PHP attributes array — + // unlike links, which are String → String). No native `span_events` field on the v0.4 wire. + let (newb, s) = one_span_builder(); + unsafe { + let event = ddog_new_event(s); + let nums = ddog_attr_list_new(2); + ddog_attr_list_push_int(nums, 3); + ddog_attr_list_push_int(nums, 4); + ddog_attributes_add_list(ddog_event_get_attributes(event), cs("nums"), nums); + } + let new_span = first_span(&to_vec_from_v1(&newb.into_payload())); + assert!(field(&new_span, "span_events").is_none()); + let events_meta = field(field(&new_span, "meta").unwrap(), "events") + .unwrap() + .as_str() + .unwrap(); + assert!(events_meta.contains(r#""nums":[3,4]"#), "got {events_meta}"); + } -#[no_mangle] -pub extern "C" fn ddog_add_span_meta_struct_zstr( - ptr: &mut SpanBytes, - key: &mut ZendString, - val: &mut ZendString, -) { - ptr.meta_struct - .insert(convert_zend_to_bytes_string(key), convert_to_bytes(val)); + #[test] + fn span_kind_str_process_survives_v04_downgrade() { + // Mirrors tracer/serializer.c: only delete `span.kind` meta when canonical. Fixes + // AMQPIntegration's `Tag::SPAN_KIND = 'process'`, previously destroyed by enum coercion. + let (b, s) = one_span_builder(); + unsafe { + let is_canonical = ddog_set_span_kind_str(s, cs("process")); + assert!( + !is_canonical, + "\"process\" is not one of the 4 canonical kind strings" + ); + ddog_attributes_add_str(ddog_span_get_attributes(s), cs("span.kind"), cs("process")); + } + let span = first_span(&to_vec_from_v1(&b.into_payload())); + assert_eq!( + field(field(&span, "meta").unwrap(), "span.kind") + .unwrap() + .as_str(), + Some("process") + ); + // Exactly once: not duplicated as a generic attribute alongside the promoted field. + let meta_entries = match field(&span, "meta").unwrap() { + Value::Map(m) => m, + other => panic!("expected map, got {other:?}"), + }; + let kind_count = meta_entries + .iter() + .filter(|(k, _)| k.as_str() == Some("span.kind")) + .count(); + assert_eq!( + kind_count, 1, + "duplicate \"span.kind\" key written to the wire" + ); + } + + #[test] + fn span_kind_str_internal_is_canonical_and_survives_v04_downgrade() { + // An explicit "internal" is the Internal kind: serializer.c deletes the tag, and the + // downgrade writes it back from the kind. + let (b, s) = one_span_builder(); + unsafe { + assert!(ddog_set_span_kind_str(s, cs("internal"))); + } + let span = first_span(&to_vec_from_v1(&b.into_payload())); + assert_eq!( + field(field(&span, "meta").unwrap(), "span.kind") + .unwrap() + .as_str(), + Some("internal") + ); + } + + #[test] + fn span_kind_unset_stays_unspecified() { + let (b, _s) = one_span_builder(); + let payload = b.into_payload(); + assert_eq!(payload.chunks[0].spans[0].span_kind, SpanKind::Unspecified); + let span = first_span(&to_vec_from_v1(&payload)); + assert!(field(&span, "meta") + .and_then(|m| field(m, "span.kind")) + .is_none()); + } + + #[test] + fn span_kind_str_known_value_is_canonical_and_not_duplicated() { + let (b, s) = one_span_builder(); + unsafe { + let is_canonical = ddog_set_span_kind_str(s, cs("server")); + assert!(is_canonical); + // serializer.c deletes the meta key in this case; not re-added as an attribute here. + } + let span = first_span(&to_vec_from_v1(&b.into_payload())); + assert_eq!( + field(field(&span, "meta").unwrap(), "span.kind") + .unwrap() + .as_str(), + Some("server") + ); + } } -#[no_mangle] -pub extern "C" fn ddog_add_zstr_span_meta_struct_CharSlice( - ptr: &mut SpanBytes, - key: &mut ZendString, - val: CharSlice, -) { - ptr.meta_struct.insert( - convert_zend_to_bytes_string(key), - Bytes::copy_from_slice(val.as_bytes()), - ); +#[cfg(test)] +mod pointer_handle_miri_tests { + // The crux of Phase 2 comment A: prove the Box-per-node pointer model is UB-clean under Stacked + // AND Tree Borrows for the hazards the old index model was chosen to avoid. Run with + // `cargo +nightly miri test` (Stacked Borrows, the default) and with `-Zmiri-tree-borrows`. + use super::*; + use datadog_sidecar_ffi::span::*; + use libdd_trace_utils::span::v1::AttributeValueBytes; + + fn cs(s: &str) -> CharSlice<'_> { + CharSlice::from_bytes(s.as_bytes()) + } + + // (a) The inferred-span hazard (serializer.c ~2059→2098): after a SECOND span is pushed into the + // same chunk, the outer frame keeps mutating and reading its ROOT span pointer with NO refetch. + #[test] + fn a_root_span_ptr_survives_sibling_push() { + let mut b = TracerPayloadV1Builder::default(); + let chunk = b.push_chunk(0, 1); + unsafe { + let root = ddog_new_span(chunk); + ddog_span_set_id(root, 100); + ddog_span_set_error(root, true); + ddog_attributes_add_lit(ddog_span_get_attributes(root), c"moved".as_ptr(), cs("v")); + + // The sibling push that reallocs `chunk.spans`; `root` must stay valid (own allocation). + let inferred = ddog_new_span(chunk); + ddog_span_set_id(inferred, 200); + + // Use `root` AFTER the sibling push, with no refetch (mirrors the transfers/debug log). + assert!(ddog_transfer_span_attr(root, inferred, c"moved".as_ptr(), true)); + ddog_span_set_error(inferred, ddog_span_get_error(root)); + let log = ddog_v1_span_debug_log(chunk, root); + assert!(!log.is_empty()); + ddog_free_charslice(log); + } + + let payload = b.into_payload(); + let spans = &payload.chunks[0].spans; + assert_eq!(spans.len(), 2); + assert_eq!(spans[0].span_id, 100); + assert_eq!(spans[1].span_id, 200); + assert!(!spans[0].attributes.contains_key("moved"), "attr moved off root"); + assert!(spans[1].attributes.contains_key("moved"), "attr moved onto inferred"); + } + + // (b) A deep nested List/KeyValue built via the container FFI and attached to a span node + // pointer, then folded through into_payload. + #[test] + fn b_nested_attr_build_on_span_ptr() { + let mut b = TracerPayloadV1Builder::default(); + let chunk = b.push_chunk(0, 1); + unsafe { + let span = ddog_new_span(chunk); + let nested = ddog_attr_map_new(1); + ddog_attributes_add_bool(ddog_attr_map_get_attributes(nested), cs("flag"), true); + let items = ddog_attr_list_new(2); + ddog_attr_list_push_str(items, cs("a")); + ddog_attr_list_push_map(items, nested); + let root = ddog_attr_map_new(2); + ddog_attributes_add_int(ddog_attr_map_get_attributes(root), cs("n"), 7); + ddog_attributes_add_list(ddog_attr_map_get_attributes(root), cs("items"), items); + ddog_attributes_add_map(ddog_span_get_attributes(span), cs("root"), root); + } + let payload = b.into_payload(); + match payload.chunks[0].spans[0].attributes.get("root") { + Some(AttributeValueBytes::KeyValue(m)) => assert_eq!(m.len(), 2), + other => panic!("expected KeyValue, got {other:?}"), + } + } + + // (c) Links and events built on a span pointer, each fully built — including a deep nested + // List/KeyValue attribute attached to the link/event node pointer — before the next push; the + // node pointers stay valid across sibling node pushes. + #[test] + fn c_links_and_events_on_span_ptr() { + let mut b = TracerPayloadV1Builder::default(); + let chunk = b.push_chunk(0, 1); + unsafe { + let span = ddog_new_span(chunk); + let l0 = ddog_new_link(span); + ddog_link_set_span_id(l0, 11); + ddog_attributes_add_str(ddog_link_get_attributes(l0), cs("k"), cs("v")); + // Deep nested attr on l0: { tags: [ "a", { deep: 1 } ] } — fully built before l1. + let deep = ddog_attr_map_new(1); + ddog_attributes_add_int(ddog_attr_map_get_attributes(deep), cs("deep"), 1); + let tags = ddog_attr_list_new(2); + ddog_attr_list_push_str(tags, cs("a")); + ddog_attr_list_push_map(tags, deep); + ddog_attributes_add_list(ddog_link_get_attributes(l0), cs("tags"), tags); + + let l1 = ddog_new_link(span); // sibling push; l0 stays valid (own allocation) + ddog_link_set_span_id(l1, 22); + ddog_link_set_span_id(l0, 111); // still valid after the sibling push + + let e0 = ddog_new_event(span); + ddog_event_set_name(e0, cs("evt")); + ddog_attributes_add_int(ddog_event_get_attributes(e0), cs("n"), 5); + // Deep nested attr on e0: { meta: { list: [ true ] } } — fully built before e1. + let list = ddog_attr_list_new(1); + ddog_attr_list_push_bool(list, true); + let meta = ddog_attr_map_new(1); + ddog_attributes_add_list(ddog_attr_map_get_attributes(meta), cs("list"), list); + ddog_attributes_add_map(ddog_event_get_attributes(e0), cs("meta"), meta); + + let e1 = ddog_new_event(span); + ddog_event_set_time(e1, 999); + ddog_event_set_name(e0, cs("evt0")); // e0 valid after e1's push + } + let payload = b.into_payload(); + let span = &payload.chunks[0].spans[0]; + assert_eq!(span.span_links.len(), 2); + assert_eq!(span.span_links[0].span_id, 111); + match span.span_links[0].attributes.get("tags") { + Some(AttributeValueBytes::List(v)) => assert_eq!(v.len(), 2), + other => panic!("expected link List attr, got {other:?}"), + } + assert_eq!(span.span_events.len(), 2); + assert_eq!(span.span_events[0].name.as_str(), "evt0"); + match span.span_events[0].attributes.get("meta") { + Some(AttributeValueBytes::KeyValue(m)) => assert_eq!(m.len(), 1), + other => panic!("expected event KeyValue attr, got {other:?}"), + } + } + + // (d) into_payload dedups duplicate keys, and a builder dropped WITHOUT into_payload frees every + // node box (Miri's leak/double-free checker is the assertion for the drop path). + #[test] + fn d_into_payload_dedup_and_drop() { + let mut b = TracerPayloadV1Builder::default(); + let chunk = b.push_chunk(0, 1); + unsafe { + let span = ddog_new_span(chunk); + ddog_attributes_add_str(ddog_span_get_attributes(span), cs("dup"), cs("first")); + ddog_attributes_add_str(ddog_span_get_attributes(span), cs("dup"), cs("second")); + } + let payload = b.into_payload(); + let attrs = &payload.chunks[0].spans[0].attributes; + assert_eq!(attrs.len(), 1, "duplicate keys deduped in into_payload"); + + // Drop path: build a populated builder and let it fall out of scope unconsumed. + let mut d = TracerPayloadV1Builder::default(); + let c = d.push_chunk(0, 2); + unsafe { + let s = ddog_new_span(c); + ddog_new_link(s); + ddog_new_event(s); + let m = ddog_attr_map_new(1); + ddog_attributes_add_int(ddog_attr_map_get_attributes(m), cs("y"), 1); + ddog_attributes_add_map(ddog_span_get_attributes(s), cs("x"), m); + } + drop(d); + } + + // (e) A deep mixed nest (list in map in list), built once with capacity 0 (forcing regrowth) and + // once with exact capacities; both attach the same value and free cleanly. + #[test] + fn e_deep_mixed_nest_any_capacity() { + unsafe fn build(span: *mut SpanNode, key: &str, cap: impl Fn(usize) -> usize) { + let inner = ddog_attr_list_new(cap(3)); + ddog_attr_list_push_int(inner, 1); + ddog_attr_list_push_bytes(inner, cs("raw")); + ddog_attr_list_push_list(inner, ddog_attr_list_new(cap(0))); + let mid = ddog_attr_map_new(cap(2)); + ddog_attributes_add_list(ddog_attr_map_get_attributes(mid), cs("inner"), inner); + ddog_attributes_add_map(ddog_attr_map_get_attributes(mid), cs("empty"), ddog_attr_map_new(cap(0))); + let outer = ddog_attr_list_new(cap(2)); + ddog_attr_list_push_map(outer, mid); + ddog_attr_list_push_str(outer, cs("tail")); + ddog_attributes_add_list(ddog_span_get_attributes(span), cs(key), outer); + } + let mut b = TracerPayloadV1Builder::default(); + let chunk = b.push_chunk(0, 1); + unsafe { + let span = ddog_new_span(chunk); + build(span, "zero", |_| 0); + build(span, "exact", |n| n); + } + let payload = b.into_payload(); + let attrs = &payload.chunks[0].spans[0].attributes; + let shape = |key: &str| match attrs.get(key) { + Some(AttributeValueBytes::List(outer)) => { + assert_eq!(outer.len(), 2); + assert!(matches!(&outer[1], AttributeValueBytes::String(s) if s.as_str() == "tail")); + match &outer[0] { + AttributeValueBytes::KeyValue(mid) => { + assert!(matches!(mid.get("empty"), Some(AttributeValueBytes::KeyValue(m)) if m.is_empty())); + match mid.get("inner") { + Some(AttributeValueBytes::List(inner)) => { + assert!(matches!(inner[0], AttributeValueBytes::Int(1))); + assert!(matches!(&inner[1], AttributeValueBytes::Bytes(b) if b.as_ref() == b"raw")); + assert!(matches!(&inner[2], AttributeValueBytes::List(l) if l.is_empty())); + } + other => panic!("expected inner List, got {other:?}"), + } + } + other => panic!("expected KeyValue, got {other:?}"), + } + } + other => panic!("expected List, got {other:?}"), + }; + shape("zero"); + shape("exact"); + } + + // (f) Attribute handles stay valid across other calls on their node and sibling pushes, with no + // refetch: the handle shares the node pointer's tag (no intermediate `&mut` in the getter). + #[test] + fn f_attribute_handles_survive_interleaved_node_calls() { + let mut b = TracerPayloadV1Builder::default(); + let chunk = b.push_chunk(0, 1); + unsafe { + let span = ddog_new_span(chunk); + let attrs = ddog_span_get_attributes(span); + ddog_attributes_add_str(attrs, cs("a"), cs("1")); + ddog_span_set_error(span, true); + ddog_span_set_id(span, 7); + let link = ddog_new_link(span); + let link_attrs = ddog_link_get_attributes(link); + let event = ddog_new_event(span); + let event_attrs = ddog_event_get_attributes(event); + ddog_attributes_add_int(attrs, cs("b"), 2); + ddog_link_set_span_id(link, 3); + ddog_attributes_add_str(link_attrs, cs("l"), cs("v")); + let link2 = ddog_new_link(span); // sibling push + ddog_event_set_name(event, cs("e")); + ddog_attributes_add_bool(event_attrs, cs("e"), true); + ddog_attributes_add_str(ddog_link_get_attributes(link2), cs("l2"), cs("v2")); + ddog_attributes_add_double(attrs, cs("c"), 1.5); + assert!(ddog_span_get_error(span)); + let second = ddog_new_span(chunk); // sibling span push + ddog_attributes_add_str(ddog_span_get_attributes(second), cs("s"), cs("2")); + let m = ddog_attr_map_new(0); + let m_attrs = ddog_attr_map_get_attributes(m); + ddog_attributes_add_int(m_attrs, cs("x"), 1); + ddog_attributes_add_str(attrs, cs("d"), cs("4")); + ddog_attributes_add_int(m_attrs, cs("y"), 2); + ddog_attributes_add_map(attrs, cs("m"), m); + } + let payload = b.into_payload(); + let span = &payload.chunks[0].spans[0]; + assert!(span.error); + assert_eq!(span.span_id, 7); + assert_eq!(span.attributes.len(), 5); + match span.attributes.get("m") { + Some(AttributeValueBytes::KeyValue(m)) => assert_eq!(m.len(), 2), + other => panic!("expected KeyValue, got {other:?}"), + } + assert_eq!(span.span_links.len(), 2); + assert!(span.span_links[0].attributes.contains_key("l")); + assert!(span.span_links[1].attributes.contains_key("l2")); + assert!(span.span_events[0].attributes.contains_key("e")); + assert!(payload.chunks[0].spans[1].attributes.contains_key("s")); + } } diff --git a/config.m4 b/config.m4 index adfb5e7c6b5..5810d1ab914 100644 --- a/config.m4 +++ b/config.m4 @@ -309,6 +309,7 @@ if test "$PHP_DDTRACE" != "no"; then tracer/standalone_limiter.c \ tracer/span.c \ tracer/span_stats.c \ + tracer/span_tags_view.c \ tracer/trace_filter.c \ tracer/trace_source.c \ tracer/tracer_startup_logging.c \ diff --git a/config.w32 b/config.w32 index c30060f8606..77c466b3570 100644 --- a/config.w32 +++ b/config.w32 @@ -78,6 +78,7 @@ if (PHP_DDTRACE != 'no') { DDTRACE_TRACER_SOURCES += " serializer.c"; DDTRACE_TRACER_SOURCES += " span.c"; DDTRACE_TRACER_SOURCES += " span_stats.c"; + DDTRACE_TRACER_SOURCES += " span_tags_view.c"; DDTRACE_TRACER_SOURCES += " standalone_limiter.c"; DDTRACE_TRACER_SOURCES += " trace_filter.c"; DDTRACE_TRACER_SOURCES += " trace_source.c"; diff --git a/ext/agent_info.h b/ext/agent_info.h index 476248ef587..abf9a3e7770 100644 --- a/ext/agent_info.h +++ b/ext/agent_info.h @@ -1,6 +1,7 @@ #ifndef DATADOG_AGENT_INFO_H #define DATADOG_AGENT_INFO_H +#include #include #include "Zend/zend_types.h" diff --git a/ext/compatibility.h b/ext/compatibility.h index 054fcf58c06..2a74285fdec 100644 --- a/ext/compatibility.h +++ b/ext/compatibility.h @@ -311,9 +311,11 @@ static zend_always_inline void _gc_try_delref(zend_refcounted_h *_rc) { #define GC_PROTECT_RECURSION(gc) (++(gc)->u.v.nApplyCount) #define GC_UNPROTECT_RECURSION(gc) (--(gc)->u.v.nApplyCount) -#define Z_IS_RECURSIVE_P(zv) GC_IS_RECURSIVE(Z_OBJPROP_P(zv)) -#define Z_PROTECT_RECURSION_P(zv) GC_PROTECT_RECURSION(Z_OBJPROP_P(zv)) -#define Z_UNPROTECT_RECURSION_P(zv) GC_UNPROTECT_RECURSION(Z_OBJPROP_P(zv)) +// Like 7.3+ (which marks the zval's own counted): arrays are marked on themselves, objects on their property table. +#define DD_RECURSION_HT_P(zv) (Z_TYPE_P(zv) == IS_ARRAY ? Z_ARR_P(zv) : Z_OBJPROP_P(zv)) +#define Z_IS_RECURSIVE_P(zv) GC_IS_RECURSIVE(DD_RECURSION_HT_P(zv)) +#define Z_PROTECT_RECURSION_P(zv) GC_PROTECT_RECURSION(DD_RECURSION_HT_P(zv)) +#define Z_UNPROTECT_RECURSION_P(zv) GC_UNPROTECT_RECURSION(DD_RECURSION_HT_P(zv)) #define ZEND_CLOSURE_OBJECT(op_array) \ ((zend_object*)((char*)(op_array) - sizeof(zend_object))) @@ -477,6 +479,7 @@ static inline int datadog_declare_property_ex(zend_class_entry *ce, zend_string #endif #define ZEND_TYPE_INIT_MASK(type) NULL +#define ZEND_TYPE_INIT_NONE(extra_flags) NULL #define ZEND_TYPE_INIT_CLASS(class_name, allow_null, extra_flags) NULL; zend_string_release(class_name) #define ZEND_ARG_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, default_value) ZEND_ARG_INFO(pass_by_ref, name) @@ -821,6 +824,9 @@ static inline zend_string *zend_ini_str(const char *name, size_t name_length, bo #define ZEND_GUARD_PROPERTY_MASK 0xf +// Pre-8.3 php-src used a bare GC_DELREF here; also free on zero, which it leaked. +#define GC_DTOR_NO_REF(p) do { if (GC_DELREF(p) == 0) rc_dtor_func((zend_refcounted *)(p)); } while (0) + // strip const #if PHP_VERSION_ID < 70300 #undef zval_get_double diff --git a/ext/configuration.h b/ext/configuration.h index 6416f741d72..4d4b51d047a 100644 --- a/ext/configuration.h +++ b/ext/configuration.h @@ -18,6 +18,11 @@ enum datadog_sidecar_connection_mode { DD_TRACE_SIDECAR_CONNECTION_MODE_THREAD = 2, // Force thread only }; +enum datadog_trace_agent_protocol_version { + DD_TRACE_AGENT_PROTOCOL_VERSION_V1 = 0, // Default: V1 when the agent advertises /v1.0/traces, else v0.4 + DD_TRACE_AGENT_PROTOCOL_VERSION_V04 = 1, // Always v0.4 +}; + /* From the curl docs on CONNECT_TIMEOUT_MS: * If libcurl is built to use the standard system name resolver, that * portion of the transfer will still use full-second resolution for @@ -103,6 +108,8 @@ enum datadog_sidecar_connection_mode { CONFIG(INT, DD_TRACE_SIDECAR_BACKPRESSURE_QUEUE, "100", .ini_change = zai_config_system_ini_change) \ CONFIG(STRING, DD_TRACE_AGENT_TEST_SESSION_TOKEN, "", .ini_change = datadog_alter_test_session_token) \ CONFIG(CUSTOM(INT), DD_TRACE_SIDECAR_CONNECTION_MODE, "auto", .parser = dd_parse_sidecar_connection_mode) \ + CONFIG(CUSTOM(INT), DD_TRACE_AGENT_PROTOCOL_VERSION, "1.0", \ + .parser = dd_parse_trace_agent_protocol_version, .ini_change = zai_config_system_ini_change) \ CONFIG(STRING, DD_TRACE_LOG_FILE, "", .ini_change = zai_config_system_ini_change) \ CONFIG(STRING, DD_TRACE_LOG_LEVEL, "error", .ini_change = datadog_alter_dd_trace_log_level, \ .env_config_fallback = ddtrace_conf_otel_log_level) \ diff --git a/ext/ffi_utils.h b/ext/ffi_utils.h index 5ee2c166e76..7893c77402b 100644 --- a/ext/ffi_utils.h +++ b/ext/ffi_utils.h @@ -12,8 +12,13 @@ static inline ddog_CharSlice dd_zai_string_to_CharSlice(zai_string str) { return (ddog_CharSlice){ .len = str.len, .ptr = str.ptr }; } +// An empty Rust slice carries a dangling (e.g. 0x1) ptr; never hand it to a Zend API. +static inline const char *dd_CharSlice_ptr(ddog_CharSlice slice) { + return slice.len ? slice.ptr : ""; +} + static inline zend_string *dd_CharSlice_to_zend_string(ddog_CharSlice slice) { - return zend_string_init(slice.ptr, slice.len, 0); + return zend_string_init(dd_CharSlice_ptr(slice), slice.len, 0); } static inline bool datadog_ffi_try(const char *msg, ddog_MaybeError maybe_error) { diff --git a/ext/sidecar.c b/ext/sidecar.c index 78a8c53da91..0bdfaa5e771 100644 --- a/ext/sidecar.c +++ b/ext/sidecar.c @@ -245,7 +245,8 @@ static void dd_sidecar_configure(ddog_SidecarTransport **transport) { dd_zend_string_to_CharSlice(get_global_DD_HOSTNAME()), dd_zend_string_to_CharSlice(get_global_DD_SERVICE()), root_session_id, - parent_session_id + parent_session_id, + get_global_DD_TRACE_AGENT_PROTOCOL_VERSION() == DD_TRACE_AGENT_PROTOCOL_VERSION_V04 ); if (normalized_service_name) { ddog_free_normalized_tag_value(normalized_service_name); diff --git a/libdatadog b/libdatadog index 634af2c847b..ce08082993a 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 634af2c847b1d0b7f6f89dff4f715a7828da93c4 +Subproject commit ce08082993a50ea3e08d5e78f2177d70198e1aa7 diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index fb7b7744f9f..161a2bedbab 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -774,6 +774,13 @@ "default": "8126" } ], + "DD_TRACE_AGENT_PROTOCOL_VERSION": [ + { + "implementation": "B", + "type": "string", + "default": "1.0" + } + ], "DD_TRACE_AGENT_RETRIES": [ { "implementation": "A", @@ -2292,9 +2299,9 @@ ], "DD_TRACE_SIDECAR_TRACE_SENDER": [ { - "implementation": "A", + "implementation": "B", "type": "boolean", - "default": "false" + "default": "true" } ], "DD_TRACE_SLIM_ANALYTICS_ENABLED": [ @@ -2522,13 +2529,6 @@ "default": "true" } ], - "DD_TRACE_WARN_LEGACY_DD_TRACE": [ - { - "implementation": "A", - "type": "boolean", - "default": "true" - } - ], "DD_TRACE_WEBSOCKET_MESSAGES_ENABLED": [ { "implementation": "A", diff --git a/tooling/generate-supported-configurations.sh b/tooling/generate-supported-configurations.sh index 7a6f505895a..7eae0ecbddc 100755 --- a/tooling/generate-supported-configurations.sh +++ b/tooling/generate-supported-configurations.sh @@ -379,11 +379,7 @@ extract_c_supported_configurations() { #undef PHP_VERSION_ID #define PHP_VERSION_ID $PHP_VERSION_ID #undef DD_SIDECAR_TRACE_SENDER_DEFAULT -#if PHP_VERSION_ID >= 80300 #define DD_SIDECAR_TRACE_SENDER_DEFAULT true -#else -#define DD_SIDECAR_TRACE_SENDER_DEFAULT false -#endif // Do not expand CALIASES() directly, otherwise parameter counting in macros is broken. #define ALTCALIASES(...) ,##__VA_ARGS__ #define ALT diff --git a/tracer/auto_flush.c b/tracer/auto_flush.c index 1c83d753e5a..b728892b1ed 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" @@ -23,27 +25,33 @@ ZEND_EXTERN_MODULE_GLOBALS(datadog); ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles, bool fast_shutdown) { bool success = true; - ddog_TracesBytes *traces = ddog_get_traces(); + // Serialization fills the native V1 builder directly (no v0.4 intermediate). The sidecar + // negotiates V1-vs-v0.4; the in-process (<=8.2) sender downgrades to v0.4 at flush time. + ddtrace_serialize_ctx serialize_ctx = { + .builder = ddog_v1_new_builder(), + .chunk = DD_CHUNK_NONE, + .mark_top_level = get_global_DD_TRACE_SIDECAR_TRACE_SENDER(), + }; + ddtrace_serialize_ctx *ctx = &serialize_ctx; + if (collect_cycles) { - success = ddtrace_serialize_closed_spans_with_cycle(traces, fast_shutdown); + ddtrace_serialize_closed_spans_with_cycle(ctx, fast_shutdown); } else { - success = ddtrace_serialize_closed_spans(traces, fast_shutdown); - } - if (!success) { - ddog_free_traces(traces); - return FAILURE; + ddtrace_serialize_closed_spans(ctx, 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)) { - ddog_free_traces(traces); + ddog_v1_free_builder(ctx->builder); return SUCCESS; } - if (!ddog_get_traces_size(traces)) { - ddog_free_traces(traces); + // Spans are built into the builder, not the (empty) V0.4 traces, so gate on the chunk count. + size_t payload_count = ddog_v1_get_chunk_count(ctx->builder); + if (!payload_count) { + ddog_v1_free_builder(ctx->builder); LOG(INFO, "No finished traces to be sent to the agent"); return SUCCESS; } @@ -61,7 +69,7 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles .lang_vendor = DDOG_CHARSLICE_C_BARE(""), .tracer_version = DDOG_CHARSLICE_C_BARE(PHP_DDTRACE_VERSION), .lang_version = php_version_rt, - .client_computed_top_level = get_DD_TRACE_STATS_COMPUTATION_ENABLED(), + .client_computed_top_level = true, // the serializer marked them (mark_top_level) .client_computed_stats = !get_global_DD_APM_TRACING_ENABLED() || (get_DD_TRACE_STATS_COMPUTATION_ENABLED() && ddog_agent_has_stats_computation()), }, .transport = DATADOG_G(sidecar), @@ -70,46 +78,60 @@ 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); + // lang/tracer_version/container_id come from parameters.tracer_headers_tags; process + // tags travel as the payload attribute "_dd.tags.process". + uint8_t formatted_runtime_id[36]; + datadog_format_runtime_id(&formatted_runtime_id); + // env/app_version/hostname/git were set on the builder from the first root span. + ddog_TracerMetadataV1 metadata = { + .runtime_id = (ddog_CharSlice) {.ptr = (char *) formatted_runtime_id, .len = sizeof(formatted_runtime_id)}, + }; + ddog_send_traces_to_sidecar_v1(ctx->builder, ¶meters, &metadata); // consumes the builder } else { + ddog_v1_free_builder(ctx->builder); // not handed to any FFI on this path LOGEV(INFO, { log("Skipping flushing trace as connection to sidecar failed"); }); } } 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); + // Removable v0.4 bolt-on: the in-process (<=8.2) background sender's array-of-1 framing can't + // parse a native V1 payload (one msgpack MAP), so it downgrades to v0.4 traces. Delete to revert. + // Consumes ctx->builder; returns a v0.4 collection to free below. + ddog_TracesBytes *v04_traces = ddog_downgrade_v1_builder_to_v04_traces(ctx->builder); + size_t trace_count = ddog_get_traces_size(v04_traces); + for (size_t i = 0; i < trace_count; i++) { + // One msgpack array-of-1 per trace, matching the background sender's framing. + ddog_CharSlice payload = ddog_serialize_trace_into_charslice(ddog_get_trace(v04_traces, i)); + if (payload.len > 0 && payload.len <= limit) { + if (!ddtrace_send_traces_via_thread(1, payload.ptr, payload.len)) { 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); + // Bump the coms group id per trace: the background sender sizes the outer msgpack + // array by the number of distinct group ids, so each trace needs its own id or N>1 + // traces collapse to array-of-1 and the agent keeps only the first. + 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); + } + if (success) { + LOGEV(INFO, { + log("Flushing %zu v0.4 trace(s) to send-queue for %s", trace_count, url); + }); } + ddog_free_traces(v04_traces); #else + ddog_v1_free_builder(ctx->builder); // in-process sender unavailable on Windows; not consumed success = false; #endif } free(url); - ddog_free_traces(traces); return success ? SUCCESS : FAILURE; } diff --git a/tracer/code_origins.c b/tracer/code_origins.c index 44977c41b2b..0b91c93e700 100644 --- a/tracer/code_origins.c +++ b/tracer/code_origins.c @@ -12,7 +12,7 @@ static inline bool dd_is_dir_sep(const char c) { } void ddtrace_add_code_origin_information(ddtrace_span_data *span, int skip_frames) { - zend_array *meta = ddtrace_property_array(&span->property_meta); + zend_array *meta = ddtrace_property_array(&span->property_attributes); zend_long max_frames = get_DD_CODE_ORIGIN_MAX_USER_FRAMES(); int current_frame = 0, collected_frames = 0; @@ -42,7 +42,10 @@ void ddtrace_add_code_origin_information(ddtrace_span_data *span, int skip_frame } if (collected_frames == 0) { - zval type, *kind = zend_hash_str_find_deref(meta, ZEND_STRL("span.kind")); + zval type, *kind = ddtrace_span_find_tag(span, ZEND_STRL("span.kind")); + if (kind) { + ZVAL_DEREF(kind); + } ZVAL_STRING(&type, (kind && Z_TYPE_P(kind) == IS_STRING ? zend_string_equals_literal(Z_STR_P(kind), "server") || zend_string_equals_literal(Z_STR_P(kind), "producer") : &span->root->span == span) ? "entry" : "exit"); if (!zend_hash_str_add(meta, ZEND_STRL("_dd.code_origin.type"), &type)) { zend_string_release(Z_STR(type)); @@ -59,7 +62,8 @@ void ddtrace_add_code_origin_information(ddtrace_span_data *span, int skip_frame zend_string_release(key); key = zend_strpprintf(0, "_dd.code_origin.frames.%d.line", current_frame); - ZVAL_LONG(&zv, current_frame == 0 ? EX(func)->op_array.line_start : EX(opline)->lineno); + // A string, as the tag was when it lived in meta. + ZVAL_STR(&zv, zend_long_to_str(current_frame == 0 ? EX(func)->op_array.line_start : EX(opline)->lineno)); zend_hash_update(meta, key, &zv); zend_string_release(key); @@ -89,11 +93,9 @@ void ddtrace_maybe_add_code_origin_information(ddtrace_span_data *span, int skip if (Z_TYPE_P(type) == IS_STRING && Z_STRLEN_P(type) != 0) { // If it's identical, we don't add it to the child so that only the parent span will be added the code origin information if (span->parent && zend_is_identical(type, &span->parent->property_type)) { - zend_array *meta = ddtrace_property_array(&span->property_meta); - zval *kind = zend_hash_str_find(meta, ZEND_STRL("span.kind")); + zval *kind = ddtrace_span_find_tag(span, ZEND_STRL("span.kind")); if (kind) { - zend_array *parent_meta = ddtrace_property_array(&span->parent->property_meta); - zval *parent_kind = zend_hash_str_find(parent_meta, ZEND_STRL("span.kind")); + zval *parent_kind = ddtrace_span_find_tag(SPANDATA(span->parent), ZEND_STRL("span.kind")); // span.kind must match, otherwise websocket has false positives for example, where both entry and exit span have type websocket if (!parent_kind || zend_is_identical(kind, parent_kind)) { return; diff --git a/tracer/coms.c b/tracer/coms.c index ddfb421a225..be5ff796ea6 100644 --- a/tracer/coms.c +++ b/tracer/coms.c @@ -916,6 +916,7 @@ static void ddtrace_curl_set_hostname_generic(CURL *curl, const char *path) { } void ddtrace_curl_set_hostname(CURL *curl) { + // The in-process (<=8.2) background sender is v0.4-only. ddtrace_curl_set_hostname_generic(curl, TRACE_PATH_STR); } diff --git a/tracer/configuration.h b/tracer/configuration.h index 180b1e4553e..23d5f217642 100644 --- a/tracer/configuration.h +++ b/tracer/configuration.h @@ -11,11 +11,9 @@ #define DD_INTEGRATION_ANALYTICS_ENABLED_DEFAULT false #define DD_INTEGRATION_ANALYTICS_SAMPLE_RATE_DEFAULT 1.0 -#if PHP_VERSION_ID >= 80300 || defined(_WIN32) +// Sidecar is the default trace sender on all PHP versions (in-process coms.c sender is the +// DD_TRACE_SIDECAR_TRACE_SENDER=0 opt-in). Thread mode isn't pcntl_fork()-safe; auto falls back. #define DD_SIDECAR_TRACE_SENDER_DEFAULT true -#else -#define DD_SIDECAR_TRACE_SENDER_DEFAULT false -#endif #if _BUILD_FROM_PECL_ #define DD_DEFAULT_SOURCES_PATH "@php_dir@/datadog_trace/src/" @@ -117,7 +115,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/configuration_dependencies.h b/tracer/configuration_dependencies.h index 10222bd3195..ee90741f274 100644 --- a/tracer/configuration_dependencies.h +++ b/tracer/configuration_dependencies.h @@ -137,6 +137,19 @@ static bool dd_parse_sidecar_connection_mode(zai_str value, zval *decoded_value, return true; } +static bool dd_parse_trace_agent_protocol_version(zai_str value, zval *decoded_value, bool persistent) { + UNUSED(persistent); + if (zai_str_eq_ci_cstr(value, "1.0") || zai_str_eq_ci_cstr(value, "1")) { + ZVAL_LONG(decoded_value, DD_TRACE_AGENT_PROTOCOL_VERSION_V1); + } else if (zai_str_eq_ci_cstr(value, "0.4")) { + ZVAL_LONG(decoded_value, DD_TRACE_AGENT_PROTOCOL_VERSION_V04); + } else { + return false; + } + + return true; +} + // Custom parser to ensure security-testing headers are always captured. static bool dd_parse_header_tags(zai_str value, zval *decoded_value, bool persistent) { if (!zai_config_decode_value(value, ZAI_CONFIG_TYPE_SET_OR_MAP_LOWERCASE, NULL, decoded_value, persistent)) { 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 0f994d6f579..f644767f286 100644 --- a/tracer/ddtrace.stub.php +++ b/tracer/ddtrace.stub.php @@ -74,7 +74,7 @@ final class FfeResult { public ?int $configVersion = null; } - class SpanEvent implements \JsonSerializable { + class SpanEvent { /** * SpanEvent constructor. * @@ -98,11 +98,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 { @@ -120,7 +115,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. @@ -148,11 +143,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. * @@ -174,6 +164,21 @@ class GitMetadata { public string $repositoryUrl = ""; } + 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; + } + class SpanData { /** * @var string|null The span name @@ -191,18 +196,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 @@ -217,14 +210,16 @@ class SpanData { public string|null $type = ""; /** - * @var string[] $meta An array of key-value span metadata; keys and values must be strings. + * @var string[] $meta A view onto the non-numeric entries of $attributes; values are stored as strings. + * @deprecated Use $attributes. Setting meta['error.ignored'] is deprecated too: use $ignoreError. */ - public array $meta = []; + public $meta = []; /** - * @var float[] $metrics An array of key-value span metrics; keys must be strings and values must be floats. + * @var float[] $metrics A view onto the numeric entries of $attributes; values are stored as floats. + * @deprecated Use $attributes. */ - public array $metrics = []; + public $metrics = []; /** * @var \Throwable|null $exception An exception generated during the execution of the original function, if any. @@ -297,6 +292,34 @@ 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; + + /** + * @var array $attributes Span attributes, keeping their type: bool, int, float, string, or nested arrays + * and objects. Null values are skipped. + */ + public array $attributes = []; + + /** + * @var bool $ignoreError Set to true to not report this span as an error, even if it has an exception or + * error tags. + */ + public bool $ignoreError = false; } class InferredSpanData extends SpanData {} @@ -317,6 +340,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. */ @@ -354,6 +379,8 @@ class RootSpanData extends SpanData { public GitMetadata|null $gitMetadata = null; public InferredSpanData|null $inferredSpan = null; + + public string $hostname = ""; } /** @@ -387,6 +414,8 @@ class SpanStack { * removal. */ public array $spanCreationObservers = []; + + public array $attributes = []; } interface Integration { @@ -538,7 +567,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 @@ -755,6 +784,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 {} @@ -774,6 +804,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 {} @@ -784,7 +815,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 @@ -950,25 +981,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. @@ -1181,31 +1193,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 * @@ -1223,6 +1210,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. @@ -1232,6 +1220,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 {} @@ -1239,6 +1228,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 {} @@ -1251,35 +1241,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 * @@ -1297,6 +1258,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' */ @@ -1319,6 +1281,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 {} @@ -1346,11 +1309,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/ddtrace_arginfo.h b/tracer/ddtrace_arginfo.h index dc107f67b09..ddfe7a6dd71 100644 --- a/tracer/ddtrace_arginfo.h +++ b/tracer/ddtrace_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 4725b7bd60526a5eeb72ca5e58dbd828c002876a */ + * Stub hash: f24f35fb55682e040fd9c2e3e6ec535f0e365194 */ 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) @@ -194,14 +194,6 @@ 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) @@ -256,19 +248,6 @@ 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_DDTrace_Internal_record_ffe_flag_evaluation, 0, 9, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, flagKey, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, variant, IS_STRING, 1) - ZEND_ARG_TYPE_INFO(0, allocationKey, IS_STRING, 1) - ZEND_ARG_TYPE_INFO(0, targetingKey, IS_STRING, 1) - ZEND_ARG_TYPE_INFO(0, attributes, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, errorType, IS_STRING, 1) - ZEND_ARG_TYPE_INFO(0, runtimeDefaultUsed, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, observeFullEvaluationData, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, evaluationTimestampMs, IS_LONG, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, targetingKeyInvalid, _IS_BOOL, 0, "false") -ZEND_END_ARG_INFO() - 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) ZEND_ARG_TYPE_MASK(0, user, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_NULL, "null") @@ -287,16 +266,6 @@ 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() - #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 @@ -309,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_DDTrace_ffe_config_version - 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) @@ -367,16 +326,11 @@ 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() @@ -440,8 +394,6 @@ ZEND_FUNCTION(DDTrace_ffe_has_config); ZEND_FUNCTION(DDTrace_ffe_config_version); 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); @@ -455,23 +407,16 @@ ZEND_FUNCTION(DDTrace_Internal_add_span_flag); ZEND_FUNCTION(DDTrace_Internal_handle_fork); ZEND_FUNCTION(DDTrace_Internal_record_ffe_evaluation_metric); ZEND_FUNCTION(DDTrace_Internal_flush_ffe_evaluation_metrics); -ZEND_FUNCTION(DDTrace_Internal_record_ffe_flag_evaluation); 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); @@ -485,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); @@ -543,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) @@ -558,28 +499,21 @@ static const zend_function_entry ext_functions[] = { ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Internal", "handle_fork"), zif_DDTrace_Internal_handle_fork, arginfo_DDTrace_Internal_handle_fork, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Internal", "record_ffe_evaluation_metric"), zif_DDTrace_Internal_record_ffe_evaluation_metric, arginfo_DDTrace_Internal_record_ffe_evaluation_metric, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Internal", "flush_ffe_evaluation_metrics"), zif_DDTrace_Internal_flush_ffe_evaluation_metrics, arginfo_DDTrace_Internal_flush_ffe_evaluation_metrics, 0, NULL, NULL) - ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Internal", "record_ffe_flag_evaluation"), zif_DDTrace_Internal_record_ffe_flag_evaluation, arginfo_DDTrace_Internal_record_ffe_flag_evaluation, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("datadog\\appsec\\v2", "track_user_login_success"), zif_datadog_appsec_v2_track_user_login_success, arginfo_datadog_appsec_v2_track_user_login_success, 0, NULL, NULL) 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) @@ -592,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 }; @@ -602,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 }; @@ -685,17 +617,11 @@ static zend_class_entry *register_class_DDTrace_FfeResult(void) 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(property_doLog_name); - zval property_observeFullEvaluationData_default_value; - ZVAL_FALSE(&property_observeFullEvaluationData_default_value); - zend_string *property_observeFullEvaluationData_name = zend_string_init("observeFullEvaluationData", sizeof("observeFullEvaluationData") - 1, 1); - zend_declare_typed_property(class_entry, property_observeFullEvaluationData_name, &property_observeFullEvaluationData_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release(property_observeFullEvaluationData_name); - zval property_serialId_default_value; ZVAL_NULL(&property_serialId_default_value); - zend_string *property_serialId_name = zend_string_init("serialId", sizeof("serialId") - 1, 1); + zend_string *property_serialId_name = zend_string_init("serialId", sizeof("serialId") - 1, true); zend_declare_typed_property(class_entry, property_serialId_name, &property_serialId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release(property_serialId_name); + zend_string_release_ex(property_serialId_name, true); zval property_providerState_default_value; ZVAL_EMPTY_ARRAY(&property_providerState_default_value); @@ -724,17 +650,18 @@ static zend_class_entry *register_class_DDTrace_FfeResult(void) 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); @@ -768,13 +695,12 @@ static zend_class_entry *register_class_DDTrace_ExceptionSpanEvent(zend_class_en 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); @@ -831,6 +757,52 @@ static zend_class_entry *register_class_DDTrace_GitMetadata(void) 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; +} + static zend_class_entry *register_class_DDTrace_SpanData(void) { zend_class_entry ce, *class_entry; @@ -840,11 +812,15 @@ 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); @@ -852,18 +828,6 @@ static zend_class_entry *register_class_DDTrace_SpanData(void) 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(property_service_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_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, 1); @@ -872,18 +836,20 @@ static zend_class_entry *register_class_DDTrace_SpanData(void) 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, 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_declare_typed_property(class_entry, property_meta_name, &property_meta_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_NONE(0)); 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, 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_declare_typed_property(class_entry, property_metrics_name, &property_metrics_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_NONE(0)); zend_string_release(property_metrics_name); zval property_exception_default_value; @@ -919,8 +885,10 @@ static zend_class_entry *register_class_DDTrace_SpanData(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_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); @@ -941,6 +909,42 @@ static zend_class_entry *register_class_DDTrace_SpanData(void) 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(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); + + zval property_ignoreError_default_value; + ZVAL_FALSE(&property_ignoreError_default_value); + zend_string *property_ignoreError_name = zend_string_init("ignoreError", sizeof("ignoreError") - 1, 1); + zend_declare_typed_property(class_entry, property_ignoreError_name, &property_ignoreError_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_string_release(property_ignoreError_name); + return class_entry; } @@ -979,6 +983,12 @@ static zend_class_entry *register_class_DDTrace_RootSpanData(zend_class_entry *c 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(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, 1); @@ -1023,6 +1033,12 @@ 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_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; } @@ -1035,8 +1051,10 @@ 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); @@ -1051,6 +1069,12 @@ static zend_class_entry *register_class_DDTrace_SpanStack(void) 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(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; } diff --git a/tracer/distributed_tracing_headers.c b/tracer/distributed_tracing_headers.c index f6eef1b68f1..40940d53adf 100644 --- a/tracer/distributed_tracing_headers.c +++ b/tracer/distributed_tracing_headers.c @@ -731,12 +731,9 @@ void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result break; } - zend_array *root_meta = span ? ddtrace_property_array(&span->property_meta) : &DDTRACE_G(root_span_tags_preset); + zend_array *root_meta = span ? ddtrace_property_array(&span->property_attributes) : &DDTRACE_G(root_span_tags_preset); if (span) { - zend_string *tagname; - ZEND_HASH_FOREACH_STR_KEY(ddtrace_property_array(&span->property_propagated_tags), tagname) { - zend_hash_del(root_meta, tagname); - } ZEND_HASH_FOREACH_END(); + ddtrace_drop_propagated_tags(root_meta, ddtrace_property_array(&span->property_propagated_tags)); ZVAL_ARR(&zv, emalloc(sizeof(HashTable))); *Z_ARR(zv) = result->propagated_tags; @@ -745,7 +742,7 @@ void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result zend_hash_copy(root_meta, &result->meta_tags, NULL); ddtrace_span_data *inferred_span = ddtrace_get_inferred_span(span); if (inferred_span) { - zend_array *inferred_meta = ddtrace_property_array(&inferred_span->property_meta); + zend_array *inferred_meta = ddtrace_property_array(&inferred_span->property_attributes); zend_hash_copy(inferred_meta, &result->meta_tags, (copy_ctor_func_t)zval_add_ref); } diff --git a/tracer/endpoint_guessing.c b/tracer/endpoint_guessing.c index 9d70ccd9d61..2a82a7a44fb 100644 --- a/tracer/endpoint_guessing.c +++ b/tracer/endpoint_guessing.c @@ -197,10 +197,10 @@ void ddtrace_maybe_add_guessed_endpoint_tag(ddtrace_root_span_data *span) return; } - zend_array* meta = ddtrace_property_array(&span->property_meta); + zend_array* attributes = ddtrace_property_array(&span->property_attributes); if (!get_DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT()) { - zval* route = zend_hash_str_find(meta, ZEND_STRL("http.route")); + zval* route = ddtrace_span_find_tag(&span->span, ZEND_STRL("http.route")); // unless we have always_simplified_endpoiont set, // we skip the calculation if http.route is set if (route && Z_TYPE_P(route) == IS_STRING) { @@ -209,8 +209,11 @@ void ddtrace_maybe_add_guessed_endpoint_tag(ddtrace_root_span_data *span) } zval* endpoint; - if ((endpoint = zend_hash_str_add(meta, ZEND_STRL("http.endpoint"), &(zval){0}))) { - zval* url = zend_hash_str_find_deref(meta, ZEND_STRL("http.url")); + if ((endpoint = zend_hash_str_add(attributes, ZEND_STRL("http.endpoint"), &(zval){0}))) { + zval* url = ddtrace_span_find_tag(&span->span, ZEND_STRL("http.url")); + if (url) { + ZVAL_DEREF(url); + } if (!url || Z_TYPE_P(url) != IS_STRING) { // "In case the url is not available, a default value of / should be used for the endpoint tag." ZVAL_STRING(endpoint, "/"); diff --git a/tracer/exception_serialize.c b/tracer/exception_serialize.c index ff4f89bfbc9..37e3987fc79 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, ddog_SpanNode *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}); + ddog_attributes_add_lit(ddog_span_get_attributes(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, ddog_SpanNode *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_span_attr_str(span, "error.type", error_type_string); } else { - ddog_add_str_span_meta_zstr(span, "error.type", exception->ce->name); + dd_span_attr_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, ddog_SpanNode *span) { + dd_span_attr_zstr(span, "error.stack", trace); zend_string_release(trace); } @@ -314,13 +314,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, ddog_SpanNode *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}); + ddog_attributes_add_str(ddog_span_get_attributes(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) }, @@ -393,7 +393,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, ddog_SpanNode *span) { if (!ddtrace_exception_debugging_is_active()) { return; } @@ -417,8 +417,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_span_attr_str(span, "error.debug_info_captured", "true"); + ddog_attributes_add_lit(ddog_span_get_attributes(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); @@ -428,7 +428,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}); + ddog_attributes_add_lit(ddog_span_get_attributes(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))); @@ -541,7 +541,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, ddog_SpanNode *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..345106e5613 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, ddog_SpanNode *span, 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 e9608a41552..82a5cfbff61 100644 --- a/tracer/functions.c +++ b/tracer/functions.c @@ -12,9 +12,11 @@ #ifdef __linux__ #include "otel_context.h" #include +#include #endif #include "random.h" #include "serializer.h" +#include "span_tags_view.h" #include "trace_context.h" #include "weak_resources.h" #include @@ -105,53 +107,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 +160,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)); @@ -317,6 +241,7 @@ static zend_object *dd_init_span_data_object(zend_class_entry *class_type, ddtra array_init(&span->property_events); array_init(&span->property_peer_service_sources); array_init(&span->property_on_close); + array_init(&span->property_attributes); #endif // Explicitly assign property-mapped NULLs span->stack = NULL; @@ -366,6 +291,7 @@ static zend_object *ddtrace_span_stack_create(zend_class_entry *class_type) { #if PHP_VERSION_ID < 80000 // Not handled in arginfo on these old versions array_init(&stack->property_span_creation_observers); + array_init(&stack->property_attributes); #endif return &stack->std; } @@ -434,6 +360,7 @@ static zend_object *ddtrace_span_stack_clone_obj(zend_object *old_obj) { } static void ddtrace_span_data_free_storage(zend_object *object) { + ddtrace_span_tags_views_release(OBJ_SPANDATA(object)); zend_object_std_dtor(object); // Prevent use after free after zend_objects_store_free_object_storage is called (e.g. preloading) [PHP < 8.1] memset(object->properties_table, 0, sizeof(ddtrace_span_data) - XtOffsetOf(ddtrace_span_data, std.properties_table)); @@ -502,6 +429,14 @@ static zval *ddtrace_span_data_readonly(zend_object *object, zend_string *member #endif } + if (ddtrace_span_tags_view_write_property(obj, prop_name, value)) { +#if PHP_VERSION_ID >= 70400 + return value; +#else + return; +#endif + } + ddtrace_span_data *span = OBJ_SPANDATA(obj); // As per unified service tagging spec if a span is created with a service name different from the global // service name it will not inherit the global version value, unless it has no ancestor traces. @@ -523,7 +458,7 @@ static zval *ddtrace_span_data_readonly(zend_object *object, zend_string *member } } if (Z_TYPE_P(value) == IS_STRING && !zend_is_identical(&span->property_service, value)) { - zend_array *meta = ddtrace_property_array(&span->property_meta); + zend_array *meta = ddtrace_property_array(&span->property_attributes); zval val; ZVAL_NEW_STR(&val, zend_string_init("m", 1, 0)); zend_hash_str_update(meta, ZEND_STRL("_dd.svc_src"), &val); @@ -770,6 +705,7 @@ static void dd_register_span_data_ce(void) { ddtrace_span_data_handlers.free_obj = ddtrace_span_data_free_storage; ddtrace_span_data_handlers.write_property = ddtrace_span_data_readonly; ddtrace_span_data_handlers.get_constructor = ddtrace_span_data_get_constructor; + ddtrace_span_tags_view_install(&ddtrace_span_data_handlers); ddtrace_ce_inferred_span_data = register_class_DDTrace_InferredSpanData(ddtrace_ce_span_data); ddtrace_ce_inferred_span_data->create_object = ddtrace_inferred_span_data_create; @@ -824,6 +760,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) { @@ -841,12 +778,14 @@ void ddtrace_register_functions_and_classes(int module_number) { register_ddtrace_symbols(module_number); dd_register_span_data_ce(); + ddtrace_register_span_tags_view(); 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; @@ -909,7 +848,7 @@ PHP_FUNCTION(DDTrace_add_distributed_tag) { zend_array *target_table, *propagated; if (DDTRACE_G(active_stack)->root_span) { - target_table = ddtrace_property_array(&DDTRACE_G(active_stack)->root_span->property_meta); + target_table = ddtrace_property_array(&DDTRACE_G(active_stack)->root_span->property_attributes); propagated = ddtrace_property_array(&DDTRACE_G(active_stack)->root_span->property_propagated_tags); } else { target_table = &DDTRACE_G(root_span_tags_preset); @@ -930,7 +869,7 @@ PHP_FUNCTION(DDTrace_add_distributed_tag) { static void _ddtrace_set_user(zend_string *user_id, zend_array *metadata, zend_bool propagate) { zend_array *target_table, *propagated; if (DDTRACE_G(active_stack)->root_span) { - target_table = ddtrace_property_array(&DDTRACE_G(active_stack)->root_span->property_meta); + target_table = ddtrace_property_array(&DDTRACE_G(active_stack)->root_span->property_attributes); propagated = ddtrace_property_array(&DDTRACE_G(active_stack)->root_span->property_propagated_tags); } else { target_table = &DDTRACE_G(root_span_tags_preset); @@ -1012,7 +951,7 @@ PHP_FUNCTION(datadog_appsec_v2_track_user_login_success) { zend_array *target_table; if (DDTRACE_G(active_stack)->root_span) { - target_table = ddtrace_property_array(&DDTRACE_G(active_stack)->root_span->property_meta); + target_table = ddtrace_property_array(&DDTRACE_G(active_stack)->root_span->property_attributes); } else { target_table = &DDTRACE_G(root_span_tags_preset); } @@ -1125,7 +1064,7 @@ PHP_FUNCTION(datadog_appsec_v2_track_user_login_failure) { zend_array *target_table; if (DDTRACE_G(active_stack)->root_span) { - target_table = ddtrace_property_array(&DDTRACE_G(active_stack)->root_span->property_meta); + target_table = ddtrace_property_array(&DDTRACE_G(active_stack)->root_span->property_attributes); } else { target_table = &DDTRACE_G(root_span_tags_preset); } @@ -1197,13 +1136,15 @@ PHP_FUNCTION(dd_trace_serialize_closed_spans) { ddtrace_mark_all_span_stacks_flushable(); - ddog_TracesBytes *traces = ddog_get_traces(); - if (!ddtrace_serialize_closed_spans_with_cycle(traces, false)) { - ddog_free_traces(traces); - RETURN_NULL(); - } + // Introspection is a debug view: always finalize into the in-memory V1 builder (no sidecar + // needed) and read it back via the V1 getters, so the shape is uniform across versions/senders. + ddtrace_serialize_ctx serialize_ctx = {.builder = ddog_v1_new_builder(), .chunk = DD_CHUNK_NONE}; + ddtrace_serialize_ctx *ctx = &serialize_ctx; - zval traces_zv = dd_serialize_rust_traces_to_zval(traces); + ddtrace_serialize_closed_spans_with_cycle(ctx, false); + + zval traces_zv = dd_serialize_rust_to_zval(ctx->builder); + ddog_v1_free_builder(ctx->builder); if (zend_hash_num_elements(Z_ARR(traces_zv)) == 1) { ZVAL_COPY(return_value, zend_hash_get_current_data(Z_ARR(traces_zv))); @@ -1219,7 +1160,6 @@ PHP_FUNCTION(dd_trace_serialize_closed_spans) { } ZEND_HASH_FOREACH_END(); } - ddog_free_traces(traces); zval_ptr_dtor(&traces_zv); ddtrace_free_span_stacks(false); @@ -1252,47 +1192,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) { @@ -1357,30 +1256,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, @@ -1948,69 +1823,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)); - - efree(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) static bool ddtrace_otel_config_is_reportable(zend_string *name) { @@ -2780,7 +2592,7 @@ PHP_FUNCTION(DDTrace_set_distributed_tracing_context) { zend_array *root_meta = &DDTRACE_G(root_span_tags_preset); zend_array *propagated_tags = &DDTRACE_G(propagated_root_span_tags); if (root_span) { - root_meta = ddtrace_property_array(&root_span->property_meta); + root_meta = ddtrace_property_array(&root_span->property_attributes); propagated_tags = ddtrace_property_array(&root_span->property_propagated_tags); } diff --git a/tracer/handlers_http.h b/tracer/handlers_http.h index 82ebffbf7f8..f5a78b6ee79 100644 --- a/tracer/handlers_http.h +++ b/tracer/handlers_http.h @@ -323,7 +323,7 @@ static inline void ddtrace_inject_distributed_headers_config(zend_array *array, } ddtrace_root_span_data *root_span = DDTRACE_G(active_stack) ? DDTRACE_G(active_stack)->root_span : NULL; - zend_array *meta = root_span ? ddtrace_property_array(&root_span->property_meta) : &DDTRACE_G(root_span_tags_preset); + zend_array *meta = root_span ? ddtrace_property_array(&root_span->property_attributes) : &DDTRACE_G(root_span_tags_preset); if (!get_DD_APM_TRACING_ENABLED() && !ddtrace_asm_event_emitted() && !ddtrace_trace_source_is_meta_asm_sourced(meta)) { return; } diff --git a/tracer/handlers_httpstreams.c b/tracer/handlers_httpstreams.c index 23617d2eb1f..6e8a7f7e078 100644 --- a/tracer/handlers_httpstreams.c +++ b/tracer/handlers_httpstreams.c @@ -69,14 +69,13 @@ static php_stream *dd_stream_opener( if (span) { ddtrace_set_global_span_properties(span); - zend_array *meta = ddtrace_property_array(&span->property_meta); + zend_array *meta = ddtrace_property_array(&span->property_attributes); 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); + // 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 */); ZVAL_STRING(&zv, filename); zend_hash_str_update(meta, ZEND_STRL("http.url"), &zv); @@ -91,7 +90,7 @@ static php_stream *dd_stream_opener( if (method_zv && Z_TYPE_P(method_zv) == IS_STRING) { // `zend_hash_str_update()` moves the zval payload into the hashtable without adding a ref. // `method_zv` is owned by the stream context options array, so we must add a ref (via ZVAL_COPY) - // to avoid leaving span meta with a dangling zend_string once the options array is destroyed. + // to avoid leaving span attributes with a dangling zend_string once the options array is destroyed. zval method_copy; ZVAL_COPY(&method_copy, method_zv); zend_hash_str_update(meta, ZEND_STRL("http.method"), &method_copy); diff --git a/tracer/hook/uhook_attributes.c b/tracer/hook/uhook_attributes.c index fd56837fdc7..4bb4d0e7532 100644 --- a/tracer/hook/uhook_attributes.c +++ b/tracer/hook/uhook_attributes.c @@ -4,6 +4,7 @@ #include "../ddtrace.h" #include "../configuration.h" #include "../span.h" +#include #include "uhook_attributes_arginfo.h" #include "uhook.h" @@ -102,6 +103,46 @@ static zval dd_uhook_save_value(zval *value) { return ret; } +// A tag value as it serialized from meta: string leaves (null -> "null"), "" for an empty or +// recursive (reference cycle) array/object, so the v0.4 wire is unchanged now that it lives in the +// attributes. +static void dd_uhook_tag_as_meta(zval *dst, zval *src) { + ZVAL_DEREF(src); + if (Z_TYPE_P(src) != IS_ARRAY && Z_TYPE_P(src) != IS_OBJECT) { + datadog_convert_to_string(dst, src); + return; + } + HashTable *ht = Z_TYPE_P(src) == IS_ARRAY ? Z_ARR_P(src) : Z_OBJPROP_P(src); + if (!zend_hash_num_elements(ht) || Z_IS_RECURSIVE_P(src)) { + ZVAL_EMPTY_STRING(dst); + return; + } + // Immutable arrays cannot form a cycle and must never be written to. + bool guard = Z_TYPE_P(src) != IS_ARRAY || !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE); + if (guard) { + Z_PROTECT_RECURSION_P(src); + } + array_init_size(dst, zend_hash_num_elements(ht)); + zend_string *key; + zend_ulong idx; + zval *val; + ZEND_HASH_FOREACH_KEY_VAL_IND(ht, idx, key, val) { + if (key && ZSTR_LEN(key) && ZSTR_VAL(key)[0] == '\0') { + continue; // protected and private members + } + zval leaf; + dd_uhook_tag_as_meta(&leaf, val); + if (key) { + zend_hash_update(Z_ARR_P(dst), key, &leaf); + } else { + zend_hash_index_update(Z_ARR_P(dst), idx, &leaf); + } + } ZEND_HASH_FOREACH_END(); + if (guard) { + Z_UNPROTECT_RECURSION_P(src); + } +} + static void dd_fill_span_data(dd_uhook_def *def, ddtrace_span_data *span) { if (def->name) { zval *name = &span->property_name; @@ -119,7 +160,7 @@ static void dd_fill_span_data(dd_uhook_def *def, ddtrace_span_data *span) { zval_ptr_dtor(service); ZVAL_STR_COPY(service, def->service); if (service_changed) { - zend_array *meta = ddtrace_property_array(&span->property_meta); + zend_array *meta = ddtrace_property_array(&span->property_attributes); zval val; ZVAL_NEW_STR(&val, zend_string_init("m", 1, 0)); zend_hash_str_update(meta, ZEND_STRL("_dd.svc_src"), &val); @@ -131,13 +172,14 @@ static void dd_fill_span_data(dd_uhook_def *def, ddtrace_span_data *span) { ZVAL_STR_COPY(type, def->type); } if (def->tags) { - zend_array *meta = ddtrace_property_array(&span->property_meta); + zend_array *meta = ddtrace_property_array(&span->property_attributes); zend_string *key; zval *value; ZEND_HASH_FOREACH_STR_KEY_VAL(def->tags, key, value) { if (key) { - Z_TRY_ADDREF_P(value); - zend_hash_update(meta, key, value); + zval tag; + dd_uhook_tag_as_meta(&tag, value); + zend_hash_update(meta, key, &tag); } } ZEND_HASH_FOREACH_END(); } @@ -211,7 +253,7 @@ static bool dd_uhook_begin(zend_ulong invocation, zend_execute_data *execute_dat bool new_span; dyn->span = ddtrace_alloc_execute_data_span_ex(invocation, execute_data, &new_span); dd_fill_span_data(def, dyn->span); - dd_uhook_fill_args_in_meta(def, ddtrace_property_array(&dyn->span->property_meta), execute_data); + dd_uhook_fill_args_in_meta(def, ddtrace_property_array(&dyn->span->property_attributes), execute_data); if (new_span) { ddtrace_observe_opened_span(dyn->span); } @@ -240,7 +282,7 @@ static void dd_uhook_generator_resumption(zend_ulong invocation, zend_execute_da dyn->span = ddtrace_alloc_execute_data_span_ex(invocation, execute_data, &new_span); dd_fill_span_data(def, dyn->span); if (def->retval) { - zend_array *meta = ddtrace_property_array(&dyn->span->property_meta); + zend_array *meta = ddtrace_property_array(&dyn->span->property_attributes); zval val = dd_uhook_save_value(value); zend_hash_str_update(meta, ZEND_STRL("send_value"), &val); } @@ -271,7 +313,7 @@ static void dd_uhook_generator_yield(zend_ulong invocation, zend_execute_data *e dd_trace_stop_span_time(dyn->span); if (def->retval) { - zend_array *meta = ddtrace_property_array(&dyn->span->property_meta); + zend_array *meta = ddtrace_property_array(&dyn->span->property_attributes); zval keyzv = dd_uhook_save_value(key); zend_hash_str_update(meta, ZEND_STRL("yield_key"), &keyzv); zval val = dd_uhook_save_value(value); @@ -303,7 +345,7 @@ static void dd_uhook_end(zend_ulong invocation, zend_execute_data *execute_data, dd_trace_stop_span_time(dyn->span); if (def->retval) { - zend_array *meta = ddtrace_property_array(&dyn->span->property_meta); + zend_array *meta = ddtrace_property_array(&dyn->span->property_attributes); zval val = dd_uhook_save_value(retval); zend_hash_str_update(meta, ZEND_STRL("return_value"), &val); } diff --git a/tracer/integrations/exec_integration.c b/tracer/integrations/exec_integration.c index 8de53fa675c..92e26a3bab5 100644 --- a/tracer/integrations/exec_integration.c +++ b/tracer/integrations/exec_integration.c @@ -94,14 +94,15 @@ static int dd_php_stdiop_close_wrapper(php_stream *stream, int close_handle) { ddtrace_span_data *span_data = OBJ_SPANDATA(Z_OBJ_P(span_data_zv)); - zend_array *meta = ddtrace_property_array(&span_data->property_meta); + zend_array *meta = ddtrace_property_array(&span_data->property_attributes); if (ret == -1) { zval zv; ZVAL_INTERNED_STR(&zv, pclose_minus_one_zstr); zend_hash_update(meta, error_message_zstr, &zv); } else { + // A string, as the tag was when it lived in meta. zval zexit; - ZVAL_LONG(&zexit, ret); + ZVAL_STR(&zexit, zend_long_to_str(ret)); zend_hash_update(meta, cmd_exit_code_zstr, &zexit); } @@ -137,7 +138,7 @@ static void dd_waitpid(ddtrace_span_data *span_data, dd_proc_span *proc) { // already closed return; } - zend_array *meta = ddtrace_property_array(&span_data->property_meta); + zend_array *meta = ddtrace_property_array(&span_data->property_attributes); int wstatus; bool exited = false; @@ -183,7 +184,7 @@ static void dd_waitpid(ddtrace_span_data *span_data, dd_proc_span *proc) { if (exited) { zval zexit; - ZVAL_LONG(&zexit, wstatus); + ZVAL_STR(&zexit, zend_long_to_str(wstatus)); // set tag 'cmd.exit_code' zend_hash_update(meta, cmd_exit_code_zstr, &zexit); diff --git a/tracer/live_debugger.c b/tracer/live_debugger.c index b4a727518d1..253cb6cb643 100644 --- a/tracer/live_debugger.c +++ b/tracer/live_debugger.c @@ -447,7 +447,7 @@ static bool dd_span_probe_begin(zend_ulong invocation, zend_execute_data *execut zval probe_id; ZVAL_STR_COPY(&probe_id, def->probe_id); - zend_hash_str_update(ddtrace_property_array(&dyn->span->property_meta), ZEND_STRL("debugger.probeid"), &probe_id); + zend_hash_str_update(ddtrace_property_array(&dyn->span->property_attributes), ZEND_STRL("debugger.probeid"), &probe_id); if (new_span) { ddtrace_observe_opened_span(dyn->span); @@ -500,7 +500,7 @@ static void dd_span_decoration_end(zend_ulong invocation, zend_execute_data *exe if (def->probe.probe.span_decoration.target == DDOG_SPAN_PROBE_TARGET_ROOT) { span = &span->stack->root_span->span; } - zend_array *meta = ddtrace_property_array(&span->property_meta); + zend_array *meta = ddtrace_property_array(&span->property_attributes); bool condition_result = true; const ddog_ProbeCondition *const *condition = def->probe.probe.span_decoration.conditions; diff --git a/tracer/priority_sampling/priority_sampling.c b/tracer/priority_sampling/priority_sampling.c index 22836a57423..97c8557d5fd 100644 --- a/tracer/priority_sampling/priority_sampling.c +++ b/tracer/priority_sampling/priority_sampling.c @@ -45,9 +45,13 @@ void ddtrace_try_read_agent_rate(void) { } } +static void dd_del_root_tag(ddtrace_root_span_data *root_span, const char *key, size_t len) { + zend_hash_str_del(ddtrace_property_array(&root_span->property_attributes), key, len); +} + static void dd_update_decision_maker_tag(ddtrace_root_span_data *root_span, enum dd_sampling_mechanism mechanism) { - zend_array *meta = ddtrace_property_array(&root_span->property_meta); + zend_array *attributes = ddtrace_property_array(&root_span->property_attributes); zend_long sampling_priority = zval_get_long(&root_span->property_sampling_priority); if (Z_TYPE(root_span->property_propagated_sampling_priority) != IS_UNDEF && @@ -58,15 +62,15 @@ static void dd_update_decision_maker_tag(ddtrace_root_span_data *root_span, if (sampling_priority > 0 && sampling_priority != DDTRACE_PRIORITY_SAMPLING_UNKNOWN) { zval dm; ZVAL_STR(&dm, zend_strpprintf(0, "-%d", mechanism)); - zend_hash_str_update(meta, "_dd.p.dm", sizeof("_dd.p.dm") - 1, &dm); + zend_hash_str_update(attributes, ZEND_STRL("_dd.p.dm"), &dm); zend_hash_str_add_empty_element(ddtrace_property_array(&root_span->property_propagated_tags), ZEND_STRL("_dd.p.dm")); } else { - zend_hash_str_del(meta, "_dd.p.dm", sizeof("_dd.p.dm") - 1); + dd_del_root_tag(root_span, ZEND_STRL("_dd.p.dm")); } } static void dd_update_knuth_sampling_rate_tag(ddtrace_root_span_data *root_span, double sample_rate) { - zend_array *meta = ddtrace_property_array(&root_span->property_meta); + zend_array *attributes = ddtrace_property_array(&root_span->property_attributes); char buf[32]; #if PHP_VERSION_ID < 80100 @@ -85,14 +89,14 @@ static void dd_update_knuth_sampling_rate_tag(ddtrace_root_span_data *root_span, } // Skip update if already set to the same value - zval *existing = zend_hash_str_find(meta, ZEND_STRL("_dd.p.ksr")); + zval *existing = zend_hash_str_find(attributes, ZEND_STRL("_dd.p.ksr")); if (existing && Z_TYPE_P(existing) == IS_STRING && zend_string_equals_cstr(Z_STR_P(existing), buf, len) == 0) { return; } zval ksr; ZVAL_STRINGL(&ksr, buf, len); - zend_hash_str_update(meta, ZEND_STRL("_dd.p.ksr"), &ksr); + zend_hash_str_update(attributes, ZEND_STRL("_dd.p.ksr"), &ksr); zend_hash_str_add_empty_element(ddtrace_property_array(&root_span->property_propagated_tags), ZEND_STRL("_dd.p.ksr")); } @@ -131,13 +135,12 @@ static bool dd_check_sampling_rule(zend_array *rule, ddtrace_span_data *span) { } if ((rule_pattern = zend_hash_str_find(rule, ZEND_STRL("tags"))) && Z_TYPE_P(rule_pattern) == IS_ARRAY) { zend_array *tag_rules = Z_ARR_P(rule_pattern); - zend_array *meta = ddtrace_property_array(&span->property_meta); - zend_array *metrics = ddtrace_property_array(&span->property_metrics); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); zend_string *tag_name; ZEND_HASH_FOREACH_STR_KEY_VAL(tag_rules, tag_name, rule_pattern) { if (tag_name) { zval *value; - if (!(value = zend_hash_find(meta, tag_name)) && !(value = zend_hash_find(metrics, tag_name))) { + if (!(value = zend_hash_find(attributes, tag_name))) { return false; } if (!dd_rule_matches(rule_pattern, value, get_DD_TRACE_SAMPLING_RULES_FORMAT())) { @@ -159,8 +162,7 @@ static ddtrace_rule_result dd_match_rules(ddtrace_span_data *span, bool eval_roo return (ddtrace_rule_result){ .sampling_rate = 0, .rule = INT32_MAX, .mechanism = DD_MECHANISM_RULE }; } - zend_array *meta = ddtrace_property_array(&span->property_meta); - if (zend_hash_str_exists(meta, ZEND_STRL("manual.keep"))) { + if (ddtrace_span_find_tag(span, ZEND_STRL("manual.keep"))) { // manual.keep and manual.drop count as manual return (ddtrace_rule_result){ .sampling_rate = 1, .rule = -2, .mechanism = DD_MECHANISM_MANUAL }; } @@ -168,7 +170,7 @@ static ddtrace_rule_result dd_match_rules(ddtrace_span_data *span, bool eval_roo if (++index >= skip_at) { return (ddtrace_rule_result){ .sampling_rate = 0, .rule = INT32_MAX, .mechanism = DD_MECHANISM_RULE }; } - if (zend_hash_str_exists(meta, ZEND_STRL("manual.drop"))) { + if (ddtrace_span_find_tag(span, ZEND_STRL("manual.drop"))) { return (ddtrace_rule_result){ .sampling_rate = 0, .rule = -1, .mechanism = DD_MECHANISM_MANUAL }; } @@ -284,7 +286,7 @@ static void dd_decide_on_sampling(ddtrace_root_span_data *span) { } else { explicit_rule = false; - zval *env = zend_hash_str_find(ddtrace_property_array(&span->property_meta), ZEND_STRL("env")); + zval *env = ddtrace_span_find_tag(&span->span, ZEND_STRL("env")); if (!env) { env = &span->property_env; } @@ -332,7 +334,7 @@ static void dd_decide_on_sampling(ddtrace_root_span_data *span) { ddtrace_otel_update_trace_flags(span); #endif } - zend_hash_str_del(ddtrace_property_array(&span->property_meta), ZEND_STRL("_dd.p.ksr")); + dd_del_root_tag(span, ZEND_STRL("_dd.p.ksr")); return; } else { sample_rate = result.sampling_rate; @@ -357,38 +359,37 @@ static void dd_decide_on_sampling(ddtrace_root_span_data *span) { zval sample_rate_zv; ZVAL_DOUBLE(&sample_rate_zv, sample_rate); - zend_array *metrics = ddtrace_property_array(&span->property_metrics); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); if (explicit_rule) { mechanism = result.mechanism; priority = sampling && !limited ? PRIORITY_SAMPLING_USER_KEEP : PRIORITY_SAMPLING_USER_REJECT; if (mechanism == DD_MECHANISM_MANUAL) { - zend_hash_str_del(metrics, ZEND_STRL("_dd.rule_psr")); - zend_hash_str_del(ddtrace_property_array(&span->property_meta), ZEND_STRL("_dd.p.ksr")); + dd_del_root_tag(span, ZEND_STRL("_dd.rule_psr")); + dd_del_root_tag(span, ZEND_STRL("_dd.p.ksr")); } else { - zend_hash_str_update(metrics, ZEND_STRL("_dd.rule_psr"), &sample_rate_zv); + zend_hash_str_update(attributes, ZEND_STRL("_dd.rule_psr"), &sample_rate_zv); dd_update_knuth_sampling_rate_tag(span, sample_rate); } - zend_hash_str_del(metrics, ZEND_STRL("_dd.agent_psr")); + dd_del_root_tag(span, ZEND_STRL("_dd.agent_psr")); } else { // manual if it's not just inherited, otherwise this value is irrelevant (as sampling priority will be default) mechanism = DDTRACE_G(agent_rate_by_service) ? DD_MECHANISM_AGENT_RATE : DD_MECHANISM_DEFAULT; priority = sampling && !limited ? PRIORITY_SAMPLING_AUTO_KEEP : PRIORITY_SAMPLING_AUTO_REJECT; - zend_hash_str_update(metrics, ZEND_STRL("_dd.agent_psr"), &sample_rate_zv); + zend_hash_str_update(attributes, ZEND_STRL("_dd.agent_psr"), &sample_rate_zv); if (mechanism == DD_MECHANISM_AGENT_RATE) { dd_update_knuth_sampling_rate_tag(span, sample_rate); } else { - zend_hash_str_del(ddtrace_property_array(&span->property_meta), ZEND_STRL("_dd.p.ksr")); + dd_del_root_tag(span, ZEND_STRL("_dd.p.ksr")); } } if (limited) { zval limit_zv; ZVAL_DOUBLE(&limit_zv, ddtrace_limiter_rate()); - zend_hash_str_update(ddtrace_property_array(&span->property_metrics), ZEND_STRL("_dd.limit_psr"), - &limit_zv); + zend_hash_str_update(attributes, ZEND_STRL("_dd.limit_psr"), &limit_zv); } if (mechanism == DD_MECHANISM_MANUAL || mechanism == DD_MECHANISM_ASM || limited || sample_rate <= 0) { diff --git a/tracer/serializer.c b/tracer/serializer.c index 86600e3e4b1..e4c41ea2546 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #ifndef _WIN32 @@ -42,6 +40,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" @@ -339,7 +338,14 @@ 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, +void dd_span_attr_str(ddog_SpanNode *span, const char *key, const char *val) { + ddog_attributes_add_lit(ddog_span_get_attributes(span), key, (ddog_CharSlice){ .ptr = val, .len = strlen(val) }); +} +void dd_span_attr_zstr(ddog_SpanNode *span, const char *key, zend_string *val) { + ddog_attributes_add_lit(ddog_span_get_attributes(span), key, dd_zend_string_to_CharSlice(val)); +} + +static void dd_add_header_to_rust_span(ddog_SpanNode *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) { @@ -356,7 +362,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); + ddog_attributes_add_zstr(ddog_span_get_attributes(span), headertag, headerval); zend_string_release(headertag); } } @@ -453,7 +459,7 @@ static void dd_add_post_fields_to_meta_recursive(zend_array *meta, const char *t } void ddtrace_set_global_span_properties(ddtrace_span_data *span) { - zend_array *meta = ddtrace_property_array(&span->property_meta); + zend_array *meta = ddtrace_property_array(&span->property_attributes); zend_array *global_tags = get_DD_TAGS(); zend_string *global_key; zval *global_val; @@ -587,7 +593,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(ddog_SpanNode *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; @@ -596,8 +602,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_span_attr_zstr(span, "peer.service.remapped_from", peer_service); + dd_span_attr_zstr(span, "peer.service", mapped_service); zend_string_release(mapped_service); return true; } @@ -623,14 +629,14 @@ struct superglob_equiv { }; static void dd_set_entrypoint_root_span_props(struct superglob_equiv *data, ddtrace_root_span_data *span) { - zend_array *meta = ddtrace_property_array(&span->property_meta); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); if (data->server){ zend_string *http_url = dd_build_req_url(data->server); if (ZSTR_LEN(http_url) > 0) { zval http_url_zv; ZVAL_STR(&http_url_zv, http_url); - zend_hash_str_add_new(meta, ZEND_STRL("http.url"), &http_url_zv); + zend_hash_str_add_new(attributes, ZEND_STRL("http.url"), &http_url_zv); } } @@ -650,16 +656,25 @@ static void dd_set_entrypoint_root_span_props(struct superglob_equiv *data, ddtr if (method) { zval http_method; ZVAL_STR(&http_method, zend_string_init(method, strlen(method), 0)); - zend_hash_str_add_new(meta, ZEND_STRL("http.method"), &http_method); + zend_hash_str_add_new(attributes, 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). + // Written as a tag 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)) { + if (!zend_hash_str_add(attributes, ZEND_STRL("span.kind"), &span_kind_server)) { zval_ptr_dtor(&span_kind_server); } + // Default component to the SAPI (the server integration layer), add-if-absent so frameworks override it. + if (strcmp(sapi_module.name, "cli") != 0) { + zval component; + ZVAL_STRING(&component, sapi_module.name); + if (!zend_hash_str_add(attributes, ZEND_STRL("component"), &component)) { + zval_ptr_dtor(&component); + } + } + if (get_DD_TRACE_URL_AS_RESOURCE_NAMES_ENABLED()) { const char *uri = dd_get_req_uri(data->server); zval *prop_resource = &span->property_resource; @@ -689,21 +704,21 @@ static void dd_set_entrypoint_root_span_props(struct superglob_equiv *data, ddtr if (get_DD_TRACE_CLIENT_IP_ENABLED() && data->server) { zval server_zv; ZVAL_ARR(&server_zv, data->server); - ddtrace_extract_ip_from_headers(&server_zv, meta); + ddtrace_extract_ip_from_headers(&server_zv, attributes); } zend_string *user_agent = dd_get_user_agent(data->server); if (user_agent && ZSTR_LEN(user_agent) > 0) { zval http_useragent; ZVAL_STR_COPY(&http_useragent, user_agent); - zend_hash_str_add_new(meta, ZEND_STRL("http.useragent"), &http_useragent); + zend_hash_str_add_new(attributes, ZEND_STRL("http.useragent"), &http_useragent); } zend_string *referrer_host = dd_get_referrer_host(data->server); if (referrer_host && ZSTR_LEN(referrer_host) > 0) { zval http_referrer_host; ZVAL_STR(&http_referrer_host, referrer_host); - zend_hash_str_add_new(meta, ZEND_STRL("http.referrer_hostname"), &http_referrer_host); + zend_hash_str_update(attributes, ZEND_STRL("http.referrer_hostname"), &http_referrer_host); } if (data->server) { @@ -721,7 +736,7 @@ static void dd_set_entrypoint_root_span_props(struct superglob_equiv *data, ddtr } } - dd_add_header_to_meta(meta, "request", lowerheader, Z_STR_P(headerval)); + dd_add_header_to_meta(attributes, "request", lowerheader, Z_STR_P(headerval)); zend_string_release(lowerheader); } } @@ -732,7 +747,7 @@ static void dd_set_entrypoint_root_span_props(struct superglob_equiv *data, ddtr zval post_zv; ZVAL_ARR(&post_zv, data->post); zend_string *empty = ZSTR_EMPTY_ALLOC(); - dd_add_post_fields_to_meta_recursive(meta, "request", empty, &post_zv, get_DD_TRACE_HTTP_POST_DATA_PARAM_ALLOWED(), false); + dd_add_post_fields_to_meta_recursive(attributes, "request", empty, &post_zv, get_DD_TRACE_HTTP_POST_DATA_PARAM_ALLOWED(), false); zend_string_release(empty); } } @@ -749,11 +764,9 @@ void ddtrace_inherit_span_properties(ddtrace_span_data *span, ddtrace_span_data zval_ptr_dtor(prop_baggage); ZVAL_COPY_DEREF(prop_baggage, prop_parent_baggage); - zend_array *parent_meta = ddtrace_property_array(&parent->property_meta); - - zval *parent_svc_src = zend_hash_str_find(parent_meta, ZEND_STRL("_dd.svc_src")); + zval *parent_svc_src = ddtrace_span_find_tag(parent, ZEND_STRL("_dd.svc_src")); if (parent_svc_src) { - zend_array *child_meta = ddtrace_property_array(&span->property_meta); + zend_array *child_meta = ddtrace_property_array(&span->property_attributes); Z_TRY_ADDREF_P(parent_svc_src); zend_hash_str_update(child_meta, ZEND_STRL("_dd.svc_src"), parent_svc_src); } @@ -761,7 +774,7 @@ void ddtrace_inherit_span_properties(ddtrace_span_data *span, ddtrace_span_data zval *prop_version = &span->property_version; zval_ptr_dtor(prop_version); zval *version; - if ((version = zend_hash_str_find(parent_meta, ZEND_STRL("version")))) { + if ((version = ddtrace_span_find_tag(parent, ZEND_STRL("version")))) { zval old = *version; datadog_convert_to_string(version, version); zval_ptr_dtor(&old); @@ -773,7 +786,7 @@ void ddtrace_inherit_span_properties(ddtrace_span_data *span, ddtrace_span_data zval *prop_env = &span->property_env; zval_ptr_dtor(prop_env); zval *env; - if ((env = zend_hash_str_find(parent_meta, ZEND_STRL("env")))) { + if ((env = ddtrace_span_find_tag(parent, ZEND_STRL("env")))) { zval old = *env; datadog_convert_to_string(env, env); zval_ptr_dtor(&old); @@ -800,10 +813,8 @@ void ddtrace_set_root_span_properties(ddtrace_root_span_data *span) { span->sampling_rule.rule = INT32_MAX; - zend_array *meta = ddtrace_property_array(&span->property_meta); - zend_array *metrics = ddtrace_property_array(&span->property_metrics); - - zend_hash_copy(meta, &DDTRACE_G(root_span_tags_preset), (copy_ctor_func_t)zval_add_ref); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); + zend_hash_copy(attributes, &DDTRACE_G(root_span_tags_preset), (copy_ctor_func_t)zval_add_ref); /* Compilers rightfully complain about array bounds due to the struct * hack if we write straight to the char storage. Saving the char* to a @@ -815,7 +826,7 @@ void ddtrace_set_root_span_properties(ddtrace_root_span_data *span) { zval zv; ZVAL_STR(&zv, encoded_id); - zend_hash_str_add_new(meta, ZEND_STRL("runtime-id"), &zv); + zend_hash_str_update(attributes, ZEND_STRL("runtime-id"), &zv); if (ddtrace_span_is_entrypoint_root(&span->span)) { struct superglob_equiv data = {0}; @@ -839,7 +850,7 @@ void ddtrace_set_root_span_properties(ddtrace_root_span_data *span) { if (ZSTR_LEN(get_DD_HOSTNAME())) { zval hostname_zv; ZVAL_STR_COPY(&hostname_zv, get_DD_HOSTNAME()); - zend_hash_str_add_new(meta, ZEND_STRL("_dd.hostname"), &hostname_zv); + zend_hash_str_update(attributes, ZEND_STRL("_dd.hostname"), &hostname_zv); } else { #ifndef HOST_NAME_MAX @@ -853,7 +864,7 @@ void ddtrace_set_root_span_properties(ddtrace_root_span_data *span) { hostname = zend_string_truncate(hostname, strlen(ZSTR_VAL(hostname)), 0); zval hostname_zv; ZVAL_STR(&hostname_zv, hostname); - zend_hash_str_add_new(meta, ZEND_STRL("_dd.hostname"), &hostname_zv); + zend_hash_str_update(attributes, ZEND_STRL("_dd.hostname"), &hostname_zv); } } } @@ -925,13 +936,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); } @@ -939,114 +943,395 @@ void ddtrace_set_root_span_properties(ddtrace_root_span_data *span) { zval pid; ZVAL_DOUBLE(&pid, (double)getpid()); - zend_hash_str_add_new(metrics, ZEND_STRL("process_id"), &pid); + zend_hash_str_update(attributes, ZEND_STRL("process_id"), &pid); } -// buf->s remains NULL if encoding fails before any output, e.g. on a pending soft OOM. -static void dd_serialize_json(zend_array *arr, smart_str *buf, int options) { - zval zv; - ZVAL_ARR(&zv, arr); - zai_json_encode(buf, &zv, options); - smart_str_0(buf); +// Backing array of an array/object value; sets *release when the caller must +// zend_release_properties() afterwards (object properties on PHP >= 7.4). +static zend_array *dd_native_props(zval *value, bool *release) { + *release = false; + if (Z_TYPE_P(value) == IS_OBJECT) { +#if PHP_VERSION_ID >= 70400 + *release = true; + return zend_get_properties_for(value, ZEND_PROP_PURPOSE_JSON); +#else + return Z_OBJPROP_P(value); +#endif + } + return Z_ARR_P(value); } -static zend_string *dd_serialize_array_key(zend_string *prefix, zend_string *str_key, zend_ulong num_key) { - char number[3 * sizeof(zend_long) + 2]; - const char *suffix; - if (str_key) { - suffix = ZSTR_VAL(str_key); - } else { - snprintf(number, sizeof(number), ZEND_LONG_FMT, (zend_long)num_key); - suffix = number; +static inline void dd_native_release_props(zend_array *arr, bool release) { +#if PHP_VERSION_ID >= 70400 + if (release) { + zend_release_properties(arr); } - // Preserve the previous %s handling of embedded NULs. - size_t prefix_len = strlen(ZSTR_VAL(prefix)); - size_t suffix_len = strlen(suffix); - if (prefix_len > SIZE_MAX - suffix_len - 1) { - return NULL; +#else + (void)arr; (void)release; +#endif +} + +// Immutable arrays (opcache SHM, the empty array) must never be written to and cannot form a cycle. +static inline bool dd_native_is_immutable(zval *value) { + return Z_TYPE_P(value) == IS_ARRAY && (GC_FLAGS(Z_ARR_P(value)) & IS_ARRAY_IMMUTABLE); +} + +// Marks array/object `value` while it is serialized, so Z_IS_RECURSIVE_P detects a reference cycle back +// to it. Objects are marked on the object: get_properties_for may build a fresh table per call (DateTime). +// Mirrors php_var_dump: the value is also held (addref) while being iterated. +static inline void dd_native_protect_recursion(zval *value) { + if (!dd_native_is_immutable(value)) { + Z_ADDREF_P(value); + Z_PROTECT_RECURSION_P(value); } - zend_string *key = zai_string_falloc(prefix_len + 1 + suffix_len); - if (!key) { - return NULL; +} + +static inline void dd_native_unprotect_recursion(zval *value) { + if (!dd_native_is_immutable(value)) { + Z_UNPROTECT_RECURSION_P(value); + GC_DTOR_NO_REF(Z_COUNTED_P(value)); } - memcpy(ZSTR_VAL(key), ZSTR_VAL(prefix), prefix_len); - ZSTR_VAL(key)[prefix_len] = '.'; - memcpy(ZSTR_VAL(key) + prefix_len + 1, suffix, suffix_len + 1); - return key; } -static bool dd_serialize_array_recursively(ddog_SpanBytes *target, zend_string *str, zval *value, bool convert_to_double) { +// A packed PHP array nests as a list; any other array, and objects, nest as a map. +static inline bool dd_native_is_list(zval *value) { + return Z_TYPE_P(value) == IS_ARRAY && zend_array_is_list(Z_ARR_P(value)); +} + +// Map member key for `arr` entry (`str_key`, `num_key`): numeric keys as decimal into `numbuf`. +static inline ddog_CharSlice dd_native_member_key(zend_string *str_key, zend_ulong num_key, char numbuf[24]) { + return str_key + ? dd_zend_string_to_CharSlice(str_key) + : (ddog_CharSlice){ .ptr = numbuf, .len = snprintf(numbuf, 24, ZEND_ULONG_FMT, num_key) }; +} + +// Protected and private object members are mangled with a leading NUL byte. +static inline bool dd_native_is_hidden_member(zend_string *str_key) { + return str_key && ZSTR_LEN(str_key) > 0 && ZSTR_VAL(str_key)[0] == '\0'; +} + +// --- Native attributes -------------------------------------------------------------------------- +// +// One emitter fills every attribute map (span, link, event, nested map): scalars keep their PHP type, +// arrays/objects nest as a List/KeyValue (objects as a map of their public properties), and a +// reference cycle becomes the "" leaf. The top-level flags keep each node's v0.4-parity differences. +#define DD_ATTR_TOP (1 << 0) // top-level entry: empty keys are skipped +#define DD_ATTR_NULL_AS_STRING (1 << 1) // null is the "null" string (links, events), not skipped +#define DD_ATTR_EMPTY_ARRAY_AS_STRING (1 << 2) // an empty array is the "" tag (spans: no v0.4 form) +#define DD_ATTR_SCALARS_AS_STRINGS (1 << 3) // scalars are strings (links) + +#define DD_ATTR_SPAN (DD_ATTR_TOP | DD_ATTR_EMPTY_ARRAY_AS_STRING) +#define DD_ATTR_EVENT (DD_ATTR_TOP | DD_ATTR_NULL_AS_STRING) +#define DD_ATTR_LINK (DD_ATTR_TOP | DD_ATTR_NULL_AS_STRING | DD_ATTR_SCALARS_AS_STRINGS) + +static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string *zkey, zval *value, int flags); +static void dd_attr_emit_list(ddog_AttrList *dest, zval *value); + +// Builds the list for packed array `value`. +static ddog_AttrList *dd_attr_build_list(zval *value) { + zend_array *arr = Z_ARR_P(value); + ddog_AttrList *list = ddog_attr_list_new(zend_hash_num_elements(arr)); + dd_native_protect_recursion(value); + zval *val; + ZEND_HASH_FOREACH_VAL_IND(arr, val) { + dd_attr_emit_list(list, val); + } ZEND_HASH_FOREACH_END(); + dd_native_unprotect_recursion(value); + return list; +} + +// Builds the map for array/object `value` (numeric keys as decimal, matching PHP's json object keys). +static ddog_AttrMap *dd_attr_build_map(zval *value) { + bool release; + zend_array *arr = dd_native_props(value, &release); + ddog_AttrMap *map = ddog_attr_map_new(zend_hash_num_elements(arr)); + ddog_Attributes *attrs = ddog_attr_map_get_attributes(map); + dd_native_protect_recursion(value); + zval *val; + zend_string *str_key; + zend_ulong num_key; + ZEND_HASH_FOREACH_KEY_VAL_IND(arr, num_key, str_key, val) { + if (!dd_native_is_hidden_member(str_key)) { + char numbuf[24]; + dd_attr_emit(attrs, dd_native_member_key(str_key, num_key, numbuf), NULL, val, 0); + } + } ZEND_HASH_FOREACH_END(); + dd_native_unprotect_recursion(value); + dd_native_release_props(arr, release); + return map; +} + +// String form of a scalar leaf (null -> "null"). +static zend_string *dd_native_typed_str(zval *value) { + return datadog_convert_to_str(value); +} + +// Emits one list element, preserving the PHP scalar type (nested nulls are skipped). +static void dd_attr_emit_list(ddog_AttrList *dest, zval *value) { ZVAL_DEREF(value); - bool success = true; + switch (Z_TYPE_P(value)) { + case IS_ARRAY: + case IS_OBJECT: + if (Z_IS_RECURSIVE_P(value)) { + ddog_attr_list_push_str(dest, DDOG_CHARSLICE_C("")); + } else if (dd_native_is_list(value)) { + ddog_attr_list_push_list(dest, dd_attr_build_list(value)); + } else { + ddog_attr_list_push_map(dest, dd_attr_build_map(value)); + } + break; + case IS_NULL: + break; // V1 has no null value + case IS_TRUE: ddog_attr_list_push_bool(dest, true); break; + case IS_FALSE: ddog_attr_list_push_bool(dest, false); break; + case IS_LONG: ddog_attr_list_push_int(dest, Z_LVAL_P(value)); break; + case IS_DOUBLE: ddog_attr_list_push_double(dest, Z_DVAL_P(value)); break; + default: { + zend_string *str = dd_native_typed_str(value); + ddog_attr_list_push_str(dest, dd_zend_string_to_CharSlice(str)); + zend_string_release(str); + break; + } + } +} - if (Z_TYPE_P(value) == IS_ARRAY || Z_TYPE_P(value) == IS_OBJECT) { - zend_array *arr; - if (Z_TYPE_P(value) == IS_OBJECT) { -#if PHP_VERSION_ID >= 70400 - arr = zend_get_properties_for(value, ZEND_PROP_PURPOSE_JSON); -#else - arr = Z_OBJPROP_P(value); -#endif - } else { - arr = Z_ARR_P(value); +// 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; +} + +// Emits `value` under `key` into `dest`; `zkey`, when given, is `key` as a zend_string (zero-copy). +static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string *zkey, zval *value, int flags) { + if ((flags & DD_ATTR_TOP) && !key.len) { + return; + } + bool as_string = flags & DD_ATTR_SCALARS_AS_STRINGS; + ZVAL_DEREF(value); + switch (Z_TYPE_P(value)) { + case IS_ARRAY: + case IS_OBJECT: + if (Z_IS_RECURSIVE_P(value) + || ((flags & DD_ATTR_EMPTY_ARRAY_AS_STRING) && Z_TYPE_P(value) == IS_ARRAY && !zend_hash_num_elements(Z_ARR_P(value)))) { + ddog_attributes_add_str(dest, key, DDOG_CHARSLICE_C("")); + } else if (dd_native_is_list(value)) { + ddog_attributes_add_list(dest, key, dd_attr_build_list(value)); + } else { + ddog_attributes_add_map(dest, key, dd_attr_build_map(value)); + } + return; + case IS_NULL: + if (!(flags & DD_ATTR_NULL_AS_STRING)) { + return; + } + break; + case IS_TRUE: + case IS_FALSE: + if (!as_string) { + ddog_attributes_add_bool(dest, key, Z_TYPE_P(value) == IS_TRUE); + return; + } + break; + case IS_LONG: + if (!as_string) { + ddog_attributes_add_int(dest, key, Z_LVAL_P(value)); + return; + } + break; + case IS_DOUBLE: + if (!as_string) { + if (zkey) { + ddog_attributes_add_double_zstr(dest, zkey, Z_DVAL_P(value)); + } else { + ddog_attributes_add_double(dest, key, Z_DVAL_P(value)); + } + return; + } + break; + } + zend_string *str = dd_native_typed_str(value); + if (zkey) { + ddog_attributes_add_zstr(dest, zkey, str); + } else { + ddog_attributes_add_str(dest, key, dd_zend_string_to_CharSlice(str)); + } + zend_string_release(str); +} + +// Emit each SpanLink into the V1 builder span, reading from the PHP link objects (scalar attributes +// are strings; dropped_attributes_count has no PHP-side source). +static void dd_span_links_to_rust(zend_array *links, ddog_SpanNode *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_new_link(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_link_set_trace_id(rust_link, id.high, id.low); + } + ddog_link_set_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_link_set_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) { + ddog_Attributes *link_attrs = ddog_link_get_attributes(rust_link); + zend_ulong idx; + zend_string *key; + zval *aval; + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(attrs), idx, key, aval) { + char numbuf[24]; + dd_attr_emit(link_attrs, dd_native_member_key(key, idx, numbuf), NULL, aval, DD_ATTR_LINK); + } ZEND_HASH_FOREACH_END(); + } + } ZEND_HASH_FOREACH_END(); +} + +// Emit each SpanEvent into the V1 builder span, dispatching attributes by type. ExceptionSpanEvent +// flattens exception.message/type/stacktrace as string attributes. +static void dd_span_events_to_rust(zend_array *events, ddog_SpanNode *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_new_event(span); + ddog_Attributes *event_attrs = ddog_event_get_attributes(rust_event); + + zval *name = &event->property_name; + if (Z_TYPE_P(name) == IS_STRING) { + ddog_event_set_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_event_set_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_attributes_add_str(event_attrs, + DDOG_CHARSLICE_C("exception.message"), dd_zend_string_to_CharSlice(message)); + } + ddog_attributes_add_str(event_attrs, + 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_attributes_add_str(event_attrs, + 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]; + dd_attr_emit(event_attrs, dd_native_member_key(key, idx, numbuf), NULL, aval, DD_ATTR_EVENT); + } ZEND_HASH_FOREACH_END(); } - if (zend_hash_num_elements(arr) && !GC_IS_RECURSIVE(arr)) { - GC_PROTECT_RECURSION(arr); + } ZEND_HASH_FOREACH_END(); +} +// Value stored through the $meta/$metrics views: meta leaves become strings, metric leaves doubles, +// and empty or recursive arrays/objects the ""/0.0 placeholder, so the v0.4 wire keeps the old form. +void ddtrace_normalize_tag_value(zval *dst, zval *value, bool metric) { + ZVAL_DEREF(value); + if (Z_TYPE_P(value) == IS_ARRAY || Z_TYPE_P(value) == IS_OBJECT) { + bool release; + zend_array *arr = dd_native_props(value, &release); + if (zend_hash_num_elements(arr) && !Z_IS_RECURSIVE_P(value)) { + bool is_list = dd_native_is_list(value); + array_init_size(dst, zend_hash_num_elements(arr)); + dd_native_protect_recursion(value); zval *val; zend_string *str_key; zend_ulong num_key; ZEND_HASH_FOREACH_KEY_VAL_IND(arr, num_key, str_key, val) { - if (str_key && ZSTR_VAL(str_key)[0] == '\0' && ZSTR_LEN(str_key) > 0) { - // Skip protected and private members + if (dd_native_is_hidden_member(str_key)) { continue; } - // All ancestor keys remain live during recursion. Stop at the - // soft limit rather than exhausting PHP's hard-limit reserve. - zend_string *key = dd_serialize_array_key(str, str_key, num_key); - if (!key) { - success = false; - break; - } - success = dd_serialize_array_recursively(target, key, val, convert_to_double); - zend_string_release(key); - if (!success) { - break; + zval child; + ddtrace_normalize_tag_value(&child, val, metric); + if (is_list) { + zend_hash_next_index_insert_new(Z_ARR_P(dst), &child); + } else if (str_key) { + zend_hash_update(Z_ARR_P(dst), str_key, &child); + } else { + zend_hash_index_update(Z_ARR_P(dst), num_key, &child); } } ZEND_HASH_FOREACH_END(); - - GC_UNPROTECT_RECURSION(arr); - } else if (convert_to_double) { - ddog_add_span_metrics_zstr(target, str, 0.0); - } else { - ddog_add_zstr_span_meta_str(target, str, ""); + dd_native_unprotect_recursion(value); + dd_native_release_props(arr, release); + return; } - -#if PHP_VERSION_ID >= 70400 - if (Z_TYPE_P(value) == IS_OBJECT) { - zend_release_properties(arr); + dd_native_release_props(arr, release); + if (metric) { + ZVAL_DOUBLE(dst, 0.0); + } else { + ZVAL_EMPTY_STRING(dst); } -#endif - } else if (convert_to_double) { - ddog_add_span_metrics_zstr(target, str, zval_get_double(value)); + } else if (metric) { + ZVAL_DOUBLE(dst, 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)); - zval_ptr_dtor(&val_as_string); + datadog_convert_to_string(dst, value); } - return success; -} - -static bool dd_serialize_array_meta_recursively(ddog_SpanBytes *target, zend_string *str, zval *value) { - return dd_serialize_array_recursively(target, str, value, false); -} - -static bool dd_serialize_array_metrics_recursively(ddog_SpanBytes *target, zend_string *str, zval *value) { - return 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(ddog_SpanNode *target, zend_string *str, zval *value) { char *data; size_t size; @@ -1062,7 +1347,9 @@ 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}); + if (ZSTR_LEN(str)) { + ddog_attributes_add_bytes(ddog_span_get_attributes(target), dd_zend_string_to_CharSlice(str), (ddog_CharSlice){.ptr = data, .len = size}); + } efree(data); } @@ -1228,34 +1515,35 @@ static bool dd_is_http_error(int status) { return false; } -static void dd_set_http_error(zend_array *meta, int status, bool ignore_error) { +static void dd_set_http_error(ddtrace_span_data *span, int status, bool ignore_error) { if (status) { + zend_array *attributes = ddtrace_property_array(&span->property_attributes); zend_string *status_str = zend_long_to_str((long)status); zval status_zv; ZVAL_STR(&status_zv, status_str); - zend_hash_str_update(meta, ZEND_STRL("http.status_code"), &status_zv); + zend_hash_str_update(attributes, ZEND_STRL("http.status_code"), &status_zv); // Only check status codes if not ignoring errors - if (!ignore_error && dd_is_http_error(status)) { - zval zv = {0}, *value; - if ((value = zend_hash_str_add(meta, ZEND_STRL("error.type"), &zv))) { - ZVAL_STR(value, zend_string_init(ZEND_STRL("HttpError"), 0)); - } + if (!ignore_error && dd_is_http_error(status) && !ddtrace_span_find_tag(span, ZEND_STRL("error.type"))) { + zval zv; + ZVAL_STR(&zv, zend_string_init(ZEND_STRL("HttpError"), 0)); + zend_hash_str_add_new(attributes, ZEND_STRL("error.type"), &zv); } } } -static void dd_set_entrypoint_root_span_props_end(zend_array *meta, int status, struct iter *headers, bool ignore_error) { - dd_set_http_error(meta, status, ignore_error); +static void dd_set_entrypoint_root_span_props_end(ddtrace_span_data *span, int status, struct iter *headers, bool ignore_error) { + dd_set_http_error(span, status, ignore_error); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); for (zend_string *lowerheader, *headerval; headers->next(headers, &lowerheader, &headerval);) { - dd_add_header_to_meta(meta, "response", lowerheader, headerval); + dd_add_header_to_meta(attributes, "response", lowerheader, headerval); zend_string_release(lowerheader); zend_string_release(headerval); } } -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(ddog_SpanNode *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); @@ -1263,19 +1551,28 @@ static void dd_set_entrypoint_root_rust_span_props_end(ddog_SpanBytes *span, str } } +// $ignoreError, or the deprecated "error.ignored" tag of a span not yet serialized (serialized spans +// have it folded into the property, see ddtrace_precompute_span). +static bool dd_span_ignores_error(ddtrace_span_data *span) { + if (zend_is_true(&span->property_ignore_error)) { + return true; + } + zval *attr = ddtrace_span_find_tag(span, ZEND_STRL("error.ignored")); + return attr && zend_is_true(attr); +} + static bool should_track_error(zend_object *exception, ddtrace_span_data *span) { if (Z_TYPE(span->property_exception) != IS_OBJECT || Z_OBJ(span->property_exception) != exception) { return true; } zval *zv; - zend_array *meta = ddtrace_property_array(&span->property_meta); // Check if error should be ignored or tracking is disabled - if ((zv = zend_hash_str_find(meta, ZEND_STRL("error.ignored"))) && zend_is_true(zv)) { + if (dd_span_ignores_error(span)) { return false; } - if ((zv = zend_hash_str_find(meta, ZEND_STRL("track_error"))) && !zend_is_true(zv)) { + if ((zv = ddtrace_span_find_tag(span, ZEND_STRL("track_error"))) && !zend_is_true(zv)) { return false; } return true; @@ -1320,91 +1617,49 @@ 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) { - ddog_add_str_span_meta_CharSlice(destination, key, value); - if (delete_source) { - ddog_del_span_meta_str(source, key); +// DD_ENV/DD_VERSION win, else the root's env/version (DD_TAGS fallback); the hostname is _dd.hostname's. +static void dd_set_payload_fields(ddog_TracerPayloadV1Builder *builder, ddtrace_span_precomputed *pre, zend_array *attributes, zval *git_metadata) { + zend_string *env = ZSTR_LEN(get_DD_ENV()) ? get_DD_ENV() : pre->env; + zend_string *version = ZSTR_LEN(get_DD_VERSION()) ? get_DD_VERSION() : pre->version; + ddog_CharSlice hostname = DDOG_CHARSLICE_C(""); + zval *hostname_zv = zend_hash_str_find(attributes, ZEND_STRL("_dd.hostname")); + if (get_DD_TRACE_REPORT_HOSTNAME() && hostname_zv && Z_TYPE_P(hostname_zv) == IS_STRING) { + hostname = dd_zend_string_to_CharSlice(Z_STR_P(hostname_zv)); + } + ddog_set_payload_metadata(builder, + env ? dd_zend_string_to_CharSlice(env) : DDOG_CHARSLICE_C(""), + version ? dd_zend_string_to_CharSlice(version) : DDOG_CHARSLICE_C(""), + hostname); + + // Only set when git metadata was injected (DD_TRACE_GIT_METADATA_ENABLED). + if (Z_TYPE_P(git_metadata) == IS_OBJECT) { + datadog_git_metadata *metadata = (datadog_git_metadata *)Z_OBJ_P(git_metadata); + ddog_Attributes *payload_attrs = ddog_payload_get_attributes(builder); + if (Z_TYPE(metadata->property_commit) == IS_STRING && Z_STRLEN(metadata->property_commit)) { + ddog_attributes_add_lit(payload_attrs, "_dd.git.commit.sha", dd_zend_string_to_CharSlice(Z_STR(metadata->property_commit))); } - } -} - -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); + if (Z_TYPE(metadata->property_repository) == IS_STRING && Z_STRLEN(metadata->property_repository)) { + ddog_attributes_add_lit(payload_attrs, "_dd.git.repository_url", dd_zend_string_to_CharSlice(Z_STR(metadata->property_repository))); } } } -bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceBytes *trace, bool p0_trace, ddog_SpanBytes **serialized_span) { - if (serialized_span) { - *serialized_span = NULL; - } - zend_array *meta = ddtrace_property_array(&span->property_meta); - zend_array *metrics = ddtrace_property_array(&span->property_metrics); +ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtrace_serialize_ctx *ctx, bool p0_trace) { + zend_array *attributes = ddtrace_property_array(&span->property_attributes); - // 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")); - if (http_status_code) { + // http.status_code is a string tag on the wire; a numeric one (e.g. OTel's metric) is converted. + zval *attr_status_code = zend_hash_str_find(attributes, ZEND_STRL("http.status_code")); + if (attr_status_code && Z_TYPE_P(attr_status_code) != IS_STRING) { zval status_code_as_string; - datadog_convert_to_string(&status_code_as_string, http_status_code); - zend_hash_str_update(meta, ZEND_STRL("http.status_code"), &status_code_as_string); - zend_hash_str_del(metrics, ZEND_STRL("http.status_code")); + datadog_convert_to_string(&status_code_as_string, attr_status_code); + zend_hash_str_update(attributes, ZEND_STRL("http.status_code"), &status_code_as_string); } - - // Remap OTel's status code (metric, http.response.status_code) to DD's status code (meta, http.status_code) - // OTel HTTP semantic conventions >= 1.21.0 - zval *http_response_status_code = zend_hash_str_find(metrics, ZEND_STRL("http.response.status_code")); - if (http_response_status_code) { + zval *attr_response_status_code = zend_hash_str_find(attributes, ZEND_STRL("http.response.status_code")); + if (attr_response_status_code && Z_TYPE_P(attr_response_status_code) != IS_STRING) { zval status_code_as_string; - datadog_convert_to_string(&status_code_as_string, http_response_status_code); - zend_hash_str_update(meta, ZEND_STRL("http.status_code"), &status_code_as_string); - zend_hash_str_del(metrics, ZEND_STRL("http.response.status_code")); + datadog_convert_to_string(&status_code_as_string, attr_response_status_code); + zend_hash_str_update(attributes, ZEND_STRL("http.status_code"), &status_code_as_string); + zend_hash_str_del(attributes, ZEND_STRL("http.response.status_code")); } ddtrace_span_precomputed pre; @@ -1418,7 +1673,7 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte } if (!ddtrace_trace_passes_filter(span)) { ddtrace_free_span_precomputed(&pre); - return true; + return NULL; } } @@ -1430,7 +1685,7 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte if (datadog_active_sapi == DATADOG_PHP_SAPI_FRANKENPHP && !status) { status = pre.has_exception ? 500 : 200; } - dd_set_http_error(meta, status, pre.ignore_error); + dd_set_http_error(span, status, pre.ignore_error); } ddtrace_span_data *inferred_span = NULL; @@ -1595,18 +1850,25 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte } ddtrace_feed_span_to_concentrator(span, &pre); ddtrace_free_span_precomputed(&pre); - return true; + return NULL; } - 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); + // The span is built directly into the native V1 builder chunk; the chunk carries the 128-bit + // trace id (set at creation). + if (ctx->chunk == DD_CHUNK_NONE) { + // dropped_trace is reserved for the agent; the chunk priority carries the sampling decision. + ctx->chunk = ddog_new_chunk(ctx->builder, span->root->trace_id.high, span->root->trace_id.low); + } + bool is_first_span = ddog_chunk_span_count(ctx->chunk) == 0; + ddog_SpanNode *rspan = ddog_new_span(ctx->chunk); + ddog_Attributes *rattrs = ddog_span_get_attributes(rspan); - ddog_set_span_trace_id(rust_span, span->root->trace_id.low); - ddog_set_span_id(rust_span, span->span_id); + ddog_span_set_id(rspan, 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 @@ -1614,20 +1876,26 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte 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) { + ddog_span_set_parent_id(rspan, parent_id_set); } - ddog_set_span_start(rust_span, span->start); - ddog_set_span_duration(rust_span, span->duration); - - if (is_first_span) { - ddog_add_str_span_meta_str(rust_span, "_dd.sdk.otlp_export", "false"); + ddog_span_set_start(rspan, span->start); + ddog_span_set_duration(rspan, span->duration); + // Process tags and the OTLP export marker are TracerPayload attributes (V1 guide), taken from the payload's first trace. + if (is_first_span && !ctx->process_tags_set) { + ctx->process_tags_set = true; + ddog_Attributes *payload_attrs = ddog_payload_get_attributes(ctx->builder); + // v0.4 downgrade puts this on each chunk's first span, as the pre-V1 serializer did. + ddog_attributes_add_lit(payload_attrs, "_dd.sdk.otlp_export", DDOG_CHARSLICE_C("false")); zend_string *process_tags = datadog_process_tags_get_serialized(); if (ZSTR_LEN(process_tags)) { const char *svc_tag_appendix = NULL; @@ -1637,8 +1905,7 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte if (dd_service && ZSTR_LEN(dd_service)) { svc_tag_appendix = ",svc.user:true"; } else { - zend_array *root_meta = ddtrace_property_array(&span->root->property_meta); - if (!zend_hash_str_exists(root_meta, ZEND_STRL("_dd.svc_src"))) { + if (!ddtrace_span_find_tag(&span->root->span, ZEND_STRL("_dd.svc_src"))) { zend_string *root_svc = datadog_convert_to_str(&span->root->property_service); if (ZSTR_LEN(root_svc)) { normalized_default = ddog_normalize_process_tag_value(dd_zend_string_to_CharSlice(root_svc)); @@ -1657,10 +1924,10 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte smart_str_appends(&combined, normalized_default); } smart_str_0(&combined); - ddog_add_str_span_meta_zstr(rust_span, "_dd.tags.process", combined.s); + ddog_attributes_add_lit(payload_attrs, "_dd.tags.process", dd_zend_string_to_CharSlice(combined.s)); smart_str_free(&combined); } else { - ddog_add_str_span_meta_zstr(rust_span, "_dd.tags.process", process_tags); + ddog_attributes_add_lit(payload_attrs, "_dd.tags.process", dd_zend_string_to_CharSlice(process_tags)); } if (normalized_default) { @@ -1671,127 +1938,176 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte // SpanData::$name defaults to fully qualified called name (set at span close) if (pre.name) { - ddog_set_span_name_zstr(rust_span, pre.name); + ddog_set_span_name_zstr(rspan, pre.name); } if (pre.name_from_meta) { - zend_hash_str_del(meta, ZEND_STRL("operation.name")); + zend_hash_str_del(attributes, ZEND_STRL("operation.name")); } // SpanData::$resource defaults to SpanData::$name if (pre.resource) { - ddog_set_span_resource_zstr(rust_span, pre.resource); + ddog_set_span_resource_zstr(rspan, pre.resource); } if (pre.resource_from_meta) { - zend_hash_str_del(meta, ZEND_STRL("resource.name")); + zend_hash_str_del(attributes, ZEND_STRL("resource.name")); } // 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); + ddog_set_span_service_zstr(rspan, pre.service); } if (pre.service_from_meta) { - zend_hash_str_del(meta, ZEND_STRL("service.name")); + zend_hash_str_del(attributes, ZEND_STRL("service.name")); } // SpanData::$type is optional and defaults to 'custom' at the Agent level if (pre.type) { - ddog_set_span_type_zstr(rust_span, pre.type); + ddog_set_span_type_zstr(rspan, pre.type); } if (pre.type_from_meta) { - zend_hash_str_del(meta, ZEND_STRL("span.type")); + zend_hash_str_del(attributes, ZEND_STRL("span.type")); } - zval *analytics_event = zend_hash_str_find(meta, ZEND_STRL("analytics.event")); + // analytics.event maps to _dd1.sr.eausr (a valid value wins over a set _dd1.sr.eausr). + zval *analytics_event = zend_hash_str_find(attributes, 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)); + ZVAL_DEREF(analytics_event); + double parsed_analytics_event = Z_TYPE_P(analytics_event) == IS_STRING + ? strconv_parse_bool(Z_STR_P(analytics_event)) + : zval_get_double(analytics_event); + if (Z_TYPE_P(analytics_event) != IS_STRING || parsed_analytics_event >= 0) { + zend_hash_str_del(attributes, ZEND_STRL("_dd1.sr.eausr")); + ddog_attributes_add_double_lit(rattrs, "_dd1.sr.eausr", parsed_analytics_event); } - zend_hash_str_del(meta, ZEND_STRL("analytics.event")); + zend_hash_str_del(attributes, 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); + ddog_attributes_add_double_lit(rattrs, "_dd.span_sampling.mechanism", 8.0); + ddog_attributes_add_double_lit(rattrs, "_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); + ddog_attributes_add_double_lit(rattrs, "_dd.span_sampling.max_per_second", span_sampling_max_per_second); } } - if (meta) { - zend_string *meta_str_key; - 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)) { - if (!dd_serialize_array_meta_recursively(rust_span, meta_str_key, orig_val)) { - goto allocation_failed; - } - } - } + // Promote span/chunk fields up front (their tags are deleted below). env/version are property-first + // with a tag fallback: DD_TAGS "env"/"version" are plain tags when DD_ENV/DD_VERSION are unset. + // pre.env/pre.version already carry that fallback. + if (pre.env) { + ddog_set_span_env(rspan, dd_zend_string_to_CharSlice(pre.env)); + } + if (pre.version) { + ddog_set_span_version(rspan, dd_zend_string_to_CharSlice(pre.version)); + } + + zval *component_prop = &span->property_component; + ZVAL_DEREF(component_prop); + if (Z_TYPE_P(component_prop) == IS_STRING && Z_STRLEN_P(component_prop) > 0) { + ddog_set_span_component(rspan, dd_zend_string_to_CharSlice(Z_STR_P(component_prop))); + } else { + zval *component_meta = zend_hash_str_find(attributes, ZEND_STRL("component")); + if (component_meta && Z_TYPE_P(component_meta) == IS_STRING) { + ddog_set_span_component(rspan, dd_zend_string_to_CharSlice(Z_STR_P(component_meta))); } - ZEND_HASH_FOREACH_END(); } - // Avoid adding it twice to meta - if (!pre.env_deprecated && pre.env) { - ddog_add_str_span_meta_zstr(rust_span, "env", pre.env); + zval *span_kind_prop = &span->property_span_kind; + ZVAL_DEREF(span_kind_prop); + // Non-canonical span.kind strings (e.g. "process") leave the kind unspecified; + // keep them as a plain attribute instead of deleting below. + bool span_kind_is_canonical = true; + if (Z_TYPE_P(span_kind_prop) == IS_LONG && Z_LVAL_P(span_kind_prop) >= 1 && Z_LVAL_P(span_kind_prop) <= 5) { + ddog_set_span_kind(rspan, (uint32_t)Z_LVAL_P(span_kind_prop)); + } else { + zval *span_kind_meta = zend_hash_str_find(attributes, ZEND_STRL("span.kind")); + if (span_kind_meta && Z_TYPE_P(span_kind_meta) == IS_STRING) { + span_kind_is_canonical = ddog_set_span_kind_str(rspan, dd_zend_string_to_CharSlice(Z_STR_P(span_kind_meta))); + } } - if (!pre.version_deprecated && pre.version) { - ddog_add_str_span_meta_zstr(rust_span, "version", pre.version); + + // _dd.origin is property-sourced; the chunk carries it (never a span attribute). + zval *origin = &span->root->property_origin; + if (Z_TYPE_P(origin) > IS_NULL && (Z_TYPE_P(origin) != IS_STRING || Z_STRLEN_P(origin))) { + ddog_set_chunk_origin(ctx->chunk, dd_zend_string_to_CharSlice(Z_STR_P(origin))); + } + + { + // _dd.p.dm is "-N" (legacy "-N"): the mechanism is the digits after the last '-'. + // Unparseable values leave the chunk field unset rather than claiming mechanism 0. + zval *dm_meta = zend_hash_str_find(attributes, ZEND_STRL("_dd.p.dm")); + if (dm_meta && Z_TYPE_P(dm_meta) == IS_STRING) { + const char *dash = zend_memrchr(Z_STRVAL_P(dm_meta), '-', Z_STRLEN_P(dm_meta)); + const char *p = dash ? dash + 1 : Z_STRVAL_P(dm_meta); + const char *end = Z_STRVAL_P(dm_meta) + Z_STRLEN_P(dm_meta); + uint64_t mech = 0; + bool valid = p < end; + for (; valid && p < end; p++) { + valid = *p >= '0' && *p <= '9' && (mech = mech * 10 + (uint64_t)(*p - '0')) <= UINT32_MAX; + } + if (valid) { + ddog_set_chunk_sampling_mechanism(ctx->chunk, (uint32_t)mech); + } + } + // Delete promoted keys so the copy loop only carries plain attributes. + zend_hash_str_del(attributes, ZEND_STRL("env")); + zend_hash_str_del(attributes, ZEND_STRL("version")); + zend_hash_str_del(attributes, ZEND_STRL("component")); + if (span_kind_is_canonical) { + zend_hash_str_del(attributes, ZEND_STRL("span.kind")); + } + zend_hash_str_del(attributes, ZEND_STRL("_dd.origin")); + zend_hash_str_del(attributes, ZEND_STRL("_dd.p.dm")); + // _sampling_priority_v1 becomes the chunk sampling priority below. + zend_hash_str_del(attributes, ZEND_STRL("_sampling_priority_v1")); } + // $attributes is the single tag store ($meta/$metrics are views onto it). + zend_string *attr_str_key; + zval *attr_val; + ZEND_HASH_FOREACH_STR_KEY_VAL_IND(attributes, attr_str_key, attr_val) { + if (attr_str_key) { + dd_attr_emit(rattrs, dd_zend_string_to_CharSlice(attr_str_key), attr_str_key, attr_val, DD_ATTR_SPAN); + } + } ZEND_HASH_FOREACH_END(); + zval *exception_zv = &span->property_exception; if (pre.has_exception && !pre.ignore_error) { enum dd_exception exception_type = DD_EXCEPTION_THROWN; 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, rspan, exception_type); } + // Links/events are emitted natively from the PHP span (the _dd.span_links/events meta keys are + // never produced on the V1 path). 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_json(span_links, &buf, 0); - if (buf.s) { - ddog_add_str_span_meta_zstr(rust_span, "_dd.span_links", buf.s); - } - smart_str_free(&buf); - EG(exception) = current_exception; + dd_span_links_to_rust(span_links, rspan); } 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_json(span_events, &buf, 0); - if (buf.s) { - ddog_add_str_span_meta_zstr(rust_span, "events", buf.s); - } - smart_str_free(&buf); - EG(exception) = current_exception; + dd_span_events_to_rust(span_events, rspan); } zval *git_metadata = &span->root->property_git_metadata; + // Payload env/app_version/hostname/git come from the payload's first root span, as the v0.4 agent read them. + if (is_root_span && !ctx->payload_fields_set) { + ctx->payload_fields_set = true; + dd_set_payload_fields(ctx->builder, &pre, attributes, git_metadata); + } if (git_metadata && Z_TYPE_P(git_metadata) == IS_OBJECT) { datadog_git_metadata *metadata = (datadog_git_metadata *)Z_OBJ_P(git_metadata); 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_span_attr_zstr(rspan, "_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_span_attr_zstr(rspan, "_dd.git.repository_url", repository_url); zend_string_release(repository_url); } } @@ -1799,20 +2115,20 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte if (get_DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED()) { 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; + zval *peer_service_tag = zend_hash_str_find(attributes, ZEND_STRL("peer.service")); 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_span_attr_str(rspan, "_dd.peer.service.source", "peer.service"); + dd_set_mapped_peer_service(rspan, 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; + zval *found_peer_service = zend_hash_find(attributes, Z_STR_P(tag)); 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_span_attr_zstr(rspan, "_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(rspan, peer)) { + dd_span_attr_zstr(rspan, "peer.service", peer); } zend_string_release(peer); break; @@ -1824,18 +2140,13 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte 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(rspan, 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)); - } - bool error = dd_compute_span_is_error(&pre); if (error) { - ddog_set_span_error(rust_span, 1); + ddog_span_set_error(rspan, true); if (Z_TYPE(span->property_exception) == IS_OBJECT) { zend_object *exception = Z_OBJ(span->property_exception); ddtrace_span_data *current = span; @@ -1843,7 +2154,7 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte do { should_track = should_track_error(exception, current); if (!should_track) { - ddog_add_str_span_meta_str(rust_span, "track_error", "false"); + dd_span_attr_str(rspan, "track_error", "false"); break; } current = current->parent ? SPANDATA(current->parent) : NULL; @@ -1851,12 +2162,6 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte } } - 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); - zend_string_release(trace_id_str); - } - // Add _dd.base_service if service name differs from mapped root service name. zval prop_service_as_string; datadog_convert_to_string(&prop_service_as_string, &span->property_service); @@ -1868,7 +2173,7 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte 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_span_attr_zstr(rspan, "_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)); @@ -1877,31 +2182,24 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte ddtrace_feed_span_to_concentrator(span, &pre); } - 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 (!dd_serialize_array_metrics_recursively(rust_span, str_key, val)) { - goto allocation_failed; - } - } - } ZEND_HASH_FOREACH_END(); + // _sampling_priority_v1 is a chunk-level field, not a span metric. if ((is_root_span && !inferred_span) || is_inferred_span) { if (Z_TYPE_P(&span->root->property_sampling_priority) != IS_UNDEF) { long sampling_priority = zval_get_long(&span->root->property_sampling_priority); - if (!get_global_DD_APM_TRACING_ENABLED() && !ddtrace_trace_source_is_meta_asm_sourced(meta)) { + if (!get_global_DD_APM_TRACING_ENABLED() && !ddtrace_trace_source_is_meta_asm_sourced(attributes)) { sampling_priority = MIN(PRIORITY_SAMPLING_AUTO_KEEP, sampling_priority); } - ddog_add_span_metrics_str(rust_span, "_sampling_priority_v1", sampling_priority); + ddog_set_chunk_sampling_priority(ctx->chunk, (int32_t)sampling_priority); } } if (!get_global_DD_APM_TRACING_ENABLED()) { - ddog_add_span_metrics_str(rust_span, "_dd.apm.enabled", 0); + ddog_attributes_add_double_lit(rattrs, "_dd.apm.enabled", 0); } - if (DATADOG_G(sidecar) && get_DD_TRACE_STATS_COMPUTATION_ENABLED() && !is_inferred_span) { + // Top-level as the agent defines it: a local root, or a span whose service differs from its parent's. + if (ctx->mark_top_level || (DATADOG_G(sidecar) && get_DD_TRACE_STATS_COMPUTATION_ENABLED() && !is_inferred_span)) { bool is_top_level_span = !span->parent; if (span->parent) { zval *parent_service = &SPANDATA(span->parent)->property_service; @@ -1915,49 +2213,43 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte } } if (is_top_level_span) { - ddog_add_span_metrics_str(rust_span, "_dd.top_level", 1); + ddog_attributes_add_double_lit(rattrs, "_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.); + ddog_attributes_add_double_lit(rattrs, "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)); + ddog_attributes_add_double_lit(rattrs, "php.memory.peak_usage_bytes", zend_memory_peak_usage(false)); + ddog_attributes_add_double_lit(rattrs, "php.memory.peak_real_usage_bytes", zend_memory_peak_usage(true)); } } - if (inferred_span) { - ddog_SpanBytes *serialized_inferred_span; - if (!ddtrace_serialize_span_to_rust_span(inferred_span, trace, p0_trace, &serialized_inferred_span)) { - goto allocation_failed; - } - rust_span = ddog_get_span(trace, rust_span_index); - - if (serialized_inferred_span) { - 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); + ddog_SpanNode *inferred = inferred_span ? ddtrace_serialize_span_to_rust_span(inferred_span, ctx, p0_trace) : NULL; + // A dropped inferred span returns NULL; skip the transfers then. Node pointers stay valid across + // sibling pushes, so rspan is still usable after the inferred span was added to the chunk. + if (inferred) { + ddog_transfer_span_attr(rspan, inferred, "_dd.agent_psr", true); + ddog_transfer_span_attr(rspan, inferred, "_dd.rule_psr", true); + ddog_transfer_span_attr(rspan, inferred, "_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); + ddog_transfer_span_attr(rspan, inferred, "error.message", false); + ddog_transfer_span_attr(rspan, inferred, "error.type", false); + ddog_transfer_span_attr(rspan, inferred, "error.stack", false); + ddog_transfer_span_attr(rspan, inferred, "track_error", false); + ddog_transfer_span_attr(rspan, inferred, "_dd.p.dm", true); + ddog_transfer_span_attr(rspan, inferred, "_dd.p.ksr", false); + ddog_transfer_span_attr(rspan, inferred, "_dd.svc_src", false); + ddog_transfer_span_attr(rspan, inferred, DD_TAG_HTTP_REQH_ENDPOINT_SCAN, false); + ddog_transfer_span_attr(rspan, inferred, DD_TAG_HTTP_REQH_SECURITY_TEST, false); - ddog_set_span_error(serialized_inferred_span, ddog_get_span_error(rust_span)); - } + ddog_span_set_error(inferred, ddog_span_get_error(rspan)); } LOGEV(SPAN, { - ddog_CharSlice span_log = ddog_span_debug_log(rust_span); + ddog_CharSlice span_log = ddog_v1_span_debug_log(ctx->chunk, rspan); log("Encoding span: %s", span_log.ptr); ddog_free_charslice(span_log); }); @@ -1967,130 +2259,226 @@ bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceByte 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(rspan, ms_str_key, ms_val); } } ZEND_HASH_FOREACH_END(); - ddog_del_span_meta_str(rust_span, "error.ignored"); - ddtrace_free_span_precomputed(&pre); - if (serialized_span) { - *serialized_span = rust_span; + return rspan; +} + +// Reads a native V1 attribute value into a zval, recursing into List/KeyValue so nested attributes +// surface as nested PHP arrays (a list becomes a packed array, a KeyValue an assoc map). +static void dd_attr_value_to_zval(const ddog_AttrValue *value, zval *out) { + switch (ddog_v1_value_type(value)) { + case ddog_DDOG_V1_ATTR_INT: + ZVAL_LONG(out, ddog_v1_value_int(value)); + break; + case ddog_DDOG_V1_ATTR_DOUBLE: + ZVAL_DOUBLE(out, ddog_v1_value_double(value)); + break; + case ddog_DDOG_V1_ATTR_BOOL: + ZVAL_BOOL(out, ddog_v1_value_bool(value)); + break; + case ddog_DDOG_V1_ATTR_BYTES: + ZVAL_STR(out, dd_CharSlice_to_zend_string(ddog_v1_value_bytes(value))); + break; + case ddog_DDOG_V1_ATTR_LIST: { + array_init(out); + size_t n = ddog_v1_value_list_len(value); + for (size_t i = 0; i < n; i++) { + zval v; + dd_attr_value_to_zval(ddog_v1_value_list_get(value, i), &v); + add_next_index_zval(out, &v); + } + break; + } + case ddog_DDOG_V1_ATTR_KEYVALUE: { + array_init(out); + const ddog_Attributes *members = ddog_v1_value_map(value); + size_t n = ddog_v1_attributes_len(members); + for (size_t i = 0; i < n; i++) { + ddog_CharSlice mkey = ddog_v1_attributes_key(members, i); + zval v; + dd_attr_value_to_zval(ddog_v1_attributes_value(members, i), &v); + // Symtable insert: a numeric member name ("0") becomes an integer key again. + add_assoc_zval_ex(out, dd_CharSlice_ptr(mkey), mkey.len, &v); + } + break; + } + default: // STRING + ZVAL_STR(out, dd_CharSlice_to_zend_string(ddog_v1_value_str(value))); + break; } - return true; +} -allocation_failed: - ddtrace_free_span_precomputed(&pre); - return false; +// Reads an attribute map into the `out` array. With `bytes_out`, Bytes values go +// there instead (v0.4 meta_struct entries). A repeated key keeps its last write, as on the wire. +static void dd_attributes_to_zval(const ddog_Attributes *attrs, zval *out, zval *bytes_out) { + size_t n = ddog_v1_attributes_len(attrs); + for (size_t i = 0; i < n; i++) { + ddog_CharSlice key = ddog_v1_attributes_key(attrs, i); + const ddog_AttrValue *value = ddog_v1_attributes_value(attrs, i); + zval v; + dd_attr_value_to_zval(value, &v); + zval *target = bytes_out && ddog_v1_value_type(value) == ddog_DDOG_V1_ATTR_BYTES ? bytes_out : out; + zend_hash_str_update(Z_ARR_P(target), dd_CharSlice_ptr(key), key.len, &v); + } +} + +// Adds `arr` under `key` if it's non-empty, else frees it. +static void dd_add_assoc_nonempty(zval *parent, const char *key, zval *arr) { + if (zend_hash_num_elements(Z_ARR_P(arr))) { + add_assoc_zval(parent, key, arr); + } else { + zval_ptr_dtor(arr); + } } -zval dd_serialize_rust_traces_to_zval(ddog_TracesBytes *traces) { +// Introspection reader for the native V1 builder: promoted and chunk-level fields are surfaced +// directly, the unified typed attribute map under "attributes", and links/events natively. +zval dd_serialize_rust_to_zval(ddog_TracerPayloadV1Builder *b) { + // The payload's process tags and OTLP export marker show on each chunk's first span, as on the v0.4 wire. + const ddog_AttrValue *process_tags_value = ddog_v1_attributes_get(ddog_payload_get_attributes(b), DDOG_CHARSLICE_C("_dd.tags.process")); + ddog_CharSlice process_tags = process_tags_value ? ddog_v1_value_str(process_tags_value) : (ddog_CharSlice){0}; + const ddog_AttrValue *otlp_export_value = ddog_v1_attributes_get(ddog_payload_get_attributes(b), DDOG_CHARSLICE_C("_dd.sdk.otlp_export")); + ddog_CharSlice otlp_export = otlp_export_value ? ddog_v1_value_str(otlp_export_value) : (ddog_CharSlice){0}; zval traces_zv; array_init(&traces_zv); - for (size_t i = 0; i < ddog_get_traces_size(traces); i++) { - ddog_TraceBytes *trace = ddog_get_trace(traces, i); + size_t chunk_count; + ddog_ChunkNode *const *chunks = ddog_v1_get_chunks(b, &chunk_count); + for (size_t c = 0; c < chunk_count; c++) { + const ddog_ChunkNode *chunk = chunks[c]; zval trace_zv; array_init(&trace_zv); - for (size_t j = 0; j < ddog_get_trace_size(trace); j++) { - ddog_SpanBytes *span = ddog_get_span(trace, j); + uint64_t tid_high = ddog_v1_get_chunk_trace_id_high(chunk); + uint64_t tid_low = ddog_v1_get_chunk_trace_id_low(chunk); + // Chunk-level fields go on the chunk's local root only, the same span the v0.4 wire picks. + const ddog_SpanNode *root = ddog_v1_get_chunk_root_span(chunk); + int32_t chunk_priority; + bool has_priority = ddog_v1_get_chunk_sampling_priority(chunk, &chunk_priority); + uint32_t chunk_mechanism; + bool has_mechanism = ddog_v1_get_chunk_sampling_mechanism(chunk, &chunk_mechanism); + ddog_CharSlice chunk_origin = ddog_v1_get_chunk_origin(chunk); + + size_t span_count; + ddog_SpanNode *const *spans = ddog_v1_get_spans(chunk, &span_count); + for (size_t j = 0; j < span_count; j++) { + ddog_SpanNode *span = spans[j]; + bool is_root = span == root; zval span_zv; array_init(&span_zv); - add_assoc_str(&span_zv, KEY_TRACE_ID, ddtrace_span_id_as_string(ddog_get_span_trace_id(span))); - add_assoc_str(&span_zv, KEY_SPAN_ID, ddtrace_span_id_as_string(ddog_get_span_id(span))); - - size_t span_parent_id = ddog_get_span_parent_id(span); - if (span_parent_id) { - add_assoc_str(&span_zv, KEY_PARENT_ID, ddtrace_span_id_as_string(span_parent_id)); + add_assoc_str(&span_zv, KEY_TRACE_ID, ddtrace_span_id_as_string(tid_low)); + if (tid_high && is_root) { + add_assoc_str(&span_zv, "trace_id_high", ddtrace_span_id_as_hex_string(tid_high)); } - - add_assoc_long(&span_zv, "start", ddog_get_span_start(span)); - add_assoc_long(&span_zv, "duration", ddog_get_span_duration(span)); - - ddog_CharSlice name = ddog_get_span_name(span); - add_assoc_str(&span_zv, "name", dd_CharSlice_to_zend_string(name)); - - ddog_CharSlice resource = ddog_get_span_resource(span); - add_assoc_str(&span_zv, "resource", dd_CharSlice_to_zend_string(resource)); - - ddog_CharSlice service = ddog_get_span_service(span); - add_assoc_str(&span_zv, "service", dd_CharSlice_to_zend_string(service)); - - ddog_CharSlice type = ddog_get_span_type(span); - add_assoc_str(&span_zv, "type", dd_CharSlice_to_zend_string(type)); - - double error = ddog_get_span_error(span); - if (error != 0) { - add_assoc_long(&span_zv, "error", error); + add_assoc_str(&span_zv, KEY_SPAN_ID, ddtrace_span_id_as_string(ddog_v1_get_span_id(span))); + uint64_t parent_id = ddog_v1_get_span_parent_id(span); + if (parent_id) { + add_assoc_str(&span_zv, KEY_PARENT_ID, ddtrace_span_id_as_string(parent_id)); } - - size_t meta_count = 0; - ddog_CharSlice *meta_keys = ddog_span_meta_get_keys(span, &meta_count); - - if (meta_count > 0) { - zval meta_zv; - array_init(&meta_zv); - - for (size_t k = 0; k < meta_count; k++) { - ddog_CharSlice key = meta_keys[k]; - ddog_CharSlice value = ddog_get_span_meta(span, key); - - zval value_zv; - ZVAL_STR(&value_zv, dd_CharSlice_to_zend_string(value)); - zend_hash_str_update(Z_ARR(meta_zv), key.ptr, key.len, &value_zv); - } - - add_assoc_zval(&span_zv, "meta", &meta_zv); + add_assoc_long(&span_zv, "start", ddog_v1_get_span_start(span)); + add_assoc_long(&span_zv, "duration", ddog_v1_get_span_duration(span)); + add_assoc_str(&span_zv, "name", dd_CharSlice_to_zend_string(ddog_v1_get_span_name(span))); + add_assoc_str(&span_zv, "resource", dd_CharSlice_to_zend_string(ddog_v1_get_span_resource(span))); + add_assoc_str(&span_zv, "service", dd_CharSlice_to_zend_string(ddog_v1_get_span_service(span))); + add_assoc_str(&span_zv, "type", dd_CharSlice_to_zend_string(ddog_v1_get_span_type(span))); + if (ddog_v1_get_span_error(span)) { + add_assoc_long(&span_zv, "error", 1); } - size_t metrics_count = 0; - ddog_CharSlice *metrics_keys = ddog_span_metrics_get_keys(span, &metrics_count); - - if (metrics_count > 0) { - zval metrics_zv; - array_init(&metrics_zv); - - for (size_t k = 0; k < metrics_count; k++) { - ddog_CharSlice key = metrics_keys[k]; - double value; +#define DD_ZVAL_PROMOTED(field, getter) \ + do { \ + ddog_CharSlice _v = getter(span); \ + if (_v.len) add_assoc_str(&span_zv, field, dd_CharSlice_to_zend_string(_v)); \ + } while (0) + DD_ZVAL_PROMOTED("env", ddog_v1_get_span_env); + DD_ZVAL_PROMOTED("version", ddog_v1_get_span_version); + DD_ZVAL_PROMOTED("component", ddog_v1_get_span_component); +#undef DD_ZVAL_PROMOTED + uint32_t span_kind = ddog_v1_get_span_kind(span); + if (span_kind) { + add_assoc_long(&span_zv, "span_kind", span_kind); + } + if (has_priority && is_root) { + add_assoc_long(&span_zv, "sampling_priority", chunk_priority); + } + if (has_mechanism && is_root) { + add_assoc_long(&span_zv, "sampling_mechanism", chunk_mechanism); + } + if (chunk_origin.len && is_root) { + add_assoc_str(&span_zv, "origin", dd_CharSlice_to_zend_string(chunk_origin)); + } - if (ddog_get_span_metrics(span, key, &value)) { - zval value_zv; - ZVAL_DOUBLE(&value_zv, value); - zend_hash_str_update(Z_ARR(metrics_zv), key.ptr, key.len, &value_zv); + // Bytes-typed attributes are v0.4 meta_struct entries; surface them under + // "meta_struct" (as the v0.4 reader did), not mixed into the attribute map. + zval attrs_zv, meta_struct_zv; + array_init(&attrs_zv); + array_init(&meta_struct_zv); + if (j == 0 && process_tags.len) { + add_assoc_str(&attrs_zv, "_dd.tags.process", dd_CharSlice_to_zend_string(process_tags)); + } + if (j == 0 && otlp_export.len) { + add_assoc_str(&attrs_zv, "_dd.sdk.otlp_export", dd_CharSlice_to_zend_string(otlp_export)); + } + dd_attributes_to_zval(ddog_span_get_attributes(span), &attrs_zv, &meta_struct_zv); + dd_add_assoc_nonempty(&span_zv, "attributes", &attrs_zv); + dd_add_assoc_nonempty(&span_zv, "meta_struct", &meta_struct_zv); + + size_t link_count; + ddog_SpanLinkBytes *const *links = ddog_v1_get_links(span, &link_count); + if (link_count > 0) { + zval links_zv; + array_init(&links_zv); + for (size_t l = 0; l < link_count; l++) { + ddog_SpanLinkBytes *link = links[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(link))); + uint64_t link_tid_high = ddog_v1_get_link_trace_id_high(link); + if (link_tid_high) { + add_assoc_str(&link_zv, "trace_id_high", ddtrace_span_id_as_hex_string(link_tid_high)); + } + add_assoc_str(&link_zv, KEY_SPAN_ID, ddtrace_span_id_as_string(ddog_v1_get_link_span_id(link))); + ddog_CharSlice tracestate = ddog_v1_get_link_tracestate(link); + 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(link)); + zval lattrs_zv; + array_init(&lattrs_zv); + dd_attributes_to_zval(ddog_link_get_attributes(link), &lattrs_zv, NULL); + dd_add_assoc_nonempty(&link_zv, "attributes", &lattrs_zv); + zend_hash_next_index_insert_new(Z_ARR(links_zv), &link_zv); } - - add_assoc_zval(&span_zv, "metrics", &metrics_zv); + add_assoc_zval(&span_zv, "span_links", &links_zv); } - size_t meta_struct_count = 0; - ddog_CharSlice *meta_struct_keys = ddog_span_meta_struct_get_keys(span, &meta_struct_count); - - if (meta_struct_count > 0) { - zval meta_struct_zv; - array_init(&meta_struct_zv); - - 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(span, key); - - zval value_zv; - ZVAL_STR(&value_zv, dd_CharSlice_to_zend_string(value)); - zend_hash_str_update(Z_ARR(meta_struct_zv), key.ptr, key.len, &value_zv); + size_t event_count; + ddog_SpanEventBytes *const *events = ddog_v1_get_events(span, &event_count); + if (event_count > 0) { + zval events_zv; + array_init(&events_zv); + for (size_t e = 0; e < event_count; e++) { + ddog_SpanEventBytes *event = events[e]; + zval event_zv; + array_init(&event_zv); + add_assoc_str(&event_zv, "name", dd_CharSlice_to_zend_string(ddog_v1_get_event_name(event))); + add_assoc_long(&event_zv, "time_unix_nano", ddog_v1_get_event_time(event)); + zval eattrs_zv; + array_init(&eattrs_zv); + dd_attributes_to_zval(ddog_event_get_attributes(event), &eattrs_zv, NULL); + dd_add_assoc_nonempty(&event_zv, "attributes", &eattrs_zv); + zend_hash_next_index_insert_new(Z_ARR(events_zv), &event_zv); } - - add_assoc_zval(&span_zv, "meta_struct", &meta_struct_zv); + add_assoc_zval(&span_zv, "span_events", &events_zv); } zend_hash_next_index_insert_new(Z_ARR_P(&trace_zv), &span_zv); - - ddog_span_free_keys_ptr(meta_keys, meta_count); - ddog_span_free_keys_ptr(metrics_keys, metrics_count); - ddog_span_free_keys_ptr(meta_struct_keys, meta_struct_count); } zend_hash_next_index_insert_new(Z_ARR_P(&traces_zv), &trace_zv); @@ -2099,7 +2487,6 @@ zval dd_serialize_rust_traces_to_zval(ddog_TracesBytes *traces) { return traces_zv; } - static zend_string *dd_truncate_uncaught_exception(zend_string *msg) { const char uncaught[] = "Uncaught "; const char *data = ZSTR_VAL(msg); @@ -2130,7 +2517,7 @@ void ddtrace_save_active_error_to_metadata(void) { continue; } - dd_fatal_error_to_meta(ddtrace_property_array(&pspan->property_meta), error); + dd_fatal_error_to_meta(ddtrace_property_array(&pspan->property_attributes), error); } zend_string_release(error.type); zend_string_release(error.msg); @@ -2226,7 +2613,7 @@ void ddtrace_error_cb(DDTRACE_ERROR_CB_PARAMETERS) { continue; } - dd_fatal_error_to_meta(ddtrace_property_array(&pspan->property_meta), error); + dd_fatal_error_to_meta(ddtrace_property_array(&pspan->property_attributes), error); } zend_string_release(error.type); zend_string_release(error.msg); @@ -2265,9 +2652,8 @@ static zend_array *dd_ser_response_committed(ddtrace_user_req_listeners *self, z UNUSED(self, entity); ddtrace_root_span_data *root_span_data = ROOTSPANDATA(span); - zend_array *meta = ddtrace_property_array(&root_span_data->property_meta); struct iter *iter = dd_iterate_arr_arr_headers(headers); - dd_set_entrypoint_root_span_props_end(meta, status, iter, false); + dd_set_entrypoint_root_span_props_end(&root_span_data->span, status, iter, false); efree(iter); return NULL; } diff --git a/tracer/serializer.h b/tracer/serializer.h index 67880c51ff2..1bfcdf3c7e1 100644 --- a/tracer/serializer.h +++ b/tracer/serializer.h @@ -6,10 +6,16 @@ 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); -// Returns false on allocation failure. A filtered span succeeds with a NULL result. -// serialized_span is optional; callers must stop serializing on failure. -bool ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddog_TraceBytes *trace, bool p0_trace, ddog_SpanBytes **serialized_span); -zval dd_serialize_rust_traces_to_zval(ddog_TracesBytes *traces); +// Returns the span's V1 builder node, or NULL when the span was dropped. +ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtrace_serialize_ctx *ctx, bool p0_trace); +zval dd_serialize_rust_to_zval(struct ddog_TracerPayloadV1Builder *builder); + +// String span attribute setters shared with exception_serialize.c. +void dd_span_attr_str(ddog_SpanNode *span, const char *key, const char *val); +void dd_span_attr_zstr(ddog_SpanNode *span, const char *key, zend_string *val); + +// Normalizes a value written through SpanData::$meta (strings) or $metrics (doubles) into `dst`. +void ddtrace_normalize_tag_value(zval *dst, zval *value, bool metric); void ddtrace_save_active_error_to_metadata(void); void ddtrace_set_global_span_properties(ddtrace_span_data *span); diff --git a/tracer/span.c b/tracer/span.c index 7087edf9161..c15ac124ccf 100644 --- a/tracer/span.c +++ b/tracer/span.c @@ -226,28 +226,29 @@ ddtrace_inferred_span_data *ddtrace_open_inferred_span(ddtrace_inferred_proxy_re ZVAL_COPY(&span->property_service, &root->property_service); // Fall back to root service name } - zend_array *meta = ddtrace_property_array(&span->property_meta); - - zend_hash_copy(meta, &DDTRACE_G(root_span_tags_preset), (copy_ctor_func_t)zval_add_ref); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); + zend_hash_copy(attributes, &DDTRACE_G(root_span_tags_preset), (copy_ctor_func_t)zval_add_ref); if (result->http_method) { ZVAL_STR_COPY(&zv, result->http_method); - zend_hash_str_add_new(meta, ZEND_STRL("http.method"), &zv); + zend_hash_str_update(attributes, ZEND_STRL("http.method"), &zv); } if (result->domain && result->path) { ZVAL_STR(&zv, strpprintf(0, "%s%s", ZSTR_VAL(result->domain), ZSTR_VAL(result->path))); - zend_hash_str_add_new(meta, ZEND_STRL("http.url"), &zv); + zend_hash_str_update(attributes, ZEND_STRL("http.url"), &zv); } if (result->stage) { ZVAL_STR_COPY(&zv, result->stage); - zend_hash_str_add_new(meta, ZEND_STRL("stage"), &zv); + zend_hash_str_update(attributes, ZEND_STRL("stage"), &zv); } - 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); + ZVAL_DOUBLE(&zv, 1); + zend_hash_str_update(attributes, ZEND_STRL("_dd.inferred_span"), &zv); + // 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)); free_inferred_proxy_result(result); @@ -548,7 +549,7 @@ ddtrace_span_data *ddtrace_alloc_execute_data_span_ex(zend_ulong index, zend_exe zend_string_release(basename); } - zend_array *meta = ddtrace_property_array(&span->property_meta); + zend_array *meta = ddtrace_property_array(&span->property_attributes); zval location; ZVAL_STR(&location, zend_strpprintf(0, "%s:%d", ZSTR_VAL(EX(func)->op_array.filename), EX(func)->op_array.opcodes->lineno)); zend_hash_str_add_new(meta, ZEND_STRL("closure.declaration"), &location); @@ -828,7 +829,7 @@ static void dd_mark_closed_spans_flushable(ddtrace_span_stack *stack) { // This might get updated later with SpanStacks, but at that point it will be orphan spans. That's intentional. if (!get_global_DD_APM_TRACING_ENABLED()) { // Increment limiter, then force sampling priority if not an asm event - if (!ddtrace_standalone_limiter_allow() && !root_span->asm_event_emitted && !ddtrace_trace_source_is_meta_asm_sourced(ddtrace_property_array(&stack->root_span->property_meta))) { + if (!ddtrace_standalone_limiter_allow() && !root_span->asm_event_emitted && !ddtrace_trace_source_is_meta_asm_sourced(ddtrace_property_array(&stack->root_span->property_attributes))) { zval priority; ZVAL_LONG(&priority, PRIORITY_SAMPLING_AUTO_REJECT); datadog_assign_variable(&root_span->property_sampling_priority, &priority); @@ -1150,8 +1151,7 @@ void ddtrace_drop_span(ddtrace_span_data *span) { dd_drop_span(span, false); } -bool ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, bool fast_shutdown) { - bool success = true; +void ddtrace_serialize_closed_spans(ddtrace_serialize_ctx *ctx, bool fast_shutdown) { if (DDTRACE_G(top_closed_stack)) { ddtrace_span_stack *rootstack = DDTRACE_G(top_closed_stack); DDTRACE_G(top_closed_stack) = NULL; @@ -1165,7 +1165,9 @@ bool ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, bool fast_shutdown stack = next_stack; next_stack = stack->next; } - ddog_TraceBytes *trace = success ? ddog_traces_new_trace(traces) : NULL; + if (ctx) { + ctx->chunk = DD_CHUNK_NONE; // one V1 chunk per V0.4 trace + } bool sampling_decided = false; bool p0_trace = false; @@ -1173,7 +1175,7 @@ bool ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, bool fast_shutdown // Note this ->next: We always splice in new spans at next, so start at next to mostly preserve order ddtrace_span_data *span = stack->closed_ring_flush->next, *end = span; stack->closed_ring_flush = NULL; - if (success && !sampling_decided) { + if (!sampling_decided) { // Detach the ring before sampling, which can trigger destructors or GC. // Snapshot once for this chunk, including attached stacks and inferred spans. // Later chunks reevaluate automatic sampling (existing behavior, unlike other tracers). @@ -1183,11 +1185,7 @@ bool ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, bool fast_shutdown do { ddtrace_span_data *tmp = span; span = tmp->next; - // A soft OOM must reach PHP before any more serialization. - // Keep draining the detached rings so their references are released. - if (success) { - success = ddtrace_serialize_span_to_rust_span(tmp, trace, p0_trace, NULL); - } + ddtrace_serialize_span_to_rust_span(tmp, ctx, p0_trace); #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); @@ -1212,21 +1210,17 @@ bool ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, bool fast_shutdown // Reset closed span counter for limit-refresh, don't touch open spans DDTRACE_G(closed_spans_count) = 0; DDTRACE_G(dropped_spans_count) = 0; - return success; } -bool ddtrace_serialize_closed_spans_with_cycle(ddog_TracesBytes *traces, bool fast_shutdown) { +void ddtrace_serialize_closed_spans_with_cycle(ddtrace_serialize_ctx *ctx, 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)) { - if (!ddtrace_serialize_closed_spans(traces, fast_shutdown)) { - return false; - } + ddtrace_serialize_closed_spans(ctx, fast_shutdown); if (DDTRACE_G(open_spans_count)) { // Also flush possible cycles here, if there are remaining open spans gc_collect_cycles(); } } - return true; } zend_string *ddtrace_span_id_as_string(uint64_t id) { return zend_strpprintf(0, "%" PRIu64, id); } @@ -1268,7 +1262,7 @@ void ddtrace_populate_span_data(ddtrace_span_data *span, zend_string **service, *service = zend_string_init(ZEND_STRL("unnamed-php-service"), 0); } - zval *prop_env = zend_hash_str_find(ddtrace_property_array(&span->property_meta), ZEND_STRL("env")); + zval *prop_env = ddtrace_span_find_tag(span, ZEND_STRL("env")); if (!prop_env) { prop_env = &span->property_env; } @@ -1278,7 +1272,7 @@ void ddtrace_populate_span_data(ddtrace_span_data *span, zend_string **service, *env = NULL; } - zval *prop_version = zend_hash_str_find(ddtrace_property_array(&span->property_meta), ZEND_STRL("version")); + zval *prop_version = ddtrace_span_find_tag(span, ZEND_STRL("version")); if (!prop_version) { prop_version = &span->property_version; } diff --git a/tracer/span.h b/tracer/span.h index 80715a2500b..6569dbcdd3f 100644 --- a/tracer/span.h +++ b/tracer/span.h @@ -16,6 +16,18 @@ #include "otel_context.h" #endif +// V1 payload build context threaded through serialization. `chunk` is DD_CHUNK_NONE until the +// first span of the current stack creates its chunk (ddtrace_serialize_closed_spans resets it per +// stack). Under the Box-per-node model `chunk` is the chunk node pointer, stable across sibling pushes. +#define DD_CHUNK_NONE (NULL) +typedef struct { + struct ddog_TracerPayloadV1Builder *builder; + struct ddog_ChunkNode *chunk; + bool process_tags_set; // the payload's _dd.tags.process / _dd.sdk.otlp_export attributes were decided + bool payload_fields_set; // the payload env/app_version/hostname/git were taken from a root span + bool mark_top_level; // mark `_dd.top_level` on every top-level span (the sidecar sender's V1 needs it) +} ddtrace_serialize_ctx; + #define DDTRACE_DROPPED_SPAN (-1ull) #define DDTRACE_SILENTLY_DROPPED_SPAN (-2ull) @@ -52,8 +64,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; @@ -76,6 +86,12 @@ 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; + zval property_ignore_error; }; } ddtrace_span_properties; @@ -96,6 +112,7 @@ struct ddtrace_span_data { uint32_t active_child_spans; struct ddtrace_span_data *next; struct ddtrace_root_span_data *root; + zend_object *tags_views[2]; // cached $meta / $metrics views (span_tags_view.c) union { ddtrace_span_properties; @@ -150,6 +167,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; @@ -157,6 +175,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) { @@ -177,6 +196,7 @@ struct ddtrace_span_stack { ddtrace_span_properties *active; }; zval property_span_creation_observers; + zval property_attributes; }; }; struct ddtrace_root_span_data *root_span; @@ -275,9 +295,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); -// Return false after an allocation failure; only release remaining detached spans. -bool ddtrace_serialize_closed_spans(ddog_TracesBytes *traces, bool fast_shutdown); -bool ddtrace_serialize_closed_spans_with_cycle(ddog_TracesBytes *traces, bool fast_shutdown); +void ddtrace_serialize_closed_spans(ddtrace_serialize_ctx *ctx, bool fast_shutdown); +void ddtrace_serialize_closed_spans_with_cycle(ddtrace_serialize_ctx *ctx, 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); @@ -295,6 +314,11 @@ static inline bool ddtrace_span_is_entrypoint_root(ddtrace_span_data *span) { return span->std.ce == ddtrace_ce_root_span_data && (!span->stack->parent_stack || !span->stack->parent_stack->parent_stack); } +// Tag lookup in SpanData::$attributes, the single tag store ($meta/$metrics are views onto it). +static inline zval *ddtrace_span_find_tag(ddtrace_span_data *span, const char *key, size_t len) { + return zend_hash_str_find(ddtrace_property_array(&span->property_attributes), key, len); +} + static inline ddtrace_span_data *ddtrace_get_inferred_span(ddtrace_root_span_data *root) { zval *inferred_span_zv = &root->property_inferred_span; if (Z_TYPE_P(inferred_span_zv) == IS_OBJECT && Z_OBJCE_P(inferred_span_zv) == ddtrace_ce_inferred_span_data) { diff --git a/tracer/span_stats.c b/tracer/span_stats.c index 2e0750a40ef..c90bedbf0a6 100644 --- a/tracer/span_stats.c +++ b/tracer/span_stats.c @@ -39,12 +39,15 @@ static const size_t GRPC_META_KEY_LENS[] = { // agent, which is larger and must be scanned in full. #define DDTRACE_MAX_PEER_TAGS 32 +static zval *dd_pre_find_tag(const ddtrace_span_precomputed *pre, const char *key, size_t len) { + return zend_hash_str_find(pre->attributes, key, len); +} + void ddtrace_precompute_span(ddtrace_span_data *span, ddtrace_span_precomputed *pre) { - pre->meta = ddtrace_property_array(&span->property_meta); - pre->metrics = ddtrace_property_array(&span->property_metrics); + pre->attributes = ddtrace_property_array(&span->property_attributes); - // Service: meta["service.name"] override then span property, then apply DD_SERVICE_MAPPING. - zval *service_name_meta = pre->meta ? zend_hash_str_find(pre->meta, ZEND_STRL("service.name")) : NULL; + // Service: "service.name" tag override then span property, then apply DD_SERVICE_MAPPING. + zval *service_name_meta = dd_pre_find_tag(pre, ZEND_STRL("service.name")); pre->service_from_meta = (service_name_meta != NULL); pre->service = NULL; if (service_name_meta) { @@ -64,8 +67,8 @@ void ddtrace_precompute_span(ddtrace_span_data *span, ddtrace_span_precomputed * } } - // Name: meta["operation.name"] (lowercased!) or span property. - zval *operation_name = pre->meta ? zend_hash_str_find(pre->meta, ZEND_STRL("operation.name")) : NULL; + // Name: "operation.name" tag (lowercased!) or span property. + zval *operation_name = dd_pre_find_tag(pre, ZEND_STRL("operation.name")); pre->name = NULL; if (operation_name && Z_TYPE_P(operation_name) == IS_STRING) { pre->name = zend_string_tolower(Z_STR_P(operation_name)); @@ -79,8 +82,8 @@ void ddtrace_precompute_span(ddtrace_span_data *span, ddtrace_span_precomputed * pre->name_from_meta = false; } - // Resource: meta["resource.name"] or span property, falling back to name. - zval *resource_name = pre->meta ? zend_hash_str_find(pre->meta, ZEND_STRL("resource.name")) : NULL; + // Resource: "resource.name" tag or span property, falling back to name. + zval *resource_name = dd_pre_find_tag(pre, ZEND_STRL("resource.name")); pre->resource_from_meta = (resource_name != NULL); pre->resource = NULL; if (resource_name) { @@ -97,8 +100,8 @@ void ddtrace_precompute_span(ddtrace_span_data *span, ddtrace_span_precomputed * pre->resource = zend_string_copy(pre->name); } - // Type: meta["span.type"] or span property. - zval *span_type = pre->meta ? zend_hash_str_find(pre->meta, ZEND_STRL("span.type")) : NULL; + // Type: "span.type" tag or span property. + zval *span_type = dd_pre_find_tag(pre, ZEND_STRL("span.type")); pre->type_from_meta = (span_type != NULL); pre->type = NULL; zval *prop_type = span_type ? span_type : &span->property_type; @@ -107,55 +110,42 @@ 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: property first, then the "env" tag fallback (matching serializer.c promotion). Without the + // fallback, DD_TAGS "env" (DD_ENV unset) would bucket stats by empty env vs the trace's. 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); + 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); - } + } + if (!pre->env) { + zval *env_meta = dd_pre_find_tag(pre, ZEND_STRL("env")); + if (env_meta && Z_TYPE_P(env_meta) == IS_STRING) { + pre->env = zend_string_copy(Z_STR_P(env_meta)); } } - // Version: prefer deprecated meta["version"] (with a warning), else the span's own property. + // Version: span property first, then the "version" tag fallback (same rationale). 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); + 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); - } + } + if (!pre->version) { + zval *version_meta = dd_pre_find_tag(pre, ZEND_STRL("version")); + if (version_meta && Z_TYPE_P(version_meta) == IS_STRING) { + pre->version = zend_string_copy(Z_STR_P(version_meta)); } } @@ -164,25 +154,36 @@ void ddtrace_precompute_span(ddtrace_span_data *span, ddtrace_span_precomputed * pre->has_exception = Z_TYPE_P(exception_zv) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception_zv), zend_ce_throwable); - zval *error_ignored_zv = pre->meta ? zend_hash_str_find(pre->meta, ZEND_STRL("error.ignored")) : NULL; - pre->ignore_error = error_ignored_zv && zend_is_true(error_ignored_zv); + // $ignoreError, or the deprecated "error.ignored" tag, which can only turn it on. The tag is folded into + // the property and dropped, so it is never emitted and should_track_error's ancestor walk still sees it. + zval *error_ignored = zend_hash_str_find(pre->attributes, ZEND_STRL("error.ignored")); + if (error_ignored) { + if (zend_is_true(error_ignored)) { + zval *ignore_error = &span->property_ignore_error; + ZVAL_DEREF(ignore_error); + zval_ptr_dtor(ignore_error); + ZVAL_TRUE(ignore_error); + } + zend_hash_str_del(pre->attributes, ZEND_STRL("error.ignored")); + } + pre->ignore_error = zend_is_true(&span->property_ignore_error); // Stats eligibility fields — fetched once here to avoid duplicate lookups in the two // call sites (ddtrace_span_concentrator_feed_cb and ddtrace_feed_span_to_concentrator). pre->has_top_level = ddtrace_span_is_entrypoint_root(span) || (span->std.ce == ddtrace_ce_root_span_data && ROOTSPANDATA(&span->std)->parent_id == 0) || (span->parent && !zend_is_identical(&span->property_service, &span->parent->property_service)); - zval *is_measured = pre->metrics ? zend_hash_str_find(pre->metrics, ZEND_STRL("_dd.measured")) : NULL; + zval *is_measured = dd_pre_find_tag(pre, ZEND_STRL("_dd.measured")); pre->is_measured = is_measured && zval_get_double(is_measured) != 0.0; pre->is_partial_snapshot = false; - zval *span_kind_zv = pre->meta ? zend_hash_str_find(pre->meta, ZEND_STRL("span.kind")) : NULL; - pre->span_kind = (span_kind_zv && Z_TYPE_P(span_kind_zv) == IS_STRING) ? Z_STR_P(span_kind_zv) : NULL; + zval *span_kind_zv = dd_pre_find_tag(pre, ZEND_STRL("span.kind")); + // Owned copy: the serializer deletes the "span.kind" tag up front, so pre must not borrow it. + pre->span_kind = (span_kind_zv && Z_TYPE_P(span_kind_zv) == IS_STRING) ? zend_string_copy(Z_STR_P(span_kind_zv)) : NULL; } bool dd_compute_span_is_error(const ddtrace_span_precomputed *pre) { if (pre->ignore_error) { return false; } - if (pre->meta && (zend_hash_str_find(pre->meta, ZEND_STRL("error.message")) != NULL || - zend_hash_str_find(pre->meta, ZEND_STRL("error.type")) != NULL)) { + if (dd_pre_find_tag(pre, ZEND_STRL("error.message")) || dd_pre_find_tag(pre, ZEND_STRL("error.type"))) { return true; } return pre->has_exception; @@ -207,6 +208,9 @@ void ddtrace_free_span_precomputed(ddtrace_span_precomputed *pre) { if (pre->version) { zend_string_release(pre->version); } + if (pre->span_kind) { + zend_string_release(pre->span_kind); + } } typedef struct { @@ -222,9 +226,6 @@ typedef struct { static ddog_PhpSpanStats ddtrace_build_span_stats_core( ddtrace_span_data *span, const ddtrace_span_precomputed *pre, ddog_CharSlice span_kind_slice ) { - zend_array *meta = pre->meta; - zend_array *metrics = pre->metrics; - ddog_CharSlice service_slice = dd_zend_string_to_CharSlice(pre->service); ddog_CharSlice name_slice = dd_zend_string_to_CharSlice(pre->name); ddog_CharSlice resource_slice = dd_zend_string_to_CharSlice(pre->resource); @@ -236,22 +237,22 @@ static ddog_PhpSpanStats ddtrace_build_span_stats_core( // HTTP and gRPC fields only appear on service entry spans, which are always stats-eligible. // They are fetched here (after the eligibility check) rather than in ddtrace_precompute_span. - zval *http_status_str_zv = meta ? zend_hash_str_find(meta, ZEND_STRL("http.status_code")) : NULL; + zval *http_status_str_zv = dd_pre_find_tag(pre, ZEND_STRL("http.status_code")); ddog_CharSlice http_status_str_slice = http_status_str_zv && Z_TYPE_P(http_status_str_zv) == IS_STRING ? dd_zend_string_to_CharSlice(Z_STR_P(http_status_str_zv)) : DDOG_CHARSLICE_C(""); - zval *http_method_zv = meta ? zend_hash_str_find(meta, ZEND_STRL("http.method")) : NULL; + zval *http_method_zv = dd_pre_find_tag(pre, ZEND_STRL("http.method")); ddog_CharSlice http_method_slice = http_method_zv && Z_TYPE_P(http_method_zv) == IS_STRING ? dd_zend_string_to_CharSlice(Z_STR_P(http_method_zv)) : DDOG_CHARSLICE_C(""); - zval *http_endpoint_zv = meta ? zend_hash_str_find(meta, ZEND_STRL("http.endpoint")) : NULL; + zval *http_endpoint_zv = dd_pre_find_tag(pre, ZEND_STRL("http.endpoint")); ddog_CharSlice http_endpoint_slice = http_endpoint_zv && Z_TYPE_P(http_endpoint_zv) == IS_STRING ? dd_zend_string_to_CharSlice(Z_STR_P(http_endpoint_zv)) : DDOG_CHARSLICE_C(""); - zval *http_route_zv = meta ? zend_hash_str_find(meta, ZEND_STRL("http.route")) : NULL; + zval *http_route_zv = dd_pre_find_tag(pre, ZEND_STRL("http.route")); ddog_CharSlice http_route_slice = http_route_zv && Z_TYPE_P(http_route_zv) == IS_STRING ? dd_zend_string_to_CharSlice(Z_STR_P(http_route_zv)) : DDOG_CHARSLICE_C(""); @@ -262,7 +263,7 @@ static ddog_PhpSpanStats ddtrace_build_span_stats_core( ? dd_zend_string_to_CharSlice(Z_STR_P(origin_zv)) : DDOG_CHARSLICE_C(""); - zval *service_source_zv = meta ? zend_hash_str_find(meta, ZEND_STRL("_dd.svc_src")) : NULL; + zval *service_source_zv = dd_pre_find_tag(pre, ZEND_STRL("_dd.svc_src")); ddog_CharSlice service_source_slice = service_source_zv && Z_TYPE_P(service_source_zv) == IS_STRING ? dd_zend_string_to_CharSlice(Z_STR_P(service_source_zv)) : DDOG_CHARSLICE_C(""); @@ -272,17 +273,12 @@ static ddog_PhpSpanStats ddtrace_build_span_stats_core( for (int i = 0; i < ddog_PHP_GRPC_KEY_COUNT; i++) { grpc_meta[i] = DDOG_CHARSLICE_C(""); grpc_metrics[i] = NAN; - if (meta) { - zval *gm = zend_hash_str_find(meta, GRPC_META_KEYS[i], GRPC_META_KEY_LENS[i]); - if (gm && Z_TYPE_P(gm) == IS_STRING) { - grpc_meta[i] = dd_zend_string_to_CharSlice(Z_STR_P(gm)); - } - } - if (metrics) { - zval *gv = zend_hash_str_find(metrics, GRPC_META_KEYS[i], GRPC_META_KEY_LENS[i]); - if (gv) { - grpc_metrics[i] = zval_get_double(gv); - } + // A string tag lands in the meta slot, a number in the metrics slot. + zval *ga = zend_hash_str_find(pre->attributes, GRPC_META_KEYS[i], GRPC_META_KEY_LENS[i]); + if (ga && Z_TYPE_P(ga) == IS_STRING) { + grpc_meta[i] = dd_zend_string_to_CharSlice(Z_STR_P(ga)); + } else if (ga) { + grpc_metrics[i] = zval_get_double(ga); } } @@ -344,7 +340,7 @@ static ddog_OwnedShmSpanInput *ddtrace_span_concentrator_feed_cb(const ddog_Span if (peer_tag_keys_count > 0 && peer_tag_keys) { for (size_t i = 0; i < peer_tag_keys_count && actual_peer_tags < DDTRACE_MAX_PEER_TAGS; i++) { const ddog_CharSlice *k = &peer_tag_keys[i]; - zval *val = zend_hash_str_find(pre->meta, k->ptr, k->len); + zval *val = dd_pre_find_tag(pre, k->ptr, k->len); if (val && Z_TYPE_P(val) == IS_STRING) { peer_tags[actual_peer_tags].key = *k; peer_tags[actual_peer_tags].value = dd_zend_string_to_CharSlice(Z_STR_P(val)); @@ -355,7 +351,7 @@ static ddog_OwnedShmSpanInput *ddtrace_span_concentrator_feed_cb(const ddog_Span } else if (!pre->span_kind || !zend_string_equals_literal(pre->span_kind, "server")) { // internal or no span.kind: use _dd.base_service only if it marks a service override static const ddog_CharSlice BASE_SERVICE_KEY = DDOG_CHARSLICE_C_BARE("_dd.base_service"); - zval *base_svc_zv = zend_hash_str_find(pre->meta, ZEND_STRL("_dd.base_service")); + zval *base_svc_zv = dd_pre_find_tag(pre, ZEND_STRL("_dd.base_service")); if (base_svc_zv && Z_TYPE_P(base_svc_zv) == IS_STRING) { peer_tags[0].key = BASE_SERVICE_KEY; peer_tags[0].value = dd_zend_string_to_CharSlice(Z_STR_P(base_svc_zv)); @@ -379,6 +375,11 @@ void ddtrace_feed_span_to_concentrator(ddtrace_span_data *span, const ddtrace_sp version_zstr = Z_STR_P(root_version_zv); } else { version_zstr = get_DD_VERSION(); + // When DD_VERSION is unset, DD_TAGS "version" lives only in meta (deleted during promotion), + // so fall back to pre->version to keep stats bucketed by the trace's version. + if (ZSTR_LEN(version_zstr) == 0 && pre->version) { + version_zstr = pre->version; + } } ddog_CharSlice version_slice = dd_zend_string_to_CharSlice(version_zstr); // Use the process-level DD_SERVICE as the concentrator key so all spans from this PHP diff --git a/tracer/span_stats.h b/tracer/span_stats.h index b33e068672c..f1fa07e17aa 100644 --- a/tracer/span_stats.h +++ b/tracer/span_stats.h @@ -13,12 +13,10 @@ * Owned strings (service, name, resource, type) are zend_string* that must be released with * ddtrace_free_span_precomputed() when no longer needed. NULL means the field is absent. * - * meta and metrics are borrowed pointers (no ownership transfer). - * zval* fields below are also borrowed from meta/metrics and share the same lifetime. + * attributes is a borrowed pointer (no ownership transfer); all tag lookups read it. */ typedef struct { - zend_array *meta; - zend_array *metrics; + zend_array *attributes; /* Owned strings — release with ddtrace_free_span_precomputed() */ zend_string *service; /* mapped service name */ @@ -27,20 +25,16 @@ typedef struct { zend_string *type; /* resolved span type */ zend_string *env; /* from span->property_env; NULL when empty */ zend_string *version; /* from span->root->property_version; NULL when empty */ - zend_string *span_kind; /* meta["span.kind"], NULL if absent or not a string */ + zend_string *span_kind; /* owned copy of meta["span.kind"], NULL if absent or not a string */ /* True when the value came from a meta override (serializer must delete that meta key) */ - bool service_from_meta; + bool service_from_meta; /* from_meta: an attributes or meta override */ bool name_from_meta; 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; + bool ignore_error; /* SpanData::$ignoreError, or the deprecated meta["error.ignored"] */ /* Stats-specific fields — precomputed to avoid repeated lookups across two call sites. */ bool has_top_level; /* ddtrace_span_is_entrypoint_root() */ @@ -59,7 +53,7 @@ void ddtrace_free_span_precomputed(ddtrace_span_precomputed *pre); /** * Compute whether a span should be marked as an error. - * Checks meta["error.message"], meta["error.type"], pre->has_exception, and meta["error.ignored"]. + * Checks the error.message/error.type tags, pre->has_exception, and pre->ignore_error. * Accurate for both sampled and non-sampled spans (HTTP errors are in PHP meta via * dd_ser_response_committed before the span is closed). */ diff --git a/tracer/span_tags_view.c b/tracer/span_tags_view.c new file mode 100644 index 00000000000..9596d74eba2 --- /dev/null +++ b/tracer/span_tags_view.c @@ -0,0 +1,520 @@ +#include "span_tags_view.h" + +#include +#include +#include +#if PHP_VERSION_ID < 70200 +#include +#define zend_ce_countable spl_ce_Countable +#endif + +#include "ddtrace.h" +#include "serializer.h" + +zend_class_entry *ddtrace_ce_span_tags_view; +static zend_object_handlers dd_span_tags_view_handlers; + +typedef struct { + ddtrace_span_data *span; // weak; NULL once the span is freed + bool metrics; + zend_object std; +} dd_span_tags_view; + +#if PHP_VERSION_ID < 80000 +#define DD_OBJ_ARG zval *object +#define DD_OBJ Z_OBJ_P(object) +#define DD_MEMBER_ARG zval *member +#define DD_MEMBER (Z_TYPE_P(member) == IS_STRING ? Z_STR_P(member) : ZSTR_EMPTY_ALLOC()) +#else +#define DD_OBJ_ARG zend_object *object +#define DD_OBJ object +#define DD_MEMBER_ARG zend_string *member +#define DD_MEMBER member +#endif + +static inline dd_span_tags_view *dd_tags_view_from_obj(zend_object *obj) { + return (dd_span_tags_view *)((char *)obj - XtOffsetOf(dd_span_tags_view, std)); +} + +// 0 for $meta, 1 for $metrics, -1 for any other property. +static inline int dd_tags_bucket_of(zend_string *name) { + if (zend_string_equals_literal(name, "meta")) { + return 0; + } + if (zend_string_equals_literal(name, "metrics")) { + return 1; + } + return -1; +} + +// Numbers are metrics; any other non-null value is meta. +static inline bool dd_tags_in_bucket(zval *val, bool metrics) { + ZVAL_DEREF(val); + if (Z_TYPE_P(val) == IS_LONG || Z_TYPE_P(val) == IS_DOUBLE) { + return metrics; + } + return !metrics && Z_TYPE_P(val) > IS_NULL; +} + +static inline zend_array *dd_tags_attrs_read(ddtrace_span_data *span) { + if (!span) { + return NULL; + } + zval *attrs = &span->property_attributes; + ZVAL_DEREF(attrs); + return Z_TYPE_P(attrs) == IS_ARRAY ? Z_ARR_P(attrs) : NULL; +} + +static void dd_tags_snapshot(zend_array *attrs, bool metrics, zval *rv) { + array_init(rv); + if (!attrs) { + return; + } + zend_ulong h; + zend_string *key; + zval *val; + ZEND_HASH_FOREACH_KEY_VAL_IND(attrs, h, key, val) { + if (dd_tags_in_bucket(val, metrics)) { + ZVAL_DEREF(val); + Z_TRY_ADDREF_P(val); + if (key) { + zend_hash_add_new(Z_ARR_P(rv), key, val); + } else { + zend_hash_index_add_new(Z_ARR_P(rv), h, val); + } + } + } ZEND_HASH_FOREACH_END(); +} + +static zend_long dd_tags_count(zend_array *attrs, bool metrics) { + zend_long count = 0; + if (attrs) { + zval *val; + ZEND_HASH_FOREACH_VAL_IND(attrs, val) { + count += dd_tags_in_bucket(val, metrics); + } ZEND_HASH_FOREACH_END(); + } + return count; +} + +// Replaces the bucket's entries of $attributes with `values` (normalized), or just clears it. +// Keys kept by `values` are updated in place so that they keep their position. +static void dd_tags_replace_bucket(ddtrace_span_data *span, bool metrics, zend_array *values) { + zend_array *attrs = ddtrace_property_array(&span->property_attributes); + zend_ulong h; + zend_string *key; + zval *val; + ZEND_HASH_FOREACH_KEY_VAL_IND(attrs, h, key, val) { + if (dd_tags_in_bucket(val, metrics) + && !(values && (key ? zend_hash_exists(values, key) : zend_hash_index_exists(values, h)))) { + if (key) { + zend_hash_del(attrs, key); + } else { + zend_hash_index_del(attrs, h); + } + } + } ZEND_HASH_FOREACH_END(); + + if (values) { + ZEND_HASH_FOREACH_KEY_VAL_IND(values, h, key, val) { + zval normalized; + ddtrace_normalize_tag_value(&normalized, val, metrics); + if (key) { + zend_hash_update(attrs, key, &normalized); + } else { + zend_hash_index_update(attrs, h, &normalized); + } + } ZEND_HASH_FOREACH_END(); + } +} + +static zval *dd_tags_find(dd_span_tags_view *view, zval *offset, zend_string **key_out) { + ZVAL_DEREF(offset); + zend_string *key = zval_get_string(offset); + zend_array *attrs = dd_tags_attrs_read(view->span); + zval *val = attrs && !EG(exception) ? zend_symtable_find(attrs, key) : NULL; + if (val && !dd_tags_in_bucket(val, view->metrics)) { + val = NULL; + } + if (key_out) { + *key_out = key; + } else { + zend_string_release(key); + } + return val; +} + +static zval *dd_tags_view_read(dd_span_tags_view *view, zval *offset, int type, zval *rv) { + if (!offset) { + zend_throw_error(NULL, "Cannot read an appended element of SpanData::$%s", view->metrics ? "metrics" : "meta"); + return &EG(uninitialized_zval); + } + zend_string *key; + zval *val = dd_tags_find(view, offset, &key); + if (val) { + ZVAL_COPY_DEREF(rv, val); + } else { + if (type == BP_VAR_R && !EG(exception)) { +#if PHP_VERSION_ID >= 80000 + zend_error(E_WARNING, "Undefined array key \"%s\"", ZSTR_VAL(key)); +#else + zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(key)); +#endif + } + ZVAL_NULL(rv); + } + zend_string_release(key); + return rv; +} + +static void dd_tags_view_write(dd_span_tags_view *view, zval *offset, zval *value) { + if (!offset) { + zend_throw_error(NULL, "Cannot append to SpanData::$%s", view->metrics ? "metrics" : "meta"); + return; + } + if (!view->span) { + return; + } + ZVAL_DEREF(offset); + zend_string *key = zval_get_string(offset); + if (!EG(exception)) { + zval normalized; + ddtrace_normalize_tag_value(&normalized, value, view->metrics); + zend_symtable_update(ddtrace_property_array(&view->span->property_attributes), key, &normalized); + } + zend_string_release(key); +} + +static bool dd_tags_view_has(dd_span_tags_view *view, zval *offset, int check_empty) { + zval *val = dd_tags_find(view, offset, NULL); + return val && (check_empty ? zend_is_true(val) : 1); +} + +static void dd_tags_view_unset(dd_span_tags_view *view, zval *offset) { + zend_string *key; + if (dd_tags_find(view, offset, &key)) { + zend_symtable_del(ddtrace_property_array(&view->span->property_attributes), key); + } + zend_string_release(key); +} + +static zend_object *dd_tags_view_create(zend_class_entry *ce) { + dd_span_tags_view *view = ecalloc(1, sizeof(*view) + zend_object_properties_size(ce)); + zend_object_std_init(&view->std, ce); + object_properties_init(&view->std, ce); + view->std.handlers = &dd_span_tags_view_handlers; + return &view->std; +} + +// The span keeps the cached view alive; the view only points back weakly. +static zend_object *dd_span_tags_view_get(ddtrace_span_data *span, int bucket) { + zend_object *obj = span->tags_views[bucket]; + if (!obj) { + obj = dd_tags_view_create(ddtrace_ce_span_tags_view); + dd_span_tags_view *view = dd_tags_view_from_obj(obj); + view->span = span; + view->metrics = bucket == 1; + span->tags_views[bucket] = obj; + } + GC_ADDREF(obj); + return obj; +} + +void ddtrace_span_tags_views_release(ddtrace_span_data *span) { + for (int i = 0; i < 2; ++i) { + zend_object *obj = span->tags_views[i]; + if (obj) { + dd_tags_view_from_obj(obj)->span = NULL; + span->tags_views[i] = NULL; + OBJ_RELEASE(obj); + } + } +} + +/* View object handlers */ + +static zval *dd_tags_view_read_dimension(DD_OBJ_ARG, zval *offset, int type, zval *rv) { + return dd_tags_view_read(dd_tags_view_from_obj(DD_OBJ), offset, type, rv); +} + +static void dd_tags_view_write_dimension(DD_OBJ_ARG, zval *offset, zval *value) { + dd_tags_view_write(dd_tags_view_from_obj(DD_OBJ), offset, value); +} + +static int dd_tags_view_has_dimension(DD_OBJ_ARG, zval *offset, int check_empty) { + return dd_tags_view_has(dd_tags_view_from_obj(DD_OBJ), offset, check_empty); +} + +static void dd_tags_view_unset_dimension(DD_OBJ_ARG, zval *offset) { + dd_tags_view_unset(dd_tags_view_from_obj(DD_OBJ), offset); +} + +#if PHP_VERSION_ID >= 80100 +static zend_result dd_tags_view_count_elements(DD_OBJ_ARG, zend_long *count) { +#else +static int dd_tags_view_count_elements(DD_OBJ_ARG, zend_long *count) { +#endif + dd_span_tags_view *view = dd_tags_view_from_obj(DD_OBJ); + *count = dd_tags_count(dd_tags_attrs_read(view->span), view->metrics); + return SUCCESS; +} + +static zend_array *dd_tags_view_snapshot_ht(zend_object *obj) { + dd_span_tags_view *view = dd_tags_view_from_obj(obj); + zval snapshot; + dd_tags_snapshot(dd_tags_attrs_read(view->span), view->metrics, &snapshot); + return Z_ARR(snapshot); +} + +#if PHP_VERSION_ID >= 70400 +static zend_array *dd_tags_view_get_properties_for(DD_OBJ_ARG, zend_prop_purpose purpose) { + (void)purpose; + return dd_tags_view_snapshot_ht(DD_OBJ); +} +#else +static HashTable *dd_tags_view_get_debug_info(zval *object, int *is_temp) { + *is_temp = 1; + return dd_tags_view_snapshot_ht(Z_OBJ_P(object)); +} +#endif + +/* View methods (ArrayAccess, Countable, IteratorAggregate) */ + +#define DD_THIS_VIEW dd_tags_view_from_obj(Z_OBJ_P(ZEND_THIS)) + +PHP_METHOD(DDTrace_SpanTagsView, offsetGet) { + zval *offset; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &offset) == FAILURE) { + return; + } + dd_tags_view_read(DD_THIS_VIEW, offset, BP_VAR_R, return_value); +} + +PHP_METHOD(DDTrace_SpanTagsView, offsetSet) { + zval *offset, *value; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &offset, &value) == FAILURE) { + return; + } + dd_tags_view_write(DD_THIS_VIEW, Z_TYPE_P(offset) == IS_NULL ? NULL : offset, value); +} + +PHP_METHOD(DDTrace_SpanTagsView, offsetExists) { + zval *offset; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &offset) == FAILURE) { + return; + } + RETURN_BOOL(dd_tags_view_has(DD_THIS_VIEW, offset, 0)); +} + +PHP_METHOD(DDTrace_SpanTagsView, offsetUnset) { + zval *offset; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &offset) == FAILURE) { + return; + } + dd_tags_view_unset(DD_THIS_VIEW, offset); +} + +PHP_METHOD(DDTrace_SpanTagsView, count) { + if (zend_parse_parameters_none() == FAILURE) { + return; + } + dd_span_tags_view *view = DD_THIS_VIEW; + RETURN_LONG(dd_tags_count(dd_tags_attrs_read(view->span), view->metrics)); +} + +PHP_METHOD(DDTrace_SpanTagsView, getIterator) { + if (zend_parse_parameters_none() == FAILURE) { + return; + } + zval snapshot; + ZVAL_ARR(&snapshot, dd_tags_view_snapshot_ht(Z_OBJ_P(ZEND_THIS))); + object_init_ex(return_value, spl_ce_ArrayIterator); +#if PHP_VERSION_ID >= 80000 + zend_call_method_with_1_params(Z_OBJ_P(return_value), spl_ce_ArrayIterator, &spl_ce_ArrayIterator->constructor, "__construct", NULL, &snapshot); +#else + zend_call_method_with_1_params(return_value, spl_ce_ArrayIterator, &spl_ce_ArrayIterator->constructor, "__construct", NULL, &snapshot); +#endif + zval_ptr_dtor(&snapshot); +} + +#if PHP_VERSION_ID >= 80100 +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_dd_tags_view_offsetGet, 0, 1, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0) +ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_dd_tags_view_offsetSet, 0, 2, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) +ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_dd_tags_view_offsetExists, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0) +ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_dd_tags_view_offsetUnset, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0) +ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_dd_tags_view_count, 0, 0, IS_LONG, 0) +ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_dd_tags_view_getIterator, 0, 0, Iterator, 0) +ZEND_END_ARG_INFO() +#else +ZEND_BEGIN_ARG_INFO_EX(arginfo_dd_tags_view_offsetGet, 0, 0, 1) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_dd_tags_view_offsetSet, 0, 0, 2) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() +#define arginfo_dd_tags_view_offsetExists arginfo_dd_tags_view_offsetGet +#define arginfo_dd_tags_view_offsetUnset arginfo_dd_tags_view_offsetGet +ZEND_BEGIN_ARG_INFO_EX(arginfo_dd_tags_view_count, 0, 0, 0) +ZEND_END_ARG_INFO() +#define arginfo_dd_tags_view_getIterator arginfo_dd_tags_view_count +#endif + +static const zend_function_entry dd_span_tags_view_methods[] = { + PHP_ME(DDTrace_SpanTagsView, offsetGet, arginfo_dd_tags_view_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(DDTrace_SpanTagsView, offsetSet, arginfo_dd_tags_view_offsetSet, ZEND_ACC_PUBLIC) + PHP_ME(DDTrace_SpanTagsView, offsetExists, arginfo_dd_tags_view_offsetExists, ZEND_ACC_PUBLIC) + PHP_ME(DDTrace_SpanTagsView, offsetUnset, arginfo_dd_tags_view_offsetUnset, ZEND_ACC_PUBLIC) + PHP_ME(DDTrace_SpanTagsView, count, arginfo_dd_tags_view_count, ZEND_ACC_PUBLIC) + PHP_ME(DDTrace_SpanTagsView, getIterator, arginfo_dd_tags_view_getIterator, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +void ddtrace_register_span_tags_view(void) { + zend_class_entry ce; + INIT_NS_CLASS_ENTRY(ce, "DDTrace", "SpanTagsView", dd_span_tags_view_methods); + ddtrace_ce_span_tags_view = zend_register_internal_class(&ce); + ddtrace_ce_span_tags_view->ce_flags |= ZEND_ACC_FINAL; + ddtrace_ce_span_tags_view->create_object = dd_tags_view_create; + zend_class_implements(ddtrace_ce_span_tags_view, 3, zend_ce_arrayaccess, zend_ce_countable, zend_ce_aggregate); + + memcpy(&dd_span_tags_view_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + dd_span_tags_view_handlers.offset = XtOffsetOf(dd_span_tags_view, std); + dd_span_tags_view_handlers.clone_obj = NULL; + dd_span_tags_view_handlers.read_dimension = dd_tags_view_read_dimension; + dd_span_tags_view_handlers.write_dimension = dd_tags_view_write_dimension; + dd_span_tags_view_handlers.has_dimension = dd_tags_view_has_dimension; + dd_span_tags_view_handlers.unset_dimension = dd_tags_view_unset_dimension; + dd_span_tags_view_handlers.count_elements = dd_tags_view_count_elements; +#if PHP_VERSION_ID >= 70400 + dd_span_tags_view_handlers.get_properties_for = dd_tags_view_get_properties_for; +#else + dd_span_tags_view_handlers.get_debug_info = dd_tags_view_get_debug_info; +#endif +} + +/* SpanData property handlers for $meta / $metrics */ + +// Read contexts get an array snapshot (so array functions keep working); write contexts the view. +static zval *dd_span_read_property(DD_OBJ_ARG, DD_MEMBER_ARG, int type, void **cache_slot, zval *rv) { + int bucket = dd_tags_bucket_of(DD_MEMBER); + if (bucket < 0) { + return std_object_handlers.read_property(object, member, type, cache_slot, rv); + } + ddtrace_span_data *span = OBJ_SPANDATA(DD_OBJ); + if (type == BP_VAR_R || type == BP_VAR_IS) { + dd_tags_snapshot(dd_tags_attrs_read(span), bucket, rv); + } else { + ZVAL_OBJ(rv, dd_span_tags_view_get(span, bucket)); + } + return rv; +} + +// NULL keeps the engine off the property slot (and its runtime cache) for $meta/$metrics. +static zval *dd_span_get_property_ptr_ptr(DD_OBJ_ARG, DD_MEMBER_ARG, int type, void **cache_slot) { + if (dd_tags_bucket_of(DD_MEMBER) >= 0) { + return NULL; + } + return std_object_handlers.get_property_ptr_ptr(object, member, type, cache_slot); +} + +static int dd_span_has_property(DD_OBJ_ARG, DD_MEMBER_ARG, int has_set_exists, void **cache_slot) { + int bucket = dd_tags_bucket_of(DD_MEMBER); + if (bucket < 0) { + return std_object_handlers.has_property(object, member, has_set_exists, cache_slot); + } + if (has_set_exists == 1) { // empty() + return dd_tags_count(dd_tags_attrs_read(OBJ_SPANDATA(DD_OBJ)), bucket) > 0; + } + return 1; +} + +static void dd_span_unset_property(DD_OBJ_ARG, DD_MEMBER_ARG, void **cache_slot) { + int bucket = dd_tags_bucket_of(DD_MEMBER); + if (bucket < 0) { + std_object_handlers.unset_property(object, member, cache_slot); + return; + } + dd_tags_replace_bucket(OBJ_SPANDATA(DD_OBJ), bucket, NULL); +} + +bool ddtrace_span_tags_view_write_property(zend_object *obj, zend_string *name, zval *value) { + int bucket = dd_tags_bucket_of(name); + if (bucket < 0) { + return false; + } + ddtrace_span_data *span = OBJ_SPANDATA(obj); + ZVAL_DEREF(value); + if (Z_TYPE_P(value) == IS_ARRAY) { + dd_tags_replace_bucket(span, bucket, Z_ARR_P(value)); + } else if (Z_TYPE_P(value) == IS_NULL) { + dd_tags_replace_bucket(span, bucket, NULL); + } else if (Z_TYPE_P(value) == IS_OBJECT && Z_OBJCE_P(value) == ddtrace_ce_span_tags_view) { + zval snapshot; + ZVAL_ARR(&snapshot, dd_tags_view_snapshot_ht(Z_OBJ_P(value))); + dd_tags_replace_bucket(span, bucket, Z_ARR(snapshot)); + zval_ptr_dtor(&snapshot); + } else { + zend_type_error("Cannot assign %s to property %s::$%s of type array", zend_zval_type_name(value), ZSTR_VAL(obj->ce->name), ZSTR_VAL(name)); + } + return true; +} + +// Properties table with $meta/$metrics replaced by their snapshots. +static zend_array *dd_span_properties_with_tags(zend_object *obj, zend_array *props) { + zend_array *ht = zend_new_array(zend_hash_num_elements(props)); + zend_string *key; + zend_ulong h; + zval *val; + ZEND_HASH_FOREACH_KEY_VAL_IND(props, h, key, val) { + int bucket = key ? dd_tags_bucket_of(key) : -1; + zval copy; + if (bucket >= 0) { + dd_tags_snapshot(dd_tags_attrs_read(OBJ_SPANDATA(obj)), bucket, ©); + } else { + ZVAL_COPY(©, val); + } + if (key) { + zend_hash_add_new(ht, key, ©); + } else { + zend_hash_index_add_new(ht, h, ©); + } + } ZEND_HASH_FOREACH_END(); + return ht; +} + +#if PHP_VERSION_ID >= 70400 +static zend_array *dd_span_get_properties_for(DD_OBJ_ARG, zend_prop_purpose purpose) { + if (purpose == ZEND_PROP_PURPOSE_SERIALIZE) { + return zend_std_get_properties_for(object, purpose); + } + return dd_span_properties_with_tags(DD_OBJ, std_object_handlers.get_properties(object)); +} +#else +static HashTable *dd_span_get_debug_info(zval *object, int *is_temp) { + *is_temp = 1; + return dd_span_properties_with_tags(Z_OBJ_P(object), std_object_handlers.get_properties(object)); +} +#endif + +void ddtrace_span_tags_view_install(zend_object_handlers *handlers) { + handlers->read_property = dd_span_read_property; + handlers->get_property_ptr_ptr = dd_span_get_property_ptr_ptr; + handlers->has_property = dd_span_has_property; + handlers->unset_property = dd_span_unset_property; +#if PHP_VERSION_ID >= 70400 + handlers->get_properties_for = dd_span_get_properties_for; +#else + handlers->get_debug_info = dd_span_get_debug_info; +#endif +} diff --git a/tracer/span_tags_view.h b/tracer/span_tags_view.h new file mode 100644 index 00000000000..1b4e9e0982f --- /dev/null +++ b/tracer/span_tags_view.h @@ -0,0 +1,19 @@ +#ifndef DD_SPAN_TAGS_VIEW_H +#define DD_SPAN_TAGS_VIEW_H + +#include +#include + +#include "span.h" + +// SpanData::$meta / $metrics are views onto SpanData::$attributes: meta holds the non-numeric +// entries, metrics the numeric ones. +extern zend_class_entry *ddtrace_ce_span_tags_view; + +void ddtrace_register_span_tags_view(void); +void ddtrace_span_tags_view_install(zend_object_handlers *handlers); +void ddtrace_span_tags_views_release(ddtrace_span_data *span); +// Handles assignments to $meta/$metrics; false for any other property. +bool ddtrace_span_tags_view_write_property(zend_object *obj, zend_string *name, zval *value); + +#endif // DD_SPAN_TAGS_VIEW_H diff --git a/tracer/trace_filter.c b/tracer/trace_filter.c index 4479a2da530..fc6178a825f 100644 --- a/tracer/trace_filter.c +++ b/tracer/trace_filter.c @@ -44,28 +44,30 @@ static const char *ddtrace_root_tag_value(const void *ctx, const char *key, uint CHECK_PROP("resource", property_resource) #undef CHECK_PROP - // Meta hash: string tags. - zend_array *meta = ddtrace_property_array(&root->property_meta); - if (meta) { - zval *val = zend_hash_str_find(meta, key, key_len); - if (val && Z_TYPE_P(val) == IS_STRING) { - *out_len = Z_STRLEN_P(val); - return Z_STRVAL_P(val); + // Attributes: string tags as-is, numbers as stringified floats, bools as on the v0.4 wire. + zval *attr = zend_hash_str_find(ddtrace_property_array(&root->property_attributes), key, key_len); + if (attr) { + ZVAL_DEREF(attr); + switch (Z_TYPE_P(attr)) { + case IS_STRING: + *out_len = Z_STRLEN_P(attr); + return Z_STRVAL_P(attr); + case IS_TRUE: + *out_len = 4; + return "true"; + case IS_FALSE: + *out_len = 5; + return "false"; + case IS_LONG: + case IS_DOUBLE: { + ZEND_TLS char attr_buf[32]; + int len = snprintf(attr_buf, sizeof(attr_buf), "%g", zval_get_double(attr)); + *out_len = (uintptr_t)(len > 0 ? len : 0); + return attr_buf; + } } } - // Metrics hash: numeric tags returned as stringified float. - zend_array *metrics = ddtrace_property_array(&root->property_metrics); - if (metrics) { - zval *val = zend_hash_str_find(metrics, key, key_len); - if (val) { - ZEND_TLS char metric_buf[32]; - double d = zval_get_double(val); - int len = snprintf(metric_buf, sizeof(metric_buf), "%g", d); - *out_len = (uintptr_t)(len > 0 ? len : 0); - return metric_buf; - } - } // Meta struct: key-presence only (value is unrepresentable as a string). zend_array *meta_struct = ddtrace_property_array(&root->property_meta_struct); diff --git a/tracer/trace_source.c b/tracer/trace_source.c index 4873ae766ff..994c1104909 100644 --- a/tracer/trace_source.c +++ b/tracer/trace_source.c @@ -56,7 +56,7 @@ void ddtrace_trace_source_set_asm_source() { return; } - zend_array *meta = ddtrace_property_array(&root_span->property_meta);; + zend_array *meta = ddtrace_property_array(&root_span->property_attributes); if (!meta) { return; } @@ -66,7 +66,7 @@ void ddtrace_trace_source_set_asm_source() { ddtrace_trace_source_add_propagated_tag(encoded); } -bool ddtrace_trace_source_is_meta_asm_sourced(zend_array *meta) { +bool ddtrace_trace_source_is_meta_asm_sourced(zend_array *meta) { if (!meta) { return false; } diff --git a/tracer/tracer_tag_propagation/tracer_tag_propagation.c b/tracer/tracer_tag_propagation/tracer_tag_propagation.c index 732d43bf248..a9897ace4ef 100644 --- a/tracer/tracer_tag_propagation/tracer_tag_propagation.c +++ b/tracer/tracer_tag_propagation/tracer_tag_propagation.c @@ -11,11 +11,15 @@ ZEND_EXTERN_MODULE_GLOBALS(datadog); -void ddtrace_clean_tracer_tags(zend_array *root_meta, zend_array *propagated_tags) { +void ddtrace_drop_propagated_tags(zend_array *tags, zend_array *propagated_tags) { zend_string *tagname; ZEND_HASH_FOREACH_STR_KEY(propagated_tags, tagname) { - zend_hash_del(root_meta, tagname); + zend_hash_del(tags, tagname); } ZEND_HASH_FOREACH_END(); +} + +void ddtrace_clean_tracer_tags(zend_array *root_meta, zend_array *propagated_tags) { + ddtrace_drop_propagated_tags(root_meta, propagated_tags); zend_hash_clean(propagated_tags); } @@ -90,16 +94,18 @@ static zend_array *ddtrace_get_propagated() { return propagated; } +// Propagated tag values live in the root span's $attributes (the preset before a root exists). static zend_array *ddtrace_get_root_meta() { zend_array *root_meta = &DDTRACE_G(root_span_tags_preset); ddtrace_root_span_data *root_span = DDTRACE_G(active_stack)->root_span; if (root_span) { - root_meta = ddtrace_property_array(&root_span->property_meta); + root_meta = ddtrace_property_array(&root_span->property_attributes); } return root_meta; } + zval *ddtrace_propagated_tags_get_tag(const char *tag) { if (!tag) { return NULL; diff --git a/tracer/tracer_tag_propagation/tracer_tag_propagation.h b/tracer/tracer_tag_propagation/tracer_tag_propagation.h index c8dd0ebe4bc..e93ab976da2 100644 --- a/tracer/tracer_tag_propagation/tracer_tag_propagation.h +++ b/tracer/tracer_tag_propagation/tracer_tag_propagation.h @@ -5,6 +5,8 @@ #include +// Deletes the values of `propagated_tags` from `tags`, keeping the propagated list. +void ddtrace_drop_propagated_tags(zend_array *tags, zend_array *propagated_tags); void ddtrace_clean_tracer_tags(zend_array *root_meta, zend_array *propagated_tags); void ddtrace_add_tracer_tags_from_header(zend_string *headerstr, zend_array *root_meta, zend_array *propagated_tags); void ddtrace_add_tracer_tags_from_array(zend_array *array, zend_array *root_meta, zend_array *propagated_tags); diff --git a/tracer/tracer_telemetry.c b/tracer/tracer_telemetry.c index 774d892bbb7..66848b21c4b 100644 --- a/tracer/tracer_telemetry.c +++ b/tracer/tracer_telemetry.c @@ -202,13 +202,19 @@ void ddtrace_telemetry_notify_integration_version(const char *name, size_t name_ } void ddtrace_telemetry_inc_spans_created(ddtrace_span_data *span) { + // Prefer the $span->component property; the tag mirror only happens later at serialization, + // so fall back to the "component" tag for spans (e.g. userland integrations) that set it directly. + zval *component_prop = &span->property_component; + ZVAL_DEREF(component_prop); zval *component = NULL; - if (Z_TYPE(span->property_meta) == IS_ARRAY) { - component = zend_hash_str_find(Z_ARRVAL(span->property_meta), ZEND_STRL("component")); + if (!(Z_TYPE_P(component_prop) == IS_STRING && Z_STRLEN_P(component_prop) > 0)) { + component = ddtrace_span_find_tag(span, 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 24f9654a5c701d199310ddb7fe31f56d25622c23 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Thu, 1 Oct 2026 18:01:48 +0200 Subject: [PATCH 02/11] refactor(integrations): write span tags through the attributes store Use typed SpanData::$attributes and the promoted env/version/component/span_kind properties instead of $meta/$metrics string conversions in the userland integrations and the OpenTelemetry bridge. Drop the userland App Analytics plumbing (addTraceAnalyticsIfEnabled, requiresExplicitTraceAnalyticsEnabling, markForTraceAnalytics and the per-integration candidates). TraceAnalyticsProcessor::normalizeAnalyticsValue and Tag::ANALYTICS_KEY are now deprecated no-ops; the serializer still maps an analytics.event tag to _dd1.sr.eausr. --- .../Integrations/AMQP/AMQPIntegration.php | 2 +- .../CakePHP/CakePHPIntegration.php | 13 +------ .../CakePHP/V2/CakePHPIntegrationLoader.php | 4 +- .../CakePHP/V3/CakePHPIntegrationLoader.php | 4 +- .../CodeIgniter/V2/CodeIgniterIntegration.php | 9 ++--- .../Integrations/Curl/CurlIntegration.php | 3 +- .../DatabaseIntegrationHelper.php | 4 +- .../Integrations/Drupal/DrupalIntegration.php | 12 +----- .../V1/ElasticSearchIntegration.php | 29 ++++++-------- .../V8/ElasticSearchIntegration.php | 1 - .../Integrations/Exec/ExecIntegration.php | 19 +++++----- .../Frankenphp/FrankenphpIntegration.php | 13 +------ .../GoogleSpannerIntegration.php | 8 ---- .../Integrations/Guzzle/GuzzleIntegration.php | 4 +- src/DDTrace/Integrations/Integration.php | 38 ++++++------------- .../Laminas/LaminasIntegration.php | 16 ++++---- .../Laravel/LaravelIntegration.php | 31 +++++---------- .../Integrations/Lumen/LumenIntegration.php | 20 +++------- .../Magento/MagentoIntegration.php | 2 +- .../Memcache/MemcacheIntegration.php | 18 --------- .../Memcached/MemcachedIntegration.php | 26 ------------- .../Integrations/Mongo/MongoIntegration.php | 16 ++------ .../MongoDB/MongoDBIntegration.php | 1 - .../Integrations/Mysqli/MysqliIntegration.php | 9 +---- .../Integrations/Nette/NetteIntegration.php | 15 ++------ .../Integrations/PDO/PDOIntegration.php | 5 +-- .../PHPRedis/PHPRedisIntegration.php | 6 +-- .../Integrations/Predis/PredisIntegration.php | 2 - .../Integrations/Psr18/Psr18Integration.php | 2 +- .../Ratchet/RatchetIntegration.php | 28 ++++++-------- .../Roadrunner/RoadrunnerIntegration.php | 11 +----- .../Integrations/SQLSRV/SQLSRVIntegration.php | 4 +- .../Integrations/Slim/SlimIntegration.php | 7 ++-- .../Integrations/Swoole/SwooleIntegration.php | 28 +++++--------- .../Symfony/SymfonyIntegration.php | 26 ++++--------- .../WordPress/WordPressIntegration.php | 8 ---- .../WordPress/WordPressIntegrationLoader.php | 7 ++-- .../Integrations/Yii/YiiIntegration.php | 13 +------ .../ZendFramework/V1/TraceRequest.php | 12 +++--- .../ZendFrameworkIntegration.php | 17 ++------- src/DDTrace/OpenTelemetry/Context.php | 6 ++- src/DDTrace/OpenTelemetry/Convention.php | 2 +- src/DDTrace/OpenTelemetry/Span.php | 19 ++++------ .../Processing/TraceAnalyticsProcessor.php | 24 ++++-------- src/DDTrace/Span.php | 23 +++++------ src/api/GlobalTracer.php | 3 ++ src/api/Tag.php | 1 + src/ddtrace_php_api.stubs.php | 9 +++-- 48 files changed, 182 insertions(+), 398 deletions(-) diff --git a/src/DDTrace/Integrations/AMQP/AMQPIntegration.php b/src/DDTrace/Integrations/AMQP/AMQPIntegration.php index 4a6c8a95616..7e5861d9fd0 100644 --- a/src/DDTrace/Integrations/AMQP/AMQPIntegration.php +++ b/src/DDTrace/Integrations/AMQP/AMQPIntegration.php @@ -491,7 +491,7 @@ public static function setGenericTags( $span->meta[Tag::SPAN_KIND] = $spanKind; $span->type = 'queue'; $span->service = 'amqp'; - $span->meta['_dd.svc_src'] = AMQPIntegration::NAME; + $span->attributes['_dd.svc_src'] = AMQPIntegration::NAME; $span->meta[Tag::COMPONENT] = self::NAME; $span->meta[Tag::MQ_SYSTEM] = self::SYSTEM; diff --git a/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php b/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php index 9adf7691128..4ea47027515 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) { @@ -45,7 +36,7 @@ public static function init(): int : 'cake_console'; } else { $rootSpan->name = 'cakephp.request'; - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; } $rootSpan->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; }; @@ -60,7 +51,7 @@ public static function init(): int self::$setStatusCodeFn = static function ($This, $scope, $args, $retval) { $rootSpan = \DDTrace\root_span(); if ($rootSpan) { - $rootSpan->meta[Tag::HTTP_STATUS_CODE] = $retval; + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = $retval; } }; diff --git a/src/DDTrace/Integrations/CakePHP/V2/CakePHPIntegrationLoader.php b/src/DDTrace/Integrations/CakePHP/V2/CakePHPIntegrationLoader.php index 0d6b6744aea..732030ae3ee 100644 --- a/src/DDTrace/Integrations/CakePHP/V2/CakePHPIntegrationLoader.php +++ b/src/DDTrace/Integrations/CakePHP/V2/CakePHPIntegrationLoader.php @@ -43,8 +43,8 @@ function (SpanData $span, array $args) { $_SERVER['REQUEST_METHOD'] . ' ' . $this->name . 'Controller@' . $request->params['action']; } - if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { - $rootSpan->meta[Tag::HTTP_URL] = Router::url($request->here, true) + if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { + $rootSpan->attributes[Tag::HTTP_URL] = Router::url($request->here, true) . Normalizer::sanitizedQueryString(); } $rootSpan->meta['cakephp.route.controller'] = $request->params['controller']; diff --git a/src/DDTrace/Integrations/CakePHP/V3/CakePHPIntegrationLoader.php b/src/DDTrace/Integrations/CakePHP/V3/CakePHPIntegrationLoader.php index 77a681baf4f..acb36e83ae1 100644 --- a/src/DDTrace/Integrations/CakePHP/V3/CakePHPIntegrationLoader.php +++ b/src/DDTrace/Integrations/CakePHP/V3/CakePHPIntegrationLoader.php @@ -40,8 +40,8 @@ function (SpanData $span) { $_SERVER['REQUEST_METHOD'] . ' ' . $this->name . 'Controller@' . $request->getParam('action'); } - if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { - $rootSpan->meta[Tag::HTTP_URL] = Router::url($request->getAttribute('here'), true) + if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { + $rootSpan->attributes[Tag::HTTP_URL] = Router::url($request->getAttribute('here'), true) . Normalizer::sanitizedQueryString(); } $rootSpan->meta['cakephp.route.controller'] = $request->getParam('controller'); diff --git a/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php b/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php index 15c8f684f67..c92a90f1370 100644 --- a/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php +++ b/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php @@ -39,11 +39,10 @@ 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; - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; $rootSpan->meta[Tag::COMPONENT] = self::NAME; $controller = $router->fetch_class(); @@ -64,8 +63,8 @@ function (SpanData $span) use ($rootSpan, $method, $service) { if (property_exists($this, 'load') && $this->load && \method_exists($this->load, 'helper')) { $this->load->helper('url'); - if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { - $rootSpan->meta[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize(base_url(uri_string())) + if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { + $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize(base_url(uri_string())) . Normalizer::sanitizedQueryString(); } $rootSpan->meta['app.endpoint'] = "{$class}::{$method}"; @@ -97,7 +96,7 @@ function (SpanData $span, $args, $retval, $ex) use ($rootSpan, $service) { if ($this->load && \method_exists($this->load, 'helper')) { $this->load->helper('url'); - $rootSpan->meta[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize(base_url(uri_string())) + $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize(base_url(uri_string())) . Normalizer::sanitizedQueryString(); $rootSpan->meta['app.endpoint'] = "{$class}::_remap"; } diff --git a/src/DDTrace/Integrations/Curl/CurlIntegration.php b/src/DDTrace/Integrations/Curl/CurlIntegration.php index fbd11c2aca4..bbc2e3b2402 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; } @@ -308,7 +307,7 @@ public static function set_curl_attributes($span, $info) { if (\dd_trace_env_config("DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN")) { $span->service = Urls::hostnameForTag($sanitizedUrl); - $span->meta['_dd.svc_src'] = 'opt.http_client_split_by_domain'; + $span->attributes['_dd.svc_src'] = 'opt.http_client_split_by_domain'; } $span->resource = $normalizedPath; diff --git a/src/DDTrace/Integrations/DatabaseIntegrationHelper.php b/src/DDTrace/Integrations/DatabaseIntegrationHelper.php index 2362f063f65..dad67703467 100644 --- a/src/DDTrace/Integrations/DatabaseIntegrationHelper.php +++ b/src/DDTrace/Integrations/DatabaseIntegrationHelper.php @@ -98,7 +98,7 @@ public static function propagateViaSqlComments( $tags["dddbs"] = $databaseService; } - $env = $rootSpan->meta["env"] ?? $rootSpan->env ?? ""; + $env = $rootSpan->attributes["env"] ?? $rootSpan->meta["env"] ?? $rootSpan->env ?? ""; if ($env == "") { $env = ini_get("datadog.env"); } @@ -126,7 +126,7 @@ public static function propagateViaSqlComments( $tags["ddps"] = $service; } - $version = $rootSpan->meta["version"] ?? $rootSpan->version ?? ""; + $version = $rootSpan->attributes["version"] ?? $rootSpan->meta["version"] ?? $rootSpan->version ?? ""; if ($version == "") { $version = ini_get("datadog.version"); } diff --git a/src/DDTrace/Integrations/Drupal/DrupalIntegration.php b/src/DDTrace/Integrations/Drupal/DrupalIntegration.php index 76b57861428..cd4f1423fa1 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'))); @@ -45,14 +37,14 @@ public static function init(): int $rootSpan->name = 'drupal.request'; $rootSpan->service = $service; Integration::tagFrameworkServiceSource($rootSpan, 'drupal'); - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; $rootSpan->meta[Tag::COMPONENT] = self::NAME; $span->name = 'drupal.kernel.handle'; $span->type = Type::WEB_SERVLET; $span->service = $service; Integration::tagFrameworkServiceSource($span, 'drupal'); - $span->meta[Tag::SPAN_KIND] = 'server'; + $span->attributes[Tag::SPAN_KIND] = 'server'; $span->meta[Tag::COMPONENT] = self::NAME; } ] 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/Exec/ExecIntegration.php b/src/DDTrace/Integrations/Exec/ExecIntegration.php index 17630f1801e..6d94c164129 100644 --- a/src/DDTrace/Integrations/Exec/ExecIntegration.php +++ b/src/DDTrace/Integrations/Exec/ExecIntegration.php @@ -60,7 +60,7 @@ static function (HookData $hook) { if ($hook->exception) { $span->exception = $hook->exception; } elseif (!is_resource($hook->returned)) { - $span->meta[Tag::ERROR_MSG] = 'popen() did not return a resource'; + $span->attributes[Tag::ERROR_MSG] = 'popen() did not return a resource'; } else { register_stream($hook->returned, $span); } @@ -121,7 +121,7 @@ static function (HookData $hook) { if ($hook->exception) { $span->exception = $hook->exception; } elseif (!is_resource($hook->returned)) { - $span->meta[Tag::ERROR_MSG] = 'proc_open() did not return a resource'; + $span->attributes[Tag::ERROR_MSG] = 'proc_open() did not return a resource'; } else { proc_assoc_span($hook->returned, $span); } @@ -155,10 +155,10 @@ static function (HookData $hook) { } if ($hook->returned['signaled']) { - $span->meta[Tag::ERROR_MSG] = 'The process was terminated by a signal'; - $span->meta[Tag::EXEC_EXIT_CODE] = $hook->returned['termsig']; + $span->attributes[Tag::ERROR_MSG] = 'The process was terminated by a signal'; + $span->attributes[Tag::EXEC_EXIT_CODE] = (string)$hook->returned['termsig']; } else { - $span->meta[Tag::EXEC_EXIT_CODE] = $hook->returned['exitcode']; + $span->attributes[Tag::EXEC_EXIT_CODE] = (string)$hook->returned['exitcode']; } self::finishSpanRestoreStack($span); @@ -195,8 +195,9 @@ static function (HookData $hook) { return; } - if ($hook->returned === -1 && isset($span->meta[Tag::EXEC_EXIT_CODE])) { - $hook->overrideReturnValue($span->meta[Tag::EXEC_EXIT_CODE]); + $exitCode = $span->attributes[Tag::EXEC_EXIT_CODE] ?? null; + if ($hook->returned === -1 && $exitCode !== null) { + $hook->overrideReturnValue((int)$exitCode); } } ); @@ -259,13 +260,13 @@ private static function postHookShell($variant) if ($hook->exception) { $span->exception = $hook->exception; } elseif ($hook->returned === false) { - $span->meta[Tag::ERROR_MSG] = "$variant() returned false"; + $span->attributes[Tag::ERROR_MSG] = "$variant() returned false"; } elseif ( !empty($retCodeArg) && isset($hook->args[$retCodeArg]) && $hook->args[$retCodeArg] !== null ) { - $span->meta[Tag::EXEC_EXIT_CODE] = $hook->args[$retCodeArg]; + $span->attributes[Tag::EXEC_EXIT_CODE] = (string)$hook->args[$retCodeArg]; } self::finishSpanRestoreStack($span); diff --git a/src/DDTrace/Integrations/Frankenphp/FrankenphpIntegration.php b/src/DDTrace/Integrations/Frankenphp/FrankenphpIntegration.php index 74fb17c2184..17753f0d515 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); @@ -54,9 +46,8 @@ static function (HookData $hook) use (&$blockingException, &$rootSpan) { Integration::tagFrameworkServiceSource($rootSpan, self::NAME); $rootSpan->type = Type::WEB_SERVLET; $rootSpan->meta[Tag::COMPONENT] = self::NAME; - $rootSpan->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_SERVER; - unset($rootSpan->meta["closure.declaration"]); - self::addTraceAnalyticsIfEnabled($rootSpan); + $rootSpan->attributes[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_SERVER; + unset($rootSpan->attributes["closure.declaration"]); 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/Guzzle/GuzzleIntegration.php b/src/DDTrace/Integrations/Guzzle/GuzzleIntegration.php index d69a3b0c65f..4e26f9f1695 100644 --- a/src/DDTrace/Integrations/Guzzle/GuzzleIntegration.php +++ b/src/DDTrace/Integrations/Guzzle/GuzzleIntegration.php @@ -174,7 +174,7 @@ public static function addRequestInfo(SpanData $span, $request) if (\dd_trace_env_config("DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN")) { $span->service = Urls::hostnameForTag($url); - $span->meta['_dd.svc_src'] = 'opt.http_client_split_by_domain'; + $span->attributes['_dd.svc_src'] = 'opt.http_client_split_by_domain'; } $span->meta[Tag::HTTP_METHOD] = $request->getMethod(); @@ -189,7 +189,7 @@ public static function addRequestInfo(SpanData $span, $request) } if (\dd_trace_env_config("DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN")) { $span->service = Urls::hostnameForTag($url); - $span->meta['_dd.svc_src'] = 'opt.http_client_split_by_domain'; + $span->attributes['_dd.svc_src'] = 'opt.http_client_split_by_domain'; } $span->meta[Tag::HTTP_METHOD] = $request->getMethod(); diff --git a/src/DDTrace/Integrations/Integration.php b/src/DDTrace/Integrations/Integration.php index 2fe53f82c21..61c06f79469 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. */ @@ -94,22 +75,27 @@ public static function handleInternalSpanServiceName(SpanData $span, string $fal $service = $mapping[$service]; } $span->service = $service; - unset($span->meta['_dd.svc_src']); + unset($span->attributes['_dd.svc_src']); if ($flatServiceNames) { - if ($rootSpan && isset($rootSpan->meta['_dd.svc_src'])) { - $span->meta['_dd.svc_src'] = $rootSpan->meta['_dd.svc_src']; + if ($rootSpan && isset($rootSpan->attributes['_dd.svc_src'])) { + $span->attributes['_dd.svc_src'] = $rootSpan->attributes['_dd.svc_src']; } } else { - $span->meta['_dd.svc_src'] = $fallbackName; + $span->attributes['_dd.svc_src'] = $fallbackName; } } + public static function hasTag(SpanData $span, $key) + { + return array_key_exists($key, $span->attributes); + } + public static function tagFrameworkServiceSource(SpanData $span, $integrationName) { if (\dd_trace_env_config('DD_SERVICE')) { - unset($span->meta['_dd.svc_src']); + unset($span->attributes['_dd.svc_src']); } else { - $span->meta['_dd.svc_src'] = $integrationName; + $span->attributes['_dd.svc_src'] = $integrationName; } } @@ -121,7 +107,7 @@ public static function setComponentMetadata(SpanData $span, $component, $service { if (!\dd_trace_env_config('DD_SERVICE')) { $span->service = $service ?? $component; - $span->meta['_dd.svc_src'] = $component; + $span->attributes['_dd.svc_src'] = $component; } $span->meta[Tag::COMPONENT] = $component; } diff --git a/src/DDTrace/Integrations/Laminas/LaminasIntegration.php b/src/DDTrace/Integrations/Laminas/LaminasIntegration.php index 8f72520fd4d..d148f4af9d9 100644 --- a/src/DDTrace/Integrations/Laminas/LaminasIntegration.php +++ b/src/DDTrace/Integrations/Laminas/LaminasIntegration.php @@ -177,7 +177,7 @@ static function (SpanData $span) { $rootSpan->name = 'laminas.request'; $rootSpan->service = \ddtrace_config_app_name('laminas'); Integration::tagFrameworkServiceSource($rootSpan, 'laminas'); - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; $rootSpan->meta[Tag::COMPONENT] = self::NAME; } ); @@ -238,9 +238,9 @@ function (SpanData $span, $args, $retval) { $request = $args[0]; $rootSpan = root_span(); - $rootSpan->meta[Tag::HTTP_METHOD] = $request->getMethod(); + $rootSpan->attributes[Tag::HTTP_METHOD] = $request->getMethod(); $rootSpan->meta[Tag::HTTP_VERSION] = $request->getVersion(); - $rootSpan->meta[Tag::HTTP_URL] = Normalizer::urlSanitize($request->getUriString()); + $rootSpan->attributes[Tag::HTTP_URL] = Normalizer::urlSanitize($request->getUriString()); $routeMatch = $retval; if (is_null($routeMatch)) { @@ -342,7 +342,7 @@ static function ($This, $scope, $args) { $rootSpan = root_span(); if ($rootSpan !== null) { $statusCode = $args[0]; - $rootSpan->meta[Tag::HTTP_STATUS_CODE] = "$statusCode"; + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = "$statusCode"; } } ); @@ -396,8 +396,8 @@ static function (SpanData $span, $args) { $method = $request->getMethod(); $rootSpan = root_span(); - $rootSpan->meta[Tag::HTTP_METHOD] = $method; - $rootSpan->meta[Tag::HTTP_URL] = Normalizer::urlSanitize($request->getUriString()); + $rootSpan->attributes[Tag::HTTP_METHOD] = $method; + $rootSpan->attributes[Tag::HTTP_URL] = Normalizer::urlSanitize($request->getUriString()); } ); @@ -589,7 +589,7 @@ static function (HookData $hook) { $detail = $args[1] ?? null; $activeSpan = active_span(); if ($detail instanceof \Throwable || $detail instanceof \Exception) { - if ($activeSpan !== null && !isset($activeSpan->meta[Tag::ERROR_TYPE])) { + if ($activeSpan !== null && !Integration::hasTag($activeSpan, Tag::ERROR_TYPE)) { $activeSpan->exception = $detail; } } elseif (is_string($detail)) { @@ -601,7 +601,7 @@ static function (HookData $hook) { ObjectKVStore::put($hook->instance, 'backtrace', $backtrace); - if ($activeSpan !== null && !isset($activeSpan->meta[Tag::ERROR_TYPE])) { + if ($activeSpan !== null && !Integration::hasTag($activeSpan, Tag::ERROR_TYPE)) { $activeSpan->meta[Tag::ERROR_TYPE] = 'ApiProblem'; $activeSpan->meta[Tag::ERROR_MSG] = $detail; $activeSpan->meta[Tag::ERROR_STACK] = $backtrace; diff --git a/src/DDTrace/Integrations/Laravel/LaravelIntegration.php b/src/DDTrace/Integrations/Laravel/LaravelIntegration.php index bfbf6815a34..aaa393a9937 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] : ''; @@ -69,13 +61,12 @@ 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(); + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = $response->getStatusCode(); } $rootSpan->service = self::getServiceName(); Integration::tagFrameworkServiceSource($rootSpan, LaravelIntegration::NAME); - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; $rootSpan->meta[Tag::COMPONENT] = self::NAME; } ); @@ -119,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")) { @@ -135,8 +125,8 @@ static function ($This, $scope, $args, $route) { $rootSpan->meta['laravel.route.name'] = $routeName; $rootSpan->meta['laravel.route.action'] = $route->getActionName(); - if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { - $rootSpan->meta[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($request->fullUrl()); + if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { + $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($request->fullUrl()); } if (\method_exists($route, 'uri')) { $rootSpan->meta[Tag::HTTP_ROUTE] = $route->uri(); @@ -147,8 +137,8 @@ static function ($This, $scope, $args, $route) { \datadog\appsec\push_addresses(["server.request.path_params" => $parameters]); } } - $rootSpan->meta[Tag::HTTP_METHOD] = $request->method(); - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::HTTP_METHOD] = $request->method(); + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; if (!\DDTrace\are_endpoints_collected()) { $routeCollection = $This->getRoutes(); @@ -186,8 +176,7 @@ function ($This, $scope, $args) { return; } - $ignoreError = isset($rootSpan->meta['error.ignored']) && $rootSpan->meta['error.ignored']; - if (isset($This->exception) && $This->getStatusCode() >= 500 && !$ignoreError) { + if (isset($This->exception) && $This->getStatusCode() >= 500 && !$rootSpan->ignoreError) { $rootSpan->exception = $This->exception; } } @@ -314,7 +303,7 @@ static function () { $rootSpan->name = 'laravel.artisan'; $rootSpan->resource = !empty($_SERVER['argv'][1]) ? 'artisan ' . $_SERVER['argv'][1] : 'artisan'; - unset($rootSpan->meta[Tag::SPAN_KIND]); + unset($rootSpan->attributes[Tag::SPAN_KIND]); $rootSpan->meta[Tag::COMPONENT] = self::NAME; } ); @@ -360,10 +349,10 @@ static function ($This, $scope, $args) { if ($args[0] && $exceptionHandler->shouldReport($args[0])) { $rootSpan->exception = $args[0]; - $rootSpan->meta['error.ignored'] = 0; + $rootSpan->ignoreError = false; } elseif ($args[0] && !$exceptionHandler->shouldReport($args[0])) { $rootSpan->exception = $args[0]; - $rootSpan->meta['error.ignored'] = 1; + $rootSpan->ignoreError = true; } }, 'recurse' => true, diff --git a/src/DDTrace/Integrations/Lumen/LumenIntegration.php b/src/DDTrace/Integrations/Lumen/LumenIntegration.php index aff0751cb2a..0e8045defa7 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 */ @@ -33,7 +25,7 @@ static function () { $rootSpan = \DDTrace\root_span(); if ($rootSpan !== null) { $rootSpan->meta[Tag::COMPONENT] = self::NAME; - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; } } ); @@ -49,11 +41,10 @@ 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()); + if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { + $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($request->getUri()); } - $rootSpan->meta[Tag::HTTP_METHOD] = $request->getMethod(); + $rootSpan->attributes[Tag::HTTP_METHOD] = $request->getMethod(); return false; } @@ -95,7 +86,8 @@ static function (SpanData $span, $args) { && !\dd_trace_env_config("DD_TRACE_URL_AS_RESOURCE_NAMES_ENABLED") && \dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING") ) { - $rootSpan->resource = $rootSpan->meta[Tag::HTTP_METHOD] . ' ' . $resourceName; + $method = $rootSpan->attributes[Tag::HTTP_METHOD] ?? $rootSpan->meta[Tag::HTTP_METHOD]; + $rootSpan->resource = $method . ' ' . $resourceName; } }, ] diff --git a/src/DDTrace/Integrations/Magento/MagentoIntegration.php b/src/DDTrace/Integrations/Magento/MagentoIntegration.php index a797e72ad49..89073e57ccd 100644 --- a/src/DDTrace/Integrations/Magento/MagentoIntegration.php +++ b/src/DDTrace/Integrations/Magento/MagentoIntegration.php @@ -171,7 +171,7 @@ function (SpanData $span) use (&$fullPageCached) { $rootSpan = root_span(); MagentoIntegration::setCommonSpanInfo($rootSpan, 'magento.request', $resource); - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; if (!$fullPageCached && isset($rootSpan->meta['magento.pathinfo'])) { $rootSpan->resource = $rootSpan->meta['magento.pathinfo']; diff --git a/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php b/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php index 2fd20dcd8dd..0706a599099 100644 --- a/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php +++ b/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php @@ -99,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)); @@ -159,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..389d2ad808c 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; }); @@ -425,7 +418,7 @@ public static function setConnectionInfo(SpanData $span, $mysqli) if (isset($hostInfo[Tag::TARGET_HOST])) { $span->service .= '-' . \DDTrace\Util\Normalizer::normalizeHostUdsAsService($hostInfo[Tag::TARGET_HOST]); - $span->meta['_dd.svc_src'] = 'opt.db_client_split_by_instance'; + $span->attributes['_dd.svc_src'] = 'opt.db_client_split_by_instance'; } } $dbName = ObjectKVStore::get($mysqli, self::KEY_DATABASE_NAME); diff --git a/src/DDTrace/Integrations/Nette/NetteIntegration.php b/src/DDTrace/Integrations/Nette/NetteIntegration.php index 620ecaf9b7c..6a774b58d1e 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} */ @@ -32,9 +24,8 @@ public static function init(): int return; } - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; - self::addTraceAnalyticsIfEnabled($rootSpan); $rootSpan->service = $service; $rootSpan->meta[Tag::COMPONENT] = self::NAME; }; @@ -63,7 +54,7 @@ static function (SpanData $span) use ($service) { $span->meta[Tag::COMPONENT] = self::NAME; $rootSpan = \DDTrace\root_span(); - $rootSpan->meta[Tag::HTTP_STATUS_CODE] = http_response_code(); + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = http_response_code(); } ); @@ -85,7 +76,7 @@ static function (SpanData $span, $args) use ($service) { $action = $request->getParameter('action'); $rootSpan = \DDTrace\root_span(); - $rootSpan->meta[Tag::HTTP_METHOD] = $request->getMethod(); + $rootSpan->attributes[Tag::HTTP_METHOD] = $request->getMethod(); $rootSpan->meta['nette.route.presenter'] = $presenter; $rootSpan->meta['nette.route.action'] = $action; } diff --git a/src/DDTrace/Integrations/PDO/PDOIntegration.php b/src/DDTrace/Integrations/PDO/PDOIntegration.php index 8d0d1779d97..aaac87b80bf 100644 --- a/src/DDTrace/Integrations/PDO/PDOIntegration.php +++ b/src/DDTrace/Integrations/PDO/PDOIntegration.php @@ -73,7 +73,6 @@ public static function init(): int $span->resource = Integration::toString($query); $instance = $hook->instance; PDOIntegration::setCommonSpanInfo($instance, $span); - PDOIntegration::addTraceAnalyticsIfEnabled($span); PDOIntegration::injectDBIntegration($instance, $hook); PDOIntegration::handleRasp($instance, $span); @@ -98,7 +97,6 @@ public static function init(): int $span->resource = Integration::toString($query); $instance = $hook->instance; PDOIntegration::setCommonSpanInfo($instance, $span); - PDOIntegration::addTraceAnalyticsIfEnabled($span); PDOIntegration::injectDBIntegration($instance, $hook); PDOIntegration::handleRasp($instance, $span); @@ -167,7 +165,6 @@ static function (HookData $hook) { } } PDOIntegration::setCommonSpanInfo($instance, $span); - PDOIntegration::addTraceAnalyticsIfEnabled($span); PDOIntegration::detectError($instance, $span); $span->resource = PDOIntegration::useQuestionMarkPlaceholders($span->resource); @@ -322,7 +319,7 @@ public static function setCommonSpanInfo($source, SpanData $span) Integration::handleInternalSpanServiceName($span, self::NAME, true); $span->service = $span->service . '-' . \DDTrace\Util\Normalizer::normalizeHostUdsAsService($storedConnectionInfo[Tag::TARGET_HOST]); - $span->meta['_dd.svc_src'] = 'opt.db_client_split_by_instance'; + $span->attributes['_dd.svc_src'] = 'opt.db_client_split_by_instance'; } else { Integration::handleInternalSpanServiceName($span, self::NAME); } diff --git a/src/DDTrace/Integrations/PHPRedis/PHPRedisIntegration.php b/src/DDTrace/Integrations/PHPRedis/PHPRedisIntegration.php index f7c3e358b5f..de7c0d50a49 100644 --- a/src/DDTrace/Integrations/PHPRedis/PHPRedisIntegration.php +++ b/src/DDTrace/Integrations/PHPRedis/PHPRedisIntegration.php @@ -329,15 +329,15 @@ public static function enrichSpan(SpanData $span, $instance, $class, $method = n if (!empty($clusterName)) { $normalizedClusterName = \DDTrace\Util\Normalizer::normalizeHostUdsAsService($clusterName); $span->service = $serviceNamePrefix . $normalizedClusterName; - $span->meta['_dd.svc_src'] = 'opt.redis_client_split_by_host'; + $span->attributes['_dd.svc_src'] = 'opt.redis_client_split_by_host'; } elseif (!empty($firstHostOrUDS)) { $normalizedHost = \DDTrace\Util\Normalizer::normalizeHostUdsAsService($firstHostOrUDS); $span->service = $serviceNamePrefix . $normalizedHost; - $span->meta['_dd.svc_src'] = 'opt.redis_client_split_by_host'; + $span->attributes['_dd.svc_src'] = 'opt.redis_client_split_by_host'; } elseif (!empty($host)) { $normalizedHost = \DDTrace\Util\Normalizer::normalizeHostUdsAsService($host); $span->service = $serviceNamePrefix . $normalizedHost; - $span->meta['_dd.svc_src'] = 'opt.redis_client_split_by_host'; + $span->attributes['_dd.svc_src'] = 'opt.redis_client_split_by_host'; } else { Integration::handleInternalSpanServiceName($span, self::NAME); } diff --git a/src/DDTrace/Integrations/Predis/PredisIntegration.php b/src/DDTrace/Integrations/Predis/PredisIntegration.php index 90b1c95daed..f36ac8ab54b 100644 --- a/src/DDTrace/Integrations/Predis/PredisIntegration.php +++ b/src/DDTrace/Integrations/Predis/PredisIntegration.php @@ -60,7 +60,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 @@ -85,7 +84,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/Psr18/Psr18Integration.php b/src/DDTrace/Integrations/Psr18/Psr18Integration.php index 727d6e0fa1f..c1ce8eb702c 100644 --- a/src/DDTrace/Integrations/Psr18/Psr18Integration.php +++ b/src/DDTrace/Integrations/Psr18/Psr18Integration.php @@ -57,7 +57,7 @@ public static function addRequestInfo(SpanData $span, $request) if (\dd_trace_env_config("DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN")) { $span->service = Urls::hostnameForTag($url); - $span->meta['_dd.svc_src'] = 'opt.http_client_split_by_domain'; + $span->attributes['_dd.svc_src'] = 'opt.http_client_split_by_domain'; } $span->meta[Tag::HTTP_METHOD] = $request->getMethod(); diff --git a/src/DDTrace/Integrations/Ratchet/RatchetIntegration.php b/src/DDTrace/Integrations/Ratchet/RatchetIntegration.php index 2b1fcc30e68..c7feb8c6f5d 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 */ @@ -78,7 +70,7 @@ public static function init(): int \DDTrace\collect_code_origins(1); if (\dd_trace_env_config("DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN")) { $span->service = Urls::hostnameForTag($url); - $span->meta['_dd.svc_src'] = 'opt.http_client_split_by_domain'; + $span->attributes['_dd.svc_src'] = 'opt.http_client_split_by_domain'; } }, static function (HookData $hook) { $span = $hook->data; @@ -182,8 +174,7 @@ public static function init(): int $activeSpan->name = "web.request"; $activeSpan->type = Type::WEB_SERVLET; $activeSpan->meta[Tag::COMPONENT] = self::NAME; - $activeSpan->meta[Tag::SPAN_KIND] = 'server'; - RatchetIntegration::addTraceAnalyticsIfEnabled($activeSpan); + $activeSpan->attributes[Tag::SPAN_KIND] = 'server'; ObjectKVStore::put($parentConn, "handshake", $activeSpan); @@ -201,7 +192,7 @@ public static function init(): int \DDTrace\install_hook(CloseResponseTrait::class . "::close", static function (HookData $hook) { if ($rootSpan = \DDTrace\root_span()) { - $rootSpan->meta[Tag::HTTP_STATUS_CODE] = $hook->args[1] ?? 400; + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = $hook->args[1] ?? 400; notify_commit($rootSpan, 400, []); } }); @@ -262,8 +253,10 @@ public static function init(): int $span = $hook->span($rootTrace ? new SpanStack : null); $span->type = Type::WEBSOCKET; $span->service = $handshake->service; - if (isset($handshake->meta['_dd.svc_src'])) { - $span->meta['_dd.svc_src'] = $handshake->meta['_dd.svc_src']; + $handshakeServiceSource = $handshake->attributes['_dd.svc_src'] + ?? $handshake->meta['_dd.svc_src'] ?? null; + if ($handshakeServiceSource !== null) { + $span->attributes['_dd.svc_src'] = $handshakeServiceSource; } $resourceParts = explode(" ", $handshake->resource, 2); $span->resource = "websocket " . end($resourceParts); @@ -280,8 +273,9 @@ public static function init(): int $span->meta["_dd.dm.resource"] = $rootSpan->resource; } foreach ($rootSpan->propagatedTags as $key => $_) { - if (isset($rootSpan->meta[$key])) { - $span->meta[$key] = $rootSpan->meta[$key]; + $value = $rootSpan->attributes[$key] ?? $rootSpan->meta[$key] ?? null; + if ($value !== null) { + $span->attributes[$key] = $value; } } $span->baggage = $rootSpan->baggage; @@ -302,7 +296,7 @@ public static function init(): int } if ($isServer) { - unset($span->meta["closure.declaration"]); + unset($span->attributes["closure.declaration"]); } RatchetIntegration::addLink($span, $handshake, true, $isServer, $frameNum++); diff --git a/src/DDTrace/Integrations/Roadrunner/RoadrunnerIntegration.php b/src/DDTrace/Integrations/Roadrunner/RoadrunnerIntegration.php index 314d17f9db1..e03033bec7a 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(); @@ -159,8 +151,7 @@ function (HookData $hook) use (&$activeSpan, &$suppressResponse, $service, &$rec $activeSpan->name = "web.request"; $activeSpan->type = Type::WEB_SERVLET; $activeSpan->meta[Tag::COMPONENT] = RoadrunnerIntegration::NAME; - $activeSpan->meta[Tag::SPAN_KIND] = 'server'; - RoadrunnerIntegration::addTraceAnalyticsIfEnabled($activeSpan); + $activeSpan->attributes[Tag::SPAN_KIND] = 'server'; 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..48694ad984b 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]); @@ -182,7 +180,7 @@ public static function setDefaultAttributes($source, SpanData $span, $name, $que if (\dd_trace_env_config("DD_TRACE_DB_CLIENT_SPLIT_BY_INSTANCE")) { if ($targetName !== "") { $span->service .= '-' . \DDTrace\Util\Normalizer::normalizeHostUdsAsService($targetName); - $span->meta['_dd.svc_src'] = 'opt.db_client_split_by_instance'; + $span->attributes['_dd.svc_src'] = 'opt.db_client_split_by_instance'; } } } diff --git a/src/DDTrace/Integrations/Slim/SlimIntegration.php b/src/DDTrace/Integrations/Slim/SlimIntegration.php index d135e66d810..a6a20fab08e 100644 --- a/src/DDTrace/Integrations/Slim/SlimIntegration.php +++ b/src/DDTrace/Integrations/Slim/SlimIntegration.php @@ -30,11 +30,10 @@ 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); - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; $rootSpan->meta[Tag::COMPONENT] = SlimIntegration::NAME; if ('4' === $majorVersion) { @@ -115,8 +114,8 @@ static function ($router, $scope, $args, $return) use ($rootSpan) { /** @var ServerRequestInterface $request */ $request = $args[1]; - if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { - $rootSpan->meta[Tag::HTTP_URL] = + if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { + $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize((string) $request->getUri()); } diff --git a/src/DDTrace/Integrations/Swoole/SwooleIntegration.php b/src/DDTrace/Integrations/Swoole/SwooleIntegration.php index e83d329c7a5..dcd95f38aaa 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,8 +32,7 @@ static function (HookData $hook) use ($server, $scheme) { Integration::tagFrameworkServiceSource($rootSpan, self::NAME); $rootSpan->type = Type::WEB_SERVLET; $rootSpan->meta[Tag::COMPONENT] = self::NAME; - $rootSpan->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_SERVER; - self::addTraceAnalyticsIfEnabled($rootSpan); + $rootSpan->attributes[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_SERVER; $args = $hook->args; /** @var Request $request */ @@ -53,7 +44,7 @@ static function (HookData $hook) use ($server, $scheme) { $headers[strtolower($name)] = $value; $normalizedHeader = preg_replace("([^a-z0-9-])", "_", strtolower($name)); if (\array_key_exists($normalizedHeader, $allowedHeaders)) { - $rootSpan->meta["http.request.headers.$normalizedHeader"] = $value; + $rootSpan->attributes["http.request.headers.$normalizedHeader"] = $value; } } consume_distributed_tracing_headers(static function ($key) use ($headers) { @@ -66,7 +57,7 @@ static function (HookData $hook) use ($server, $scheme) { } if (isset($headers["user-agent"])) { - $rootSpan->meta["http.useragent"] = $headers["user-agent"]; + $rootSpan->attributes["http.useragent"] = $headers["user-agent"]; } if (!empty(\dd_trace_env_config('DD_TRACE_HTTP_POST_DATA_PARAM_ALLOWED'))) { @@ -96,15 +87,15 @@ static function (HookData $hook) use ($server, $scheme) { ?? '/' ); $rootSpan->resource = $request->server['request_method'] . ' ' . $normalizedPath; - $rootSpan->meta[Tag::HTTP_METHOD] = $request->server['request_method']; + $rootSpan->attributes[Tag::HTTP_METHOD] = $request->server['request_method']; $host = $headers['host'] ?? ($request->server['remote_addr'] . ':' . $request->server['server_port']); $path = $request->server['request_uri'] ?? $request->server['path_info'] ?? ''; $query = isset($request->server['query_string']) ? '?' . $request->server['query_string'] : ''; $url = $scheme . $host . $path . $query; - $rootSpan->meta[Tag::HTTP_URL] = Normalizer::urlSanitize($url); + $rootSpan->attributes[Tag::HTTP_URL] = Normalizer::urlSanitize($url); - unset($rootSpan->meta['closure.declaration']); + unset($rootSpan->attributes['closure.declaration']); } ); } @@ -173,7 +164,8 @@ static function ($response, $scope, $args) { // Note: The response's body can be retrieved here, from the args if (!$rootSpan->exception - && ((int)$rootSpan->meta[Tag::HTTP_STATUS_CODE]) >= 500 + && ((int)($rootSpan->attributes[Tag::HTTP_STATUS_CODE] + ?? $rootSpan->meta[Tag::HTTP_STATUS_CODE] ?? 0)) >= 500 && $ex = \DDTrace\find_active_exception() ) { $rootSpan->exception = $ex; @@ -196,7 +188,7 @@ static function ($response, $scope, $args) { $allowedHeaders = \dd_trace_env_config("DD_TRACE_HEADER_TAGS"); $normalizedHeader = preg_replace("([^a-z0-9-])", "_", strtolower($key)); if (\array_key_exists($normalizedHeader, $allowedHeaders)) { - $rootSpan->meta["http.response.headers.$normalizedHeader"] = $value; + $rootSpan->attributes["http.response.headers.$normalizedHeader"] = $value; } } ); @@ -207,7 +199,7 @@ static function ($response, $scope, $args) { static function ($response, $scope, $args) { $rootSpan = \DDTrace\root_span(); if ($rootSpan && \count($args) > 0) { - $rootSpan->meta[Tag::HTTP_STATUS_CODE] = $args[0]; + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = $args[0]; } } ); diff --git a/src/DDTrace/Integrations/Symfony/SymfonyIntegration.php b/src/DDTrace/Integrations/Symfony/SymfonyIntegration.php index 2ac324ec74b..2e8c7fc9ba2 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 * @@ -51,16 +43,15 @@ public static function init(): int $rootSpan->name = 'symfony.request'; $rootSpan->service = $service; Integration::tagFrameworkServiceSource($rootSpan, SymfonyIntegration::NAME); - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; $rootSpan->meta[Tag::COMPONENT] = SymfonyIntegration::NAME; - SymfonyIntegration::addTraceAnalyticsIfEnabled($rootSpan); $span->name = 'symfony.httpkernel.kernel.handle'; $span->resource = \get_class($this); $span->type = Type::WEB_SERVLET; $span->service = $service; Integration::tagFrameworkServiceSource($span, SymfonyIntegration::NAME); - $span->meta[Tag::SPAN_KIND] = 'server'; + $span->attributes[Tag::SPAN_KIND] = 'server'; $span->meta[Tag::COMPONENT] = SymfonyIntegration::NAME; }, ] @@ -476,16 +467,15 @@ static function(SpanData $span, $args, $response) use ($handle_http_route) { $span->meta[Tag::COMPONENT] = self::NAME; $rootSpan = \DDTrace\root_span(); - $rootSpan->meta[Tag::HTTP_METHOD] = $request->getMethod(); + $rootSpan->attributes[Tag::HTTP_METHOD] = $request->getMethod(); $rootSpan->meta[Tag::COMPONENT] = self::$frameworkPrefix; - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; - self::addTraceAnalyticsIfEnabled($rootSpan); + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; - if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { - $rootSpan->meta[Tag::HTTP_URL] = Normalizer::urlSanitize($request->getUri()); + if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { + $rootSpan->attributes[Tag::HTTP_URL] = Normalizer::urlSanitize($request->getUri()); } if (isset($response)) { - $rootSpan->meta[Tag::HTTP_STATUS_CODE] = $response->getStatusCode(); + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = $response->getStatusCode(); } $route_name = $request->attributes->get('_route'); @@ -634,7 +624,7 @@ static function(HookData $hook) use ($controllerName) { 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. - \DDTrace\root_span()->meta['error.ignored'] = 1; + \DDTrace\root_span()->ignoreError = true; } }; // Symfony 4.3- diff --git a/src/DDTrace/Integrations/WordPress/WordPressIntegration.php b/src/DDTrace/Integrations/WordPress/WordPressIntegration.php index 8a3774dc260..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} */ diff --git a/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php b/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php index 72413204c93..a407df5771b 100644 --- a/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php +++ b/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php @@ -204,16 +204,15 @@ 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; - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; if ('cli' !== PHP_SAPI) { $normalizedPath = Normalizer::uriNormalizeincomingPath($_SERVER['REQUEST_URI']); $rootSpan->resource = $_SERVER['REQUEST_METHOD'] . ' ' . $normalizedPath; - if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { - $rootSpan->meta[Tag::HTTP_URL] = Normalizer::urlSanitize(home_url(add_query_arg($_GET))); + if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { + $rootSpan->attributes[Tag::HTTP_URL] = Normalizer::urlSanitize(home_url(add_query_arg($_GET))); } } } diff --git a/src/DDTrace/Integrations/Yii/YiiIntegration.php b/src/DDTrace/Integrations/Yii/YiiIntegration.php index 91fa862d5f9..6bbb54c95b6 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} */ @@ -37,8 +29,7 @@ static function () { $rootSpan = \DDTrace\root_span(); if ($rootSpan !== null) { $rootSpan->meta[Tag::COMPONENT] = self::NAME; - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; - self::addTraceAnalyticsIfEnabled($rootSpan); + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; } } ); @@ -104,7 +95,7 @@ function (SpanData $span, $args) use (&$firstController) { $endpoint = "{$controller}::{$this->action->actionMethod}"; $rootSpan->meta["app.endpoint"] = $endpoint; - $rootSpan->meta[Tag::HTTP_URL] = + $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize(Url::base(true) . Url::current()); } diff --git a/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php b/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php index cf4aa4a07a3..38b3487241f 100644 --- a/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php +++ b/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php @@ -2,6 +2,7 @@ namespace DDTrace\Integrations\ZendFramework\V1; +use DDTrace\Integrations\Integration; use DDTrace\Integrations\ZendFramework\ZendFrameworkIntegration; use DDTrace\Tag; use Zend_Controller_Front; @@ -21,7 +22,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(); @@ -31,12 +31,12 @@ public function preDispatch(Zend_Controller_Request_Abstract $request) if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { $span->resource = $controller . '@' . $action . ' ' . $route; } - $span->meta[Tag::HTTP_METHOD] = $request->getMethod(); - $span->meta[Tag::SPAN_KIND] = 'server'; + $span->attributes[Tag::HTTP_METHOD] = $request->getMethod(); + $span->attributes[Tag::SPAN_KIND] = 'server'; $span->meta[Tag::COMPONENT] = ZendFrameworkIntegration::NAME; - if (!array_key_exists(Tag::HTTP_URL, $span->meta)) { - $span->meta[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize( + if (!Integration::hasTag($span, Tag::HTTP_URL)) { + $span->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize( $request->getScheme() . '://' . $request->getHttpHost() . $request->getRequestUri() @@ -53,6 +53,6 @@ public function postDispatch(Zend_Controller_Request_Abstract $request) if (null === $span) { return; } - $span->meta[Tag::HTTP_STATUS_CODE] = $this->getResponse()->getHttpResponseCode(); + $span->attributes[Tag::HTTP_STATUS_CODE] = $this->getResponse()->getHttpResponseCode(); } } diff --git a/src/DDTrace/Integrations/ZendFramework/ZendFrameworkIntegration.php b/src/DDTrace/Integrations/ZendFramework/ZendFrameworkIntegration.php index 89744136740..25c27e606c0 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. @@ -63,12 +54,12 @@ static function ($broker, $scope, $args) { if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { $rootSpan->resource = $controller . '@' . $action . ' ' . $route; } - $rootSpan->meta[Tag::HTTP_METHOD] = $request->getMethod(); - $rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->attributes[Tag::HTTP_METHOD] = $request->getMethod(); + $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; $rootSpan->meta[Tag::COMPONENT] = self::NAME; - if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { - $rootSpan->meta[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize( + if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { + $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize( $request->getScheme() . '://' . $request->getHttpHost() . $request->getRequestUri() diff --git a/src/DDTrace/OpenTelemetry/Context.php b/src/DDTrace/OpenTelemetry/Context.php index 47efb029ae0..be653be3a6a 100644 --- a/src/DDTrace/OpenTelemetry/Context.php +++ b/src/DDTrace/OpenTelemetry/Context.php @@ -211,7 +211,11 @@ private static function activateParent(?SpanData $currentSpan): ContextInterface $currentSpan, API\SpanContext::create($currentTraceId, $currentSpanId, $traceFlags, $traceState), // $context self::getDDInstrumentationScope(), // $instrumentationScope - isset($currentSpan->meta[Tag::SPAN_KIND]) ? self::convertDDSpanKindToOtel($currentSpan->meta[Tag::SPAN_KIND]) : API\SpanKind::KIND_INTERNAL, // $kind + isset($currentSpan->attributes[Tag::SPAN_KIND]) || isset($currentSpan->meta[Tag::SPAN_KIND]) + ? self::convertDDSpanKindToOtel( + $currentSpan->attributes[Tag::SPAN_KIND] ?? $currentSpan->meta[Tag::SPAN_KIND] + ) + : API\SpanKind::KIND_INTERNAL, // $kind API\Span::fromContext($parentContext), // $parentSpan (TODO: Handle null parent span) ? $parentContext, // $parentContext NoopSpanProcessor::getInstance(), // $spanProcessor diff --git a/src/DDTrace/OpenTelemetry/Convention.php b/src/DDTrace/OpenTelemetry/Convention.php index 3ba0d21880e..95121cbc156 100644 --- a/src/DDTrace/OpenTelemetry/Convention.php +++ b/src/DDTrace/OpenTelemetry/Convention.php @@ -10,7 +10,7 @@ class Convention { public static function defaultOperationName(SpanData $span): string { - $meta = $span->meta; + $meta = $span->attributes + $span->meta; $spanKind = $meta[Tag::SPAN_KIND] ?? null; switch (true) { diff --git a/src/DDTrace/OpenTelemetry/Span.php b/src/DDTrace/OpenTelemetry/Span.php index d298013ca49..1b5317d39db 100644 --- a/src/DDTrace/OpenTelemetry/Span.php +++ b/src/DDTrace/OpenTelemetry/Span.php @@ -276,7 +276,7 @@ public function getKind(): int */ public function getAttribute(string $key): mixed { - return $this->span->meta[$key] ?? ($this->span->metrics[$key] ?? null); + return $this->span->attributes[$key] ?? null; } public function getStartEpochNanos(): int @@ -305,19 +305,14 @@ public function isRecording(): bool private static function _setAttribute(SpanData $span, string $key, $value): void { if ($value === null) { - unset($span->meta[$key]); - unset($span->metrics[$key]); + unset($span->attributes[$key]); } elseif ($key[0] === '_' && \strncmp($key, '_dd.p.', 6) === 0) { $distributedKey = \substr($key, 6); // strlen('_dd.p.') === 6 \DDTrace\add_distributed_tag($distributedKey, $value); - } elseif (\is_float($value) - || \is_int($value) - || (\is_array($value) && \count($value) > 0 && \is_numeric($value[0]))) { // Note: Assumes attribute with primitive, homogeneous array values - $span->metrics[$key] = $value; } elseif ($key === 'service.name') { $span->service = $value; } else { - $span->meta[$key] = $value; + $span->attributes[$key] = $value; } } @@ -445,11 +440,11 @@ public function setStatus(string $code, ?string $description = null): SpanInterf } if ($this->status->getCode() === API\StatusCode::STATUS_UNSET && $code === API\StatusCode::STATUS_ERROR) { - $this->span->meta[Tag::ERROR_MSG] = $description; + $this->span->attributes[Tag::ERROR_MSG] = $description; } elseif ($this->status->getCode() === API\StatusCode::STATUS_ERROR && $code === API\StatusCode::STATUS_OK) { - unset($this->span->meta[Tag::ERROR_MSG]); - unset($this->span->meta[Tag::ERROR_TYPE]); - unset($this->span->meta[Tag::ERROR_STACK]); + unset($this->span->attributes[Tag::ERROR_MSG]); + unset($this->span->attributes[Tag::ERROR_TYPE]); + unset($this->span->attributes[Tag::ERROR_STACK]); } $this->status = StatusData::create($code, $description); 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/DDTrace/Span.php b/src/DDTrace/Span.php index 82cba27474b..a928f23e0bc 100644 --- a/src/DDTrace/Span.php +++ b/src/DDTrace/Span.php @@ -146,7 +146,7 @@ public function setTag($key, $value, $setIfFinished = false) } if ($key === Tag::ERROR_MSG) { - $this->internalSpan->meta[$key] = (string)$value; + $this->internalSpan->attributes[$key] = (string)$value; $this->setError(true); return; } @@ -182,8 +182,8 @@ public function setTag($key, $value, $setIfFinished = false) if ($key === Tag::HTTP_STATUS_CODE && $value >= 500) { $this->hasError = true; - if (!isset($this->internalSpan->meta[Tag::ERROR_TYPE])) { - $this->internalSpan->meta[Tag::ERROR_TYPE] = 'Internal Server Error'; + if (!isset($this->internalSpan->attributes[Tag::ERROR_TYPE])) { + $this->internalSpan->attributes[Tag::ERROR_TYPE] = 'Internal Server Error'; } } @@ -198,7 +198,7 @@ public function setTag($key, $value, $setIfFinished = false) } } - $this->internalSpan->meta[$key] = (string)$value; + $this->internalSpan->attributes[$key] = (string)$value; } /** @@ -244,7 +244,8 @@ public function setMetric($key, $value) return; } - $this->internalSpan->metrics[$key] = $value; + // As a double, which is what the metrics bucket held on the wire. + $this->internalSpan->attributes[$key] = is_array($value) ? $value : (float)$value; } /** @@ -275,9 +276,9 @@ public function setError($error) { if (($error instanceof Exception) || ($error instanceof Throwable)) { $this->hasError = true; - $this->internalSpan->meta[Tag::ERROR_MSG] = $error->getMessage(); - $this->internalSpan->meta[Tag::ERROR_TYPE] = get_class($error); - $this->internalSpan->meta[Tag::ERROR_STACK] = $error->getTraceAsString(); + $this->internalSpan->attributes[Tag::ERROR_MSG] = $error->getMessage(); + $this->internalSpan->attributes[Tag::ERROR_TYPE] = get_class($error); + $this->internalSpan->attributes[Tag::ERROR_STACK] = $error->getTraceAsString(); return; } @@ -300,8 +301,8 @@ public function setError($error) public function setRawError($message, $type) { $this->hasError = true; - $this->internalSpan->meta[Tag::ERROR_MSG] = $message; - $this->internalSpan->meta[Tag::ERROR_TYPE] = $type; + $this->internalSpan->attributes[Tag::ERROR_MSG] = $message; + $this->internalSpan->attributes[Tag::ERROR_TYPE] = $type; } public function hasError() @@ -377,7 +378,7 @@ public function log(array $fields = [], $timestamp = null) // messages, and logging multiple messages is not prohibited by the OpenTracing spec: // https://opentracing.io/docs/overview/tags-logs-baggage/#logs // We want to deprecate this behavior and change it. In the meantime we apply this workaround. - $this->internalSpan->meta[Tag::ERROR_MSG] = (string)$value; + $this->internalSpan->attributes[Tag::ERROR_MSG] = (string)$value; } elseif ($key === Tag::LOG_STACK) { $this->setTag(Tag::ERROR_STACK, $value); } 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/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 6b32afbcc78..16c79106d15 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'; From ed75ea1a0d4dfd15e21577d6be3b14588699bc98 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Thu, 1 Oct 2026 18:02:45 +0200 Subject: [PATCH 03/11] test: migrate tests to the V1 span introspection shape dd_trace_serialize_closed_spans() now reports the V1 shape: a typed attributes map with promoted fields (span_kind, component, sampling_priority, ...) and native span links and events. Migrate the phpt, PHPUnit and snapshot tests to it, and add coverage for the V1 and v0.4 wires, span attributes, ignoreError and the default root component. Remove tests for the retired userland msgpack serializer and thread sender (dd_trace_serialize_msgpack, dd_trace_send_traces_via_thread, the in-process background sender capability tests) and for the removed App Analytics trace search config. --- .../api_security_telemetry_missing_route.phpt | 4 +- .../client_init_record_span_tags.phpt | 2 + .../extension/rinit_record_span_tags.phpt | 2 + .../extension/rinit_root_span_add_tag.phpt | 1 + .../extension/rinit_rshutdown_basic.phpt | Bin 5031 -> 5037 bytes appsec/tests/extension/root_span_add_tag.phpt | 37 +-- .../EndpointFallbackSamplingTests.groovy | 4 +- .../test_ddtrace_is_fully_loaded.php | 8 +- .../API/MessagePackSerializationBench.php | 41 ---- tests/Common/CLITestCase.php | 11 +- tests/Common/SnapshotTestTrait.php | 3 +- tests/Common/SpanAssertionTrait.php | 11 +- tests/Common/SpanChecker.php | 215 ++++++++++++++++-- tests/Common/TracerTestTrait.php | 12 + .../Composer/ComposerInteroperabilityTest.php | 10 + tests/DistributedTracing/SyntheticsTest.php | 1 + tests/Integration/DatabaseMonitoringTest.php | 8 +- .../LongRunning/LongRunningScriptTest.php | 11 +- tests/Integration/ResponseStatusCodeTest.php | 2 + tests/Integration/TracerTest.php | 24 +- .../Integrations/Curl/CurlIntegrationTest.php | 106 +-------- .../Custom/Autoloaded/CommonScenariosTest.php | 3 + .../Custom/Autoloaded/FatalErrorTest.php | 1 + .../Autoloaded/TraceSearchConfigTest.php | 54 ----- .../HttpHeadersConfiguredTest.php | 1 + .../HttpHeadersNotConfiguredTest.php | 1 + .../NotAutoloaded/IncomingUserInfoTest.php | 1 + .../Integrations/Exec/ExecIntegrationTest.php | 8 +- .../Guzzle/V5/GuzzleIntegrationTest.php | 3 +- .../Guzzle/V6/GuzzleIntegrationTest.php | 2 +- .../Laravel/V4/TraceSearchConfigTest.php | 88 ------- .../Laravel/V5_7/TraceSearchConfigTest.php | 85 ------- tests/Integrations/Laravel/V5_8/QueueTest.php | 11 +- .../Laravel/V5_8/TraceSearchConfigTest.php | 85 ------- tests/Integrations/Laravel/V8_x/QueueTest.php | 11 +- .../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 ------ .../MongoDB/Latest/MongoDBTest.php | 4 +- tests/Integrations/Mysqli/MysqliTest.php | 2 +- tests/Integrations/PDO/PDOTest.php | 15 +- .../Integrations/PHPRedis/V5/PHPRedisTest.php | 4 +- .../Integrations/Predis/Latest/PredisTest.php | 12 +- .../Integrations/Ratchet/V0_4/RatchetTest.php | 2 +- tests/Integrations/SQLSRV/SQLSRVTest.php | 15 +- .../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 ----- .../Integration/API/BaggageTest.php | 8 +- .../Integration/API/TracerTest.php | 106 ++++----- .../Integration/InteroperabilityTest.php | 101 ++++++-- .../Integration/SpanProvenanceTest.php | 2 +- tests/Unit/ConfigurationTest.php | 41 ---- .../TraceAnalyticsProcessorTest.php | 31 +-- tests/Unit/SpanTest.php | 22 +- tests/WebServer.php | 6 + tests/ext/active_span.phpt | 41 +++- ...al_tag_on_userland_and_internal_spans.phpt | 8 +- tests/ext/analytics_event.phpt | 43 ++++ .../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 +- .../ext/background-sender/agent_headers.phpt | 4 +- .../agent_headers_container_id.phpt | 3 +- .../agent_headers_container_id_empty.phpt | 3 +- .../agent_headers_container_id_fargate.phpt | 3 +- .../agent_headers_ignore_userland.phpt | 49 ---- .../agent_headers_unix_domain_socket.phpt | 1 + .../ext/background-sender/agent_sampling.phpt | 7 +- ...ckground_sender_restores_capabilities.phpt | 79 ------- .../background_sender_survives_setuid.phpt | 77 ------- tests/ext/base_service.phpt | 10 +- tests/ext/client_side_stats_top_level.phpt | 2 +- tests/ext/close_spans_until.phpt | 16 +- .../dd_trace_send_traces_via_thread_001.phpt | 23 -- .../dd_trace_send_traces_via_thread_002.phpt | 21 -- .../dd_trace_serialize_header_to_meta.phpt | 8 +- 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 --- ...serialize_msgpack_meta_struct_int_key.phpt | 14 -- .../dd_trace_serialize_msgpack_reference.phpt | 47 ---- tests/ext/dd_trace_span_data_get_link.phpt | 2 +- ...ce_span_data_serialization_with_links.phpt | 89 ++++++-- ...n_link_event_native_nested_attributes.phpt | 62 +++++ .../distributed_trace_asm_standalone_01.phpt | 40 ++-- .../distributed_trace_asm_standalone_02.phpt | 36 ++- .../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 +- .../distributed_trace_bogus_ids.phpt | 31 ++- .../distributed_trace_inherit.phpt | 38 ++-- ...stributed_trace_overwrite_active_span.phpt | 21 +- ...f_class_or_function_exists_by_default.phpt | 2 - tests/ext/env_meta_fallback_promoted.phpt | 35 +++ tests/ext/extract_ip_private_01.phpt | 2 +- tests/ext/extract_server_values.phpt | 19 +- tests/ext/fibers/fiber_observer_bailout.phpt | 6 +- tests/ext/fibers/fiber_stack_switch.phpt | 6 +- tests/ext/flush-autofinish.phpt | 4 +- tests/ext/force_flush_traces.phpt | 2 +- tests/ext/generate_128_bit_trace_id.phpt | 4 +- ...t_resource_renaming_always_simplified.phpt | 8 +- ...http_endpoint_resource_renaming_basic.phpt | 9 +- tests/ext/includes/fake_tracer.inc | 4 +- tests/ext/inferred_proxy/alter_service.phpt | 47 ++-- tests/ext/inferred_proxy/basic_test.phpt | 49 ++-- .../consume_distributed_tracing_headers.phpt | 40 ++-- .../inferred_proxy/distributed_tracing.phpt | 50 ++-- .../ext/inferred_proxy/error_propagated.phpt | 53 ++--- .../inferred_proxy/fallback_service_name.phpt | 49 ++-- .../inferred_proxy/incomplete_headers.phpt | 39 ++-- tests/ext/inferred_proxy/multiple_traces.phpt | 74 +++--- .../propagated_tags_after_span_start.phpt | 49 ++-- .../propagated_tags_before_span_start.phpt | 45 ++-- tests/ext/inferred_proxy/sampling_rules.phpt | 37 ++- .../security_headers_forwarded.phpt | 8 +- .../serialization-sampling-chunk.phpt | 10 +- tests/ext/inherit_meta_from_parent.phpt | 9 +- .../curl/distributed_tracing_curl.phpt | 2 +- .../distributed_tracing_curl_copy_handle.phpt | 2 +- .../distributed_tracing_curl_drop_dm.phpt | 2 +- ...ted_tracing_curl_existing_headers_001.phpt | 2 +- ...ted_tracing_curl_existing_headers_002.phpt | 2 +- ...ted_tracing_curl_existing_headers_003.phpt | 2 +- ...distributed_tracing_curl_invalid_tags.phpt | 2 +- ...stributed_tracing_curl_multi_exec_001.phpt | 2 +- ...stributed_tracing_curl_multi_exec_002.phpt | 2 +- ...stributed_tracing_curl_multi_exec_003.phpt | 2 +- ...d_tracing_curl_multi_exec_copy_handle.phpt | 2 +- ..._curl_multi_exec_existing_headers_001.phpt | 2 +- ..._curl_multi_exec_existing_headers_002.phpt | 2 +- .../distributed_tracing_curl_tracestate.phpt | 2 +- .../drupal/drupal_integration.inc | 4 +- ...me_engine_service_dropped_nested_span.phpt | 2 +- .../theme_render_dropped_nested_span.phpt | 2 +- .../distributed_tracing_http_streams.phpt | 10 +- ...acing_http_streams_with_headers_array.phpt | 2 +- ...cing_http_streams_with_headers_string.phpt | 2 +- ...t_metadata_injection_from_valid_files.phpt | 4 +- ...metadata_injection_from_invalid_files.phpt | 78 ++++--- .../source_code/commit_sha_env_var.phpt | 31 ++- .../git_metadata_injection_from_env.phpt | 39 ++-- ...t_metadata_injection_from_global_tags.phpt | 43 ++-- ...injection_remove_credentials_from_env.phpt | 37 ++- .../source_code/repository_url_env_var.phpt | 33 ++- tests/ext/ip_collection_01.phpt | 2 +- tests/ext/ip_collection_02.phpt | 2 +- tests/ext/ip_collection_03.phpt | 2 +- tests/ext/ip_collection_04.phpt | 2 +- tests/ext/ip_collection_05.phpt | 2 +- tests/ext/limiter/002-limiter-reached.phpt | 4 +- .../003-limiter-with-asm-standalone.phpt | 2 +- .../debugger_span_decoration_probe.phpt | 10 +- tests/ext/nested_exceptions.phpt | 10 +- ...l_http_response_status_code_remapping.phpt | 6 +- ...onse_status_code_remapping_precedence.phpt | 6 +- .../ext/otel_http_status_code_remapping.phpt | 6 +- .../pcntl_fork_long_running_autoflush.phpt | 8 +- tests/ext/peer_service_disabled_default.phpt | 12 +- tests/ext/peer_service_honor_user_value.phpt | 18 +- tests/ext/peer_service_remapping.phpt | 30 +-- ...rvice_sources_not_serialized_when_set.phpt | 4 +- ...ice_sources_not_serialized_when_unset.phpt | 4 +- .../peer_service_use_first_available_tag.phpt | 24 +- tests/ext/peer_service_wrong_values.phpt | 18 +- ...-rule-name-as-glob-with-question-mark.phpt | 3 +- .../serialization-chunk.phpt | 12 +- tests/ext/process_tags.phpt | 6 +- tests/ext/referrer_extraction_01.phpt | 25 +- tests/ext/referrer_extraction_02.phpt | 27 +-- tests/ext/referrer_extraction_03.phpt | 25 +- tests/ext/referrer_extraction_04.phpt | 25 +- tests/ext/referrer_extraction_05.phpt | 27 +-- .../request-replayer/analytics_event_v04.phpt | 57 +++++ .../client_side_stats_dd_tags_env.phpt | 63 +++++ ...ent_side_stats_inferred_span_sampling.phpt | 69 ++++++ .../dd_trace_exception_span_event.phpt | 37 ++- .../request-replayer/dd_trace_span_event.phpt | 43 +++- .../dd_trace_span_link_with_exception.phpt | 22 +- .../serializer_wire_inprocess_multitrace.phpt | 67 ++++++ .../serializer_wire_inprocess_v04.phpt | 61 +++++ .../serializer_wire_inprocess_v1.phpt | 53 +++++ .../serializer_wire_sidecar_forced_v04.phpt | 43 ++++ .../serializer_wire_sidecar_v1.phpt | 56 +++++ .../span_attributes_v04_wire.phpt | 69 ++++++ .../span_link_event_attributes_v04_wire.phpt | 76 +++++++ .../top_level_marked_on_v1_wire.phpt | 64 ++++++ .../traced_attribute_tags_v04_wire.phpt | 72 ++++++ tests/ext/root_span_default_component.phpt | 17 ++ .../ext/root_span_default_component_cli.phpt | 15 ++ ...span_default_component_framework_wins.phpt | 17 ++ 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 | 29 +-- ...ot_span_url_as_resource_names_no_host.phpt | 29 +-- 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 | 19 +- .../root_span_url_with_post_no_param_set.phpt | 19 +- ...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 +- ...ampling_mechanism_from_decision_maker.phpt | 29 +++ .../ext/sandbox-prehook/dd_trace_method.phpt | 68 +++--- .../sandbox-prehook/exception_error_log.phpt | 2 +- .../sandbox-prehook/exception_handling.phpt | 12 +- .../class_resolver_bailout_hook.phpt | 2 +- .../limiter_reset_flush_with_open_spans.phpt | 8 +- .../nested_dropped_spans.phpt | 2 - .../reset_configured_overrides.phpt | 9 +- 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 | 32 +-- .../ext/sandbox/dd_trace_function_alias.phpt | 2 - .../sandbox/dd_trace_function_complex.phpt | 101 ++++---- .../sandbox/dd_trace_function_internal.phpt | 27 +-- .../sandbox/dd_trace_function_userland.phpt | 4 +- tests/ext/sandbox/dd_trace_method.phpt | 76 +++---- 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 +- tests/ext/sandbox/die_in_sandbox.phpt | 6 +- .../errors_are_flagged_from_userland.phpt | 31 ++- tests/ext/sandbox/exception_error_log.phpt | 2 +- ...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 +- 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 +- .../install_hook/trace_closure_ge_php_84.phpt | 8 - .../ext/sandbox/install_hook/trace_file.phpt | 4 - .../sandbox/install_hook/trace_function.phpt | 2 - .../sandbox/install_hook/trace_generator.phpt | 1 - .../trace_generator_ge_php_84.phpt | 1 - tests/ext/sandbox/manual_flush.phpt | 4 +- .../retval_is_null_with_exception.phpt | 2 +- .../ext/sandbox/safe_to_string_metadata.phpt | 114 ++++++---- ...to_string_metadata_drops_invalid_keys.phpt | 4 +- .../safe_to_string_metadata_ge_php_84.phpt | 115 ++++++---- tests/ext/sandbox/safe_to_string_metrics.phpt | 50 +++- tests/ext/sandbox/span_clone.phpt | 140 ++++++++---- ...c_tracing_closures_will_not_bind_this.phpt | 2 +- tests/ext/sdk_otlp_export_marker.phpt | 2 +- .../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 +- tests/ext/span_attributes_empty_keys.phpt | 27 +++ tests/ext/span_attributes_input.phpt | 119 ++++++++++ tests/ext/span_data_attributes_init.phpt | 47 ++++ tests/ext/span_data_meta_view.phpt | 141 ++++++++++++ tests/ext/span_data_meta_view_jit.phpt | 48 ++++ tests/ext/span_ignore_error.phpt | 65 ++++++ .../ext/span_kind_meta_fallback_promoted.phpt | 30 +++ .../span_link_event_recursive_attributes.phpt | 57 +++++ tests/ext/span_on_close.phpt | 6 +- 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/span_with_removed_exception.phpt | 81 +++---- tests/ext/start_span_with_all_properties.phpt | 62 +++-- tests/ext/start_span_without_closing.phpt | 27 +-- ...start_span_without_closing_autofinish.phpt | 4 +- 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_default_cleared.phpt | 4 +- 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/test_special_attributes.phpt | 17 +- tests/ext/test_special_attributes_bis.phpt | 17 +- tests/ext/traced_attribute.phpt | 22 +- tests/ext/traced_attribute_delayed.phpt | 4 - ...ed_attribute_tags_recursive_and_empty.phpt | 32 +++ tests/ext/ust.phpt | 60 +++-- tests/ext/ust_precedence_over_ddtags.phpt | 8 +- tests/ext/ust_via_ddtags.phpt | 8 +- .../dd_trace_send_traces_via_thread.phpt | 59 ----- tests/opcache/include_trace_attribute.php | 2 +- tests/opcache/preload_trace_attribute.phpt | 7 +- .../span_attributes_immutable_arrays.phpt | 45 ++++ ...oller_test.test_scenario_health_check.json | 1 + ..._test.test_silenced_spans_are_dropped.json | 13 ++ ..._test.test_silenced_spans_are_dropped.json | 13 ++ ..._test.test_silenced_spans_are_dropped.json | 13 ++ ..._test.test_silenced_spans_are_dropped.json | 13 ++ ..._test.test_silenced_spans_are_dropped.json | 13 ++ ..._test.test_scenario_get_parameterized.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...est_scenario_get_to_missing_route_cgi.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ....test_scenario_get_with_exception_cgi.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ...ter.v3_1.exit_test.test_scenario_exit.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ...stributed_tracing_high_level_producer.json | 1 + ...t.test_span_links_high_level_consumer.json | 2 + ...t.test_span_links_high_level_producer.json | 1 + ...st.test_span_links_low_level_consumer.json | 3 + ...st.test_span_links_low_level_producer.json | 1 + ...atest.rest_test.test_scenario_rest2xx.json | 1 + ...atest.rest_test.test_scenario_rest4xx.json | 1 + ...atest.rest_test.test_scenario_rest5xx.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ...pigw_test.test_laravel_inferred_proxy.json | 4 + ...test_laravel_inferred_proxy_exception.json | 4 + ..._test.test_scenario_get_dynamic_route.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...t_scenario_get_with_ignored_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ...octane.apigw_test.test_inferred_proxy.json | 4 + ...gw_test.test_inferred_proxy_exception.json | 4 + ..._test.test_scenario_get_dynamic_route.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...t_scenario_get_with_ignored_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_dynamic_route.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_dynamic_route.json | 10 + ..._test.test_scenario_get_return_string.json | 10 + ...st.test_scenario_get_to_missing_route.json | 10 + ...test.test_scenario_get_with_exception.json | 10 + ...rios_test.test_scenario_get_with_view.json | 10 + ..._test.test_scenario_get_dynamic_route.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_dynamic_route.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ...aravel.v8_x.queue_test.test_broadcast.json | 1 + ..._test.test_scenario_get_dynamic_route.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ...runner.apigw_test.test_inferred_proxy.json | 4 + ...gw_test.test_inferred_proxy_exception.json | 4 + ...st.test_scenario_get_to_missing_route.json | 1 + ...nger_test.test_async_success_consumer.json | 5 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ...ame_test.test_resource_to_uri_mapping.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ...ame_test.test_resource_to_uri_mapping.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...nger_test.test_async_success_consumer.json | 5 + ..._test.test_scenario_get_return_string.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...acks_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...acks_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...acks_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...st.test_scenario_get_to_missing_route.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...acks_test.test_scenario_get_with_view.json | 1 + ..._test.test_scenario_get_return_string.json | 1 + ...test.test_scenario_get_with_exception.json | 1 + ...rios_test.test_scenario_get_with_view.json | 1 + 485 files changed, 3992 insertions(+), 4368 deletions(-) delete mode 100644 tests/Benchmarks/API/MessagePackSerializationBench.php 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 create mode 100644 tests/ext/analytics_event.phpt 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_meta_struct_int_key.phpt delete mode 100644 tests/ext/dd_trace_serialize_msgpack_reference.phpt create mode 100644 tests/ext/dd_trace_span_link_event_native_nested_attributes.phpt create mode 100644 tests/ext/env_meta_fallback_promoted.phpt create mode 100644 tests/ext/request-replayer/analytics_event_v04.phpt create mode 100644 tests/ext/request-replayer/client_side_stats_dd_tags_env.phpt create mode 100644 tests/ext/request-replayer/client_side_stats_inferred_span_sampling.phpt create mode 100644 tests/ext/request-replayer/serializer_wire_inprocess_multitrace.phpt create mode 100644 tests/ext/request-replayer/serializer_wire_inprocess_v04.phpt create mode 100644 tests/ext/request-replayer/serializer_wire_inprocess_v1.phpt create mode 100644 tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt create mode 100644 tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt create mode 100644 tests/ext/request-replayer/span_attributes_v04_wire.phpt create mode 100644 tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt create mode 100644 tests/ext/request-replayer/top_level_marked_on_v1_wire.phpt create mode 100644 tests/ext/request-replayer/traced_attribute_tags_v04_wire.phpt create mode 100644 tests/ext/root_span_default_component.phpt create mode 100644 tests/ext/root_span_default_component_cli.phpt create mode 100644 tests/ext/root_span_default_component_framework_wins.phpt create mode 100644 tests/ext/sampling_mechanism_from_decision_maker.phpt create mode 100644 tests/ext/span_attributes_empty_keys.phpt create mode 100644 tests/ext/span_attributes_input.phpt create mode 100644 tests/ext/span_data_attributes_init.phpt create mode 100644 tests/ext/span_data_meta_view.phpt create mode 100644 tests/ext/span_data_meta_view_jit.phpt create mode 100644 tests/ext/span_ignore_error.phpt create mode 100644 tests/ext/span_kind_meta_fallback_promoted.phpt create mode 100644 tests/ext/span_link_event_recursive_attributes.phpt create mode 100644 tests/ext/traced_attribute_tags_recursive_and_empty.phpt delete mode 100644 tests/ext/wrong-parameter-errors/dd_trace_send_traces_via_thread.phpt create mode 100644 tests/opcache/span_attributes_immutable_arrays.phpt diff --git a/appsec/tests/extension/api_security_telemetry_missing_route.phpt b/appsec/tests/extension/api_security_telemetry_missing_route.phpt index f391a0b8c02..56fec6a1c5c 100644 --- a/appsec/tests/extension/api_security_telemetry_missing_route.phpt +++ b/appsec/tests/extension/api_security_telemetry_missing_route.phpt @@ -41,7 +41,7 @@ var_dump(rshutdown()); $c = $helper->get_commands(); echo "Sampler hash sent: ", $c[0][1][1], "\n"; -match_log('/Telemetry metric api_security\.missing_route added with tags framework:unknown and value 1/'); +match_log('/Telemetry metric api_security\.missing_route added with tags framework:cgi-fcgi and value 1/'); no_match_log('/api_security\.request\./'); ?> @@ -49,5 +49,5 @@ no_match_log('/api_security\.request\./'); bool(true) bool(true) Sampler hash sent: 0 -found message in log matching /Telemetry metric api_security\.missing_route added with tags framework:unknown and value 1/ +found message in log matching /Telemetry metric api_security\.missing_route added with tags framework:cgi-fcgi and value 1/ no message in log matching /api_security\.request\./ diff --git a/appsec/tests/extension/client_init_record_span_tags.phpt b/appsec/tests/extension/client_init_record_span_tags.phpt index 4f9ec5f1442..33871426ff5 100644 --- a/appsec/tests/extension/client_init_record_span_tags.phpt +++ b/appsec/tests/extension/client_init_record_span_tags.phpt @@ -75,6 +75,7 @@ Array [http.url] => https://localhost:8888/foo [http.method] => GET [span.kind] => server + [component] => cgi-fcgi [http.useragent] => my user agent ) rinit @@ -93,6 +94,7 @@ Array [_dd.runtime_family] => php [_dd.sdk.otlp_export] => false [appsec.event] => true + [component] => cgi-fcgi [http.endpoint] => /foo [http.method] => GET [http.request.headers.user-agent] => my user agent diff --git a/appsec/tests/extension/rinit_record_span_tags.phpt b/appsec/tests/extension/rinit_record_span_tags.phpt index 744750f8bec..27a0e061cf3 100644 --- a/appsec/tests/extension/rinit_record_span_tags.phpt +++ b/appsec/tests/extension/rinit_record_span_tags.phpt @@ -70,6 +70,7 @@ Array [http.url] => https://localhost:8888/foo [http.method] => GET [span.kind] => server + [component] => cgi-fcgi [http.useragent] => my user agent ) rinit @@ -88,6 +89,7 @@ Array [_dd.runtime_family] => php [_dd.sdk.otlp_export] => false [appsec.event] => true + [component] => cgi-fcgi [http.endpoint] => /foo [http.method] => GET [http.request.headers.user-agent] => my user agent diff --git a/appsec/tests/extension/rinit_root_span_add_tag.phpt b/appsec/tests/extension/rinit_root_span_add_tag.phpt index 6b63c962340..99fda6dc62f 100644 --- a/appsec/tests/extension/rinit_root_span_add_tag.phpt +++ b/appsec/tests/extension/rinit_root_span_add_tag.phpt @@ -62,6 +62,7 @@ Array [_dd.p.dm] => -0 [_dd.p.tid] => %s [_dd.sdk.otlp_export] => false + [component] => cgi-fcgi [ddappsec] => true [env] => staging [http.method] => GET diff --git a/appsec/tests/extension/rinit_rshutdown_basic.phpt b/appsec/tests/extension/rinit_rshutdown_basic.phpt index dba70527bd463ce283fcda10f50ec343cf74972f..33991beab7571e04e875d4f7a205840f10c556f7 100644 GIT binary patch delta 23 ecmZ3kzE*uh4hvUeNl8&=QfWzQ@#X>+bAAA8&j^74 delta 17 YcmZ3hzFd7n4hu_eYDwbeG8S`w06L5X;Q#;t diff --git a/appsec/tests/extension/root_span_add_tag.phpt b/appsec/tests/extension/root_span_add_tag.phpt index 3f036359d4f..0ef51517796 100644 --- a/appsec/tests/extension/root_span_add_tag.phpt +++ b/appsec/tests/extension/root_span_add_tag.phpt @@ -28,9 +28,11 @@ bool(true) bool(false) array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -45,33 +47,14 @@ array(1) { string(12) "appsec_tests" ["type"]=> string(3) "cli" - ["meta"]=> - array(5) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.sdk.otlp_export"]=> - string(5) "false" + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(%d) {%A ["after"]=> - string(9) "root_span" - ["runtime-id"]=> - string(%d) %s - } - ["metrics"]=> - array(6) { - [%s"]=> - float(%d) - ["_sampling_priority_v1"]=> - float(1) - ["php.compilation.total_time_ms"]=> - float(%s) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) - ["php.memory.peak_usage_bytes"]=> - float(%f) - ["process_id"]=> - float(%f) + string(9) "root_span"%A } } } diff --git a/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/EndpointFallbackSamplingTests.groovy b/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/EndpointFallbackSamplingTests.groovy index c8c73394f3c..b7670d1ad92 100644 --- a/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/EndpointFallbackSamplingTests.groovy +++ b/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/EndpointFallbackSamplingTests.groovy @@ -177,7 +177,9 @@ trait EndpointFallbackSamplingTests extends SamplingTestsInFpm { assert metric.namespace == 'appsec' assert metric.type == 'count' assert metric.points[0][1] >= 1.0 - assert 'framework:unknown' in metric.tags + // root span component now defaults to the SAPI name (fpm-fcgi here); + // this trait is only mixed into Apache2FpmTests + assert 'framework:fpm-fcgi' in metric.tags } } finally { resetFpm() diff --git a/loader/tests/functional/test_ddtrace_is_fully_loaded.php b/loader/tests/functional/test_ddtrace_is_fully_loaded.php index e5105cdbdb7..72a2e9e312d 100644 --- a/loader/tests/functional/test_ddtrace_is_fully_loaded.php +++ b/loader/tests/functional/test_ddtrace_is_fully_loaded.php @@ -34,14 +34,14 @@ [resource] => sh [service] => ddtrace.php [type] => system - [meta] => Array + [component] => subprocess + [attributes] => Array ( + [cmd.shell] => echo using passthru + [_dd.code_origin.type] => exit [_dd.code_origin.frames.1.file] => %s/fixtures/ddtrace.php [_dd.code_origin.frames.1.line] => 13 - [_dd.code_origin.type] => exit [cmd.exit_code] => 0 - [cmd.shell] => echo using passthru - [component] => subprocess ) %A EOS 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/Common/CLITestCase.php b/tests/Common/CLITestCase.php index e7cbf691c62..a48bcdfaddf 100644 --- a/tests/Common/CLITestCase.php +++ b/tests/Common/CLITestCase.php @@ -75,9 +75,16 @@ public function getTracesFromCommand($arguments = '', $overrideEnvs = []) public function getAgentRequestFromCommand($arguments = '', $overrideEnvs = []) { $this->executeCommand($arguments, $overrideEnvs); - foreach ($this->retrieveDumpedTraceData() as $request) { + // retrieveDumpedTraceData()'s v0.4/v0.7-only filter misses a v1-sidecar trace + // (/v1.0/traces) and falls through to this runner's own command_execution span. + $isTraceRequest = function ($request) { $uri = $request['uri'] ?? ''; - if (strpos($uri, '/v0.4/traces') === 0 || strpos($uri, '/v0.7/traces') === 0) { + return strpos($uri, '/v0.4/traces') === 0 + || strpos($uri, '/v0.7/traces') === 0 + || strpos($uri, '/v1.0/traces') === 0; + }; + foreach ($this->retrieveDumpedData($isTraceRequest) as $request) { + if ($isTraceRequest($request)) { return $request; } } diff --git a/tests/Common/SnapshotTestTrait.php b/tests/Common/SnapshotTestTrait.php index be61583431b..e39be05fc2b 100644 --- a/tests/Common/SnapshotTestTrait.php +++ b/tests/Common/SnapshotTestTrait.php @@ -404,7 +404,8 @@ protected function ignoreSampledTraces($traces) { $sampledTraceIDs = []; foreach ($traces as $trace) { foreach ($trace as $span) { - if (isset($span['metrics']['_sampling_priority_v1']) && $span['metrics']['_sampling_priority_v1'] === 0) { + list(, $metrics) = SpanChecker::extractMetaMetrics($span); + if (isset($metrics['_sampling_priority_v1']) && (int) $metrics['_sampling_priority_v1'] === 0) { $sampledTraceIDs[$span['trace_id']] = true; } } diff --git a/tests/Common/SpanAssertionTrait.php b/tests/Common/SpanAssertionTrait.php index 96fd3388cfc..489b22df13d 100644 --- a/tests/Common/SpanAssertionTrait.php +++ b/tests/Common/SpanAssertionTrait.php @@ -65,24 +65,27 @@ public function assertError(array $span, $message, array $expectedStackLinesGrou { $this->assertSame(1, $span['error']); + // Normalize the V1 introspection shape (attributes) and the flat v0.4 wire to a meta view. + list($meta,) = SpanChecker::extractMetaMetrics($span); + // message assertion supports '*' wildcard but DOES NOT enforce order. $messagePartsByWildcard = \explode('*', $message); foreach ($messagePartsByWildcard as $messagePart) { $this->assertNotSame( false, - \strpos($span['meta'][Tag::ERROR_MSG], $messagePart), - \sprintf('Message "%s" does not contain "%s"', $span['meta'][Tag::ERROR_MSG], $message) + \strpos($meta[Tag::ERROR_MSG], $messagePart), + \sprintf('Message "%s" does not contain "%s"', $meta[Tag::ERROR_MSG], $message) ); } - $stackGroups = \explode('stack groups separator', $span['meta']['error.stack']); + $stackGroups = \explode('stack groups separator', $meta['error.stack']); if (count($stackGroups) !== count($expectedStackLinesGroups)) { $this->fail( \sprintf( 'Found %d stack groups, expected %d: %s', count($stackGroups), count($expectedStackLinesGroups), - $span['meta']['error.stack'] + $meta['error.stack'] ) ); } diff --git a/tests/Common/SpanChecker.php b/tests/Common/SpanChecker.php index ed56d53e8ff..0e2ea51e46b 100644 --- a/tests/Common/SpanChecker.php +++ b/tests/Common/SpanChecker.php @@ -63,6 +63,164 @@ public static function dumpTracesGraph(array $traces) return self::dumpSpansGraph($actualGraph); } + /** + * Derives the legacy flat `meta` (string tags) and `metrics` (numeric tags) views from a span. + * + * The V1 introspection shape (`dd_trace_serialize_closed_spans()`) merges the old string `meta` + * and numeric `metrics` maps into a single typed `attributes` map, and promotes some keys to + * top-level span fields. The v0.4 agent wire (parsed from the request replayer) keeps the old + * flat `meta`/`metrics`. Tests assert against the legacy model, so normalize both shapes to it. + * + * Reconstruction is the exact inverse of the reshape, so the derived `meta`/`metrics` match what + * master's introspection returned for the same span. + * + * @return array{0: array, 1: array} `[$meta, $metrics]` + */ + public static function extractMetaMetrics(array $span) + { + // Old flat shape (v0.4 wire): already split into meta/metrics. + if (\array_key_exists('meta', $span) || \array_key_exists('metrics', $span)) { + return [ + isset($span['meta']) ? $span['meta'] : [], + isset($span['metrics']) ? $span['metrics'] : [], + ]; + } + + // New V1 introspection shape: split attributes back by type and restore promoted keys. + $meta = []; + $metrics = []; + foreach (isset($span['attributes']) ? $span['attributes'] : [] as $key => $value) { + if (\is_int($value) || \is_float($value)) { + $metrics[$key] = $value; + } else { + // Strings and nested array/map attributes belong to the meta view. + $meta[$key] = $value; + } + } + // Promoted string keys move back into meta under their original tag names. + if (isset($span['env'])) { + $meta['env'] = $span['env']; + } + if (isset($span['version'])) { + $meta['version'] = $span['version']; + } + if (isset($span['component'])) { + $meta['component'] = $span['component']; + } + // span_kind is an int enum, ALWAYS present; 1 (Internal) is the default and was not emitted + // as a `span.kind` meta tag in the old shape, so only restore the explicit kinds (2-5). + if (isset($span['span_kind'])) { + $kinds = [2 => 'server', 3 => 'client', 4 => 'producer', 5 => 'consumer']; + if (isset($kinds[$span['span_kind']])) { + $meta['span.kind'] = $kinds[$span['span_kind']]; + } + } + // Chunk-level keys: introspection only emits these on the chunk's local root (as the wire). + if (isset($span['origin'])) { + $meta['_dd.origin'] = $span['origin']; + } + if (isset($span['trace_id_high'])) { + $meta['_dd.p.tid'] = $span['trace_id_high']; + } + // sampling_mechanism is the unsigned _dd.p.dm value (sign is always '-'). + if (isset($span['sampling_mechanism'])) { + $meta['_dd.p.dm'] = '-' . $span['sampling_mechanism']; + } + // sampling_priority (int) was the numeric _sampling_priority_v1 metric. + if (isset($span['sampling_priority'])) { + $metrics['_sampling_priority_v1'] = (float) $span['sampling_priority']; + } + return [$meta, $metrics]; + } + + /** + * Converts a V1 introspection span into the flat v0.4 shape the test agent expects, so + * introspection traces (from `flushAndGetTraces()`) can be sent to the agent for snapshotting. + * Old flat spans are returned unchanged. + */ + public static function spanToWireShape(array $span) + { + if (\array_key_exists('meta', $span) || \array_key_exists('metrics', $span)) { + return $span; + } + list($meta, $metrics) = self::extractMetaMetrics($span); + unset( + $span['attributes'], + $span['span_kind'], + $span['env'], + $span['version'], + $span['component'], + $span['origin'], + $span['trace_id_high'], + $span['sampling_priority'], + $span['sampling_mechanism'] + ); + if ($meta) { + $span['meta'] = $meta; + } + if ($metrics) { + $span['metrics'] = $metrics; + } + return $span; + } + + /** + * Moves native `span_links` (v0.4 downgrade wire, or V1 introspection) into the legacy + * `meta['_dd.span_links']` JSON string that the test agent accepts and that the stored + * snapshots were captured with. The test agent cannot decode a native `span_links` list. + */ + public static function spanLinksToLegacyMeta(array $span) + { + if (empty($span['span_links'])) { + unset($span['span_links']); + return $span; + } + $links = []; + foreach ($span['span_links'] as $link) { + $high = isset($link['trace_id_high']) ? $link['trace_id_high'] : 0; + // Introspection renders the high half as 16 hex digits, the wire as a decimal integer. + $highHex = \is_string($high) && \strlen($high) === 16 ? $high : self::decimalToHex($high, 16); + $legacy = [ + 'trace_id' => $highHex . self::decimalToHex($link['trace_id'], 16), + 'span_id' => self::decimalToHex($link['span_id'], 16), + ]; + if (!empty($link['trace_state'])) { + $legacy['trace_state'] = $link['trace_state']; + } elseif (!empty($link['tracestate'])) { + $legacy['trace_state'] = $link['tracestate']; + } + if (!empty($link['attributes'])) { + $legacy['attributes'] = $link['attributes']; + } + if (!empty($link['flags'])) { + $legacy['flags'] = $link['flags']; + } + $links[] = $legacy; + } + unset($span['span_links']); + $span['meta']['_dd.span_links'] = json_encode($links); + return $span; + } + + /** Decimal (int or numeric string, possibly above PHP_INT_MAX) to zero-padded lowercase hex. */ + private static function decimalToHex($decimal, $width) + { + $digits = (string)$decimal; + $hex = ''; + while ($digits !== '' && $digits !== '0') { + $quotient = ''; + $carry = 0; + foreach (str_split($digits) as $d) { + $carry = $carry * 10 + (int)$d; + $quotient .= intdiv($carry, 16); + $carry %= 16; + } + $hex = dechex($carry) . $hex; + $digits = ltrim($quotient, '0'); + } + return str_pad($hex, $width, '0', STR_PAD_LEFT); + } + public static function dumpSpansGraph(array $spansGraph, int $indent = 0) { $out = ""; @@ -85,23 +243,20 @@ public static function dumpSpansGraph(array $spansGraph, int $indent = 0) $out .= ' (' . implode(', ', $values) . ')'; } $out .= "\n"; - if (isset($span['meta'])) { - unset($span['meta']['_dd.p.dm']); - unset($span['meta']['_dd.p.tid']); - unset($span['meta']['_dd.sdk.otlp_export']); - unset($span['meta']['http.client_ip']); - foreach ($span['meta'] as $k => $v) { - $out .= str_repeat(' ', $indent) . ' ' . $k . ' => ' . $v . "\n"; - } + list($dumpMeta, $dumpMetrics) = self::extractMetaMetrics($span); + unset($dumpMeta['_dd.p.dm']); + unset($dumpMeta['_dd.p.tid']); + unset($dumpMeta['_dd.sdk.otlp_export']); + unset($dumpMeta['http.client_ip']); + foreach ($dumpMeta as $k => $v) { + $out .= str_repeat(' ', $indent) . ' ' . $k . ' => ' . (is_scalar($v) ? $v : json_encode($v)) . "\n"; } - if (isset($span['metrics'])) { - unset($span['metrics']['php.compilation.total_time_ms']); - unset($span['metrics']['php.memory.peak_usage_bytes']); - unset($span['metrics']['php.memory.peak_real_usage_bytes']); - unset($span['metrics']['process_id']); - foreach ($span['metrics'] as $k => $v) { - $out .= str_repeat(' ', $indent) . ' ' . $k . ' => ' . $v . "\n"; - } + unset($dumpMetrics['php.compilation.total_time_ms']); + unset($dumpMetrics['php.memory.peak_usage_bytes']); + unset($dumpMetrics['php.memory.peak_real_usage_bytes']); + unset($dumpMetrics['process_id']); + foreach ($dumpMetrics as $k => $v) { + $out .= str_repeat(' ', $indent) . ' ' . $k . ' => ' . (is_scalar($v) ? $v : json_encode($v)) . "\n"; } $out .= self::dumpSpansGraph($node['children'], $indent + 2); } @@ -388,20 +543,19 @@ public function assertSpan($span, SpanAssertion $exp) { TestCase::assertNotNull($span, 'Expected span was not found \'' . $exp->getOperationName() . '\'.'); - $spanMeta = isset($span['meta']) ? $span['meta'] : []; - $spanMetrics = isset($span['metrics']) ? $span['metrics'] : []; + list($spanMeta, $spanMetrics) = self::extractMetaMetrics($span); $namePrefix = $exp->getOperationName() . ': '; // Checking status code here because this can be tested also when we want to check only for existence if ($exp->getStatusCode() !== SpanAssertion::NOT_TESTED) { $actualStatusCode - = isset($span['meta']['http.status_code']) ? $span['meta']['http.status_code'] : ''; + = isset($spanMeta['http.status_code']) ? $spanMeta['http.status_code'] : ''; $expectedStatusCode = strval($exp->getStatusCode()); if ($actualStatusCode !== $expectedStatusCode) { TestCase::assertSame( $exp->getStatusCode(), - isset($span['meta']['http.status_code']) ? $span['meta']['http.status_code'] : '', + isset($spanMeta['http.status_code']) ? $spanMeta['http.status_code'] : '', $namePrefix . "Wrong value for 'status code'. " . "Expected: $expectedStatusCode. Actual: $actualStatusCode" . print_r($span, true) @@ -446,7 +600,16 @@ public function assertSpan($span, SpanAssertion $exp) } foreach ($exp->getExistingTagNames(true) as $key) { - TestCase::assertArrayHasKey($key, $spanMeta); + if ($key === '_dd.span_links') { + // Links live in the top-level native span_links (V1 introspection / dd_trace_serialize_closed_spans) + // OR the legacy '_dd.span_links' meta tag (v0.4 wire). Accept either so both paths pass. + TestCase::assertTrue( + !empty($span['span_links']) || isset($spanMeta['_dd.span_links']), + $exp->getOperationName() . ": expected span links but neither top-level span_links nor meta['_dd.span_links'] is present" + ); + } else { + TestCase::assertArrayHasKey($key, $spanMeta); + } } if ($exp->isOnlyCheckExistence()) { @@ -543,6 +706,12 @@ function ($key) use ($pattern) { if ($tagName === Tag::PID) { TestCase::assertArrayHasKey($tagName, $spanMetrics); unset($spanMetrics[Tag::PID]); + } elseif ($tagName === '_dd.span_links') { + // Links: top-level native span_links (introspection) OR legacy _dd.span_links meta (v0.4 wire). + TestCase::assertTrue( + !empty($span['span_links']) || isset($spanMeta['_dd.span_links']), + $exp->getOperationName() . ": expected span links but neither top-level span_links nor meta['_dd.span_links'] is present" + ); } else { TestCase::assertArrayHasKey($tagName, $spanMeta); } @@ -570,6 +739,10 @@ function ($key) use ($pattern) { // Set by sidecar only unset($spanMetrics['_top_level']); } + if (!isset($metrics['_dd.top_level'])) { + // Set by the sidecar on the V1 path unless explicitly tested + unset($spanMetrics['_dd.top_level']); + } TestCase::assertEquals( $metrics, $spanMetrics, diff --git a/tests/Common/TracerTestTrait.php b/tests/Common/TracerTestTrait.php index 9515d79ebb7..be51045449d 100644 --- a/tests/Common/TracerTestTrait.php +++ b/tests/Common/TracerTestTrait.php @@ -79,6 +79,18 @@ public function isolateTracer($fn, $tracer = null, $config = []) public function sendTracesToTestAgent($traces) { + // flushAndGetTraces() returns the V1 introspection shape (attributes + promoted keys). + // The test agent negotiates the v0.4 wire, so convert each span to the flat shape it + // expects (and that the stored snapshots were captured in) before sending. Native + // span_links become the legacy `_dd.span_links` meta JSON: the test agent rejects the list. + foreach ($traces as &$trace) { + foreach ($trace as &$span) { + $span = SpanChecker::spanLinksToLegacyMeta(SpanChecker::spanToWireShape($span)); + } + unset($span); + } + unset($trace); + // The data to be sent in the POST request $data_json = json_encode($traces); diff --git a/tests/Composer/ComposerInteroperabilityTest.php b/tests/Composer/ComposerInteroperabilityTest.php index a5ddf820202..24468d824f7 100644 --- a/tests/Composer/ComposerInteroperabilityTest.php +++ b/tests/Composer/ComposerInteroperabilityTest.php @@ -103,6 +103,7 @@ function ($execute) { 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ]); } @@ -138,6 +139,7 @@ function ($execute) { 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]) ->withChildren([ SpanAssertion::build('my_operation', 'web.request', 'memcached', 'my_resource') @@ -180,6 +182,7 @@ function ($execute) { 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]) ->withChildren([ SpanAssertion::build('my_operation', 'web.request', 'memcached', 'my_resource') @@ -222,6 +225,7 @@ function ($execute) { 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ]); } @@ -257,6 +261,7 @@ function ($execute) { 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]) ->withChildren([ SpanAssertion::build('my_operation', 'web.request', 'memcached', 'my_resource') @@ -293,6 +298,7 @@ function ($execute) { 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ]); } @@ -322,6 +328,7 @@ function ($execute) { 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-composer', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ]); } @@ -356,6 +363,7 @@ function ($execute) { 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-composer', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ]); } @@ -392,6 +400,7 @@ function ($execute) { 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-composer-autoload-fails', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ]); } @@ -428,6 +437,7 @@ function ($execute) { 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/composer-autoload-fails', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ]); } diff --git a/tests/DistributedTracing/SyntheticsTest.php b/tests/DistributedTracing/SyntheticsTest.php index 995f4e9bef1..f379128f5db 100644 --- a/tests/DistributedTracing/SyntheticsTest.php +++ b/tests/DistributedTracing/SyntheticsTest.php @@ -54,6 +54,7 @@ public function testSyntheticsRequest() 'http.url' => 'http://localhost/index.php', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), '_dd.origin' => 'synthetics-browser', ])->withExactMetrics([ '_sampling_priority_v1' => 1, diff --git a/tests/Integration/DatabaseMonitoringTest.php b/tests/Integration/DatabaseMonitoringTest.php index b4c239d76b2..68b6b4c378d 100644 --- a/tests/Integration/DatabaseMonitoringTest.php +++ b/tests/Integration/DatabaseMonitoringTest.php @@ -325,7 +325,7 @@ public function testBaseHashInjection() $this->assertNotEmpty($matches, 'ddsh not found in SQL comment'); $ddshValue = $matches[1]; - $propagatedHash = $traces[0][1]['meta']['_dd.propagated_hash'] ?? null; + $propagatedHash = $traces[0][1]['attributes']['_dd.propagated_hash'] ?? null; $this->assertNotNull($propagatedHash, '_dd.propagated_hash not found in span'); $this->assertSame($ddshValue, $propagatedHash, 'ddsh in SQL comment does not match _dd.propagated_hash in span'); } @@ -361,7 +361,7 @@ public function testBaseHashInjectionWithoutContainerTagsHash() $this->assertNotEmpty($matches, 'ddsh not found in SQL comment'); $ddshValue = $matches[1]; - $propagatedHash = $traces[0][1]['meta']['_dd.propagated_hash'] ?? null; + $propagatedHash = $traces[0][1]['attributes']['_dd.propagated_hash'] ?? null; $this->assertNotNull($propagatedHash, '_dd.propagated_hash not found in span'); $this->assertSame($ddshValue, $propagatedHash, 'ddsh in SQL comment does not match _dd.propagated_hash in span'); } @@ -445,11 +445,11 @@ public function testDynamicServiceMode() ); $ddshValue = preg_replace('/^.*ddsh=\'([^\']+)\'.*$/', '$1', $commentedQuery); - $propagatedHash = $traces[0][1]['meta']['_dd.propagated_hash'] ?? null; + $propagatedHash = $traces[0][1]['attributes']['_dd.propagated_hash'] ?? null; $this->assertNotNull($propagatedHash, '_dd.propagated_hash not found in span'); $this->assertSame($ddshValue, $propagatedHash, 'ddsh in SQL comment does not match _dd.propagated_hash in span'); // dynamic_service is not full mode, so the trace-injected marker must be absent - $this->assertArrayNotHasKey('_dd.dbm_trace_injected', $traces[0][1]['meta']); + $this->assertArrayNotHasKey('_dd.dbm_trace_injected', $traces[0][1]['attributes']); } } diff --git a/tests/Integration/LongRunning/LongRunningScriptTest.php b/tests/Integration/LongRunning/LongRunningScriptTest.php index ea557f8da06..d0e3b7c985f 100644 --- a/tests/Integration/LongRunning/LongRunningScriptTest.php +++ b/tests/Integration/LongRunning/LongRunningScriptTest.php @@ -23,12 +23,13 @@ public function testMultipleTracesFromLongRunningScriptSetCorrectTraceCountHeade 'DD_TRACE_BGS_TIMEOUT' => 3000, ]); - $headerName = 'X-Datadog-Trace-Count'; - if (\dd_trace_env_config("DD_TRACE_SIDECAR_TRACE_SENDER")) { - $headerName = strtolower($headerName); - } + // Header names are case-insensitive; the sender's casing (coms.c vs sidecar) is + // independent of this runner's own config, so accept either. + $traceCount = $agentRequest['headers']['X-Datadog-Trace-Count'] + ?? $agentRequest['headers']['x-datadog-trace-count'] + ?? null; - $this->assertSame('3', $agentRequest['headers'][$headerName]); + $this->assertSame('3', $traceCount); $this->assertCount(3, $this->loadTraces($agentRequest)); } diff --git a/tests/Integration/ResponseStatusCodeTest.php b/tests/Integration/ResponseStatusCodeTest.php index 58896f2e061..8e5b1053661 100644 --- a/tests/Integration/ResponseStatusCodeTest.php +++ b/tests/Integration/ResponseStatusCodeTest.php @@ -40,6 +40,7 @@ function () { 'http.url' => 'http://localhost/success', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ] ); @@ -66,6 +67,7 @@ function () { 'http.url' => 'http://localhost/error', 'http.status_code' => '500', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ] )->setError(), ] diff --git a/tests/Integration/TracerTest.php b/tests/Integration/TracerTest.php index 377561d5499..27be186cadb 100644 --- a/tests/Integration/TracerTest.php +++ b/tests/Integration/TracerTest.php @@ -44,9 +44,9 @@ public function testGlobalTagsArePresentOnLegacySpansByFlushTime() }); $this->assertSame('custom.name', $traces[0][0]['name']); - $this->assertSame('local', $traces[0][0]['meta']['local_tag']); - $this->assertSame('global', $traces[0][0]['meta']['global_tag']); - $this->assertSame('span_wins', $traces[0][0]['meta']['also_in_span']); + $this->assertSame('local', $traces[0][0]['attributes']['local_tag']); + $this->assertSame('global', $traces[0][0]['attributes']['global_tag']); + $this->assertSame('span_wins', $traces[0][0]['attributes']['also_in_span']); } public function testGlobalTagsArePresentOnInternalSpansByFlushTime() @@ -70,9 +70,9 @@ function (SpanData $span) { }); $this->assertSame('custom.name', $traces[0][0]['name']); - $this->assertSame('local', $traces[0][0]['meta']['local_tag']); - $this->assertSame('global', $traces[0][0]['meta']['global_tag']); - $this->assertSame('span_wins', $traces[0][0]['meta']['also_in_span']); + $this->assertSame('local', $traces[0][0]['attributes']['local_tag']); + $this->assertSame('global', $traces[0][0]['attributes']['global_tag']); + $this->assertSame('span_wins', $traces[0][0]['attributes']['also_in_span']); } /** @@ -246,7 +246,7 @@ public function testEnvironmentIsAddedToASpan() $scope->close(); }); - $this->assertSame('my-env', $traces[0][0]['meta']['env']); + $this->assertSame('my-env', $traces[0][0]['env']); } public function testEnvironmentIsOptional() @@ -257,7 +257,7 @@ public function testEnvironmentIsOptional() $scope->close(); }); - $this->assertTrue(empty($traces[0][0]['meta']['env'])); + $this->assertTrue(empty($traces[0][0]['env'])); } public function testServiceVersionIsAddedToASpan() @@ -268,7 +268,7 @@ public function testServiceVersionIsAddedToASpan() $scope->close(); }); - $this->assertSame('1.2.3', $traces[0][0]['meta']['version']); + $this->assertSame('1.2.3', $traces[0][0]['version']); } public function testServiceVersionIsOptional() @@ -279,7 +279,7 @@ public function testServiceVersionIsOptional() $scope->close(); }); - $this->assertTrue(empty($traces[0][0]['meta']['version'])); + $this->assertTrue(empty($traces[0][0]['version'])); } public function testTracerReset() @@ -431,7 +431,7 @@ public function testBaseService() }); $this->assertSame('changed_child', $traces[0][1]['service']); - $this->assertSame('original_service', $traces[0][1]['meta']['_dd.base_service']); + $this->assertSame('original_service', $traces[0][1]['attributes']['_dd.base_service']); } public function testBaseServiceWithMapping() @@ -448,7 +448,7 @@ public function testBaseServiceWithMapping() }); $this->assertSame('changed_child', $traces[0][1]['service']); - $this->assertSame('changed_service', $traces[0][1]['meta']['_dd.base_service']); + $this->assertSame('changed_service', $traces[0][1]['attributes']['_dd.base_service']); } public function dummyMethodGlobalTags() diff --git a/tests/Integrations/Curl/CurlIntegrationTest.php b/tests/Integrations/Curl/CurlIntegrationTest.php index b082dc5b826..3b914b393da 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', @@ -193,7 +192,7 @@ function ($execute) { $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']) + ->withExistingTagsNames(['http.method', 'http.url', 'http.status_code', 'span.kind', 'component']) ->withChildren([ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://' . HTTPBIN_INTEGRATION . '/status/?') ->withExactTags([ @@ -614,109 +613,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/CommonScenariosTest.php b/tests/Integrations/Custom/Autoloaded/CommonScenariosTest.php index d53be6143fe..5102883537c 100644 --- a/tests/Integrations/Custom/Autoloaded/CommonScenariosTest.php +++ b/tests/Integrations/Custom/Autoloaded/CommonScenariosTest.php @@ -50,6 +50,7 @@ public function provideSpecs() 'http.url' => 'http://localhost/simple?key=value&', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ], 'A simple GET request with a view' => [ @@ -63,6 +64,7 @@ public function provideSpecs() 'http.url' => 'http://localhost/simple_view?key=value&', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ], 'A GET request with an exception' => [ @@ -76,6 +78,7 @@ public function provideSpecs() 'http.url' => 'http://localhost/error?key=value&', 'http.status_code' => '500', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ])->setError(), ], ] diff --git a/tests/Integrations/Custom/Autoloaded/FatalErrorTest.php b/tests/Integrations/Custom/Autoloaded/FatalErrorTest.php index cad7a21dca9..4078e731b2e 100644 --- a/tests/Integrations/Custom/Autoloaded/FatalErrorTest.php +++ b/tests/Integrations/Custom/Autoloaded/FatalErrorTest.php @@ -47,6 +47,7 @@ public function testScenario() 'http.url' => 'http://localhost/fatal', 'http.status_code' => '200', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]) ->setError("E_ERROR", "Intentional E_ERROR") ->withExistingTagsNames(['error.stack']), 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/Custom/NotAutoloaded/HttpHeadersConfiguredTest.php b/tests/Integrations/Custom/NotAutoloaded/HttpHeadersConfiguredTest.php index 4e95479b97f..7e33955d87d 100644 --- a/tests/Integrations/Custom/NotAutoloaded/HttpHeadersConfiguredTest.php +++ b/tests/Integrations/Custom/NotAutoloaded/HttpHeadersConfiguredTest.php @@ -44,6 +44,7 @@ public function testSelectedHeadersAreIncluded() 'http.request.headers.forth-header' => '123', 'http.response.headers.third-header' => 'separated: with : colon', 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]; if (\getenv('DD_TRACE_TEST_SAPI') != 'apache2handler') { $tags['http.request.headers.w__rd-header'] = 'foo'; diff --git a/tests/Integrations/Custom/NotAutoloaded/HttpHeadersNotConfiguredTest.php b/tests/Integrations/Custom/NotAutoloaded/HttpHeadersNotConfiguredTest.php index 135b17939c9..49c5ba56d8d 100644 --- a/tests/Integrations/Custom/NotAutoloaded/HttpHeadersNotConfiguredTest.php +++ b/tests/Integrations/Custom/NotAutoloaded/HttpHeadersNotConfiguredTest.php @@ -47,6 +47,7 @@ public function testSelectedHeadersAreIncluded() 'http.url' => 'http://localhost/', 'http.status_code' => 200, 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ] ); diff --git a/tests/Integrations/Custom/NotAutoloaded/IncomingUserInfoTest.php b/tests/Integrations/Custom/NotAutoloaded/IncomingUserInfoTest.php index b9684547b88..5d7251fcad3 100644 --- a/tests/Integrations/Custom/NotAutoloaded/IncomingUserInfoTest.php +++ b/tests/Integrations/Custom/NotAutoloaded/IncomingUserInfoTest.php @@ -38,6 +38,7 @@ public function testSelectedHeadersAreIncluded() 'http.url' => 'http://localhost/', 'http.status_code' => 200, 'span.kind' => 'server', + 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), ]), ] ); diff --git a/tests/Integrations/Exec/ExecIntegrationTest.php b/tests/Integrations/Exec/ExecIntegrationTest.php index b9237a54ed2..4cf99aff87e 100644 --- a/tests/Integrations/Exec/ExecIntegrationTest.php +++ b/tests/Integrations/Exec/ExecIntegrationTest.php @@ -537,7 +537,7 @@ public function testShellRedaction($sf) $this->assertEquals( "md5(){ return; }; FOO=? BAR=? echo foo -- --password=? -pass ?; md5 ? ?", - $traces[0][0]['meta']['cmd.shell'] + $traces[0][0]['attributes']['cmd.shell'] ); } @@ -554,8 +554,9 @@ public function testShellTruncation() $this->assertEquals( 4 * 1024, - strlen($traces[0][0]['meta']['cmd.shell']) + strlen($traces[0][0]['attributes']['cmd.shell']) ); + $this->assertSame('true', $traces[0][0]['attributes']['cmd.truncated']); } /** @@ -582,8 +583,9 @@ public function testExecTruncation() $this->assertEquals( '["echo","' . str_repeat('a', 4092) . '",""]', - $traces[0][0]['meta']['cmd.exec'] + $traces[0][0]['attributes']['cmd.exec'] ); + $this->assertSame('true', $traces[0][0]['attributes']['cmd.truncated']); } public function testProcOpenInjectsSessionIds() diff --git a/tests/Integrations/Guzzle/V5/GuzzleIntegrationTest.php b/tests/Integrations/Guzzle/V5/GuzzleIntegrationTest.php index 8504ee23c4a..3faddda75ec 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', @@ -373,7 +372,7 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'top_level_app', 'web', 'GET /guzzle_in_web_request.php') - ->withExistingTagsNames(['http.method', 'http.url', 'http.status_code', 'span.kind']) + ->withExistingTagsNames(['http.method', 'http.url', 'http.status_code', 'span.kind', 'component']) ->withChildren([ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') ->withExactTags([ diff --git a/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php b/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php index 1147345bd5c..4c79851f2c3 100644 --- a/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php +++ b/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php @@ -437,7 +437,7 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'top_level_app', 'web', 'GET /guzzle_in_web_request.php') - ->withExistingTagsNames(['http.method', 'http.url', 'http.status_code', 'span.kind']) + ->withExistingTagsNames(['http.method', 'http.url', 'http.status_code', 'span.kind', 'component']) ->withChildren([ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') ->withExactTags([ 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/QueueTest.php b/tests/Integrations/Laravel/V5_8/QueueTest.php index 89e0c8a79ca..b98993a42da 100644 --- a/tests/Integrations/Laravel/V5_8/QueueTest.php +++ b/tests/Integrations/Laravel/V5_8/QueueTest.php @@ -117,10 +117,13 @@ public function testSimplePushAndProcess() }); $processSpanFromArtisanTrace = array_values($processSpanFromArtisanTrace)[0]; - $spanLinks = $processSpanFromArtisanTrace['meta']['_dd.span_links']; - $spanLinks = json_decode($spanLinks, true)[0]; - $spanLinksTraceId = $spanLinks['trace_id']; - $spanLinksSpanId = $spanLinks['span_id']; + // v0.4 carries native span_links (ids as decimal integers); render them as hex. + $spanLinks = $processSpanFromArtisanTrace['span_links'][0]; + $toHex = function ($id) { + return str_pad(self::largeBaseConvert((string) $id, 10, 16), 16, '0', STR_PAD_LEFT); + }; + $spanLinksTraceId = $toHex($spanLinks['trace_id_high'] ?? 0) . $toHex($spanLinks['trace_id']); + $spanLinksSpanId = $toHex($spanLinks['span_id']); $processSpanFromProcessTrace = array_filter($processTrace1[0], function ($span) { return $span['name'] === 'laravel.queue.process'; 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/QueueTest.php b/tests/Integrations/Laravel/V8_x/QueueTest.php index 14a0f0d04a3..be831f7f63f 100644 --- a/tests/Integrations/Laravel/V8_x/QueueTest.php +++ b/tests/Integrations/Laravel/V8_x/QueueTest.php @@ -138,10 +138,13 @@ public function testSimplePushAndProcess() }); $processSpanFromArtisanTrace = array_values($processSpanFromArtisanTrace)[0]; - $spanLinks = $processSpanFromArtisanTrace['meta']['_dd.span_links']; - $spanLinks = json_decode($spanLinks, true)[0]; - $spanLinksTraceId = $spanLinks['trace_id']; - $spanLinksSpanId = $spanLinks['span_id']; + // v0.4 carries native span_links (ids as decimal integers); render them as hex. + $spanLinks = $processSpanFromArtisanTrace['span_links'][0]; + $toHex = function ($id) { + return str_pad(self::largeBaseConvert((string) $id, 10, 16), 16, '0', STR_PAD_LEFT); + }; + $spanLinksTraceId = $toHex($spanLinks['trace_id_high'] ?? 0) . $toHex($spanLinks['trace_id']); + $spanLinksSpanId = $toHex($spanLinks['span_id']); $processSpanFromProcessTrace = array_filter($processTrace1[0], function ($span) { return $span['name'] === 'laravel.queue.process'; 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/MongoDB/Latest/MongoDBTest.php b/tests/Integrations/MongoDB/Latest/MongoDBTest.php index d4805c64328..f06ef682878 100644 --- a/tests/Integrations/MongoDB/Latest/MongoDBTest.php +++ b/tests/Integrations/MongoDB/Latest/MongoDBTest.php @@ -396,9 +396,9 @@ public function testQueryNormalization($query, $expected) }); if (null === $expected) { - $this->assertArrayNotHasKey('mongodb.query', $traces[0][0]['meta']); + $this->assertArrayNotHasKey('mongodb.query', $traces[0][0]['attributes']); } else { - $this->assertSame($expected, $traces[0][0]['meta']['mongodb.query']); + $this->assertSame($expected, $traces[0][0]['attributes']['mongodb.query']); } } diff --git a/tests/Integrations/Mysqli/MysqliTest.php b/tests/Integrations/Mysqli/MysqliTest.php index 525a795f629..fc532c77b28 100644 --- a/tests/Integrations/Mysqli/MysqliTest.php +++ b/tests/Integrations/Mysqli/MysqliTest.php @@ -636,7 +636,7 @@ public function testPreparedStatementUsesServiceModeForDBM() // Verify that SERVICE mode is used for the prepare span $this->assertArrayNotHasKey( '_dd.dbm_trace_injected', - $prepareSpan['meta'] ?? [], + $prepareSpan['attributes'] ?? [], 'mysqli.prepare should use SERVICE mode' ); } diff --git a/tests/Integrations/PDO/PDOTest.php b/tests/Integrations/PDO/PDOTest.php index 1c28313202d..6d508bfba84 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, ]), @@ -269,7 +266,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, ]), @@ -336,7 +332,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, ]), @@ -359,7 +354,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, ]), @@ -496,7 +490,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, ]), @@ -535,7 +528,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, ]), @@ -573,7 +565,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, ]), @@ -612,7 +603,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, ]), @@ -791,7 +781,7 @@ public function testPreparedStatementUsesServiceModeForDBM() // Verify that SERVICE mode is used for the prepare span $this->assertArrayNotHasKey( '_dd.dbm_trace_injected', - $prepareSpan['meta'] ?? [], + $prepareSpan['attributes'] ?? [], 'PDO.prepare should use SERVICE mode' ); } @@ -830,7 +820,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, ]), @@ -874,7 +863,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/PHPRedis/V5/PHPRedisTest.php b/tests/Integrations/PHPRedis/V5/PHPRedisTest.php index ea8edf96e2c..16008833ce1 100644 --- a/tests/Integrations/PHPRedis/V5/PHPRedisTest.php +++ b/tests/Integrations/PHPRedis/V5/PHPRedisTest.php @@ -2486,7 +2486,7 @@ public function testOrphansRemoval() }); $span = $traces[0][0]; - $this->assertEquals(0, $span['metrics']['_sampling_priority_v1']); + $this->assertEquals(0, $span['sampling_priority']); } public function testOrphansRemoval64bit() @@ -2502,6 +2502,6 @@ public function testOrphansRemoval64bit() }); $span = $traces[0][0]; - $this->assertEquals(0, $span['metrics']['_sampling_priority_v1']); + $this->assertEquals(0, $span['sampling_priority']); } } diff --git a/tests/Integrations/Predis/Latest/PredisTest.php b/tests/Integrations/Predis/Latest/PredisTest.php index 0dd5a5ca766..8238b91dab6 100644 --- a/tests/Integrations/Predis/Latest/PredisTest.php +++ b/tests/Integrations/Predis/Latest/PredisTest.php @@ -70,8 +70,8 @@ public function testConnectionAndServiceInfo($firstArgument, $host, $port, $serv } }); $span = $traces[0][0]; - $this->assertSame($host, $span['meta']['out.host']); - $this->assertSame("$port", $span['meta']['out.port']); + $this->assertSame($host, $span['attributes']['out.host']); + $this->assertSame("$port", $span['attributes']['out.port']); $this->assertSame('redis', $span['service']); // With split by domain @@ -84,8 +84,8 @@ public function testConnectionAndServiceInfo($firstArgument, $host, $port, $serv } }); $span = $traces[0][0]; - $this->assertSame($host, $span['meta']['out.host']); - $this->assertSame("$port", $span['meta']['out.port']); + $this->assertSame($host, $span['attributes']['out.host']); + $this->assertSame("$port", $span['attributes']['out.port']); $this->assertSame($service, $span['service']); } @@ -350,7 +350,7 @@ public function testOrphansRemoval() }); $span = $traces[0][0]; - $this->assertEquals(0, $span['metrics']['_sampling_priority_v1']); + $this->assertEquals(0, $span['sampling_priority']); } public function testOrphansRemoval64bit() @@ -365,7 +365,7 @@ public function testOrphansRemoval64bit() }); $span = $traces[0][0]; - $this->assertEquals(0, $span['metrics']['_sampling_priority_v1']); + $this->assertEquals(0, $span['sampling_priority']); } public function testNoFakeServices() diff --git a/tests/Integrations/Ratchet/V0_4/RatchetTest.php b/tests/Integrations/Ratchet/V0_4/RatchetTest.php index cca875d9a12..8fbf9dfb165 100644 --- a/tests/Integrations/Ratchet/V0_4/RatchetTest.php +++ b/tests/Integrations/Ratchet/V0_4/RatchetTest.php @@ -74,7 +74,7 @@ public function onError(ConnectionInterface $conn, \Exception $e) { foreach ($traces[0] as &$span) { $span["resource"] = preg_replace('(:(\d+)$)', ':%d', $span["resource"]); // Our checker has problems with two root spans being identical in primary attributes - if ($span["resource"] === "websocket /" && ($span["metrics"]['websocket.message.length'] ?? "") == '12') { + if ($span["resource"] === "websocket /" && ($span["attributes"]['websocket.message.length'] ?? "") == '12') { $span["resource"] .= 2; } } diff --git a/tests/Integrations/SQLSRV/SQLSRVTest.php b/tests/Integrations/SQLSRV/SQLSRVTest.php index 70b85ff515d..cad76a91463 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, ]) @@ -414,7 +403,7 @@ public function testPreparedStatementUsesServiceModeForDBM() // Verify that SERVICE mode is used for the prepare span $this->assertArrayNotHasKey( '_dd.dbm_trace_injected', - $prepareSpan['meta'] ?? [], + $prepareSpan['attributes'] ?? [], 'sqlsrv_prepare should use SERVICE mode' ); } @@ -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(), - ]), - ] - ); - } -} diff --git a/tests/OpenTelemetry/Integration/API/BaggageTest.php b/tests/OpenTelemetry/Integration/API/BaggageTest.php index 3ac84f07060..7e1dc5bb87a 100644 --- a/tests/OpenTelemetry/Integration/API/BaggageTest.php +++ b/tests/OpenTelemetry/Integration/API/BaggageTest.php @@ -93,10 +93,10 @@ public function testSpansAndBaggage() }); list($parent, $child) = $traces[0]; - $this->assertSame(Tag::SPAN_KIND_VALUE_SERVER, $parent['meta'][Tag::SPAN_KIND]); - $this->assertSame('GET', $parent['meta']['http.method']); - $this->assertSame('/parent', $parent['meta']['http.uri']); - $this->assertSame('1', $child['meta']['user.id']); + $this->assertSame(2, $parent['span_kind']); // span_kind enum: Server=2 + $this->assertSame('GET', $parent['attributes']['http.method']); + $this->assertSame('/parent', $parent['attributes']['http.uri']); + $this->assertSame('1', $child['attributes']['user.id']); $this->assertFlameGraph($traces, [ SpanAssertion::exists('server.request', 'parent', false, (PHP_VERSION_ID < 80100) ? 'datadog/dd-trace-tests' : 'unknown_service:php') diff --git a/tests/OpenTelemetry/Integration/API/TracerTest.php b/tests/OpenTelemetry/Integration/API/TracerTest.php index fcb598201bf..b56a7bc76fd 100644 --- a/tests/OpenTelemetry/Integration/API/TracerTest.php +++ b/tests/OpenTelemetry/Integration/API/TracerTest.php @@ -65,7 +65,7 @@ public function testOtelSetSpanStatusError() $errorSpan->end(); }); - $this->assertSame('error_desc', $traces[0][0]['meta']['error.message']); + $this->assertSame('error_desc', $traces[0][0]['attributes']['error.message']); } public function testUnorderedOtelSpanActivation() @@ -111,7 +111,7 @@ public function testManuallyCreatedSpanWithNoCustomTags() $this->assertNotEquals(0, $span['duration']); $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); - $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['metrics']["_sampling_priority_v1"]); + $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['sampling_priority']); } public function testManuallyCreatedSpanWithCustomTags() @@ -133,9 +133,9 @@ public function testManuallyCreatedSpanWithCustomTags() $this->assertNotEquals(0, $span['duration']); $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); - $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['metrics']["_sampling_priority_v1"]); - $this->assertSame('bar', $span['meta']['foo']); - $this->assertSame('baz', $span['meta']['bar']); + $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['sampling_priority']); + $this->assertSame('bar', $span['attributes']['foo']); + $this->assertSame('baz', $span['attributes']['bar']); } public function testManuallyCreatedSpanWithNestedAttributes() @@ -157,12 +157,12 @@ public function testManuallyCreatedSpanWithNestedAttributes() $this->assertNotEquals(0, $span['duration']); $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); - $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['metrics']["_sampling_priority_v1"]); - $this->assertSame('bar', $span['meta']['foo']); - $this->assertSame('baz', $span['meta']['bar']); - $this->assertSame('bar', $span['meta']['nested.foo']); - $this->assertSame('baz', $span['meta']['nested.bar']); - $this->assertSame('alone', $span['meta']['nested.0']); + $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['sampling_priority']); + $this->assertSame('bar', $span['attributes']['foo']); + $this->assertSame('baz', $span['attributes']['bar']); + $this->assertSame('bar', $span['attributes']['nested']['foo']); + $this->assertSame('baz', $span['attributes']['nested']['bar']); + $this->assertSame('alone', $span['attributes']['nested'][0]); } public function testManuallyCreatedNestedSpansBasic() @@ -228,7 +228,7 @@ public function testCreateSpanInvalidParent() $this->assertNotEmpty($span['trace_id']); $this->assertSame($span['trace_id'], $span['span_id']); $this->assertArrayNotHasKey('parent_id', $span); - $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['metrics']["_sampling_priority_v1"]); + $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['sampling_priority']); } public function testCreateANewTraceInTheSameProcess() @@ -290,22 +290,21 @@ public function testSpanAttributes() $span->end(); }); - $meta = $traces[0][0]['meta']; - $metrics = $traces[0][0]['metrics']; - $this->assertSame("a", $meta['string']); - $this->assertArrayNotHasKey("null-string", $meta); - $this->assertSame("", $meta['empty_string']); - $this->assertEquals(1, $metrics['number']); - $this->assertSame("true", $meta['boolean']); - $this->assertSame("a", $meta['string-array.0']); - $this->assertSame("b", $meta['string-array.1']); - $this->assertSame("c", $meta['string-array.2']); - $this->assertSame("true", $meta['boolean-array.0']); - $this->assertSame("false", $meta['boolean-array.1']); - $this->assertEquals("1.1", $metrics['float-array.0']); - $this->assertEquals("2.2", $metrics['float-array.1']); - $this->assertEquals("3.3", $metrics['float-array.2']); - $this->assertSame("", $meta['empty-array']); + $attributes = $traces[0][0]['attributes']; + $this->assertSame("a", $attributes['string']); + $this->assertArrayNotHasKey("null-string", $attributes); + $this->assertSame("", $attributes['empty_string']); + $this->assertEquals(1, $attributes['number']); + $this->assertTrue($attributes['boolean']); + $this->assertSame("a", $attributes['string-array'][0]); + $this->assertSame("b", $attributes['string-array'][1]); + $this->assertSame("c", $attributes['string-array'][2]); + $this->assertTrue($attributes['boolean-array'][0]); + $this->assertFalse($attributes['boolean-array'][1]); + $this->assertEquals("1.1", $attributes['float-array'][0]); + $this->assertEquals("2.2", $attributes['float-array'][1]); + $this->assertEquals("3.3", $attributes['float-array'][2]); + $this->assertSame("", $attributes['empty-array']); } /** @@ -322,17 +321,18 @@ public function testSpanKind($otelSpanKind, $tagSpanKind) }); $span = $traces[0][0]; - $this->assertSame($tagSpanKind, $span['meta']['span.kind']); + $this->assertSame($tagSpanKind, $span['span_kind']); } public function providerSpanKind() { + // V1 introspection promotes span.kind to the int enum: Internal=1,Server=2,Client=3,Producer=4,Consumer=5 return [ - [SpanKind::KIND_CLIENT, Tag::SPAN_KIND_VALUE_CLIENT], - [SpanKind::KIND_SERVER, Tag::SPAN_KIND_VALUE_SERVER], - [SpanKind::KIND_PRODUCER, Tag::SPAN_KIND_VALUE_PRODUCER], - [SpanKind::KIND_CONSUMER, Tag::SPAN_KIND_VALUE_CONSUMER], - [SpanKind::KIND_INTERNAL, Tag::SPAN_KIND_VALUE_INTERNAL], + [SpanKind::KIND_CLIENT, 3], + [SpanKind::KIND_SERVER, 2], + [SpanKind::KIND_PRODUCER, 4], + [SpanKind::KIND_CONSUMER, 5], + [SpanKind::KIND_INTERNAL, 1], ]; } @@ -375,10 +375,10 @@ public function testReservedAttributesOverridesAnalyticsEvent($analyticsEventVal $span = $traces[0][0]; if ($expectedMetricValue !== null) { - $actualMetricValue = $span['metrics']['_dd1.sr.eausr']; + $actualMetricValue = $span['attributes']['_dd1.sr.eausr']; $this->assertEquals($expectedMetricValue, $actualMetricValue); } else { - $this->assertArrayNotHasKey('_dd1.sr.eausr', $span['metrics']); + $this->assertArrayNotHasKey('_dd1.sr.eausr', $span['attributes']); } } @@ -394,7 +394,7 @@ public function testSpanErrorStatus() $span = $traces[0][0]; $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); - $this->assertSame('error message', $span['meta']['error.message']); + $this->assertSame('error message', $span['attributes']['error.message']); $this->assertEquals(1, $span['error']); } @@ -416,7 +416,7 @@ public function testSpanStatusTransition() $span = $traces[0][0]; $this->assertArrayNotHasKey("error", $span); - $this->assertArrayNotHasKey("error.message", $span['meta']); + $this->assertArrayNotHasKey("error.message", $span['attributes']); $this->assertSame("internal", $span['name']); $this->assertSame("test.span", $span['resource']); } @@ -433,7 +433,7 @@ public function testRecordException() $span = $traces[0][0]; $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); - $this->assertNotEmpty($span['meta'][Tag::ERROR_STACK]); + $this->assertNotEmpty($span['attributes'][Tag::ERROR_STACK]); } public function testSpanNameUpdate() @@ -469,9 +469,9 @@ public function testSpanUpdateAfterEnd() $span = $traces[0][0]; $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); - $this->assertSame('error message', $span['meta']['error.message']); + $this->assertSame('error message', $span['attributes']['error.message']); $this->assertEquals(1, $span['error']); - $this->assertSame('bar', $span['meta']['foo']); + $this->assertSame('bar', $span['attributes']['foo']); } public function testConcurrentSpans() @@ -522,10 +522,10 @@ public function testConcurrentSpans() $this->assertSame($rootSpan['span_id'], $httpSpan['parent_id']); $this->assertSame("http-$i", $httpSpan['resource']); - $this->assertSame("GET", $httpSpan['meta']['http.method']); - $this->assertSame("example.com/$i", $httpSpan['meta']['http.url']); - $this->assertSame('200', $httpSpan['meta']['http.status_code']); - $this->assertSame('1024', $httpSpan['meta']['http.response_content_length']); + $this->assertSame("GET", $httpSpan['attributes']['http.method']); + $this->assertSame("example.com/$i", $httpSpan['attributes']['http.url']); + $this->assertSame('200', $httpSpan['attributes']['http.status_code']); + $this->assertSame('1024', $httpSpan['attributes']['http.response_content_length']); } } @@ -544,8 +544,8 @@ public function testGetSpanContextWithMultipleTraceStates() }); $span = $traces[0][0]; - $this->assertSame('t61rcWkgMzE', $span['meta']['_dd.p.congo']); - $this->assertSame('tehehe', $span['meta']['_dd.p.some_val']); + $this->assertSame('t61rcWkgMzE', $span['attributes']['_dd.p.congo']); + $this->assertSame('tehehe', $span['attributes']['_dd.p.some_val']); } /** @@ -589,7 +589,7 @@ public function testGetSpanContextWithRemoteParent(int $traceFlags, ?TraceState $span = $traces[0][0]; $this->assertSame($low, $span['trace_id']); - $this->assertSame($high, $span['meta']['_dd.p.tid']); + $this->assertSame($high, $span['trace_id_high']); $this->assertSame($decSpanId, $span['parent_id']); } @@ -834,7 +834,7 @@ public function getDescription(): string $spans = $traces[0]; list($childSpan) = $spans; $this->assertSame("11803532876627986230", $childSpan['trace_id']); - $this->assertSame("4bf92f3577b34da6", $childSpan['meta']['_dd.p.tid']); + $this->assertSame("4bf92f3577b34da6", $childSpan['trace_id_high']); $this->assertSame("67667974448284343", $childSpan['parent_id']); } @@ -874,10 +874,10 @@ public function testAddItemToTracestate() $span = $traces[0]; list($childSpan, $span) = $span; - $this->assertSame('t61rcWkgMzE', $span['meta']['_dd.p.congo']); - $this->assertSame('t61rcWkgMzE', $childSpan['meta']['_dd.p.congo']); - $this->assertSame('-0', $span['meta']['_dd.p.dm']); - $this->assertSame('-0', $childSpan['meta']['_dd.p.dm']); + $this->assertSame('t61rcWkgMzE', $span['attributes']['_dd.p.congo']); + $this->assertSame('t61rcWkgMzE', $childSpan['attributes']['_dd.p.congo']); + $this->assertSame(0, $span['sampling_mechanism']); // _dd.p.dm '-0' promotes to sampling_mechanism=0 + $this->assertSame(0, $childSpan['sampling_mechanism']); $this->assertFlameGraph($traces, [ SpanAssertion::exists('internal', 'test.span') diff --git a/tests/OpenTelemetry/Integration/InteroperabilityTest.php b/tests/OpenTelemetry/Integration/InteroperabilityTest.php index 96d4d6e3ab8..58a16797a01 100644 --- a/tests/OpenTelemetry/Integration/InteroperabilityTest.php +++ b/tests/OpenTelemetry/Integration/InteroperabilityTest.php @@ -120,7 +120,7 @@ public function testActivateAnAlreadyActiveDatadogSpan() $span = $traces[0][0]; $this->assertSame('dd.span', $span['name']); - $this->assertArrayNotHasKey('parent_id', $span['meta']); + $this->assertArrayNotHasKey('parent_id', $span['attributes']); } /** @noinspection PhpParamsInspection */ @@ -175,8 +175,8 @@ public function testMixingOpenTelemetrylAndDatadogBasic() $this->assertSame('other.span', $child['resource']); $this->assertSame($parent['span_id'], $child['parent_id']); $this->assertSame($parent['trace_id'], $child['trace_id']); - $this->assertSame('bar', $child['meta']['foo']); - $this->assertArrayNotHasKey('foo', $parent['meta']); + $this->assertSame('bar', $child['attributes']['foo']); + $this->assertArrayNotHasKey('foo', $parent['attributes']); } public function testActivateSpanWithAnotherActiveNonActivatedDatadogSpan() @@ -733,7 +733,7 @@ public function testW3CInteroperability() $this->assertSame('18374692078461386817', $traces[0][0]['parent_id']); $otelRootSpan = $traces[0][0]; - $this->assertSame('ff00000000000517', $otelRootSpan['meta']['_dd.p.tid']); + $this->assertSame('ff00000000000517', $otelRootSpan['trace_id_high']); $this->assertFlameGraph($traces, [ SpanAssertion::exists('internal', 'otel.root.span', false, 'phpunit') @@ -785,7 +785,7 @@ public function testB3SingleInteroperability() $this->assertSame('18374692078461386817', $traces[0][0]['parent_id']); $otelRootSpan = $traces[0][0]; - $this->assertSame('ff00000000000517', $otelRootSpan['meta']['_dd.p.tid']); + $this->assertSame('ff00000000000517', $otelRootSpan['trace_id_high']); $this->assertFlameGraph($traces, [ SpanAssertion::exists('internal', 'otel.root.span', false, 'phpunit') @@ -841,7 +841,7 @@ public function testB3MultiInteroperability() $this->assertSame('18374692078461386817', $traces[0][0]['parent_id']); $otelRootSpan = $traces[0][0]; - $this->assertSame('ff00000000000517', $otelRootSpan['meta']['_dd.p.tid']); + $this->assertSame('ff00000000000517', $otelRootSpan['trace_id_high']); $this->assertFlameGraph($traces, [ SpanAssertion::exists('internal', 'otel.root.span', false, 'phpunit') @@ -882,10 +882,10 @@ public function testBaggageInteroperability() }); list($parent, $child) = $traces[0]; - $this->assertSame(Tag::SPAN_KIND_VALUE_SERVER, $parent['meta'][Tag::SPAN_KIND]); - $this->assertSame('GET', $parent['meta']['http.method']); - $this->assertSame('/parent', $parent['meta']['http.uri']); - $this->assertSame('1', $child['meta']['user.id']); + $this->assertSame(2, $parent['span_kind']); // span_kind enum: Server=2 + $this->assertSame('GET', $parent['attributes']['http.method']); + $this->assertSame('/parent', $parent['attributes']['http.uri']); + $this->assertSame('1', $child['attributes']['user.id']); $this->assertFlameGraph($traces, [ SpanAssertion::exists('server.request', 'parent', false, (PHP_VERSION_ID < 80100) ? 'datadog/dd-trace-tests' : 'unknown_service:php') @@ -920,7 +920,7 @@ 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']); + $this->assertEquals(1.0, $span['attributes']['_dd1.sr.eausr']); } public function testHasEnded() @@ -976,7 +976,7 @@ public function testAttributesInteroperability() $this->assertCount(1, $traces[0]); - $meta = $traces[0][0]['meta']; + $meta = $traces[0][0]['attributes']; $this->assertArrayNotHasKey('arg1', $meta); $this->assertSame('value2', $meta['arg2']); $this->assertSame('value3', $meta['arg3']); @@ -986,8 +986,8 @@ public function testAttributesInteroperability() $this->assertSame('value', $meta['key']); $this->assertArrayNotHasKey('post', $meta); - $this->assertEquals(1, $traces[0][0]['metrics']['m1']); - $this->assertEquals(2, $traces[0][0]['metrics']['m2']); + $this->assertEquals(1, $traces[0][0]['attributes']['m1']); + $this->assertEquals(2, $traces[0][0]['attributes']['m2']); } public function testSpanLinksInteroperabilityFromDatadogSpan() @@ -1024,7 +1024,14 @@ public function testSpanLinksInteroperabilityFromDatadogSpan() }); $this->assertCount(1, $traces[0]); - $this->assertSame("[{\"trace_id\":\"ff0000000000051791e0000000000041\",\"span_id\":\"ff00000000000517\",\"trace_state\":\"dd=t.dm:-0\",\"attributes\":{\"arg1\":\"value1\",\"arg2\":\"value2\"}}]", $traces[0][0]['meta']['_dd.span_links']); + $this->assertSame([[ + 'trace_id' => '10511401530282737729', + 'trace_id_high' => 'ff00000000000517', + 'span_id' => '18374686479671624983', + 'trace_state' => 'dd=t.dm:-0', + 'flags' => 0, + 'attributes' => ['arg1' => 'value1', 'arg2' => 'value2'], + ]], $traces[0][0]['span_links']); } public function testBasicSpanLinksFromDatadog() @@ -1050,7 +1057,12 @@ public function testBasicSpanLinksFromDatadog() }); $this->assertCount(1, $traces[0]); - $this->assertSame("[{\"trace_id\":\"ff0000000000051791e0000000000041\",\"span_id\":\"ff00000000000517\"}]", $traces[0][0]['meta']['_dd.span_links']); + $this->assertSame([[ + 'trace_id' => '10511401530282737729', + 'trace_id_high' => 'ff00000000000517', + 'span_id' => '18374686479671624983', + 'flags' => 0, + ]], $traces[0][0]['span_links']); } public function testSpanLinksInteroperabilityFromOpenTelemetrySpan() @@ -1079,7 +1091,15 @@ public function testSpanLinksInteroperabilityFromOpenTelemetrySpan() }); $this->assertCount(1, $traces[0]); - $this->assertSame("[{\"trace_id\":\"12345678876543211234567887654321\",\"span_id\":\"8765432112345678\",\"trace_state\":\"dd=t.dm:-0\",\"attributes\":{\"arg1\":\"value1\"},\"dropped_attributes_count\":0}]", $traces[0][0]['meta']['_dd.span_links']); + // dropped_attributes_count is not surfaced in the V1 structured span_links (no PHP-side source). + $this->assertSame([[ + 'trace_id' => '1311768467139281697', + 'trace_id_high' => '1234567887654321', + 'span_id' => '9756277977086449272', + 'trace_state' => 'dd=t.dm:-0', + 'flags' => 0, + 'attributes' => ['arg1' => 'value1'], + ]], $traces[0][0]['span_links']); } public function testSpanLinksInteroperabilityBothTypes() @@ -1134,7 +1154,22 @@ public function testSpanLinksInteroperabilityBothTypes() }); $this->assertCount(1, $traces[0]); - $this->assertSame("[{\"trace_id\":\"12345678876543211234567887654321\",\"span_id\":\"8765432112345678\",\"trace_state\":\"dd=t.dm:-0\",\"attributes\":{\"arg1\":\"value1\"},\"dropped_attributes_count\":0},{\"trace_id\":\"ff0000000000051791e0000000000041\",\"span_id\":\"ff00000000000517\"}]", $traces[0][0]['meta']['_dd.span_links']); + $this->assertSame([ + [ + 'trace_id' => '1311768467139281697', + 'trace_id_high' => '1234567887654321', + 'span_id' => '9756277977086449272', + 'trace_state' => 'dd=t.dm:-0', + 'flags' => 0, + 'attributes' => ['arg1' => 'value1'], + ], + [ + 'trace_id' => '10511401530282737729', + 'trace_id_high' => 'ff00000000000517', + 'span_id' => '18374686479671624983', + 'flags' => 0, + ], + ], $traces[0][0]['span_links']); } public function testSpanLinksInteroperabilityRemoval() @@ -1294,7 +1329,15 @@ public function testSpanEventsInteroperabilityFromDatadogSpan() }); $this->assertCount(1, $traces[0]); - $this->assertSame("[{\"name\":\"event-name\",\"time_unix_nano\":1720037568765201300,\"attributes\":{\"arg1\":\"value1\",\"int_array\":[3,4],\"string_array\":[\"5\",\"6\"]}}]", $traces[0][0]['meta']['events']); + $this->assertSame([[ + 'name' => 'event-name', + 'time_unix_nano' => 1720037568765201300, + 'attributes' => [ + 'arg1' => 'value1', + 'int_array' => [3, 4], + 'string_array' => ['5', '6'], + ], + ]], $traces[0][0]['span_events']); } public function testSpanEventsInteroperabilityFromOpenTelemetrySpan() @@ -1326,7 +1369,15 @@ public function testSpanEventsInteroperabilityFromOpenTelemetrySpan() }); $this->assertCount(1, $traces[0]); - $this->assertSame("[{\"name\":\"event-name\",\"time_unix_nano\":1720037568765201300,\"attributes\":{\"arg1\":\"value1\",\"int_array\":[3,4],\"string_array\":[\"5\",\"6\"]}}]", $traces[0][0]['meta']['events']); + $this->assertSame([[ + 'name' => 'event-name', + 'time_unix_nano' => 1720037568765201300, + 'attributes' => [ + 'arg1' => 'value1', + 'int_array' => [3, 4], + 'string_array' => ['5', '6'], + ], + ]], $traces[0][0]['span_events']); } public function testOtelRecordExceptionAttributesSerialization() @@ -1347,7 +1398,7 @@ public function testOtelRecordExceptionAttributesSerialization() $otelSpan->end(); }); - $events = json_decode($traces[0][0]['meta']['events'], true); + $events = $traces[0][0]['span_events']; $this->assertCount(3, $events); $event1 = $events[0]; @@ -1361,10 +1412,10 @@ public function testOtelRecordExceptionAttributesSerialization() $event3 = $events[2]; $this->assertSame('message override', $event3['attributes']['exception.message']); - $this->assertSame(\DDTrace\get_sanitized_exception_trace($lastException), $traces[0][0]['meta']['error.stack']); + $this->assertSame(\DDTrace\get_sanitized_exception_trace($lastException), $traces[0][0]['attributes']['error.stack']); - $this->assertArrayNotHasKey('error.message', $traces[0][0]['meta']); - $this->assertArrayNotHasKey('error.type', $traces[0][0]['meta']); + $this->assertArrayNotHasKey('error.message', $traces[0][0]['attributes']); + $this->assertArrayNotHasKey('error.type', $traces[0][0]['attributes']); $this->assertArrayNotHasKey('error', $traces[0][0]); } @@ -1398,7 +1449,7 @@ public function testExceptionSpanEvents() close_span(); }); - $event = json_decode($traces[0][0]['meta']['events'], true)[0]; + $event = $traces[0][0]['span_events'][0]; $this->assertSame('Test exception message', $event['attributes']['exception.message']); $this->assertSame('Exception', $event['attributes']['exception.type']); diff --git a/tests/OpenTelemetry/Integration/SpanProvenanceTest.php b/tests/OpenTelemetry/Integration/SpanProvenanceTest.php index 3c91add91a8..7ed3e6ff13c 100644 --- a/tests/OpenTelemetry/Integration/SpanProvenanceTest.php +++ b/tests/OpenTelemetry/Integration/SpanProvenanceTest.php @@ -28,6 +28,6 @@ function testOtelSpanMarked() }); $this->assertEquals($traces[0][0]["resource"], "file_get_contents"); $this->assertEquals($traces[0][0]["name"], "internal"); - $this->assertEquals($traces[0][0]["meta"]["component"], "otel.io"); + $this->assertEquals($traces[0][0]["component"], "otel.io"); } } diff --git a/tests/Unit/ConfigurationTest.php b/tests/Unit/ConfigurationTest.php index b40be2a5d9d..884d209b3a3 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/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/WebServer.php b/tests/WebServer.php index 6bac5e863cd..0919d608a26 100644 --- a/tests/WebServer.php +++ b/tests/WebServer.php @@ -120,6 +120,12 @@ public function __construct($indexFile, $host = '0.0.0.0', $port = 80, $ddprofSe $this->ddprofServiceName = $ddprofServiceName; } + // SAPI name of the default web server, which the tracer reports as the root span's default component. + public static function defaultSapiName() + { + return \getenv('DD_TRACE_TEST_SAPI') ?: 'cli-server'; + } + public function setRoadrunner($version) { $this->roadrunnerVersion = $version; diff --git a/tests/ext/active_span.phpt b/tests/ext/active_span.phpt index e08a13ea52b..dea587bfc5c 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 (30) { ["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,49 @@ 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) { - }%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r + } + ["env"]=> + string(0) "" + ["version"]=> + string(0) "" + ["component"]=> + string(0) "" + ["spanKind"]=> + int(0) + ["attributes"]=> + array(2) { + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + float(%f) + } + ["ignoreError"]=> + bool(false)%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 +128,7 @@ object(DDTrace\RootSpanData)#%d (24) { NULL ["inferredSpan"]=> NULL + ["hostname"]=> + string(0) "" } bool(true) 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..d62abff2683 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(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -49,7 +51,7 @@ array(2) { string(49) "add_global_tag_on_userland_and_internal_spans.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["attributes"]=> array(2) { ["alone"]=> string(2) "no" @@ -77,7 +79,7 @@ array(2) { string(49) "add_global_tag_on_userland_and_internal_spans.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["attributes"]=> array(2) { ["alone"]=> string(2) "no" diff --git a/tests/ext/analytics_event.phpt b/tests/ext/analytics_event.phpt new file mode 100644 index 00000000000..07ddd7720ee --- /dev/null +++ b/tests/ext/analytics_event.phpt @@ -0,0 +1,43 @@ +--TEST-- +analytics.event maps to the _dd1.sr.eausr metric, set via $meta or $attributes +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--FILE-- + function ($s) { $s->meta['analytics.event'] = 'true'; }, + 'meta string F' => function ($s) { $s->meta['analytics.event'] = 'F'; }, + 'meta bool true' => function ($s) { $s->meta['analytics.event'] = true; }, + 'attributes bool false' => function ($s) { $s->attributes['analytics.event'] = false; }, + 'attributes float' => function ($s) { $s->attributes['analytics.event'] = 0.5; }, + 'attributes string 1' => function ($s) { $s->attributes['analytics.event'] = '1'; }, + 'invalid string' => function ($s) { $s->meta['analytics.event'] = 'yes'; }, + 'invalid string keeps metric' => function ($s) { $s->meta['analytics.event'] = 'yes'; $s->metrics['_dd1.sr.eausr'] = 0.25; }, + 'valid value wins over metric' => function ($s) { $s->meta['analytics.event'] = 'true'; $s->metrics['_dd1.sr.eausr'] = 0; }, + 'metric only' => function ($s) { $s->metrics['_dd1.sr.eausr'] = 0.75; }, +]; +foreach ($cases as $name => $set) { + $s = \DDTrace\start_span(); + $s->name = $name; + $set($s); + \DDTrace\close_span(); +} +foreach (dd_trace_serialize_closed_spans() as $span) { + $attrs = $span['attributes']; + echo $span['name'], ': eausr=', var_export(isset($attrs['_dd1.sr.eausr']) ? $attrs['_dd1.sr.eausr'] : null, true), + ' analytics.event=', isset($attrs['analytics.event']) ? 'kept' : 'removed', "\n"; +} +?> +--EXPECT-- +metric only: eausr=0.75 analytics.event=removed +valid value wins over metric: eausr=1.0 analytics.event=removed +invalid string keeps metric: eausr=0.25 analytics.event=removed +invalid string: eausr=NULL analytics.event=removed +attributes string 1: eausr=1.0 analytics.event=removed +attributes float: eausr=0.5 analytics.event=removed +attributes bool false: eausr=0.0 analytics.event=removed +meta bool true: eausr=1.0 analytics.event=removed +meta string F: eausr=0.0 analytics.event=removed +meta string true: eausr=1.0 analytics.event=removed 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/background-sender/agent_headers.phpt b/tests/ext/background-sender/agent_headers.phpt index 75c4120b047..a5c8ca510d7 100644 --- a/tests/ext/background-sender/agent_headers.phpt +++ b/tests/ext/background-sender/agent_headers.phpt @@ -1,6 +1,7 @@ --TEST-- HTTP headers are sent to the Agent from the background sender --SKIPIF-- + --ENV-- DD_TRACE_LOG_LEVEL=info,startup=off @@ -10,6 +11,7 @@ DD_TRACE_AGENT_FLUSH_AFTER_N_REQUESTS=1 DD_TRACE_AGENT_FLUSH_INTERVAL=666 DD_TRACE_GENERATE_ROOT_SPAN=0 DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 --INI-- datadog.trace.agent_test_session_token=background-sender/agent_headers --FILE-- @@ -39,7 +41,7 @@ echo 'Done.' . PHP_EOL; ?> --EXPECTF-- -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for http://request-replayer:80 +[ddtrace] [info] [%d] Flushing %d v0.4 trace(s) to send-queue for http://request-replayer:80 content-type: application/msgpack datadog-meta-lang: php diff --git a/tests/ext/background-sender/agent_headers_container_id.phpt b/tests/ext/background-sender/agent_headers_container_id.phpt index 6442f0c7bfa..8251c40442e 100644 --- a/tests/ext/background-sender/agent_headers_container_id.phpt +++ b/tests/ext/background-sender/agent_headers_container_id.phpt @@ -12,6 +12,7 @@ DD_TRACE_AGENT_FLUSH_AFTER_N_REQUESTS=1 DD_TRACE_AGENT_FLUSH_INTERVAL=666 DD_TRACE_GENERATE_ROOT_SPAN=0 DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 --INI-- ddtrace.cgroup_file={PWD}/stubs/cgroup.docker datadog.trace.agent_test_session_token=background-sender/agent_headers_container_id @@ -38,7 +39,7 @@ echo 'Done.' . PHP_EOL; ?> --EXPECTF-- -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for http://request-replayer:80 +[ddtrace] [info] [%d] Flushing %d v0.4 trace(s) to send-queue for http://request-replayer:80 datadog-container-id:%s9d5b23edb1ba181e8910389a99906598d69ac9a0ead109ee55730cc416d95f7f datadog-meta-lang: php diff --git a/tests/ext/background-sender/agent_headers_container_id_empty.phpt b/tests/ext/background-sender/agent_headers_container_id_empty.phpt index c54653abee0..cce106108da 100644 --- a/tests/ext/background-sender/agent_headers_container_id_empty.phpt +++ b/tests/ext/background-sender/agent_headers_container_id_empty.phpt @@ -1,6 +1,7 @@ --TEST-- An empty container ID is not sent via HTTP headers to the Agent --SKIPIF-- + --ENV-- DD_TRACE_LOG_LEVEL=info,startup=off @@ -38,7 +39,7 @@ echo 'Done.' . PHP_EOL; ?> --EXPECTF-- -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for http://request-replayer:80 +[ddtrace] [info] [%d] Flushing %d v0.4 trace(s) to send-queue for http://request-replayer:80 datadog-meta-lang: php diff --git a/tests/ext/background-sender/agent_headers_container_id_fargate.phpt b/tests/ext/background-sender/agent_headers_container_id_fargate.phpt index fa4fccffb7e..f4dc2817feb 100644 --- a/tests/ext/background-sender/agent_headers_container_id_fargate.phpt +++ b/tests/ext/background-sender/agent_headers_container_id_fargate.phpt @@ -12,6 +12,7 @@ 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 +DD_TRACE_SIDECAR_TRACE_SENDER=0 --INI-- ddtrace.cgroup_file={PWD}/stubs/cgroup.fargate.1.4 datadog.trace.agent_test_session_token=background-sender/agent_headers_container_id_fargate @@ -37,7 +38,7 @@ echo 'Done.' . PHP_EOL; ?> --EXPECTF-- -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for http://request-replayer:80 +[ddtrace] [info] [%d] Flushing %d v0.4 trace(s) to send-queue for http://request-replayer:80 datadog-container-id:%s34dc0b5e626f2c5c4c5170e34b10e765-1234567890 datadog-meta-lang: php 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/agent_headers_unix_domain_socket.phpt b/tests/ext/background-sender/agent_headers_unix_domain_socket.phpt index 040b4d15b2f..816a9516786 100644 --- a/tests/ext/background-sender/agent_headers_unix_domain_socket.phpt +++ b/tests/ext/background-sender/agent_headers_unix_domain_socket.phpt @@ -11,6 +11,7 @@ DD_TRACE_AGENT_FLUSH_INTERVAL=333 DD_TRACE_GENERATE_ROOT_SPAN=0 DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 DD_REMOTE_CONFIG_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 --INI-- datadog.trace.agent_test_session_token=background-sender/agent_headers_unix_domain_socket --FILE-- diff --git a/tests/ext/background-sender/agent_sampling.phpt b/tests/ext/background-sender/agent_sampling.phpt index fe32799f15a..d6f9194f757 100644 --- a/tests/ext/background-sender/agent_sampling.phpt +++ b/tests/ext/background-sender/agent_sampling.phpt @@ -2,6 +2,7 @@ The background sender informs about changes to the agent sample rate --SKIPIF-- @@ -59,10 +60,10 @@ echo "Specific sampling: {$get_sampling()}\n"; ?> --EXPECTF-- -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for http://request-replayer:80 +[ddtrace] [info] [%d] Flushing 1 v0.4 trace(s) to send-queue for http://request-replayer:80 Initial sampling: 1 -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for http://request-replayer:80 +[ddtrace] [info] [%d] Flushing 1 v0.4 trace(s) to send-queue for http://request-replayer:80 Generic sampling: 0 -[ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for http://request-replayer:80 +[ddtrace] [info] [%d] Flushing 1 v0.4 trace(s) to send-queue for http://request-replayer:80 Specific sampling: 1 [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/base_service.phpt b/tests/ext/base_service.phpt index a775ec2358f..146041e8b8b 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(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -37,12 +39,12 @@ array(1) { string(7) "changed" ["type"]=> string(3) "cli" - ["meta"]=> + ["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/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/close_spans_until.phpt b/tests/ext/close_spans_until.phpt index f2247f99c5b..591cfd918d8 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_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_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/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_meta_struct_int_key.phpt b/tests/ext/dd_trace_serialize_msgpack_meta_struct_int_key.phpt deleted file mode 100644 index e73c2b2e957..00000000000 --- a/tests/ext/dd_trace_serialize_msgpack_meta_struct_int_key.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -dd_trace_serialize_msgpack() counts only the meta_struct entries it writes ---DESCRIPTION-- -Integer keys in meta_struct are skipped, so the map must not count them. ---FILE-- - ["a" => "x", 0 => "y"], -]]]; - -echo implode(' ', str_split(bin2hex(dd_trace_serialize_msgpack($traces)), 2)), "\n"; -?> ---EXPECT-- -91 91 81 ab 6d 65 74 61 5f 73 74 72 75 63 74 81 a1 61 c4 01 78 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..2740be69277 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 native 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 native span_links). + $span->links = [$secondLink]; } ); @@ -39,31 +43,20 @@ 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 (native top-level span_links), which is the real wire path. +var_dump($spans[0]); +var_dump($spans[1]['name'], $spans[1]['span_links']); +var_dump($spans[2]['name'], $spans[2]['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) { +array(11) { ["trace_id"]=> string(20) "13930160852258120406" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(19) "2513787319205155662" ["parent_id"]=> @@ -80,9 +73,57 @@ 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_links"]=> + array(2) { + [0]=> + array(4) { + ["trace_id"]=> + string(20) "13930160852258120406" + ["trace_id_high"]=> + string(16) "%s" + ["span_id"]=> + string(20) "11788048577503494824" + ["flags"]=> + int(0) + } + [1]=> + array(4) { + ["trace_id"]=> + string(20) "13930160852258120406" + ["trace_id_high"]=> + string(16) "%s" + ["span_id"]=> + string(20) "13874630024467741450" + ["flags"]=> + int(0) + } + } +} +string(3) "bar" +array(1) { + [0]=> + array(4) { + ["trace_id"]=> + string(20) "13930160852258120406" + ["trace_id_high"]=> + string(16) "%s" + ["span_id"]=> + string(20) "13874630024467741450" + ["flags"]=> + int(0) + } +} +string(3) "foo" +array(1) { + [0]=> + array(4) { + ["trace_id"]=> + string(20) "13930160852258120406" + ["trace_id_high"]=> + string(16) "%s" + ["span_id"]=> + string(20) "11788048577503494824" + ["flags"]=> + int(0) } } diff --git a/tests/ext/dd_trace_span_link_event_native_nested_attributes.phpt b/tests/ext/dd_trace_span_link_event_native_nested_attributes.phpt new file mode 100644 index 00000000000..2c6e2409470 --- /dev/null +++ b/tests/ext/dd_trace_span_link_event_native_nested_attributes.phpt @@ -0,0 +1,62 @@ +--TEST-- +Span link and event array/object attributes serialize as native nested V1 attributes +--ENV-- +DD_TRACE_DEBUG_PRNG_SEED=42 +--FILE-- +name = 'foo'; + + // A link whose attributes include an array and a nested object/map. Before Phase 3 these were + // json_encode()'d to a string; they must now round-trip as native nested attributes. + $link = new SpanLink(); + $link->traceId = "42"; + $link->spanId = "6"; + $link->attributes = ['nums' => [3, 4], 'nested' => ['k' => 'v']]; + $span->links[] = $link; + + // Same for an event. + $span->events[] = new SpanEvent('evt', ['arr' => [3, 4], 'obj' => ['k' => 'v']], 1); +}); + +foo(); + +$spans = dd_clean_spans(); +$link = $spans[0]['span_links'][0]; +$event = $spans[0]['span_events'][0]; + +// Native nested shape: lists become packed arrays (typed leaves preserved), maps become assoc arrays. +var_dump($link['attributes']['nums']); +var_dump($link['attributes']['nested']); +var_dump($event['attributes']['arr']); +var_dump($event['attributes']['obj']); + +?> +--EXPECT-- +array(2) { + [0]=> + int(3) + [1]=> + int(4) +} +array(1) { + ["k"]=> + string(1) "v" +} +array(2) { + [0]=> + int(3) + [1]=> + int(4) +} +array(1) { + ["k"]=> + string(1) "v" +} 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..7a55657c358 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(13) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -47,39 +47,36 @@ array(2) { string(39) "distributed_trace_asm_standalone_01.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(6) { - ["_dd.origin"]=> - string(7) "datadog" + ["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(10) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -98,12 +95,7 @@ array(2) { string(39) "distributed_trace_asm_standalone_01.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(1) { - ["_dd.origin"]=> - string(7) "datadog" - } - ["metrics"]=> + ["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..4fbf2826724 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(13) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -47,35 +47,32 @@ 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" + ["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(10) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -94,12 +91,7 @@ array(2) { string(39) "distributed_trace_asm_standalone_02.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(1) { - ["_dd.origin"]=> - string(7) "datadog" - } - ["metrics"]=> + ["attributes"]=> array(1) { ["_dd.apm.enabled"]=> float(0) 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_bogus_ids.phpt b/tests/ext/distributed_tracing/distributed_trace_bogus_ids.phpt index b5b61f87fce..b8070bee42a 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(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -38,30 +40,25 @@ 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" + ["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..dba77a081c7 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(13) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -46,37 +46,34 @@ array(2) { string(29) "distributed_trace_inherit.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(6) { - ["_dd.origin"]=> - string(7) "datadog" + ["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(9) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -95,10 +92,5 @@ array(2) { string(29) "distributed_trace_inherit.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(1) { - ["_dd.origin"]=> - string(7) "datadog" - } } } 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 10bc4e9a015..61b4a9eb80d 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"], $span["meta"]["_dd.sdk.otlp_export"]); - 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.sdk.otlp_export"], + $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; } @@ -98,7 +113,7 @@ array(7) { } bool(true) parent: 321, trace: 123, meta: {"_dd.origin":"foo","a":"b"} -parent: %d, trace: 123, meta: {"_dd.origin":"foo"} +parent: %d, trace: 123, meta: [] bool(true) array(5) { ["trace_id"]=> diff --git a/tests/ext/do_not_check_if_class_or_function_exists_by_default.phpt b/tests/ext/do_not_check_if_class_or_function_exists_by_default.phpt index f094385b51c..fe26a0e6855 100644 --- a/tests/ext/do_not_check_if_class_or_function_exists_by_default.phpt +++ b/tests/ext/do_not_check_if_class_or_function_exists_by_default.phpt @@ -1,7 +1,5 @@ --TEST-- Do not throw exceptions when veryfying if class/method and function exists. ---ENV-- -DD_TRACE_WARN_LEGACY_DD_TRACE=0 --FILE-- name = "http.request"; +$s->service = "web"; +\DDTrace\close_span(); + +$spans = dd_trace_serialize_closed_spans(); +$root = $spans[0]; +// env/version promoted from the DD_TAGS-sourced meta fallback; deleted from the unified +// attributes map once promoted to the dedicated top-level fields. +echo "env=" . var_export($root["env"] ?? null, true) . "\n"; +echo "version=" . var_export($root["version"] ?? null, true) . "\n"; +echo "attributes.env=" . var_export($root["attributes"]["env"] ?? null, true) . "\n"; +echo "attributes.version=" . var_export($root["attributes"]["version"] ?? null, true) . "\n"; +?> +--EXPECT-- +env='staging' +version='1.2.3' +attributes.env=NULL +attributes.version=NULL 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 69d8ad24e0a..f503b5beb53 100644 --- a/tests/ext/extract_server_values.phpt +++ b/tests/ext/extract_server_values.phpt @@ -27,21 +27,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(6) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.sdk.otlp_export"]=> - string(5) "false" - ["_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/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/force_flush_traces.phpt b/tests/ext/force_flush_traces.phpt index 252758568b3..e3b5d8bd43b 100644 --- a/tests/ext/force_flush_traces.phpt +++ b/tests/ext/force_flush_traces.phpt @@ -44,5 +44,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 745924ce7ea..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"; } @@ -32,7 +32,6 @@ function test_endpoint($path) { } else { echo "Path: $path - No spans\n\n"; } - dd_trace_reset(); } // Test invalid inputs and root @@ -95,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/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..710e509a4cd 100644 --- a/tests/ext/inferred_proxy/alter_service.phpt +++ b/tests/ext/inferred_proxy/alter_service.phpt @@ -51,24 +51,24 @@ 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", + "component": "cgi-fcgi", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "process_id": %d, "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { "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,21 +76,18 @@ 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", + "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, "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "http.status_code": "200", + "_dd.agent_psr": 1 } }, { @@ -103,9 +100,7 @@ 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" } -] \ 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..331851110d6 100644 --- a/tests/ext/inferred_proxy/basic_test.phpt +++ b/tests/ext/inferred_proxy/basic_test.phpt @@ -68,25 +68,25 @@ 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", + "component": "cgi-fcgi", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "process_id": %d, + "foo": "bar", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { "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,21 +94,18 @@ 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", + "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, "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "http.status_code": "200", + "_dd.agent_psr": 1 } }, { @@ -121,9 +118,7 @@ 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" } -]Duration is within 0.01% of expected duration \ No newline at end of file +]Duration is within 0.01% of expected duration diff --git a/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt b/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt index 4023bf9f6b2..f6da750f554 100644 --- a/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt +++ b/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt @@ -56,21 +56,20 @@ 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", + "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,20 +77,17 @@ 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", + "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 } }, { @@ -104,9 +100,7 @@ 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" } -] \ 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..eb29334b900 100644 --- a/tests/ext/inferred_proxy/distributed_tracing.phpt +++ b/tests/ext/inferred_proxy/distributed_tracing.phpt @@ -58,22 +58,20 @@ 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", + "component": "cgi-fcgi", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "process_id": %d, + "foo": "bar", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { "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 +84,18 @@ 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", + "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" } }, { @@ -113,10 +108,7 @@ 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" } -] \ 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..59c066fbad1 100644 --- a/tests/ext/inferred_proxy/error_propagated.phpt +++ b/tests/ext/inferred_proxy/error_propagated.phpt @@ -61,27 +61,27 @@ 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", + "component": "cgi-fcgi", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "process_id": %d, "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}", "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 +90,21 @@ 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", + "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, "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "http.status_code": "500", + "error.type": "Exception", + "_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..970b47ce63e 100644 --- a/tests/ext/inferred_proxy/fallback_service_name.phpt +++ b/tests/ext/inferred_proxy/fallback_service_name.phpt @@ -52,25 +52,25 @@ 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", + "component": "cgi-fcgi", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "process_id": %d, + "foo": "bar", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { "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,20 +78,17 @@ 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", + "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, "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "http.status_code": "200", + "_dd.agent_psr": 1 } }, { @@ -104,9 +101,7 @@ 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" } -] \ 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..900be82425e 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,27 +45,25 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "aws-server", "type": "web", - "meta": { + "env": "local-prod", + "version": "1.0", + "component": "cgi-fcgi", + "span_kind": 2, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", + "http.method": "GET", + "process_id": %d, + "_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": { "_dd.agent_psr": 1, - "_sampling_priority_v1": 1, + "http.status_code": "200", "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 } }, { @@ -77,9 +76,7 @@ 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" } -] \ 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..85f9bb78285 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,24 +55,22 @@ 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", - "http.method": "GET", - "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", + "env": "local-prod", + "version": "1.0", + "component": "cgi-fcgi", + "span_kind": 2, + "sampling_priority": 1, + "sampling_mechanism": 0, + "attributes": { "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { + "http.url": "http:\/\/localhost:8888\/foo", + "http.method": "GET", + "process_id": %d, "_dd.agent_psr": 1, - "_sampling_priority_v1": 1, + "http.status_code": "200", "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,24 +83,24 @@ 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", + "component": "cgi-fcgi", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "process_id": %d, "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { "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,21 +108,18 @@ 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", + "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, "_dd.inferred_span": 1, - "_sampling_priority_v1": 1 + "http.status_code": "200", + "_dd.agent_psr": 1 } }, { @@ -136,9 +132,7 @@ 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" } -] \ 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..c9ddbba259f 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,21 @@ 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", + "component": "cgi-fcgi", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "process_id": %d, + "_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": { "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 +82,20 @@ 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", + "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" } } -] \ 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..598989147f9 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,21 @@ 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", + "component": "cgi-fcgi", + "span_kind": 2, + "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", + "process_id": %d, "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server", - "version": "1.0" - }, - "metrics": { "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 +81,20 @@ 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", + "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" } } -] \ 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..90be2db7999 100644 --- a/tests/ext/inferred_proxy/sampling_rules.phpt +++ b/tests/ext/inferred_proxy/sampling_rules.phpt @@ -48,23 +48,23 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "foo", "type": "web", - "meta": { - "_dd.p.ksr": "0.3", + "component": "cgi-fcgi", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", "http.method": "GET", + "process_id": %d, + "_dd.p.ksr": "0.3", "http.status_code": "200", - "http.url": "http:\/\/localhost:8888\/foo", - "runtime-id": "%s", - "span.kind": "server" - }, - "metrics": { "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 +72,17 @@ 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", + "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", "_dd.inferred_span": 1, + "http.status_code": "200", "_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/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/inferred_proxy/serialization-sampling-chunk.phpt b/tests/ext/inferred_proxy/serialization-sampling-chunk.phpt index 23d77530908..e8e1de6e0a6 100644 --- a/tests/ext/inferred_proxy/serialization-sampling-chunk.phpt +++ b/tests/ext/inferred_proxy/serialization-sampling-chunk.phpt @@ -25,16 +25,16 @@ class ChangeSamplingDuringSerialization { $root = DDTrace\start_span(); $root->name = 'keep.root'; -$root->metrics['http.status_code'] = new ChangeSamplingDuringSerialization(); +$root->attributes['http.status_code'] = new ChangeSamplingDuringSerialization(); DDTrace\close_span(); foreach (dd_trace_serialize_closed_spans() as $span) { echo $span['name'], "\n"; - if (isset($span['metrics']['_dd.span_sampling.mechanism'])) { - echo 'single span: ', $span['metrics']['_dd.span_sampling.mechanism'], "\n"; + if (isset($span['attributes']['_dd.span_sampling.mechanism'])) { + echo 'single span: ', $span['attributes']['_dd.span_sampling.mechanism'], "\n"; } - if (isset($span['metrics']['_sampling_priority_v1'])) { - echo 'trace priority: ', $span['metrics']['_sampling_priority_v1'], "\n"; + if (isset($span['sampling_priority'])) { + echo 'trace priority: ', $span['sampling_priority'], "\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/curl/distributed_tracing_curl.phpt b/tests/ext/integrations/curl/distributed_tracing_curl.phpt index 3484ebedcf6..bc2ae49254b 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl.phpt @@ -47,7 +47,7 @@ var_dump($headers['x-datadog-parent-id'] === (string) $spans[0]['span_id']); var_dump(abs(hexdec($headers['x-b3-spanid']) - $spans[0]['span_id']) < (1 << 13)); var_dump(abs(hexdec($headers['x-b3-traceid']) - $headers['x-datadog-trace-id']) < (1 << 13)); var_dump($headers['b3'] == "{$headers['x-b3-traceid']}-{$headers['x-b3-spanid']}-1"); -var_dump($spans[0]["meta"]["_dd.propagation_error"]); +var_dump($spans[0]["attributes"]["_dd.propagation_error"]); echo 'Done.' . PHP_EOL; diff --git a/tests/ext/integrations/curl/distributed_tracing_curl_copy_handle.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_copy_handle.phpt index 8214b7c9f61..85f876fcee9 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_copy_handle.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_copy_handle.phpt @@ -95,4 +95,4 @@ x-datadog-trace-id: %d x-foo: after-the-copy Done. -[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 diff --git a/tests/ext/integrations/curl/distributed_tracing_curl_drop_dm.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_drop_dm.phpt index f3e19fc36e0..10cc6280b8c 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_drop_dm.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_drop_dm.phpt @@ -35,7 +35,7 @@ dt_dump_headers_from_httpbin($headers, [ ]); $spans = dd_trace_serialize_closed_spans(); -var_dump(isset($spans[0]["meta"]["_dd.propagation_error"])); +var_dump(isset($spans[0]["attributes"]["_dd.propagation_error"])); echo 'Done.' . PHP_EOL; diff --git a/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_001.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_001.phpt index e39edbc762e..4adb416e777 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_001.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_001.phpt @@ -65,4 +65,4 @@ x-mas: tree x-my-custom-header: foo Done. -[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 diff --git a/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_002.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_002.phpt index 2f7b20fb70e..508bd9faa93 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_002.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_002.phpt @@ -65,4 +65,4 @@ x-mas: tree x-my-custom-header: foo Done. -[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 diff --git a/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_003.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_003.phpt index 2509206ca49..b8927bf9d01 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_003.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_existing_headers_003.phpt @@ -82,4 +82,4 @@ x-datadog-parent-id: %d x-orig-header: foo Done. -[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 diff --git a/tests/ext/integrations/curl/distributed_tracing_curl_invalid_tags.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_invalid_tags.phpt index 134d2b895b2..cd5f6f99a24 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_invalid_tags.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_invalid_tags.phpt @@ -35,7 +35,7 @@ dt_dump_headers_from_httpbin($headers, [ ]); $spans = dd_trace_serialize_closed_spans(); -var_dump(isset($spans[0]["meta"]["_dd.propagation_error"])); +var_dump(isset($spans[0]["attributes"]["_dd.propagation_error"])); echo 'Done.' . PHP_EOL; diff --git a/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_001.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_001.phpt index 5d6ac75c126..011dab40ecf 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_001.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_001.phpt @@ -72,4 +72,4 @@ x-datadog-parent-id: %d x-datadog-origin: phpt-test x-datadog-parent-id: %d Done. -[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/integrations/curl/distributed_tracing_curl_multi_exec_002.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_002.phpt index 79b4472761b..b1534007226 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_002.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_002.phpt @@ -73,4 +73,4 @@ x-datadog-parent-id: %d x-datadog-origin: phpt-test x-datadog-parent-id: %d Done. -[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/integrations/curl/distributed_tracing_curl_multi_exec_003.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_003.phpt index 253fb227705..63f0c6bad51 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_003.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_003.phpt @@ -74,4 +74,4 @@ x-datadog-parent-id: %d x-datadog-origin: phpt-test x-datadog-parent-id: %d Done. -[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/integrations/curl/distributed_tracing_curl_multi_exec_copy_handle.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_copy_handle.phpt index 83312123873..da8389ef5b3 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_copy_handle.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_copy_handle.phpt @@ -91,4 +91,4 @@ x-datadog-origin: phpt-test x-datadog-parent-id: %d x-foo: not copied Done. -[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/integrations/curl/distributed_tracing_curl_multi_exec_existing_headers_001.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_existing_headers_001.phpt index c8597de99b4..8e1c77dc6ca 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_existing_headers_001.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_existing_headers_001.phpt @@ -88,4 +88,4 @@ x-ch-2-foo: foo x-datadog-origin: phpt-test x-datadog-parent-id: %d Done. -[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/integrations/curl/distributed_tracing_curl_multi_exec_existing_headers_002.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_existing_headers_002.phpt index da71329a71f..1e185300c9f 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_existing_headers_002.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_multi_exec_existing_headers_002.phpt @@ -92,4 +92,4 @@ x-ch-2-foo: foo x-datadog-origin: phpt-test x-datadog-parent-id: %d Done. -[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/integrations/curl/distributed_tracing_curl_tracestate.phpt b/tests/ext/integrations/curl/distributed_tracing_curl_tracestate.phpt index 3fdf84c3860..9c58e95ee65 100644 --- a/tests/ext/integrations/curl/distributed_tracing_curl_tracestate.phpt +++ b/tests/ext/integrations/curl/distributed_tracing_curl_tracestate.phpt @@ -35,7 +35,7 @@ dt_dump_headers_from_httpbin($headers, [ ]); $spans = dd_trace_serialize_closed_spans(); -var_dump(isset($spans[0]["meta"]["_dd.propagation_error"])); +var_dump(isset($spans[0]["attributes"]["_dd.propagation_error"])); echo 'Done.' . PHP_EOL; diff --git a/tests/ext/integrations/drupal/drupal_integration.inc b/tests/ext/integrations/drupal/drupal_integration.inc index e065e051666..55e48eb018c 100644 --- a/tests/ext/integrations/drupal/drupal_integration.inc +++ b/tests/ext/integrations/drupal/drupal_integration.inc @@ -38,10 +38,10 @@ function dd_drupal_render_report(array $spans, array $probeTargets) if ($span['name'] !== 'drupal.theme.render') { continue; } - $file = isset($span['meta']['drupal.template.file']) ? $span['meta']['drupal.template.file'] : ''; + $file = isset($span['attributes']['drupal.template.file']) ? $span['attributes']['drupal.template.file'] : ''; $tags[$file] = (isset($tags[$file]) ? $tags[$file] : 0) + 1; // Also reported so that a begin hook exception swallowed by the sandbox cannot pass silently. - $engine = isset($span['meta']['drupal.render.engine']) ? $span['meta']['drupal.render.engine'] : ''; + $engine = isset($span['attributes']['drupal.render.engine']) ? $span['attributes']['drupal.render.engine'] : ''; $engines[$engine] = (isset($engines[$engine]) ? $engines[$engine] : 0) + 1; } ksort($tags); diff --git a/tests/ext/integrations/drupal/theme_engine_service_dropped_nested_span.phpt b/tests/ext/integrations/drupal/theme_engine_service_dropped_nested_span.phpt index f4024575b61..001c4a758f7 100644 --- a/tests/ext/integrations/drupal/theme_engine_service_dropped_nested_span.phpt +++ b/tests/ext/integrations/drupal/theme_engine_service_dropped_nested_span.phpt @@ -114,7 +114,7 @@ namespace continue; } echo "surviving render span template.file = ", - isset($span['meta']['drupal.template.file']) ? $span['meta']['drupal.template.file'] : '', + isset($span['attributes']['drupal.template.file']) ? $span['attributes']['drupal.template.file'] : '', "\n"; } dd_drupal_render_report($spans, ['Drupal\Core\Template\TwigThemeEngine::renderTemplate']); diff --git a/tests/ext/integrations/drupal/theme_render_dropped_nested_span.phpt b/tests/ext/integrations/drupal/theme_render_dropped_nested_span.phpt index 21323d191d0..8676b380170 100644 --- a/tests/ext/integrations/drupal/theme_render_dropped_nested_span.phpt +++ b/tests/ext/integrations/drupal/theme_render_dropped_nested_span.phpt @@ -86,7 +86,7 @@ namespace continue; } echo "surviving render span template.file = ", - isset($span['meta']['drupal.template.file']) ? $span['meta']['drupal.template.file'] : '', + isset($span['attributes']['drupal.template.file']) ? $span['attributes']['drupal.template.file'] : '', "\n"; } dd_drupal_render_report($spans, ['twig_render_template']); diff --git a/tests/ext/integrations/http_streams/distributed_tracing_http_streams.phpt b/tests/ext/integrations/http_streams/distributed_tracing_http_streams.phpt index cfa41ac6309..c8267cd2e96 100644 --- a/tests/ext/integrations/http_streams/distributed_tracing_http_streams.phpt +++ b/tests/ext/integrations/http_streams/distributed_tracing_http_streams.phpt @@ -50,8 +50,12 @@ echo "resource: " . $span['resource'] . "\n"; echo "type: " . $span['type'] . "\n"; echo "service: " . $span['service'] . "\n"; echo "meta:\n"; -ksort($span['meta']); -foreach ($span['meta'] as $k => $v) { +// The v1 introspection shape merges meta+metrics into a single attributes map and +// promotes component/span.kind to top-level fields; keep the string tags to preserve +// this test's historical meta view. +$attrs = array_filter($span['attributes'], 'is_string'); +ksort($attrs); +foreach ($attrs as $k => $v) { echo " $k: $v\n"; } @@ -72,10 +76,8 @@ resource: %s type: cli service: %s meta: - component: php.stream http.method: GET http.url: http://%s:%d/headers network.destination.name: %s - span.kind: client Done. [ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/integrations/http_streams/distributed_tracing_http_streams_with_headers_array.phpt b/tests/ext/integrations/http_streams/distributed_tracing_http_streams_with_headers_array.phpt index 98cb4604ab6..7da44b660c4 100644 --- a/tests/ext/integrations/http_streams/distributed_tracing_http_streams_with_headers_array.phpt +++ b/tests/ext/integrations/http_streams/distributed_tracing_http_streams_with_headers_array.phpt @@ -93,4 +93,4 @@ x-datadog-trace-id: %d x-foo: two Done. -[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 diff --git a/tests/ext/integrations/http_streams/distributed_tracing_http_streams_with_headers_string.phpt b/tests/ext/integrations/http_streams/distributed_tracing_http_streams_with_headers_string.phpt index a2acac25e60..2f485057ed7 100644 --- a/tests/ext/integrations/http_streams/distributed_tracing_http_streams_with_headers_string.phpt +++ b/tests/ext/integrations/http_streams/distributed_tracing_http_streams_with_headers_string.phpt @@ -85,4 +85,4 @@ x-datadog-trace-id: %d x-foo: two Done. -[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 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/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..3a41aa29f6b 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) { + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) ["_dd.git.repository_url"]=> string(32) "https://github.com/user/repo_new" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["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) { + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) ["_dd.git.repository_url"]=> string(32) "https://github.com/user/repo_new" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["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) { + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) ["_dd.git.repository_url"]=> string(32) "https://github.com/user/repo_new" - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["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" + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) + ["_dd.git.repository_url"]=> + string(32) "https://github.com/user/repo_new" + ["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..5b8534a25c3 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -40,30 +42,25 @@ 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" + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(7) { ["runtime-id"]=> string(%d) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) + ["_dd.git.commit.sha"]=> + string(6) "123456" ["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/integrations/source_code/git_metadata_injection_from_env.phpt b/tests/ext/integrations/source_code/git_metadata_injection_from_env.phpt index d420f7f4b7b..ea9e02e4c07 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -41,33 +43,28 @@ array(2) { string(35) "git_metadata_injection_from_env.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(5) { + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(8) { + ["runtime-id"]=> + string(%d) "%s" + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) ["_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) { - ["_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]=> @@ -91,4 +88,4 @@ array(2) { ["type"]=> string(3) "cli" } -} \ 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..d5057ea5445 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -40,37 +42,32 @@ 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" + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(10) { + ["runtime-id"]=> + string(%d) "%s" + ["process_id"]=> + float(%f) ["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.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) + ["_dd.git.commit.sha"]=> + string(6) "123456" + ["_dd.git.repository_url"]=> + string(24) "github.com/user/env_repo" ["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]=> @@ -93,7 +90,7 @@ array(2) { string(43) "git_metadata_injection_from_global_tags.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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..7357f811ffb 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -41,33 +43,28 @@ array(2) { string(54) "git_metadata_injection_remove_credentials_from_env.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(5) { + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(8) { + ["runtime-id"]=> + string(%d) "%s" + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) ["_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) { - ["_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]=> 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..638bcf947aa 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -40,31 +42,26 @@ 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" + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(7) { ["runtime-id"]=> string(%d) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) ["_dd.agent_psr"]=> float(1) - ["_sampling_priority_v1"]=> - float(1) + ["_dd.git.repository_url"]=> + string(24) "github.com/user/env_repo" ["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]=> diff --git a/tests/ext/ip_collection_01.phpt b/tests/ext/ip_collection_01.phpt index a92a5d91e8a..80efa5465c4 100644 --- a/tests/ext/ip_collection_01.phpt +++ b/tests/ext/ip_collection_01.phpt @@ -8,7 +8,7 @@ REMOTE_ADDR=127.0.0.1 DDTrace\start_span(); DDTrace\close_span(0); $span = dd_trace_serialize_closed_spans(); -var_dump(isset($span[0]["meta"]["http.client_ip"])); +var_dump(isset($span[0]["attributes"]["http.client_ip"])); ?> --EXPECTF-- bool(false) diff --git a/tests/ext/ip_collection_02.phpt b/tests/ext/ip_collection_02.phpt index b73dca0798e..0ad7dea2256 100644 --- a/tests/ext/ip_collection_02.phpt +++ b/tests/ext/ip_collection_02.phpt @@ -8,7 +8,7 @@ REMOTE_ADDR=127.0.0.1 DDTrace\start_span(); DDTrace\close_span(0); $span = dd_trace_serialize_closed_spans(); -var_dump(isset($span[0]["meta"]["http.client_ip"])); +var_dump(isset($span[0]["attributes"]["http.client_ip"])); ?> --EXPECTF-- bool(false) 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/ip_collection_04.phpt b/tests/ext/ip_collection_04.phpt index 33d734344ae..699d0bd462f 100644 --- a/tests/ext/ip_collection_04.phpt +++ b/tests/ext/ip_collection_04.phpt @@ -10,7 +10,7 @@ datadog.trace.client_ip_header_disabled=true DDTrace\start_span(); DDTrace\close_span(0); $span = dd_trace_serialize_closed_spans(); -var_dump(isset($span[0]["meta"]["http.client_ip"])); +var_dump(isset($span[0]["attributes"]["http.client_ip"])); ?> --EXPECTF-- bool(false) diff --git a/tests/ext/ip_collection_05.phpt b/tests/ext/ip_collection_05.phpt index 33d734344ae..699d0bd462f 100644 --- a/tests/ext/ip_collection_05.phpt +++ b/tests/ext/ip_collection_05.phpt @@ -10,7 +10,7 @@ datadog.trace.client_ip_header_disabled=true DDTrace\start_span(); DDTrace\close_span(0); $span = dd_trace_serialize_closed_spans(); -var_dump(isset($span[0]["meta"]["http.client_ip"])); +var_dump(isset($span[0]["attributes"]["http.client_ip"])); ?> --EXPECTF-- bool(false) 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/live-debugger/debugger_span_decoration_probe.phpt b/tests/ext/live-debugger/debugger_span_decoration_probe.phpt index e94a93f1dbc..a3ababbe416 100644 --- a/tests/ext/live-debugger/debugger_span_decoration_probe.phpt +++ b/tests/ext/live-debugger/debugger_span_decoration_probe.phpt @@ -23,14 +23,14 @@ if (!dd_trace_internal_fn("await_agent_info")) { } function &foo($arg) { - $meta = &\DDTrace\active_span()->meta; + $meta = &\DDTrace\active_span()->attributes; unset($meta["runtime-id"]); return $meta; } function &root($arg) { - $meta = &\DDTrace\root_span()->meta; - unset($meta["runtime-id"]); + $meta = &\DDTrace\root_span()->attributes; + unset($meta["runtime-id"], $meta["process_id"]); return $arg; } @@ -53,13 +53,13 @@ await_probe_installation(function() { \DDTrace\start_span(); var_dump(foo(["foo" => (object)["var" => 1, "val" => "test"], "val" => 123])); -\DDTrace\active_span()->meta = []; +\DDTrace\active_span()->attributes = []; $meta = foo(["foo" => (object)["var" => 2]]); ksort($meta); var_dump($meta); root(1); -var_dump(\DDTrace\root_span()->meta); +var_dump(\DDTrace\root_span()->attributes); $dlr = new DebuggerLogReplayer; $log = $dlr->waitForDebuggerDataAndReplay(); diff --git a/tests/ext/nested_exceptions.phpt b/tests/ext/nested_exceptions.phpt index cf79fb27e80..e8d11dcddac 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -39,10 +41,12 @@ array(1) { string(3) "cli" ["error"]=> int(1) - ["meta"]=> + ["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 +57,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..f571b7c9905 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(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -33,7 +35,7 @@ array(1) { string(44) "otel_http_response_status_code_remapping.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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..b8f5f8f3e21 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(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -34,7 +36,7 @@ array(1) { string(55) "otel_http_response_status_code_remapping_precedence.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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..b6646d4695a 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(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -33,7 +35,7 @@ array(1) { string(35) "otel_http_status_code_remapping.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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..8bab4d83118 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(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -42,14 +44,14 @@ array(1) { string(33) "peer_service_disabled_default.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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..f1ef0d76015 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(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -48,14 +50,14 @@ array(2) { string(33) "peer_service_honor_user_value.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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]=> @@ -78,14 +80,14 @@ array(2) { string(33) "peer_service_honor_user_value.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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..9d7483846ca 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(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -53,18 +55,18 @@ array(2) { string(26) "peer_service_remapping.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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" } @@ -89,20 +91,20 @@ array(2) { string(26) "peer_service_remapping.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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..08fb6c0837d 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(10) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> 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..4024a2bc699 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(10) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> diff --git a/tests/ext/peer_service_use_first_available_tag.phpt b/tests/ext/peer_service_use_first_available_tag.phpt index 06999a9cc80..def02e5d2e3 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(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -55,12 +57,12 @@ array(3) { string(40) "peer_service_use_first_available_tag.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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" } @@ -85,14 +87,14 @@ array(3) { string(40) "peer_service_use_first_available_tag.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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" } @@ -117,14 +119,14 @@ array(3) { string(40) "peer_service_use_first_available_tag.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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..840373fd8e5 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(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -48,12 +50,12 @@ array(2) { string(29) "peer_service_wrong_values.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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" } @@ -78,14 +80,14 @@ array(2) { string(29) "peer_service_wrong_values.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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/priority_sampling/021-rule-name-as-glob-with-question-mark.phpt b/tests/ext/priority_sampling/021-rule-name-as-glob-with-question-mark.phpt index 4614f26881f..f098415b9fa 100644 --- a/tests/ext/priority_sampling/021-rule-name-as-glob-with-question-mark.phpt +++ b/tests/ext/priority_sampling/021-rule-name-as-glob-with-question-mark.phpt @@ -91,7 +91,8 @@ foreach ($tests as list($pattern, $name, $matches)) { ini_set("datadog.trace.sampling_rules", '[{"tags":{"foo":"' . $pattern . '"},"sample_rate":0.7},{"sample_rate": 0.3}]'); $root = \DDTrace\root_span(); - $root->meta["foo"] = $name; + // Typed, so the numeric/null rules apply ($meta stores strings). + $root->attributes["foo"] = $name; \DDTrace\get_priority_sampling(); diff --git a/tests/ext/priority_sampling/serialization-chunk.phpt b/tests/ext/priority_sampling/serialization-chunk.phpt index 11192c42235..6778267391f 100644 --- a/tests/ext/priority_sampling/serialization-chunk.phpt +++ b/tests/ext/priority_sampling/serialization-chunk.phpt @@ -17,8 +17,8 @@ class ChangeSamplingDuringSerialization { $root = DDTrace\start_span(); $root->name = 'root'; -// Serialization converts this metric to a string tag and releases the old value. -$root->metrics['http.status_code'] = new ChangeSamplingDuringSerialization(); +// Serialization converts this attribute to a string tag and releases the old value. +$root->attributes['http.status_code'] = new ChangeSamplingDuringSerialization(); DDTrace\start_span()->name = 'keep.child'; DDTrace\close_span(); @@ -31,15 +31,15 @@ DDTrace\close_span(); DDTrace\close_span(); foreach (dd_trace_serialize_closed_spans() as $span) { - echo $span['name'], ': ', isset($span['metrics']['_dd.span_sampling.mechanism']) ? 'single span' : 'trace', "\n"; + echo $span['name'], ': ', isset($span['attributes']['_dd.span_sampling.mechanism']) ? 'single span' : 'trace', "\n"; } // Subsequent chunks must observe the new configuration. DDTrace\start_span()->name = 'keep.next'; DDTrace\close_span(); $span = dd_trace_serialize_closed_spans()[0]; -echo $span['name'], ': ', isset($span['metrics']['_dd.span_sampling.mechanism']) ? 'single span' : 'trace', "\n"; -var_dump($span['metrics']['_sampling_priority_v1']); +echo $span['name'], ': ', isset($span['attributes']['_dd.span_sampling.mechanism']) ? 'single span' : 'trace', "\n"; +var_dump($span['sampling_priority']); var_dump(dd_trace_serialize_closed_spans()); ?> @@ -49,6 +49,6 @@ unmatched: trace keep.child: single span keep.attached: single span keep.next: trace -float(2) +int(2) array(0) { } 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/referrer_extraction_01.phpt b/tests/ext/referrer_extraction_01.phpt index 6d41422406f..ab6c26a1c5f 100644 --- a/tests/ext/referrer_extraction_01.phpt +++ b/tests/ext/referrer_extraction_01.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.sdk.otlp_export"]=> - string(5) "false" - ["_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" diff --git a/tests/ext/referrer_extraction_02.phpt b/tests/ext/referrer_extraction_02.phpt index ce4817172a8..eb70044f44b 100644 --- a/tests/ext/referrer_extraction_02.phpt +++ b/tests/ext/referrer_extraction_02.phpt @@ -15,28 +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(10) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.sdk.otlp_export"]=> - string(5) "false" - ["_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" diff --git a/tests/ext/referrer_extraction_03.phpt b/tests/ext/referrer_extraction_03.phpt index 2a0f673213f..a7cbf5c5c18 100644 --- a/tests/ext/referrer_extraction_03.phpt +++ b/tests/ext/referrer_extraction_03.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.sdk.otlp_export"]=> - string(5) "false" - ["_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" diff --git a/tests/ext/referrer_extraction_04.phpt b/tests/ext/referrer_extraction_04.phpt index 181a7684919..f14c33a5003 100644 --- a/tests/ext/referrer_extraction_04.phpt +++ b/tests/ext/referrer_extraction_04.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.sdk.otlp_export"]=> - string(5) "false" - ["_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" diff --git a/tests/ext/referrer_extraction_05.phpt b/tests/ext/referrer_extraction_05.phpt index edb0b56b5b2..e2569f33b5f 100644 --- a/tests/ext/referrer_extraction_05.phpt +++ b/tests/ext/referrer_extraction_05.phpt @@ -15,28 +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(10) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.sdk.otlp_export"]=> - string(5) "false" - ["_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]" diff --git a/tests/ext/request-replayer/analytics_event_v04.phpt b/tests/ext/request-replayer/analytics_event_v04.phpt new file mode 100644 index 00000000000..9196d71fdb1 --- /dev/null +++ b/tests/ext/request-replayer/analytics_event_v04.phpt @@ -0,0 +1,57 @@ +--TEST-- +analytics.event maps to the _dd1.sr.eausr metric on the v0.4 wire +--SKIPIF-- + [ + 'method' => 'PUT', + 'header' => ["Content-Type: application/json", "X-Datadog-Test-Session-Token: analytics_event_v04"], + 'content' => json_encode(["endpoints" => ["/v0.4/traces", "/v0.6/stats", "/v0.7/config"], "client_drop_p0s" => false, "version" => "7.66.0"]), +]]); +if (@file_get_contents("http://request-replayer/set-agent-info", false, $ctx) === false) { + die("skip: request-replayer not reachable"); +} +?> +--ENV-- +DD_TRACE_LOG_LEVEL=error,startup=off +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 +--INI-- +datadog.trace.agent_test_session_token=analytics_event_v04 +--FILE-- +clearDumpedData(); + +dd_trace_internal_fn('await_agent_info'); + +$s = \DDTrace\start_span(); +$s->name = "root"; +$s->meta["analytics.event"] = "true"; +$c = \DDTrace\start_span(); +$c->name = "child"; +$c->attributes["analytics.event"] = 0; +\DDTrace\close_span(); +\DDTrace\close_span(); +dd_trace_internal_fn("synchronous_flush"); + +$req = $rr->waitForRequest(function ($r) { return strpos($r["uri"], "traces") !== false; }); +echo "uri=" . $req["uri"] . "\n"; +$spans = json_decode($req["body"], true)[0]; +usort($spans, function ($a, $b) { return strcmp($a["name"], $b["name"]); }); +foreach ($spans as $span) { + echo $span["name"], ": eausr=", var_export($span["metrics"]["_dd1.sr.eausr"] ?? null, true), + " analytics.event=", isset($span["meta"]["analytics.event"]) || isset($span["metrics"]["analytics.event"]) ? "kept" : "removed", "\n"; +} +?> +--EXPECT-- +uri=/v0.4/traces +child: eausr=0 analytics.event=removed +root: eausr=1 analytics.event=removed diff --git a/tests/ext/request-replayer/client_side_stats_dd_tags_env.phpt b/tests/ext/request-replayer/client_side_stats_dd_tags_env.phpt new file mode 100644 index 00000000000..98b0ac8d73f --- /dev/null +++ b/tests/ext/request-replayer/client_side_stats_dd_tags_env.phpt @@ -0,0 +1,63 @@ +--TEST-- +Client-side span stats bucket by DD_TAGS env/version when DD_ENV/DD_VERSION are unset +--SKIPIF-- + += 80100) { + echo "nocache\n"; +} +$ctx = stream_context_create([ + 'http' => [ + 'method' => 'PUT', + 'header' => [ + 'Content-Type: application/json', + 'X-Datadog-Test-Session-Token: client_side_stats_dd_tags', + ], + 'content' => json_encode(['version' => '7.65.0', 'client_drop_p0s' => true]), + ] +]); +file_get_contents('http://request-replayer/set-agent-info', false, $ctx); +?> +--ENV-- +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=1 +DD_TRACE_STATS_COMPUTATION_ENABLED=1 +DD_TAGS=env:staging,version:9.9.9-tags +--INI-- +datadog.trace.agent_test_session_token=client_side_stats_dd_tags +--FILE-- +name = "web.request"; +$root->resource = "GET /test"; +$root->service = "stats-test-service"; +\DDTrace\close_span(); + +dd_trace_internal_fn('synchronous_flush', 5000); +$rr->waitForDataAndReplay(); + +$statsRequest = $rr->waitForStats(); +$payload = json_decode($statsRequest['body'], true); + +// env/version come from DD_TAGS (merged into meta) since DD_ENV/DD_VERSION are unset. Without the +// meta fallback in the stats path they would bucket by empty strings while traces carry the values. +echo "env: " . $payload['Env'] . "\n"; +echo "version: " . $payload['Version'] . "\n"; + +?> +--EXPECT-- +env: staging +version: 9.9.9-tags diff --git a/tests/ext/request-replayer/client_side_stats_inferred_span_sampling.phpt b/tests/ext/request-replayer/client_side_stats_inferred_span_sampling.phpt new file mode 100644 index 00000000000..200b7860d81 --- /dev/null +++ b/tests/ext/request-replayer/client_side_stats_inferred_span_sampling.phpt @@ -0,0 +1,69 @@ +--TEST-- +Single-span-sampled p0 root with an inferred span and agent stats does not crash (F1 NULL-guard) +--SKIPIF-- + += 80100) { + echo "nocache\n"; +} +$ctx = stream_context_create([ + 'http' => [ + 'method' => 'PUT', + 'header' => [ + 'Content-Type: application/json', + 'X-Datadog-Test-Session-Token: css_inferred_span_sampling', + ], + 'content' => json_encode(['version' => '7.65.0', 'client_drop_p0s' => true]), + ] +]); +file_get_contents('http://request-replayer/set-agent-info', false, $ctx); +?> +--ENV-- +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=1 +DD_TRACE_STATS_COMPUTATION_ENABLED=1 +DD_SERVICE=aws-server +DD_TRACE_SAMPLE_RATE=0 +DD_SPAN_SAMPLING_RULES=[{"service":"aws-server","name":"web.request","sample_rate":1.0}] +DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED=1 +HTTP_X_DD_PROXY=aws-apigateway +HTTP_X_DD_PROXY_REQUEST_TIME_MS=1742285908783 +HTTP_X_DD_PROXY_PATH=/test +HTTP_X_DD_PROXY_HTTPMETHOD=GET +HTTP_X_DD_PROXY_DOMAIN_NAME=example.com +HTTP_X_DD_PROXY_STAGE=aws-prod +METHOD=GET +SERVER_NAME=localhost:8888 +SCRIPT_NAME=/foo.php +REQUEST_URI=/foo +DD_TRACE_DEBUG_PRNG_SEED=42 +--INI-- +datadog.trace.agent_test_session_token=css_inferred_span_sampling +--FILE-- +name = "web.request"; +\DDTrace\close_span(); + +echo "before flush\n"; +// Serialization runs here: the p0 root is single-span-sampled (so it builds), then its inferred +// parent recurses and is dropped into the stats concentrator, returning the {0} sentinel sink. +// Without the NULL guard the parent's transfer/set_error deref a NULL builder and crash. +dd_trace_internal_fn('synchronous_flush', 5000); +echo "after flush\n"; + +?> +--EXPECT-- +before flush +after flush 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..a4d0c5e2dca 100644 --- a/tests/ext/request-replayer/dd_trace_exception_span_event.phpt +++ b/tests/ext/request-replayer/dd_trace_exception_span_event.phpt @@ -8,6 +8,7 @@ DD_TRACE_AGENT_PORT=80 DD_TRACE_AGENT_FLUSH_INTERVAL=333 DD_TRACE_GENERATE_ROOT_SPAN=0 DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 --INI-- datadog.trace.agent_test_session_token=dd_trace_exception_span_event --FILE-- @@ -49,8 +50,40 @@ $root = json_decode($replay["body"], true); $spans = $root["chunks"][0]["spans"] ?? $root[0]; $span = $spans[0]; -var_dump($span['meta']['events']); +// This test pins the in-process sender (v0.4-only): events are legacy `events` meta JSON, no +// `span_events` field. Handle both shapes anyway; ddAnyValueToPhp() unwraps the v1 AnyValue form. +function ddAnyValueToPhp($v) { + if (!is_array($v) || !array_key_exists('type', $v)) { + return $v; // already a plain value (legacy `events` meta JSON) + } + switch ($v['type']) { + case 0: return $v['string_value']; + case 1: return $v['bool_value']; + case 2: return $v['int_value']; + case 3: return $v['double_value']; + case 4: return array_map('ddAnyValueToPhp', $v['array_value']['values']); + default: return $v; + } +} +if (isset($span['span_events'])) { + $event = $span['span_events'][0]; +} else { + $event = json_decode($span['meta']['events'], true)[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(ddAnyValueToPhp($attrs['exception.message'])); +var_dump(ddAnyValueToPhp($attrs['exception.type'])); +var_dump(ddAnyValueToPhp($attrs['custom.attribute'])); +var_dump(ddAnyValueToPhp($attrs['exception.stacktrace'])); ?> --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..0e9c1a62243 100644 --- a/tests/ext/request-replayer/dd_trace_span_event.phpt +++ b/tests/ext/request-replayer/dd_trace_span_event.phpt @@ -8,6 +8,7 @@ DD_TRACE_AGENT_PORT=80 DD_TRACE_AGENT_FLUSH_INTERVAL=333 DD_TRACE_GENERATE_ROOT_SPAN=0 DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 --INI-- datadog.trace.agent_test_session_token=dd_trace_span_event --FILE-- @@ -41,8 +42,46 @@ $replay = $rr->waitForDataAndReplay(); $root = json_decode($replay["body"], true); $spans = $root["chunks"][0]["spans"] ?? $root[0]; $span = $spans[0]; -var_dump($span['meta']['events']); +// This test pins the in-process sender (v0.4-only): events are legacy `events` meta JSON. Handle +// the v1 AnyValue shape too; ddAnyValueToPhp() unwraps it to the same plain PHP value. +function ddAnyValueToPhp($v) { + if (!is_array($v) || !array_key_exists('type', $v)) { + return $v; // already a plain value (legacy `events` meta JSON) + } + switch ($v['type']) { + case 0: return $v['string_value']; + case 1: return $v['bool_value']; + case 2: return $v['int_value']; + case 3: return $v['double_value']; + case 4: return array_map('ddAnyValueToPhp', $v['array_value']['values']); + default: return $v; + } +} +if (isset($span['span_events'])) { + $event = $span['span_events'][0]; +} else { + $event = json_decode($span['meta']['events'], true)[0]; +} +$attrs = $event['attributes']; +var_dump($event['name'], $event['time_unix_nano']); +var_dump(ddAnyValueToPhp($attrs['arg1'])); +var_dump(ddAnyValueToPhp($attrs['int_array'])); +var_dump(ddAnyValueToPhp($attrs['string_array'])); ?> --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" +array(2) { + [0]=> + int(3) + [1]=> + int(4) +} +array(2) { + [0]=> + string(1) "5" + [1]=> + string(1) "6" +} diff --git a/tests/ext/request-replayer/dd_trace_span_link_with_exception.phpt b/tests/ext/request-replayer/dd_trace_span_link_with_exception.phpt index 6dbbca8840b..9795c149b99 100644 --- a/tests/ext/request-replayer/dd_trace_span_link_with_exception.phpt +++ b/tests/ext/request-replayer/dd_trace_span_link_with_exception.phpt @@ -48,14 +48,30 @@ try { echo 'Caught exception: ' . $e->getMessage() . PHP_EOL; } -$replay = $rr->waitForDataAndReplay(); +// Find the request carrying our Foo.bar span (the wire may be v0.4 or v1 depending on which +// protocol the sidecar has negotiated). +$replay = $rr->waitForRequest(function ($r) { + if (strpos($r["uri"], "traces") === false) return false; + $b = json_decode($r["body"], true); + $s = $b["chunks"][0]["spans"][0] ?? ($b[0][0] ?? null); + return $s && ($s["name"] ?? null) === "Foo.bar"; +}); $root = json_decode($replay["body"], true); $spans = $root["chunks"][0]["spans"] ?? $root[0]; $span = $spans[0]; var_dump($span['meta']['error.message']); var_dump($span['meta']['error.type']); var_dump($span['meta']['error.stack']); -var_dump($span['meta']['_dd.span_links']); +// Span links are carried natively (numeric ids) on the v0.4 downgrade wire and as the +// _dd.span_links meta JSON (zero-padded hex ids) on the v1 wire. Both encode the same 128-bit +// trace id (hex 0x42) and span id (0x6); normalise to ":". +if (isset($span['span_links'])) { + $link = $span['span_links'][0]; + printf("link=%x:%x\n", $link['trace_id'], $link['span_id']); +} else { + $link = json_decode($span['meta']['_dd.span_links'], true)[0]; + printf("link=%x:%x\n", hexdec($link['trace_id']), hexdec($link['span_id'])); +} ?> --EXPECTF-- Caught exception: Oops! @@ -64,4 +80,4 @@ string(9) "Exception" string(%d) "#0 %sdd_trace_span_link_with_exception.php(12): Foo->doException() #1 %sdd_trace_span_link_with_exception.php(33): Foo->bar() #2 {main}" -string(33) "[{"trace_id":"42","span_id":"6"}]" +link=42:6 diff --git a/tests/ext/request-replayer/serializer_wire_inprocess_multitrace.phpt b/tests/ext/request-replayer/serializer_wire_inprocess_multitrace.phpt new file mode 100644 index 00000000000..1c3aff755f1 --- /dev/null +++ b/tests/ext/request-replayer/serializer_wire_inprocess_multitrace.phpt @@ -0,0 +1,67 @@ +--TEST-- +In-process sender frames every trace of a multi-trace flush (per-trace coms group id) +--SKIPIF-- + [ + 'method' => 'PUT', + 'header' => ["Content-Type: application/json", "X-Datadog-Test-Session-Token: inproc_multitrace"], + 'content' => json_encode(["endpoints" => ["/v0.4/traces", "/v0.6/stats", "/v0.7/config"], "client_drop_p0s" => false, "version" => "7.66.0"]), +]]); +if (@file_get_contents("http://request-replayer/set-agent-info", false, $ctx) === false) { + die("skip: request-replayer not reachable"); +} +?> +--ENV-- +DD_TRACE_LOG_LEVEL=info,startup=off +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 +--INI-- +datadog.trace.agent_test_session_token=inproc_multitrace +--FILE-- +clearDumpedData(); + +dd_trace_internal_fn('await_agent_info'); + +// Three independent root traces closed before a single flush. Each closed span +// stack becomes its own v0.4 trace; the background sender must frame all three +// (outer msgpack array of N) so the agent keeps every trace, not just the first. +for ($i = 0; $i < 3; $i++) { + $s = \DDTrace\start_trace_span(); + $s->name = "root$i"; + $s->service = "svc"; + \DDTrace\close_span(); +} +// One flush serializes all three closed traces together, exercising the +// per-trace coms group-id path; synchronous_flush then pushes the buffer. +\DDTrace\flush(); +dd_trace_internal_fn("synchronous_flush"); + +$req = $rr->waitForRequest(function ($r) { return strpos($r["uri"], "/v0.4/traces") !== false; }); +$traces = json_decode($req["body"], true); +echo "uri=" . $req["uri"] . "\n"; +echo "trace_count_header=" . $req["headers"]["X-Datadog-Trace-Count"] . "\n"; +echo "trace_count=" . count($traces) . "\n"; +$names = array_map(function ($t) { return $t[0]["name"]; }, $traces); +sort($names); +echo "names=" . implode(",", $names) . "\n"; +?> +--EXPECTF-- +[ddtrace] [info] [%d] Flushing 3 v0.4 trace(s) to send-queue for http://request-replayer:80 +uri=/v0.4/traces +trace_count_header=3 +trace_count=3 +names=root0,root1,root2 +[ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/request-replayer/serializer_wire_inprocess_v04.phpt b/tests/ext/request-replayer/serializer_wire_inprocess_v04.phpt new file mode 100644 index 00000000000..b49a8d67009 --- /dev/null +++ b/tests/ext/request-replayer/serializer_wire_inprocess_v04.phpt @@ -0,0 +1,61 @@ +--TEST-- +In-process sender + non-v1 agent serializes the v0.4 wire (/v0.4/traces, no chunks) +--SKIPIF-- + [ + 'method' => 'PUT', + 'header' => ["Content-Type: application/json", "X-Datadog-Test-Session-Token: serializer_wire_v04"], + 'content' => json_encode(["endpoints" => ["/v0.4/traces", "/v0.6/stats", "/v0.7/config"], "client_drop_p0s" => false, "version" => "7.66.0"]), +]]); +if (@file_get_contents("http://request-replayer/set-agent-info", false, $ctx) === false) { + die("skip: request-replayer not reachable"); +} +?> +--ENV-- +DD_TRACE_LOG_LEVEL=info,startup=off +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 +--INI-- +datadog.trace.agent_test_session_token=serializer_wire_v04 +--FILE-- +clearDumpedData(); + +// Decide the wire before flushing (reads the non-v1 /info above). +dd_trace_internal_fn('await_agent_info'); + +$s = \DDTrace\start_span(); +$s->name = "root"; +$s->service = "svc"; +$s->meta["span.kind"] = "server"; +\DDTrace\close_span(); +dd_trace_internal_fn("synchronous_flush"); + +$req = $rr->waitForRequest(function ($r) { return strpos($r["uri"], "traces") !== false; }); +$root = json_decode($req["body"], true); +$spans = $root["chunks"][0]["spans"] ?? $root[0]; +echo "uri=" . $req["uri"] . "\n"; +echo "has_chunks=" . (isset($root['chunks']) ? "yes" : "no") . "\n"; +echo "span_name=" . $spans[0]["name"] . "\n"; +echo "priority=" . $spans[0]["metrics"]["_sampling_priority_v1"] . "\n"; +echo "span_kind=" . $spans[0]["meta"]["span.kind"] . "\n"; +?> +--EXPECTF-- +[ddtrace] [info] [%d] Flushing %d v0.4 trace(s) to send-queue for http://request-replayer:80 +uri=/v0.4/traces +has_chunks=no +span_name=root +priority=1 +span_kind=server +[ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/request-replayer/serializer_wire_inprocess_v1.phpt b/tests/ext/request-replayer/serializer_wire_inprocess_v1.phpt new file mode 100644 index 00000000000..09653ef7ec4 --- /dev/null +++ b/tests/ext/request-replayer/serializer_wire_inprocess_v1.phpt @@ -0,0 +1,53 @@ +--TEST-- +In-process sender ignores a v1-capable agent and still serializes the v0.4 wire (/v0.4/traces) +--DESCRIPTION-- +Locks the in-process sender -> v0.4 wire mapping even when the agent advertises /v1.0/traces. The +in-process (<=8.2 / DD_TRACE_SIDECAR_TRACE_SENDER=0) sender ALWAYS downgrades the native V1 builder +to v0.4 and posts each trace to /v0.4/traces; a native V1 payload is a single msgpack MAP that the +background sender's array-of-1 framing (comms_php.c mpack_expect_array_match) cannot parse, so the +in-process path never uses /v1.0/traces regardless of agent capability. +--SKIPIF-- + +--ENV-- +DD_TRACE_LOG_LEVEL=info,startup=off +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 +--INI-- +datadog.trace.agent_test_session_token=serializer_wire_inprocess_v1 +--FILE-- +clearDumpedData(); + +// The default request-replayer /info advertises /v1.0/traces; confirm the in-process sender +// still downgrades to v0.4. +dd_trace_internal_fn('await_agent_info'); + +$s = \DDTrace\start_span(); +$s->name = "root"; +$s->service = "svc"; +\DDTrace\close_span(); +dd_trace_internal_fn("synchronous_flush"); + +$req = $rr->waitForRequest(function ($r) { return strpos($r["uri"], "traces") !== false; }); +$root = json_decode($req["body"], true); +$spans = $root["chunks"][0]["spans"] ?? $root[0]; +echo "uri=" . $req["uri"] . "\n"; +echo "has_chunks=" . (isset($root['chunks']) ? "yes" : "no") . "\n"; +echo "span_name=" . $spans[0]["name"] . "\n"; +?> +--EXPECTF-- +[ddtrace] [info] [%d] Flushing %d v0.4 trace(s) to send-queue for http://request-replayer:80 +uri=/v0.4/traces +has_chunks=no +span_name=root +[ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt b/tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt new file mode 100644 index 00000000000..8d70aeabf4a --- /dev/null +++ b/tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt @@ -0,0 +1,43 @@ +--TEST-- +DD_TRACE_AGENT_PROTOCOL_VERSION=0.4 keeps the sidecar on /v0.4/traces although the agent advertises /v1.0/traces +--SKIPIF-- + +--ENV-- +DD_TRACE_LOG_LEVEL=error,startup=off +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=1 +DD_TRACE_AGENT_PROTOCOL_VERSION=0.4 +--INI-- +datadog.trace.agent_test_session_token=serializer_wire_sidecar_forced_v04 +--FILE-- +clearDumpedData(); + +// Without the setting the sidecar switches to v1 once its /info fetch completes (well within 3s). +$v04 = $v1 = 0; +for ($i = 0; $i < 30; $i++) { + $s = \DDTrace\start_span(); + $s->name = "root"; + \DDTrace\close_span(); + dd_trace_internal_fn("synchronous_flush"); + usleep(100000); + foreach (($rr->replayAllRequests() ?: []) as $r) { + if (strpos($r["uri"], "/v1.0/traces") !== false) $v1++; + if (strpos($r["uri"], "/v0.4/traces") !== false) $v04++; + } +} +echo "v0.4 requests: ", $v04 > 0 ? "some" : "none", "\n"; +echo "v1 requests: $v1\n"; +?> +--EXPECT-- +v0.4 requests: some +v1 requests: 0 diff --git a/tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt b/tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt new file mode 100644 index 00000000000..6e594290002 --- /dev/null +++ b/tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt @@ -0,0 +1,56 @@ +--TEST-- +Sidecar sender + v1-capable agent serializes the v1 wire (/v1.0/traces, chunks) +--SKIPIF-- + +--ENV-- +DD_TRACE_LOG_LEVEL=error,startup=off +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=1 +--INI-- +datadog.trace.agent_test_session_token=serializer_wire_sidecar_v1 +--FILE-- +clearDumpedData(); + +// The sidecar sends v0.4 until its own /info fetch has advertised /v1.0/traces, and may batch +// several traces per payload: resend "root" until it shows up in any chunk of a v1 request. +$req = null; +$foundSpan = null; +for ($i = 0; $i < 100 && $req === null; $i++) { + $s = \DDTrace\start_span(); + $s->name = "root"; + $s->service = "svc"; + \DDTrace\close_span(); + dd_trace_internal_fn("synchronous_flush"); + usleep(100000); + foreach (($rr->replayAllRequests() ?: []) as $r) { + if (strpos($r["uri"], "/v1.0/traces") === false) continue; + foreach ((json_decode($r["body"], true)["chunks"] ?? []) as $chunk) { + foreach (($chunk["spans"] ?? []) as $span) { + if (($span["name"] ?? null) === "root" && ($span["service"] ?? null) === "svc") { + $req = $r; + $foundSpan = $span; + } + } + } + } +} +echo "uri=" . ($req["uri"] ?? "none") . "\n"; +// Derived from the matched span itself, not from $req's truthiness: proves the +// v1 payload actually carries the span's own name/service, not just any chunk. +echo "span_name=" . ($foundSpan["name"] ?? "none") . "\n"; +echo "span_service=" . ($foundSpan["service"] ?? "none") . "\n"; +?> +--EXPECT-- +uri=/v1.0/traces +span_name=root +span_service=svc diff --git a/tests/ext/request-replayer/span_attributes_v04_wire.phpt b/tests/ext/request-replayer/span_attributes_v04_wire.phpt new file mode 100644 index 00000000000..360a958287f --- /dev/null +++ b/tests/ext/request-replayer/span_attributes_v04_wire.phpt @@ -0,0 +1,69 @@ +--TEST-- +Typed SpanData::$attributes on the v0.4 wire: numbers go to metrics, bools and strings to meta, nested values flatten +--SKIPIF-- + [ + 'method' => 'PUT', + 'header' => ["Content-Type: application/json", "X-Datadog-Test-Session-Token: span_attributes_v04"], + 'content' => json_encode(["endpoints" => ["/v0.4/traces", "/v0.6/stats", "/v0.7/config"], "client_drop_p0s" => false, "version" => "7.66.0"]), +]]); +if (@file_get_contents("http://request-replayer/set-agent-info", false, $ctx) === false) { + die("skip: request-replayer not reachable"); +} +?> +--ENV-- +DD_TRACE_LOG_LEVEL=info,startup=off +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 +--INI-- +datadog.trace.agent_test_session_token=span_attributes_v04 +--FILE-- +clearDumpedData(); + +dd_trace_internal_fn('await_agent_info'); + +$s = \DDTrace\start_span(); +$s->name = "root"; +$s->attributes = ['int' => 42, 'float' => 1.5, 'bool' => true, 'false' => false, 'string' => 's', 'list' => [1, 'two'], 'map' => ['k' => 'v']]; +$s->meta['string'] = 'meta wins'; +$s->meta['meta_only'] = 'm'; +$s->metrics['int'] = 7; +\DDTrace\close_span(); +dd_trace_internal_fn("synchronous_flush"); + +$req = $rr->waitForRequest(function ($r) { return strpos($r["uri"], "traces") !== false; }); +$span = json_decode($req["body"], true)[0][0]; +echo "uri=" . $req["uri"] . "\n"; +foreach (['meta', 'metrics'] as $bucket) { + foreach (['int', 'float', 'bool', 'false', 'string', 'list.0', 'list.1', 'map.k', 'meta_only'] as $key) { + if (isset($span[$bucket][$key])) { + echo "$bucket.$key=", var_export($span[$bucket][$key], true), "\n"; + } + } +} +?> +--EXPECTF-- +[ddtrace] [info] [%d] Flushing %d v0.4 trace(s) to send-queue for http://request-replayer:80 +uri=/v0.4/traces +meta.bool='true' +meta.false='false' +meta.string='meta wins' +meta.list.1='two' +meta.map.k='v' +meta.meta_only='m' +metrics.int=7 +metrics.float=1.5 +metrics.list.0=1 +[ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt b/tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt new file mode 100644 index 00000000000..2150b976dc0 --- /dev/null +++ b/tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt @@ -0,0 +1,76 @@ +--TEST-- +v0.4 native span_links and legacy events JSON print floats like json_encode and objects as property maps +--SKIPIF-- + [ + 'method' => 'PUT', + 'header' => ["Content-Type: application/json", "X-Datadog-Test-Session-Token: span_link_event_attributes_v04_wire"], + 'content' => json_encode(["endpoints" => ["/v0.4/traces", "/v0.6/stats", "/v0.7/config"], "client_drop_p0s" => false, "version" => "7.66.0"]), +]]); +if (@file_get_contents("http://request-replayer/set-agent-info", false, $ctx) === false) { + die("skip: request-replayer not reachable"); +} +?> +--ENV-- +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 +--INI-- +datadog.trace.agent_test_session_token=span_link_event_attributes_v04_wire +serialize_precision=-1 +--FILE-- +clearDumpedData(); +dd_trace_internal_fn('await_agent_info'); + +class Pub { public $a = 1; protected $prot = 'p'; private $priv = 'x'; } + +$floats = [1e20, 1e-5, 0.1, 1.5, 1e17, 123456789012345678.0, -0.0, 3.0]; +$s = \DDTrace\start_span(); +$s->name = "root"; +$link = new \DDTrace\SpanLink(); +$link->traceId = str_repeat('0', 31) . '1'; +$link->spanId = str_repeat('0', 15) . '2'; +$link->attributes = ['floats' => $floats]; +$s->links[] = $link; +$s->events[] = new \DDTrace\SpanEvent('evt', ['f' => 1e20, 'floats' => $floats, 'obj' => new Pub, 'nested' => ['k' => [1e-5]]], 1); +\DDTrace\close_span(); +dd_trace_internal_fn("synchronous_flush"); + +$req = $rr->waitForRequest(function ($r) { return strpos($r["uri"], "traces") !== false; }); +$span = json_decode($req["body"], true)[0][0]; +$meta = $span["meta"]; +$expected = json_encode($floats); +echo $expected, "\n"; +// Native links carry nested values as a JSON string, events as raw JSON: both must print json_encode's floats. +var_dump(!isset($meta["_dd.span_links"]) && $span["span_links"][0]["attributes"]["floats"] === $expected); +var_dump(strpos($meta["events"], '"floats":' . $expected) !== false); +var_dump(strpos($meta["events"], '"f":1.0e+20') !== false); +$attrs = json_decode($meta["events"], true)[0]["attributes"]; +var_dump($attrs["obj"], $attrs["nested"]); +?> +--EXPECT-- +[1.0e+20,1.0e-5,0.1,1.5,1.0e+17,1.2345678901234568e+17,-0,3] +bool(true) +bool(true) +bool(true) +array(1) { + ["a"]=> + int(1) +} +array(1) { + ["k"]=> + array(1) { + [0]=> + float(1.0E-5) + } +} diff --git a/tests/ext/request-replayer/top_level_marked_on_v1_wire.phpt b/tests/ext/request-replayer/top_level_marked_on_v1_wire.phpt new file mode 100644 index 00000000000..e98e70adf9a --- /dev/null +++ b/tests/ext/request-replayer/top_level_marked_on_v1_wire.phpt @@ -0,0 +1,64 @@ +--TEST-- +The sidecar sender marks _dd.top_level on the V1 wire (local root and service changes) without stats computation +--SKIPIF-- + +--ENV-- +DD_TRACE_LOG_LEVEL=error,startup=off +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=1 +DD_TRACE_STATS_COMPUTATION_ENABLED=0 +--INI-- +datadog.trace.agent_test_session_token=top_level_marked_on_v1_wire +--FILE-- +clearDumpedData(); + +// The sidecar sends v0.4 until its /info fetch advertises /v1.0/traces: resend until a v1 request carries the trace. +$found = null; +for ($i = 0; $i < 100 && $found === null; $i++) { + $root = \DDTrace\start_span(); + $root->name = "root"; + $root->service = "svc"; + $same = \DDTrace\start_span(); + $same->name = "child_same_service"; + $same->service = "svc"; + \DDTrace\close_span(); + $diff = \DDTrace\start_span(); + $diff->name = "child_other_service"; + $diff->service = "other"; + \DDTrace\close_span(); + \DDTrace\close_span(); + dd_trace_internal_fn("synchronous_flush"); + usleep(100000); + foreach (($rr->replayAllRequests() ?: []) as $r) { + if (strpos($r["uri"], "/v1.0/traces") === false) continue; + foreach ((json_decode($r["body"], true)["chunks"] ?? []) as $chunk) { + $names = array_column($chunk["spans"] ?? [], "name"); + if (in_array("child_other_service", $names, true)) { + $found = $chunk["spans"]; + } + } + } +} +$marks = []; +foreach ($found ?: [] as $span) { + $marks[$span["name"]] = isset($span["metrics"]["_dd.top_level"]) ? "1" : "not set"; +} +ksort($marks); +foreach ($marks as $name => $mark) { + echo "$name: _dd.top_level=$mark\n"; +} +?> +--EXPECT-- +child_other_service: _dd.top_level=1 +child_same_service: _dd.top_level=not set +root: _dd.top_level=1 diff --git a/tests/ext/request-replayer/traced_attribute_tags_v04_wire.phpt b/tests/ext/request-replayer/traced_attribute_tags_v04_wire.phpt new file mode 100644 index 00000000000..b3f02644863 --- /dev/null +++ b/tests/ext/request-replayer/traced_attribute_tags_v04_wire.phpt @@ -0,0 +1,72 @@ +--TEST-- +#[DDTrace\Trace] tags keep their meta strings on the v0.4 wire (array leaves included) +--SKIPIF-- + [ + 'method' => 'PUT', + 'header' => ["Content-Type: application/json", "X-Datadog-Test-Session-Token: traced_attribute_tags_v04"], + 'content' => json_encode(["endpoints" => ["/v0.4/traces", "/v0.6/stats", "/v0.7/config"], "client_drop_p0s" => false, "version" => "7.66.0"]), +]]); +if (@file_get_contents("http://request-replayer/set-agent-info", false, $ctx) === false) { + die("skip: request-replayer not reachable"); +} +?> +--ENV-- +DD_TRACE_LOG_LEVEL=info,startup=off +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 +--INI-- +datadog.trace.agent_test_session_token=traced_attribute_tags_v04 +--FILE-- +clearDumpedData(); + +dd_trace_internal_fn('await_agent_info'); + +#[DDTrace\Trace(name: "traced", tags: ["i" => 7, "arr" => [1, true, 2.5, null], "map" => ["k" => 3, "e" => []]])] +function traced() {} + +$s = \DDTrace\start_span(); +$s->name = "root"; +traced(); +\DDTrace\close_span(); +dd_trace_internal_fn("synchronous_flush"); + +$req = $rr->waitForRequest(function ($r) { return strpos($r["uri"], "traces") !== false; }); +foreach (json_decode($req["body"], true)[0] as $span) { + if ($span["name"] !== "traced") { + continue; + } + foreach (['meta', 'metrics'] as $bucket) { + $tags = isset($span[$bucket]) ? $span[$bucket] : []; + ksort($tags); + foreach ($tags as $key => $value) { + if (preg_match('/^(i|arr|map)\b/', $key)) { + echo "$bucket.$key=", var_export($value, true), "\n"; + } + } + } +} +?> +--EXPECTF-- +[ddtrace] [info] [%d] Flushing %d v0.4 trace(s) to send-queue for http://request-replayer:80 +meta.arr.0='1' +meta.arr.1='true' +meta.arr.2='2.5' +meta.arr.3='null' +meta.i='7' +meta.map.e='' +meta.map.k='3' +[ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/root_span_default_component.phpt b/tests/ext/root_span_default_component.phpt new file mode 100644 index 00000000000..1efb1ce9543 --- /dev/null +++ b/tests/ext/root_span_default_component.phpt @@ -0,0 +1,17 @@ +--TEST-- +Web entrypoint root spans default component to the SAPI name +--ENV-- +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_TRACE_GENERATE_ROOT_SPAN=0 +--GET-- +foo=bar +--FILE-- + +--EXPECT-- +string(8) "cgi-fcgi" +string(8) "cgi-fcgi" diff --git a/tests/ext/root_span_default_component_cli.phpt b/tests/ext/root_span_default_component_cli.phpt new file mode 100644 index 00000000000..3fa007b0219 --- /dev/null +++ b/tests/ext/root_span_default_component_cli.phpt @@ -0,0 +1,15 @@ +--TEST-- +CLI root spans get no default component +--ENV-- +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_TRACE_GENERATE_ROOT_SPAN=0 +--FILE-- + +--EXPECT-- +bool(false) +bool(false) diff --git a/tests/ext/root_span_default_component_framework_wins.phpt b/tests/ext/root_span_default_component_framework_wins.phpt new file mode 100644 index 00000000000..c1e92530f01 --- /dev/null +++ b/tests/ext/root_span_default_component_framework_wins.phpt @@ -0,0 +1,17 @@ +--TEST-- +A component set by an integration overrides the web root span default +--ENV-- +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_TRACE_GENERATE_ROOT_SPAN=0 +--GET-- +foo=bar +--FILE-- +meta["component"] = "laravel"; +DDTrace\close_span(); +$spans = dd_trace_serialize_closed_spans(); +var_dump($spans[0]["component"]); +?> +--EXPECT-- +string(7) "laravel" 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 6ea6f960276..4224d657dfb 100644 --- a/tests/ext/root_span_url_as_resource_names.phpt +++ b/tests/ext/root_span_url_as_resource_names.phpt @@ -17,26 +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(9) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.sdk.otlp_export"]=> - string(5) "false" - ["_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 e7aaa05caf1..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,26 +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(9) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.sdk.otlp_export"]=> - string(5) "false" - ["_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 ee48fa4a2a0..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,18 +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(5) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.sdk.otlp_export"]=> - string(5) "false" - ["_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 2472ca28fdb..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,18 +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(5) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" - ["_dd.sdk.otlp_export"]=> - string(5) "false" - ["_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" diff --git a/tests/ext/sampling_mechanism_from_decision_maker.phpt b/tests/ext/sampling_mechanism_from_decision_maker.phpt new file mode 100644 index 00000000000..4dc9ad334f6 --- /dev/null +++ b/tests/ext/sampling_mechanism_from_decision_maker.phpt @@ -0,0 +1,29 @@ +--TEST-- +The V1 chunk sampling_mechanism takes the digits after the last '-' of _dd.p.dm, and is unset when unparseable +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +--FILE-- + '42', + 'x-datadog-parent-id' => '10', + 'x-datadog-sampling-priority' => '1', + 'x-datadog-tags' => "_dd.p.dm=$dm", + ]); + DDTrace\close_span(); + $span = dd_trace_serialize_closed_spans()[0]; + echo json_encode($dm), " => ", $span['sampling_mechanism'] ?? 'unset', "\n"; +} + +?> +--EXPECT-- +"-4" => 4 +"934086a686-4" => 4 +"-12" => 12 +"-abc" => unset +"4-" => unset +"-" => unset diff --git a/tests/ext/sandbox-prehook/dd_trace_method.phpt b/tests/ext/sandbox-prehook/dd_trace_method.phpt index e7ea5c45418..5668afcb1a0 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -112,36 +114,31 @@ array(3) { string(10) "FooService" ["type"]=> string(7) "FooType" - ["meta"]=> - array(5) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(10) { + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + float(%f) ["_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) ["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) } } @@ -165,16 +162,18 @@ array(3) { string(10) "FooService" ["type"]=> string(7) "FooType" - ["meta"]=> + ["attributes"]=> array(1) { ["rand.range"]=> string(8) "42 - 999" } } [2]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -189,28 +188,23 @@ 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" + ["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-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-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-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/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 add87210a25..e9789bece26 100644 --- a/tests/ext/sandbox/dd_dumper.inc +++ b/tests/ext/sandbox/dd_dumper.inc @@ -31,18 +31,24 @@ 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"]); - unset($span["meta"]["_dd.sdk.otlp_export"]); - foreach ($span['meta'] as $k => $v) { + unset($span["attributes"]["runtime-id"]); + unset($span["attributes"]["_dd.tags.process"]); + unset($span["attributes"]["_dd.sdk.otlp_export"]); + // 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 { @@ -81,11 +87,11 @@ 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']); - unset($span['meta']['_dd.sdk.otlp_export']); - if (empty($span['meta'])) { - unset($span['meta']); + if (isset($span['attributes'])) { + unset($span['attributes']['_dd.tags.process']); + unset($span['attributes']['_dd.sdk.otlp_export']); + 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..d83c7229fc0 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -113,42 +115,37 @@ array(5) { string(10) "BarService" ["type"]=> string(7) "BarType" - ["meta"]=> - array(8) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(13) { + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + float(%f) ["_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) ["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) } } @@ -172,7 +169,7 @@ array(5) { string(29) "dd_trace_function_complex.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["attributes"]=> array(1) { ["_dd.base_service"]=> string(10) "BarService" @@ -198,16 +195,18 @@ array(5) { string(29) "dd_trace_function_complex.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["attributes"]=> array(1) { ["_dd.base_service"]=> string(10) "BarService" } } [3]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -222,35 +221,32 @@ 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" + ["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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -265,28 +261,23 @@ 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" + ["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..cd207cca443 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -44,28 +46,23 @@ 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" + ["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..8cb397114cb 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(10) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> diff --git a/tests/ext/sandbox/dd_trace_method.phpt b/tests/ext/sandbox/dd_trace_method.phpt index 16762177c00..388e2a789de 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -121,42 +123,37 @@ array(3) { string(10) "FooService" ["type"]=> string(7) "FooType" - ["meta"]=> - array(8) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(13) { + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + float(%f) ["_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) ["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) } } @@ -180,20 +177,22 @@ array(3) { string(19) "dd_trace_method.php" ["type"]=> string(3) "cli" - ["meta"]=> + ["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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -208,28 +207,23 @@ 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" + ["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/die_in_sandbox.phpt b/tests/ext/sandbox/die_in_sandbox.phpt index dea8d53cc7c..d91c341475e 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/sandbox/errors_are_flagged_from_userland.phpt b/tests/ext/sandbox/errors_are_flagged_from_userland.phpt index 9839c6dc576..6abce1e1aa9 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(13) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -46,30 +48,25 @@ 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" + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(7) { ["runtime-id"]=> string(36) "%s" - } - ["metrics"]=> - array(6) { + ["process_id"]=> + float(%f) + ["error.message"]=> + string(9) "Foo error" ["_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/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/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_closure_ge_php_84.phpt b/tests/ext/sandbox/install_hook/trace_closure_ge_php_84.phpt index fbf920b9dfb..bb3ad57b5a5 100644 --- a/tests/ext/sandbox/install_hook/trace_closure_ge_php_84.phpt +++ b/tests/ext/sandbox/install_hook/trace_closure_ge_php_84.phpt @@ -71,33 +71,25 @@ include __DIR__ . '/../dd_dumper.inc'; --EXPECTF-- spans(\DDTrace\SpanData) (8) { intval (trace_closure_ge_php_84.php, 0, cli) - _dd.p.tid => %s result => 0 {closure:%s.php:7\{closure} (trace_closure_ge_php_84.php, 1, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure_ge_php_84.php:7 result => 1 test\foo.{closure} (trace_closure_ge_php_84.php, 2, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure_ge_php_84.php:12 result => 2 test\bar.foo.{closure} (trace_closure_ge_php_84.php, 3, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure_ge_php_84.php:19 result => 3 intval (trace_closure_ge_php_84.php, 0, cli) - _dd.p.tid => %s result => 1 {closure:%s.php:7\{closure} (trace_closure_ge_php_84.php, 1, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure_ge_php_84.php:7 result => 2 test\foo.{closure} (trace_closure_ge_php_84.php, 2, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure_ge_php_84.php:12 result => 3 test\bar.foo.{closure} (trace_closure_ge_php_84.php, 3, cli) - _dd.p.tid => %s closure.declaration => %stests%cext%csandbox%cinstall_hook%ctrace_closure_ge_php_84.php:19 result => 4 } 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/install_hook/trace_generator_ge_php_84.phpt b/tests/ext/sandbox/install_hook/trace_generator_ge_php_84.phpt index 8954f507ab7..44d3c41ed26 100644 --- a/tests/ext/sandbox/install_hook/trace_generator_ge_php_84.phpt +++ b/tests/ext/sandbox/install_hook/trace_generator_ge_php_84.phpt @@ -39,7 +39,6 @@ include __DIR__ . '/../dd_dumper.inc'; --EXPECTF-- spans(\DDTrace\SpanData) (1) { {closure:%s.php:%d\{closure} (trace_generator_ge_php_84.php, {closure:%s.php:%d\{closure}, cli) - _dd.p.tid => %s closure.declaration => %s:%d result => 3 (trace_generator_ge_php_84.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.phpt b/tests/ext/sandbox/safe_to_string_metadata.phpt index 58efbfa21b2..97dab3a5469 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'], $span['meta']['_dd.sdk.otlp_export']); +unset($span['attributes']['process_id'], $span['attributes']['_dd.tags.process'], $span['attributes']['_dd.sdk.otlp_export']); $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; @@ -74,50 +77,20 @@ foreach ($span['meta'] as $key => $value) { } ?> --EXPECTF-- - array(1) { [0]=> string(9) "recursive" } -arg.0.0: string(9) "recursive" -arg.0.1: string(0) "" +arg.0: array(2) { + [0]=> + string(9) "recursive" + [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" @@ -145,9 +118,14 @@ object(DateTime)#%d (3) { ["timezone"]=> 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: array(3) { + ["date"]=> + string(26) "2019-09-10 00:00:00.000000" + ["timezone_type"]=> + string(1) "3" + ["timezone"]=> + string(3) "UTC" +} object(MyDt)#%d (3) { ["date"]=> @@ -157,6 +135,54 @@ object(MyDt)#%d (3) { ["timezone"]=> 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: array(3) { + ["date"]=> + string(26) "2019-09-10 00:00:00.000000" + ["timezone_type"]=> + string(1) "3" + ["timezone"]=> + string(3) "UTC" +} + +array(1) { + ["foo"]=> + int(0) +} +arg.10: array(1) { + ["foo"]=> + string(1) "0" +} + +array(1) { + ["bar"]=> + array(2) { + [0]=> + int(1) + ["key"]=> + int(2) + } +} +arg.11: array(1) { + ["bar"]=> + array(2) { + [0]=> + string(1) "1" + ["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" \ No newline at end of file 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/safe_to_string_metadata_ge_php_84.phpt b/tests/ext/sandbox/safe_to_string_metadata_ge_php_84.phpt index fbec543abc2..fd811fb96e7 100644 --- a/tests/ext/sandbox/safe_to_string_metadata_ge_php_84.phpt +++ b/tests/ext/sandbox/safe_to_string_metadata_ge_php_84.phpt @@ -58,9 +58,14 @@ $allTheTypes[0][1] = &$allTheTypes[0]; call_user_func_array('meta_to_string', $allTheTypes); list($span) = dd_clean_spans(); -unset($span['meta']['process_id']); +// The v1 introspection shape merges meta+metrics into a single attributes map, so +// filter to the 'arg.*' string entries this test set (skipping runtime metrics, +// code-origin tags, etc.) before applying the arg-index/stringify assertions. $last = -1; -foreach ($span['meta'] as $key => $value) { +foreach ($span['attributes'] as $key => $value) { + if (strncmp($key, 'arg.', 4) !== 0) { + continue; + } $index = (int)substr($key, 4); if ($last != $index) { echo PHP_EOL; @@ -80,45 +85,16 @@ array(1) { [0]=> string(9) "recursive" } -arg.0.0: string(9) "recursive" -arg.0.1: string(0) "" +arg.0: array(2) { + [0]=> + string(9) "recursive" + [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" @@ -152,9 +128,14 @@ object(DateTime)#%d (3) { ["timezone"]=> 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: array(3) { + ["date"]=> + string(26) "2019-09-10 00:00:00.000000" + ["timezone_type"]=> + string(1) "3" + ["timezone"]=> + string(3) "UTC" +} object(MyDt)#%d (3) { ["date"]=> @@ -164,6 +145,54 @@ object(MyDt)#%d (3) { ["timezone"]=> 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: array(3) { + ["date"]=> + string(26) "2019-09-10 00:00:00.000000" + ["timezone_type"]=> + string(1) "3" + ["timezone"]=> + string(3) "UTC" +} + +array(1) { + ["foo"]=> + int(0) +} +arg.10: array(1) { + ["foo"]=> + string(1) "0" +} + +array(1) { + ["bar"]=> + array(2) { + [0]=> + int(1) + ["key"]=> + int(2) + } +} +arg.11: array(1) { + ["bar"]=> + array(2) { + [0]=> + string(1) "1" + ["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..723ba500515 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; @@ -48,13 +51,16 @@ foreach ($span['metrics'] as $key => $value) { } ?> --EXPECTF-- - array(1) { [0]=> int(42) } -arg.0.0: float(42) -arg.0.1: float(0) +arg.0: array(2) { + [0]=> + float(42) + [1]=> + float(0) +} int(42) arg.1: float(42) @@ -72,7 +78,10 @@ array(1) { [0]=> float(4.2) } -arg.5.0: float(4.2) +arg.5: array(1) { + [0]=> + float(4.2) +} array(3) { [0]=> @@ -82,9 +91,14 @@ array(3) { [2]=> float(3.3) } -arg.6.0: float(1.1) -arg.6.1: float(2.2) -arg.6.2: float(3.3) +arg.6: array(3) { + [0]=> + float(1.1) + [1]=> + float(2.2) + [2]=> + float(3.3) +} array(3) { [0]=> @@ -102,7 +116,19 @@ array(3) { float(3.3) } } -arg.7.0.0: float(4.2) -arg.7.0.1: float(42) -arg.7.1: float(2.2) -arg.7.2.0: float(3.3) +arg.7: array(3) { + [0]=> + array(2) { + [0]=> + float(4.2) + [1]=> + float(42) + } + [1]=> + float(2.2) + [2]=> + array(1) { + [0]=> + float(3.3) + } +} \ No newline at end of file diff --git a/tests/ext/sandbox/span_clone.phpt b/tests/ext/sandbox/span_clone.phpt index 0ce6e5ee728..44d2d29fc6a 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 (30) { ["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,49 @@ 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) { - }%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r + } + ["env"]=> + string(0) "" + ["version"]=> + string(0) "" + ["component"]=> + string(0) "" + ["spanKind"]=> + int(0) + ["attributes"]=> + array(2) { + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + float(%f) + } + ["ignoreError"]=> + bool(false)%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 +127,16 @@ object(DDTrace\RootSpanData)#%d (24) { NULL ["inferredSpan"]=> NULL + ["hostname"]=> + string(0) "" } -object(DDTrace\RootSpanData)#%d (24) { +object(DDTrace\RootSpanData)#%d (30) { ["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 +168,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 +178,18 @@ object(DDTrace\RootSpanData)#%d (24) { ["spanCreationObservers"]=> array(0) { } + ["attributes"]=> + array(0) { + } } ["active"]=> - object(DDTrace\RootSpanData)#%d (24) { + object(DDTrace\RootSpanData)#%d (30) { ["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 +227,31 @@ object(DDTrace\RootSpanData)#%d (24) { } ["baggage"]=> array(0) { - }%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r + } + ["env"]=> + string(0) "" + ["version"]=> + string(0) "" + ["component"]=> + string(0) "" + ["spanKind"]=> + int(0) + ["attributes"]=> + array(2) { + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + float(%f) + } + ["ignoreError"]=> + bool(false)%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 +261,46 @@ object(DDTrace\RootSpanData)#%d (24) { NULL ["inferredSpan"]=> NULL + ["hostname"]=> + string(0) "" } ["spanCreationObservers"]=> array(0) { } + ["attributes"]=> + array(0) { + } } ["onClose"]=> array(0) { } ["baggage"]=> array(0) { - }%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r + } + ["env"]=> + string(0) "" + ["version"]=> + string(0) "" + ["component"]=> + string(0) "" + ["spanKind"]=> + int(0) + ["attributes"]=> + array(2) { + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + float(%f) + } + ["ignoreError"]=> + bool(false)%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,12 +310,16 @@ object(DDTrace\RootSpanData)#%d (24) { NULL ["inferredSpan"]=> NULL + ["hostname"]=> + string(0) "" } array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -269,28 +334,23 @@ 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" + ["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/sdk_otlp_export_marker.phpt b/tests/ext/sdk_otlp_export_marker.phpt index 1c04645c8fb..0a9fb54f4b3 100644 --- a/tests/ext/sdk_otlp_export_marker.phpt +++ b/tests/ext/sdk_otlp_export_marker.phpt @@ -18,7 +18,7 @@ $seen = []; foreach (dd_trace_serialize_closed_spans() as $span) { $first = !isset($seen[$span['trace_id']]); $seen[$span['trace_id']] = true; - echo ($first ? "first" : "other"), ": ", var_export($span['meta']['_dd.sdk.otlp_export'] ?? null, true), "\n"; + echo ($first ? "first" : "other"), ": ", var_export($span['attributes']['_dd.sdk.otlp_export'] ?? null, true), "\n"; } echo count($seen), " chunks\n"; ?> 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"])); diff --git a/tests/ext/span_attributes_empty_keys.phpt b/tests/ext/span_attributes_empty_keys.phpt new file mode 100644 index 00000000000..aa75f194f89 --- /dev/null +++ b/tests/ext/span_attributes_empty_keys.phpt @@ -0,0 +1,27 @@ +--TEST-- +Empty attribute keys and values survive the native read-back (empty Rust slices carry a dangling ptr) +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--FILE-- +attributes = [ + '' => 'empty key', // dropped: a top-level attribute needs a key + 'empty' => '', + 'nested' => ['a' => ['b' => ['' => 1, 'c' => '']]], + 'list' => ['', ['' => '']], +]; +\DDTrace\close_span(); + +$attrs = dd_trace_serialize_closed_spans()[0]['attributes']; +foreach (['', 'empty', 'nested', 'list'] as $key) { + echo var_export($key, true), ' => ', json_encode(isset($attrs[$key]) ? $attrs[$key] : null), "\n"; +} +?> +--EXPECT-- +'' => null +'empty' => "" +'nested' => {"a":{"b":{"":1,"c":""}}} +'list' => ["",{"":""}] diff --git a/tests/ext/span_attributes_input.phpt b/tests/ext/span_attributes_input.phpt new file mode 100644 index 00000000000..60b4f712f77 --- /dev/null +++ b/tests/ext/span_attributes_input.phpt @@ -0,0 +1,119 @@ +--TEST-- +SpanData::$attributes is the tag store: typed values, $meta/$metrics writes land in it (last write wins), special keys lifted +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--FILE-- +name = 'original.name'; +$s->attributes = [ + 'int' => 42, + 'float' => 1.5, + 'bool' => true, + 'string' => 'str', + 'null' => null, + 'list' => [1, 'two', false], + 'map' => ['k' => 'v', 'n' => [3]], + 'object' => new Point, + // overwritten below through $meta / $metrics + 'both' => 'from attributes', + 'all' => 'from attributes', + // special keys + 'service.name' => 'attr-service', + 'resource.name' => 'attr-resource', + 'operation.name' => 'Attr.Operation', + 'span.type' => 'attr-type', + 'env' => 'attr-env', + 'version' => 'attr-version', + 'component' => 'attr-component', + 'span.kind' => 'client', + 'analytics.event' => true, + 'http.status_code' => 404, + '_sampling_priority_v1' => 2, + '_dd1.sr.eausr' => 1, + 'error.ignored' => true, +]; +$s->meta['both'] = 'from meta'; +$s->meta['all'] = 'from meta'; +$s->meta['meta_only'] = 'from meta'; +$s->meta['meta_metric'] = 'from meta'; +$s->metrics['all'] = 3; +$s->metrics['meta_metric'] = 4; +$s->metrics['metric_only'] = 5; +$s->exception = new Exception('ignored via the attributes tag'); +\DDTrace\close_span(); + +$span = dd_trace_serialize_closed_spans()[0]; +foreach (['name', 'resource', 'service', 'type', 'env', 'version', 'component', 'span_kind'] as $field) { + echo "$field: ", var_export(isset($span[$field]) ? $span[$field] : null, true), "\n"; +} +echo "error: ", isset($span['error']) ? $span['error'] : 0, "\n"; +$attrs = $span['attributes']; +foreach (['runtime-id', 'process_id', '_dd.p.tid', '_dd.p.dm', '_dd.tags.process', '_dd.sdk.otlp_export', '_dd.agent_psr', '_dd.svc_src', 'php.compilation.total_time_ms', 'php.memory.peak_real_usage_bytes', 'php.memory.peak_usage_bytes'] as $volatile) { + unset($attrs[$volatile]); +} +ksort($attrs); +var_dump($attrs); +?> +--EXPECT-- +name: 'attr.operation' +resource: 'attr-resource' +service: 'attr-service' +type: 'attr-type' +env: 'attr-env' +version: 'attr-version' +component: 'attr-component' +span_kind: 3 +error: 0 +array(14) { + ["_dd1.sr.eausr"]=> + float(1) + ["all"]=> + float(3) + ["bool"]=> + bool(true) + ["both"]=> + string(9) "from meta" + ["float"]=> + float(1.5) + ["http.status_code"]=> + string(3) "404" + ["int"]=> + int(42) + ["list"]=> + array(3) { + [0]=> + int(1) + [1]=> + string(3) "two" + [2]=> + bool(false) + } + ["map"]=> + array(2) { + ["k"]=> + string(1) "v" + ["n"]=> + array(1) { + [0]=> + int(3) + } + } + ["meta_metric"]=> + float(4) + ["meta_only"]=> + string(9) "from meta" + ["metric_only"]=> + float(5) + ["object"]=> + array(1) { + ["x"]=> + int(1) + } + ["string"]=> + string(3) "str" +} \ No newline at end of file diff --git a/tests/ext/span_data_attributes_init.phpt b/tests/ext/span_data_attributes_init.phpt new file mode 100644 index 00000000000..bacd6de58ac --- /dev/null +++ b/tests/ext/span_data_attributes_init.phpt @@ -0,0 +1,47 @@ +--TEST-- +Directly constructed span/stack objects expose an initialized attributes array +--DESCRIPTION-- +The declared `public array $attributes = []` must materialize to an empty array on +every PHP version. On PHP 7 the create_object callbacks (dd_init_span_data_object, +ddtrace_span_stack_create) must init property_attributes explicitly, since typed +array properties there default to NULL rather than their stub default. +--FILE-- +attributes); +var_dump((new \DDTrace\RootSpanData())->attributes); +var_dump((new \DDTrace\InferredSpanData())->attributes); +var_dump((new \DDTrace\SpanStack())->attributes); +var_dump((new UserSpan())->attributes); + +$span = new UserSpan(); +$span->attributes['k'] = 'v'; +var_dump($span->attributes); + +// Tracer-created spans and stacks go through the same create_object callbacks. +$s = \DDTrace\start_span(); +var_dump($s->attributes, $s->stack->attributes); +\DDTrace\close_span(); +?> +--EXPECT-- +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(1) { + ["k"]=> + string(1) "v" +} +array(0) { +} +array(0) { +} diff --git a/tests/ext/span_data_meta_view.phpt b/tests/ext/span_data_meta_view.phpt new file mode 100644 index 00000000000..c86802fa5b1 --- /dev/null +++ b/tests/ext/span_data_meta_view.phpt @@ -0,0 +1,141 @@ +--TEST-- +SpanData::$meta and $metrics are views onto SpanData::$attributes +--DESCRIPTION-- +$attributes is the single tag store: writes, unsets and reads through the deprecated $meta +(non-numeric entries, stored as strings) and $metrics (numeric entries, stored as floats) act on it, +and the last write wins. +--ENV-- +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TAGS=team:a,region:eu +--FILE-- +attributes['http.url'] = 'https://tracer.example'; +var_dump($span->meta['http.url']); +$span->meta['http.url'] = 'https://user.example'; +var_dump($span->attributes['http.url']); + +echo "-- unset through meta\n"; +unset($span->meta['http.url']); +var_dump(isset($span->attributes['http.url']), isset($span->meta['http.url'])); + +echo "-- buckets and coercion\n"; +$span->meta['num'] = 42; +$span->metrics['m'] = 3; +var_dump($span->attributes['num'], $span->attributes['m']); +var_dump(isset($span->meta['m']), isset($span->metrics['m']), isset($span->metrics['num'])); +var_dump($span->meta['missing'] ?? 'default', empty($span->meta['num'])); + +echo "-- array functions on a read\n"; +var_dump(is_array($span->meta), array_key_exists('num', $span->meta), array_key_exists('m', $span->meta)); +$merged = array_merge($span->meta, ['x' => 'y']); +var_dump($merged['num'], $merged['x']); +$span->meta += ['added' => 'yes']; +var_dump($span->attributes['added']); + +echo "-- nested values keep the old string leaves\n"; +$span->meta['nested'] = ['a' => 1, 'b' => [true, null], 'c' => []]; +var_dump($span->attributes['nested']); + +echo "-- whole-array assignment replaces the bucket\n"; +$span->meta = ['only' => 'this']; +var_dump($span->meta, $span->metrics['m'], isset($span->attributes['team'])); + +echo "-- iteration and the view object\n"; +$span->meta['k2'] = 'v2'; +foreach ($span->meta as $k => $v) { + echo "$k=$v\n"; +} +$view = &$span->meta; +var_dump(get_class($view), count($view), $view instanceof ArrayAccess, $view instanceof Countable, $view instanceof IteratorAggregate); +$view['via_ref'] = 'r'; +unset($view); +var_dump($span->attributes['via_ref']); + +echo "-- isset/?? contexts and writes through attributes\n"; +$x = $span->meta ?? []; +var_dump(is_array($x), array_merge($x, ['extra' => 'e'])['extra']); +$span->attributes['via_attrs'] = 'a'; +var_dump(isset($span->meta['via_attrs']), isset($span->metrics['via_attrs'])); +\DDTrace\close_span(); + +echo "-- DD_TAGS globals\n"; +$s1 = \DDTrace\start_span(); +$s1->name = 's1'; +unset($s1->meta['team']); +\DDTrace\close_span(); +$s2 = \DDTrace\start_span(); +$s2->name = 's2'; +$s2->meta['team'] = 'b'; +\DDTrace\close_span(); +\DDTrace\close_span(); +foreach (dd_trace_serialize_closed_spans() as $serialized) { + if (in_array($serialized['name'], ['s1', 's2'])) { + echo $serialized['name'], ': team=', $serialized['attributes']['team'] ?? 'unset', ' region=', $serialized['attributes']['region'], "\n"; + } +} +?> +--EXPECT-- +-- tracer tag read and overridden through meta +string(22) "https://tracer.example" +string(20) "https://user.example" +-- unset through meta +bool(false) +bool(false) +-- buckets and coercion +string(2) "42" +float(3) +bool(false) +bool(true) +bool(false) +string(7) "default" +bool(false) +-- array functions on a read +bool(true) +bool(true) +bool(false) +string(2) "42" +string(1) "y" +string(3) "yes" +-- nested values keep the old string leaves +array(3) { + ["a"]=> + string(1) "1" + ["b"]=> + array(2) { + [0]=> + string(4) "true" + [1]=> + string(4) "null" + } + ["c"]=> + string(0) "" +} +-- whole-array assignment replaces the bucket +array(1) { + ["only"]=> + string(4) "this" +} +float(3) +bool(false) +-- iteration and the view object +only=this +k2=v2 +string(20) "DDTrace\SpanTagsView" +int(2) +bool(true) +bool(true) +bool(true) +string(1) "r" +-- isset/?? contexts and writes through attributes +bool(true) +string(1) "e" +bool(true) +bool(false) +-- DD_TAGS globals +s2: team=b region=eu +s1: team=unset region=eu diff --git a/tests/ext/span_data_meta_view_jit.phpt b/tests/ext/span_data_meta_view_jit.phpt new file mode 100644 index 00000000000..3b45f92effc --- /dev/null +++ b/tests/ext/span_data_meta_view_jit.phpt @@ -0,0 +1,48 @@ +--TEST-- +SpanData::$meta / $metrics views under the tracing JIT +--SKIPIF-- + + +--ENV-- +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_TRACE_GENERATE_ROOT_SPAN=0 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=32M +opcache.jit=tracing +opcache.jit_hot_loop=1 +opcache.jit_hot_func=1 +zend_extension=opcache.so +--FILE-- +meta["k$i"] = $i; + $span->metrics["m$i"] = $i; + if (isset($span->meta["k" . ($i - 1)])) { + unset($span->meta["k" . ($i - 1)]); + } + return count($span->meta) + count($span->metrics); +} + +\DDTrace\start_span(); +$span = \DDTrace\start_span(); +$total = 0; +for ($i = 0; $i < 200; $i++) { + $total += tag($span, $i); +} +$meta = $span->meta; +var_dump($total > 0, array_values(preg_grep('/^k/', array_keys($meta))), $span->attributes['k199']); +var_dump(count(preg_grep('/^m\d+$/', array_keys($span->metrics))), $span->metrics['m199']); +\DDTrace\close_span(); +\DDTrace\close_span(); +?> +--EXPECT-- +bool(true) +array(1) { + [0]=> + string(4) "k199" +} +string(3) "199" +int(200) +float(199) diff --git a/tests/ext/span_ignore_error.phpt b/tests/ext/span_ignore_error.phpt new file mode 100644 index 00000000000..513c8c6190a --- /dev/null +++ b/tests/ext/span_ignore_error.phpt @@ -0,0 +1,65 @@ +--TEST-- +SpanData::$ignoreError and the deprecated meta['error.ignored'] suppress the span error; the child gets track_error=false +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +--FILE-- +ignoreError); + +function run($label, $ignore) { + echo "$label\n"; + $e = new Exception("boom"); + $root = \DDTrace\start_span(); + $root->name = 'root'; + $child = \DDTrace\start_span(); + $child->name = 'child'; + $child->exception = $e; + \DDTrace\close_span(); + $root->exception = $e; + $ignore($root); + \DDTrace\close_span(); + foreach (dd_trace_serialize_closed_spans() as $span) { + $attrs = isset($span['attributes']) ? $span['attributes'] : []; + $errorTags = array_filter(array_keys($attrs), function ($k) { return strpos($k, 'error') === 0; }); + sort($errorTags); + echo " ", $span['name'], ": error=", isset($span['error']) ? $span['error'] : 0, + " error tags=[", implode(',', $errorTags), "]", + " track_error=", isset($attrs['track_error']) ? $attrs['track_error'] : '-', "\n"; + } + echo " root ignoreError after flush: ", var_export($root->ignoreError, true), "\n"; +} + +run('not ignored', function ($root) {}); +run('property', function ($root) { $root->ignoreError = true; }); +run('deprecated tag', function ($root) { $root->meta['error.ignored'] = 1; }); +run('deprecated falsy tag cannot unset the property', function ($root) { $root->ignoreError = true; $root->meta['error.ignored'] = 0; }); +run('deprecated falsy tag alone', function ($root) { $root->meta['error.ignored'] = 0; }); +run('falsy attributes tag does not mask a truthy meta tag', function ($root) { $root->attributes['error.ignored'] = 0; $root->meta['error.ignored'] = 1; }); +?> +--EXPECT-- +bool(false) +not ignored + root: error=1 error tags=[error.message,error.stack,error.type] track_error=- + child: error=1 error tags=[error.message,error.stack,error.type] track_error=- + root ignoreError after flush: false +property + root: error=0 error tags=[] track_error=- + child: error=1 error tags=[error.message,error.stack,error.type] track_error=false + root ignoreError after flush: true +deprecated tag + root: error=0 error tags=[] track_error=- + child: error=1 error tags=[error.message,error.stack,error.type] track_error=false + root ignoreError after flush: true +deprecated falsy tag cannot unset the property + root: error=0 error tags=[] track_error=- + child: error=1 error tags=[error.message,error.stack,error.type] track_error=false + root ignoreError after flush: true +deprecated falsy tag alone + root: error=1 error tags=[error.message,error.stack,error.type] track_error=- + child: error=1 error tags=[error.message,error.stack,error.type] track_error=- + root ignoreError after flush: false +falsy attributes tag does not mask a truthy meta tag + root: error=0 error tags=[] track_error=- + child: error=1 error tags=[error.message,error.stack,error.type] track_error=false + root ignoreError after flush: true diff --git a/tests/ext/span_kind_meta_fallback_promoted.phpt b/tests/ext/span_kind_meta_fallback_promoted.phpt new file mode 100644 index 00000000000..b764dc426e5 --- /dev/null +++ b/tests/ext/span_kind_meta_fallback_promoted.phpt @@ -0,0 +1,30 @@ +--TEST-- +Root span with only meta["span.kind"] (no property) still promotes span_kind (R2 meta fallback) +--DESCRIPTION-- +Entrypoint/integration spans set span.kind via meta (serializer writes meta["span.kind"]="server" +for HTTP roots), not via the OTel property. The V1-only serializer must fall back to the meta value +when property_span_kind is unset, so the promoted top-level span_kind is still emitted. Agent-free: +asserts the introspection view that mirrors the V1 builder's promoted fields. +--INI-- +datadog.trace.generate_root_span=0 +--ENV-- +DD_TRACE_AUTO_FLUSH_ENABLED=0 +--FILE-- +name = "http.request"; +$s->service = "web"; +$s->meta["span.kind"] = "server"; // meta only, no $s->kind property +\DDTrace\close_span(); + +$spans = dd_trace_serialize_closed_spans(); +$root = $spans[0]; +// server == OTEL SpanKind 2; promoted from meta fallback (dd_span_kind_meta_to_otel). The serializer +// consumes meta["span.kind"] once promoted, so the introspection (pre-encode builder) view no longer +// carries it in the unified attributes map; the wire decoders re-materialise span.kind downstream. +echo "span_kind=" . var_export($root["span_kind"] ?? null, true) . "\n"; +echo "attributes.span.kind=" . var_export($root["attributes"]["span.kind"] ?? null, true) . "\n"; +?> +--EXPECT-- +span_kind=2 +attributes.span.kind=NULL diff --git a/tests/ext/span_link_event_recursive_attributes.phpt b/tests/ext/span_link_event_recursive_attributes.phpt new file mode 100644 index 00000000000..9363a9061eb --- /dev/null +++ b/tests/ext/span_link_event_recursive_attributes.phpt @@ -0,0 +1,57 @@ +--TEST-- +Self-referencing span link, event and meta attributes serialize with a bounded "" placeholder +--ENV-- +DD_TRACE_DEBUG_PRNG_SEED=42 +--FILE-- +name = 'foo'; + + $arr = ['x']; + $arr[] = &$arr; + $obj = new stdClass; + $obj->v = 1; + $obj->self = $obj; + $ao = new ArrayObject(['d' => 2]); + $ao['self'] = $ao; + // DateTime builds a fresh properties table on every read, so only an object-level guard stops it. + $dt = new DateTime('2020-01-01 00:00:00 UTC'); + @$dt->self = $dt; + $attrs = ['arr' => $arr, 'obj' => $obj, 'ao' => $ao, 'empty' => []]; + + $link = new SpanLink(); + $link->traceId = "42"; + $link->spanId = "6"; + $link->attributes = $attrs + ['dt' => $dt]; + $span->links[] = $link; + $span->events[] = new SpanEvent('evt', $attrs + ['dt' => $dt], 1); + $span->meta['dt'] = $dt; +}); + +foo(); + +$spans = dd_trace_serialize_closed_spans(); +foreach ([$spans[0]['span_links'][0]['attributes'], $spans[0]['span_events'][0]['attributes']] as $attrs) { + $dt = $attrs['dt']; + unset($attrs['dt']); + echo json_encode($attrs), "\n"; + var_dump($dt['self'], $dt['timezone']); +} +var_dump($spans[0]['attributes']['dt']['self']); + +?> +--EXPECT-- +{"arr":["x",""],"obj":{"v":1,"self":""},"ao":{"d":2,"self":""},"empty":[]} +string(0) "" +string(3) "UTC" +{"arr":["x",""],"obj":{"v":1,"self":""},"ao":{"d":2,"self":""},"empty":[]} +string(0) "" +string(3) "UTC" +string(0) "" diff --git a/tests/ext/span_on_close.phpt b/tests/ext/span_on_close.phpt index a58461fa4e3..7267d0e6fb1 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/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/span_with_removed_exception.phpt b/tests/ext/span_with_removed_exception.phpt index a4bf52232f0..f09f177e2ca 100644 --- a/tests/ext/span_with_removed_exception.phpt +++ b/tests/ext/span_with_removed_exception.phpt @@ -54,9 +54,11 @@ try { --EXPECTF-- array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -71,37 +73,34 @@ array(1) { string(31) "span_with_removed_exception.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(3) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["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) } } } array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -116,37 +115,34 @@ array(1) { string(31) "span_with_removed_exception.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(3) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["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) } } } array(1) { [0]=> - array(10) { + array(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -161,28 +157,23 @@ array(1) { string(31) "span_with_removed_exception.php" ["type"]=> string(3) "cli" - ["meta"]=> - array(3) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["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_with_all_properties.phpt b/tests/ext/start_span_with_all_properties.phpt index 4ce1682c97a..c264bafd55a 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -75,35 +77,32 @@ 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" + ["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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -118,34 +117,29 @@ array(2) { string(4) "test" ["type"]=> string(6) "runner" - ["meta"]=> - array(5) { - ["_dd.p.dm"]=> - string(2) "-0" - ["_dd.p.tid"]=> - string(16) "%s" + ["sampling_priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["attributes"]=> + array(9) { + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + float(%f) ["_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) ["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..eca8c28fab7 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(12) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["start"]=> @@ -47,28 +49,23 @@ 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" + ["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..338eefdb7dd 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(10) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> 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 --EXPECT-- root service: my-app diff --git a/tests/ext/svc_src_inheritance.phpt b/tests/ext/svc_src_inheritance.phpt index 0e339b5a4a9..c330b7c7d4e 100644 --- a/tests/ext/svc_src_inheritance.phpt +++ b/tests/ext/svc_src_inheritance.phpt @@ -18,8 +18,8 @@ $child->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 6512b575e72..cdc3952a331 100644 --- a/tests/ext/telemetry/broken_pipe.phpt +++ b/tests/ext/telemetry/broken_pipe.phpt @@ -76,7 +76,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/test_special_attributes.phpt b/tests/ext/test_special_attributes.phpt index 1539e37ff7e..2f010af5034 100644 --- a/tests/ext/test_special_attributes.phpt +++ b/tests/ext/test_special_attributes.phpt @@ -36,6 +36,8 @@ array(1) { array(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -52,17 +54,14 @@ array(1) { string(11) "new.service" ["type"]=> string(8) "new.type" - ["meta"]=> - array(2) { - ["_dd.base_service"]=> - string(27) "test_special_attributes.php" - ["_dd.svc_src"]=> - string(1) "m" - } - ["metrics"]=> - array(1) { + ["attributes"]=> + array(3) { ["_dd1.sr.eausr"]=> float(1) + ["_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 d08ff85c7bf..d0486fc96a6 100644 --- a/tests/ext/test_special_attributes_bis.phpt +++ b/tests/ext/test_special_attributes_bis.phpt @@ -37,6 +37,8 @@ array(1) { array(11) { ["trace_id"]=> string(%d) "%d" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -53,17 +55,14 @@ array(1) { string(14) "mapped.service" ["type"]=> string(8) "new.type" - ["meta"]=> - array(2) { - ["_dd.base_service"]=> - string(31) "test_special_attributes_bis.php" - ["_dd.svc_src"]=> - string(1) "m" - } - ["metrics"]=> - array(1) { + ["attributes"]=> + array(3) { ["_dd1.sr.eausr"]=> float(1) + ["_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/traced_attribute_tags_recursive_and_empty.phpt b/tests/ext/traced_attribute_tags_recursive_and_empty.phpt new file mode 100644 index 00000000000..276de719d5d --- /dev/null +++ b/tests/ext/traced_attribute_tags_recursive_and_empty.phpt @@ -0,0 +1,32 @@ +--TEST-- +#[DDTrace\Trace] tags: a self-referencing object tag becomes "" at the cycle, and empty tags are accepted +--SKIPIF-- + +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--FILE-- +me = $this; } +} + +#[DDTrace\Trace(name: "recursive", tags: ["s" => new SelfRef])] +function recursive() {} + +#[DDTrace\Trace(name: "empty", tags: [])] +function emptyTags() {} + +recursive(); +emptyTags(); + +foreach (dd_trace_serialize_closed_spans() as $span) { + echo $span['name'], ": ", json_encode(isset($span['attributes']['s']) ? $span['attributes']['s'] : null), "\n"; +} +?> +--EXPECT-- +empty: null +recursive: {"me":"","v":"1"} diff --git a/tests/ext/ust.phpt b/tests/ext/ust.phpt index 08e02f7387f..7f36e2485bb 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,27 @@ array(2) { string(12) "version_test" ["type"]=> string(3) "cli" - ["meta"]=> + ["env"]=> + string(8) "env_test" + ["version"]=> + string(5) "5.2.0" + ["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 +74,8 @@ array(2) { array(%d) { ["trace_id"]=> string(%d) "%s" + ["trace_id_high"]=> + string(16) "%s" ["span_id"]=> string(%d) "%s" ["start"]=> @@ -91,27 +90,22 @@ array(2) { string(13) "no dd_service" ["type"]=> string(3) "cli" - ["meta"]=> + ["env"]=> + string(8) "env_test" + ["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) ["process_id"]=> float(%f) + ["_dd.svc_src"]=> + string(1) "m" + ["_dd.agent_psr"]=> + float(1) } } } 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'] ] ]); } 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/tests/opcache/include_trace_attribute.php b/tests/opcache/include_trace_attribute.php index 2c2289a90e0..f3eaba2a055 100644 --- a/tests/opcache/include_trace_attribute.php +++ b/tests/opcache/include_trace_attribute.php @@ -6,7 +6,7 @@ final class PreloadedTraced { const TAGS = ['component' => 'preloaded']; - #[\DDTrace\Trace(name: "preloaded.method", resource: "rsrc", tags: self::TAGS)] + #[\DDTrace\Trace(name: "preloaded.method", resource: "rsrc", attributes: self::TAGS)] public static function method() { $span = \DDTrace\active_span(); diff --git a/tests/opcache/preload_trace_attribute.phpt b/tests/opcache/preload_trace_attribute.phpt index ad429e3c664..58537364635 100644 --- a/tests/opcache/preload_trace_attribute.phpt +++ b/tests/opcache/preload_trace_attribute.phpt @@ -32,7 +32,12 @@ final class TraitUser (new TraitUser())->viaTrait(); (new TraitUser())->viaTrait(); -$names = array_column(dd_trace_serialize_closed_spans(), 'name'); +$names = []; +foreach (dd_trace_serialize_closed_spans()['chunks'] as $chunk) { + foreach ($chunk['spans'] as $span) { + $names[] = $span['name']; + } +} sort($names); echo implode("\n", $names), "\n"; ?> diff --git a/tests/opcache/span_attributes_immutable_arrays.phpt b/tests/opcache/span_attributes_immutable_arrays.phpt new file mode 100644 index 00000000000..28143ffff0c --- /dev/null +++ b/tests/opcache/span_attributes_immutable_arrays.phpt @@ -0,0 +1,45 @@ +--TEST-- +Immutable (opcache SHM) arrays as span meta/metrics and link/event attributes serialize without being written to +--SKIPIF-- + +--ENV-- +DD_TRACE_DEBUG_PRNG_SEED=42 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.protect_memory=1 +opcache.file_update_protection=0 +--FILE-- +name = 'foo'; +$span->meta['flat'] = ['a', 'b']; +$span->meta['nested'] = ['k' => ['x' => [1, 2]], 'v' => 'w']; +$span->metrics['m'] = [1, 2.5]; + +$link = new SpanLink(); +$link->traceId = "42"; +$link->spanId = "6"; +$link->attributes = ['list' => [1, 2], 'map' => ['a' => ['b' => true]]]; +$span->links[] = $link; +$span->events[] = new SpanEvent('evt', ['list' => ['x', 'y'], 'map' => ['n' => [3]]], 1); +\DDTrace\close_span(); + +$spans = dd_trace_serialize_closed_spans(); +echo json_encode([ + $spans[0]['attributes']['flat'], + $spans[0]['attributes']['nested'], + $spans[0]['attributes']['m'], + $spans[0]['span_links'][0]['attributes'], + $spans[0]['span_events'][0]['attributes'], +]), "\n"; +var_dump(opcache_get_status(false)['opcache_enabled']); + +?> +--EXPECT-- +[["a","b"],{"k":{"x":["1","2"]},"v":"w"},[1,2.5],{"list":[1,2],"map":{"a":{"b":true}}},{"list":["x","y"],"map":{"n":[3]}}] +bool(true) diff --git a/tests/snapshots/integrations.code_igniter.v3_1.no_ci_controller_test.test_scenario_health_check.json b/tests/snapshots/integrations.code_igniter.v3_1.no_ci_controller_test.test_scenario_health_check.json index 94f4baa2036..4b434afcdae 100644 --- a/tests/snapshots/integrations.code_igniter.v3_1.no_ci_controller_test.test_scenario_health_check.json +++ b/tests/snapshots/integrations.code_igniter.v3_1.no_ci_controller_test.test_scenario_health_check.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.cli.symfony.latest.common_scenarios_test.test_silenced_spans_are_dropped.json b/tests/snapshots/tests.integrations.cli.symfony.latest.common_scenarios_test.test_silenced_spans_are_dropped.json index b70090a34de..41edfa5f224 100644 --- a/tests/snapshots/tests.integrations.cli.symfony.latest.common_scenarios_test.test_silenced_spans_are_dropped.json +++ b/tests/snapshots/tests.integrations.cli.symfony.latest.common_scenarios_test.test_silenced_spans_are_dropped.json @@ -14,6 +14,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }, @@ -48,6 +49,9 @@ "_dd.code_origin.frames.6.line": "11", "_dd.code_origin.type": "exit", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -61,6 +65,9 @@ "meta": { "_dd.base_service": "console", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -75,6 +82,9 @@ "_dd.base_service": "console", "component": "symfony", "symfony.console.command.class": "App\\Command\\SttyCommand" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -88,5 +98,8 @@ "meta": { "_dd.base_service": "console", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }]] diff --git a/tests/snapshots/tests.integrations.cli.symfony.v4_4.common_scenarios_test.test_silenced_spans_are_dropped.json b/tests/snapshots/tests.integrations.cli.symfony.v4_4.common_scenarios_test.test_silenced_spans_are_dropped.json index 33cae852b2d..5158782ea4a 100644 --- a/tests/snapshots/tests.integrations.cli.symfony.v4_4.common_scenarios_test.test_silenced_spans_are_dropped.json +++ b/tests/snapshots/tests.integrations.cli.symfony.v4_4.common_scenarios_test.test_silenced_spans_are_dropped.json @@ -14,6 +14,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }, @@ -48,6 +49,9 @@ "_dd.code_origin.frames.4.line": "42", "_dd.code_origin.type": "exit", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -61,6 +65,9 @@ "meta": { "_dd.base_service": "console", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -75,6 +82,9 @@ "_dd.base_service": "console", "component": "symfony", "symfony.console.command.class": "App\\Command\\SttyCommand" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -88,5 +98,8 @@ "meta": { "_dd.base_service": "console", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }]] diff --git a/tests/snapshots/tests.integrations.cli.symfony.v5_2.common_scenarios_test.test_silenced_spans_are_dropped.json b/tests/snapshots/tests.integrations.cli.symfony.v5_2.common_scenarios_test.test_silenced_spans_are_dropped.json index 929c34b97aa..41d50574433 100644 --- a/tests/snapshots/tests.integrations.cli.symfony.v5_2.common_scenarios_test.test_silenced_spans_are_dropped.json +++ b/tests/snapshots/tests.integrations.cli.symfony.v5_2.common_scenarios_test.test_silenced_spans_are_dropped.json @@ -14,6 +14,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }, @@ -48,6 +49,9 @@ "_dd.code_origin.frames.4.line": "43", "_dd.code_origin.type": "exit", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -61,6 +65,9 @@ "meta": { "_dd.base_service": "console", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -75,6 +82,9 @@ "_dd.base_service": "console", "component": "symfony", "symfony.console.command.class": "App\\Command\\SttyCommand" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -88,5 +98,8 @@ "meta": { "_dd.base_service": "console", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }]] diff --git a/tests/snapshots/tests.integrations.cli.symfony.v6_2.common_scenarios_test.test_silenced_spans_are_dropped.json b/tests/snapshots/tests.integrations.cli.symfony.v6_2.common_scenarios_test.test_silenced_spans_are_dropped.json index 2c72d326a01..09042e94eee 100644 --- a/tests/snapshots/tests.integrations.cli.symfony.v6_2.common_scenarios_test.test_silenced_spans_are_dropped.json +++ b/tests/snapshots/tests.integrations.cli.symfony.v6_2.common_scenarios_test.test_silenced_spans_are_dropped.json @@ -14,6 +14,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }, @@ -48,6 +49,9 @@ "_dd.code_origin.frames.4.line": "43", "_dd.code_origin.type": "exit", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -77,6 +81,9 @@ "meta": { "_dd.base_service": "console", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -91,6 +98,9 @@ "_dd.base_service": "console", "component": "symfony", "symfony.console.command.class": "App\\Command\\SttyCommand" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -104,5 +114,8 @@ "meta": { "_dd.base_service": "console", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }]] diff --git a/tests/snapshots/tests.integrations.cli.symfony.v7_3.common_scenarios_test.test_silenced_spans_are_dropped.json b/tests/snapshots/tests.integrations.cli.symfony.v7_3.common_scenarios_test.test_silenced_spans_are_dropped.json index ab515a77696..e218355e4aa 100644 --- a/tests/snapshots/tests.integrations.cli.symfony.v7_3.common_scenarios_test.test_silenced_spans_are_dropped.json +++ b/tests/snapshots/tests.integrations.cli.symfony.v7_3.common_scenarios_test.test_silenced_spans_are_dropped.json @@ -14,6 +14,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }, @@ -48,6 +49,9 @@ "_dd.code_origin.frames.6.line": "11", "_dd.code_origin.type": "exit", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -77,6 +81,9 @@ "meta": { "_dd.base_service": "console", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -91,6 +98,9 @@ "_dd.base_service": "console", "component": "symfony", "symfony.console.command.class": "App\\Command\\SttyCommand" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -104,5 +114,8 @@ "meta": { "_dd.base_service": "console", "component": "symfony" + }, + "metrics": { + "_dd.top_level": 1 } }]] diff --git a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_parameterized.json b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_parameterized.json index 1da3301fe8b..7f6f2288bfc 100644 --- a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_parameterized.json +++ b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_parameterized.json @@ -20,6 +20,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_return_string.json index 6f874986516..039730f2ece 100644 --- a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_return_string.json @@ -20,6 +20,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_to_missing_route.json index 5170c9dbe32..b688f9898e8 100644 --- a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }]] diff --git a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_to_missing_route_cgi.json b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_to_missing_route_cgi.json index c50a1bd1bf6..5dd7bf72465 100644 --- a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_to_missing_route_cgi.json +++ b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_to_missing_route_cgi.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }]] diff --git a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_exception.json index c89ca53ba12..98b8df7f91c 100644 --- a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_exception.json @@ -24,6 +24,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_exception_cgi.json b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_exception_cgi.json index 49e57af64c0..449cde8c08b 100644 --- a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_exception_cgi.json +++ b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_exception_cgi.json @@ -24,6 +24,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_view.json index f1c4002d99b..211d5220188 100644 --- a/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.code_igniter.v3_1.common_scenarios_test.test_scenario_get_with_view.json @@ -20,6 +20,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.code_igniter.v3_1.exit_test.test_scenario_exit.json b/tests/snapshots/tests.integrations.code_igniter.v3_1.exit_test.test_scenario_exit.json index fb342972d71..641f60e4f12 100644 --- a/tests/snapshots/tests.integrations.code_igniter.v3_1.exit_test.test_scenario_exit.json +++ b/tests/snapshots/tests.integrations.code_igniter.v3_1.exit_test.test_scenario_exit.json @@ -20,6 +20,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_to_missing_route.json index 18190be1c79..592ca28d228 100644 --- a/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "symfony.route.action": "Drupal\\system\\Controller\\Http4xxController@on404" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_with_exception.json index 4981d83b9ba..61df7c29636 100644 --- a/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_with_exception.json @@ -23,6 +23,7 @@ "symfony.route.name": "error" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_with_view.json index 16afc5508e4..512452ba570 100644 --- a/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.drupal.v10_1.common_scenarios_test.test_scenario_get_with_view.json @@ -19,6 +19,7 @@ "symfony.route.name": "simple_view" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_to_missing_route.json index f96ed6fb99a..9301f9d053a 100644 --- a/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "symfony.route.action": "Drupal\\system\\Controller\\Http4xxController@on404" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_with_exception.json index 18490266bdc..90f6bcf189b 100644 --- a/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_with_exception.json @@ -23,6 +23,7 @@ "symfony.route.name": "error" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_with_view.json index 42eaba32f3e..0f51aa908d0 100644 --- a/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.drupal.v8_9.common_scenarios_test.test_scenario_get_with_view.json @@ -19,6 +19,7 @@ "symfony.route.name": "simple_view" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_to_missing_route.json index 82c03046b6f..9983b39cf3c 100644 --- a/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "symfony.route.action": "Drupal\\system\\Controller\\Http4xxController@on404" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_with_exception.json index a7b5ee58bef..b7286a56a12 100644 --- a/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_with_exception.json @@ -23,6 +23,7 @@ "symfony.route.name": "error" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_with_view.json index fbcc57a8a7f..a780052f9da 100644 --- a/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.drupal.v9_5.common_scenarios_test.test_scenario_get_with_view.json @@ -19,6 +19,7 @@ "symfony.route.name": "simple_view" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.kafka_test.test_distributed_tracing_high_level_producer.json b/tests/snapshots/tests.integrations.kafka_test.test_distributed_tracing_high_level_producer.json index b56f8a0bdbc..abde238ee69 100644 --- a/tests/snapshots/tests.integrations.kafka_test.test_distributed_tracing_high_level_producer.json +++ b/tests/snapshots/tests.integrations.kafka_test.test_distributed_tracing_high_level_producer.json @@ -22,6 +22,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1, "messaging.kafka.partition": -1, "messaging.message_payload_size_bytes": 11 diff --git a/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_consumer.json b/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_consumer.json index 54a5a7197cc..643301750a4 100644 --- a/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_consumer.json +++ b/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_consumer.json @@ -23,6 +23,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1, "messaging.kafka.message_offset": 18, "messaging.kafka.partition": 0, @@ -54,6 +55,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1, "messaging.kafka.message_offset": 19, "messaging.kafka.partition": 0, diff --git a/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_producer.json b/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_producer.json index 7fe2dab3e1a..78594198028 100644 --- a/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_producer.json +++ b/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_producer.json @@ -22,6 +22,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1, "messaging.kafka.partition": -1, "messaging.message_payload_size_bytes": 11 diff --git a/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_consumer.json b/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_consumer.json index 904d2796f9b..55529a131c9 100644 --- a/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_consumer.json +++ b/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_consumer.json @@ -23,6 +23,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1, "messaging.kafka.message_offset": 10, "messaging.kafka.partition": 0, @@ -54,6 +55,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1, "messaging.kafka.message_offset": 11, "messaging.kafka.partition": 0, @@ -83,6 +85,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }]] diff --git a/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_producer.json b/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_producer.json index c85c7b76669..0632de35181 100644 --- a/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_producer.json +++ b/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_producer.json @@ -22,6 +22,7 @@ }, "metrics": { "_dd.agent_psr": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1, "messaging.kafka.partition": -1, "messaging.message_payload_size_bytes": 11 diff --git a/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest2xx.json b/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest2xx.json index 781cebdb29d..877807a6fef 100644 --- a/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest2xx.json +++ b/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest2xx.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest4xx.json b/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest4xx.json index bcd9fe56956..1912e0b7897 100644 --- a/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest4xx.json +++ b/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest4xx.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest5xx.json b/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest5xx.json index b12796c2391..55ee8be5b2e 100644 --- a/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest5xx.json +++ b/tests/snapshots/tests.integrations.laminas.api_tools.latest.rest_test.test_scenario_rest5xx.json @@ -25,6 +25,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_return_string.json index 1bdb15085fc..5ecbf47c32e 100644 --- a/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_return_string.json @@ -20,6 +20,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_to_missing_route.json index cebd2538ca6..ccdc06d7ec3 100644 --- a/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -17,6 +17,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_with_exception.json index 378a177110c..7555d81e765 100644 --- a/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_with_exception.json @@ -24,6 +24,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_with_view.json index 2d16a69aa4d..c4837b309cf 100644 --- a/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.laminas.mvc.latest.common_scenarios_test.test_scenario_get_with_view.json @@ -20,6 +20,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_return_string.json index 1095152bcea..c42fe8d4320 100644 --- a/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_return_string.json @@ -22,6 +22,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_to_missing_route.json index 771abe7c6b1..bd72765dfcc 100644 --- a/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_with_exception.json index b7e009b6638..79d3208952d 100644 --- a/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_with_exception.json @@ -26,6 +26,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_with_view.json index 901042e3de5..e1305168b82 100644 --- a/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.laminas.mvc.v3_3.common_scenarios_test.test_scenario_get_with_view.json @@ -22,6 +22,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.apigw_test.test_laravel_inferred_proxy.json b/tests/snapshots/tests.integrations.laravel.apigw_test.test_laravel_inferred_proxy.json index 30a75fbd360..2f435e1cbf4 100644 --- a/tests/snapshots/tests.integrations.laravel.apigw_test.test_laravel_inferred_proxy.json +++ b/tests/snapshots/tests.integrations.laravel.apigw_test.test_laravel_inferred_proxy.json @@ -20,6 +20,7 @@ }, "metrics": { "_dd.inferred_span": 1, + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, @@ -43,6 +44,9 @@ "runtime-id": "c6544e02-6221-4cb4-8ef7-3539ff93cc34", "span.kind": "server", "version": "1.0" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { diff --git a/tests/snapshots/tests.integrations.laravel.apigw_test.test_laravel_inferred_proxy_exception.json b/tests/snapshots/tests.integrations.laravel.apigw_test.test_laravel_inferred_proxy_exception.json index 1d07dbb6152..0b168b113d1 100644 --- a/tests/snapshots/tests.integrations.laravel.apigw_test.test_laravel_inferred_proxy_exception.json +++ b/tests/snapshots/tests.integrations.laravel.apigw_test.test_laravel_inferred_proxy_exception.json @@ -24,6 +24,7 @@ }, "metrics": { "_dd.inferred_span": 1, + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, @@ -51,6 +52,9 @@ "runtime-id": "c6544e02-6221-4cb4-8ef7-3539ff93cc34", "span.kind": "server", "version": "1.0" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { diff --git a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_dynamic_route.json b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_dynamic_route.json index a259ccb31a7..3ba2e8e3a04 100644 --- a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_dynamic_route.json +++ b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_dynamic_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_return_string.json index 8a232b92304..b1b107fff1b 100644 --- a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_return_string.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_to_missing_route.json index cba33f84cdc..47153756895 100644 --- a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_exception.json index 8f1d421becd..96df301cdbf 100644 --- a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_exception.json @@ -25,6 +25,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_ignored_exception.json b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_ignored_exception.json index ac0e27db473..f37c60706fe 100644 --- a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_ignored_exception.json +++ b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_ignored_exception.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_view.json index 2f0e9cc11a9..aed64532564 100644 --- a/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.laravel.latest.common_scenarios_test.test_scenario_get_with_view.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.octane.apigw_test.test_inferred_proxy.json b/tests/snapshots/tests.integrations.laravel.octane.apigw_test.test_inferred_proxy.json index b272893f432..c82fbc8f52d 100644 --- a/tests/snapshots/tests.integrations.laravel.octane.apigw_test.test_inferred_proxy.json +++ b/tests/snapshots/tests.integrations.laravel.octane.apigw_test.test_inferred_proxy.json @@ -19,6 +19,7 @@ }, "metrics": { "_dd.inferred_span": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }, @@ -48,6 +49,9 @@ "runtime-id": "3cbb2740-e2da-426b-8029-a79481b8378d", "span.kind": "server", "version": "1.0" + }, + "metrics": { + "_dd.top_level": 1 } }, { diff --git a/tests/snapshots/tests.integrations.laravel.octane.apigw_test.test_inferred_proxy_exception.json b/tests/snapshots/tests.integrations.laravel.octane.apigw_test.test_inferred_proxy_exception.json index 419fe5954d0..1ff452d6e5f 100644 --- a/tests/snapshots/tests.integrations.laravel.octane.apigw_test.test_inferred_proxy_exception.json +++ b/tests/snapshots/tests.integrations.laravel.octane.apigw_test.test_inferred_proxy_exception.json @@ -23,6 +23,7 @@ }, "metrics": { "_dd.inferred_span": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }, @@ -56,6 +57,9 @@ "runtime-id": "a84b7cbb-5525-4317-a319-a9a2ac251625", "span.kind": "server", "version": "1.0" + }, + "metrics": { + "_dd.top_level": 1 } }, { diff --git a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_dynamic_route.json b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_dynamic_route.json index 61f9f360c1c..7fa90af88ab 100644 --- a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_dynamic_route.json +++ b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_dynamic_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_return_string.json index 4f0313c6f4d..63a30ba8553 100644 --- a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_return_string.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_to_missing_route.json index 078498389ad..8134f303cf7 100644 --- a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_exception.json index 83bad2e3d5f..3ab1bcd474f 100644 --- a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_exception.json @@ -25,6 +25,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_ignored_exception.json b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_ignored_exception.json index 3233a40a359..6f1a0d09b38 100644 --- a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_ignored_exception.json +++ b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_ignored_exception.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_view.json index 112ac020a34..1322a09af26 100644 --- a/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.laravel.v10_x.common_scenarios_test.test_scenario_get_with_view.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_dynamic_route.json b/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_dynamic_route.json index 173019f7ad9..c1e7863e1ab 100644 --- a/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_dynamic_route.json +++ b/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_dynamic_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_return_string.json index 129eb9bf54e..932c674cbe0 100644 --- a/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_return_string.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_to_missing_route.json index 75ca1fa3f67..419a9973dab 100644 --- a/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_with_exception.json index 2099de60186..5ba93105324 100644 --- a/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_with_exception.json @@ -25,6 +25,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_with_view.json index 680f92fc800..982c4721926 100644 --- a/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.laravel.v11_x.common_scenarios_test.test_scenario_get_with_view.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_dynamic_route.json b/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_dynamic_route.json index 22efd535627..14cca27eef4 100644 --- a/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_dynamic_route.json +++ b/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_dynamic_route.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, @@ -35,6 +36,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { @@ -48,6 +52,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { @@ -61,6 +68,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { diff --git a/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_return_string.json index 70b03dbba75..8266c058d35 100644 --- a/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_return_string.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, @@ -35,6 +36,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { @@ -48,6 +52,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { @@ -61,6 +68,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { diff --git a/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_to_missing_route.json index e311fa2b009..9b836b3f0dd 100644 --- a/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, @@ -32,6 +33,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { @@ -45,6 +49,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { @@ -58,6 +65,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { diff --git a/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_with_exception.json index 2934d7bfe6e..cc6f2e3164f 100644 --- a/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_with_exception.json @@ -25,6 +25,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, @@ -39,6 +40,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { @@ -52,6 +56,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { @@ -65,6 +72,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { diff --git a/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_with_view.json index 20a7a2d853e..b9fa3364fba 100644 --- a/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.laravel.v5_7.common_scenarios_test.test_scenario_get_with_view.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, @@ -35,6 +36,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { @@ -48,6 +52,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { @@ -61,6 +68,9 @@ "meta": { "_dd.base_service": "laravel_test_app", "component": "laravel" + }, + "metrics": { + "_dd.top_level": 1.0 } }, { diff --git a/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_dynamic_route.json b/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_dynamic_route.json index 3e1774ade87..6bddedff1cf 100644 --- a/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_dynamic_route.json +++ b/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_dynamic_route.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_return_string.json index ede2a71d263..2c84358d40b 100644 --- a/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_return_string.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_to_missing_route.json index f8a3c1d0e0f..05add0c60b7 100644 --- a/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_with_exception.json index bd6e68a2a27..7f29380f5b7 100644 --- a/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_with_exception.json @@ -25,6 +25,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_with_view.json index e6dd0b6f683..dc1c35643da 100644 --- a/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.laravel.v5_8.common_scenarios_test.test_scenario_get_with_view.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_dynamic_route.json b/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_dynamic_route.json index e2ee39ae9c5..62019100993 100644 --- a/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_dynamic_route.json +++ b/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_dynamic_route.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_return_string.json index 1ad5cb004a7..9ad7139cec4 100644 --- a/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_return_string.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_to_missing_route.json index 884e59bdbc7..22fea5b1a87 100644 --- a/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_with_exception.json index 0d1c1ee654c..6e9645c95ad 100644 --- a/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_with_exception.json @@ -25,6 +25,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_with_view.json index de7b4288e70..d4d83260a77 100644 --- a/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.laravel.v8_x.common_scenarios_test.test_scenario_get_with_view.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v8_x.queue_test.test_broadcast.json b/tests/snapshots/tests.integrations.laravel.v8_x.queue_test.test_broadcast.json index 66ee49f491e..971f75b6c50 100644 --- a/tests/snapshots/tests.integrations.laravel.v8_x.queue_test.test_broadcast.json +++ b/tests/snapshots/tests.integrations.laravel.v8_x.queue_test.test_broadcast.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_dynamic_route.json b/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_dynamic_route.json index 6c2bed6035b..325172bd86a 100644 --- a/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_dynamic_route.json +++ b/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_dynamic_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_return_string.json index 01e28d6b433..365e5b484a2 100644 --- a/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_return_string.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_to_missing_route.json index eea5cc8a4bb..4a8df662160 100644 --- a/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_with_exception.json index c822b1957aa..54ecdda91d4 100644 --- a/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_with_exception.json @@ -25,6 +25,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_with_view.json index 34138c0c85d..34e088e269c 100644 --- a/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.laravel.v9_x.common_scenarios_test.test_scenario_get_with_view.json @@ -21,6 +21,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_return_string.json index 2997d6ac172..7e8e4c01c9c 100644 --- a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_return_string.json @@ -22,6 +22,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json index 19ee5e01bdf..62985721749 100644 --- a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -22,6 +22,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_exception.json index bf66290873e..ef08bad4c65 100644 --- a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_exception.json @@ -26,6 +26,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_view.json index 61fc7ee4502..9f749be8df6 100644 --- a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_view.json @@ -22,6 +22,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_return_string.json index 72c71d68a02..68dc912b0b6 100644 --- a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_return_string.json @@ -22,6 +22,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_to_missing_route.json index b953f93fb26..9ea121f0eac 100644 --- a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -22,6 +22,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_exception.json index 76190413d61..fe0454314f7 100644 --- a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_exception.json @@ -26,6 +26,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_view.json index eb115310c09..dae272177b5 100644 --- a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_view.json @@ -22,6 +22,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.roadrunner.apigw_test.test_inferred_proxy.json b/tests/snapshots/tests.integrations.roadrunner.apigw_test.test_inferred_proxy.json index d5425bb8d1f..c43646f2204 100644 --- a/tests/snapshots/tests.integrations.roadrunner.apigw_test.test_inferred_proxy.json +++ b/tests/snapshots/tests.integrations.roadrunner.apigw_test.test_inferred_proxy.json @@ -19,6 +19,7 @@ }, "metrics": { "_dd.inferred_span": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }, @@ -45,5 +46,8 @@ "runtime-id": "fd6e51db-bf2d-40fe-aa43-ae7c29474411", "span.kind": "server", "version": "1.0" + }, + "metrics": { + "_dd.top_level": 1 } }]] diff --git a/tests/snapshots/tests.integrations.roadrunner.apigw_test.test_inferred_proxy_exception.json b/tests/snapshots/tests.integrations.roadrunner.apigw_test.test_inferred_proxy_exception.json index d39002c24b3..9d423e45d71 100644 --- a/tests/snapshots/tests.integrations.roadrunner.apigw_test.test_inferred_proxy_exception.json +++ b/tests/snapshots/tests.integrations.roadrunner.apigw_test.test_inferred_proxy_exception.json @@ -23,6 +23,7 @@ }, "metrics": { "_dd.inferred_span": 1, + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }, @@ -53,5 +54,8 @@ "runtime-id": "fd6e51db-bf2d-40fe-aa43-ae7c29474411", "span.kind": "server", "version": "1.0" + }, + "metrics": { + "_dd.top_level": 1 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.latest.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.symfony.latest.common_scenarios_test.test_scenario_get_to_missing_route.json index 5b560f719a5..8a2e40557d4 100644 --- a/tests/snapshots/tests.integrations.symfony.latest.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.symfony.latest.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success_consumer.json b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success_consumer.json index 462f84f9e88..4272fd7d6b8 100644 --- a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success_consumer.json @@ -25,6 +25,7 @@ "span.kind": "consumer" }, "metrics": { + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }, @@ -294,6 +295,9 @@ "out.host": "mysql-integration", "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -321,6 +325,7 @@ "span.kind": "client" }, "metrics": { + "_dd.top_level": 1, "db.row_count": 1 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_return_string.json index 82348173bb7..0cb1cfa7cc5 100644 --- a/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_return_string.json @@ -20,6 +20,7 @@ "symfony.route.name": "simple" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json index e8d995e047b..62c2259e3e0 100644 --- a/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -19,6 +19,7 @@ "symfony.route.action": "Symfony\\Bundle\\TwigBundle\\Controller\\ExceptionController@showAction" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_with_exception.json index 201954f0c1c..4e48a91ae98 100644 --- a/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_with_exception.json @@ -24,6 +24,7 @@ "symfony.route.name": "error" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_with_view.json index 02531a7ac64..48fe18f313d 100644 --- a/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.symfony.v2_3.common_scenarios_test.test_scenario_get_with_view.json @@ -20,6 +20,7 @@ "symfony.route.name": "simple_view" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.v2_3.route_name_test.test_resource_to_uri_mapping.json b/tests/snapshots/tests.integrations.symfony.v2_3.route_name_test.test_resource_to_uri_mapping.json index 420610342cd..d4f1d5e20f9 100644 --- a/tests/snapshots/tests.integrations.symfony.v2_3.route_name_test.test_resource_to_uri_mapping.json +++ b/tests/snapshots/tests.integrations.symfony.v2_3.route_name_test.test_resource_to_uri_mapping.json @@ -20,6 +20,7 @@ "symfony.route.name": "homepage" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_return_string.json index a0a9c474648..c15e1da0b35 100644 --- a/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_return_string.json @@ -20,6 +20,7 @@ "symfony.route.name": "simple" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_to_missing_route.json index 62625f35801..9d96bd56556 100644 --- a/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -19,6 +19,7 @@ "symfony.route.action": "Symfony\\Bundle\\TwigBundle\\Controller\\ExceptionController@showAction" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_with_exception.json index ae304477a08..ef36dad8b79 100644 --- a/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_with_exception.json @@ -24,6 +24,7 @@ "symfony.route.name": "error" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_with_view.json index 37bea1d81a8..98208159413 100644 --- a/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.symfony.v2_8.common_scenarios_test.test_scenario_get_with_view.json @@ -20,6 +20,7 @@ "symfony.route.name": "simple_view" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.v2_8.route_name_test.test_resource_to_uri_mapping.json b/tests/snapshots/tests.integrations.symfony.v2_8.route_name_test.test_resource_to_uri_mapping.json index f6586cf06a2..0dd4c90ea12 100644 --- a/tests/snapshots/tests.integrations.symfony.v2_8.route_name_test.test_resource_to_uri_mapping.json +++ b/tests/snapshots/tests.integrations.symfony.v2_8.route_name_test.test_resource_to_uri_mapping.json @@ -20,6 +20,7 @@ "symfony.route.name": "homepage" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.v7_3.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.symfony.v7_3.common_scenarios_test.test_scenario_get_to_missing_route.json index cbebb8fe4ea..19a6a3fe293 100644 --- a/tests/snapshots/tests.integrations.symfony.v7_3.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.symfony.v7_3.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success_consumer.json b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success_consumer.json index 91884722f8c..48dd4481412 100644 --- a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success_consumer.json @@ -25,6 +25,7 @@ "span.kind": "consumer" }, "metrics": { + "_dd.top_level": 1, "_sampling_priority_v1": 1 } }, @@ -275,6 +276,9 @@ "out.host": "mysql-integration", "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.top_level": 1 } }, { @@ -302,6 +306,7 @@ "span.kind": "client" }, "metrics": { + "_dd.top_level": 1, "db.row_count": 1 } }]] diff --git a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_return_string.json index a94467e5ad4..c52c1e95d43 100644 --- a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_return_string.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_exception.json index 942275e9995..df402ca4e83 100644 --- a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_exception.json @@ -23,6 +23,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_view.json index 4cea0bce0da..10973e8ec51 100644 --- a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_view.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_return_string.json index 34e87afcbd1..a5cc6c32ea6 100644 --- a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_return_string.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_exception.json index ad6b6999981..d1fa9686386 100644 --- a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_exception.json @@ -23,6 +23,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_view.json index 3da297ba272..2e742dc1a32 100644 --- a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_view.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_return_string.json index 5fe007192cb..3dcd49d0728 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_return_string.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_to_missing_route.json index 2f1cd43bf7f..71457ff117b 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_exception.json index 323e0bbfd23..fa190896854 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_exception.json @@ -23,6 +23,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_view.json index f74b08cfaf3..e88095a347d 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_view.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_return_string.json index b2cc305f4fe..d53181a322c 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_return_string.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_to_missing_route.json index 80cf347caa3..655799c0e5a 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_exception.json index 310b142ac51..d40c587ac13 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_exception.json @@ -23,6 +23,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_view.json index ca8d5fe1348..f306df4b012 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_view.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_return_string.json index ebfef74a265..364428dd2f9 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_return_string.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_to_missing_route.json index 9aecdba4a4e..fcbfbed2a68 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_exception.json index 27319620a33..c75d2591f79 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_exception.json @@ -23,6 +23,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_view.json index 683d022d4e2..4cebcc1c975 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_view.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_return_string.json index a2f281d70d4..c7709609650 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_return_string.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_to_missing_route.json index 29e5c09037b..30aa12bb9d5 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -18,6 +18,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_exception.json index c982920760e..25c068123fb 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_exception.json @@ -23,6 +23,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_view.json index 671eb3f7d1a..646e2faeb8d 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_view.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_return_string.json index d965665100a..dd042c501ff 100644 --- a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_return_string.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_with_exception.json index 10673208e8e..05a84d8a3a0 100644 --- a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_with_exception.json @@ -23,6 +23,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_with_view.json index e055001b0cc..991fad422c0 100644 --- a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_callbacks_test.test_scenario_get_with_view.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_return_string.json index cfbeb419d9c..256570c3791 100644 --- a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_return_string.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_with_exception.json index 76919c42279..2f3d6240e08 100644 --- a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_with_exception.json @@ -23,6 +23,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, diff --git a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_with_view.json index 4b9c2000682..a884b778df1 100644 --- a/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v6_1.common_scenarios_test.test_scenario_get_with_view.json @@ -19,6 +19,7 @@ "span.kind": "server" }, "metrics": { + "_dd.top_level": 1.0, "_sampling_priority_v1": 1.0 } }, From 22cf9e79fe0344fea01568ee538abe0508fd829f Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Thu, 1 Oct 2026 18:02:52 +0200 Subject: [PATCH 04/11] ci(request-replayer): decode the V1 trace payload Add a msgpack V1 decoder to the request-replayer and advertise /v1.0/traces in its /info, so the PHP test suite can inspect V1 payloads. Move the CI service to the 5.0 image and force-pull the Windows service images so a runner with a stale cached digest does not skip a rebuilt image. Add APM_TRACING_EFFICIENT_PAYLOAD to the System Tests matrix. --- .gitlab/generate-common.php | 2 +- .gitlab/generate-package.php | 1 + .gitlab/generate-tracer.php | 4 +- dockerfiles/services/.env | 2 +- .../services/request-replayer/src/index.php | 31 +- .../src/msgpack_v1_decoder.php | 620 ++++++++++++++++++ 6 files changed, 653 insertions(+), 7 deletions(-) create mode 100644 dockerfiles/services/request-replayer/src/msgpack_v1_decoder.php diff --git a/.gitlab/generate-common.php b/.gitlab/generate-common.php index 6ba761d7c61..ad90f4132f1 100644 --- a/.gitlab/generate-common.php +++ b/.gitlab/generate-common.php @@ -237,7 +237,7 @@ function windows_git_setup_with_packages() { KUBERNETES_SERVICE_MEMORY_LIMIT: 1Gi request-replayer: - name: registry.ddbuild.io/ci/dd-trace-php/request-replayer:4.0 + name: registry.ddbuild.io/ci/dd-trace-php/request-replayer:5.0 alias: request-replayer command: ["php", "-S", ":80", "index.php"] variables: diff --git a/.gitlab/generate-package.php b/.gitlab/generate-package.php index dead87aa900..be64920e520 100644 --- a/.gitlab/generate-package.php +++ b/.gitlab/generate-package.php @@ -1758,6 +1758,7 @@ function package_extension_jobs(array $platform, string $kind = "all"): array parallel: matrix: - TESTSUITE: + - APM_TRACING_EFFICIENT_PAYLOAD - APPSEC_API_SECURITY - APPSEC_API_SECURITY_RC - APPSEC_API_SECURITY_NO_RESPONSE_BODY diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index f7f2b0c9376..ae73538e5fc 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -137,7 +137,10 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { # Start the container network and services docker network create -d "nat" -o com.docker.network.windowsshim.dnsservers="1.1.1.1" net + # Force a pull so a runner with a stale cached digest doesn't skip the rebuilt image. + docker pull registry.ddbuild.io/images/mirror/datadog/dd-trace-ci:httpbin-windows docker run --network net -d --name httpbin-integration registry.ddbuild.io/images/mirror/datadog/dd-trace-ci:httpbin-windows + docker pull registry.ddbuild.io/ci/dd-trace-php/dd-trace-ci:php-request-replayer-3.0_windows docker run --network net -d --name request-replayer registry.ddbuild.io/ci/dd-trace-php/dd-trace-ci:php-request-replayer-3.0_windows docker run --env GITLAB_CI=$env:GITLAB_CI -v ${pwd}:C:\Users\ContainerAdministrator\app --network net -d --name ${CONTAINER_NAME} ${IMAGE} ping -t localhost @@ -678,7 +681,6 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { ARCH: "amd64" DD_TRACE_STARTUP_LOGS: "0" DD_TRACE_WARN_CALL_STACK_DEPTH: "0" - DD_TRACE_WARN_LEGACY_DD_TRACE: "0" DD_TRACE_GIT_METADATA_ENABLED: "0" REPORT_EXIT_STATUS: "1" TEST_PHP_JUNIT: "${CI_PROJECT_DIR}/artifacts/tests/php-tests.xml" diff --git a/dockerfiles/services/.env b/dockerfiles/services/.env index d8351f38823..0821a222f03 100644 --- a/dockerfiles/services/.env +++ b/dockerfiles/services/.env @@ -1 +1 @@ -REQUEST_REPLAYER_VERSION=4.0 +REQUEST_REPLAYER_VERSION=5.0 diff --git a/dockerfiles/services/request-replayer/src/index.php b/dockerfiles/services/request-replayer/src/index.php index 257403b9afd..55bc8652781 100644 --- a/dockerfiles/services/request-replayer/src/index.php +++ b/dockerfiles/services/request-replayer/src/index.php @@ -48,6 +48,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(); @@ -337,8 +340,22 @@ function logRequest($message, $data = '') }); break; case '/info': - $file = withRequestReplayerStateLock(REQUEST_STATE_LOCK_FILE, function () { - return @file_get_contents(REQUEST_AGENT_INFO_FILE) ?: "{}"; + // Default advertises /v1.0/traces so both senders negotiate the v1 wire. Tests needing a + // specific /info override it via /set-agent-info (that file is served verbatim). + $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 = withRequestReplayerStateLock(REQUEST_STATE_LOCK_FILE, function () use ($default_info) { + return @file_get_contents(REQUEST_AGENT_INFO_FILE) ?: $default_info; }); logRequest('Requested /info endpoint, returning ' . $file); header("datadog-agent-state: " . sha1($file)); @@ -394,8 +411,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..fe9191e0bb9 --- /dev/null +++ b/dockerfiles/services/request-replayer/src/msgpack_v1_decoder.php @@ -0,0 +1,620 @@ +buf = $buf; + $this->len = strlen($buf); + } + + /** Decodes the whole payload into the v0.4-shaped `{"chunks":[...]}` PHP array. */ + public function decode() + { + $chunks = []; + $payloadAttributes = []; + $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, + // except process tags, which v0.4 carries on each trace's first span. + $payloadAttributes = $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; + } + } + if (isset($payloadAttributes['_dd.tags.process'])) { + foreach ($chunks as &$chunk) { + if (!empty($chunk['spans'])) { + $chunk['spans'][0]['meta']['_dd.tags.process'] = $payloadAttributes['_dd.tags.process']; + } + } + unset($chunk); + } + 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'], as the v0.4 downgrade does; Unspecified (0, or the + // field absent) leaves no meta entry. + 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 1: return "internal"; + case 2: return "server"; + case 3: return "client"; + case 4: return "producer"; + case 5: return "consumer"; + // 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 8b5083d44241e2977e20e162dae924f99fd54434 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Thu, 1 Oct 2026 18:03:05 +0200 Subject: [PATCH 05/11] ci(temp): run system-tests from leiyks/php-v1-payload, revert before merge Clone system-tests at SYSTEM_TESTS_REF (default leiyks/php-v1-payload, DataDog/system-tests#7843) from SYSTEM_TESTS_REPO. --- .gitlab/generate-package.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab/generate-package.php b/.gitlab/generate-package.php index be64920e520..e6c27a4993f 100644 --- a/.gitlab/generate-package.php +++ b/.gitlab/generate-package.php @@ -1699,6 +1699,8 @@ function package_extension_jobs(array $platform, string $kind = "all"): array PIP_CACHE_DIR: $CI_PROJECT_DIR/.cache/pip APT_CACHE: $CI_PROJECT_DIR/.cache/apt DOCKER_DEFAULT_PLATFORM: linux/amd64 + # TODO: point back at "main" once DataDog/system-tests#7843 (leiyks/php-v1-payload) is merged. + SYSTEM_TESTS_REF: "leiyks/php-v1-payload" # TODO DD_API_KEY; SYSTEM_TESTS_AWS_ACCESS_KEY_ID; SYSTEM_TESTS_AWS_SECRET_ACCESS_KEY needs: - job: "package extension (bundles): [amd64, x86_64-unknown-linux-gnu]" From 7489ff095df394cd7516c4688a14a397e91473c7 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Thu, 15 Oct 2026 14:35:58 +0200 Subject: [PATCH 06/11] address review --- .gitlab/generate-ci-images.php | 4 +- .gitlab/generate-common.php | 13 +- .gitlab/generate-tracer.php | 6 +- Cargo.lock | 1 - Cargo.toml | 1 - appsec/src/extension/commands_helpers.c | 10 +- appsec/src/extension/duration_acc.c | 8 +- appsec/src/extension/request_lifecycle.c | 17 +- appsec/src/extension/tags.c | 407 ++++---- appsec/src/extension/telemetry.c | 20 +- appsec/src/extension/tracer_bridge.c | 95 +- appsec/src/extension/tracer_bridge.h | 13 +- .../api_security_telemetry_missing_route.phpt | 6 +- .../api_security_telemetry_no_route_404.phpt | 2 +- .../api_security_telemetry_no_schema.phpt | 6 +- .../api_security_telemetry_schema.phpt | 6 +- .../client_init_record_span_tags.phpt | 19 +- appsec/tests/extension/ddtrace_basic.phpt | 17 +- appsec/tests/extension/push_params_ok_04.phpt | 12 +- appsec/tests/extension/push_params_ok_05.phpt | 10 +- appsec/tests/extension/push_params_ok_06.phpt | 10 +- .../rasp_duration_ext_user_requests.phpt | 20 +- .../tests/extension/report_backtrace_01.phpt | 2 +- .../tests/extension/report_backtrace_05.phpt | 2 +- .../tests/extension/report_backtrace_06.phpt | 2 +- ...q_abort_from_user_login_success_event.phpt | 2 +- .../tests/extension/rexec_force_keep_01.phpt | 16 +- .../tests/extension/rexec_force_keep_02.phpt | 14 +- .../tests/extension/rexec_force_keep_03.phpt | 14 +- .../tests/extension/rexec_force_keep_04.phpt | 16 +- .../rinit_asm_events_propagate_tags.phpt | 6 +- .../tests/extension/rinit_force_keep_01.phpt | 16 +- .../tests/extension/rinit_force_keep_02.phpt | 14 +- .../tests/extension/rinit_force_keep_03.phpt | 14 +- .../extension/rinit_record_span_tags.phpt | 19 +- .../rinit_record_span_tags_fail.phpt | 8 +- ...hpt => rinit_root_span_add_attribute.phpt} | 8 +- .../extension/rinit_rshutdown_basic.phpt | Bin 5037 -> 5059 bytes .../extension/root_span_add_attribute.phpt | 72 ++ ...dd_attribute_with_intermediate_spans.phpt} | 6 +- appsec/tests/extension/root_span_add_tag.phpt | 60 -- .../extension/rshutdown_force_keep_01.phpt | 16 +- .../extension/rshutdown_force_keep_02.phpt | 14 +- .../extension/rshutdown_force_keep_03.phpt | 14 +- .../extension/rshutdown_force_keep_04.phpt | 16 +- .../rshutdown_sampler_key_missing_method.phpt | 4 +- .../rshutdown_sampler_key_missing_route.phpt | 2 +- .../extension/rshutdown_sampler_key_ok.phpt | 4 +- ...shutdown_sampler_key_sec_api_disabled.phpt | 4 +- .../rshutdown_sampler_low_priority.phpt | 4 +- .../track_authenticated_user_event.phpt | 17 +- ...icated_user_event_automated_anon_mode.phpt | 15 +- ...user_event_automated_anon_mode_compat.phpt | 15 +- ...r_event_automated_anon_mode_full_name.phpt | 15 +- ...ser_event_automated_anon_mode_no_user.phpt | 11 +- ..._user_event_automated_dedup_same_user.phpt | 15 +- ...ted_user_event_automated_default_mode.phpt | 15 +- ..._user_event_automated_disabled_config.phpt | 11 +- ...ed_user_event_automated_disabled_mode.phpt | 11 +- ...cated_user_event_automated_ident_mode.phpt | 15 +- ...ser_event_automated_ident_mode_compat.phpt | 15 +- ..._event_automated_ident_mode_full_name.phpt | 15 +- ...er_event_automated_ident_mode_no_user.phpt | 11 +- ...ted_user_event_automated_invalid_mode.phpt | 11 +- ...ted_user_event_automated_no_root_span.phpt | 8 +- ...authenticated_user_event_no_root_span.phpt | 8 +- ...rack_authenticated_user_event_no_user.phpt | 11 +- ...ticated_user_event_sdk_takes_priority.phpt | 15 +- ...ated_user_event_sdk_takes_priority_02.phpt | 15 +- ...ated_user_event_sdk_takes_priority_03.phpt | 15 +- ...ated_user_event_sdk_takes_priority_04.phpt | 15 +- .../tests/extension/track_custom_event.phpt | 21 +- .../track_custom_event_empty_event.phpt | 2 +- .../track_custom_event_no_root_span.phpt | 2 +- .../track_user_login_failure_event.phpt | 39 +- ...gin_failure_event_automated_anon_mode.phpt | 23 +- ...lure_event_automated_anon_mode_compat.phpt | 23 +- ...e_event_automated_anon_mode_full_name.phpt | 23 +- ...re_event_automated_anon_mode_no_login.phpt | 21 +- ...ure_event_automated_anon_mode_no_user.phpt | 19 +- ..._failure_event_automated_default_mode.phpt | 23 +- ...ilure_event_automated_disabled_config.phpt | 11 +- ...failure_event_automated_disabled_mode.phpt | 11 +- ...in_failure_event_automated_ident_mode.phpt | 23 +- ...failure_event_automated_ident_mode_02.phpt | 23 +- ...ure_event_automated_ident_mode_compat.phpt | 23 +- ..._event_automated_ident_mode_full_name.phpt | 23 +- ..._failure_event_automated_invalid_mode.phpt | 11 +- ...ogin_failure_event_automated_no_login.phpt | 21 +- ...login_failure_event_automated_no_user.phpt | 19 +- ...ser_login_failure_event_existing_user.phpt | 27 +- ...rack_user_login_failure_event_no_user.phpt | 19 +- ...ogin_failure_event_sdk_takes_priority.phpt | 29 +- ...n_failure_event_sdk_takes_priority_02.phpt | 27 +- ...n_failure_event_sdk_takes_priority_03.phpt | 27 +- ...n_failure_event_sdk_takes_priority_04.phpt | 29 +- ...n_failure_event_sdk_takes_priority_05.phpt | 27 +- ...n_failure_event_sdk_takes_priority_06.phpt | 27 +- .../track_user_login_failure_v2_01.phpt | 32 +- ...r_login_failure_v2_01_appsec_disabled.phpt | 24 +- .../track_user_login_failure_v2_02.phpt | 28 +- ...r_login_failure_v2_02_appsec_disabled.phpt | 24 +- .../track_user_login_failure_v2_03.phpt | 16 +- ...r_login_failure_v2_03_appsec_disabled.phpt | 8 +- .../track_user_login_success_event.phpt | 37 +- ...gin_success_event_automated_anon_mode.phpt | 23 +- ...cess_event_automated_anon_mode_compat.phpt | 23 +- ...s_event_automated_anon_mode_full_name.phpt | 23 +- ...ess_event_automated_anon_mode_no_user.phpt | 19 +- ..._success_event_automated_default_mode.phpt | 23 +- ...ccess_event_automated_disabled_config.phpt | 11 +- ...success_event_automated_disabled_mode.phpt | 11 +- ...n_success_event_automated_empty_login.phpt | 11 +- ...in_success_event_automated_empty_user.phpt | 19 +- ...in_success_event_automated_ident_mode.phpt | 23 +- ...success_event_automated_ident_mode_02.phpt | 23 +- ...ess_event_automated_ident_mode_compat.phpt | 23 +- ..._event_automated_ident_mode_full_name.phpt | 23 +- ..._success_event_automated_invalid_mode.phpt | 11 +- ...ogin_success_event_sdk_takes_priority.phpt | 29 +- ...n_success_event_sdk_takes_priority_02.phpt | 27 +- ...n_success_event_sdk_takes_priority_03.phpt | 27 +- .../track_user_login_success_v2_01.phpt | 32 +- ...r_login_success_v2_01_appsec_disabled.phpt | 24 +- .../track_user_login_success_v2_02.phpt | 40 +- ...r_login_success_v2_02_appsec_disabled.phpt | 32 +- .../track_user_login_success_v2_03.phpt | 32 +- ...r_login_success_v2_03_appsec_disabled.phpt | 24 +- .../track_user_login_success_v2_04.phpt | 32 +- ...r_login_success_v2_04_appsec_disabled.phpt | 24 +- .../track_user_login_success_v2_05.phpt | 28 +- ...r_login_success_v2_05_appsec_disabled.phpt | 20 +- .../track_user_login_success_v2_06.phpt | 28 +- ...r_login_success_v2_06_appsec_disabled.phpt | 20 +- .../track_user_login_success_v2_07.phpt | 24 +- ...r_login_success_v2_07_appsec_disabled.phpt | 20 +- .../extension/track_user_signup_event.phpt | 37 +- ...user_signup_event_automated_anon_mode.phpt | 23 +- ...gnup_event_automated_anon_mode_compat.phpt | 23 +- ...p_event_automated_anon_mode_full_name.phpt | 23 +- ...nup_event_automated_anon_mode_no_user.phpt | 19 +- ...r_signup_event_automated_default_mode.phpt | 23 +- ...ignup_event_automated_disabled_config.phpt | 11 +- ..._signup_event_automated_disabled_mode.phpt | 11 +- ...ser_signup_event_automated_empty_user.phpt | 19 +- ...ser_signup_event_automated_ident_mode.phpt | 23 +- ...nup_event_automated_ident_mode_compat.phpt | 23 +- ..._event_automated_ident_mode_full_name.phpt | 23 +- ...r_signup_event_automated_invalid_mode.phpt | 11 +- ..._user_signup_event_sdk_takes_priority.phpt | 27 +- ...er_signup_event_sdk_takes_priority_02.phpt | 27 +- ...er_signup_event_sdk_takes_priority_03.phpt | 27 +- ..._tracking_block_from_login_failure_v2.phpt | 2 +- ...ser_tracking_block_from_login_success.phpt | 2 +- ..._tracking_block_from_login_success_v2.phpt | 2 +- .../user_tracking_block_from_set_user.phpt | 2 +- ...king_do_nothing_from_login_failure_v2.phpt | 27 +- ...racking_do_nothing_from_login_success.phpt | 25 +- ...king_do_nothing_from_login_success_v2.phpt | 29 +- ...ser_tracking_do_nothing_from_set_user.phpt | 15 +- ..._tracking_redirect_from_login_success.phpt | 2 +- .../user_tracking_redirect_from_set_user.phpt | 2 +- .../EndpointFallbackSamplingTests.groovy | 5 +- .../src/test/www/base/public/api_security.php | 2 +- .../www/base/public/endpoint_fallback.php | 24 +- components-rs/common.h | 34 +- components-rs/datadog.h | 47 +- components-rs/sidecar.h | 449 +++------ components-rs/tracer_runtime/bytes.rs | 603 +---------- datadog-setup.php | 24 - docker-compose.yml | 2 +- dockerfiles/ci/windows/docker-compose.yml | 2 +- .../services/request-replayer/src/index.php | 6 +- .../src/msgpack_v1_decoder.php | 332 ++----- .../verify_packages/verify_windows.ps1 | 2 +- ext/ffi_utils.h | 2 +- libdatadog | 2 +- loader/tests/functional/fixtures/ddtrace.php | 8 +- .../test_ddtrace_is_fully_loaded.php | 4 +- metadata/supported-configurations.json | 933 +----------------- .../Integrations/AMQP/AMQPIntegration.php | 160 ++- .../CakePHP/CakePHPIntegration.php | 11 +- .../CakePHP/V2/CakePHPIntegrationLoader.php | 8 +- .../CakePHP/V3/CakePHPIntegrationLoader.php | 12 +- .../CodeIgniter/V2/CodeIgniterIntegration.php | 35 +- .../Integrations/Curl/CurlIntegration.php | 76 +- .../DatabaseIntegrationHelper.php | 16 +- .../Integrations/Drupal/DrupalIntegration.php | 55 +- .../V1/ElasticSearchIntegration.php | 35 +- .../V8/ElasticSearchIntegration.php | 23 +- .../Eloquent/EloquentIntegration.php | 11 +- .../Integrations/Exec/ExecIntegration.php | 13 +- .../Frankenphp/FrankenphpIntegration.php | 7 +- .../GoogleSpannerIntegration.php | 13 +- .../Integrations/Guzzle/GuzzleIntegration.php | 29 +- .../HttpClientIntegrationHelper.php | 12 +- src/DDTrace/Integrations/Integration.php | 4 +- .../Integrations/Kafka/KafkaIntegration.php | 41 +- .../Laminas/LaminasIntegration.php | 73 +- .../Laravel/LaravelIntegration.php | 37 +- .../LaravelQueue/LaravelQueueIntegration.php | 33 +- .../Integrations/Logs/LogsIntegration.php | 26 +- .../Integrations/Lumen/LumenIntegration.php | 25 +- .../Magento/MagentoIntegration.php | 148 +-- .../Memcache/MemcacheIntegration.php | 19 +- .../Memcached/MemcachedIntegration.php | 43 +- .../Integrations/Mongo/MongoIntegration.php | 59 +- .../DatadogSubscriberWithReturnTypes.php | 8 +- .../DatadogSubscriberWithoutReturnTypes.php | 8 +- .../MongoDB/MongoDBIntegration.php | 25 +- .../Integrations/Mysqli/MysqliCommon.php | 2 +- .../Integrations/Mysqli/MysqliIntegration.php | 41 +- .../Integrations/Nette/NetteIntegration.php | 31 +- .../Integrations/OpenAI/OpenAIIntegration.php | 81 +- .../Integrations/PDO/PDOIntegration.php | 21 +- .../PHPRedis/PHPRedisIntegration.php | 39 +- .../Integrations/Pcntl/PcntlIntegration.php | 8 +- .../Integrations/Predis/PredisIntegration.php | 21 +- .../Integrations/Psr18/Psr18Integration.php | 15 +- .../Ratchet/RatchetIntegration.php | 78 +- .../Roadrunner/RoadrunnerIntegration.php | 9 +- .../Integrations/SQLSRV/SQLSRVIntegration.php | 21 +- .../Integrations/Slim/SlimIntegration.php | 25 +- .../Integrations/Swoole/SwooleIntegration.php | 16 +- .../Symfony/SymfonyIntegration.php | 59 +- .../SymfonyMessengerIntegration.php | 33 +- .../WordPress/WordPressIntegrationLoader.php | 63 +- .../Integrations/Yii/YiiIntegration.php | 31 +- .../Integrations/ZendFramework/V1/Ddtrace.php | 2 +- .../ZendFramework/V1/TraceRequest.php | 13 +- .../ZendFrameworkIntegration.php | 13 +- src/DDTrace/OpenTelemetry/Context.php | 20 +- src/DDTrace/OpenTelemetry/Convention.php | 46 +- .../OpenTelemetry/Detectors/Service.php | 2 +- src/DDTrace/OpenTelemetry/Span.php | 69 +- src/DDTrace/ScopeManager.php | 6 +- src/DDTrace/Span.php | 23 +- src/DDTrace/Tracer.php | 37 +- src/DDTrace/Util/BaseConverter.php | 39 + src/DDTrace/Util/SpanKindNames.php | 18 + .../SpanEnrichmentAccumulator.php | 2 +- .../FeatureFlags/SpanEnrichmentRegistry.php | 8 +- src/api/GlobalTracer.php | 4 +- src/ddtrace_php_api.stubs.php | 3 + tests/Common/CLITestCase.php | 15 +- tests/Common/SnapshotTestTrait.php | 110 ++- tests/Common/SpanAssertion.php | 159 +-- tests/Common/SpanAssertionTrait.php | 13 +- tests/Common/SpanChecker.php | 437 +++----- tests/Common/TracerTestTrait.php | 195 ++-- .../Composer/ComposerInteroperabilityTest.php | 46 +- .../DistributedTraceTest.php | 23 +- .../SamplingPriorityTest.php | 12 +- .../SandboxAndLegacyTest.php | 26 +- tests/DistributedTracing/SyntheticsTest.php | 12 +- .../Custom/Version_Autoloaded/no-root-span | 2 +- .../Custom/Version_Not_Autoloaded/sandbox.php | 2 +- .../CurrentContextAccessTest.php | 79 +- tests/Integration/DatabaseMonitoringTest.php | 22 +- .../ErrorReporting/ErrorReportingTest.php | 64 +- .../LongRunning/LongRunningScriptTest.php | 13 +- tests/Integration/OrphansTest.php | 12 +- tests/Integration/ResponseStatusCodeTest.php | 8 +- tests/Integration/TracerTest.php | 68 +- tests/Integrations/AMQP/V2/AMQPTest.php | 158 ++- .../CLI/CakePHP/V2_8/CommonScenariosTest.php | 6 +- .../CLI/CakePHP/V3_10/CommonScenariosTest.php | 4 +- .../CLI/Custom/Autoloaded/NoRootSpanTest.php | 6 +- .../Laravel/Latest/CommonScenariosTest.php | 8 +- .../CLI/Laravel/V10_X/CommonScenariosTest.php | 4 +- .../CLI/Laravel/V5_8/CommonScenariosTest.php | 8 +- .../CLI/Laravel/V8_X/CommonScenariosTest.php | 8 +- .../CLI/Laravel/V9_X/CommonScenariosTest.php | 8 +- .../CLI/Symfony/V4_4/CommonScenariosTest.php | 38 +- .../CLI/Symfony/V5_2/CommonScenariosTest.php | 38 +- .../CLI/Symfony/V6_2/CommonScenariosTest.php | 38 +- .../CakePHP/V2_8/CommonScenariosTest.php | 24 +- .../CakePHP/V3_10/CommonScenariosTest.php | 24 +- .../CakePHP/V4_5/CommonScenariosTest.php | 24 +- .../CodeIgniter/V2_2/CommonScenariosTest.php | 20 +- .../CodeIgniter/V2_2/ExitTest.php | 4 +- .../CodeIgniter/V2_2/NoCI_ControllertTest.php | 4 +- .../Integrations/Curl/CurlIntegrationTest.php | 125 +-- .../Custom/Autoloaded/AgentUrlEnvVarTest.php | 2 +- .../Custom/Autoloaded/CommonScenariosTest.php | 12 +- .../Autoloaded/CompileTimeDisabledTest.php | 6 +- .../Autoloaded/CompileTimeEnabledTest.php | 6 +- .../Custom/Autoloaded/FatalErrorTest.php | 6 +- .../Custom/Autoloaded/GitMetadataTest.php | 38 +- .../Custom/Autoloaded/ProcessTagsWebTest.php | 13 +- .../Autoloaded/SidecarThreadModeRootTest.php | 4 +- .../Autoloaded/SidecarThreadModeTest.php | 8 +- .../HttpHeadersConfiguredTest.php | 6 +- .../HttpHeadersNotConfiguredTest.php | 6 +- .../NotAutoloaded/IncomingUserInfoTest.php | 6 +- .../V1/ElasticSearchIntegrationTest.php | 24 +- .../V8/ElasticSearchIntegrationTest.php | 24 +- .../Integrations/Exec/ExecIntegrationTest.php | 68 +- .../Frankenphp/CommonScenariosTest.php | 4 +- .../Frankenphp/DistributedTracingTest.php | 35 +- .../Guzzle/Latest/GuzzleIntegrationTest.php | 52 +- .../Guzzle/V5/GuzzleIntegrationTest.php | 44 +- .../Guzzle/V6/GuzzleIntegrationTest.php | 107 +- tests/Integrations/Kafka/KafkaTest.php | 182 ++-- .../Integrations/Laravel/Octane/APIGWTest.php | 102 +- .../Octane/Latest/CommonScenariosTest.php | 46 +- .../Laravel/V4/CommonScenariosTest.php | 16 +- .../Integrations/Laravel/V4/EloquentTest.php | 10 +- .../Laravel/V5_7/EloquentTest.php | 12 +- .../Laravel/V5_7/PipelineTracingTest.php | 6 +- .../Laravel/V5_8/EloquentTest.php | 12 +- tests/Integrations/Laravel/V5_8/QueueTest.php | 106 +- .../Laravel/V8_x/EloquentTest.php | 12 +- .../Laravel/V8_x/HttpHideRouteTest.php | 2 +- .../Laravel/V8_x/InternalExceptionsTest.php | 24 +- tests/Integrations/Laravel/V8_x/QueueTest.php | 122 +-- .../Laravel/V8_x/QueueTestNotDistributed.php | 19 +- .../Laravel/V8_x/RouteCachingTest.php | 4 +- .../Lumen/V5_2/CommonScenariosTest.php | 32 +- .../Lumen/V5_6/CommonScenariosTest.php | 22 +- .../Lumen/V5_6/DeprecatedResourceNameTest.php | 4 +- tests/Integrations/Memcache/MemcacheTest.php | 44 +- .../Integrations/Memcached/MemcachedTest.php | 150 ++- tests/Integrations/Mongo/MongoTest.php | 82 +- .../MongoDB/Latest/MongoDBTest.php | 46 +- tests/Integrations/Mysqli/MysqliTest.php | 120 +-- tests/Integrations/Nette/Latest/NetteTest.php | 28 +- tests/Integrations/Nette/V2_4/NetteTest.php | 28 +- tests/Integrations/PCNTL/PCNTLTest.php | 8 +- tests/Integrations/PDO/PDOTest.php | 132 ++- .../PHPRedis/V3/PHPRedisClusterTest.php | 70 +- .../Integrations/PHPRedis/V3/PHPRedisTest.php | 84 +- .../PHPRedis/V4/PHPRedisClusterTest.php | 96 +- .../Integrations/PHPRedis/V4/PHPRedisTest.php | 112 +-- .../PHPRedis/V5/PHPRedisClusterTest.php | 106 +- .../Integrations/PHPRedis/V5/PHPRedisTest.php | 130 ++- .../Integrations/Predis/Latest/PredisTest.php | 61 +- .../Integrations/Ratchet/V0_4/RatchetTest.php | 104 +- tests/Integrations/Roadrunner/APIGWTest.php | 78 +- .../Roadrunner/V2/CommonScenariosTest.php | 6 +- .../Roadrunner/V2/DistributedTracingTest.php | 35 +- .../Roadrunner/V2/IPExtractionTest.php | 13 +- .../Roadrunner/V2/InvalidContentTypeTest.php | 10 +- .../Roadrunner/V2/MultipartFormDataTest.php | 8 +- .../Roadrunner/V2/XWwwFormUrlencodedTest.php | 8 +- tests/Integrations/SQLSRV/SQLSRVTest.php | 108 +- .../Slim/Latest/CommonScenariosTest.php | 36 +- .../Slim/V3_12/CommonScenariosTest.php | 20 +- .../Swoole/CommonScenariosTest.php | 6 +- .../Swoole/DistributedTracingTest.php | 35 +- .../Integrations/Swoole/IPExtractionTest.php | 13 +- .../Swoole/InvalidContentTypeTest.php | 10 +- .../Swoole/SecurityTestingHeadersTest.php | 12 +- .../Swoole/XWwwFormUrlencodedTest.php | 8 +- .../Symfony/Latest/CommonScenariosTest.php | 22 +- .../Symfony/Latest/MessengerTest.php | 58 +- .../Symfony/V3_0/CommonScenariosTest.php | 30 +- .../Symfony/V3_3/CommonScenariosTest.php | 30 +- .../V3_4/AutofinishedTracesSymfony34Test.php | 4 +- .../Symfony/V3_4/CommonScenariosTest.php | 22 +- .../Symfony/V3_4/TemplateEnginesTest.php | 6 +- .../Symfony/V4_0/CommonScenariosTest.php | 30 +- .../Symfony/V4_2/CommonScenariosTest.php | 30 +- .../Symfony/V4_4/CommonScenariosTest.php | 22 +- .../Symfony/V4_4/MessengerTest.php | 64 +- .../Symfony/V5_0/CommonScenariosTest.php | 22 +- .../Symfony/V5_1/CommonScenariosTest.php | 22 +- .../Symfony/V5_2/CommonScenariosTest.php | 22 +- .../Symfony/V5_2/ConsoleCommandTest.php | 2 +- .../Symfony/V5_2/MessengerTest.php | 65 +- .../Symfony/V6_2/CommonScenariosTest.php | 22 +- .../Symfony/V6_2/ConsoleCommandTest.php | 2 +- .../Symfony/V6_2/MessengerTest.php | 66 +- .../Symfony/V7_3/CommonScenariosTest.php | 22 +- .../Symfony/V7_3/MessengerTest.php | 58 +- .../Yii/Latest/CommonScenariosTest.php | 36 +- .../LazyLoadingIntegrationsFromYiiTest.php | 8 +- tests/Integrations/Yii/Latest/ModuleTest.php | 8 +- .../Yii/Latest/ParameterizedRouteTest.php | 8 +- .../ZendFramework/V1/CommonScenariosTest.php | 6 +- .../V1_21/CommonScenariosTest.php | 6 +- .../Integration/API/BaggageTest.php | 3 +- .../Integration/API/TracerTest.php | 196 ++-- .../Integration/Context/Fiber/FiberTest.php | 4 +- .../Integration/InteroperabilityTest.php | 132 +-- .../Integration/SDK/SpanBuilderTest.php | 39 + .../Integration/SDK/SpanProcessorTest.php | 2 +- .../Integration/SpanProvenanceTest.php | 6 +- tests/Unit/ConfigurationTest.php | 13 +- .../HttpClientIntegrationHelperTest.php | 24 +- tests/Unit/SpanTest.php | 33 + tests/Unit/TracerTest.php | 16 +- tests/WebServer.php | 6 - tests/ext/active_span.phpt | 30 +- ...al_tag_on_userland_and_internal_spans.phpt | 10 +- tests/ext/analytics_event.phpt | 43 - .../agent_sampling-standalone-asm_01.phpt | 7 +- .../agent_sampling-standalone-asm_02.phpt | 3 +- .../agent_sampling-standalone-asm_03.phpt | 3 +- .../ext/background-sender/agent_sampling.phpt | 3 +- .../agent_sampling_sidecar.phpt | 3 +- tests/ext/base_service.phpt | 6 +- .../ext/call_user_func/namespaced-array.phpt | 4 +- tests/ext/call_user_func/namespaced.phpt | 4 +- .../call_user_func/not-namespaced-array.phpt | 4 +- tests/ext/call_user_func/not-namespaced.phpt | 4 +- ...client_side_stats_disabled_by_default.phpt | 2 +- tests/ext/client_side_stats_top_level.phpt | 2 +- tests/ext/dd_trace_current_context.phpt | 5 + tests/ext/dd_trace_current_context_noenv.phpt | 5 + .../dd_trace_serialize_header_to_meta.phpt | 2 +- ...ce_span_data_serialization_with_links.phpt | 46 +- .../baggage/baggage_span_tags.phpt | 8 +- .../baggage/baggage_span_tags_empty.phpt | 8 +- .../baggage/baggage_span_tags_keys.phpt | 8 +- .../baggage/baggage_span_tags_wildcard.phpt | 8 +- .../distributed_trace_asm_standalone_01.phpt | 159 +-- .../distributed_trace_asm_standalone_02.phpt | 151 +-- .../distributed_trace_asm_standalone_03.phpt | 4 +- .../distributed_trace_asm_standalone_04.phpt | 4 +- .../distributed_trace_asm_standalone_05.phpt | 4 +- .../distributed_trace_asm_standalone_06.phpt | 14 +- .../distributed_trace_asm_standalone_07.phpt | 10 +- .../distributed_trace_asm_standalone_08.phpt | 4 +- .../distributed_trace_asm_standalone_09.phpt | 4 +- .../distributed_trace_bogus_ids.phpt | 99 +- .../distributed_trace_inherit.phpt | 147 +-- ...tributed_trace_inherit_b3-single-span.phpt | 5 +- ...ce_inherit_b3-single-span_no_sampling.phpt | 5 +- .../distributed_trace_inherit_b3.phpt | 3 + .../distributed_trace_overwrite.phpt | 9 +- ...stributed_trace_overwrite_active_span.phpt | 42 +- ...stributed_trace_reset_context_on_init.phpt | 9 +- .../dropped_spans_have_negative_duration.phpt | 2 +- tests/ext/env_meta_fallback_promoted.phpt | 2 +- tests/ext/extract_ip_private_01.phpt | 2 +- tests/ext/extract_server_values.phpt | 2 +- tests/ext/generate_128_bit_trace_id.phpt | 16 +- ...t_resource_renaming_always_simplified.phpt | 2 +- ...http_endpoint_resource_renaming_basic.phpt | 4 +- tests/ext/includes/fake_tracer.inc | 2 +- tests/ext/includes/request_replayer.inc | 6 + tests/ext/inferred_proxy/alter_service.phpt | 8 +- tests/ext/inferred_proxy/basic_test.phpt | 8 +- .../consume_distributed_tracing_headers.phpt | 126 +-- .../inferred_proxy/distributed_tracing.phpt | 139 +-- .../ext/inferred_proxy/error_propagated.phpt | 11 +- .../inferred_proxy/fallback_service_name.phpt | 8 +- .../inferred_proxy/incomplete_headers.phpt | 9 +- tests/ext/inferred_proxy/multiple_traces.phpt | 195 ++-- .../propagated_tags_after_span_start.phpt | 120 +-- .../propagated_tags_before_span_start.phpt | 120 +-- tests/ext/inferred_proxy/sampling_rules.phpt | 105 +- .../security_headers_forwarded.phpt | 2 +- .../serialization-sampling-chunk.phpt | 7 +- tests/ext/inherit_meta_from_parent.phpt | 2 +- .../curl/curl_multi_exec_span_limit.phpt | 3 +- .../curl/distributed_tracing_curl.phpt | 2 +- .../distributed_tracing_curl_drop_dm.phpt | 2 +- ...distributed_tracing_curl_invalid_tags.phpt | 2 +- .../distributed_tracing_curl_tracestate.phpt | 2 +- .../drupal/drupal_integration.inc | 4 +- ...me_engine_service_dropped_nested_span.phpt | 5 +- .../theme_render_dropped_nested_span.phpt | 5 +- .../drupal/theme_render_dropped_span.phpt | 5 +- .../distributed_tracing_http_streams.phpt | 2 +- ...ributed_tracing_http_streams_disabled.phpt | 2 +- ...t_metadata_injection_from_valid_files.phpt | 15 +- ...metadata_injection_from_invalid_files.phpt | 74 +- .../source_code/commit_sha_env_var.phpt | 135 +-- .../git_metadata_injection_from_env.phpt | 139 +-- ...t_metadata_injection_from_global_tags.phpt | 161 +-- ...injection_remove_credentials_from_env.phpt | 139 +-- .../source_code/repository_url_env_var.phpt | 135 +-- tests/ext/ip_collection_01.phpt | 2 +- tests/ext/ip_collection_02.phpt | 2 +- tests/ext/ip_collection_03.phpt | 2 +- tests/ext/ip_collection_04.phpt | 2 +- tests/ext/ip_collection_05.phpt | 2 +- .../legacy_tracer_distributed_context.phpt | 73 ++ tests/ext/limiter/002-limiter-reached.phpt | 12 +- .../003-limiter-with-asm-standalone.phpt | 10 +- tests/ext/meta_struct.phpt | 2 +- tests/ext/nested_exceptions.phpt | 8 +- ...l_http_response_status_code_remapping.phpt | 44 - ...onse_status_code_remapping_precedence.phpt | 45 - .../ext/otel_http_status_code_remapping.phpt | 44 - .../pcntl_fork_long_running_autoflush.phpt | 4 +- tests/ext/peer_service_disabled_default.phpt | 6 +- tests/ext/peer_service_honor_user_value.phpt | 10 +- tests/ext/peer_service_remapping.phpt | 10 +- ...rvice_sources_not_serialized_when_set.phpt | 6 +- ...ice_sources_not_serialized_when_unset.phpt | 6 +- .../peer_service_use_first_available_tag.phpt | 14 +- tests/ext/peer_service_wrong_values.phpt | 10 +- .../serialization-chunk.phpt | 16 +- tests/ext/process_tags.phpt | 23 +- tests/ext/referrer_extraction_01.phpt | 2 +- tests/ext/referrer_extraction_02.phpt | 2 +- tests/ext/referrer_extraction_03.phpt | 2 +- tests/ext/referrer_extraction_04.phpt | 2 +- tests/ext/referrer_extraction_05.phpt | 2 +- tests/ext/report_hostname_on_payload.phpt | 24 + .../request-replayer/analytics_event_v04.phpt | 57 -- .../dd_trace_exception_span_event.phpt | 38 +- .../request-replayer/dd_trace_span_event.phpt | 36 +- .../dd_trace_span_link_with_exception.phpt | 23 +- ...process_sender_traced_attribute_tags.phpt} | 8 +- .../serializer_wire_inprocess_v04.phpt | 2 +- .../serializer_wire_inprocess_v1.phpt | 4 +- .../span_link_event_attributes_v04_wire.phpt | 12 +- .../top_level_marked_by_sidecar_sender.phpt | 65 ++ .../top_level_marked_on_v1_wire.phpt | 64 -- tests/ext/root_span_default_component.phpt | 9 +- .../ext/root_span_default_component_cli.phpt | 4 +- ...span_default_component_framework_wins.phpt | 4 +- 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 | 2 +- ...t_span_http_client_ip_x_forwarded_for.phpt | 2 +- tests/ext/root_span_http_useragent.phpt | 2 +- .../root_span_security_testing_headers.phpt | 2 +- ..._span_security_testing_headers_absent.phpt | 2 +- .../ext/root_span_url_as_resource_names.phpt | 2 +- ...ot_span_url_as_resource_names_no_host.phpt | 2 +- tests/ext/root_span_url_with_post_array.phpt | 2 +- ...root_span_url_with_post_array_allowed.phpt | 2 +- tests/ext/root_span_url_with_post_fields.phpt | 2 +- ...span_url_with_post_implicit_array_key.phpt | 2 +- .../ext/root_span_url_with_post_no_param.phpt | 2 +- .../root_span_url_with_post_no_param_set.phpt | 2 +- ...pan_url_with_post_only_allowed_params.phpt | 2 +- ...t_span_url_with_post_simple_whitelist.phpt | 2 +- .../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 +- ...ampling_mechanism_from_decision_maker.phpt | 4 +- tests/ext/sandbox-prehook/close_on_exit.phpt | 2 +- .../dd_trace_function_internal.phpt | 2 +- .../dd_trace_function_userland.phpt | 2 +- .../ext/sandbox-prehook/dd_trace_method.phpt | 26 +- tests/ext/sandbox-prehook/drop_spans.phpt | 2 +- .../sandbox-prehook/exception_handling.phpt | 2 +- ...errors_are_ignored_in_tracing_closure.phpt | 2 +- ...in_limited_tracing_userland_functions.phpt | 3 +- tests/ext/sandbox-prehook/new_static.phpt | 2 +- tests/ext/sandbox/close-on-exit-retval.phpt | 2 +- tests/ext/sandbox/close-on-exit.phpt | 2 +- tests/ext/sandbox/dd_dumper.inc | 27 +- .../ext/sandbox/dd_trace_function_alias.phpt | 5 +- .../sandbox/dd_trace_function_complex.phpt | 42 +- .../sandbox/dd_trace_function_internal.phpt | 12 +- .../sandbox/dd_trace_function_userland.phpt | 6 +- tests/ext/sandbox/dd_trace_method.phpt | 26 +- tests/ext/sandbox/dd_trace_method_alias.phpt | 5 +- .../sandbox/deferred_load_using_function.phpt | 2 +- tests/ext/sandbox/drop_spans.phpt | 2 +- .../errors_are_flagged_from_userland.phpt | 14 +- ...tion_does_not_close_span_that_catches.phpt | 2 +- ...tion_from_user_error_handler_internal.phpt | 2 +- ...ption_handled_for_correct_catch_block.phpt | 2 +- ...eption_handled_in_correct_catch_frame.phpt | 2 +- .../exception_handled_in_multicatch.phpt | 2 +- .../exception_handled_with_finally.phpt | 2 +- tests/ext/sandbox/exception_handling.phpt | 2 +- ...errors_are_ignored_in_tracing_closure.phpt | 2 +- ...ons_are_passed_to_the_tracing_closure.phpt | 2 +- ...inal_call_rethrown_in_tracing_closure.phpt | 2 +- .../sandbox/fatal_errors_are_tracked_001.phpt | 5 +- .../sandbox/fatal_errors_are_tracked_002.phpt | 5 +- .../sandbox/fatal_errors_are_tracked_003.phpt | 5 +- .../sandbox/fatal_errors_are_tracked_004.phpt | 5 +- .../sandbox/fatal_errors_are_tracked_005.phpt | 5 +- .../fatal_errors_ignored_in_shutdown.phpt | 2 +- ...tal_errors_ignored_in_tracing_closure.phpt | 2 +- tests/ext/sandbox/generator.phpt | 2 +- .../ext/sandbox/generator_with_exception.phpt | 2 +- tests/ext/sandbox/generator_with_return.phpt | 2 +- tests/ext/sandbox/generator_yield_from.phpt | 2 +- .../hook_function/dropping_trace_hook.phpt | 8 +- .../hook_method/posthook_span_ids_02.phpt | 2 +- .../hook_method/prehook_span_ids_02.phpt | 2 +- ...in_limited_tracing_internal_functions.phpt | 3 +- ...s_in_limited_tracing_internal_methods.phpt | 3 +- ...in_limited_tracing_userland_functions.phpt | 3 +- ...s_in_limited_tracing_userland_methods.phpt | 3 +- tests/ext/sandbox/new_static.phpt | 6 +- tests/ext/sandbox/non-zero_duration.phpt | 2 +- tests/ext/sandbox/return_by_ref.phpt | 2 +- .../ext/sandbox/safe_to_string_metadata.phpt | 4 +- .../safe_to_string_metadata_ge_php_84.phpt | 2 +- tests/ext/sandbox/safe_to_string_metrics.phpt | 2 +- .../sandbox/safe_to_string_properties.phpt | 3 +- tests/ext/sandbox/span_clone.phpt | 98 +- .../sandbox/span_resource_serialization.phpt | 2 +- tests/ext/sandbox/spans_out_of_sync_01.phpt | 5 +- tests/ext/sandbox/spans_out_of_sync_02.phpt | 5 +- tests/ext/sandbox/spans_out_of_sync_03.phpt | 5 +- tests/ext/sandbox/spans_out_of_sync_04.phpt | 5 +- tests/ext/sandbox/vm_var_types_return.phpt | 2 +- tests/ext/sdk_otlp_export_marker.phpt | 28 +- tests/ext/set_user_no_metadata.phpt | 8 +- tests/ext/set_user_with_metadata.phpt | 8 +- .../set_user_with_propagation_by_default.phpt | 8 +- ...ser_with_propagation_override_default.phpt | 8 +- ..._without_propagation_override_default.phpt | 8 +- tests/ext/sidecar_enabled.phpt | 6 +- .../accept-single-span.phpt | 2 +- .../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 +- tests/ext/span_attributes_empty_keys.phpt | 2 +- tests/ext/span_attributes_input.phpt | 145 ++- tests/ext/span_data_attributes_init.phpt | 17 +- tests/ext/span_data_meta_view.phpt | 12 +- tests/ext/span_ignore_error.phpt | 12 +- .../ext/span_kind_meta_fallback_promoted.phpt | 2 +- .../span_link_event_recursive_attributes.phpt | 14 +- .../span_link_typed_scalar_attributes.phpt | 42 + tests/ext/span_meta_alias_read.phpt | 92 ++ .../ext/span_stack/stack_dropped_parent.phpt | 2 +- tests/ext/span_stack/start_span_stack.phpt | 2 +- tests/ext/span_with_removed_exception.phpt | 36 +- tests/ext/start_span_with_all_properties.phpt | 22 +- tests/ext/start_span_without_closing.phpt | 12 +- ...start_span_without_closing_autofinish.phpt | 10 +- tests/ext/startup_logging.phpt | 4 +- tests/ext/startup_logging_json.phpt | 4 +- tests/ext/startup_logging_skipif_unix_83.inc | 6 - tests/ext/svc_auto_tag_cli.phpt | 3 +- tests/ext/svc_auto_tag_otel.phpt | 3 +- tests/ext/svc_runtime_change.phpt | 3 +- tests/ext/svc_src_default_cleared.phpt | 2 +- tests/ext/svc_src_inheritance.phpt | 2 +- tests/ext/svc_src_manual_override.phpt | 2 +- tests/ext/svc_user_tag.phpt | 3 +- tests/ext/telemetry/integration.phpt | 2 +- .../ext/telemetry/metrics_spans_created.phpt | 6 +- tests/ext/test_special_attributes.phpt | 17 +- tests/ext/test_special_attributes_bis.phpt | 17 +- tests/ext/traced_attribute.phpt | 2 +- ...ribute_attributes_recursive_and_empty.phpt | 33 + .../ext/traced_attribute_kind_component.phpt | 35 + .../traced_attribute_tags_and_attributes.phpt | 44 + ...aced_attribute_tags_deprecation_count.phpt | 53 + ...ed_attribute_tags_recursive_and_empty.phpt | 14 +- tests/ext/track_user_login_failure_01.phpt | 8 +- tests/ext/track_user_login_failure_02.phpt | 8 +- tests/ext/track_user_login_failure_03.phpt | 8 +- tests/ext/track_user_login_success_01.phpt | 8 +- tests/ext/track_user_login_success_02.phpt | 8 +- tests/ext/track_user_login_success_03.phpt | 8 +- tests/ext/track_user_login_success_04.phpt | 8 +- tests/ext/track_user_login_success_05.phpt | 8 +- tests/ext/track_user_login_success_06.phpt | 8 +- tests/ext/track_user_login_success_07.phpt | 8 +- tests/ext/try_drop_span.phpt | 2 +- tests/ext/try_drop_span_root.phpt | 2 +- tests/ext/ust.phpt | 20 +- tests/ext/ust_precedence_over_ddtags.phpt | 2 +- tests/ext/ust_via_ddtags.phpt | 2 +- .../DDTrace_trace_id.phpt | 5 +- .../span_attributes_immutable_arrays.phpt | 2 +- .../app/public/long_running_script.php | 6 +- .../RandomizedTests/RandomExecutionPath.php | 10 +- ..._test.test_silenced_spans_are_dropped.json | 8 +- ..._test.test_silenced_spans_are_dropped.json | 8 +- ..._test.test_silenced_spans_are_dropped.json | 8 +- ..._test.test_silenced_spans_are_dropped.json | 12 +- ..._test.test_silenced_spans_are_dropped.json | 12 +- ...zzle_integration_test.test_multi_exec.json | 540 +++++----- ...zzle_integration_test.test_multi_exec.json | 540 +++++----- ...t.test_span_links_high_level_consumer.json | 48 +- ...st.test_span_links_low_level_consumer.json | 59 +- ...aravel.v8_x.queue_test.test_broadcast.json | 8 +- ..._test.test_scenario_get_return_string.json | 4 +- ...st.test_scenario_get_to_missing_route.json | 12 +- ...test.test_scenario_get_with_exception.json | 4 +- ...rios_test.test_scenario_get_with_view.json | 12 +- ..._test.test_scenario_get_return_string.json | 4 +- ...st.test_scenario_get_to_missing_route.json | 12 +- ...test.test_scenario_get_with_exception.json | 4 +- ...rios_test.test_scenario_get_with_view.json | 12 +- ...ai.open_ai_test.test_cancel_fine_tune.json | 2 +- ...n_ai_test.test_create_chat_completion.json | 2 +- ...st.test_create_chat_completion_stream.json | 2 +- ...create_chat_completion_with_functions.json | 2 +- ...eate_chat_completion_with_image_input.json | 4 +- ...e_chat_completion_with_multiple_roles.json | 2 +- ...i.open_ai_test.test_create_completion.json | 4 +- ...ai_test.test_create_completion_stream.json | 2 +- ...ai.open_ai_test.test_create_embedding.json | 2 +- ...create_embedding_with_multiple_inputs.json | 2 +- ...open_ai.open_ai_test.test_create_file.json | 4 +- ...pen_ai.open_ai_test.test_create_image.json | 4 +- ...i.open_ai_test.test_create_image_edit.json | 4 +- ...n_ai_test.test_create_image_variation.json | 4 +- ...i.open_ai_test.test_create_moderation.json | 4 +- ...est.test_create_transcription_to_json.json | 2 +- ...est.test_create_transcription_to_text.json | 4 +- ..._create_transcription_to_verbose_json.json | 2 +- ..._test.test_create_translation_to_json.json | 2 +- ..._test.test_create_translation_to_text.json | 4 +- ...st_create_translation_to_verbose_json.json | 2 +- ...open_ai.open_ai_test.test_delete_file.json | 4 +- ...pen_ai.open_ai_test.test_delete_model.json | 4 +- ....open_ai.open_ai_test.test_list_files.json | 4 +- ...en_ai_test.test_list_fine_tune_events.json | 4 +- ...est.test_list_fine_tune_events_stream.json | 4 +- ...open_ai.open_ai_test.test_list_models.json | 4 +- ...est_log_prompt_completion_sample_rate.json | 4 +- ...en_ai.open_ai_test.test_logs_disabled.json | 4 +- ...ai.open_ai_test.test_metrics_disabled.json | 4 +- ..._ai.open_ai_test.test_open_ai_service.json | 10 +- ...en_ai.open_ai_test.test_retrieve_file.json | 4 +- ....open_ai_test.test_retrieve_fine_tune.json | 2 +- ...n_ai.open_ai_test.test_retrieve_model.json | 4 +- ..._ai.open_ai_test.test_span_char_limit.json | 4 +- ...st_span_prompt_completion_sample_rate.json | 4 +- ...est.messenger_test.test_async_failure.json | 82 +- ...nger_test.test_async_failure_consumer.json | 32 +- ...est.messenger_test.test_async_success.json | 82 +- ...nger_test.test_async_success_consumer.json | 14 +- ...async_with_tracer_disabled_on_consume.json | 82 +- ...4_4.messenger_test.test_async_failure.json | 12 +- ...nger_test.test_async_failure_consumer.json | 8 +- ...4_4.messenger_test.test_async_success.json | 12 +- ...nger_test.test_async_success_consumer.json | 8 +- ...async_with_tracer_disabled_on_consume.json | 12 +- ...5_2.messenger_test.test_async_failure.json | 12 +- ...nger_test.test_async_failure_consumer.json | 16 +- ...5_2.messenger_test.test_async_success.json | 12 +- ...nger_test.test_async_success_consumer.json | 8 +- ...async_with_tracer_disabled_on_consume.json | 12 +- ...6_2.messenger_test.test_async_failure.json | 68 +- ...nger_test.test_async_failure_consumer.json | 22 +- ...6_2.messenger_test.test_async_success.json | 68 +- ...nger_test.test_async_success_consumer.json | 14 +- ...async_with_tracer_disabled_on_consume.json | 68 +- ...7_3.messenger_test.test_async_failure.json | 76 +- ...nger_test.test_async_failure_consumer.json | 32 +- ...7_3.messenger_test.test_async_success.json | 76 +- ...nger_test.test_async_success_consumer.json | 14 +- ...async_with_tracer_disabled_on_consume.json | 76 +- ...acks_test.test_scenario_get_with_view.json | 6 +- ...rios_test.test_scenario_get_with_view.json | 6 +- ...acks_test.test_scenario_get_with_view.json | 6 +- ...rios_test.test_scenario_get_with_view.json | 6 +- ...acks_test.test_scenario_get_with_view.json | 6 +- ...rios_test.test_scenario_get_with_view.json | 6 +- tests/xdebug/2.9.5/autoload_php.phpt | 2 +- tests/xdebug/3.0.0/autoload_php.phpt | 2 +- tracer/auto_flush.c | 8 +- tracer/code_origins.c | 35 +- tracer/coms.c | 1 - tracer/configuration.h | 11 +- tracer/ddtrace.c | 5 - tracer/ddtrace.stub.php | 96 +- tracer/ddtrace_arginfo.h | 339 ++++--- tracer/distributed_tracing_headers.c | 64 +- tracer/distributed_tracing_headers.h | 2 +- tracer/endpoint_guessing.c | 7 +- tracer/exception_serialize.c | 12 +- tracer/exception_serialize.h | 2 +- tracer/functions.c | 85 +- tracer/handlers_http.h | 4 +- tracer/handlers_httpstreams.c | 11 +- tracer/hook/uhook_arginfo.h | 4 +- tracer/hook/uhook_attributes.c | 125 +-- tracer/hook/uhook_attributes.stub.php | 15 +- tracer/hook/uhook_attributes_arginfo.h | 17 +- tracer/integrations/exec_integration.c | 17 +- tracer/integrations/integrations.c | 2 - tracer/integrations/integrations.h | 2 - tracer/ip_extraction.c | 4 +- tracer/ip_extraction.h | 2 +- tracer/live_debugger.c | 8 +- tracer/priority_sampling/priority_sampling.c | 43 +- tracer/serializer.c | 734 +++++--------- tracer/serializer.h | 8 +- tracer/span.c | 25 +- tracer/span.h | 32 +- tracer/span_stats.c | 148 +-- tracer/span_stats.h | 27 +- tracer/span_tags_view.c | 264 ++++- tracer/span_tags_view.h | 4 + tracer/trace_filter.c | 20 +- tracer/trace_source.c | 18 +- tracer/trace_source.h | 3 +- tracer/tracer_startup_logging.c | 4 +- .../tracer_tag_propagation.c | 49 +- .../tracer_tag_propagation.h | 10 +- tracer/tracer_telemetry.c | 8 - 797 files changed, 10972 insertions(+), 12166 deletions(-) rename appsec/tests/extension/{rinit_root_span_add_tag.phpt => rinit_root_span_add_attribute.phpt} (87%) create mode 100644 appsec/tests/extension/root_span_add_attribute.phpt rename appsec/tests/extension/{root_span_add_tag_with_intermediate_spans.phpt => root_span_add_attribute_with_intermediate_spans.phpt} (88%) delete mode 100644 appsec/tests/extension/root_span_add_tag.phpt create mode 100644 src/DDTrace/Util/BaseConverter.php create mode 100644 src/DDTrace/Util/SpanKindNames.php delete mode 100644 tests/ext/analytics_event.phpt create mode 100644 tests/ext/legacy_tracer_distributed_context.phpt delete mode 100644 tests/ext/otel_http_response_status_code_remapping.phpt delete mode 100644 tests/ext/otel_http_response_status_code_remapping_precedence.phpt delete mode 100644 tests/ext/otel_http_status_code_remapping.phpt create mode 100644 tests/ext/report_hostname_on_payload.phpt delete mode 100644 tests/ext/request-replayer/analytics_event_v04.phpt rename tests/ext/request-replayer/{traced_attribute_tags_v04_wire.phpt => inprocess_sender_traced_attribute_tags.phpt} (87%) create mode 100644 tests/ext/request-replayer/top_level_marked_by_sidecar_sender.phpt delete mode 100644 tests/ext/request-replayer/top_level_marked_on_v1_wire.phpt create mode 100644 tests/ext/span_link_typed_scalar_attributes.phpt create mode 100644 tests/ext/span_meta_alias_read.phpt delete mode 100644 tests/ext/startup_logging_skipif_unix_83.inc create mode 100644 tests/ext/traced_attribute_attributes_recursive_and_empty.phpt create mode 100644 tests/ext/traced_attribute_kind_component.phpt create mode 100644 tests/ext/traced_attribute_tags_and_attributes.phpt create mode 100644 tests/ext/traced_attribute_tags_deprecation_count.phpt diff --git a/.gitlab/generate-ci-images.php b/.gitlab/generate-ci-images.php index 5b983fe1809..934bada0dff 100644 --- a/.gitlab/generate-ci-images.php +++ b/.gitlab/generate-ci-images.php @@ -256,7 +256,9 @@ function parse_compose(string $path, array $env): array Write-Host "Downloading docker-compose..." [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $dockerCompose = "$PWD\docker-compose.exe" - Start-BitsTransfer -Source "$env:GITHUB_RELEASES_MIRROR/docker/compose/releases/download/v2.36.0/docker-compose-windows-x86_64.exe" -Destination $dockerCompose + # Start-BitsTransfer gets HTTP 405 from the releases mirror; a plain GET works (as curl does on Linux). + curl.exe -L --fail -o $dockerCompose "$env:GITHUB_RELEASES_MIRROR/docker/compose/releases/download/v2.36.0/docker-compose-windows-x86_64.exe" + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } # Scope Docker auth to this job: CI Identities for registry.ddbuild.io only, # no ECR catch-all that would fail without AWS_DEFAULT_REGION. Docker calls diff --git a/.gitlab/generate-common.php b/.gitlab/generate-common.php index ad90f4132f1..0626fdddd8e 100644 --- a/.gitlab/generate-common.php +++ b/.gitlab/generate-common.php @@ -213,10 +213,10 @@ function windows_git_setup_with_packages() { ?> .services: - test-agent: - name: registry.ddbuild.io/images/mirror/dd-apm-test-agent/ddapm-test-agent:v1.22.1 + test-agent: &test_agent_service + name: registry.ddbuild.io/images/mirror/dd-apm-test-agent/ddapm-test-agent:v1.67.0 alias: test-agent - variables: + variables: &test_agent_variables LOG_LEVEL: DEBUG TRACE_LANGUAGE: php DD_TRACE_AGENT_URL: http://request-replayer:80 @@ -236,6 +236,13 @@ function windows_git_setup_with_packages() { KUBERNETES_SERVICE_MEMORY_REQUEST: 1Gi KUBERNETES_SERVICE_MEMORY_LIMIT: 1Gi + # For jobs without a request-replayer: the test agent forwards /info to DD_TRACE_AGENT_URL and fails it if that host is missing. + test-agent-standalone: + <<: *test_agent_service + variables: + <<: *test_agent_variables + DD_TRACE_AGENT_URL: "" + request-replayer: name: registry.ddbuild.io/ci/dd-trace-php/request-replayer:5.0 alias: request-replayer diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index ae73538e5fc..01034502d67 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -140,8 +140,8 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { # Force a pull so a runner with a stale cached digest doesn't skip the rebuilt image. docker pull registry.ddbuild.io/images/mirror/datadog/dd-trace-ci:httpbin-windows docker run --network net -d --name httpbin-integration registry.ddbuild.io/images/mirror/datadog/dd-trace-ci:httpbin-windows - docker pull registry.ddbuild.io/ci/dd-trace-php/dd-trace-ci:php-request-replayer-3.0_windows - docker run --network net -d --name request-replayer registry.ddbuild.io/ci/dd-trace-php/dd-trace-ci:php-request-replayer-3.0_windows + docker pull registry.ddbuild.io/ci/dd-trace-php/dd-trace-ci:php-request-replayer-5.0_windows + docker run --network net -d --name request-replayer registry.ddbuild.io/ci/dd-trace-php/dd-trace-ci:php-request-replayer-5.0_windows docker run --env GITLAB_CI=$env:GITLAB_CI -v ${pwd}:C:\Users\ContainerAdministrator\app --network net -d --name ${CONTAINER_NAME} ${IMAGE} ping -t localhost # Enable NTFS long path support so cargo's libgit2-based git checkouts of @@ -668,7 +668,7 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { "PHP Language Tests: []": extends: .debug_test services: - - !reference [.services, test-agent] + - !reference [.services, test-agent-standalone] needs: - job: "compile extension: debug" parallel: diff --git a/Cargo.lock b/Cargo.lock index e6e1ea964f8..fea7f2da817 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1257,7 +1257,6 @@ dependencies = [ "rand_distr", "regex", "regex-automata", - "rmpv", "rustc-hash", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 4875be3d47b..de6edc48434 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,7 +159,6 @@ cc = { version = "1.0", optional = true } [dev-dependencies] tempfile = "3.3" static_assertions = "1" -rmpv = "1.3.0" [profile.dev] debug = 2 diff --git a/appsec/src/extension/commands_helpers.c b/appsec/src/extension/commands_helpers.c index 929357f2dea..f231d3862c5 100644 --- a/appsec/src/extension/commands_helpers.c +++ b/appsec/src/extension/commands_helpers.c @@ -689,8 +689,8 @@ void dd_command_process_meta(mpack_node_t root, zend_object *nonnull span) const char *val_str = mpack_node_str(value); size_t val_len = mpack_node_strlen(value); - bool res = - dd_trace_span_add_tag_str(span, key_str, key_len, val_str, val_len); + bool res = dd_trace_span_add_attribute_str( + span, key_str, key_len, val_str, val_len); if (!res) { mlog(dd_log_warning, "Failed to add tag %.*s", (int)key_len, @@ -712,8 +712,8 @@ void dd_command_process_meta(mpack_node_t root, zend_object *nonnull span) bool dd_command_process_metrics(mpack_node_t root, zend_object *nonnull span) { - zval *metrics_zv = dd_trace_span_get_metrics(span); - if (metrics_zv == NULL) { + zval *attributes = dd_trace_span_get_attributes(span); + if (attributes == NULL) { return false; } @@ -761,7 +761,7 @@ bool dd_command_process_metrics(mpack_node_t root, zend_object *nonnull span) mlog(dd_log_debug, "Adding to root span the metric '%.*s'", (int)key_len, key_str); - zval *res = zend_hash_add(Z_ARRVAL_P(metrics_zv), ztag, &zv); + zval *res = zend_hash_add(Z_ARRVAL_P(attributes), ztag, &zv); zend_string_release(ztag); if (res == NULL) { diff --git a/appsec/src/extension/duration_acc.c b/appsec/src/extension/duration_acc.c index 44660f8f97f..ec9dca0c66b 100644 --- a/appsec/src/extension/duration_acc.c +++ b/appsec/src/extension/duration_acc.c @@ -30,8 +30,8 @@ static double _elapsed_ns(const struct timespec *start) void dd_duration_flush_metrics(zend_object *nonnull span) { - zval *metrics_zv = dd_trace_span_get_metrics(span); - if (!metrics_zv) { + zval *attributes = dd_trace_span_get_attributes(span); + if (!attributes) { return; } @@ -44,7 +44,7 @@ void dd_duration_flush_metrics(zend_object *nonnull span) if (_waf_ext_ns > 0.0) { // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) ZVAL_DOUBLE(&zv, _waf_ext_ns / 1e3); - if (zend_hash_add(Z_ARRVAL_P(metrics_zv), _waf_ext_key, &zv) == NULL) { + if (zend_hash_add(Z_ARRVAL_P(attributes), _waf_ext_key, &zv) == NULL) { mlog(dd_log_warning, "Failed to add metric %.*s", (int)ZSTR_LEN(_waf_ext_key), ZSTR_VAL(_waf_ext_key)); } @@ -54,7 +54,7 @@ void dd_duration_flush_metrics(zend_object *nonnull span) if (_rasp_ext_ns > 0.0) { // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) ZVAL_DOUBLE(&zv, _rasp_ext_ns / 1e3); - if (zend_hash_add(Z_ARRVAL_P(metrics_zv), _rasp_ext_key, &zv) == NULL) { + if (zend_hash_add(Z_ARRVAL_P(attributes), _rasp_ext_key, &zv) == NULL) { mlog(dd_log_warning, "Failed to add metric %.*s", (int)ZSTR_LEN(_rasp_ext_key), ZSTR_VAL(_rasp_ext_key)); } diff --git a/appsec/src/extension/request_lifecycle.c b/appsec/src/extension/request_lifecycle.c index e52f02a98f0..3778504aa10 100644 --- a/appsec/src/extension/request_lifecycle.c +++ b/appsec/src/extension/request_lifecycle.c @@ -1058,8 +1058,8 @@ static uint64_t _calc_sampling_key(zend_object *root_span, int status_code, return 0; } - zval *nullable meta = dd_trace_span_get_meta(root_span); - if (!meta) { + zval *nullable attributes = dd_trace_span_get_attributes(root_span); + if (!attributes) { return 0; } @@ -1075,14 +1075,15 @@ static uint64_t _calc_sampling_key(zend_object *root_span, int status_code, zend_string *route_or_endpoint = NULL; bool free_route_or_endpoint = false; - zval *route = zend_hash_str_find(Z_ARRVAL_P(meta), ZEND_STRL("http.route")); + zval *route = + zend_hash_str_find(Z_ARRVAL_P(attributes), ZEND_STRL("http.route")); const bool has_http_route = route && Z_TYPE_P(route) == IS_STRING; if (has_http_route) { route_or_endpoint = Z_STR_P(route); } else { // http.route is absent, check for http.endpoint - zval *endpoint = - zend_hash_str_find(Z_ARRVAL_P(meta), ZEND_STRL("http.endpoint")); + zval *endpoint = zend_hash_str_find( + Z_ARRVAL_P(attributes), ZEND_STRL("http.endpoint")); const bool has_http_endpoint = endpoint && Z_TYPE_P(endpoint) == IS_STRING; if (has_http_endpoint) { @@ -1098,8 +1099,8 @@ static uint64_t _calc_sampling_key(zend_object *root_span, int status_code, } else { // http.endpoint not computed, compute it now without setting the // tag - zval *url = - zend_hash_str_find(Z_ARRVAL_P(meta), ZEND_STRL("http.url")); + zval *url = zend_hash_str_find( + Z_ARRVAL_P(attributes), ZEND_STRL("http.url")); const bool has_http_url = url && Z_TYPE_P(url) == IS_STRING; if (has_http_url) { route_or_endpoint = dd_trace_guess_endpoint_from_url( @@ -1122,7 +1123,7 @@ static uint64_t _calc_sampling_key(zend_object *root_span, int status_code, } zval *method = - zend_hash_str_find(Z_ARRVAL_P(meta), ZEND_STRL("http.method")); + zend_hash_str_find(Z_ARRVAL_P(attributes), ZEND_STRL("http.method")); if (!method || Z_TYPE_P(method) != IS_STRING) { mlog_g(dd_log_debug, "No http.method tag; not sampling"); // we treat the absence of http.method also as a missing route, because diff --git a/appsec/src/extension/tags.c b/appsec/src/extension/tags.c index 0f33cbdb8c9..5d686888524 100644 --- a/appsec/src/extension/tags.c +++ b/appsec/src/extension/tags.c @@ -149,7 +149,7 @@ static void _add_basic_ancillary_tags(zend_object *nonnull span, static bool _add_all_ancillary_tags( zend_object *nonnull span, const zend_array *nonnull server); static void _set_runtime_family(zend_object *nonnull span); -static bool _set_appsec_enabled(zval *metrics_zv); +static bool _set_appsec_enabled(zval *attributes); static void _register_functions(void); static void _register_test_functions(void); @@ -386,10 +386,10 @@ void dd_tags_add_tags( const zend_array *nonnull server = dd_get_superglob_or_equiv( LSTRARG("_SERVER"), TRACK_VARS_SERVER, superglob_equiv); - zval *metrics_zv = dd_trace_span_get_metrics(span); - if (metrics_zv) { + zval *attributes = dd_trace_span_get_attributes(span); + if (attributes) { // metric _dd.appsec.enabled - bool added = _set_appsec_enabled(metrics_zv); + bool added = _set_appsec_enabled(attributes); if (added) { mlog(dd_log_debug, "Added metric %s", DD_METRIC_ENABLED); } else { @@ -422,7 +422,8 @@ void dd_tags_add_tags( ZVAL_STR(&tag_value_zv, tag_value); // tag _dd.appsec.json - bool res = dd_trace_span_add_tag(span, _dd_tag_data_zstr, &tag_value_zv); + bool res = + dd_trace_span_add_attribute(span, _dd_tag_data_zstr, &tag_value_zv); if (!res) { mlog(dd_log_info, "Failed adding tag " DD_TAG_DATA " to root span"); return; @@ -431,7 +432,7 @@ void dd_tags_add_tags( // tag appsec.event zval _true_zval; ZVAL_STR(&_true_zval, _true_zstr); - res = dd_trace_span_add_tag(span, _dd_tag_event_zstr, &_true_zval); + res = dd_trace_span_add_attribute(span, _dd_tag_event_zstr, &_true_zval); if (!res) { mlog(dd_log_info, "Failed adding tag " DD_TAG_EVENT " to root span"); return; @@ -493,79 +494,79 @@ static zend_string *_concat_json_fragments(void) } // NOLINTEND(bugprone-multi-level-implicit-pointer-conversion) -static void _add_basic_tags_to_meta( - zval *nonnull meta, const zend_array *nonnull server, HashTable *headers); -static void _add_all_tags_to_meta( - zval *nonnull meta, const zend_array *nonnull server); -static void _dd_http_method(zend_array *meta_ht); +static void _add_basic_tags_to_attributes(zval *nonnull attributes, + const zend_array *nonnull server, HashTable *headers); +static void _add_all_tags_to_attributes( + zval *nonnull attributes, const zend_array *nonnull server); +static void _dd_http_method(zend_array *attributes_ht); static void _dd_http_url( - zend_array *meta_ht, const zend_array *nonnull _server); + zend_array *attributes_ht, const zend_array *nonnull _server); static void _dd_http_user_agent( - zend_array *meta_ht, const zend_array *nonnull _server); -static void _dd_http_status_code(zend_array *meta_ht); + zend_array *attributes_ht, const zend_array *nonnull _server); +static void _dd_http_status_code(zend_array *attributes_ht); static void _dd_http_network_client_ip( - zend_array *meta_ht, const zend_array *_server); -static void _dd_http_client_ip(zend_array *meta_ht); -static void _dd_request_headers(zend_array *meta_ht, const zend_array *_server, - const zend_array *nonnull relevant_headers); -static void _dd_response_headers(zend_array *meta_ht); -static void _dd_event_user_id(zend_array *meta_ht); -static void _dd_appsec_blocked(zend_array *meta_ht); + zend_array *attributes_ht, const zend_array *_server); +static void _dd_http_client_ip(zend_array *attributes_ht); +static void _dd_request_headers(zend_array *attributes_ht, + const zend_array *_server, const zend_array *nonnull relevant_headers); +static void _dd_response_headers(zend_array *attributes_ht); +static void _dd_event_user_id(zend_array *attributes_ht); +static void _dd_appsec_blocked(zend_array *attributes_ht); static void _add_basic_ancillary_tags(zend_object *nonnull span, const zend_array *nonnull server, HashTable *headers) { - zval *nullable meta = dd_trace_span_get_meta(span); - if (!meta) { + zval *nullable attributes = dd_trace_span_get_attributes(span); + if (!attributes) { return; } - _add_basic_tags_to_meta(meta, server, headers); + _add_basic_tags_to_attributes(attributes, server, headers); } static bool _add_all_ancillary_tags( zend_object *nonnull span, const zend_array *nonnull server) { - zval *nullable meta = dd_trace_span_get_meta(span); - if (!meta) { + zval *nullable attributes = dd_trace_span_get_attributes(span); + if (!attributes) { return false; } - _add_all_tags_to_meta(meta, server); + _add_all_tags_to_attributes(attributes, server); return true; } // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) -static void _add_basic_tags_to_meta( - zval *nonnull meta, const zend_array *nonnull _server, HashTable *headers) +static void _add_basic_tags_to_attributes(zval *nonnull attributes, + const zend_array *nonnull _server, HashTable *headers) { - zend_array *meta_ht = Z_ARRVAL_P(meta); + zend_array *attributes_ht = Z_ARRVAL_P(attributes); - _dd_http_client_ip(meta_ht); + _dd_http_client_ip(attributes_ht); - _dd_request_headers(meta_ht, _server, headers); - _dd_response_headers(meta_ht); + _dd_request_headers(attributes_ht, _server, headers); + _dd_response_headers(attributes_ht); } // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) -static void _add_all_tags_to_meta( - zval *nonnull meta, const zend_array *nonnull _server) +static void _add_all_tags_to_attributes( + zval *nonnull attributes, const zend_array *nonnull _server) { - zend_array *meta_ht = Z_ARRVAL_P(meta); - _dd_http_method(meta_ht); - _dd_http_url(meta_ht, _server); - _dd_http_user_agent(meta_ht, _server); - _dd_http_status_code(meta_ht); - _dd_http_network_client_ip(meta_ht, _server); - _dd_request_headers(meta_ht, _server, &_relevant_headers); - _dd_http_client_ip(meta_ht); - _dd_response_headers(meta_ht); - _dd_event_user_id(meta_ht); - _dd_appsec_blocked(meta_ht); + zend_array *attributes_ht = Z_ARRVAL_P(attributes); + _dd_http_method(attributes_ht); + _dd_http_url(attributes_ht, _server); + _dd_http_user_agent(attributes_ht, _server); + _dd_http_status_code(attributes_ht); + _dd_http_network_client_ip(attributes_ht, _server); + _dd_request_headers(attributes_ht, _server, &_relevant_headers); + _dd_http_client_ip(attributes_ht); + _dd_response_headers(attributes_ht); + _dd_event_user_id(attributes_ht); + _dd_appsec_blocked(attributes_ht); } -static void _add_new_zstr_to_meta(zend_array *meta_ht, zend_string *key, - zend_string *val, bool copy, bool override) +static void _add_new_zstr_to_attributes(zend_array *attributes_ht, + zend_string *key, zend_string *val, bool copy, bool override) { if (ZSTR_LEN(key) <= INT_MAX && ZSTR_LEN(val) <= INT_MAX) { mlog(dd_log_debug, "Adding tag '%.*s' with value '%.*s'", @@ -580,9 +581,9 @@ static void _add_new_zstr_to_meta(zend_array *meta_ht, zend_string *key, zval zv; ZVAL_STR(&zv, val); if (override) { - added = zend_hash_update(meta_ht, key, &zv); + added = zend_hash_update(attributes_ht, key, &zv); } else { - added = zend_hash_add(meta_ht, key, &zv); + added = zend_hash_add(attributes_ht, key, &zv); } if (copy && added == NULL) { @@ -590,9 +591,9 @@ static void _add_new_zstr_to_meta(zend_array *meta_ht, zend_string *key, } } -static void _dd_http_method(zend_array *meta_ht) +static void _dd_http_method(zend_array *attributes_ht) { - if (zend_hash_exists(meta_ht, _dd_tag_http_method_zstr)) { + if (zend_hash_exists(attributes_ht, _dd_tag_http_method_zstr)) { return; } const char *method = SG(request_info).request_method; @@ -600,12 +601,12 @@ static void _dd_http_method(zend_array *meta_ht) return; } zend_string *method_zstr = zend_string_init(method, strlen(method), 0); - _add_new_zstr_to_meta( - meta_ht, _dd_tag_http_method_zstr, method_zstr, false, false); + _add_new_zstr_to_attributes( + attributes_ht, _dd_tag_http_method_zstr, method_zstr, false, false); } -static void _dd_http_url(zend_array *meta_ht, const zend_array *_server) +static void _dd_http_url(zend_array *attributes_ht, const zend_array *_server) { - if (zend_hash_exists(meta_ht, _dd_tag_http_url_zstr)) { + if (zend_hash_exists(attributes_ht, _dd_tag_http_url_zstr)) { return; } @@ -650,14 +651,14 @@ static void _dd_http_url(zend_array *meta_ht, const zend_array *_server) smart_str_appendl(&url_str, uri, uri_len); smart_str_0(&url_str); - _add_new_zstr_to_meta( - meta_ht, _dd_tag_http_url_zstr, url_str.s, false, false); + _add_new_zstr_to_attributes( + attributes_ht, _dd_tag_http_url_zstr, url_str.s, false, false); } static void _dd_http_user_agent( - zend_array *meta_ht, const zend_array *nonnull _server) + zend_array *attributes_ht, const zend_array *nonnull _server) { - if (zend_hash_exists(meta_ht, _dd_tag_http_user_agent_zstr)) { + if (zend_hash_exists(attributes_ht, _dd_tag_http_user_agent_zstr)) { return; } zend_string *http_user_agent_zstr = @@ -666,13 +667,13 @@ static void _dd_http_user_agent( return; } - _add_new_zstr_to_meta(meta_ht, _dd_tag_http_user_agent_zstr, + _add_new_zstr_to_attributes(attributes_ht, _dd_tag_http_user_agent_zstr, http_user_agent_zstr, true, false); } -static void _dd_http_status_code(zend_array *meta_ht) +static void _dd_http_status_code(zend_array *attributes_ht) { - if (zend_hash_exists(meta_ht, _dd_tag_http_status_code_zstr)) { + if (zend_hash_exists(attributes_ht, _dd_tag_http_status_code_zstr)) { return; } @@ -685,14 +686,14 @@ static void _dd_http_status_code(zend_array *meta_ht) ZVAL_LONG(&zv, (zend_long)status); convert_to_string(&zv); - _add_new_zstr_to_meta( - meta_ht, _dd_tag_http_status_code_zstr, Z_STR(zv), false, false); + _add_new_zstr_to_attributes( + attributes_ht, _dd_tag_http_status_code_zstr, Z_STR(zv), false, false); } static void _dd_http_network_client_ip( - zend_array *meta_ht, const zend_array *_server) + zend_array *attributes_ht, const zend_array *_server) { - if (zend_hash_exists(meta_ht, _dd_tag_network_client_ip_zstr)) { + if (zend_hash_exists(attributes_ht, _dd_tag_network_client_ip_zstr)) { return; } zend_string *remote_addr_zstr = @@ -701,27 +702,28 @@ static void _dd_http_network_client_ip( return; } - _add_new_zstr_to_meta( - meta_ht, _dd_tag_network_client_ip_zstr, remote_addr_zstr, true, false); + _add_new_zstr_to_attributes(attributes_ht, _dd_tag_network_client_ip_zstr, + remote_addr_zstr, true, false); } -static void _dd_http_client_ip(zend_array *meta_ht) +static void _dd_http_client_ip(zend_array *attributes_ht) { - if (zend_hash_exists(meta_ht, _dd_tag_http_client_ip_zstr)) { + if (zend_hash_exists(attributes_ht, _dd_tag_http_client_ip_zstr)) { return; } zend_string *client_ip = dd_req_lifecycle_get_client_ip(); if (client_ip) { - _add_new_zstr_to_meta( - meta_ht, _dd_tag_http_client_ip_zstr, client_ip, true, false); + _add_new_zstr_to_attributes( + attributes_ht, _dd_tag_http_client_ip_zstr, client_ip, true, false); } } -static void _try_add_tag(zend_array *meta_ht, zend_string *tag_name, zval *val) +static void _try_add_attribute( + zend_array *attributes_ht, zend_string *tag_name, zval *val) { Z_TRY_ADDREF_P(val); - bool added = zend_hash_add(meta_ht, tag_name, val) != NULL; + bool added = zend_hash_add(attributes_ht, tag_name, val) != NULL; if (added) { mlog(dd_log_debug, "Adding request header tag '%s' -> '%s", ZSTR_VAL(tag_name), ZSTR_VAL(Z_STR_P(val))); @@ -732,7 +734,7 @@ static void _try_add_tag(zend_array *meta_ht, zend_string *tag_name, zval *val) static void _dd_request_headers( // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) - zend_array *meta_ht, const zend_array *nonnull _server, + zend_array *attributes_ht, const zend_array *nonnull _server, const zend_array *relevant_headers) { // Pack headers @@ -749,9 +751,9 @@ static void _dd_request_headers( } if (zend_string_equals_literal(key, "CONTENT_TYPE")) { - _try_add_tag(meta_ht, _dd_tag_content_type, val); + _try_add_attribute(attributes_ht, _dd_tag_content_type, val); } else if (zend_string_equals_literal(key, "CONTENT_LENGTH")) { - _try_add_tag(meta_ht, _dd_tag_content_length, val); + _try_add_attribute(attributes_ht, _dd_tag_content_length, val); } if (ZSTR_LEN(key) <= LSTRLEN("HTTP_") || @@ -777,7 +779,7 @@ static void _dd_request_headers( continue; } - _try_add_tag(meta_ht, tag_name, val); + _try_add_attribute(attributes_ht, tag_name, val); zend_string_release(tag_name); } ZEND_HASH_FOREACH_END(); @@ -785,7 +787,7 @@ static void _dd_request_headers( static zend_string *nullable _is_relevant_resp_header( const char *name, size_t name_len); -static void _dd_response_headers(zend_array *meta_ht) +static void _dd_response_headers(zend_array *attributes_ht) { zend_llist *l = &SG(sapi_headers).headers; zend_llist_position pos; @@ -816,7 +818,7 @@ static void _dd_response_headers(zend_array *meta_ht) zval zv; ZVAL_STR(&zv, header_value); - bool added = zend_hash_add(meta_ht, tag_name, &zv) != NULL; + bool added = zend_hash_add(attributes_ht, tag_name, &zv) != NULL; if (added) { mlog(dd_log_debug, "Adding response header tag '%s' -> '%s", ZSTR_VAL(tag_name), ZSTR_VAL(header_value)); @@ -826,19 +828,19 @@ static void _dd_response_headers(zend_array *meta_ht) } } -static void _dd_event_user_id(zend_array *meta_ht) +static void _dd_event_user_id(zend_array *attributes_ht) { if (_event_user_id) { - _add_new_zstr_to_meta( - meta_ht, _dd_tag_user_id, _event_user_id, true, false); + _add_new_zstr_to_attributes( + attributes_ht, _dd_tag_user_id, _event_user_id, true, false); } } -static void _dd_appsec_blocked(zend_array *meta_ht) +static void _dd_appsec_blocked(zend_array *attributes_ht) { if (dd_req_lifecycle_is_blocked()) { - _add_new_zstr_to_meta( - meta_ht, _dd_tag_blocked_zstr, _true_zstr, true, false); + _add_new_zstr_to_attributes( + attributes_ht, _dd_tag_blocked_zstr, _true_zstr, true, false); } } @@ -868,7 +870,7 @@ static zend_string *nullable _is_relevant_resp_header( static void _set_runtime_family(zend_object *nonnull span) { - bool res = dd_trace_span_add_tag_str( + bool res = dd_trace_span_add_attribute_str( span, LSTRARG(DD_TAG_RUNTIME_FAMILY), LSTRARG("php")); if (!res && !get_global_DD_APPSEC_TESTING()) { mlog(dd_log_warning, @@ -876,7 +878,7 @@ static void _set_runtime_family(zend_object *nonnull span) } } -static void _add_custom_event_keyval(zend_array *nonnull meta_ht, +static void _add_custom_event_keyval(zend_array *nonnull attributes_ht, // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) zend_string *nonnull event, zend_string *nonnull key, zend_string *nonnull value, bool copy, bool override) @@ -890,11 +892,12 @@ static void _add_custom_event_keyval(zend_array *nonnull meta_ht, smart_str_append_ex(&key_str, key, 0); smart_str_0(&key_str); - _add_new_zstr_to_meta(meta_ht, key_str.s, value, copy, override); + _add_new_zstr_to_attributes( + attributes_ht, key_str.s, value, copy, override); smart_str_free(&key_str); } -static void _add_custom_event_metadata(zend_array *nonnull meta_ht, +static void _add_custom_event_metadata(zend_array *nonnull attributes_ht, zend_string *nonnull event, HashTable *nullable metadata, bool override) { if (metadata == NULL) { @@ -909,7 +912,7 @@ static void _add_custom_event_metadata(zend_array *nonnull meta_ht, continue; } _add_custom_event_keyval( - meta_ht, event, key, Z_STR_P(value), true, override); + attributes_ht, event, key, Z_STR_P(value), true, override); } ZEND_HASH_FOREACH_END(); } @@ -934,7 +937,7 @@ bool match_regex(zend_string *pattern, zend_string *subject) return Z_TYPE(ret) == IS_LONG && Z_LVAL(ret) > 0; } -static zval *nullable _root_span_get_meta(void) +static zval *nullable _root_span_get_attributes(void) { zend_object *nullable span = dd_req_lifecycle_get_cur_span(); if (!span) { @@ -942,11 +945,11 @@ static zval *nullable _root_span_get_meta(void) return NULL; } - zval *nullable meta = dd_trace_span_get_meta(span); - if (!meta) { - mlog(dd_log_warning, "Failed to retrieve root span meta"); + zval *nullable attributes = dd_trace_span_get_attributes(span); + if (!attributes) { + mlog(dd_log_warning, "Failed to retrieve root span attributes"); } - return meta; + return attributes; } PHP_FUNCTION(datadog_appsec_internal_track_user_signup_event_automated) @@ -995,13 +998,13 @@ PHP_FUNCTION(datadog_appsec_internal_track_user_signup_event_automated) user_id = zend_empty_string; } - zval *nullable meta = _root_span_get_meta(); - if (!meta) { + zval *nullable attributes = _root_span_get_attributes(); + if (!attributes) { return; } _user_event_triggered = true; - zend_array *meta_ht = Z_ARRVAL_P(meta); + zend_array *attributes_ht = Z_ARRVAL_P(attributes); user_collection_mode mode = dd_get_user_collection_mode(); if (mode == user_mode_disabled || @@ -1030,11 +1033,12 @@ PHP_FUNCTION(datadog_appsec_internal_track_user_signup_event_automated) if (ZSTR_LEN(user_id) > 0) { // appsec.events.users.signup.usr.id = - _add_custom_event_keyval(meta_ht, _dd_signup_event, _dd_tag_user_id, - anon_user_id ? anon_user_id : user_id, true, false); + _add_custom_event_keyval(attributes_ht, _dd_signup_event, + _dd_tag_user_id, anon_user_id ? anon_user_id : user_id, true, + false); // _dd.appsec.usr.id = - _add_new_zstr_to_meta(meta_ht, _dd_appsec_user_id, + _add_new_zstr_to_attributes(attributes_ht, _dd_appsec_user_id, anon_user_id ? anon_user_id : user_id, !anon_user_id, true); } else if (anon_user_id) { zend_string_release(anon_user_id); @@ -1042,24 +1046,24 @@ PHP_FUNCTION(datadog_appsec_internal_track_user_signup_event_automated) // _dd.appsec.events.users.signup.auto.mode = // - _add_new_zstr_to_meta(meta_ht, _dd_signup_event_auto_mode, + _add_new_zstr_to_attributes(attributes_ht, _dd_signup_event_auto_mode, dd_get_user_collection_mode_zstr(), true, false); // _dd.appsec.events.users.signup.usr.login = - _add_new_zstr_to_meta(meta_ht, _dd_signup_event_login, + _add_new_zstr_to_attributes(attributes_ht, _dd_signup_event_login, anon_user_login ? anon_user_login : user_login, true, false); // _dd.appsec.usr.login = - _add_new_zstr_to_meta(meta_ht, _dd_appsec_user_login, + _add_new_zstr_to_attributes(attributes_ht, _dd_appsec_user_login, anon_user_login ? anon_user_login : user_login, !anon_user_login, true); // appsec.events.users.signup.success.track = true _add_custom_event_keyval( - meta_ht, _dd_signup_event, _track_zstr, _true_zstr, true, false); + attributes_ht, _dd_signup_event, _track_zstr, _true_zstr, true, false); // server.business_logic.users.signup = null - _add_new_zstr_to_meta( - meta_ht, _dd_business_logic_users_signup, _null_zstr, true, true); + _add_new_zstr_to_attributes( + attributes_ht, _dd_business_logic_users_signup, _null_zstr, true, true); dd_trace_emit_asm_event(); } @@ -1089,35 +1093,36 @@ PHP_FUNCTION(datadog_appsec_track_user_signup_event) return; } - zval *nullable meta = _root_span_get_meta(); - if (!meta) { + zval *nullable attributes = _root_span_get_attributes(); + if (!attributes) { return; } _user_event_triggered = true; - zend_array *meta_ht = Z_ARRVAL_P(meta); + zend_array *attributes_ht = Z_ARRVAL_P(attributes); // appsec.events.users.signup.usr.id = _add_custom_event_keyval( - meta_ht, _dd_signup_event, _dd_tag_user_id, user_id, true, true); + attributes_ht, _dd_signup_event, _dd_tag_user_id, user_id, true, true); // _dd.appsec.events.users.signup.usr.login = - _add_new_zstr_to_meta(meta_ht, _dd_signup_event_login, user_id, true, true); + _add_new_zstr_to_attributes( + attributes_ht, _dd_signup_event_login, user_id, true, true); // _dd.appsec.events.users.signup.sdk = true - _add_new_zstr_to_meta( - meta_ht, _dd_signup_event_sdk, _true_zstr, true, true); + _add_new_zstr_to_attributes( + attributes_ht, _dd_signup_event_sdk, _true_zstr, true, true); // appsec.events.users.signup. = - _add_custom_event_metadata(meta_ht, _dd_signup_event, metadata, true); + _add_custom_event_metadata(attributes_ht, _dd_signup_event, metadata, true); // appsec.events.users.signup.success.track = true _add_custom_event_keyval( - meta_ht, _dd_signup_event, _track_zstr, _true_zstr, true, true); + attributes_ht, _dd_signup_event, _track_zstr, _true_zstr, true, true); // server.business_logic.users.signup = null - _add_new_zstr_to_meta( - meta_ht, _dd_business_logic_users_signup, _null_zstr, true, true); + _add_new_zstr_to_attributes( + attributes_ht, _dd_business_logic_users_signup, _null_zstr, true, true); dd_trace_emit_asm_event(); } @@ -1168,13 +1173,13 @@ PHP_FUNCTION(datadog_appsec_internal_track_user_login_success_event_automated) user_id = zend_empty_string; } - zval *nullable meta = _root_span_get_meta(); - if (!meta) { + zval *nullable attributes = _root_span_get_attributes(); + if (!attributes) { return; } _user_event_triggered = true; - zend_array *meta_ht = Z_ARRVAL_P(meta); + zend_array *attributes_ht = Z_ARRVAL_P(attributes); user_collection_mode mode = dd_get_user_collection_mode(); if (mode == user_mode_disabled || @@ -1206,11 +1211,11 @@ PHP_FUNCTION(datadog_appsec_internal_track_user_login_success_event_automated) user_id, user_login, user_event_login_success); // usr.id = - _add_new_zstr_to_meta(meta_ht, _dd_tag_user_id, + _add_new_zstr_to_attributes(attributes_ht, _dd_tag_user_id, anon_user_id ? anon_user_id : user_id, true, false); // _dd.appsec.usr.id = - _add_new_zstr_to_meta(meta_ht, _dd_appsec_user_id, + _add_new_zstr_to_attributes(attributes_ht, _dd_appsec_user_id, anon_user_id ? anon_user_id : user_id, !anon_user_id, true); } else if (anon_user_id) { zend_string_release(anon_user_id); @@ -1218,24 +1223,25 @@ PHP_FUNCTION(datadog_appsec_internal_track_user_login_success_event_automated) // _dd.appsec.events.users.login.success.auto.mode = // - _add_new_zstr_to_meta(meta_ht, _dd_login_success_event_auto_mode, - dd_get_user_collection_mode_zstr(), true, false); + _add_new_zstr_to_attributes(attributes_ht, + _dd_login_success_event_auto_mode, dd_get_user_collection_mode_zstr(), + true, false); // _dd.appsec.events.users.login.success.usr.login = - _add_new_zstr_to_meta(meta_ht, _dd_login_success_event_login, + _add_new_zstr_to_attributes(attributes_ht, _dd_login_success_event_login, anon_user_login ? anon_user_login : user_login, true, false); // _dd.appsec.usr.login = - _add_new_zstr_to_meta(meta_ht, _dd_appsec_user_login, + _add_new_zstr_to_attributes(attributes_ht, _dd_appsec_user_login, anon_user_login ? anon_user_login : user_login, !anon_user_login, true); // appsec.events.users.login.success.track = true - _add_custom_event_keyval( - meta_ht, _dd_login_success_event, _track_zstr, _true_zstr, true, false); + _add_custom_event_keyval(attributes_ht, _dd_login_success_event, + _track_zstr, _true_zstr, true, false); // server.business_logic.users.login.success = null - _add_new_zstr_to_meta(meta_ht, _dd_business_logic_users_login_success, - _null_zstr, true, true); + _add_new_zstr_to_attributes(attributes_ht, + _dd_business_logic_users_login_success, _null_zstr, true, true); dd_trace_emit_asm_event(); } @@ -1263,39 +1269,40 @@ PHP_FUNCTION(datadog_appsec_track_user_login_success_event) return; } - zval *nullable meta = _root_span_get_meta(); - if (!meta) { + zval *nullable attributes = _root_span_get_attributes(); + if (!attributes) { return; } _user_event_triggered = true; - zend_array *meta_ht = Z_ARRVAL_P(meta); + zend_array *attributes_ht = Z_ARRVAL_P(attributes); dd_find_and_apply_verdict_for_user( user_id, zend_empty_string, user_event_login_success); // usr.id = - _add_new_zstr_to_meta(meta_ht, _dd_tag_user_id, user_id, true, true); + _add_new_zstr_to_attributes( + attributes_ht, _dd_tag_user_id, user_id, true, true); // _dd.appsec.events.users.login.success.usr.login = - _add_new_zstr_to_meta( - meta_ht, _dd_login_success_event_login, user_id, true, true); + _add_new_zstr_to_attributes( + attributes_ht, _dd_login_success_event_login, user_id, true, true); // _dd.appsec.events.users.login.success.sdk = true - _add_new_zstr_to_meta( - meta_ht, _dd_login_success_event_sdk, _true_zstr, true, true); + _add_new_zstr_to_attributes( + attributes_ht, _dd_login_success_event_sdk, _true_zstr, true, true); // appsec.events.users.login.success. = _add_custom_event_metadata( - meta_ht, _dd_login_success_event, metadata, true); + attributes_ht, _dd_login_success_event, metadata, true); // appsec.events.users.login.success.track = true - _add_custom_event_keyval( - meta_ht, _dd_login_success_event, _track_zstr, _true_zstr, true, true); + _add_custom_event_keyval(attributes_ht, _dd_login_success_event, + _track_zstr, _true_zstr, true, true); // server.business_logic.users.login.success = null - _add_new_zstr_to_meta(meta_ht, _dd_business_logic_users_login_success, - _null_zstr, true, true); + _add_new_zstr_to_attributes(attributes_ht, + _dd_business_logic_users_login_success, _null_zstr, true, true); dd_trace_emit_asm_event(); } @@ -1346,13 +1353,13 @@ PHP_FUNCTION(datadog_appsec_internal_track_user_login_failure_event_automated) user_id = zend_empty_string; } - zval *nullable meta = _root_span_get_meta(); - if (!meta) { + zval *nullable attributes = _root_span_get_attributes(); + if (!attributes) { return; } _user_event_triggered = true; - zend_array *meta_ht = Z_ARRVAL_P(meta); + zend_array *attributes_ht = Z_ARRVAL_P(attributes); user_collection_mode mode = dd_get_user_collection_mode(); if (mode == user_mode_disabled || @@ -1387,12 +1394,12 @@ PHP_FUNCTION(datadog_appsec_internal_track_user_login_failure_event_automated) if (ZSTR_LEN(user_id) > 0) { // appsec.events.users.login.failure.usr.id = - _add_custom_event_keyval(meta_ht, _dd_login_failure_event, + _add_custom_event_keyval(attributes_ht, _dd_login_failure_event, _dd_tag_user_id, anon_user_id ? anon_user_id : user_id, true, false); // _dd.appsec.usr.id = - _add_new_zstr_to_meta(meta_ht, _dd_appsec_user_id, + _add_new_zstr_to_attributes(attributes_ht, _dd_appsec_user_id, anon_user_id ? anon_user_id : user_id, !anon_user_id, true); } else if (anon_user_id) { zend_string_release(anon_user_id); @@ -1400,16 +1407,18 @@ PHP_FUNCTION(datadog_appsec_internal_track_user_login_failure_event_automated) // _dd.appsec.events.users.login.failure.auto.mode = // - _add_new_zstr_to_meta(meta_ht, _dd_login_failure_event_auto_mode, - dd_get_user_collection_mode_zstr(), true, false); + _add_new_zstr_to_attributes(attributes_ht, + _dd_login_failure_event_auto_mode, dd_get_user_collection_mode_zstr(), + true, false); if (ZSTR_LEN(user_login) > 0) { // _dd.appsec.events.users.login.failure.usr.login = - _add_new_zstr_to_meta(meta_ht, _dd_login_failure_event_login, + _add_new_zstr_to_attributes(attributes_ht, + _dd_login_failure_event_login, anon_user_login ? anon_user_login : user_login, true, false); // _dd.appsec.usr.login = - _add_new_zstr_to_meta(meta_ht, _dd_appsec_user_login, + _add_new_zstr_to_attributes(attributes_ht, _dd_appsec_user_login, anon_user_login ? anon_user_login : user_login, !anon_user_login, true); } else if (anon_user_login) { @@ -1417,16 +1426,16 @@ PHP_FUNCTION(datadog_appsec_internal_track_user_login_failure_event_automated) } // appsec.events.users.login.failure.track = true - _add_custom_event_keyval( - meta_ht, _dd_login_failure_event, _track_zstr, _true_zstr, true, false); + _add_custom_event_keyval(attributes_ht, _dd_login_failure_event, + _track_zstr, _true_zstr, true, false); // appsec.events.users.login.failure.usr.exists = - _add_custom_event_keyval(meta_ht, _dd_login_failure_event, _usr_exists_zstr, - exists ? _true_zstr : _false_zstr, true, false); + _add_custom_event_keyval(attributes_ht, _dd_login_failure_event, + _usr_exists_zstr, exists ? _true_zstr : _false_zstr, true, false); // server.business_logic.users.login.failure = null - _add_new_zstr_to_meta(meta_ht, _dd_business_logic_users_login_failure, - _null_zstr, true, true); + _add_new_zstr_to_attributes(attributes_ht, + _dd_business_logic_users_login_failure, _null_zstr, true, true); dd_trace_emit_asm_event(); } @@ -1450,43 +1459,43 @@ PHP_FUNCTION(datadog_appsec_track_user_login_failure_event) return; } - zval *nullable meta = _root_span_get_meta(); - if (!meta) { + zval *nullable attributes = _root_span_get_attributes(); + if (!attributes) { return; } _user_event_triggered = true; - zend_array *meta_ht = Z_ARRVAL_P(meta); + zend_array *attributes_ht = Z_ARRVAL_P(attributes); if (ZSTR_LEN(user_id) > 0) { // appsec.events.users.login.failure.usr.id = - _add_custom_event_keyval(meta_ht, _dd_login_failure_event, + _add_custom_event_keyval(attributes_ht, _dd_login_failure_event, _dd_tag_user_id, user_id, true, true); // _dd.appsec.events.users.login.failure.usr.login = - _add_new_zstr_to_meta( - meta_ht, _dd_login_failure_event_login, user_id, true, true); + _add_new_zstr_to_attributes( + attributes_ht, _dd_login_failure_event_login, user_id, true, true); } // appsec.events.users.login.failure.track = true - _add_custom_event_keyval( - meta_ht, _dd_login_failure_event, _track_zstr, _true_zstr, true, true); + _add_custom_event_keyval(attributes_ht, _dd_login_failure_event, + _track_zstr, _true_zstr, true, true); // _dd.appsec.events.users.login.failure.sdk = true - _add_new_zstr_to_meta( - meta_ht, _dd_login_failure_event_sdk, _true_zstr, true, true); + _add_new_zstr_to_attributes( + attributes_ht, _dd_login_failure_event_sdk, _true_zstr, true, true); // appsec.events.users.login.failure. = _add_custom_event_metadata( - meta_ht, _dd_login_failure_event, metadata, true); + attributes_ht, _dd_login_failure_event, metadata, true); // appsec.events.users.login.failure.usr.exists = - _add_custom_event_keyval(meta_ht, _dd_login_failure_event, _usr_exists_zstr, - exists ? _true_zstr : _false_zstr, true, true); + _add_custom_event_keyval(attributes_ht, _dd_login_failure_event, + _usr_exists_zstr, exists ? _true_zstr : _false_zstr, true, true); // server.business_logic.users.login.failure = null - _add_new_zstr_to_meta(meta_ht, _dd_business_logic_users_login_failure, - _null_zstr, true, true); + _add_new_zstr_to_attributes(attributes_ht, + _dd_business_logic_users_login_failure, _null_zstr, true, true); dd_trace_emit_asm_event(); } @@ -1537,8 +1546,8 @@ PHP_FUNCTION(datadog_appsec_internal_track_authenticated_user_event_automated) } } - zval *nullable meta = _root_span_get_meta(); - if (!meta) { + zval *nullable attributes = _root_span_get_attributes(); + if (!attributes) { if (anon_user_id) { zend_string_release(anon_user_id); } @@ -1546,22 +1555,22 @@ PHP_FUNCTION(datadog_appsec_internal_track_authenticated_user_event_automated) } _user_event_triggered = true; - zend_array *meta_ht = Z_ARRVAL_P(meta); + zend_array *attributes_ht = Z_ARRVAL_P(attributes); dd_find_and_apply_verdict_for_user( user_id, zend_empty_string, user_event_none); // usr.id = - _add_new_zstr_to_meta(meta_ht, _dd_tag_user_id, + _add_new_zstr_to_attributes(attributes_ht, _dd_tag_user_id, anon_user_id ? anon_user_id : user_id, true, false); // _dd.appsec.usr.id = - _add_new_zstr_to_meta(meta_ht, _dd_appsec_user_id, + _add_new_zstr_to_attributes(attributes_ht, _dd_appsec_user_id, anon_user_id ? anon_user_id : user_id, !anon_user_id, true); // _dd.appsec.user.collection_mode = // - _add_new_zstr_to_meta(meta_ht, _dd_user_collection_mode, + _add_new_zstr_to_attributes(attributes_ht, _dd_user_collection_mode, dd_get_user_collection_mode_zstr(), true, false); if (_auth_user_event_automated_last_user_id) { @@ -1593,26 +1602,27 @@ PHP_FUNCTION(datadog_appsec_track_authenticated_user_event) return; } - zval *nullable meta = _root_span_get_meta(); - if (!meta) { + zval *nullable attributes = _root_span_get_attributes(); + if (!attributes) { return; } _user_event_triggered = true; - zend_array *meta_ht = Z_ARRVAL_P(meta); + zend_array *attributes_ht = Z_ARRVAL_P(attributes); dd_find_and_apply_verdict_for_user( user_id, zend_empty_string, user_event_none); // usr.id = - _add_new_zstr_to_meta(meta_ht, _dd_tag_user_id, user_id, true, true); + _add_new_zstr_to_attributes( + attributes_ht, _dd_tag_user_id, user_id, true, true); // _dd.appsec.user.collection_mode = sdk - _add_new_zstr_to_meta( - meta_ht, _dd_user_collection_mode, _dd_sdk_zstr, true, true); + _add_new_zstr_to_attributes( + attributes_ht, _dd_user_collection_mode, _dd_sdk_zstr, true, true); // usr. = - _add_custom_event_metadata(meta_ht, _dd_tag_user, metadata, true); + _add_custom_event_metadata(attributes_ht, _dd_tag_user, metadata, true); } PHP_FUNCTION(datadog_appsec_track_custom_event) @@ -1638,12 +1648,12 @@ PHP_FUNCTION(datadog_appsec_track_custom_event) return; } - zval *nullable meta = _root_span_get_meta(); - if (!meta) { + zval *nullable attributes = _root_span_get_attributes(); + if (!attributes) { return; } - zend_array *meta_ht = Z_ARRVAL_P(meta); + zend_array *attributes_ht = Z_ARRVAL_P(attributes); // Generate full event name size_t event_len = LSTRLEN(DD_APPSEC_EVENTS_PREFIX) + ZSTR_LEN(event_name); @@ -1655,21 +1665,21 @@ PHP_FUNCTION(datadog_appsec_track_custom_event) // appsec.events..track = true _add_custom_event_keyval( - meta_ht, event_str.s, _track_zstr, _true_zstr, true, true); + attributes_ht, event_str.s, _track_zstr, _true_zstr, true, true); // appsec.events.. = - _add_custom_event_metadata(meta_ht, event_str.s, metadata, true); + _add_custom_event_metadata(attributes_ht, event_str.s, metadata, true); smart_str_free(&event_str); dd_trace_emit_asm_event(); } -static bool _set_appsec_enabled(zval *metrics_zv) +static bool _set_appsec_enabled(zval *attributes) { zval zv; ZVAL_LONG(&zv, DDAPPSEC_G(active) ? 1 : 0); - return zend_hash_add(Z_ARRVAL_P(metrics_zv), _dd_metric_enabled, &zv) != + return zend_hash_add(Z_ARRVAL_P(attributes), _dd_metric_enabled, &zv) != NULL; } @@ -1691,7 +1701,7 @@ static PHP_FUNCTION(datadog_appsec_testing_add_all_ancillary_tags) return; } - _add_all_tags_to_meta(arr, Z_ARRVAL_P(server)); + _add_all_tags_to_attributes(arr, Z_ARRVAL_P(server)); } static PHP_FUNCTION(datadog_appsec_testing_add_basic_ancillary_tags) @@ -1711,7 +1721,8 @@ static PHP_FUNCTION(datadog_appsec_testing_add_basic_ancillary_tags) mlog(dd_log_warning, "Could not retrieve _SERVER"); return; } - _add_basic_tags_to_meta(arr, Z_ARRVAL_P(server), &_relevant_basic_headers); + _add_basic_tags_to_attributes( + arr, Z_ARRVAL_P(server), &_relevant_basic_headers); } // clang-format off diff --git a/appsec/src/extension/telemetry.c b/appsec/src/extension/telemetry.c index cfb9f63916d..b54dbd7c784 100644 --- a/appsec/src/extension/telemetry.c +++ b/appsec/src/extension/telemetry.c @@ -25,8 +25,6 @@ static zend_string *_api_sec_request_schema_zstr; static zend_string *_api_sec_request_no_schema_zstr; static zend_string *_api_sec_missing_route_zstr; -static zend_string *_component_literal_zstr; - static THREAD_LOCAL_ON_ZTS bool _schema_extracted; static zend_string *nullable _duration_ext_tags_from_cache(void); @@ -60,8 +58,6 @@ void dd_telemetry_startup(void) zend_string_init_interned(LSTRARG("api_security.request.no_schema"), 1); _api_sec_missing_route_zstr = zend_string_init_interned(LSTRARG("api_security.missing_route"), 1); - _component_literal_zstr = - zend_string_init_interned(LSTRARG("component"), 1); } void dd_telemetry_gshutdown(ddappsec_globals *nonnull globals) @@ -161,7 +157,7 @@ void dd_telemetry_add_api_security_request( } #define DD_UNKNOWN_FRAMEWORK "unknown" -// Builds the framework tag out of the root span's component tag, which is what +// Builds the framework tag out of the root span's $component, which is what // the framework integrations set (e.g. laravel, symfony, wordpress). Per // RFC-1012, the name is normalized by lowercasing it and replacing spaces with // underscores. @@ -170,15 +166,11 @@ static zend_string *nonnull _framework_tag(zend_object *nullable root_span) const char *framework = DD_UNKNOWN_FRAMEWORK; size_t framework_len = LSTRLEN(DD_UNKNOWN_FRAMEWORK); - zval *nullable meta = root_span ? dd_trace_span_get_meta(root_span) : NULL; - if (meta != NULL && Z_TYPE_P(meta) == IS_ARRAY) { - zval *nullable component = - zend_hash_find_ex(Z_ARRVAL_P(meta), _component_literal_zstr, true); - if (component != NULL && Z_TYPE_P(component) == IS_STRING && - Z_STRLEN_P(component) > 0) { - framework = Z_STRVAL_P(component); - framework_len = Z_STRLEN_P(component); - } + zend_string *nullable component = + root_span ? dd_trace_span_get_component(root_span) : NULL; + if (component != NULL && ZSTR_LEN(component) > 0) { + framework = ZSTR_VAL(component); + framework_len = ZSTR_LEN(component); } zend_string *tags_zstr = diff --git a/appsec/src/extension/tracer_bridge.c b/appsec/src/extension/tracer_bridge.c index 939ed48a6f7..d5a17a47adf 100644 --- a/appsec/src/extension/tracer_bridge.c +++ b/appsec/src/extension/tracer_bridge.c @@ -30,8 +30,7 @@ #endif static zend_string *_attributes_propname; -static zend_string *_meta_propname; -static zend_string *_metrics_propname; +static zend_string *_component_propname; static zend_string *_meta_struct_propname; static THREAD_LOCAL_ON_ZTS bool _asm_event_emitted; @@ -40,8 +39,7 @@ static void _register_testing_objects(void); void dd_trace_startup(void) { _attributes_propname = zend_string_init_interned(LSTRARG("attributes"), 1); - _meta_propname = zend_string_init_interned(LSTRARG("meta"), 1); - _metrics_propname = zend_string_init_interned(LSTRARG("metrics"), 1); + _component_propname = zend_string_init_interned(LSTRARG("component"), 1); _meta_struct_propname = zend_string_init_interned(LSTRARG("meta_struct"), 1); @@ -59,13 +57,13 @@ void dd_trace_shutdown(void) {} bool dd_trace_enabled(void) { return get_DD_TRACE_ENABLED(); } -bool dd_trace_span_add_tag( +bool dd_trace_span_add_attribute( zend_object *nonnull span, zend_string *nonnull tag, zval *nonnull value) { - zval *meta = dd_trace_span_get_meta(span); - if (!meta) { + zval *attributes = dd_trace_span_get_attributes(span); + if (!attributes) { if (!get_global_DD_APPSEC_TESTING()) { - mlog(dd_log_warning, "Failed to retrieve root span meta"); + mlog(dd_log_warning, "Failed to retrieve root span attributes"); } zval_ptr_dtor(value); return false; @@ -78,7 +76,7 @@ bool dd_trace_span_add_tag( mlog(dd_log_debug, "Adding to root span the tag '%s'", ZSTR_VAL(tag)); } - if (zend_hash_add(Z_ARRVAL_P(meta), tag, value) == NULL) { + if (zend_hash_add(Z_ARRVAL_P(attributes), tag, value) == NULL) { zval_ptr_dtor(value); return false; } @@ -86,7 +84,7 @@ bool dd_trace_span_add_tag( return true; } -bool dd_trace_span_add_tag_str(zend_object *nonnull span, +bool dd_trace_span_add_attribute_str(zend_object *nonnull span, const char *nonnull tag, size_t tag_len, const char *nonnull value, size_t value_len) { @@ -95,10 +93,10 @@ bool dd_trace_span_add_tag_str(zend_object *nonnull span, return false; } - zval *meta = dd_trace_span_get_meta(span); - if (!meta) { + zval *attributes = dd_trace_span_get_attributes(span); + if (!attributes) { if (!get_global_DD_APPSEC_TESTING()) { - mlog(dd_log_warning, "Failed to retrieve root span meta"); + mlog(dd_log_warning, "Failed to retrieve root span attributes"); } return false; } @@ -111,7 +109,7 @@ bool dd_trace_span_add_tag_str(zend_object *nonnull span, mlog(dd_log_debug, "Adding to root span the tag '%.*s' with value '%.*s'", (int)tag_len, tag, (int)value_len, value); - bool res = zend_hash_add(Z_ARRVAL_P(meta), ztag, &zvalue) != NULL; + bool res = zend_hash_add(Z_ARRVAL_P(attributes), ztag, &zvalue) != NULL; zend_string_release(ztag); if (!res) { @@ -162,35 +160,34 @@ static zval *_get_span_modifiable_array_property( return res; } -// $meta and $metrics are views onto $attributes, the span's single tag store. -zval *nullable dd_trace_span_get_meta(zend_object *nonnull zobj) +zval *nullable dd_trace_span_get_attributes(zend_object *nonnull zobj) { return _get_span_modifiable_array_property(zobj, _attributes_propname); } -zval *nullable dd_trace_span_get_metrics(zend_object *nonnull zobj) +zval *nullable dd_trace_span_get_meta_struct(zend_object *nonnull zobj) { - return _get_span_modifiable_array_property(zobj, _attributes_propname); + return _get_span_modifiable_array_property(zobj, _meta_struct_propname); } -// Reads $meta/$metrics through the span's handlers: an array of that bucket. -static zval *_read_span_property( - zend_object *nonnull zobj, zend_string *nonnull propname, zval *nonnull rv) +zend_string *nullable dd_trace_span_get_component(zend_object *nonnull zobj) { #if PHP_VERSION_ID >= 80000 - return zobj->handlers->read_property(zobj, propname, BP_VAR_R, NULL, rv); + zval *res = zobj->handlers->get_property_ptr_ptr( + zobj, _component_propname, BP_VAR_IS, NULL); #else zval obj; ZVAL_OBJ(&obj, zobj); zval prop; - ZVAL_STR(&prop, propname); - return zobj->handlers->read_property(&obj, &prop, BP_VAR_R, NULL, rv); + ZVAL_STR(&prop, _component_propname); + zval *res = + zobj->handlers->get_property_ptr_ptr(&obj, &prop, BP_VAR_IS, NULL); #endif -} - -zval *nullable dd_trace_span_get_meta_struct(zend_object *nonnull zobj) -{ - return _get_span_modifiable_array_property(zobj, _meta_struct_propname); + if (res == NULL) { + return NULL; + } + ZVAL_DEREF(res); + return Z_TYPE_P(res) == IS_STRING ? Z_STR_P(res) : NULL; } zend_string *nullable dd_trace_get_formatted_runtime_id(bool persistent) @@ -348,7 +345,7 @@ static PHP_FUNCTION(datadog_appsec_testing_ddtrace_rshutdown) datadog_module->module_number) == SUCCESS); } -static PHP_FUNCTION(datadog_appsec_testing_root_span_add_tag) +static PHP_FUNCTION(datadog_appsec_testing_root_span_add_attribute) { zend_string *tag = NULL; zval *value = NULL; @@ -366,12 +363,12 @@ static PHP_FUNCTION(datadog_appsec_testing_root_span_add_tag) } Z_TRY_ADDREF_P(value); - bool result = dd_trace_span_add_tag(root_span, tag, value); + bool result = dd_trace_span_add_attribute(root_span, tag, value); RETURN_BOOL(result); } -static PHP_FUNCTION(datadog_appsec_testing_root_span_get_meta) // NOLINT +static PHP_FUNCTION(datadog_appsec_testing_root_span_get_attributes) // NOLINT { if (zend_parse_parameters_none() == FAILURE) { RETURN_FALSE; @@ -382,11 +379,9 @@ static PHP_FUNCTION(datadog_appsec_testing_root_span_get_meta) // NOLINT RETURN_NULL(); } - zval rv; - zval *meta_zv = _read_span_property(root_span, _meta_propname, &rv); - RETVAL_ZVAL(meta_zv, 1 /* copy */, 0 /* no destroy original */); - if (meta_zv == &rv) { - zval_ptr_dtor(&rv); + zval *attributes_zv = dd_trace_span_get_attributes(root_span); + if (attributes_zv) { + RETURN_ZVAL(attributes_zv, 1 /* copy */, 0 /* no destroy original */); } } @@ -407,25 +402,6 @@ static PHP_FUNCTION(datadog_appsec_testing_root_span_get_meta_struct) // NOLINT } } -static PHP_FUNCTION(datadog_appsec_testing_root_span_get_metrics) // NOLINT -{ - if (zend_parse_parameters_none() == FAILURE) { - RETURN_FALSE; - } - - __auto_type root_span = dd_trace_get_active_root_span(); - if (!root_span) { - RETURN_NULL(); - } - - zval rv; - zval *metrics_zv = _read_span_property(root_span, _metrics_propname, &rv); - RETVAL_ZVAL(metrics_zv, 1 /* copy */, 0 /* no destroy original */); - if (metrics_zv == &rv) { - zval_ptr_dtor(&rv); - } -} - static PHP_FUNCTION(datadog_appsec_testing_get_formatted_runtime_id) // NOLINT { if (zend_parse_parameters_none() == FAILURE) { @@ -450,17 +426,16 @@ ZEND_END_ARG_INFO() ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_root_span_add_tag, 0, 0, _IS_BOOL, 2) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_root_span_add_attribute, 0, 0, _IS_BOOL, 2) ZEND_ARG_TYPE_INFO(0, tag, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0) ZEND_END_ARG_INFO() static const zend_function_entry functions[] = { ZEND_RAW_FENTRY(DD_TESTING_NS "ddtrace_rshutdown", PHP_FN(datadog_appsec_testing_ddtrace_rshutdown), void_ret_bool_arginfo, 0, NULL, NULL) - ZEND_RAW_FENTRY(DD_TESTING_NS "root_span_add_tag", PHP_FN(datadog_appsec_testing_root_span_add_tag), arginfo_root_span_add_tag, 0, NULL, NULL) - ZEND_RAW_FENTRY(DD_TESTING_NS "root_span_get_meta", PHP_FN(datadog_appsec_testing_root_span_get_meta), void_ret_nullable_array, 0, NULL, NULL) + ZEND_RAW_FENTRY(DD_TESTING_NS "root_span_add_attribute", PHP_FN(datadog_appsec_testing_root_span_add_attribute), arginfo_root_span_add_attribute, 0, NULL, NULL) + ZEND_RAW_FENTRY(DD_TESTING_NS "root_span_get_attributes", PHP_FN(datadog_appsec_testing_root_span_get_attributes), void_ret_nullable_array, 0, NULL, NULL) ZEND_RAW_FENTRY(DD_TESTING_NS "root_span_get_meta_struct", PHP_FN(datadog_appsec_testing_root_span_get_meta_struct), void_ret_nullable_array, 0, NULL, NULL) - ZEND_RAW_FENTRY(DD_TESTING_NS "root_span_get_metrics", PHP_FN(datadog_appsec_testing_root_span_get_metrics), void_ret_nullable_array, 0, NULL, NULL) ZEND_RAW_FENTRY(DD_TESTING_NS "get_formatted_runtime_id", PHP_FN(datadog_appsec_testing_get_formatted_runtime_id), void_ret_nullable_string, 0, NULL, NULL) PHP_FE_END }; diff --git a/appsec/src/extension/tracer_bridge.h b/appsec/src/extension/tracer_bridge.h index b0727dd8314..9d3699b4037 100644 --- a/appsec/src/extension/tracer_bridge.h +++ b/appsec/src/extension/tracer_bridge.h @@ -29,10 +29,10 @@ zend_object *nullable dd_trace_get_active_root_span(void); // increases the refcount of tag, but not value (like zval_hash_add) // however, it destroy value if the operation fails (unlike zval_hash_add) -bool dd_trace_span_add_tag( +bool dd_trace_span_add_attribute( zend_object *nonnull zobj, zend_string *nonnull tag, zval *nonnull value); -bool dd_trace_span_add_tag_str(zend_object *nonnull zobj, +bool dd_trace_span_add_attribute_str(zend_object *nonnull zobj, const char *nonnull tag, size_t tag_len, const char *nonnull value, size_t value_len); @@ -41,11 +41,12 @@ void dd_trace_close_all_spans_and_flush(void); void dd_trace_emit_asm_event(void); -// Provides the array zval representing $root_span->attributes (which $meta -// and $metrics are views onto), if any. Ready for modification, refcount == 1 -zval *nullable dd_trace_span_get_meta(zend_object *nonnull); -zval *nullable dd_trace_span_get_metrics(zend_object *nonnull); +// Provides the array zval representing $root_span->attributes, if any. +// It is ready for modification, with refcount == 1 +zval *nullable dd_trace_span_get_attributes(zend_object *nonnull); zval *nullable dd_trace_span_get_meta_struct(zend_object *nonnull); +// Provides $root_span->component (borrowed), if it is a string +zend_string *nullable dd_trace_span_get_component(zend_object *nonnull); void dd_trace_span_add_propagated_tags( zend_string *nonnull key, zval *nonnull value); diff --git a/appsec/tests/extension/api_security_telemetry_missing_route.phpt b/appsec/tests/extension/api_security_telemetry_missing_route.phpt index 56fec6a1c5c..36914e41f72 100644 --- a/appsec/tests/extension/api_security_telemetry_missing_route.phpt +++ b/appsec/tests/extension/api_security_telemetry_missing_route.phpt @@ -35,13 +35,13 @@ $helper->get_commands(); // ignore // no http.route, no http.endpoint and no http.url: no route can be determined $rootSpan = root_span(); -$rootSpan->meta["http.method"] = "GET"; +$rootSpan->attributes["http.method"] = "GET"; var_dump(rshutdown()); $c = $helper->get_commands(); echo "Sampler hash sent: ", $c[0][1][1], "\n"; -match_log('/Telemetry metric api_security\.missing_route added with tags framework:cgi-fcgi and value 1/'); +match_log('/Telemetry metric api_security\.missing_route added with tags framework:web and value 1/'); no_match_log('/api_security\.request\./'); ?> @@ -49,5 +49,5 @@ no_match_log('/api_security\.request\./'); bool(true) bool(true) Sampler hash sent: 0 -found message in log matching /Telemetry metric api_security\.missing_route added with tags framework:cgi-fcgi and value 1/ +found message in log matching /Telemetry metric api_security\.missing_route added with tags framework:web and value 1/ no message in log matching /api_security\.request\./ diff --git a/appsec/tests/extension/api_security_telemetry_no_route_404.phpt b/appsec/tests/extension/api_security_telemetry_no_route_404.phpt index 8df49aad496..95d589c7e4e 100644 --- a/appsec/tests/extension/api_security_telemetry_no_route_404.phpt +++ b/appsec/tests/extension/api_security_telemetry_no_route_404.phpt @@ -36,7 +36,7 @@ $helper->get_commands(); // ignore // an endpoint that does not exist has no route to speak of; it must not be // counted as a missing route $rootSpan = root_span(); -$rootSpan->meta["http.method"] = "GET"; +$rootSpan->attributes["http.method"] = "GET"; var_dump(rshutdown()); $helper->get_commands(); // ignore diff --git a/appsec/tests/extension/api_security_telemetry_no_schema.phpt b/appsec/tests/extension/api_security_telemetry_no_schema.phpt index 2c4948bc4ee..42a501324de 100644 --- a/appsec/tests/extension/api_security_telemetry_no_schema.phpt +++ b/appsec/tests/extension/api_security_telemetry_no_schema.phpt @@ -34,9 +34,9 @@ var_dump(rinit()); $helper->get_commands(); // ignore $rootSpan = root_span(); -$rootSpan->meta["http.method"] = "GET"; -$rootSpan->meta["http.route"] = "/foo/bar"; -$rootSpan->meta["component"] = "symfony"; +$rootSpan->attributes["http.method"] = "GET"; +$rootSpan->attributes["http.route"] = "/foo/bar"; +$rootSpan->component = "symfony"; var_dump(rshutdown()); $helper->get_commands(); // ignore diff --git a/appsec/tests/extension/api_security_telemetry_schema.phpt b/appsec/tests/extension/api_security_telemetry_schema.phpt index 98f03a8c311..f72f368defc 100644 --- a/appsec/tests/extension/api_security_telemetry_schema.phpt +++ b/appsec/tests/extension/api_security_telemetry_schema.phpt @@ -34,10 +34,10 @@ var_dump(rinit()); $helper->get_commands(); // ignore $rootSpan = root_span(); -$rootSpan->meta["http.method"] = "GET"; -$rootSpan->meta["http.route"] = "/foo/bar"; +$rootSpan->attributes["http.method"] = "GET"; +$rootSpan->attributes["http.route"] = "/foo/bar"; // framework names are normalized: lowercased, spaces replaced with underscores -$rootSpan->meta["component"] = "Laravel Framework"; +$rootSpan->component = "Laravel Framework"; var_dump(rshutdown()); $helper->get_commands(); // ignore diff --git a/appsec/tests/extension/client_init_record_span_tags.phpt b/appsec/tests/extension/client_init_record_span_tags.phpt index 33871426ff5..337683567c9 100644 --- a/appsec/tests/extension/client_init_record_span_tags.phpt +++ b/appsec/tests/extension/client_init_record_span_tags.phpt @@ -17,13 +17,15 @@ HTTP_USER_AGENT=my user agent a=b --FILE-- finished_with_commands(); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [http.url] => https://localhost:8888/foo [http.method] => GET - [span.kind] => server - [component] => cgi-fcgi + [http.url] => https://localhost:8888/foo [http.useragent] => my user agent + [process_id] => %d + [runtime-id] => %s ) rinit bool(true) @@ -94,7 +95,7 @@ Array [_dd.runtime_family] => php [_dd.sdk.otlp_export] => false [appsec.event] => true - [component] => cgi-fcgi + [component] => web [http.endpoint] => /foo [http.method] => GET [http.request.headers.user-agent] => my user agent diff --git a/appsec/tests/extension/ddtrace_basic.phpt b/appsec/tests/extension/ddtrace_basic.phpt index 9e8076a7763..76f81ea296a 100644 --- a/appsec/tests/extension/ddtrace_basic.phpt +++ b/appsec/tests/extension/ddtrace_basic.phpt @@ -50,8 +50,9 @@ var_dump($root_span->name); var_dump($root_span->service); var_dump($root_span->type); var_dump($root_span->id); -var_dump($root_span->meta); -var_dump($root_span->metrics); +$attributes = $root_span->attributes; +ksort($attributes); +var_dump($attributes); $trace_id = \DDTrace\root_span()->id; echo 'trace id: ', $trace_id, "\n"; @@ -85,15 +86,13 @@ string(17) "ddtrace_basic.php" string(12) "appsec_tests" string(3) "cli" string(%d) "%d" -array(2) { - ["runtime-id"]=> - string(%d) %s +array(3) { ["ddappsec"]=> string(4) "true" -} -array(1) { - [%s]=> - float(%d) + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) "%s" } trace id: %s ddtrace_rshutdown diff --git a/appsec/tests/extension/push_params_ok_04.phpt b/appsec/tests/extension/push_params_ok_04.phpt index ae337853c4f..59e2085da3a 100644 --- a/appsec/tests/extension/push_params_ok_04.phpt +++ b/appsec/tests/extension/push_params_ok_04.phpt @@ -4,7 +4,7 @@ Some addresses are rasp requests when rasp enabled datadog.appsec.enabled=1 --FILE-- 1234], "lfi"); var_dump(rshutdown()); -print_r(root_span_get_metrics()); +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); var_dump($helper->get_command("request_exec")); @@ -28,10 +30,12 @@ bool(true) bool(true) Array ( - [process_id] => %d [_dd.appsec.enabled] => %d - [_dd.appsec.waf.duration_ext] => %f [_dd.appsec.rasp.duration_ext] => %f + [_dd.appsec.waf.duration_ext] => %f + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) array(2) { [0]=> diff --git a/appsec/tests/extension/push_params_ok_05.phpt b/appsec/tests/extension/push_params_ok_05.phpt index fd2f34186d9..cd1e62271e3 100644 --- a/appsec/tests/extension/push_params_ok_05.phpt +++ b/appsec/tests/extension/push_params_ok_05.phpt @@ -6,7 +6,7 @@ datadog.appsec.enabled=1 DD_APPSEC_RASP_ENABLED=false --FILE-- 1234], "lfi"); var_dump(rshutdown()); -print_r(root_span_get_metrics()); +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); var_dump($helper->get_command("request_exec")); @@ -29,9 +31,11 @@ bool(true) bool(true) Array ( - [process_id] => %d [_dd.appsec.enabled] => %d [_dd.appsec.waf.duration_ext] => %f + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) array(0) { } diff --git a/appsec/tests/extension/push_params_ok_06.phpt b/appsec/tests/extension/push_params_ok_06.phpt index 6b25c5513b0..cb0cd3b4d91 100644 --- a/appsec/tests/extension/push_params_ok_06.phpt +++ b/appsec/tests/extension/push_params_ok_06.phpt @@ -5,7 +5,7 @@ datadog.appsec.enabled=1 datadog.appsec.rasp_enabled=0 --FILE-- 1234], "lfi"); var_dump(rshutdown()); -print_r(root_span_get_metrics()); +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); var_dump($helper->get_command("request_exec")); @@ -28,9 +30,11 @@ bool(true) bool(true) Array ( - [process_id] => %d [_dd.appsec.enabled] => %d [_dd.appsec.waf.duration_ext] => %f + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) array(0) { } diff --git a/appsec/tests/extension/rasp_duration_ext_user_requests.phpt b/appsec/tests/extension/rasp_duration_ext_user_requests.phpt index 412ff9f46d0..286dd814d12 100644 --- a/appsec/tests/extension/rasp_duration_ext_user_requests.phpt +++ b/appsec/tests/extension/rasp_duration_ext_user_requests.phpt @@ -45,11 +45,11 @@ for ($i = 0; $i < NUM_CALLS; $i++) { notify_commit($span1, 200, array()); -// Get metrics for first request -$metrics1 = $span1->metrics ?? []; -echo "First request has duration_ext: " . (isset($metrics1['_dd.appsec.rasp.duration_ext']) ? "yes" : "no") . "\n"; -if (isset($metrics1['_dd.appsec.rasp.duration_ext'])) { - $duration1 = $metrics1['_dd.appsec.rasp.duration_ext']; +// Get attributes for first request +$attributes1 = $span1->attributes; +echo "First request has duration_ext: " . (isset($attributes1['_dd.appsec.rasp.duration_ext']) ? "yes" : "no") . "\n"; +if (isset($attributes1['_dd.appsec.rasp.duration_ext'])) { + $duration1 = $attributes1['_dd.appsec.rasp.duration_ext']; echo "First request duration_ext is positive: " . ($duration1 > 0 ? "yes" : "no") . "\n"; } @@ -63,11 +63,11 @@ push_addresses(["server.request.body" => "test3"], "lfi"); notify_commit($span2, 200, array()); -// Get metrics for second request -$metrics2 = $span2->metrics ?? []; -echo "Second request has duration_ext: " . (isset($metrics2['_dd.appsec.rasp.duration_ext']) ? "yes" : "no") . "\n"; -if (isset($metrics2['_dd.appsec.rasp.duration_ext'])) { - $duration2 = $metrics2['_dd.appsec.rasp.duration_ext']; +// Get attributes for second request +$attributes2 = $span2->attributes; +echo "Second request has duration_ext: " . (isset($attributes2['_dd.appsec.rasp.duration_ext']) ? "yes" : "no") . "\n"; +if (isset($attributes2['_dd.appsec.rasp.duration_ext'])) { + $duration2 = $attributes2['_dd.appsec.rasp.duration_ext']; echo "Second request duration_ext is positive: " . ($duration2 > 0 ? "yes" : "no") . "\n"; } diff --git a/appsec/tests/extension/report_backtrace_01.phpt b/appsec/tests/extension/report_backtrace_01.phpt index 6fde1ed260a..cca6dcbf4d1 100644 --- a/appsec/tests/extension/report_backtrace_01.phpt +++ b/appsec/tests/extension/report_backtrace_01.phpt @@ -23,7 +23,7 @@ DDTrace\start_span(); $root = DDTrace\active_span(); one("foo"); DDTrace\close_span(0); -$span = dd_trace_serialize_closed_spans(); +$span = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; $meta_struct = $span[0]["meta_struct"]; var_dump(decode_msgpack($meta_struct["_dd.stack"])); DDTrace\flush(); diff --git a/appsec/tests/extension/report_backtrace_05.phpt b/appsec/tests/extension/report_backtrace_05.phpt index d6ff9d3626a..b01f071f25b 100644 --- a/appsec/tests/extension/report_backtrace_05.phpt +++ b/appsec/tests/extension/report_backtrace_05.phpt @@ -36,7 +36,7 @@ one("foo"); DDTrace\close_span(0); -$span = dd_trace_serialize_closed_spans(); +$span = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; $meta_struct = $span[0]["meta_struct"]; var_dump(decode_msgpack($meta_struct["_dd.stack"])); diff --git a/appsec/tests/extension/report_backtrace_06.phpt b/appsec/tests/extension/report_backtrace_06.phpt index 27e399fcc4e..4c04b998aaf 100644 --- a/appsec/tests/extension/report_backtrace_06.phpt +++ b/appsec/tests/extension/report_backtrace_06.phpt @@ -23,7 +23,7 @@ DDTrace\start_span(); $root = DDTrace\active_span(); one("foo"); DDTrace\close_span(0); -$span = dd_trace_serialize_closed_spans(); +$span = dd_trace_serialize_closed_spans()['chunks'][0]['spans'] ?? []; var_dump(isset($span[0]["meta_struct"])); DDTrace\flush(); ?> diff --git a/appsec/tests/extension/req_abort_from_user_login_success_event.phpt b/appsec/tests/extension/req_abort_from_user_login_success_event.phpt index 47aae1b8994..cf304bc2da3 100644 --- a/appsec/tests/extension/req_abort_from_user_login_success_event.phpt +++ b/appsec/tests/extension/req_abort_from_user_login_success_event.phpt @@ -4,7 +4,7 @@ Track a user login success event and verify the tags in the root span DD_APPSEC_ENABLED=1 --FILE-- --EXPECTF-- -root_span_get_metrics(): +root_span_get_attributes(): Array ( - [%s] => %d [_dd.appsec.enabled] => 1 [_dd.appsec.waf.duration_ext] => %f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) int(2) diff --git a/appsec/tests/extension/rexec_force_keep_02.phpt b/appsec/tests/extension/rexec_force_keep_02.phpt index ce982c5f074..76fa0917537 100644 --- a/appsec/tests/extension/rexec_force_keep_02.phpt +++ b/appsec/tests/extension/rexec_force_keep_02.phpt @@ -5,7 +5,7 @@ datadog.appsec.enabled=1 datadog.appsec.log_file=/tmp/php_appsec_test.log --FILE-- --EXPECTF-- -root_span_get_metrics(): +root_span_get_attributes(): Array ( - [%s] => %d [_dd.appsec.enabled] => 1 [_dd.appsec.waf.duration_ext] => %f + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) diff --git a/appsec/tests/extension/rexec_force_keep_03.phpt b/appsec/tests/extension/rexec_force_keep_03.phpt index 6b054887b34..ce4da77e11a 100644 --- a/appsec/tests/extension/rexec_force_keep_03.phpt +++ b/appsec/tests/extension/rexec_force_keep_03.phpt @@ -5,7 +5,7 @@ datadog.appsec.enabled=1 datadog.appsec.log_file=/tmp/php_appsec_test.log --FILE-- --EXPECTF-- -root_span_get_metrics(): +root_span_get_attributes(): Array ( - [%s] => %d [_dd.appsec.enabled] => 1 [_dd.appsec.waf.duration_ext] => %f + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) diff --git a/appsec/tests/extension/rexec_force_keep_04.phpt b/appsec/tests/extension/rexec_force_keep_04.phpt index 851f942c99b..be498eee4eb 100644 --- a/appsec/tests/extension/rexec_force_keep_04.phpt +++ b/appsec/tests/extension/rexec_force_keep_04.phpt @@ -5,7 +5,7 @@ datadog.appsec.enabled=1 datadog.appsec.log_file=/tmp/php_appsec_test.log --FILE-- --EXPECTF-- -root_span_get_metrics(): +root_span_get_attributes(): Array ( - [%s] => %d [_dd.appsec.enabled] => 1 [_dd.appsec.waf.duration_ext] => %f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) int(2) diff --git a/appsec/tests/extension/rinit_asm_events_propagate_tags.phpt b/appsec/tests/extension/rinit_asm_events_propagate_tags.phpt index af850a5da08..79d2dca7813 100644 --- a/appsec/tests/extension/rinit_asm_events_propagate_tags.phpt +++ b/appsec/tests/extension/rinit_asm_events_propagate_tags.phpt @@ -11,7 +11,7 @@ HTTP_X_DATADOG_ORIGIN=datadog HTTP_X_DATADOG_TAGS=_dd.p.custom_tag=inherited,_dd.p.second_tag=bar --FILE-- get_commands(); //ignore -$context = DDTrace\current_context(); +$root = DDTrace\root_span(); echo "ASM is enabled on _dd.p.ts propagated tags? "; -echo isset($context['distributed_tracing_propagated_tags']['_dd.p.ts']) && $context['distributed_tracing_propagated_tags']['_dd.p.ts'] === "02" ? "Yes": "No"; +echo array_key_exists('_dd.p.ts', $root->propagatedTags) && ($root->attributes['_dd.p.ts'] ?? null) === "02" ? "Yes": "No"; echo PHP_EOL; echo "rshutdown\n"; diff --git a/appsec/tests/extension/rinit_force_keep_01.phpt b/appsec/tests/extension/rinit_force_keep_01.phpt index ada484208e6..93286e107b1 100644 --- a/appsec/tests/extension/rinit_force_keep_01.phpt +++ b/appsec/tests/extension/rinit_force_keep_01.phpt @@ -5,7 +5,7 @@ datadog.appsec.enabled=1 datadog.appsec.log_file=/tmp/php_appsec_test.log --FILE-- --EXPECTF-- bool(true) bool(true) -root_span_get_metrics(): +root_span_get_attributes(): Array ( - [%s] => %d [_dd.appsec.enabled] => 1 [_dd.appsec.waf.duration_ext] => %f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) int(2) diff --git a/appsec/tests/extension/rinit_force_keep_02.phpt b/appsec/tests/extension/rinit_force_keep_02.phpt index 272c09d1118..9e7d100b6aa 100644 --- a/appsec/tests/extension/rinit_force_keep_02.phpt +++ b/appsec/tests/extension/rinit_force_keep_02.phpt @@ -4,7 +4,7 @@ Sampling priority is left as it is when not forced datadog.appsec.enabled=1 --FILE-- --EXPECTF-- bool(true) bool(true) -root_span_get_metrics(): +root_span_get_attributes(): Array ( - [%s] => %d [_dd.appsec.enabled] => 1 [_dd.appsec.waf.duration_ext] => %f + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) diff --git a/appsec/tests/extension/rinit_force_keep_03.phpt b/appsec/tests/extension/rinit_force_keep_03.phpt index 6e81fc7c244..db951945352 100644 --- a/appsec/tests/extension/rinit_force_keep_03.phpt +++ b/appsec/tests/extension/rinit_force_keep_03.phpt @@ -5,7 +5,7 @@ datadog.appsec.enabled=1 datadog.appsec.log_file=/tmp/php_appsec_test.log --FILE-- --EXPECTF-- bool(true) bool(true) -root_span_get_metrics(): +root_span_get_attributes(): Array ( - [%s] => %d [_dd.appsec.enabled] => 1 [_dd.appsec.waf.duration_ext] => %f + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) diff --git a/appsec/tests/extension/rinit_record_span_tags.phpt b/appsec/tests/extension/rinit_record_span_tags.phpt index 27a0e061cf3..46b9b4cedac 100644 --- a/appsec/tests/extension/rinit_record_span_tags.phpt +++ b/appsec/tests/extension/rinit_record_span_tags.phpt @@ -17,13 +17,15 @@ HTTP_USER_AGENT=my user agent a=b --FILE-- finished_with_commands(); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [http.url] => https://localhost:8888/foo [http.method] => GET - [span.kind] => server - [component] => cgi-fcgi + [http.url] => https://localhost:8888/foo [http.useragent] => my user agent + [process_id] => %d + [runtime-id] => %s ) rinit bool(true) @@ -89,7 +90,7 @@ Array [_dd.runtime_family] => php [_dd.sdk.otlp_export] => false [appsec.event] => true - [component] => cgi-fcgi + [component] => web [http.endpoint] => /foo [http.method] => GET [http.request.headers.user-agent] => my user agent diff --git a/appsec/tests/extension/rinit_record_span_tags_fail.phpt b/appsec/tests/extension/rinit_record_span_tags_fail.phpt index 074ecdc5758..e41f6acff9d 100644 --- a/appsec/tests/extension/rinit_record_span_tags_fail.phpt +++ b/appsec/tests/extension/rinit_record_span_tags_fail.phpt @@ -8,7 +8,7 @@ datadog.appsec.log_file=/tmp/php_appsec_test.log datadog.appsec.log_level=debug --FILE-- true]); -echo "root_span_get_meta (should fail: no root span):\n"; -var_dump(root_span_get_meta()); +echo "root_span_get_attributes (should fail: no root span):\n"; +var_dump(root_span_get_attributes()); echo "rinit\n"; var_dump(rinit()); @@ -44,7 +44,7 @@ $helper->finished_with_commands(); ?> --EXPECTF-- -root_span_get_meta (should fail: no root span): +root_span_get_attributes (should fail: no root span): NULL rinit bool(true) diff --git a/appsec/tests/extension/rinit_root_span_add_tag.phpt b/appsec/tests/extension/rinit_root_span_add_attribute.phpt similarity index 87% rename from appsec/tests/extension/rinit_root_span_add_tag.phpt rename to appsec/tests/extension/rinit_root_span_add_attribute.phpt index 99fda6dc62f..c2652a35762 100644 --- a/appsec/tests/extension/rinit_root_span_add_tag.phpt +++ b/appsec/tests/extension/rinit_root_span_add_attribute.phpt @@ -1,5 +1,5 @@ --TEST-- -Test ddtrace_root_span_add_tag +Test root_span_add_attribute --INI-- datadog.appsec.log_file=/tmp/php_appsec_test.log datadog.appsec.log_level=debug @@ -35,8 +35,8 @@ $helper = Helper::createInitedRun([ var_dump(rinit()); $helper->get_commands(); -var_dump(\datadog\appsec\testing\root_span_add_tag("ddappsec", "true")); -var_dump(\datadog\appsec\testing\root_span_add_tag("ddappsec", "true")); +var_dump(\datadog\appsec\testing\root_span_add_attribute("ddappsec", "true")); +var_dump(\datadog\appsec\testing\root_span_add_attribute("ddappsec", "true")); var_dump(ddtrace_rshutdown()); dd_trace_internal_fn('synchronous_flush'); @@ -62,7 +62,7 @@ Array [_dd.p.dm] => -0 [_dd.p.tid] => %s [_dd.sdk.otlp_export] => false - [component] => cgi-fcgi + [component] => web [ddappsec] => true [env] => staging [http.method] => GET diff --git a/appsec/tests/extension/rinit_rshutdown_basic.phpt b/appsec/tests/extension/rinit_rshutdown_basic.phpt index 33991beab7571e04e875d4f7a205840f10c556f7..4c102180e48326c04aa45b6949f499c81e473ea4 100644 GIT binary patch delta 35 pcmZ3hepr1&IEz@cdU8f-UUsp1Y_vgaw0dztVjhsaIh-Yo9{}M*3-|y4 delta 12 TcmX@CzE*uhILqc-mN0$*An^oK diff --git a/appsec/tests/extension/root_span_add_attribute.phpt b/appsec/tests/extension/root_span_add_attribute.phpt new file mode 100644 index 00000000000..f76f8700c24 --- /dev/null +++ b/appsec/tests/extension/root_span_add_attribute.phpt @@ -0,0 +1,72 @@ +--TEST-- +Test root_span_add_attribute +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_SERVICE=appsec_tests +--INI-- +datadog.appsec.log_file=/tmp/php_appsec_test.log +datadog.appsec.log_level=debug +--FILE-- + +--EXPECTF-- +bool(false) +bool(true) +bool(false) +array(2) { + ["attributes"]=> + array(1) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + } + ["chunks"]=> + array(1) { + [0]=> + array(4) { + ["trace_id"]=> + string(%d) "%s" + ["priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["spans"]=> + array(1) { + [0]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(27) "root_span_add_attribute.php" + ["resource"]=> + string(27) "root_span_add_attribute.php" + ["service"]=> + string(12) "appsec_tests" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(%d) {%A + ["after"]=> + string(9) "root_span"%A + } + } + } + } + } +} diff --git a/appsec/tests/extension/root_span_add_tag_with_intermediate_spans.phpt b/appsec/tests/extension/root_span_add_attribute_with_intermediate_spans.phpt similarity index 88% rename from appsec/tests/extension/root_span_add_tag_with_intermediate_spans.phpt rename to appsec/tests/extension/root_span_add_attribute_with_intermediate_spans.phpt index 4b124ab02b7..848bc780368 100644 --- a/appsec/tests/extension/root_span_add_tag_with_intermediate_spans.phpt +++ b/appsec/tests/extension/root_span_add_attribute_with_intermediate_spans.phpt @@ -7,7 +7,7 @@ SERVER_NAME=localhost:8888 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 --FILE-- get_commands(); //ignore -var_dump(root_span_add_tag("before", "root_span")); +var_dump(root_span_add_attribute("before", "root_span")); DDTrace\start_span(); -var_dump(root_span_add_tag("after", "root_span")); +var_dump(root_span_add_attribute("after", "root_span")); DDTrace\close_span(0); diff --git a/appsec/tests/extension/root_span_add_tag.phpt b/appsec/tests/extension/root_span_add_tag.phpt deleted file mode 100644 index 0ef51517796..00000000000 --- a/appsec/tests/extension/root_span_add_tag.phpt +++ /dev/null @@ -1,60 +0,0 @@ ---TEST-- -Test ddtrace_root_span_add_tag ---ENV-- -DD_TRACE_GENERATE_ROOT_SPAN=0 -DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 -DD_TRACE_AUTO_FLUSH_ENABLED=0 -DD_SERVICE=appsec_tests ---INI-- -datadog.appsec.log_file=/tmp/php_appsec_test.log -datadog.appsec.log_level=debug ---FILE-- - ---EXPECTF-- -bool(false) -bool(true) -bool(false) -array(1) { - [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" - ["span_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(21) "root_span_add_tag.php" - ["resource"]=> - string(21) "root_span_add_tag.php" - ["service"]=> - string(12) "appsec_tests" - ["type"]=> - string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) - ["attributes"]=> - array(%d) {%A - ["after"]=> - string(9) "root_span"%A - } - } -} diff --git a/appsec/tests/extension/rshutdown_force_keep_01.phpt b/appsec/tests/extension/rshutdown_force_keep_01.phpt index 5ea5a40467e..bd0cd6d176f 100644 --- a/appsec/tests/extension/rshutdown_force_keep_01.phpt +++ b/appsec/tests/extension/rshutdown_force_keep_01.phpt @@ -4,7 +4,7 @@ Sampling priority is set to 2 when helper forces keep datadog.appsec.enabled=1 --FILE-- --EXPECTF-- bool(true) bool(true) -root_span_get_metrics(): +root_span_get_attributes(): Array ( - [%s] => %d [_dd.appsec.enabled] => 1 [_dd.appsec.waf.duration_ext] => %f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) int(2) diff --git a/appsec/tests/extension/rshutdown_force_keep_02.phpt b/appsec/tests/extension/rshutdown_force_keep_02.phpt index 7e5effa5b62..36fff3b10dc 100644 --- a/appsec/tests/extension/rshutdown_force_keep_02.phpt +++ b/appsec/tests/extension/rshutdown_force_keep_02.phpt @@ -4,7 +4,7 @@ Sampling priority is not set when helper set force to false datadog.appsec.enabled=1 --FILE-- --EXPECTF-- bool(true) bool(true) -root_span_get_metrics(): +root_span_get_attributes(): Array ( - [%s] => %d [_dd.appsec.enabled] => 1 [_dd.appsec.waf.duration_ext] => %f + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) diff --git a/appsec/tests/extension/rshutdown_force_keep_03.phpt b/appsec/tests/extension/rshutdown_force_keep_03.phpt index 0deabeb1a07..1dac4355624 100644 --- a/appsec/tests/extension/rshutdown_force_keep_03.phpt +++ b/appsec/tests/extension/rshutdown_force_keep_03.phpt @@ -4,7 +4,7 @@ Sampling priority is not set when helper set force to false datadog.appsec.enabled=1 --FILE-- --EXPECTF-- bool(true) bool(true) -root_span_get_metrics(): +root_span_get_attributes(): Array ( - [%s] => %d [_dd.appsec.enabled] => 1 [_dd.appsec.waf.duration_ext] => %f + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) diff --git a/appsec/tests/extension/rshutdown_force_keep_04.phpt b/appsec/tests/extension/rshutdown_force_keep_04.phpt index c1f3c92043d..d5f00ed4469 100644 --- a/appsec/tests/extension/rshutdown_force_keep_04.phpt +++ b/appsec/tests/extension/rshutdown_force_keep_04.phpt @@ -4,7 +4,7 @@ Force keep on rshutdown, overrides rinit datadog.appsec.enabled=1 --FILE-- --EXPECTF-- bool(true) bool(true) -root_span_get_metrics(): +root_span_get_attributes(): Array ( - [%s] => %d [_dd.appsec.enabled] => 1 [_dd.appsec.waf.duration_ext] => %f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [_dd.runtime_family] => php + [process_id] => %d + [runtime-id] => %s ) int(2) diff --git a/appsec/tests/extension/rshutdown_sampler_key_missing_method.phpt b/appsec/tests/extension/rshutdown_sampler_key_missing_method.phpt index 7871e67a6f9..80042a2f19e 100644 --- a/appsec/tests/extension/rshutdown_sampler_key_missing_method.phpt +++ b/appsec/tests/extension/rshutdown_sampler_key_missing_method.phpt @@ -24,8 +24,8 @@ var_dump(rinit()); $helper->get_commands(); // ignore $rootSpan = root_span(); -$rootSpan->meta["http.route"] = "/foo/bar"; -unset($rootSpan->meta["http.method"]); +$rootSpan->attributes["http.route"] = "/foo/bar"; +unset($rootSpan->attributes["http.method"]); var_dump(rshutdown()); diff --git a/appsec/tests/extension/rshutdown_sampler_key_missing_route.phpt b/appsec/tests/extension/rshutdown_sampler_key_missing_route.phpt index 007102c5ef6..9ec16a2f020 100644 --- a/appsec/tests/extension/rshutdown_sampler_key_missing_route.phpt +++ b/appsec/tests/extension/rshutdown_sampler_key_missing_route.phpt @@ -24,7 +24,7 @@ var_dump(rinit()); $helper->get_commands(); // ignore $rootSpan = root_span(); -$rootSpan->meta["http.method"] = "GET"; +$rootSpan->attributes["http.method"] = "GET"; var_dump(rshutdown()); diff --git a/appsec/tests/extension/rshutdown_sampler_key_ok.phpt b/appsec/tests/extension/rshutdown_sampler_key_ok.phpt index 8a2882ce327..58abba3e3a8 100644 --- a/appsec/tests/extension/rshutdown_sampler_key_ok.phpt +++ b/appsec/tests/extension/rshutdown_sampler_key_ok.phpt @@ -24,8 +24,8 @@ var_dump(rinit()); $helper->get_commands(); // ignore $rootSpan = root_span(); -$rootSpan->meta["http.method"] = "GET"; -$rootSpan->meta["http.route"] = "/foo/bar"; +$rootSpan->attributes["http.method"] = "GET"; +$rootSpan->attributes["http.route"] = "/foo/bar"; var_dump(rshutdown()); diff --git a/appsec/tests/extension/rshutdown_sampler_key_sec_api_disabled.phpt b/appsec/tests/extension/rshutdown_sampler_key_sec_api_disabled.phpt index cb4ee9a1726..ca06adff62a 100644 --- a/appsec/tests/extension/rshutdown_sampler_key_sec_api_disabled.phpt +++ b/appsec/tests/extension/rshutdown_sampler_key_sec_api_disabled.phpt @@ -24,8 +24,8 @@ var_dump(rinit()); $helper->get_commands(); // ignore $rootSpan = root_span(); -$rootSpan->meta["http.method"] = "GET"; -$rootSpan->meta["http.route"] = "/foo/bar"; +$rootSpan->attributes["http.method"] = "GET"; +$rootSpan->attributes["http.route"] = "/foo/bar"; var_dump(rshutdown()); diff --git a/appsec/tests/extension/rshutdown_sampler_low_priority.phpt b/appsec/tests/extension/rshutdown_sampler_low_priority.phpt index 4e6fc351249..8f83a92e1df 100644 --- a/appsec/tests/extension/rshutdown_sampler_low_priority.phpt +++ b/appsec/tests/extension/rshutdown_sampler_low_priority.phpt @@ -23,8 +23,8 @@ var_dump(rinit()); $helper->get_commands(); // ignore $rootSpan = root_span(); -$rootSpan->meta["http.method"] = "GET"; -$rootSpan->meta["http.route"] = "/foo/bar"; +$rootSpan->attributes["http.method"] = "GET"; +$rootSpan->attributes["http.route"] = "/foo/bar"; set_priority_sampling(0); diff --git a/appsec/tests/extension/track_authenticated_user_event.phpt b/appsec/tests/extension/track_authenticated_user_event.phpt index 87756ed6ef2..52488536ccd 100644 --- a/appsec/tests/extension/track_authenticated_user_event.phpt +++ b/appsec/tests/extension/track_authenticated_user_event.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => sdk + [process_id] => %d [runtime-id] => %s + [usr.email] => noneofyour@business.com [usr.id] => ID - [_dd.appsec.user.collection_mode] => sdk - [usr.value] => something [usr.metadata] => some other metadata - [usr.email] => noneofyour@business.com + [usr.value] => something ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode.phpt index b38981a0a3c..9916ead2209 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anon --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => anonymization + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 + [process_id] => %d [runtime-id] => %s [usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.user.collection_mode] => anonymization ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_compat.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_compat.phpt index 31a66cb44c9..a011e9c4c58 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_compat.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_compat.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING=safe --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => anonymization + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 + [process_id] => %d [runtime-id] => %s [usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.user.collection_mode] => anonymization ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_full_name.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_full_name.phpt index 5ced50377f8..8c6b56a6423 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_full_name.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_full_name.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anonymization --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => anonymization + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 + [process_id] => %d [runtime-id] => %s [usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.user.collection_mode] => anonymization ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_no_user.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_no_user.phpt index fc82699b50c..455807546cb 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_no_user.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_anon_mode_no_user.phpt @@ -8,7 +8,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anon --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_dedup_same_user.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_dedup_same_user.phpt index 6ac4ef6136b..c192e2683c2 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_dedup_same_user.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_dedup_same_user.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => identification + [_dd.appsec.usr.id] => sameUser + [process_id] => %d [runtime-id] => %s [usr.id] => sameUser - [_dd.appsec.usr.id] => sameUser - [_dd.appsec.user.collection_mode] => identification ) diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_default_mode.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_default_mode.phpt index c7cf0c2c198..382add44ea8 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_default_mode.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_default_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => identification + [_dd.appsec.usr.id] => automatedID + [process_id] => %d [runtime-id] => %s [usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID - [_dd.appsec.user.collection_mode] => identification ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_disabled_config.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_disabled_config.phpt index 3f51429349d..1cdda7f6a6b 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_disabled_config.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_disabled_config.phpt @@ -7,7 +7,7 @@ DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING_ENABLED=0 --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_disabled_mode.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_disabled_mode.phpt index 9db61471a34..c8a9f8ae2fc 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_disabled_mode.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_disabled_mode.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=disabled --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode.phpt index d789a16015b..c1c0c6b26a1 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => identification + [_dd.appsec.usr.id] => automatedID + [process_id] => %d [runtime-id] => %s [usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID - [_dd.appsec.user.collection_mode] => identification ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_compat.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_compat.phpt index 6ccae51f068..18667efa8b1 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_compat.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_compat.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING=extended --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => identification + [_dd.appsec.usr.id] => automatedID + [process_id] => %d [runtime-id] => %s [usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID - [_dd.appsec.user.collection_mode] => identification ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_full_name.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_full_name.phpt index a4fac7783f3..06c9969e803 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_full_name.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_full_name.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=identification --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => identification + [_dd.appsec.usr.id] => automatedID + [process_id] => %d [runtime-id] => %s [usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID - [_dd.appsec.user.collection_mode] => identification ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_no_user.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_no_user.phpt index 11ee50ccba0..905edcce743 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_no_user.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_ident_mode_no_user.phpt @@ -8,7 +8,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=identification --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_invalid_mode.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_invalid_mode.phpt index 6a11d328cea..ae8192dde63 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_invalid_mode.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_invalid_mode.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=invalid --FILE-- --EXPECTF-- %AWarning:%a[ddappsec] Unknown user collection mode: invalid%a -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_automated_no_root_span.phpt b/appsec/tests/extension/track_authenticated_user_event_automated_no_root_span.phpt index c9bf4579231..aae8e30a1d7 100644 --- a/appsec/tests/extension/track_authenticated_user_event_automated_no_root_span.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_automated_no_root_span.phpt @@ -8,7 +8,7 @@ DD_APPSEC_ENABLED=1 DD_TRACE_GENERATE_ROOT_SPAN=0 --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): diff --git a/appsec/tests/extension/track_authenticated_user_event_no_root_span.phpt b/appsec/tests/extension/track_authenticated_user_event_no_root_span.phpt index c8b51e02036..2a13595f592 100644 --- a/appsec/tests/extension/track_authenticated_user_event_no_root_span.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_no_root_span.phpt @@ -8,7 +8,7 @@ DD_APPSEC_ENABLED=1 DD_TRACE_GENERATE_ROOT_SPAN=0 --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): diff --git a/appsec/tests/extension/track_authenticated_user_event_no_user.phpt b/appsec/tests/extension/track_authenticated_user_event_no_user.phpt index d6250ed5f21..0a5892b7d30 100644 --- a/appsec/tests/extension/track_authenticated_user_event_no_user.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_no_user.phpt @@ -8,7 +8,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=identification --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority.phpt b/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority.phpt index 863edfe10e2..fcd200174ea 100644 --- a/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- "someValue" ] ); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => sdk + [_dd.appsec.usr.id] => automatedID + [process_id] => %d [runtime-id] => %s [usr.id] => ID - [_dd.appsec.usr.id] => automatedID - [_dd.appsec.user.collection_mode] => sdk [usr.metadata] => someValue ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_02.phpt b/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_02.phpt index 3c5f31d9e04..d1a0697b560 100644 --- a/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_02.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_02.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => sdk + [_dd.appsec.usr.id] => automatedID + [process_id] => %d [runtime-id] => %s [usr.id] => ID - [_dd.appsec.user.collection_mode] => sdk [usr.metadata] => someValue - [_dd.appsec.usr.id] => automatedID ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_03.phpt b/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_03.phpt index 273c7d036e6..3ae3fed515e 100644 --- a/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_03.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_03.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => sdk + [_dd.appsec.usr.id] => otherAutomatedID + [process_id] => %d [runtime-id] => %s [usr.id] => otherID - [_dd.appsec.usr.id] => otherAutomatedID - [_dd.appsec.user.collection_mode] => sdk [usr.metadata] => otherValue ) \ No newline at end of file diff --git a/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_04.phpt b/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_04.phpt index 2cd99847937..77578fd1fdf 100644 --- a/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_04.phpt +++ b/appsec/tests/extension/track_authenticated_user_event_sdk_takes_priority_04.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- "otherValue" ] ); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [_dd.appsec.user.collection_mode] => sdk + [_dd.appsec.usr.id] => otherAutomatedID + [process_id] => %d [runtime-id] => %s [usr.id] => otherID - [_dd.appsec.user.collection_mode] => sdk [usr.metadata] => otherValue - [_dd.appsec.usr.id] => otherAutomatedID ) \ No newline at end of file diff --git a/appsec/tests/extension/track_custom_event.phpt b/appsec/tests/extension/track_custom_event.phpt index e02049990ef..b11a2aba651 100644 --- a/appsec/tests/extension/track_custom_event.phpt +++ b/appsec/tests/extension/track_custom_event.phpt @@ -4,7 +4,7 @@ Track a custom event and verify the contents of the root span DD_APPSEC_ENABLED=1 --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [appsec.events.myevent.email] => noneofyour@business.com + [appsec.events.myevent.metadata] => some other metadata [appsec.events.myevent.track] => true [appsec.events.myevent.value] => something - [appsec.events.myevent.metadata] => some other metadata - [appsec.events.myevent.email] => noneofyour@business.com - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 + [process_id] => %d + [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_custom_event_empty_event.phpt b/appsec/tests/extension/track_custom_event_empty_event.phpt index 0b2d3c00156..4265ccb10a2 100644 --- a/appsec/tests/extension/track_custom_event_empty_event.phpt +++ b/appsec/tests/extension/track_custom_event_empty_event.phpt @@ -7,7 +7,7 @@ datadog.appsec.log_level=debug DD_APPSEC_ENABLED=1 --FILE-- --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_failure_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => sdkID - [appsec.events.users.login.failure.usr.login] => sdkID - [appsec.events.users.login.failure.track] => true + [_dd.appsec.enabled] => 1 [_dd.appsec.events.users.login.failure.sdk] => true - [appsec.events.users.login.failure.value] => something - [appsec.events.users.login.failure.metadata] => some other metadata + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [_dd.runtime_family] => php [appsec.events.users.login.failure.email] => noneofyour@business.com + [appsec.events.users.login.failure.metadata] => some other metadata + [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => false + [appsec.events.users.login.failure.usr.id] => sdkID + [appsec.events.users.login.failure.usr.login] => sdkID + [appsec.events.users.login.failure.value] => something + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 - [_dd.runtime_family] => php -) -root_span_get_metrics(): -Array -( - [%s] => %d - [_dd.appsec.enabled] => 1 ) int(2) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode.phpt index 7418004be97..64d54acc034 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anon --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.events.users.login.failure.auto.mode] => anonymization - [appsec.events.users.login.failure.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true + [appsec.events.users.login.failure.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 + [appsec.events.users.login.failure.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_compat.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_compat.phpt index b55dd196752..19d8ab06a90 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_compat.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_compat.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING=safe --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.events.users.login.failure.auto.mode] => anonymization - [appsec.events.users.login.failure.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true + [appsec.events.users.login.failure.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 + [appsec.events.users.login.failure.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_full_name.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_full_name.phpt index 7c29277bfeb..fdfd63e6d6a 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_full_name.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_full_name.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anonymization --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.events.users.login.failure.auto.mode] => anonymization - [appsec.events.users.login.failure.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true + [appsec.events.users.login.failure.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 + [appsec.events.users.login.failure.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_no_login.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_no_login.phpt index 1a1bb35403f..f64a90a8a82 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_no_login.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_no_login.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anon --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.events.users.login.failure.auto.mode] => anonymization + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true + [appsec.events.users.login.failure.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_no_user.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_no_user.phpt index cfd4c490f45..16d626ecb90 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_no_user.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_anon_mode_no_user.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anon --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s [_dd.appsec.events.users.login.failure.auto.mode] => anonymization - [appsec.events.users.login.failure.usr.login] => anon_428821350e9691491f616b754cd8315f [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true + [appsec.events.users.login.failure.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_default_mode.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_default_mode.phpt index 6b532c5e2de..0f890418686 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_default_mode.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_default_mode.phpt @@ -4,7 +4,7 @@ Metadata is kept on automated (default) identification mode DD_APPSEC_ENABLED=1 --FILE-- 'discarded']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.failure.auto.mode] => identification - [appsec.events.users.login.failure.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true + [appsec.events.users.login.failure.usr.id] => automatedID + [appsec.events.users.login.failure.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_disabled_config.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_disabled_config.phpt index c9fc3694157..3565d36afe8 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_disabled_config.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_disabled_config.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING_ENABLED=0 --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_disabled_mode.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_disabled_mode.phpt index 2747603b320..69002415c10 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_disabled_mode.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_disabled_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=disabled --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode.phpt index 608210e88c8..9db99cdcce2 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- 'some@email.com']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.failure.auto.mode] => identification - [appsec.events.users.login.failure.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true + [appsec.events.users.login.failure.usr.id] => automatedID + [appsec.events.users.login.failure.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_02.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_02.phpt index 994758b559f..ee1e7fccdc5 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_02.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_02.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- 'some@email.com']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.failure.auto.mode] => identification - [appsec.events.users.login.failure.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true + [appsec.events.users.login.failure.usr.id] => automatedID + [appsec.events.users.login.failure.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_compat.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_compat.phpt index 7b01f3a16cc..f1958def015 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_compat.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_compat.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING=extended --FILE-- 'some@email.com']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.failure.auto.mode] => identification - [appsec.events.users.login.failure.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true + [appsec.events.users.login.failure.usr.id] => automatedID + [appsec.events.users.login.failure.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_full_name.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_full_name.phpt index 438b174fc96..404aef541a8 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_full_name.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_ident_mode_full_name.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=identification --FILE-- 'some@email.com']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.failure.auto.mode] => identification - [appsec.events.users.login.failure.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true + [appsec.events.users.login.failure.usr.id] => automatedID + [appsec.events.users.login.failure.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_invalid_mode.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_invalid_mode.phpt index b4ddddd5500..733dcc6f8d8 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_invalid_mode.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_invalid_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=invalid --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- %AWarning:%a[ddappsec] Unknown user collection mode: invalid%a -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_no_login.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_no_login.phpt index acb357d8a41..b70dd81ac54 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_no_login.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_no_login.phpt @@ -4,7 +4,7 @@ Track an automated user login failure event without login provided and verify th DD_APPSEC_ENABLED=1 --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.failure.auto.mode] => identification + [_dd.appsec.usr.id] => automatedID + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => false + [appsec.events.users.login.failure.usr.id] => automatedID + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_automated_no_user.phpt b/appsec/tests/extension/track_user_login_failure_event_automated_no_user.phpt index ab6d8677068..933eb721069 100644 --- a/appsec/tests/extension/track_user_login_failure_event_automated_no_user.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_automated_no_user.phpt @@ -4,7 +4,7 @@ Track an automated user login failure event without user provided and verify the DD_APPSEC_ENABLED=1 --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s [_dd.appsec.events.users.login.failure.auto.mode] => identification - [appsec.events.users.login.failure.usr.login] => login [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => false + [appsec.events.users.login.failure.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_existing_user.phpt b/appsec/tests/extension/track_user_login_failure_event_existing_user.phpt index c2ef7fd0850..ada2241f7f1 100644 --- a/appsec/tests/extension/track_user_login_failure_event_existing_user.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_existing_user.phpt @@ -4,7 +4,7 @@ Track a user login failure event and verify the tags in the root span DD_APPSEC_ENABLED=1 --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_failure_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => sdkID - [appsec.events.users.login.failure.usr.login] => sdkID - [appsec.events.users.login.failure.track] => true [_dd.appsec.events.users.login.failure.sdk] => true - [appsec.events.users.login.failure.value] => something - [appsec.events.users.login.failure.metadata] => some other metadata + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.email] => noneofyour@business.com + [appsec.events.users.login.failure.metadata] => some other metadata + [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true + [appsec.events.users.login.failure.usr.id] => sdkID + [appsec.events.users.login.failure.usr.login] => sdkID + [appsec.events.users.login.failure.value] => something + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_no_user.phpt b/appsec/tests/extension/track_user_login_failure_event_no_user.phpt index f7c79be7c12..22b48a1ead4 100644 --- a/appsec/tests/extension/track_user_login_failure_event_no_user.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_no_user.phpt @@ -4,7 +4,7 @@ Track a user login failure event without user provided and verify the tags in th DD_APPSEC_ENABLED=1 --FILE-- --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_failure_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.track] => true [_dd.appsec.events.users.login.failure.sdk] => true + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => false + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority.phpt b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority.phpt index 50e235cd49c..69ee98618a3 100644 --- a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority.phpt @@ -4,7 +4,7 @@ When values are set with automated event and with sdk, SDK takes priority DD_APPSEC_ENABLED=1 --FILE-- "something-from-sdk"]); track_user_login_failure_event_automated('test', "login", "automatedID", false, ["value" => "something-from-automated"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_failure_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s + [_dd.appsec.events.users.login.failure.auto.mode] => identification + [_dd.appsec.events.users.login.failure.sdk] => true + [_dd.appsec.usr.id] => automatedID + [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [appsec.events.users.login.failure.track] => true + [appsec.events.users.login.failure.usr.exists] => true [appsec.events.users.login.failure.usr.id] => sdkID [appsec.events.users.login.failure.usr.login] => sdkID - [appsec.events.users.login.failure.track] => true - [_dd.appsec.events.users.login.failure.sdk] => true [appsec.events.users.login.failure.value] => something-from-sdk - [appsec.events.users.login.failure.usr.exists] => true + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 - [_dd.appsec.usr.id] => automatedID - [_dd.appsec.events.users.login.failure.auto.mode] => identification - [_dd.appsec.usr.login] => login ) diff --git a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_02.phpt b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_02.phpt index 46eca3b5a1e..b00af568c71 100644 --- a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_02.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_02.phpt @@ -4,7 +4,7 @@ When values are set with automated event and with sdk, SDK takes priority DD_APPSEC_ENABLED=1 --FILE-- "something-from-automated"]); track_user_login_failure_event("sdkID", true, ["value" => "something-from-sdk"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_failure_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => sdkID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.failure.auto.mode] => identification - [appsec.events.users.login.failure.usr.login] => sdkID + [_dd.appsec.events.users.login.failure.sdk] => true + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true - [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 - [_dd.appsec.events.users.login.failure.sdk] => true + [appsec.events.users.login.failure.usr.id] => sdkID + [appsec.events.users.login.failure.usr.login] => sdkID [appsec.events.users.login.failure.value] => something-from-sdk + [process_id] => %d + [runtime-id] => %s + [server.business_logic.users.login.failure] => null ) diff --git a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_03.phpt b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_03.phpt index e03969f73ff..e5ff0b3a89f 100644 --- a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_03.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_03.phpt @@ -4,7 +4,7 @@ Latest sdk values take priority DD_APPSEC_ENABLED=1 --FILE-- "something-from-sdk"]) track_user_login_failure_event("otherSdkID", true, ["value" => "something-from-sdk-2"]); track_user_login_failure_event_automated('test', "otherLogin", "otherAutomatedID", false, ["value" => "something-from-automated-2"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_failure_event() is deprecated in %s on line %d Deprecated: Function datadog\appsec\track_user_login_failure_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => otherSdkID - [_dd.appsec.usr.id] => otherAutomatedID [_dd.appsec.events.users.login.failure.auto.mode] => identification - [appsec.events.users.login.failure.usr.login] => otherSdkID + [_dd.appsec.events.users.login.failure.sdk] => true + [_dd.appsec.usr.id] => otherAutomatedID [_dd.appsec.usr.login] => otherLogin + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true - [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 - [_dd.appsec.events.users.login.failure.sdk] => true + [appsec.events.users.login.failure.usr.id] => otherSdkID + [appsec.events.users.login.failure.usr.login] => otherSdkID [appsec.events.users.login.failure.value] => something-from-sdk-2 + [process_id] => %d + [runtime-id] => %s + [server.business_logic.users.login.failure] => null ) diff --git a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_04.phpt b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_04.phpt index 54debdf345a..f23a4083460 100644 --- a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_04.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_04.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- "something-from-sdk"]); track_user_login_failure_event_automated('test', "login", "automatedID", false, ["value" => "something-from-automated"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_failure_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s + [_dd.appsec.events.users.login.failure.auto.mode] => identification + [_dd.appsec.events.users.login.failure.sdk] => true + [_dd.appsec.usr.id] => automatedID + [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [appsec.events.users.login.failure.track] => true + [appsec.events.users.login.failure.usr.exists] => true [appsec.events.users.login.failure.usr.id] => sdkID [appsec.events.users.login.failure.usr.login] => sdkID - [appsec.events.users.login.failure.track] => true - [_dd.appsec.events.users.login.failure.sdk] => true [appsec.events.users.login.failure.value] => something-from-sdk - [appsec.events.users.login.failure.usr.exists] => true + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 - [_dd.appsec.usr.id] => automatedID - [_dd.appsec.events.users.login.failure.auto.mode] => identification - [_dd.appsec.usr.login] => login ) diff --git a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_05.phpt b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_05.phpt index 20e46ff932a..c7599982d2c 100644 --- a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_05.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_05.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- "something-from-automated"]); track_user_login_failure_event("sdkID", true, ["value" => "something-from-sdk"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_failure_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => sdkID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.failure.auto.mode] => identification - [appsec.events.users.login.failure.usr.login] => sdkID + [_dd.appsec.events.users.login.failure.sdk] => true + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true - [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 - [_dd.appsec.events.users.login.failure.sdk] => true + [appsec.events.users.login.failure.usr.id] => sdkID + [appsec.events.users.login.failure.usr.login] => sdkID [appsec.events.users.login.failure.value] => something-from-sdk + [process_id] => %d + [runtime-id] => %s + [server.business_logic.users.login.failure] => null ) diff --git a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_06.phpt b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_06.phpt index f546f8302ba..13940c99eab 100644 --- a/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_06.phpt +++ b/appsec/tests/extension/track_user_login_failure_event_sdk_takes_priority_06.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- "something-from-sdk"]) track_user_login_failure_event("otherSdkID", true, ["value" => "something-from-sdk-2"]); track_user_login_failure_event_automated('test', "otherLogin", "otherAutomatedID", false, ["value" => "something-from-automated-2"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_failure_event() is deprecated in %s on line %d Deprecated: Function datadog\appsec\track_user_login_failure_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.id] => otherSdkID - [_dd.appsec.usr.id] => otherAutomatedID [_dd.appsec.events.users.login.failure.auto.mode] => identification - [appsec.events.users.login.failure.usr.login] => otherSdkID + [_dd.appsec.events.users.login.failure.sdk] => true + [_dd.appsec.usr.id] => otherAutomatedID [_dd.appsec.usr.login] => otherLogin + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.failure.track] => true [appsec.events.users.login.failure.usr.exists] => true - [server.business_logic.users.login.failure] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 - [_dd.appsec.events.users.login.failure.sdk] => true + [appsec.events.users.login.failure.usr.id] => otherSdkID + [appsec.events.users.login.failure.usr.login] => otherSdkID [appsec.events.users.login.failure.value] => something-from-sdk-2 + [process_id] => %d + [runtime-id] => %s + [server.business_logic.users.login.failure] => null ) diff --git a/appsec/tests/extension/track_user_login_failure_v2_01.phpt b/appsec/tests/extension/track_user_login_failure_v2_01.phpt index 7e7beee644c..c06fd90ab26 100644 --- a/appsec/tests/extension/track_user_login_failure_v2_01.phpt +++ b/appsec/tests/extension/track_user_login_failure_v2_01.phpt @@ -15,27 +15,31 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(9) { - ["runtime-id"]=> - string(%d) %s - ["appsec.events.users.login.failure.usr.login"]=> - string(%d) "login" - ["appsec.events.users.login.failure.usr.exists"]=> - string(%d) "true" - ["appsec.events.users.login.failure.track"]=> - string(%d) "true" +array(10) { ["_dd.appsec.events.users.login.failure.sdk"]=> string(%d) "true" + ["_dd.p.dm"]=> + string(2) "-5" + ["_dd.p.ts"]=> + string(2) "02" ["appsec.events.users.login.failure.metakey1"]=> string(%d) "metavalue" ["appsec.events.users.login.failure.metakey2"]=> string(%d) "metavalue02" - ["_dd.p.ts"]=> - string(2) "02" - ["_dd.p.dm"]=> - string(2) "-5" + ["appsec.events.users.login.failure.track"]=> + string(%d) "true" + ["appsec.events.users.login.failure.usr.exists"]=> + string(%d) "true" + ["appsec.events.users.login.failure.usr.login"]=> + string(%d) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_failure_v2_01_appsec_disabled.phpt b/appsec/tests/extension/track_user_login_failure_v2_01_appsec_disabled.phpt index 4b37f5cd736..06b853258b0 100644 --- a/appsec/tests/extension/track_user_login_failure_v2_01_appsec_disabled.phpt +++ b/appsec/tests/extension/track_user_login_failure_v2_01_appsec_disabled.phpt @@ -17,23 +17,27 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(7) { - ["runtime-id"]=> - string(%d) %s - ["appsec.events.users.login.failure.usr.login"]=> - string(%d) "login" - ["appsec.events.users.login.failure.usr.exists"]=> - string(%d) "true" - ["appsec.events.users.login.failure.track"]=> - string(%d) "true" +array(8) { ["_dd.appsec.events.users.login.failure.sdk"]=> string(%d) "true" ["appsec.events.users.login.failure.metakey1"]=> string(%d) "metavalue" ["appsec.events.users.login.failure.metakey2"]=> string(%d) "metavalue02" + ["appsec.events.users.login.failure.track"]=> + string(%d) "true" + ["appsec.events.users.login.failure.usr.exists"]=> + string(%d) "true" + ["appsec.events.users.login.failure.usr.login"]=> + string(%d) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_failure_v2_02.phpt b/appsec/tests/extension/track_user_login_failure_v2_02.phpt index 47f60fc3b03..6df75994a3c 100644 --- a/appsec/tests/extension/track_user_login_failure_v2_02.phpt +++ b/appsec/tests/extension/track_user_login_failure_v2_02.phpt @@ -12,23 +12,27 @@ ddtrace_version_at_least('0.85.0'); false ); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(7) { - ["runtime-id"]=> - string(%d) %s - ["appsec.events.users.login.failure.usr.login"]=> - string(%d) "login" - ["appsec.events.users.login.failure.usr.exists"]=> - string(%d) "false" - ["appsec.events.users.login.failure.track"]=> - string(%d) "true" +array(8) { ["_dd.appsec.events.users.login.failure.sdk"]=> string(%d) "true" - ["_dd.p.ts"]=> - string(2) "02" ["_dd.p.dm"]=> string(2) "-5" + ["_dd.p.ts"]=> + string(2) "02" + ["appsec.events.users.login.failure.track"]=> + string(%d) "true" + ["appsec.events.users.login.failure.usr.exists"]=> + string(%d) "false" + ["appsec.events.users.login.failure.usr.login"]=> + string(%d) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_failure_v2_02_appsec_disabled.phpt b/appsec/tests/extension/track_user_login_failure_v2_02_appsec_disabled.phpt index a1153fe0ea3..ed29d050ca7 100644 --- a/appsec/tests/extension/track_user_login_failure_v2_02_appsec_disabled.phpt +++ b/appsec/tests/extension/track_user_login_failure_v2_02_appsec_disabled.phpt @@ -14,19 +14,23 @@ ddtrace_version_at_least('0.85.0'); false ); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(5) { - ["runtime-id"]=> - string(%d) %s - ["appsec.events.users.login.failure.usr.login"]=> - string(%d) "login" - ["appsec.events.users.login.failure.usr.exists"]=> - string(%d) "false" - ["appsec.events.users.login.failure.track"]=> - string(%d) "true" +array(6) { ["_dd.appsec.events.users.login.failure.sdk"]=> string(%d) "true" + ["appsec.events.users.login.failure.track"]=> + string(%d) "true" + ["appsec.events.users.login.failure.usr.exists"]=> + string(%d) "false" + ["appsec.events.users.login.failure.usr.login"]=> + string(%d) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_failure_v2_03.phpt b/appsec/tests/extension/track_user_login_failure_v2_03.phpt index 1d6f0e690b3..304ac4bd3fd 100644 --- a/appsec/tests/extension/track_user_login_failure_v2_03.phpt +++ b/appsec/tests/extension/track_user_login_failure_v2_03.phpt @@ -13,15 +13,19 @@ $emptyLogin = ""; false ); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(3) { - ["runtime-id"]=> - string(%d) %s - ["_dd.p.ts"]=> - string(2) "02" +array(4) { ["_dd.p.dm"]=> string(2) "-5" + ["_dd.p.ts"]=> + string(2) "02" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_failure_v2_03_appsec_disabled.phpt b/appsec/tests/extension/track_user_login_failure_v2_03_appsec_disabled.phpt index 618eb6406f9..f54a7657c08 100644 --- a/appsec/tests/extension/track_user_login_failure_v2_03_appsec_disabled.phpt +++ b/appsec/tests/extension/track_user_login_failure_v2_03_appsec_disabled.phpt @@ -15,11 +15,15 @@ $emptyLogin = ""; false ); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(1) { +array(2) { + ["process_id"]=> + int(%d) ["runtime-id"]=> string(%d) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_success_event.phpt b/appsec/tests/extension/track_user_login_success_event.phpt index cc8e6bfe7ef..0ae5b8add8b 100644 --- a/appsec/tests/extension/track_user_login_success_event.phpt +++ b/appsec/tests/extension/track_user_login_success_event.phpt @@ -4,7 +4,7 @@ Track a user login success event and verify the tags in the root span DD_APPSEC_ENABLED=1 --FILE-- --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_success_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => sdkID - [appsec.events.users.login.success.usr.login] => sdkID + [_dd.appsec.enabled] => 1 [_dd.appsec.events.users.login.success.sdk] => true - [appsec.events.users.login.success.value] => something - [appsec.events.users.login.success.metadata] => some other metadata + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [_dd.runtime_family] => php [appsec.events.users.login.success.email] => noneofyour@business.com + [appsec.events.users.login.success.metadata] => some other metadata [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => sdkID + [appsec.events.users.login.success.value] => something + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 - [_dd.runtime_family] => php -) -root_span_get_metrics(): -Array -( - [%s] => %d - [_dd.appsec.enabled] => 1 + [usr.id] => sdkID ) int(2) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_anon_mode.phpt b/appsec/tests/extension/track_user_login_success_event_automated_anon_mode.phpt index be46db66343..7e28e6eac66 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_anon_mode.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_anon_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anon --FILE-- 'discarded']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.events.users.login.success.auto.mode] => anonymization - [appsec.events.users.login.success.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 + [usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_compat.phpt b/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_compat.phpt index 38370973ec1..87b2ad815e6 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_compat.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_compat.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING=safe --FILE-- 'discarded']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.events.users.login.success.auto.mode] => anonymization - [appsec.events.users.login.success.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 + [usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_full_name.phpt b/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_full_name.phpt index d13aa55d886..84ceb9180d6 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_full_name.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_full_name.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anonymization --FILE-- 'discarded']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.events.users.login.success.auto.mode] => anonymization - [appsec.events.users.login.success.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 + [usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_no_user.phpt b/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_no_user.phpt index 8e762458ed4..b5bb4fecaf8 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_no_user.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_anon_mode_no_user.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anon --FILE-- 'discarded']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s [_dd.appsec.events.users.login.success.auto.mode] => anonymization - [appsec.events.users.login.success.usr.login] => anon_428821350e9691491f616b754cd8315f [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_default_mode.phpt b/appsec/tests/extension/track_user_login_success_event_automated_default_mode.phpt index 01e2b71bd77..e260823b218 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_default_mode.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_default_mode.phpt @@ -4,7 +4,7 @@ Track automated user login success event without specifying a mode and verify th DD_APPSEC_ENABLED=1 --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.success.auto.mode] => identification - [appsec.events.users.login.success.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 + [usr.id] => automatedID ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_disabled_config.phpt b/appsec/tests/extension/track_user_login_success_event_automated_disabled_config.phpt index 1a7ada7001f..6ffa4c932f2 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_disabled_config.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_disabled_config.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING_ENABLED=0 --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_disabled_mode.phpt b/appsec/tests/extension/track_user_login_success_event_automated_disabled_mode.phpt index ec14127d742..1e65391730d 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_disabled_mode.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_disabled_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=disabled --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_empty_login.phpt b/appsec/tests/extension/track_user_login_success_event_automated_empty_login.phpt index 82c00d66ee4..e14cb222e24 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_empty_login.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_empty_login.phpt @@ -7,7 +7,7 @@ datadog.appsec.log_level=debug DD_APPSEC_ENABLED=1 --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_empty_user.phpt b/appsec/tests/extension/track_user_login_success_event_automated_empty_user.phpt index 7b3e115ffb7..fba61d8aa4b 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_empty_user.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_empty_user.phpt @@ -7,7 +7,7 @@ datadog.appsec.log_level=debug DD_APPSEC_ENABLED=1 --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s [_dd.appsec.events.users.login.success.auto.mode] => identification - [appsec.events.users.login.success.usr.login] => login [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_ident_mode.phpt b/appsec/tests/extension/track_user_login_success_event_automated_ident_mode.phpt index f174a19c61a..1c3a2cbd76f 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_ident_mode.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_ident_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- 'some@email.com']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.success.auto.mode] => identification - [appsec.events.users.login.success.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 + [usr.id] => automatedID ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_02.phpt b/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_02.phpt index 6e747b8dc38..d3a8479ece7 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_02.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_02.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- 'some@email.com']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.success.auto.mode] => identification - [appsec.events.users.login.success.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 + [usr.id] => automatedID ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_compat.phpt b/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_compat.phpt index 14c2bab4e55..919e5b6d003 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_compat.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_compat.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING=extended --FILE-- 'some@email.com']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.success.auto.mode] => identification - [appsec.events.users.login.success.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 + [usr.id] => automatedID ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_full_name.phpt b/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_full_name.phpt index a35d3f63415..553793eae91 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_full_name.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_ident_mode_full_name.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=identification --FILE-- 'some@email.com']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.success.auto.mode] => identification - [appsec.events.users.login.success.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 + [usr.id] => automatedID ) diff --git a/appsec/tests/extension/track_user_login_success_event_automated_invalid_mode.phpt b/appsec/tests/extension/track_user_login_success_event_automated_invalid_mode.phpt index 2ebecb3a964..3dab8e4f6b5 100644 --- a/appsec/tests/extension/track_user_login_success_event_automated_invalid_mode.phpt +++ b/appsec/tests/extension/track_user_login_success_event_automated_invalid_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=invalid --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- %AWarning:%a[ddappsec] Unknown user collection mode: invalid%a -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority.phpt b/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority.phpt index da333927184..ceb9d26f23c 100644 --- a/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority.phpt +++ b/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority.phpt @@ -4,7 +4,7 @@ When values are set with automated event and with sdk, SDK takes priority DD_APPSEC_ENABLED=1 --FILE-- "something-from-sdk"]); track_user_login_success_event_automated('test', "login", "automatedID", ["value" => "something-from-automated"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_success_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => sdkID - [appsec.events.users.login.success.usr.login] => sdkID + [_dd.appsec.events.users.login.success.auto.mode] => identification [_dd.appsec.events.users.login.success.sdk] => true - [appsec.events.users.login.success.value] => something-from-sdk - [appsec.events.users.login.success.track] => true - [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 [_dd.appsec.usr.id] => automatedID - [_dd.appsec.events.users.login.success.auto.mode] => identification [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => sdkID + [appsec.events.users.login.success.value] => something-from-sdk + [process_id] => %d + [runtime-id] => %s + [server.business_logic.users.login.success] => null + [usr.id] => sdkID ) diff --git a/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority_02.phpt b/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority_02.phpt index 64544c4735c..95670270b3f 100644 --- a/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority_02.phpt +++ b/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority_02.phpt @@ -4,7 +4,7 @@ When values are set with automated event and with sdk, SDK takes priority DD_APPSEC_ENABLED=1 --FILE-- "something-from-automated"]); track_user_login_success_event("sdkID", ["value" => "something-from-sdk"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_success_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => sdkID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.login.success.auto.mode] => identification - [appsec.events.users.login.success.usr.login] => sdkID + [_dd.appsec.events.users.login.success.sdk] => true + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login - [appsec.events.users.login.success.track] => true - [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 [_dd.p.dm] => -5 - [_dd.appsec.events.users.login.success.sdk] => true + [_dd.p.ts] => 02 + [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => sdkID [appsec.events.users.login.success.value] => something-from-sdk + [process_id] => %d + [runtime-id] => %s + [server.business_logic.users.login.success] => null + [usr.id] => sdkID ) diff --git a/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority_03.phpt b/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority_03.phpt index a0e0a6ea08c..70f2d7e154f 100644 --- a/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority_03.phpt +++ b/appsec/tests/extension/track_user_login_success_event_sdk_takes_priority_03.phpt @@ -4,7 +4,7 @@ Latest sdk values take priority DD_APPSEC_ENABLED=1 --FILE-- "something-from-sdk"]); track_user_login_success_event("otherSdkID", ["value" => "something-from-sdk-2"]); track_user_login_success_event_automated('test', "otherLogin", "otherAutomatedID", ["value" => "something-from-automated-2"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- Deprecated: Function datadog\appsec\track_user_login_success_event() is deprecated in %s on line %d Deprecated: Function datadog\appsec\track_user_login_success_event() is deprecated in %s on line %d -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => otherSdkID - [_dd.appsec.usr.id] => otherAutomatedID [_dd.appsec.events.users.login.success.auto.mode] => identification - [appsec.events.users.login.success.usr.login] => otherSdkID + [_dd.appsec.events.users.login.success.sdk] => true + [_dd.appsec.usr.id] => otherAutomatedID [_dd.appsec.usr.login] => otherLogin - [appsec.events.users.login.success.track] => true - [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 [_dd.p.dm] => -5 - [_dd.appsec.events.users.login.success.sdk] => true + [_dd.p.ts] => 02 + [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => otherSdkID [appsec.events.users.login.success.value] => something-from-sdk-2 + [process_id] => %d + [runtime-id] => %s + [server.business_logic.users.login.success] => null + [usr.id] => otherSdkID ) diff --git a/appsec/tests/extension/track_user_login_success_v2_01.phpt b/appsec/tests/extension/track_user_login_success_v2_01.phpt index c42c05f4596..8aefc4846c8 100644 --- a/appsec/tests/extension/track_user_login_success_v2_01.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_01.phpt @@ -15,35 +15,39 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(13) { - ["runtime-id"]=> - string(%d) %s - ["appsec.events.users.login.success.usr.login"]=> - string(%d) "login" - ["appsec.events.users.login.success.track"]=> - string(%d) "true" +array(14) { ["_dd.appsec.events.users.login.success.sdk"]=> string(%d) "true" ["_dd.appsec.user.collection_mode"]=> string(%d) "sdk" - ["appsec.events.users.login.success.usr.id"]=> - string(7) "user_id" + ["_dd.p.dm"]=> + string(2) "-5" + ["_dd.p.ts"]=> + string(2) "02" ["appsec.events.users.login.success.metakey1"]=> string(%d) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(%d) "metavalue02" + ["appsec.events.users.login.success.track"]=> + string(%d) "true" + ["appsec.events.users.login.success.usr.id"]=> + string(7) "user_id" + ["appsec.events.users.login.success.usr.login"]=> + string(%d) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) %s ["usr.id"]=> string(%d) "user_id" ["usr.metakey1"]=> string(%d) "metavalue" ["usr.metakey2"]=> string(%d) "metavalue02" - ["_dd.p.ts"]=> - string(2) "02" - ["_dd.p.dm"]=> - string(2) "-5" } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_success_v2_01_appsec_disabled.phpt b/appsec/tests/extension/track_user_login_success_v2_01_appsec_disabled.phpt index ee05f4f3019..687b28b0d36 100644 --- a/appsec/tests/extension/track_user_login_success_v2_01_appsec_disabled.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_01_appsec_disabled.phpt @@ -17,27 +17,31 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(11) { - ["runtime-id"]=> - string(%d) %s - ["appsec.events.users.login.success.usr.login"]=> - string(%d) "login" - ["appsec.events.users.login.success.track"]=> - string(%d) "true" +array(12) { ["_dd.appsec.events.users.login.success.sdk"]=> string(%d) "true" ["_dd.appsec.user.collection_mode"]=> string(%d) "sdk" - ["appsec.events.users.login.success.usr.id"]=> - string(7) "user_id" ["appsec.events.users.login.success.metakey1"]=> string(%d) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(%d) "metavalue02" + ["appsec.events.users.login.success.track"]=> + string(%d) "true" + ["appsec.events.users.login.success.usr.id"]=> + string(7) "user_id" + ["appsec.events.users.login.success.usr.login"]=> + string(%d) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) %s ["usr.id"]=> string(%d) "user_id" ["usr.metakey1"]=> diff --git a/appsec/tests/extension/track_user_login_success_v2_02.phpt b/appsec/tests/extension/track_user_login_success_v2_02.phpt index 5b865e222e5..90c1b01cd6d 100644 --- a/appsec/tests/extension/track_user_login_success_v2_02.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_02.phpt @@ -19,39 +19,43 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(15) { - ["runtime-id"]=> - string(%s) %s - ["appsec.events.users.login.success.usr.id"]=> - string(%s) "1234" - ["appsec.events.users.login.success.usr.email"]=> - string(%s) "mail@to.es" - ["appsec.events.users.login.success.usr.name"]=> - string(%s) "user name" - ["appsec.events.users.login.success.usr.login"]=> - string(%s) "login" - ["appsec.events.users.login.success.track"]=> - string(%s) "true" +array(16) { ["_dd.appsec.events.users.login.success.sdk"]=> string(%s) "true" ["_dd.appsec.user.collection_mode"]=> string(%s) "sdk" + ["_dd.p.dm"]=> + string(2) "-5" + ["_dd.p.ts"]=> + string(2) "02" ["appsec.events.users.login.success.metakey1"]=> string(%s) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(%s) "metavalue02" + ["appsec.events.users.login.success.track"]=> + string(%s) "true" + ["appsec.events.users.login.success.usr.email"]=> + string(%s) "mail@to.es" + ["appsec.events.users.login.success.usr.id"]=> + string(%s) "1234" + ["appsec.events.users.login.success.usr.login"]=> + string(%s) "login" + ["appsec.events.users.login.success.usr.name"]=> + string(%s) "user name" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%s) %s ["usr.id"]=> string(%s) "1234" ["usr.metakey1"]=> string(%s) "metavalue" ["usr.metakey2"]=> string(%s) "metavalue02" - ["_dd.p.ts"]=> - string(2) "02" - ["_dd.p.dm"]=> - string(2) "-5" } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_success_v2_02_appsec_disabled.phpt b/appsec/tests/extension/track_user_login_success_v2_02_appsec_disabled.phpt index 9e8ba4dd77f..7a66828878e 100644 --- a/appsec/tests/extension/track_user_login_success_v2_02_appsec_disabled.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_02_appsec_disabled.phpt @@ -21,23 +21,13 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(13) { - ["runtime-id"]=> - string(%s) %s - ["appsec.events.users.login.success.usr.id"]=> - string(%s) "1234" - ["appsec.events.users.login.success.usr.email"]=> - string(%s) "mail@to.es" - ["appsec.events.users.login.success.usr.name"]=> - string(%s) "user name" - ["appsec.events.users.login.success.usr.login"]=> - string(%s) "login" - ["appsec.events.users.login.success.track"]=> - string(%s) "true" +array(14) { ["_dd.appsec.events.users.login.success.sdk"]=> string(%s) "true" ["_dd.appsec.user.collection_mode"]=> @@ -46,6 +36,20 @@ array(13) { string(%s) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(%s) "metavalue02" + ["appsec.events.users.login.success.track"]=> + string(%s) "true" + ["appsec.events.users.login.success.usr.email"]=> + string(%s) "mail@to.es" + ["appsec.events.users.login.success.usr.id"]=> + string(%s) "1234" + ["appsec.events.users.login.success.usr.login"]=> + string(%s) "login" + ["appsec.events.users.login.success.usr.name"]=> + string(%s) "user name" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%s) %s ["usr.id"]=> string(%s) "1234" ["usr.metakey1"]=> diff --git a/appsec/tests/extension/track_user_login_success_v2_03.phpt b/appsec/tests/extension/track_user_login_success_v2_03.phpt index bc882258e4d..5e7f0e52c94 100644 --- a/appsec/tests/extension/track_user_login_success_v2_03.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_03.phpt @@ -18,35 +18,39 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(13) { - ["runtime-id"]=> - string(%s) %s - ["appsec.events.users.login.success.usr.id"]=> - string(%s) "1234" - ["appsec.events.users.login.success.usr.login"]=> - string(%s) "login" - ["appsec.events.users.login.success.track"]=> - string(%s) "true" +array(14) { ["_dd.appsec.events.users.login.success.sdk"]=> string(%s) "true" ["_dd.appsec.user.collection_mode"]=> string(%s) "sdk" + ["_dd.p.dm"]=> + string(2) "-5" + ["_dd.p.ts"]=> + string(2) "02" ["appsec.events.users.login.success.metakey1"]=> string(%s) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(%s) "metavalue02" + ["appsec.events.users.login.success.track"]=> + string(%s) "true" + ["appsec.events.users.login.success.usr.id"]=> + string(%s) "1234" + ["appsec.events.users.login.success.usr.login"]=> + string(%s) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%s) %s ["usr.id"]=> string(%s) "1234" ["usr.metakey1"]=> string(%s) "metavalue" ["usr.metakey2"]=> string(%s) "metavalue02" - ["_dd.p.ts"]=> - string(2) "02" - ["_dd.p.dm"]=> - string(2) "-5" } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_success_v2_03_appsec_disabled.phpt b/appsec/tests/extension/track_user_login_success_v2_03_appsec_disabled.phpt index 1a326da8415..e1e0831873d 100644 --- a/appsec/tests/extension/track_user_login_success_v2_03_appsec_disabled.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_03_appsec_disabled.phpt @@ -20,19 +20,13 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(11) { - ["runtime-id"]=> - string(%s) %s - ["appsec.events.users.login.success.usr.id"]=> - string(%s) "1234" - ["appsec.events.users.login.success.usr.login"]=> - string(%s) "login" - ["appsec.events.users.login.success.track"]=> - string(%s) "true" +array(12) { ["_dd.appsec.events.users.login.success.sdk"]=> string(%s) "true" ["_dd.appsec.user.collection_mode"]=> @@ -41,6 +35,16 @@ array(11) { string(%s) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(%s) "metavalue02" + ["appsec.events.users.login.success.track"]=> + string(%s) "true" + ["appsec.events.users.login.success.usr.id"]=> + string(%s) "1234" + ["appsec.events.users.login.success.usr.login"]=> + string(%s) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%s) %s ["usr.id"]=> string(%s) "1234" ["usr.metakey1"]=> diff --git a/appsec/tests/extension/track_user_login_success_v2_04.phpt b/appsec/tests/extension/track_user_login_success_v2_04.phpt index 3ebd62ab7ee..1afd9ffd639 100644 --- a/appsec/tests/extension/track_user_login_success_v2_04.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_04.phpt @@ -17,27 +17,31 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(9) { - ["runtime-id"]=> - string(%s) %s - ["appsec.events.users.login.success.usr.some_key"]=> - string(10) "some value" - ["appsec.events.users.login.success.usr.login"]=> - string(5) "login" - ["appsec.events.users.login.success.track"]=> - string(4) "true" +array(10) { ["_dd.appsec.events.users.login.success.sdk"]=> string(4) "true" + ["_dd.p.dm"]=> + string(2) "-5" + ["_dd.p.ts"]=> + string(2) "02" ["appsec.events.users.login.success.metakey1"]=> string(9) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(11) "metavalue02" - ["_dd.p.ts"]=> - string(2) "02" - ["_dd.p.dm"]=> - string(2) "-5" + ["appsec.events.users.login.success.track"]=> + string(4) "true" + ["appsec.events.users.login.success.usr.login"]=> + string(5) "login" + ["appsec.events.users.login.success.usr.some_key"]=> + string(10) "some value" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%s) %s } diff --git a/appsec/tests/extension/track_user_login_success_v2_04_appsec_disabled.phpt b/appsec/tests/extension/track_user_login_success_v2_04_appsec_disabled.phpt index 899ff14f42a..c18c52a3e9f 100644 --- a/appsec/tests/extension/track_user_login_success_v2_04_appsec_disabled.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_04_appsec_disabled.phpt @@ -19,23 +19,27 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(7) { - ["runtime-id"]=> - string(%s) %s - ["appsec.events.users.login.success.usr.some_key"]=> - string(10) "some value" - ["appsec.events.users.login.success.usr.login"]=> - string(5) "login" - ["appsec.events.users.login.success.track"]=> - string(4) "true" +array(8) { ["_dd.appsec.events.users.login.success.sdk"]=> string(4) "true" ["appsec.events.users.login.success.metakey1"]=> string(9) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(11) "metavalue02" + ["appsec.events.users.login.success.track"]=> + string(4) "true" + ["appsec.events.users.login.success.usr.login"]=> + string(5) "login" + ["appsec.events.users.login.success.usr.some_key"]=> + string(10) "some value" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%s) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_success_v2_05.phpt b/appsec/tests/extension/track_user_login_success_v2_05.phpt index efa26e37c57..49af74db60a 100644 --- a/appsec/tests/extension/track_user_login_success_v2_05.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_05.phpt @@ -17,25 +17,29 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(8) { - ["runtime-id"]=> - string(%s) %s - ["appsec.events.users.login.success.usr.login"]=> - string(5) "login" - ["appsec.events.users.login.success.track"]=> - string(4) "true" +array(9) { ["_dd.appsec.events.users.login.success.sdk"]=> string(4) "true" + ["_dd.p.dm"]=> + string(2) "-5" + ["_dd.p.ts"]=> + string(2) "02" ["appsec.events.users.login.success.metakey1"]=> string(9) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(11) "metavalue02" - ["_dd.p.ts"]=> - string(2) "02" - ["_dd.p.dm"]=> - string(2) "-5" + ["appsec.events.users.login.success.track"]=> + string(4) "true" + ["appsec.events.users.login.success.usr.login"]=> + string(5) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%s) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_success_v2_05_appsec_disabled.phpt b/appsec/tests/extension/track_user_login_success_v2_05_appsec_disabled.phpt index b7f5c279e01..a4ebd3d2282 100644 --- a/appsec/tests/extension/track_user_login_success_v2_05_appsec_disabled.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_05_appsec_disabled.phpt @@ -19,21 +19,25 @@ ddtrace_version_at_least('0.85.0'); "metakey2" => "metavalue02", ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(6) { - ["runtime-id"]=> - string(%s) %s - ["appsec.events.users.login.success.usr.login"]=> - string(5) "login" - ["appsec.events.users.login.success.track"]=> - string(4) "true" +array(7) { ["_dd.appsec.events.users.login.success.sdk"]=> string(4) "true" ["appsec.events.users.login.success.metakey1"]=> string(9) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(11) "metavalue02" + ["appsec.events.users.login.success.track"]=> + string(4) "true" + ["appsec.events.users.login.success.usr.login"]=> + string(5) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%s) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_success_v2_06.phpt b/appsec/tests/extension/track_user_login_success_v2_06.phpt index 9260f1f4397..a8019988c91 100644 --- a/appsec/tests/extension/track_user_login_success_v2_06.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_06.phpt @@ -11,23 +11,27 @@ ddtrace_version_at_least('0.85.0'); 'metakey1' => 'meta value' ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(7) { - ["runtime-id"]=> - string(%d) %s - ["appsec.events.users.login.success.usr.login"]=> - string(%d) "login" - ["appsec.events.users.login.success.track"]=> - string(%d) "true" +array(8) { ["_dd.appsec.events.users.login.success.sdk"]=> string(%d) "true" - ["appsec.events.users.login.success.metakey1"]=> - string(%d) "meta value" - ["_dd.p.ts"]=> - string(2) "02" ["_dd.p.dm"]=> string(2) "-5" + ["_dd.p.ts"]=> + string(2) "02" + ["appsec.events.users.login.success.metakey1"]=> + string(%d) "meta value" + ["appsec.events.users.login.success.track"]=> + string(%d) "true" + ["appsec.events.users.login.success.usr.login"]=> + string(%d) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_success_v2_06_appsec_disabled.phpt b/appsec/tests/extension/track_user_login_success_v2_06_appsec_disabled.phpt index a6e28759222..d4a875f4446 100644 --- a/appsec/tests/extension/track_user_login_success_v2_06_appsec_disabled.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_06_appsec_disabled.phpt @@ -13,19 +13,23 @@ ddtrace_version_at_least('0.85.0'); 'metakey1' => 'meta value' ]); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(5) { - ["runtime-id"]=> - string(%d) %s - ["appsec.events.users.login.success.usr.login"]=> - string(%d) "login" - ["appsec.events.users.login.success.track"]=> - string(%d) "true" +array(6) { ["_dd.appsec.events.users.login.success.sdk"]=> string(%d) "true" ["appsec.events.users.login.success.metakey1"]=> string(%d) "meta value" + ["appsec.events.users.login.success.track"]=> + string(%d) "true" + ["appsec.events.users.login.success.usr.login"]=> + string(%d) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_success_v2_07.phpt b/appsec/tests/extension/track_user_login_success_v2_07.phpt index 5643b006a0a..65659682c28 100644 --- a/appsec/tests/extension/track_user_login_success_v2_07.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_07.phpt @@ -9,21 +9,25 @@ include __DIR__ . '/inc/ddtrace_version.php'; ddtrace_version_at_least('0.85.0'); \datadog\appsec\v2\track_user_login_success("login"); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(6) { - ["runtime-id"]=> - string(%d) %s - ["appsec.events.users.login.success.usr.login"]=> - string(%d) "login" - ["appsec.events.users.login.success.track"]=> - string(%d) "true" +array(7) { ["_dd.appsec.events.users.login.success.sdk"]=> string(%d) "true" - ["_dd.p.ts"]=> - string(2) "02" ["_dd.p.dm"]=> string(2) "-5" + ["_dd.p.ts"]=> + string(2) "02" + ["appsec.events.users.login.success.track"]=> + string(%d) "true" + ["appsec.events.users.login.success.usr.login"]=> + string(%d) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_login_success_v2_07_appsec_disabled.phpt b/appsec/tests/extension/track_user_login_success_v2_07_appsec_disabled.phpt index 2aca21ae4b4..9f50aee6670 100644 --- a/appsec/tests/extension/track_user_login_success_v2_07_appsec_disabled.phpt +++ b/appsec/tests/extension/track_user_login_success_v2_07_appsec_disabled.phpt @@ -11,17 +11,21 @@ include __DIR__ . '/inc/ddtrace_version.php'; ddtrace_version_at_least('0.85.0'); \datadog\appsec\v2\track_user_login_success("login"); $root = \DDTrace\root_span(); -var_dump($root->meta); +$attributes = $root->attributes; +ksort($attributes); +var_dump($attributes); ?> --EXPECTF-- -array(4) { - ["runtime-id"]=> - string(%d) %s - ["appsec.events.users.login.success.usr.login"]=> - string(%d) "login" - ["appsec.events.users.login.success.track"]=> - string(%d) "true" +array(5) { ["_dd.appsec.events.users.login.success.sdk"]=> string(%d) "true" + ["appsec.events.users.login.success.track"]=> + string(%d) "true" + ["appsec.events.users.login.success.usr.login"]=> + string(%d) "login" + ["process_id"]=> + int(%d) + ["runtime-id"]=> + string(%d) %s } \ No newline at end of file diff --git a/appsec/tests/extension/track_user_signup_event.phpt b/appsec/tests/extension/track_user_signup_event.phpt index 879f2cfbffd..6f14e553e47 100644 --- a/appsec/tests/extension/track_user_signup_event.phpt +++ b/appsec/tests/extension/track_user_signup_event.phpt @@ -4,7 +4,7 @@ Track a user signup event and verify the tags in the root span DD_APPSEC_ENABLED=1 --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.signup.usr.id] => sdkID - [appsec.events.users.signup.usr.login] => sdkID + [_dd.appsec.enabled] => 1 [_dd.appsec.events.users.signup.sdk] => true - [appsec.events.users.signup.value] => something - [appsec.events.users.signup.metadata] => some other metadata + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [_dd.runtime_family] => php [appsec.events.users.signup.email] => noneofyour@business.com + [appsec.events.users.signup.metadata] => some other metadata [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.id] => sdkID + [appsec.events.users.signup.usr.login] => sdkID + [appsec.events.users.signup.value] => something + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 - [_dd.runtime_family] => php -) -root_span_get_metrics(): -Array -( - [%s] => %d - [_dd.appsec.enabled] => 1 ) int(2) diff --git a/appsec/tests/extension/track_user_signup_event_automated_anon_mode.phpt b/appsec/tests/extension/track_user_signup_event_automated_anon_mode.phpt index fd7d9443d07..a2d0e1791ba 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_anon_mode.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_anon_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anon --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.signup.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.events.users.signup.auto.mode] => anonymization - [appsec.events.users.signup.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 + [appsec.events.users.signup.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_signup_event_automated_anon_mode_compat.phpt b/appsec/tests/extension/track_user_signup_event_automated_anon_mode_compat.phpt index 11b72b839eb..5eb7d059793 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_anon_mode_compat.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_anon_mode_compat.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING=safe --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.signup.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.events.users.signup.auto.mode] => anonymization - [appsec.events.users.signup.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 + [appsec.events.users.signup.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_signup_event_automated_anon_mode_full_name.phpt b/appsec/tests/extension/track_user_signup_event_automated_anon_mode_full_name.phpt index 65c58f8d94b..c26824c0d5d 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_anon_mode_full_name.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_anon_mode_full_name.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anonymization --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.signup.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 - [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.events.users.signup.auto.mode] => anonymization - [appsec.events.users.signup.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.appsec.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.id] => anon_b3ddafd7029d645b44fb990eea55b003 + [appsec.events.users.signup.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_signup_event_automated_anon_mode_no_user.phpt b/appsec/tests/extension/track_user_signup_event_automated_anon_mode_no_user.phpt index 111fcbe2b7c..d9785c7e52e 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_anon_mode_no_user.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_anon_mode_no_user.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=anon --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s [_dd.appsec.events.users.signup.auto.mode] => anonymization - [appsec.events.users.signup.usr.login] => anon_428821350e9691491f616b754cd8315f [_dd.appsec.usr.login] => anon_428821350e9691491f616b754cd8315f + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.login] => anon_428821350e9691491f616b754cd8315f + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_signup_event_automated_default_mode.phpt b/appsec/tests/extension/track_user_signup_event_automated_default_mode.phpt index b98994b6205..8c7812da915 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_default_mode.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_default_mode.phpt @@ -4,7 +4,7 @@ Track automated user signup event without specifying a mode and verify the tags DD_APPSEC_ENABLED=1 --FILE-- --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.signup.usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.signup.auto.mode] => identification - [appsec.events.users.signup.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.id] => automatedID + [appsec.events.users.signup.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_signup_event_automated_disabled_config.phpt b/appsec/tests/extension/track_user_signup_event_automated_disabled_config.phpt index 81444c3c051..11e7e603179 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_disabled_config.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_disabled_config.phpt @@ -6,7 +6,7 @@ DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING_ENABLED=0 --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_user_signup_event_automated_disabled_mode.phpt b/appsec/tests/extension/track_user_signup_event_automated_disabled_mode.phpt index 5f43bfe26ef..d8cb4af3414 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_disabled_mode.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_disabled_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=disabled --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_user_signup_event_automated_empty_user.phpt b/appsec/tests/extension/track_user_signup_event_automated_empty_user.phpt index a2fa180c498..2f156493e3b 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_empty_user.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_empty_user.phpt @@ -7,7 +7,7 @@ datadog.appsec.log_level=debug DD_APPSEC_ENABLED=1 --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s [_dd.appsec.events.users.signup.auto.mode] => identification - [appsec.events.users.signup.usr.login] => login [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_signup_event_automated_ident_mode.phpt b/appsec/tests/extension/track_user_signup_event_automated_ident_mode.phpt index 56200b7ff6d..4b22b664efe 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_ident_mode.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_ident_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=ident --FILE-- 'some@email.com']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.signup.usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.signup.auto.mode] => identification - [appsec.events.users.signup.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.id] => automatedID + [appsec.events.users.signup.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_signup_event_automated_ident_mode_compat.phpt b/appsec/tests/extension/track_user_signup_event_automated_ident_mode_compat.phpt index 248373ff906..d584054ebc6 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_ident_mode_compat.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_ident_mode_compat.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING=extended --FILE-- 'some@email.com']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.signup.usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.signup.auto.mode] => identification - [appsec.events.users.signup.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.id] => automatedID + [appsec.events.users.signup.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_signup_event_automated_ident_mode_full_name.phpt b/appsec/tests/extension/track_user_signup_event_automated_ident_mode_full_name.phpt index f8ab4c0f689..dc8e2cd4f20 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_ident_mode_full_name.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_ident_mode_full_name.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=identification --FILE-- 'some@email.com']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.signup.usr.id] => automatedID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.signup.auto.mode] => identification - [appsec.events.users.signup.usr.login] => login + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.id] => automatedID + [appsec.events.users.signup.usr.login] => login + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 ) diff --git a/appsec/tests/extension/track_user_signup_event_automated_invalid_mode.phpt b/appsec/tests/extension/track_user_signup_event_automated_invalid_mode.phpt index d3441005056..2b590341600 100644 --- a/appsec/tests/extension/track_user_signup_event_automated_invalid_mode.phpt +++ b/appsec/tests/extension/track_user_signup_event_automated_invalid_mode.phpt @@ -5,7 +5,7 @@ DD_APPSEC_ENABLED=1 DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE=invalid --FILE-- "noneofyour@business.com" ]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- %AWarning:%a[ddappsec] Unknown user collection mode: invalid%a -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s ) diff --git a/appsec/tests/extension/track_user_signup_event_sdk_takes_priority.phpt b/appsec/tests/extension/track_user_signup_event_sdk_takes_priority.phpt index fd6d89a53fd..48dd9230c9d 100644 --- a/appsec/tests/extension/track_user_signup_event_sdk_takes_priority.phpt +++ b/appsec/tests/extension/track_user_signup_event_sdk_takes_priority.phpt @@ -4,7 +4,7 @@ When values are set with automated event and with sdk, SDK takes priority DD_APPSEC_ENABLED=1 --FILE-- "something-from-sdk"]); track_user_signup_event_automated('test', "login", "automatedID", ["value" => "something-from-automated"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s + [_dd.appsec.events.users.signup.auto.mode] => identification + [_dd.appsec.events.users.signup.sdk] => true + [_dd.appsec.usr.id] => automatedID + [_dd.appsec.usr.login] => login + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [appsec.events.users.signup.track] => true [appsec.events.users.signup.usr.id] => sdkID [appsec.events.users.signup.usr.login] => sdkID - [_dd.appsec.events.users.signup.sdk] => true [appsec.events.users.signup.value] => something-from-sdk - [appsec.events.users.signup.track] => true + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 - [_dd.appsec.usr.id] => automatedID - [_dd.appsec.events.users.signup.auto.mode] => identification - [_dd.appsec.usr.login] => login ) diff --git a/appsec/tests/extension/track_user_signup_event_sdk_takes_priority_02.phpt b/appsec/tests/extension/track_user_signup_event_sdk_takes_priority_02.phpt index 86489edecba..e4ccf29f1a2 100644 --- a/appsec/tests/extension/track_user_signup_event_sdk_takes_priority_02.phpt +++ b/appsec/tests/extension/track_user_signup_event_sdk_takes_priority_02.phpt @@ -4,7 +4,7 @@ When values are set with automated event and with sdk, SDK takes priority DD_APPSEC_ENABLED=1 --FILE-- "something-from-automated"]); track_user_signup_event("sdkID", ["value" => "something-from-sdk"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.signup.usr.id] => sdkID - [_dd.appsec.usr.id] => automatedID [_dd.appsec.events.users.signup.auto.mode] => identification - [appsec.events.users.signup.usr.login] => sdkID + [_dd.appsec.events.users.signup.sdk] => true + [_dd.appsec.usr.id] => automatedID [_dd.appsec.usr.login] => login - [appsec.events.users.signup.track] => true - [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 [_dd.p.dm] => -5 - [_dd.appsec.events.users.signup.sdk] => true + [_dd.p.ts] => 02 + [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.id] => sdkID + [appsec.events.users.signup.usr.login] => sdkID [appsec.events.users.signup.value] => something-from-sdk + [process_id] => %d + [runtime-id] => %s + [server.business_logic.users.signup] => null ) diff --git a/appsec/tests/extension/track_user_signup_event_sdk_takes_priority_03.phpt b/appsec/tests/extension/track_user_signup_event_sdk_takes_priority_03.phpt index d26a5e56176..cad68c2c191 100644 --- a/appsec/tests/extension/track_user_signup_event_sdk_takes_priority_03.phpt +++ b/appsec/tests/extension/track_user_signup_event_sdk_takes_priority_03.phpt @@ -4,7 +4,7 @@ Latest sdk values take priority DD_APPSEC_ENABLED=1 --FILE-- "something-from-sdk"]); track_user_signup_event("OtherSdkID", ["value" => "something-from-sdk-2"]); track_user_signup_event_automated('test', "OtherLogin", "OtherAutomatedID", ["value" => "something-from-automated-2"]); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.signup.usr.id] => OtherSdkID - [_dd.appsec.usr.id] => OtherAutomatedID [_dd.appsec.events.users.signup.auto.mode] => identification - [appsec.events.users.signup.usr.login] => OtherSdkID + [_dd.appsec.events.users.signup.sdk] => true + [_dd.appsec.usr.id] => OtherAutomatedID [_dd.appsec.usr.login] => OtherLogin - [appsec.events.users.signup.track] => true - [server.business_logic.users.signup] => null - [_dd.p.ts] => 02 [_dd.p.dm] => -5 - [_dd.appsec.events.users.signup.sdk] => true + [_dd.p.ts] => 02 + [appsec.events.users.signup.track] => true + [appsec.events.users.signup.usr.id] => OtherSdkID + [appsec.events.users.signup.usr.login] => OtherSdkID [appsec.events.users.signup.value] => something-from-sdk-2 + [process_id] => %d + [runtime-id] => %s + [server.business_logic.users.signup] => null ) diff --git a/appsec/tests/extension/user_tracking_block_from_login_failure_v2.phpt b/appsec/tests/extension/user_tracking_block_from_login_failure_v2.phpt index 33c812b80d8..5f51b8cdcd6 100644 --- a/appsec/tests/extension/user_tracking_block_from_login_failure_v2.phpt +++ b/appsec/tests/extension/user_tracking_block_from_login_failure_v2.phpt @@ -4,7 +4,7 @@ Block from user v2 login failure event DD_APPSEC_ENABLED=1 --FILE-- get_commands(); // Ignore $c = $helper->get_commands(); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); $helper->finished_with_commands(); ?> --EXPECTF-- -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.failure.usr.login] => some login - [appsec.events.users.login.failure.usr.exists] => false - [appsec.events.users.login.failure.track] => true [_dd.appsec.events.users.login.failure.sdk] => true - [appsec.events.users.login.failure.value] => something - [appsec.events.users.login.failure.metadata] => some other metadata - [appsec.events.users.login.failure.email] => noneofyour@business.com - [_dd.p.ts] => 02 [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [appsec.events.users.login.failure.email] => noneofyour@business.com + [appsec.events.users.login.failure.metadata] => some other metadata + [appsec.events.users.login.failure.track] => true + [appsec.events.users.login.failure.usr.exists] => false + [appsec.events.users.login.failure.usr.login] => some login + [appsec.events.users.login.failure.value] => something + [process_id] => %d + [runtime-id] => %s ) \ No newline at end of file diff --git a/appsec/tests/extension/user_tracking_do_nothing_from_login_success.phpt b/appsec/tests/extension/user_tracking_do_nothing_from_login_success.phpt index 04c53b0becb..c5b78b5ca31 100644 --- a/appsec/tests/extension/user_tracking_do_nothing_from_login_success.phpt +++ b/appsec/tests/extension/user_tracking_do_nothing_from_login_success.phpt @@ -4,7 +4,7 @@ Don't block or redirect from user login success event DD_APPSEC_ENABLED=1 --FILE-- get_commands(); echo "usr.id:\n"; var_dump($c[0][1][0]['usr.id']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); $helper->finished_with_commands(); ?> @@ -41,18 +43,19 @@ $helper->finished_with_commands(); Deprecated: Function datadog\appsec\track_user_login_success_event() is deprecated in %s on line %d usr.id: string(5) "Admin" -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [usr.id] => Admin - [appsec.events.users.login.success.usr.login] => Admin [_dd.appsec.events.users.login.success.sdk] => true - [appsec.events.users.login.success.value] => something - [appsec.events.users.login.success.metadata] => some other metadata + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 [appsec.events.users.login.success.email] => noneofyour@business.com + [appsec.events.users.login.success.metadata] => some other metadata [appsec.events.users.login.success.track] => true + [appsec.events.users.login.success.usr.login] => Admin + [appsec.events.users.login.success.value] => something + [process_id] => %d + [runtime-id] => %s [server.business_logic.users.login.success] => null - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 + [usr.id] => Admin ) diff --git a/appsec/tests/extension/user_tracking_do_nothing_from_login_success_v2.phpt b/appsec/tests/extension/user_tracking_do_nothing_from_login_success_v2.phpt index 0a1e39f84d2..6f989b81245 100644 --- a/appsec/tests/extension/user_tracking_do_nothing_from_login_success_v2.phpt +++ b/appsec/tests/extension/user_tracking_do_nothing_from_login_success_v2.phpt @@ -4,7 +4,7 @@ Don't block or redirect from v2 user login success event DD_APPSEC_ENABLED=1 --FILE-- get_commands(); echo "usr.id:\n"; var_dump($c[0][1][0]['usr.id']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); $helper->finished_with_commands(); ?> --EXPECTF-- usr.id: string(7) "some id" -root_span_get_meta(): +root_span_get_attributes(): Array ( - [runtime-id] => %s - [appsec.events.users.login.success.usr.login] => some login - [appsec.events.users.login.success.track] => true [_dd.appsec.events.users.login.success.sdk] => true [_dd.appsec.user.collection_mode] => sdk + [_dd.p.dm] => -5 + [_dd.p.ts] => 02 + [appsec.events.users.login.success.email] => noneofyour@business.com + [appsec.events.users.login.success.metadata] => some other metadata + [appsec.events.users.login.success.track] => true [appsec.events.users.login.success.usr.id] => some id + [appsec.events.users.login.success.usr.login] => some login [appsec.events.users.login.success.value] => something - [appsec.events.users.login.success.metadata] => some other metadata - [appsec.events.users.login.success.email] => noneofyour@business.com + [process_id] => %d + [runtime-id] => %s + [usr.email] => noneofyour@business.com [usr.id] => some id - [usr.value] => something [usr.metadata] => some other metadata - [usr.email] => noneofyour@business.com - [_dd.p.ts] => 02 - [_dd.p.dm] => -5 + [usr.value] => something ) diff --git a/appsec/tests/extension/user_tracking_do_nothing_from_set_user.phpt b/appsec/tests/extension/user_tracking_do_nothing_from_set_user.phpt index 1481d1819bd..12709133f12 100644 --- a/appsec/tests/extension/user_tracking_do_nothing_from_set_user.phpt +++ b/appsec/tests/extension/user_tracking_do_nothing_from_set_user.phpt @@ -4,7 +4,7 @@ Don't block or redirect from DDTrace\set_user DD_APPSEC_ENABLED=1 --FILE-- get_commands(); echo "usr.id:\n"; var_dump($c[0][1][0]['usr.id']); -echo "root_span_get_meta():\n"; -print_r(root_span_get_meta()); +echo "root_span_get_attributes():\n"; +$attributes = root_span_get_attributes(); +ksort($attributes); +print_r($attributes); $helper->finished_with_commands(); ?> --EXPECTF-- usr.id: string(5) "Admin" -root_span_get_meta(): +root_span_get_attributes(): Array ( + [process_id] => %d [runtime-id] => %s + [usr.email] => noneofyour@business.com [usr.id] => Admin - [usr.value] => something [usr.metadata] => some other metadata - [usr.email] => noneofyour@business.com + [usr.value] => something ) diff --git a/appsec/tests/extension/user_tracking_redirect_from_login_success.phpt b/appsec/tests/extension/user_tracking_redirect_from_login_success.phpt index 3f3913aac86..800da39e2fa 100644 --- a/appsec/tests/extension/user_tracking_redirect_from_login_success.phpt +++ b/appsec/tests/extension/user_tracking_redirect_from_login_success.phpt @@ -4,7 +4,7 @@ Redirect from a user login success event DD_APPSEC_ENABLED=1 --FILE-- = 1.0 - // root span component now defaults to the SAPI name (fpm-fcgi here); - // this trait is only mixed into Apache2FpmTests - assert 'framework:fpm-fcgi' in metric.tags + // web root spans default their component to "web" + assert 'framework:web' in metric.tags } } finally { resetFpm() diff --git a/appsec/tests/integration/src/test/www/base/public/api_security.php b/appsec/tests/integration/src/test/www/base/public/api_security.php index c32148bae61..d712633d841 100644 --- a/appsec/tests/integration/src/test/www/base/public/api_security.php +++ b/appsec/tests/integration/src/test/www/base/public/api_security.php @@ -1,7 +1,7 @@ meta["http.route"] = $_GET["route"] ?: "/foo/bar"; +$rootSpan->attributes["http.route"] = $_GET["route"] ?: "/foo/bar"; header("Content-Type: application/json"); diff --git a/appsec/tests/integration/src/test/www/base/public/endpoint_fallback.php b/appsec/tests/integration/src/test/www/base/public/endpoint_fallback.php index e6dea7b9616..670db099d61 100644 --- a/appsec/tests/integration/src/test/www/base/public/endpoint_fallback.php +++ b/appsec/tests/integration/src/test/www/base/public/endpoint_fallback.php @@ -5,8 +5,8 @@ switch ($case) { case 'with_route': // Test case: http.route is present - should use it for sampling - $rootSpan->meta["http.route"] = "/users/{id}/profile"; - $rootSpan->meta["http.method"] = "GET"; + $rootSpan->attributes["http.route"] = "/users/{id}/profile"; + $rootSpan->attributes["http.method"] = "GET"; header("Content-Type: application/json"); http_response_code(200); @@ -21,8 +21,8 @@ case 'with_endpoint': // Test case: http.route is absent, http.endpoint is present - should use http.endpoint for sampling // Do NOT set http.route - $rootSpan->meta["http.endpoint"] = "/api/products/{param:int}"; - $rootSpan->meta["http.method"] = "GET"; + $rootSpan->attributes["http.endpoint"] = "/api/products/{param:int}"; + $rootSpan->attributes["http.method"] = "GET"; header("Content-Type: application/json"); http_response_code(200); @@ -37,8 +37,8 @@ case '404': // Test case: http.route is absent, http.endpoint is present, but status is 404 - should NOT sample // Do NOT set http.route - $rootSpan->meta["http.endpoint"] = "/api/notfound/{param:int}"; - $rootSpan->meta["http.method"] = "GET"; + $rootSpan->attributes["http.endpoint"] = "/api/notfound/{param:int}"; + $rootSpan->attributes["http.method"] = "GET"; header("Content-Type: application/json"); http_response_code(404); @@ -55,8 +55,8 @@ // The endpoint should be computed but NOT added as a tag on the span // Do NOT set http.route or http.endpoint // Set http.url so endpoint can be computed - $rootSpan->meta["http.url"] = "http://localhost:8080/endpoint_fallback_computed/users/123/orders/456"; - $rootSpan->meta["http.method"] = "GET"; + $rootSpan->attributes["http.url"] = "http://localhost:8080/endpoint_fallback_computed/users/123/orders/456"; + $rootSpan->attributes["http.method"] = "GET"; header("Content-Type: application/json"); http_response_code(200); @@ -69,10 +69,10 @@ break; case 'missing_route': - unset($rootSpan->meta["http.route"]); - unset($rootSpan->meta["http.endpoint"]); - unset($rootSpan->meta["http.url"]); - $rootSpan->meta["http.method"] = "GET"; + unset($rootSpan->attributes["http.route"]); + unset($rootSpan->attributes["http.endpoint"]); + unset($rootSpan->attributes["http.url"]); + $rootSpan->attributes["http.method"] = "GET"; header("Content-Type: application/json"); http_response_code(200); diff --git a/components-rs/common.h b/components-rs/common.h index 84f9ca34a77..95c0402fa2b 100644 --- a/components-rs/common.h +++ b/components-rs/common.h @@ -1239,11 +1239,15 @@ typedef struct ddog_ContextKey { enum ddog_MetricType _1; } ddog_ContextKey; +typedef struct ddog_TracerPayloadBytes ddog_TracerPayloadBytes; +typedef struct ddog_TraceChunkBytes ddog_TraceChunkBytes; typedef struct ddog_SpanBytes ddog_SpanBytes; typedef struct ddog_SpanLinkBytes ddog_SpanLinkBytes; typedef struct ddog_SpanEventBytes ddog_SpanEventBytes; typedef struct ddog_AttributeAnyValueBytes ddog_AttributeAnyValueBytes; typedef struct ddog_AttributeArrayValueBytes ddog_AttributeArrayValueBytes; +typedef struct ddog_Attributes ddog_Attributes; +typedef struct ddog_AttrValue ddog_AttrValue; /** @@ -1322,23 +1326,6 @@ typedef struct ddog_AttrList ddog_AttrList; */ typedef struct ddog_AttrMap ddog_AttrMap; -/** - * Opaque handle to one attribute value inside an [`Attributes`] map or a list. - */ -typedef struct ddog_AttrValue ddog_AttrValue; - -/** - * Opaque handle to an attribute map: the payload's, a chunk's, span's, link's or event's - * (`ddog_*_get_attributes`), or an owned nested map's ([`ddog_attr_map_get_attributes`]). - */ -typedef struct ddog_Attributes ddog_Attributes; - -/** - * A chunk node in the builder: its own heap allocation, so a `*mut ChunkNode` handed to C stays - * valid across sibling chunk pushes. Its spans live as separate `Box` allocations. - */ -typedef struct ddog_ChunkNode ddog_ChunkNode; - /** * Fundamental configuration of the RC client, which always must be set. */ @@ -1373,19 +1360,6 @@ typedef struct ddog_RuntimeMetadata ddog_RuntimeMetadata; typedef struct ddog_ShmHandle ddog_ShmHandle; -/** - * A span node in the builder: its own heap allocation, so a held `*mut SpanNode` stays valid - * across sibling span pushes into the same chunk (the inferred-span case). Links/events are - * likewise separate `Box` allocations. - */ -typedef struct ddog_SpanNode ddog_SpanNode; - -/** - * Builds a native V1 [`TracerPayloadBytes`] holding readable strings. Each node is its own heap - * allocation (see the module docs); the builder owns the top-level chunk pointers. - */ -typedef struct ddog_TracerPayloadV1Builder ddog_TracerPayloadV1Builder; - typedef struct ddog_NativeFile { struct ddog_PlatformHandle_File *handle; } ddog_NativeFile; diff --git a/components-rs/datadog.h b/components-rs/datadog.h index 23eaa6c4327..cec183a5088 100644 --- a/components-rs/datadog.h +++ b/components-rs/datadog.h @@ -149,62 +149,23 @@ void ddog_init_span_func(void (*free_func)(ddog_OwnedZendString), void (*addref_func)(struct _zend_string*), ddog_OwnedZendString (*init_func)(ddog_CharSlice)); -/** - * # Safety - * `span` must be a live span node pointer from `ddog_new_span` (every `*_zstr` span setter). - */ -void ddog_set_span_service_zstr(ddog_SpanNode *span, struct _zend_string *str); +void ddog_set_span_service_zstr(ddog_SpanBytes *span, struct _zend_string *str); -/** - * # Safety - * See [`ddog_set_span_service_zstr`]. - */ -void ddog_set_span_name_zstr(ddog_SpanNode *span, struct _zend_string *str); +void ddog_set_span_name_zstr(ddog_SpanBytes *span, struct _zend_string *str); -/** - * # Safety - * See [`ddog_set_span_service_zstr`]. - */ -void ddog_set_span_resource_zstr(ddog_SpanNode *span, struct _zend_string *str); - -/** - * # Safety - * See [`ddog_set_span_service_zstr`]. - */ -void ddog_set_span_type_zstr(ddog_SpanNode *span, struct _zend_string *str); +void ddog_set_span_resource_zstr(ddog_SpanBytes *span, struct _zend_string *str); -/** - * String attribute under a static C literal key. - * - * # Safety - * `attrs` must be a live `Attributes` handle and `key` a static NUL-terminated string (applies - * to every attribute adder below). - */ -void ddog_attributes_add_lit(ddog_Attributes *attrs, const char *key, ddog_CharSlice value); +void ddog_set_span_type_zstr(ddog_SpanBytes *span, struct _zend_string *str); /** * String attribute sharing both zend strings (zero-copy). - * - * # Safety - * See [`ddog_attributes_add_lit`]. */ void ddog_attributes_add_zstr(ddog_Attributes *attrs, struct _zend_string *key, struct _zend_string *value); -/** - * Double attribute under a static C literal key. - * - * # Safety - * See [`ddog_attributes_add_lit`]. - */ -void ddog_attributes_add_double_lit(ddog_Attributes *attrs, const char *key, double value); - /** * Double attribute under a shared zend string key (zero-copy). - * - * # Safety - * See [`ddog_attributes_add_lit`]. */ void ddog_attributes_add_double_zstr(ddog_Attributes *attrs, struct _zend_string *key, diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index dc7409516b0..45944af1ff7 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -503,18 +503,18 @@ void ddog_send_traces_to_sidecar(ddog_TracesBytes *traces, * from `parameters.tracer_headers_tags` and `metadata`; lang_interpreter/lang_vendor go as * headers. */ -void ddog_send_traces_to_sidecar_v1(struct ddog_TracerPayloadV1Builder *builder, +void ddog_send_traces_to_sidecar_v1(ddog_TracerPayloadBytes *builder, struct ddog_SenderParameters *parameters, const struct ddog_TracerMetadataV1 *metadata); /** * Downgrades a native V1 builder to the in-memory v0.4 collection for the in-process `coms.c` - * sender (PHP <= 8.2). Consumes `builder`. Returns the collection (not one whole-payload - * CharSlice) so `auto_flush` can frame each trace individually; a single CharSlice would drop - * extra traces of a multi-trace payload. Empty collection on error; free with + * sender (DD_TRACE_SIDECAR_TRACE_SENDER=0). Consumes `builder`. Returns the collection (not one + * whole-payload CharSlice) so `auto_flush` can frame each trace individually; a single CharSlice + * would drop extra traces of a multi-trace payload. Empty collection on error; free with * [`crate::span_v04::ddog_free_traces`]. */ -ddog_TracesBytes *ddog_downgrade_v1_builder_to_v04_traces(struct ddog_TracerPayloadV1Builder *builder); +ddog_TracesBytes *ddog_downgrade_v1_builder_to_v04_traces(ddog_TracerPayloadBytes *builder); /** * Drops the agent info reader. @@ -675,213 +675,98 @@ int32_t ddog_sidecar_signal_flush_run(const struct ddog_SignalFlush *flush); * 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); +ddog_TracerPayloadBytes *ddog_v1_new_builder(void); /** * Frees a V1 payload builder. */ -void ddog_v1_free_builder(struct ddog_TracerPayloadV1Builder *_builder); +void ddog_v1_free_builder(ddog_TracerPayloadBytes *_builder); /** * Sets the payload `env` / `app_version` / `hostname` fields (empty = unset). */ -void ddog_set_payload_metadata(struct ddog_TracerPayloadV1Builder *builder, +void ddog_set_payload_metadata(ddog_TracerPayloadBytes *builder, ddog_CharSlice env, ddog_CharSlice app_version, ddog_CharSlice hostname); /** - * Appends a chunk carrying the 128-bit trace id (high/low halves), returning its node pointer. + * Appends a chunk carrying the 128-bit trace id (high/low halves). */ -struct ddog_ChunkNode *ddog_new_chunk(struct ddog_TracerPayloadV1Builder *builder, - uint64_t trace_id_high, - uint64_t trace_id_low); +ddog_TraceChunkBytes *ddog_new_chunk(ddog_TracerPayloadBytes *builder, + uint64_t trace_id_high, + uint64_t trace_id_low); /** * Number of spans already in `chunk`. - * - * # Safety - * `chunk` must be a live chunk node pointer from [`ddog_new_chunk`] (applies to every chunk fn). */ -uintptr_t ddog_chunk_span_count(struct ddog_ChunkNode *chunk); +uintptr_t ddog_chunk_span_count(const ddog_TraceChunkBytes *chunk); /** - * Appends an empty span to `chunk`, returning its node pointer. - * - * # Safety - * See [`ddog_chunk_span_count`]. + * Appends an empty span to `chunk`. */ -struct ddog_SpanNode *ddog_new_span(struct ddog_ChunkNode *chunk); +ddog_SpanBytes *ddog_new_span(ddog_TraceChunkBytes *chunk); /** - * Appends an empty link to `span`, returning its node pointer. - * - * # Safety - * `span` must be a live span node pointer from [`ddog_new_span`] (applies to every span fn). + * Appends an empty link to `span`. */ -ddog_SpanLinkBytes *ddog_new_link(struct ddog_SpanNode *span); +ddog_SpanLinkBytes *ddog_new_link(ddog_SpanBytes *span); /** - * Appends an empty event to `span`, returning its node pointer. - * - * # Safety - * See [`ddog_new_link`]. + * Appends an empty event to `span`. */ -ddog_SpanEventBytes *ddog_new_event(struct ddog_SpanNode *span); +ddog_SpanEventBytes *ddog_new_event(ddog_SpanBytes *span); -/** - * # Safety - * See [`ddog_new_link`] (applies to every `ddog_span_set_*` / `ddog_set_span_*`). - */ -void ddog_span_set_id(struct ddog_SpanNode *span, uint64_t value); +void ddog_span_set_id(ddog_SpanBytes *span, uint64_t value); -/** - * # Safety - * See [`ddog_span_set_id`]. - */ -void ddog_span_set_parent_id(struct ddog_SpanNode *span, uint64_t value); +void ddog_span_set_parent_id(ddog_SpanBytes *span, uint64_t value); -/** - * # Safety - * See [`ddog_span_set_id`]. - */ -void ddog_span_set_start(struct ddog_SpanNode *span, int64_t value); +void ddog_span_set_start(ddog_SpanBytes *span, int64_t value); -/** - * # Safety - * See [`ddog_span_set_id`]. - */ -void ddog_span_set_duration(struct ddog_SpanNode *span, int64_t value); +void ddog_span_set_duration(ddog_SpanBytes *span, int64_t value); -/** - * # Safety - * See [`ddog_span_set_id`]. - */ -void ddog_span_set_error(struct ddog_SpanNode *span, bool error); +void ddog_span_set_error(ddog_SpanBytes *span, bool error); /** * Reads the span error flag (e.g. to mirror it onto an inferred span). - * - * # Safety - * See [`ddog_new_link`]. */ -bool ddog_span_get_error(struct ddog_SpanNode *span); +bool ddog_span_get_error(const ddog_SpanBytes *span); -/** - * # Safety - * See [`ddog_span_get_error`]. - */ -void ddog_set_span_service(struct ddog_SpanNode *span, ddog_CharSlice value); +void ddog_set_span_service(ddog_SpanBytes *span, ddog_CharSlice value); -/** - * # Safety - * See [`ddog_span_get_error`]. - */ -void ddog_set_span_name(struct ddog_SpanNode *span, ddog_CharSlice value); +void ddog_set_span_name(ddog_SpanBytes *span, ddog_CharSlice value); -/** - * # Safety - * See [`ddog_span_get_error`]. - */ -void ddog_set_span_resource(struct ddog_SpanNode *span, ddog_CharSlice value); +void ddog_set_span_resource(ddog_SpanBytes *span, ddog_CharSlice value); -/** - * # Safety - * See [`ddog_span_get_error`]. - */ -void ddog_set_span_type(struct ddog_SpanNode *span, ddog_CharSlice value); +void ddog_set_span_type(ddog_SpanBytes *span, ddog_CharSlice value); -/** - * # Safety - * See [`ddog_span_get_error`]. - */ -void ddog_set_span_env(struct ddog_SpanNode *span, ddog_CharSlice value); +void ddog_set_span_env(ddog_SpanBytes *span, ddog_CharSlice value); -/** - * # Safety - * See [`ddog_span_get_error`]. - */ -void ddog_set_span_version(struct ddog_SpanNode *span, ddog_CharSlice value); +void ddog_set_span_version(ddog_SpanBytes *span, ddog_CharSlice value); -/** - * # Safety - * See [`ddog_span_get_error`]. - */ -void ddog_set_span_component(struct ddog_SpanNode *span, ddog_CharSlice value); +void ddog_set_span_component(ddog_SpanBytes *span, ddog_CharSlice value); /** * Sets the span kind from an OTEL wire value (unset/unknown → Unspecified). - * - * # Safety - * See [`ddog_new_link`]. */ -void ddog_set_span_kind(struct ddog_SpanNode *span, uint32_t kind); +void ddog_set_span_kind(ddog_SpanBytes *span, uint32_t kind); -/** - * Sets the span kind from a v0.4 `span.kind` string. Returns `false` for a non-canonical kind, - * which has no wire slot, so the caller keeps it as a plain attribute. - * - * # Safety - * See [`ddog_new_link`]. - */ -bool ddog_set_span_kind_str(struct ddog_SpanNode *span, ddog_CharSlice value); +void ddog_set_chunk_origin(ddog_TraceChunkBytes *chunk, ddog_CharSlice origin); -/** - * # Safety - * See [`ddog_chunk_span_count`] (applies to every `ddog_set_chunk_*`). - */ -void ddog_set_chunk_origin(struct ddog_ChunkNode *chunk, ddog_CharSlice origin); - -/** - * # Safety - * See [`ddog_set_chunk_origin`]. - */ -void ddog_set_chunk_sampling_priority(struct ddog_ChunkNode *chunk, int32_t priority); +void ddog_set_chunk_sampling_priority(ddog_TraceChunkBytes *chunk, int32_t priority); -/** - * # Safety - * See [`ddog_set_chunk_origin`]. - */ -void ddog_set_chunk_sampling_mechanism(struct ddog_ChunkNode *chunk, uint32_t mechanism); +void ddog_set_chunk_sampling_mechanism(ddog_TraceChunkBytes *chunk, uint32_t mechanism); -/** - * # Safety - * `link` must be a live link node pointer from [`ddog_new_link`] (applies to every - * `ddog_link_*`). - */ void ddog_link_set_trace_id(ddog_SpanLinkBytes *link, uint64_t trace_id_high, uint64_t trace_id_low); -/** - * # Safety - * See [`ddog_link_set_trace_id`]. - */ void ddog_link_set_span_id(ddog_SpanLinkBytes *link, uint64_t value); -/** - * # Safety - * See [`ddog_link_set_trace_id`]. - */ -void ddog_link_set_flags(ddog_SpanLinkBytes *link, uint32_t value); - -/** - * # Safety - * See [`ddog_link_set_trace_id`]. - */ void ddog_link_set_tracestate(ddog_SpanLinkBytes *link, ddog_CharSlice value); -/** - * # Safety - * `event` must be a live event node pointer from [`ddog_new_event`] (applies to every - * `ddog_event_*`). - */ void ddog_event_set_name(ddog_SpanEventBytes *event, ddog_CharSlice value); -/** - * # Safety - * See [`ddog_event_set_name`]. - */ void ddog_event_set_time(ddog_SpanEventBytes *event, uint64_t time_unix_nano); /** @@ -890,99 +775,82 @@ void ddog_event_set_time(ddog_SpanEventBytes *event, uint64_t time_unix_nano); * # Safety * `builder` must be a live builder from [`ddog_v1_new_builder`]. */ -struct ddog_Attributes *ddog_payload_get_attributes(struct ddog_TracerPayloadV1Builder *builder); +ddog_Attributes *ddog_payload_get_attributes(ddog_TracerPayloadBytes *builder); /** * # Safety - * See [`ddog_chunk_span_count`]. + * `chunk` must be a live pointer from [`ddog_new_chunk`] or [`ddog_v1_get_chunk`]. */ -struct ddog_Attributes *ddog_chunk_get_attributes(struct ddog_ChunkNode *chunk); +ddog_Attributes *ddog_chunk_get_attributes(ddog_TraceChunkBytes *chunk); /** * # Safety - * See [`ddog_new_link`]. + * `span` must be a live pointer from [`ddog_new_span`] or [`ddog_v1_get_span`]. */ -struct ddog_Attributes *ddog_span_get_attributes(struct ddog_SpanNode *span); +ddog_Attributes *ddog_span_get_attributes(ddog_SpanBytes *span); /** * # Safety - * See [`ddog_link_set_trace_id`]. + * `link` must be a live pointer from [`ddog_new_link`] or [`ddog_v1_get_link`]. */ -struct ddog_Attributes *ddog_link_get_attributes(ddog_SpanLinkBytes *link); +ddog_Attributes *ddog_link_get_attributes(ddog_SpanLinkBytes *link); /** * # Safety - * See [`ddog_event_set_name`]. + * `event` must be a live pointer from [`ddog_new_event`] or [`ddog_v1_get_event`]. */ -struct ddog_Attributes *ddog_event_get_attributes(ddog_SpanEventBytes *event); +ddog_Attributes *ddog_event_get_attributes(ddog_SpanEventBytes *event); -/** - * # Safety - * `attrs` must be a live [`Attributes`] handle (applies to every `ddog_attributes_add_*`). - */ -void ddog_attributes_add_str(struct ddog_Attributes *attrs, - ddog_CharSlice key, - ddog_CharSlice value); +void ddog_attributes_add_str(ddog_Attributes *attrs, ddog_CharSlice key, ddog_CharSlice value); /** + * String attribute under a static C literal key (not copied). + * * # Safety - * See [`ddog_attributes_add_str`]. + * `key` must be a NUL-terminated string that lives for the rest of the program. */ -void ddog_attributes_add_int(struct ddog_Attributes *attrs, ddog_CharSlice key, int64_t value); +void ddog_attributes_add_lit(ddog_Attributes *attrs, const char *key, ddog_CharSlice value); -/** - * # Safety - * See [`ddog_attributes_add_str`]. - */ -void ddog_attributes_add_double(struct ddog_Attributes *attrs, ddog_CharSlice key, double value); +void ddog_attributes_add_int(ddog_Attributes *attrs, ddog_CharSlice key, int64_t value); + +void ddog_attributes_add_double(ddog_Attributes *attrs, ddog_CharSlice key, double value); /** + * Double attribute under a static C literal key (not copied). + * * # Safety - * See [`ddog_attributes_add_str`]. + * See [`ddog_attributes_add_lit`]. */ -void ddog_attributes_add_bool(struct ddog_Attributes *attrs, ddog_CharSlice key, bool value); +void ddog_attributes_add_double_lit(ddog_Attributes *attrs, const char *key, double value); + +void ddog_attributes_add_bool(ddog_Attributes *attrs, ddog_CharSlice key, bool value); /** * Bytes attribute (v0.4 `meta_struct`), copied verbatim. - * - * # Safety - * See [`ddog_attributes_add_str`]. */ -void ddog_attributes_add_bytes(struct ddog_Attributes *attrs, - ddog_CharSlice key, - ddog_CharSlice value); +void ddog_attributes_add_bytes(ddog_Attributes *attrs, ddog_CharSlice key, ddog_CharSlice value); /** * Sets `attrs[key]` to `list`, which is consumed. - * - * # Safety - * See [`ddog_attributes_add_str`]; `list` must be a live list from [`ddog_attr_list_new`]. */ -void ddog_attributes_add_list(struct ddog_Attributes *attrs, +void ddog_attributes_add_list(ddog_Attributes *attrs, ddog_CharSlice key, struct ddog_AttrList *list); /** - * Sets `attrs[key]` to `map`, which is consumed. - * - * # Safety - * See [`ddog_attributes_add_str`]; `map` must be a live map from [`ddog_attr_map_new`], other than - * the one `attrs` belongs to. + * Sets `attrs[key]` to `map`, which is consumed (it must not be the map `attrs` belongs to). */ -void ddog_attributes_add_map(struct ddog_Attributes *attrs, - ddog_CharSlice key, - struct ddog_AttrMap *map); +void ddog_attributes_add_map(ddog_Attributes *attrs, ddog_CharSlice key, struct ddog_AttrMap *map); /** * Copies the attribute `key` from `from_span` onto `to_span`, returning whether the source had it; * removes it from the source when `delete_source` is set. Type-preserving. * * # Safety - * `from_span`/`to_span` must be live, distinct span node pointers from [`ddog_new_span`]; `key` - * a static NUL-terminated string. + * `from_span`/`to_span` must be distinct; `key` a static NUL-terminated string. */ -bool ddog_transfer_span_attr(struct ddog_SpanNode *from_span, - struct ddog_SpanNode *to_span, +bool ddog_transfer_span_attr(ddog_SpanBytes *from_span, + ddog_SpanBytes *to_span, const char *key, bool delete_source); @@ -998,131 +866,108 @@ struct ddog_AttrMap *ddog_attr_map_new(uintptr_t capacity); /** * The attribute map of an owned nested `map`, filled with the `ddog_attributes_add_*` family. - * - * # Safety - * `map` must be a live map from [`ddog_attr_map_new`]. */ -struct ddog_Attributes *ddog_attr_map_get_attributes(struct ddog_AttrMap *map); +ddog_Attributes *ddog_attr_map_get_attributes(struct ddog_AttrMap *map); -/** - * # Safety - * `list` must be a live list from [`ddog_attr_list_new`] (applies to every `ddog_attr_list_*`); - * a `child` is consumed. - */ void ddog_attr_list_push_str(struct ddog_AttrList *list, ddog_CharSlice value); -/** - * # Safety - * See [`ddog_attr_list_push_str`]. - */ void ddog_attr_list_push_int(struct ddog_AttrList *list, int64_t value); -/** - * # Safety - * See [`ddog_attr_list_push_str`]. - */ void ddog_attr_list_push_double(struct ddog_AttrList *list, double value); -/** - * # Safety - * See [`ddog_attr_list_push_str`]. - */ void ddog_attr_list_push_bool(struct ddog_AttrList *list, bool value); -/** - * # Safety - * See [`ddog_attr_list_push_str`]. - */ void ddog_attr_list_push_bytes(struct ddog_AttrList *list, ddog_CharSlice value); /** - * # Safety - * See [`ddog_attr_list_push_str`]. + * Pushes `child`, which is consumed. */ void ddog_attr_list_push_list(struct ddog_AttrList *list, struct ddog_AttrList *child); /** - * # Safety - * See [`ddog_attr_list_push_str`]. + * Pushes `child`, which is consumed. */ void ddog_attr_list_push_map(struct ddog_AttrList *list, struct ddog_AttrMap *child); -/** - * The builder's chunk node pointers; `len` receives their count. - */ -struct ddog_ChunkNode *const *ddog_v1_get_chunks(const struct ddog_TracerPayloadV1Builder *builder, - uintptr_t *len); +ddog_CharSlice ddog_v1_get_payload_env(const ddog_TracerPayloadBytes *builder); + +ddog_CharSlice ddog_v1_get_payload_app_version(const ddog_TracerPayloadBytes *builder); + +ddog_CharSlice ddog_v1_get_payload_hostname(const ddog_TracerPayloadBytes *builder); /** * Number of chunks in the builder. */ -uintptr_t ddog_v1_get_chunk_count(const struct ddog_TracerPayloadV1Builder *builder); +uintptr_t ddog_v1_get_chunk_count(const ddog_TracerPayloadBytes *builder); /** - * The chunk's span node pointers; `len` receives their count. + * Chunk `idx` (null if out of range). */ -struct ddog_SpanNode *const *ddog_v1_get_spans(const struct ddog_ChunkNode *chunk, uintptr_t *len); +ddog_TraceChunkBytes *ddog_v1_get_chunk(ddog_TracerPayloadBytes *builder, uintptr_t idx); /** - * The chunk's local-root span, as the v0.4 wire picks it (`local_root_idx`), or null if empty. - * Chunk-level trace tags (trace_id_high, sampling priority/mechanism, origin) belong on it only. + * Span `idx` of `chunk` (null if out of range), e.g. to re-fetch a span after a sibling push. */ -struct ddog_SpanNode *ddog_v1_get_chunk_root_span(const struct ddog_ChunkNode *chunk); +ddog_SpanBytes *ddog_v1_get_span(ddog_TraceChunkBytes *chunk, uintptr_t idx); + +uintptr_t ddog_v1_get_link_count(const ddog_SpanBytes *span); /** - * The span's link node pointers; `len` receives their count. + * Link `idx` of `span` (null if out of range). */ -ddog_SpanLinkBytes *const *ddog_v1_get_links(const struct ddog_SpanNode *span, uintptr_t *len); +ddog_SpanLinkBytes *ddog_v1_get_link(ddog_SpanBytes *span, uintptr_t idx); + +uintptr_t ddog_v1_get_event_count(const ddog_SpanBytes *span); /** - * The span's event node pointers; `len` receives their count. + * Event `idx` of `span` (null if out of range). */ -ddog_SpanEventBytes *const *ddog_v1_get_events(const struct ddog_SpanNode *span, uintptr_t *len); +ddog_SpanEventBytes *ddog_v1_get_event(ddog_SpanBytes *span, uintptr_t idx); -uint64_t ddog_v1_get_chunk_trace_id_high(const struct ddog_ChunkNode *chunk); +uint64_t ddog_v1_get_chunk_trace_id_high(const ddog_TraceChunkBytes *chunk); -uint64_t ddog_v1_get_chunk_trace_id_low(const struct ddog_ChunkNode *chunk); +uint64_t ddog_v1_get_chunk_trace_id_low(const ddog_TraceChunkBytes *chunk); /** * Reads the chunk sampling priority; returns `false` (and leaves `out` untouched) when unset. */ -bool ddog_v1_get_chunk_sampling_priority(const struct ddog_ChunkNode *chunk, int32_t *out); +bool ddog_v1_get_chunk_sampling_priority(const ddog_TraceChunkBytes *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_ChunkNode *chunk, uint32_t *out); +bool ddog_v1_get_chunk_sampling_mechanism(const ddog_TraceChunkBytes *chunk, uint32_t *out); -ddog_CharSlice ddog_v1_get_chunk_origin(const struct ddog_ChunkNode *chunk); +ddog_CharSlice ddog_v1_get_chunk_origin(const ddog_TraceChunkBytes *chunk); -ddog_CharSlice ddog_v1_get_span_service(const struct ddog_SpanNode *span); +ddog_CharSlice ddog_v1_get_span_service(const ddog_SpanBytes *span); -ddog_CharSlice ddog_v1_get_span_name(const struct ddog_SpanNode *span); +ddog_CharSlice ddog_v1_get_span_name(const ddog_SpanBytes *span); -ddog_CharSlice ddog_v1_get_span_resource(const struct ddog_SpanNode *span); +ddog_CharSlice ddog_v1_get_span_resource(const ddog_SpanBytes *span); -ddog_CharSlice ddog_v1_get_span_type(const struct ddog_SpanNode *span); +ddog_CharSlice ddog_v1_get_span_type(const ddog_SpanBytes *span); -ddog_CharSlice ddog_v1_get_span_env(const struct ddog_SpanNode *span); +ddog_CharSlice ddog_v1_get_span_env(const ddog_SpanBytes *span); -ddog_CharSlice ddog_v1_get_span_version(const struct ddog_SpanNode *span); +ddog_CharSlice ddog_v1_get_span_version(const ddog_SpanBytes *span); -ddog_CharSlice ddog_v1_get_span_component(const struct ddog_SpanNode *span); +ddog_CharSlice ddog_v1_get_span_component(const ddog_SpanBytes *span); -uint64_t ddog_v1_get_span_id(const struct ddog_SpanNode *span); +uint64_t ddog_v1_get_span_id(const ddog_SpanBytes *span); -uint64_t ddog_v1_get_span_parent_id(const struct ddog_SpanNode *span); +uint64_t ddog_v1_get_span_parent_id(const ddog_SpanBytes *span); -int64_t ddog_v1_get_span_start(const struct ddog_SpanNode *span); +int64_t ddog_v1_get_span_start(const ddog_SpanBytes *span); -int64_t ddog_v1_get_span_duration(const struct ddog_SpanNode *span); +int64_t ddog_v1_get_span_duration(const ddog_SpanBytes *span); -bool ddog_v1_get_span_error(const struct ddog_SpanNode *span); +bool ddog_v1_get_span_error(const ddog_SpanBytes *span); /** * The span kind as its OTEL wire value. */ -uint32_t ddog_v1_get_span_kind(const struct ddog_SpanNode *span); +uint32_t ddog_v1_get_span_kind(const ddog_SpanBytes *span); uint64_t ddog_v1_get_link_trace_id_high(const ddog_SpanLinkBytes *link); @@ -1130,8 +975,6 @@ uint64_t ddog_v1_get_link_trace_id_low(const ddog_SpanLinkBytes *link); uint64_t ddog_v1_get_link_span_id(const ddog_SpanLinkBytes *link); -uint32_t ddog_v1_get_link_flags(const ddog_SpanLinkBytes *link); - ddog_CharSlice ddog_v1_get_link_tracestate(const ddog_SpanLinkBytes *link); uint64_t ddog_v1_get_event_time(const ddog_SpanEventBytes *event); @@ -1140,122 +983,70 @@ ddog_CharSlice ddog_v1_get_event_name(const ddog_SpanEventBytes *event); /** * Number of entries in `attrs`, including not-yet-deduped repeated keys (the last one wins). - * - * # Safety - * `attrs` must be a live [`Attributes`] handle (applies to every `ddog_v1_attributes_*`). */ -uintptr_t ddog_v1_attributes_len(const struct ddog_Attributes *attrs); +uintptr_t ddog_v1_attributes_len(const ddog_Attributes *attrs); /** * Key of the entry at `idx` (empty if out of range). - * - * # Safety - * See [`ddog_v1_attributes_len`]. */ -ddog_CharSlice ddog_v1_attributes_key(const struct ddog_Attributes *attrs, uintptr_t idx); +ddog_CharSlice ddog_v1_attributes_key(const ddog_Attributes *attrs, uintptr_t idx); /** * Value of the entry at `idx` (null if out of range). - * - * # Safety - * See [`ddog_v1_attributes_len`]. */ -const struct ddog_AttrValue *ddog_v1_attributes_value(const struct ddog_Attributes *attrs, - uintptr_t idx); - -/** - * Value of `key` (null if absent). - * - * # Safety - * See [`ddog_v1_attributes_len`]. - */ -const struct ddog_AttrValue *ddog_v1_attributes_get(const struct ddog_Attributes *attrs, - ddog_CharSlice key); +const ddog_AttrValue *ddog_v1_attributes_value(const ddog_Attributes *attrs, uintptr_t idx); /** * [`DDOG_V1_ATTR_*`] type tag of `value`. - * - * # Safety - * `value` must be a live [`AttrValue`] handle (applies to every `ddog_v1_value_*`). */ -uint32_t ddog_v1_value_type(const struct ddog_AttrValue *value); +uint32_t ddog_v1_value_type(const ddog_AttrValue *value); /** * The string (empty unless a `String`). - * - * # Safety - * See [`ddog_v1_value_type`]. */ -ddog_CharSlice ddog_v1_value_str(const struct ddog_AttrValue *value); +ddog_CharSlice ddog_v1_value_str(const ddog_AttrValue *value); /** * The bytes (empty unless `Bytes`). - * - * # Safety - * See [`ddog_v1_value_type`]. */ -ddog_CharSlice ddog_v1_value_bytes(const struct ddog_AttrValue *value); +ddog_CharSlice ddog_v1_value_bytes(const ddog_AttrValue *value); /** * The integer (0 unless an `Int`). - * - * # Safety - * See [`ddog_v1_value_type`]. */ -int64_t ddog_v1_value_int(const struct ddog_AttrValue *value); +int64_t ddog_v1_value_int(const ddog_AttrValue *value); /** * The double (0.0 unless a `Float`). - * - * # Safety - * See [`ddog_v1_value_type`]. */ -double ddog_v1_value_double(const struct ddog_AttrValue *value); +double ddog_v1_value_double(const ddog_AttrValue *value); /** * The boolean (false unless a true `Bool`). - * - * # Safety - * See [`ddog_v1_value_type`]. */ -bool ddog_v1_value_bool(const struct ddog_AttrValue *value); +bool ddog_v1_value_bool(const ddog_AttrValue *value); /** * Number of elements (0 unless a `List`). - * - * # Safety - * See [`ddog_v1_value_type`]. */ -uintptr_t ddog_v1_value_list_len(const struct ddog_AttrValue *value); +uintptr_t ddog_v1_value_list_len(const ddog_AttrValue *value); /** * Element `idx` (null unless a `List` with that element). - * - * # Safety - * See [`ddog_v1_value_type`]. */ -const struct ddog_AttrValue *ddog_v1_value_list_get(const struct ddog_AttrValue *value, - uintptr_t idx); +const ddog_AttrValue *ddog_v1_value_list_get(const ddog_AttrValue *value, uintptr_t idx); /** * The members of a `KeyValue`, read with the `ddog_v1_attributes_*` family (null otherwise). - * - * # Safety - * See [`ddog_v1_value_type`]. */ -const struct ddog_Attributes *ddog_v1_value_map(const struct ddog_AttrValue *value); +const ddog_Attributes *ddog_v1_value_map(const ddog_AttrValue *value); /** - * Renders a span for dd-trace-php's `DD_TRACE_DEBUG` "Encoding span" line. Takes the owning - * chunk/span node pointers (the outer frame's still-live handles), so it works mid-build before - * the nodes are folded into the inline payload. The returned owned slice must be freed with + * Renders a span for a tracer's debug log. The returned owned slice must be freed with * [`ddog_free_charslice`]. - * - * # Safety - * `chunk`/`span` must be live node pointers previously returned by - * `ddog_new_chunk`/`ddog_new_span` (with `span` a span of `chunk`). */ -ddog_CharSlice ddog_v1_span_debug_log(struct ddog_ChunkNode *chunk, struct ddog_SpanNode *span); +ddog_CharSlice ddog_v1_span_debug_log(const ddog_TraceChunkBytes *chunk, + const ddog_SpanBytes *span); /** * Frees an owned [`CharSlice`]. Only the few functions that document it return owned slices (the diff --git a/components-rs/tracer_runtime/bytes.rs b/components-rs/tracer_runtime/bytes.rs index c3a67b8b516..dea4a5069a5 100644 --- a/components-rs/tracer_runtime/bytes.rs +++ b/components-rs/tracer_runtime/bytes.rs @@ -1,9 +1,8 @@ -use datadog_sidecar_ffi::span::{attrs_mut, bytes_string_from_literal, Attributes, SpanNode}; +use datadog_sidecar_ffi::span::Attributes; use libdd_common_ffi::slice::CharSlice; use libdd_tinybytes::{Bytes, BytesString, RefCountedCell, RefCountedCellVTable}; -use libdd_trace_utils::span::v1::AttributeValueBytes; +use libdd_trace_utils::span::v1::{AttributeValueBytes, SpanBytes}; use std::borrow::Cow; -use std::os::raw::c_char; use std::ptr::NonNull; /// cbindgen:no-export @@ -133,615 +132,47 @@ fn convert_zend_to_bytes_string(zend_str: &mut ZendString) -> BytesString { } // PHP-specific additions to the V1 builder FFI (`datadog_sidecar_ffi::span`): zero-copy -// zend_string fields and static C-literal keys. +// zend_string fields. -/// # Safety -/// `span` must be a live span node pointer from `ddog_new_span` (every `*_zstr` span setter). #[no_mangle] -pub unsafe extern "C" fn ddog_set_span_service_zstr(span: *mut SpanNode, str: &mut ZendString) { - (*span).span_mut().service = convert_zend_to_bytes_string(str); +pub extern "C" fn ddog_set_span_service_zstr(span: &mut SpanBytes, str: &mut ZendString) { + span.service = convert_zend_to_bytes_string(str); } -/// # Safety -/// See [`ddog_set_span_service_zstr`]. #[no_mangle] -pub unsafe extern "C" fn ddog_set_span_name_zstr(span: *mut SpanNode, str: &mut ZendString) { - (*span).span_mut().name = convert_zend_to_bytes_string(str); +pub extern "C" fn ddog_set_span_name_zstr(span: &mut SpanBytes, str: &mut ZendString) { + span.name = convert_zend_to_bytes_string(str); } -/// # Safety -/// See [`ddog_set_span_service_zstr`]. #[no_mangle] -pub unsafe extern "C" fn ddog_set_span_resource_zstr(span: *mut SpanNode, str: &mut ZendString) { - (*span).span_mut().resource = convert_zend_to_bytes_string(str); +pub extern "C" fn ddog_set_span_resource_zstr(span: &mut SpanBytes, str: &mut ZendString) { + span.resource = convert_zend_to_bytes_string(str); } -/// # Safety -/// See [`ddog_set_span_service_zstr`]. #[no_mangle] -pub unsafe extern "C" fn ddog_set_span_type_zstr(span: *mut SpanNode, str: &mut ZendString) { - (*span).span_mut().r#type = convert_zend_to_bytes_string(str); -} - -/// String attribute under a static C literal key. -/// -/// # Safety -/// `attrs` must be a live `Attributes` handle and `key` a static NUL-terminated string (applies -/// to every attribute adder below). -#[no_mangle] -pub unsafe extern "C" fn ddog_attributes_add_lit( - attrs: *mut Attributes, - key: *const c_char, - value: CharSlice, -) { - let value = AttributeValueBytes::String(datadog_sidecar_ffi::span::bytes_string_from_slice(value)); - attrs_mut(attrs).insert(bytes_string_from_literal(key), value); +pub extern "C" fn ddog_set_span_type_zstr(span: &mut SpanBytes, str: &mut ZendString) { + span.r#type = convert_zend_to_bytes_string(str); } /// String attribute sharing both zend strings (zero-copy). -/// -/// # Safety -/// See [`ddog_attributes_add_lit`]. #[no_mangle] -pub unsafe extern "C" fn ddog_attributes_add_zstr( - attrs: *mut Attributes, +pub extern "C" fn ddog_attributes_add_zstr( + attrs: &mut Attributes, key: &mut ZendString, value: &mut ZendString, ) { - attrs_mut(attrs).insert( + attrs.0.insert( convert_zend_to_bytes_string(key), AttributeValueBytes::String(convert_zend_to_bytes_string(value)), ); } -/// Double attribute under a static C literal key. -/// -/// # Safety -/// See [`ddog_attributes_add_lit`]. -#[no_mangle] -pub unsafe extern "C" fn ddog_attributes_add_double_lit( - attrs: *mut Attributes, - key: *const c_char, - value: f64, -) { - attrs_mut(attrs).insert(bytes_string_from_literal(key), AttributeValueBytes::Float(value)); -} - /// Double attribute under a shared zend string key (zero-copy). -/// -/// # Safety -/// See [`ddog_attributes_add_lit`]. #[no_mangle] -pub unsafe extern "C" fn ddog_attributes_add_double_zstr( - attrs: *mut Attributes, +pub extern "C" fn ddog_attributes_add_double_zstr( + attrs: &mut Attributes, key: &mut ZendString, value: f64, ) { - attrs_mut(attrs).insert(convert_zend_to_bytes_string(key), AttributeValueBytes::Float(value)); -} - -#[cfg(test)] -mod v04_parity_tests { - // Wire-safety gate: the v0.4 downgrade of a NATIVE nested attribute carries the SAME dotted - // `meta` / `metrics` keys+values (and same meta-vs-metrics bucketing) the OLD C dotted flatten - // produced. Each case builds both shapes through the FFI, encodes both to v0.4, and compares the - // decoded `meta` / `metrics` maps order-insensitively — msgpack map key order is not significant - // for v0.4 consumers, and it is the only byte-level difference between the two encodings (it - // stems from `VecMap::dedup` reversing entries, which reorders nested vs flat topologies - // differently; list indices / map members are encoded in the dotted keys, so no data changes). - use datadog_sidecar_ffi::span::*; - use libdd_common_ffi::slice::CharSlice; - use libdd_trace_utils::msgpack_encoder::v04::to_vec_from_v1; - use libdd_trace_utils::span::v1::SpanKind; - use rmpv::Value; - - fn cs(s: &str) -> CharSlice<'_> { - CharSlice::from_bytes(s.as_bytes()) - } - - fn one_span_builder() -> (TracerPayloadV1Builder, *mut SpanNode) { - let mut b = TracerPayloadV1Builder::default(); - let c = b.push_chunk(0, 1); - // Safety: `c` is the live chunk node just pushed. - let s = unsafe { (*c).push_span() }; - (b, s) - } - - /// Decodes v0.4 bytes (`[[span,...],...]`) and returns the first span's map. - fn first_span(bytes: &[u8]) -> Value { - match rmpv::decode::read_value(&mut &bytes[..]).expect("valid msgpack") { - Value::Array(traces) => match traces.into_iter().next().expect("one trace") { - Value::Array(spans) => spans.into_iter().next().expect("one span"), - other => panic!("trace not an array: {other:?}"), - }, - other => panic!("payload not an array: {other:?}"), - } - } - - /// Extracts `span[key]` (a `meta`/`metrics` map) as `(key, value)` pairs sorted by key, so two - /// encodings can be compared independently of msgpack map serialization order. - fn sorted_bucket(span: &Value, key: &str) -> Vec<(String, Value)> { - let entries = match span { - Value::Map(entries) => entries, - other => panic!("span not a map: {other:?}"), - }; - let mut out = Vec::new(); - if let Some((_, Value::Map(bucket))) = - entries.iter().find(|(k, _)| k.as_str() == Some(key)) - { - for (k, v) in bucket { - out.push((k.as_str().expect("string key").to_string(), v.clone())); - } - } - out.sort_by(|a, b| a.0.cmp(&b.0)); - out - } - - #[test] - fn meta_nested_matches_old_flat_v04() { - // NEW: meta attr "m" = { bar: [ "1", { key: "2" }, "" ], "5": "v" } - // (String leaves, as the meta path stringifies — mirrors the old convert_to_double=false). - let (newb, s) = one_span_builder(); - unsafe { - let bar = ddog_attr_list_new(3); - ddog_attr_list_push_str(bar, cs("1")); - let e = ddog_attr_map_new(1); - ddog_attributes_add_str(ddog_attr_map_get_attributes(e), cs("key"), cs("2")); - ddog_attr_list_push_map(bar, e); - ddog_attr_list_push_str(bar, cs("")); // empty/recursive placeholder equivalent - let m = ddog_attr_map_new(2); - ddog_attributes_add_list(ddog_attr_map_get_attributes(m), cs("bar"), bar); - ddog_attributes_add_str(ddog_attr_map_get_attributes(m), cs("5"), cs("v")); // numeric-keyed member -> "m.5" - ddog_attributes_add_map(ddog_span_get_attributes(s), cs("m"), m); - } - - // OLD: the identical dotted keys the C flatten wrote, in traversal order. - let (oldb, s) = one_span_builder(); - unsafe { - ddog_attributes_add_str(ddog_span_get_attributes(s), cs("m.bar.0"), cs("1")); - ddog_attributes_add_str(ddog_span_get_attributes(s), cs("m.bar.1.key"), cs("2")); - ddog_attributes_add_str(ddog_span_get_attributes(s), cs("m.bar.2"), cs("")); - ddog_attributes_add_str(ddog_span_get_attributes(s), cs("m.5"), cs("v")); - } - - let new_span = first_span(&to_vec_from_v1(&newb.into_payload())); - let old_span = first_span(&to_vec_from_v1(&oldb.into_payload())); - assert_eq!( - sorted_bucket(&new_span, "meta"), - sorted_bucket(&old_span, "meta"), - "v0.4 meta keys+values of native nesting must match the old flat dotted meta" - ); - assert_eq!(sorted_bucket(&new_span, "metrics"), sorted_bucket(&old_span, "metrics")); - } - - #[test] - fn metrics_nested_matches_old_flat_v04() { - // NEW: metrics attr "mm" = { nums: [ 1.0, 2.5 ], deep: { x: 0.0 } } - // (Float leaves, as the metrics path uses zval_get_double -> convert_to_double=true.) - let (newb, s) = one_span_builder(); - unsafe { - let mm = ddog_attr_map_new(2); - let nums = ddog_attr_list_new(2); - ddog_attr_list_push_double(nums, 1.0); - ddog_attr_list_push_double(nums, 2.5); - ddog_attributes_add_list(ddog_attr_map_get_attributes(mm), cs("nums"), nums); - let deep = ddog_attr_map_new(1); - ddog_attributes_add_double(ddog_attr_map_get_attributes(deep), cs("x"), 0.0); // empty/recursive placeholder equivalent - ddog_attributes_add_map(ddog_attr_map_get_attributes(mm), cs("deep"), deep); - ddog_attributes_add_map(ddog_span_get_attributes(s), cs("mm"), mm); - } - - let (oldb, s) = one_span_builder(); - unsafe { - ddog_attributes_add_double(ddog_span_get_attributes(s), cs("mm.nums.0"), 1.0); - ddog_attributes_add_double(ddog_span_get_attributes(s), cs("mm.nums.1"), 2.5); - ddog_attributes_add_double(ddog_span_get_attributes(s), cs("mm.deep.x"), 0.0); - } - - let new_span = first_span(&to_vec_from_v1(&newb.into_payload())); - let old_span = first_span(&to_vec_from_v1(&oldb.into_payload())); - assert_eq!( - sorted_bucket(&new_span, "metrics"), - sorted_bucket(&old_span, "metrics"), - "v0.4 metrics keys+values of native nesting must match the old flat dotted metrics" - ); - assert_eq!(sorted_bucket(&new_span, "meta"), sorted_bucket(&old_span, "meta")); - } - - /// `span[key]` (a msgpack map field) as a borrowed value. - fn field<'a>(v: &'a Value, key: &str) -> Option<&'a Value> { - match v { - Value::Map(m) => m.iter().find(|(k, _)| k.as_str() == Some(key)).map(|(_, v)| v), - _ => None, - } - } - - #[test] - fn link_nested_attr_matches_old_json_string_v04() { - // NEW: native nested link attr `nums = [3, 4]` built through the container FFI. - let (newb, s) = one_span_builder(); - unsafe { - let link = ddog_new_link(s); - let nums = ddog_attr_list_new(2); - ddog_attr_list_push_int(nums, 3); - ddog_attr_list_push_int(nums, 4); - ddog_attributes_add_list(ddog_link_get_attributes(link), cs("nums"), nums); - } - // OLD: the JSON string the pre-native serializer produced (json_encode([3,4])). - let (oldb, s) = one_span_builder(); - unsafe { - let link = ddog_new_link(s); - ddog_attributes_add_str(ddog_link_get_attributes(link), cs("nums"), cs("[3,4]")); - } - - let new_span = first_span(&to_vec_from_v1(&newb.into_payload())); - let old_span = first_span(&to_vec_from_v1(&oldb.into_payload())); - // v0.4 links are native `span_links` with String attributes: the nested value carries the - // old json_encode string. - let nums = |sp: &Value| { - let link = &field(sp, "span_links").unwrap().as_array().unwrap()[0]; - field(field(link, "attributes").unwrap(), "nums").unwrap().clone() - }; - assert_eq!(nums(&new_span).as_str(), Some("[3,4]")); - assert_eq!(nums(&new_span), nums(&old_span)); - } - - #[test] - fn event_nested_attr_downgrades_to_legacy_events_meta_native_array() { - // Native nested event attr `nums = [3, 4]` built through the container FFI. On the v0.4 - // downgrade it lands in the legacy `events` meta as a REAL JSON array (event attributes - // keep native JSON types, matching master's json_encode of the PHP attributes array — - // unlike links, which are String → String). No native `span_events` field on the v0.4 wire. - let (newb, s) = one_span_builder(); - unsafe { - let event = ddog_new_event(s); - let nums = ddog_attr_list_new(2); - ddog_attr_list_push_int(nums, 3); - ddog_attr_list_push_int(nums, 4); - ddog_attributes_add_list(ddog_event_get_attributes(event), cs("nums"), nums); - } - let new_span = first_span(&to_vec_from_v1(&newb.into_payload())); - assert!(field(&new_span, "span_events").is_none()); - let events_meta = field(field(&new_span, "meta").unwrap(), "events") - .unwrap() - .as_str() - .unwrap(); - assert!(events_meta.contains(r#""nums":[3,4]"#), "got {events_meta}"); - } - - #[test] - fn span_kind_str_process_survives_v04_downgrade() { - // Mirrors tracer/serializer.c: only delete `span.kind` meta when canonical. Fixes - // AMQPIntegration's `Tag::SPAN_KIND = 'process'`, previously destroyed by enum coercion. - let (b, s) = one_span_builder(); - unsafe { - let is_canonical = ddog_set_span_kind_str(s, cs("process")); - assert!( - !is_canonical, - "\"process\" is not one of the 4 canonical kind strings" - ); - ddog_attributes_add_str(ddog_span_get_attributes(s), cs("span.kind"), cs("process")); - } - let span = first_span(&to_vec_from_v1(&b.into_payload())); - assert_eq!( - field(field(&span, "meta").unwrap(), "span.kind") - .unwrap() - .as_str(), - Some("process") - ); - // Exactly once: not duplicated as a generic attribute alongside the promoted field. - let meta_entries = match field(&span, "meta").unwrap() { - Value::Map(m) => m, - other => panic!("expected map, got {other:?}"), - }; - let kind_count = meta_entries - .iter() - .filter(|(k, _)| k.as_str() == Some("span.kind")) - .count(); - assert_eq!( - kind_count, 1, - "duplicate \"span.kind\" key written to the wire" - ); - } - - #[test] - fn span_kind_str_internal_is_canonical_and_survives_v04_downgrade() { - // An explicit "internal" is the Internal kind: serializer.c deletes the tag, and the - // downgrade writes it back from the kind. - let (b, s) = one_span_builder(); - unsafe { - assert!(ddog_set_span_kind_str(s, cs("internal"))); - } - let span = first_span(&to_vec_from_v1(&b.into_payload())); - assert_eq!( - field(field(&span, "meta").unwrap(), "span.kind") - .unwrap() - .as_str(), - Some("internal") - ); - } - - #[test] - fn span_kind_unset_stays_unspecified() { - let (b, _s) = one_span_builder(); - let payload = b.into_payload(); - assert_eq!(payload.chunks[0].spans[0].span_kind, SpanKind::Unspecified); - let span = first_span(&to_vec_from_v1(&payload)); - assert!(field(&span, "meta") - .and_then(|m| field(m, "span.kind")) - .is_none()); - } - - #[test] - fn span_kind_str_known_value_is_canonical_and_not_duplicated() { - let (b, s) = one_span_builder(); - unsafe { - let is_canonical = ddog_set_span_kind_str(s, cs("server")); - assert!(is_canonical); - // serializer.c deletes the meta key in this case; not re-added as an attribute here. - } - let span = first_span(&to_vec_from_v1(&b.into_payload())); - assert_eq!( - field(field(&span, "meta").unwrap(), "span.kind") - .unwrap() - .as_str(), - Some("server") - ); - } -} - -#[cfg(test)] -mod pointer_handle_miri_tests { - // The crux of Phase 2 comment A: prove the Box-per-node pointer model is UB-clean under Stacked - // AND Tree Borrows for the hazards the old index model was chosen to avoid. Run with - // `cargo +nightly miri test` (Stacked Borrows, the default) and with `-Zmiri-tree-borrows`. - use super::*; - use datadog_sidecar_ffi::span::*; - use libdd_trace_utils::span::v1::AttributeValueBytes; - - fn cs(s: &str) -> CharSlice<'_> { - CharSlice::from_bytes(s.as_bytes()) - } - - // (a) The inferred-span hazard (serializer.c ~2059→2098): after a SECOND span is pushed into the - // same chunk, the outer frame keeps mutating and reading its ROOT span pointer with NO refetch. - #[test] - fn a_root_span_ptr_survives_sibling_push() { - let mut b = TracerPayloadV1Builder::default(); - let chunk = b.push_chunk(0, 1); - unsafe { - let root = ddog_new_span(chunk); - ddog_span_set_id(root, 100); - ddog_span_set_error(root, true); - ddog_attributes_add_lit(ddog_span_get_attributes(root), c"moved".as_ptr(), cs("v")); - - // The sibling push that reallocs `chunk.spans`; `root` must stay valid (own allocation). - let inferred = ddog_new_span(chunk); - ddog_span_set_id(inferred, 200); - - // Use `root` AFTER the sibling push, with no refetch (mirrors the transfers/debug log). - assert!(ddog_transfer_span_attr(root, inferred, c"moved".as_ptr(), true)); - ddog_span_set_error(inferred, ddog_span_get_error(root)); - let log = ddog_v1_span_debug_log(chunk, root); - assert!(!log.is_empty()); - ddog_free_charslice(log); - } - - let payload = b.into_payload(); - let spans = &payload.chunks[0].spans; - assert_eq!(spans.len(), 2); - assert_eq!(spans[0].span_id, 100); - assert_eq!(spans[1].span_id, 200); - assert!(!spans[0].attributes.contains_key("moved"), "attr moved off root"); - assert!(spans[1].attributes.contains_key("moved"), "attr moved onto inferred"); - } - - // (b) A deep nested List/KeyValue built via the container FFI and attached to a span node - // pointer, then folded through into_payload. - #[test] - fn b_nested_attr_build_on_span_ptr() { - let mut b = TracerPayloadV1Builder::default(); - let chunk = b.push_chunk(0, 1); - unsafe { - let span = ddog_new_span(chunk); - let nested = ddog_attr_map_new(1); - ddog_attributes_add_bool(ddog_attr_map_get_attributes(nested), cs("flag"), true); - let items = ddog_attr_list_new(2); - ddog_attr_list_push_str(items, cs("a")); - ddog_attr_list_push_map(items, nested); - let root = ddog_attr_map_new(2); - ddog_attributes_add_int(ddog_attr_map_get_attributes(root), cs("n"), 7); - ddog_attributes_add_list(ddog_attr_map_get_attributes(root), cs("items"), items); - ddog_attributes_add_map(ddog_span_get_attributes(span), cs("root"), root); - } - let payload = b.into_payload(); - match payload.chunks[0].spans[0].attributes.get("root") { - Some(AttributeValueBytes::KeyValue(m)) => assert_eq!(m.len(), 2), - other => panic!("expected KeyValue, got {other:?}"), - } - } - - // (c) Links and events built on a span pointer, each fully built — including a deep nested - // List/KeyValue attribute attached to the link/event node pointer — before the next push; the - // node pointers stay valid across sibling node pushes. - #[test] - fn c_links_and_events_on_span_ptr() { - let mut b = TracerPayloadV1Builder::default(); - let chunk = b.push_chunk(0, 1); - unsafe { - let span = ddog_new_span(chunk); - let l0 = ddog_new_link(span); - ddog_link_set_span_id(l0, 11); - ddog_attributes_add_str(ddog_link_get_attributes(l0), cs("k"), cs("v")); - // Deep nested attr on l0: { tags: [ "a", { deep: 1 } ] } — fully built before l1. - let deep = ddog_attr_map_new(1); - ddog_attributes_add_int(ddog_attr_map_get_attributes(deep), cs("deep"), 1); - let tags = ddog_attr_list_new(2); - ddog_attr_list_push_str(tags, cs("a")); - ddog_attr_list_push_map(tags, deep); - ddog_attributes_add_list(ddog_link_get_attributes(l0), cs("tags"), tags); - - let l1 = ddog_new_link(span); // sibling push; l0 stays valid (own allocation) - ddog_link_set_span_id(l1, 22); - ddog_link_set_span_id(l0, 111); // still valid after the sibling push - - let e0 = ddog_new_event(span); - ddog_event_set_name(e0, cs("evt")); - ddog_attributes_add_int(ddog_event_get_attributes(e0), cs("n"), 5); - // Deep nested attr on e0: { meta: { list: [ true ] } } — fully built before e1. - let list = ddog_attr_list_new(1); - ddog_attr_list_push_bool(list, true); - let meta = ddog_attr_map_new(1); - ddog_attributes_add_list(ddog_attr_map_get_attributes(meta), cs("list"), list); - ddog_attributes_add_map(ddog_event_get_attributes(e0), cs("meta"), meta); - - let e1 = ddog_new_event(span); - ddog_event_set_time(e1, 999); - ddog_event_set_name(e0, cs("evt0")); // e0 valid after e1's push - } - let payload = b.into_payload(); - let span = &payload.chunks[0].spans[0]; - assert_eq!(span.span_links.len(), 2); - assert_eq!(span.span_links[0].span_id, 111); - match span.span_links[0].attributes.get("tags") { - Some(AttributeValueBytes::List(v)) => assert_eq!(v.len(), 2), - other => panic!("expected link List attr, got {other:?}"), - } - assert_eq!(span.span_events.len(), 2); - assert_eq!(span.span_events[0].name.as_str(), "evt0"); - match span.span_events[0].attributes.get("meta") { - Some(AttributeValueBytes::KeyValue(m)) => assert_eq!(m.len(), 1), - other => panic!("expected event KeyValue attr, got {other:?}"), - } - } - - // (d) into_payload dedups duplicate keys, and a builder dropped WITHOUT into_payload frees every - // node box (Miri's leak/double-free checker is the assertion for the drop path). - #[test] - fn d_into_payload_dedup_and_drop() { - let mut b = TracerPayloadV1Builder::default(); - let chunk = b.push_chunk(0, 1); - unsafe { - let span = ddog_new_span(chunk); - ddog_attributes_add_str(ddog_span_get_attributes(span), cs("dup"), cs("first")); - ddog_attributes_add_str(ddog_span_get_attributes(span), cs("dup"), cs("second")); - } - let payload = b.into_payload(); - let attrs = &payload.chunks[0].spans[0].attributes; - assert_eq!(attrs.len(), 1, "duplicate keys deduped in into_payload"); - - // Drop path: build a populated builder and let it fall out of scope unconsumed. - let mut d = TracerPayloadV1Builder::default(); - let c = d.push_chunk(0, 2); - unsafe { - let s = ddog_new_span(c); - ddog_new_link(s); - ddog_new_event(s); - let m = ddog_attr_map_new(1); - ddog_attributes_add_int(ddog_attr_map_get_attributes(m), cs("y"), 1); - ddog_attributes_add_map(ddog_span_get_attributes(s), cs("x"), m); - } - drop(d); - } - - // (e) A deep mixed nest (list in map in list), built once with capacity 0 (forcing regrowth) and - // once with exact capacities; both attach the same value and free cleanly. - #[test] - fn e_deep_mixed_nest_any_capacity() { - unsafe fn build(span: *mut SpanNode, key: &str, cap: impl Fn(usize) -> usize) { - let inner = ddog_attr_list_new(cap(3)); - ddog_attr_list_push_int(inner, 1); - ddog_attr_list_push_bytes(inner, cs("raw")); - ddog_attr_list_push_list(inner, ddog_attr_list_new(cap(0))); - let mid = ddog_attr_map_new(cap(2)); - ddog_attributes_add_list(ddog_attr_map_get_attributes(mid), cs("inner"), inner); - ddog_attributes_add_map(ddog_attr_map_get_attributes(mid), cs("empty"), ddog_attr_map_new(cap(0))); - let outer = ddog_attr_list_new(cap(2)); - ddog_attr_list_push_map(outer, mid); - ddog_attr_list_push_str(outer, cs("tail")); - ddog_attributes_add_list(ddog_span_get_attributes(span), cs(key), outer); - } - let mut b = TracerPayloadV1Builder::default(); - let chunk = b.push_chunk(0, 1); - unsafe { - let span = ddog_new_span(chunk); - build(span, "zero", |_| 0); - build(span, "exact", |n| n); - } - let payload = b.into_payload(); - let attrs = &payload.chunks[0].spans[0].attributes; - let shape = |key: &str| match attrs.get(key) { - Some(AttributeValueBytes::List(outer)) => { - assert_eq!(outer.len(), 2); - assert!(matches!(&outer[1], AttributeValueBytes::String(s) if s.as_str() == "tail")); - match &outer[0] { - AttributeValueBytes::KeyValue(mid) => { - assert!(matches!(mid.get("empty"), Some(AttributeValueBytes::KeyValue(m)) if m.is_empty())); - match mid.get("inner") { - Some(AttributeValueBytes::List(inner)) => { - assert!(matches!(inner[0], AttributeValueBytes::Int(1))); - assert!(matches!(&inner[1], AttributeValueBytes::Bytes(b) if b.as_ref() == b"raw")); - assert!(matches!(&inner[2], AttributeValueBytes::List(l) if l.is_empty())); - } - other => panic!("expected inner List, got {other:?}"), - } - } - other => panic!("expected KeyValue, got {other:?}"), - } - } - other => panic!("expected List, got {other:?}"), - }; - shape("zero"); - shape("exact"); - } - - // (f) Attribute handles stay valid across other calls on their node and sibling pushes, with no - // refetch: the handle shares the node pointer's tag (no intermediate `&mut` in the getter). - #[test] - fn f_attribute_handles_survive_interleaved_node_calls() { - let mut b = TracerPayloadV1Builder::default(); - let chunk = b.push_chunk(0, 1); - unsafe { - let span = ddog_new_span(chunk); - let attrs = ddog_span_get_attributes(span); - ddog_attributes_add_str(attrs, cs("a"), cs("1")); - ddog_span_set_error(span, true); - ddog_span_set_id(span, 7); - let link = ddog_new_link(span); - let link_attrs = ddog_link_get_attributes(link); - let event = ddog_new_event(span); - let event_attrs = ddog_event_get_attributes(event); - ddog_attributes_add_int(attrs, cs("b"), 2); - ddog_link_set_span_id(link, 3); - ddog_attributes_add_str(link_attrs, cs("l"), cs("v")); - let link2 = ddog_new_link(span); // sibling push - ddog_event_set_name(event, cs("e")); - ddog_attributes_add_bool(event_attrs, cs("e"), true); - ddog_attributes_add_str(ddog_link_get_attributes(link2), cs("l2"), cs("v2")); - ddog_attributes_add_double(attrs, cs("c"), 1.5); - assert!(ddog_span_get_error(span)); - let second = ddog_new_span(chunk); // sibling span push - ddog_attributes_add_str(ddog_span_get_attributes(second), cs("s"), cs("2")); - let m = ddog_attr_map_new(0); - let m_attrs = ddog_attr_map_get_attributes(m); - ddog_attributes_add_int(m_attrs, cs("x"), 1); - ddog_attributes_add_str(attrs, cs("d"), cs("4")); - ddog_attributes_add_int(m_attrs, cs("y"), 2); - ddog_attributes_add_map(attrs, cs("m"), m); - } - let payload = b.into_payload(); - let span = &payload.chunks[0].spans[0]; - assert!(span.error); - assert_eq!(span.span_id, 7); - assert_eq!(span.attributes.len(), 5); - match span.attributes.get("m") { - Some(AttributeValueBytes::KeyValue(m)) => assert_eq!(m.len(), 2), - other => panic!("expected KeyValue, got {other:?}"), - } - assert_eq!(span.span_links.len(), 2); - assert!(span.span_links[0].attributes.contains_key("l")); - assert!(span.span_links[1].attributes.contains_key("l2")); - assert!(span.span_events[0].attributes.contains_key("e")); - assert!(payload.chunks[0].spans[1].attributes.contains_key("s")); - } + attrs.0.insert(convert_zend_to_bytes_string(key), AttributeValueBytes::Float(value)); } diff --git a/datadog-setup.php b/datadog-setup.php index 4492a36bb6d..098cba4d98e 100644 --- a/datadog-setup.php +++ b/datadog-setup.php @@ -2532,36 +2532,12 @@ function get_ini_settings( 'Integrations names available at: see https://docs.datadoghq.com/tracing/setup_overview/setup/php/?tab=containers#integration-names', ], ], - [ - 'name' => 'datadog.trace._analytics_enabled', - 'default' => 'Off', - 'commented' => true, - 'description' => [ - 'Whether analytics for the integration is enabled.', - 'Integrations names available at: see https://docs.datadoghq.com/tracing/setup_overview/setup/php/?tab=containers#integration-names', - ], - ], - [ - 'name' => 'datadog.trace._analytics_sample_rate', - 'default' => '1.0', - 'commented' => true, - 'description' => [ - 'Sampling rate for analyzed spans. Valid values are between 0.0 and 1.0.', - 'Integrations names available at: see https://docs.datadoghq.com/tracing/setup_overview/setup/php/?tab=containers#integration-names', - ], - ], [ 'name' => 'datadog.distributed_tracing', 'default' => 'On', 'commented' => true, 'description' => 'Enables distributed tracing', ], - [ - 'name' => 'datadog.trace.analytics_enabled', - 'default' => 'Off', - 'commented' => true, - 'description' => 'Global switch for trace analytics', - ], [ 'name' => 'datadog.trace.bgs_connect_timeout', 'default' => '2000', diff --git a/docker-compose.yml b/docker-compose.yml index 9d24921fe64..2dab74860ca 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -295,7 +295,7 @@ services: windows-request-replayer: - image: datadog/dd-trace-ci:php-request-replayer-3.0_windows + image: datadog/dd-trace-ci:php-request-replayer-5.0_windows ports: - "8766:80" networks: diff --git a/dockerfiles/ci/windows/docker-compose.yml b/dockerfiles/ci/windows/docker-compose.yml index e234fe6a6a5..761e71d6cb6 100644 --- a/dockerfiles/ci/windows/docker-compose.yml +++ b/dockerfiles/ci/windows/docker-compose.yml @@ -173,7 +173,7 @@ services: phpSha256Hash: 8b2777c741e83f188d3ca6d8e98ece7264acafee86787298fae57e05d0dddc78 request-replayer: - image: ${CI_REGISTRY_IMAGE:-datadog/dd-trace-ci}:php-request-replayer-3.0_windows + image: ${CI_REGISTRY_IMAGE:-datadog/dd-trace-ci}:php-request-replayer-5.0_windows build: platforms: - windows/amd64 diff --git a/dockerfiles/services/request-replayer/src/index.php b/dockerfiles/services/request-replayer/src/index.php index 55bc8652781..9cb33df8561 100644 --- a/dockerfiles/services/request-replayer/src/index.php +++ b/dockerfiles/services/request-replayer/src/index.php @@ -48,7 +48,7 @@ function decodeDogStatsDMetrics($metrics) return $decodedMetrics; } -// v1 (`/v1.0/traces`) msgpack decoder, normalizing to the v0.4 per-span view. +// v1 (`/v1.0/traces`) msgpack decoder, producing a JSON view of the v1 payload. require __DIR__ . '/msgpack_v1_decoder.php'; $uri = explode("?", $_SERVER['REQUEST_URI'])[0]; @@ -415,9 +415,9 @@ function logRequest($message, $data = '') || (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. + // Store a JSON view of it; keep float zero fractions so typed values survive. $decoder = new V1TraceDecoder($raw); - $body = json_encode($decoder->decode()); + $body = json_encode($decoder->decode(), JSON_PRESERVE_ZERO_FRACTION); } 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 diff --git a/dockerfiles/services/request-replayer/src/msgpack_v1_decoder.php b/dockerfiles/services/request-replayer/src/msgpack_v1_decoder.php index fe9191e0bb9..255c3675ddb 100644 --- a/dockerfiles/services/request-replayer/src/msgpack_v1_decoder.php +++ b/dockerfiles/services/request-replayer/src/msgpack_v1_decoder.php @@ -1,16 +1,19 @@ 'container_id', 3 => 'language_name', 4 => 'language_version', + 5 => 'tracer_version', 6 => 'runtime_id', 7 => 'env', 8 => 'hostname', 9 => 'app_version']; 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; @@ -39,267 +44,94 @@ public function __construct($buf) $this->len = strlen($buf); } - /** Decodes the whole payload into the v0.4-shaped `{"chunks":[...]}` PHP array. */ + /** Decodes the whole payload into its JSON view. */ public function decode() { - $chunks = []; - $payloadAttributes = []; + $payload = []; $mapLen = $this->readMapLen(); for ($i = 0; $i < $mapLen; $i++) { $key = $this->readUint(); + if (isset(self::PAYLOAD_FIELDS[$key])) { + $payload[self::PAYLOAD_FIELDS[$key]] = $this->readInterned(); + continue; + } switch ($key) { case self::TRACE_CHUNKS: + $payload['chunks'] = []; $count = $this->readArrayLen(); for ($c = 0; $c < $count; $c++) { - $chunks[] = $this->decodeChunk(); + $payload['chunks'][] = $this->decodeChunk(); } break; case self::TRACE_ATTRIBUTES: - // Payload-level attributes (e.g. _dd.apm_mode) are not part of the per-span view, - // except process tags, which v0.4 carries on each trace's first span. - $payloadAttributes = $this->readAttributesMap(); + $payload['attributes'] = $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; } } - if (isset($payloadAttributes['_dd.tags.process'])) { - foreach ($chunks as &$chunk) { - if (!empty($chunk['spans'])) { - $chunk['spans'][0]['meta']['_dd.tags.process'] = $payloadAttributes['_dd.tags.process']; - } - } - unset($chunk); - } - return ['chunks' => $chunks]; + return $payload; } private function decodeChunk() { - $traceIdBytes = null; - $origin = null; - $priority = null; - $samplingMechanism = null; - $spans = []; - + $chunk = []; $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_TRACE_ID: $chunk['trace_id'] = bin2hex($this->readBin()); break; + case self::CHUNK_PRIORITY: $chunk['priority'] = $this->readInt(); break; + case self::CHUNK_ORIGIN: $chunk['origin'] = $this->readInterned(); break; + case self::CHUNK_SAMPLING_MECHANISM: $chunk['sampling_mechanism'] = $this->readUint(); break; + case self::CHUNK_DROPPED_TRACE: $chunk['dropped_trace'] = $this->readBool(); break; + case self::CHUNK_ATTRIBUTES: $chunk['attributes'] = $this->readAttributesMap(); break; case self::CHUNK_SPANS: + $chunk['spans'] = []; $count = $this->readArrayLen(); for ($s = 0; $s < $count; $s++) { - $spans[] = $this->decodeSpan(); + $chunk['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; + return $chunk; } 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; - + $span = []; $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'], as the v0.4 downgrade does; Unspecified (0, or the - // field absent) leaves no meta entry. - if ($kind !== null) { - $kindStr = $this->spanKindToStr($kind); - if ($kindStr !== null) { - $span['meta']['span.kind'] = $kindStr; + 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_TYPE: $span['type'] = $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->readInt(); break; + case self::SPAN_DURATION: $span['duration'] = $this->readInt(); break; + case self::SPAN_ERROR: $span['error'] = $this->readBool(); break; + case self::SPAN_ENV: $span['env'] = $this->readInterned(); break; + case self::SPAN_VERSION: $span['version'] = $this->readInterned(); break; + case self::SPAN_COMPONENT: $span['component'] = $this->readInterned(); break; + case self::SPAN_KIND: $span['span_kind'] = $this->readUint(); break; + case self::SPAN_ATTRIBUTES:$span['attributes'] = $this->readAttributesMap(); break; + case self::SPAN_LINKS: $span['span_links'] = $this->readSpanLinks(); break; + case self::SPAN_EVENTS: $span['span_events'] = $this->readSpanEvents(); break; + default: $this->skipValue(); break; } } - - 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 1: return "internal"; - case 2: return "server"; - case 3: return "client"; - case 4: return "producer"; - case 5: return "consumer"; - // 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). */ + /** Reads a v1 attributes map into an associative array of typed values. */ private function readAttributesMap() { $out = []; @@ -310,22 +142,21 @@ private function readAttributesMap() $entries = intdiv($n, 3); for ($i = 0; $i < $entries; $i++) { $key = $this->readInterned(); - list(, $value) = $this->readTypedValue(); - $out[$key] = $value; + $out[$key] = $this->readTypedValue(); } return $out; } - /** Reads `[type_uint8, value]`, returning [$type, $phpValue]. */ + /** Reads `[type_uint8, value]` into its PHP value. */ 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_STRING: return $this->readInterned(); + case self::ANY_BOOL: return $this->readBool(); + case self::ANY_DOUBLE: return $this->readDouble(); + case self::ANY_INT64: return $this->readInt(); + case self::ANY_BYTES: return ['bytes' => base64_encode($this->readBin())]; case self::ANY_ARRAY: $n = $this->readArrayLen(); if ($n % 2 !== 0) { @@ -333,69 +164,41 @@ private function readTypedValue() } $items = []; for ($i = 0, $c = intdiv($n, 2); $i < $c; $i++) { - list(, $v) = $this->readTypedValue(); - $items[] = $v; + $items[] = $this->readTypedValue(); } - return [$type, $items]; + return $items; case self::ANY_KEY_VALUE_LIST: - return [$type, $this->readAttributesMap()]; + return (object)$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_TRACE_ID: $link['trace_id'] = bin2hex($this->readBin()); 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(); + $link['span_id'] = str_pad(dechex_gmp($this->readUint()), 16, "0", STR_PAD_LEFT); break; + case self::LINK_ATTRIBUTES: $link['attributes'] = $this->readAttributesMap(); break; + case self::LINK_TRACE_STATE: $link['tracestate'] = $this->readInterned(); break; + case self::LINK_FLAGS: $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 = []; @@ -595,11 +398,6 @@ private function beUint($bytes) 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. diff --git a/dockerfiles/verify_packages/verify_windows.ps1 b/dockerfiles/verify_packages/verify_windows.ps1 index a333652df54..c8035f9a9f3 100644 --- a/dockerfiles/verify_packages/verify_windows.ps1 +++ b/dockerfiles/verify_packages/verify_windows.ps1 @@ -20,5 +20,5 @@ php build/packages/datadog-setup.php --php-bin=all --file=$(ls build/packages/dd if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } # Check the installed integration, keeping its span until the assertion. -echo " subprocess [attributes] => Array ( - [cmd.shell] => echo using passthru - [_dd.code_origin.type] => exit [_dd.code_origin.frames.1.file] => %s/fixtures/ddtrace.php [_dd.code_origin.frames.1.line] => 13 + [_dd.code_origin.type] => exit [cmd.exit_code] => 0 + [cmd.shell] => echo using passthru ) %A EOS diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index 161a2bedbab..d244209295e 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -823,26 +823,6 @@ "default": "" } ], - "DD_TRACE_AMQP_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_AMQP_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_AMQP_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_AMQP_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_AMQP_ENABLED": [ { "implementation": "A", @@ -850,13 +830,6 @@ "default": "true" } ], - "DD_TRACE_ANALYTICS_ENABLED": [ - { - "implementation": "B", - "type": "boolean", - "default": "false" - } - ], "DD_TRACE_APPEND_TRACE_IDS_TO_LOGS": [ { "implementation": "A", @@ -920,26 +893,6 @@ "default": "2097152" } ], - "DD_TRACE_CAKEPHP_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_CAKEPHP_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_CAKEPHP_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_CAKEPHP_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_CAKEPHP_ENABLED": [ { "implementation": "A", @@ -968,26 +921,6 @@ "default": "true" } ], - "DD_TRACE_CODEIGNITER_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_CODEIGNITER_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_CODEIGNITER_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_CODEIGNITER_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_CODEIGNITER_ENABLED": [ { "implementation": "A", @@ -995,26 +928,6 @@ "default": "true" } ], - "DD_TRACE_CURL_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_CURL_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_CURL_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_CURL_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_CURL_ENABLED": [ { "implementation": "A", @@ -1050,26 +963,6 @@ "default": "-1" } ], - "DD_TRACE_DRUPAL_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_DRUPAL_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_DRUPAL_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_DRUPAL_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_DRUPAL_ENABLED": [ { "implementation": "A", @@ -1077,26 +970,6 @@ "default": "true" } ], - "DD_TRACE_ELASTICSEARCH_ANALYTICS_ENABLED": [ - { - "implementation": "B", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_ELASTICSEARCH_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_ELASTICSEARCH_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_ELASTICSEARCH_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_ELASTICSEARCH_ENABLED": [ { "implementation": "A", @@ -1104,26 +977,6 @@ "default": "true" } ], - "DD_TRACE_ELOQUENT_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_ELOQUENT_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_ELOQUENT_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_ELOQUENT_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_ELOQUENT_ENABLED": [ { "implementation": "A", @@ -1138,26 +991,6 @@ "default": "true" } ], - "DD_TRACE_EXEC_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_EXEC_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_EXEC_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_EXEC_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_EXEC_ENABLED": [ { "implementation": "A", @@ -1165,26 +998,6 @@ "default": "true" } ], - "DD_TRACE_FILESYSTEM_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_FILESYSTEM_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_FILESYSTEM_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_FILESYSTEM_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_FILESYSTEM_ENABLED": [ { "implementation": "A", @@ -1227,26 +1040,6 @@ "default": "true" } ], - "DD_TRACE_FRANKENPHP_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_FRANKENPHP_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_FRANKENPHP_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_FRANKENPHP_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_FRANKENPHP_ENABLED": [ { "implementation": "A", @@ -1268,26 +1061,6 @@ "default": "true" } ], - "DD_TRACE_GOOGLESPANNER_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_GOOGLESPANNER_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_GOOGLESPANNER_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_GOOGLESPANNER_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_GOOGLESPANNER_ENABLED": [ { "implementation": "A", @@ -1295,26 +1068,6 @@ "default": "true" } ], - "DD_TRACE_GUZZLE_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_GUZZLE_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_GUZZLE_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_GUZZLE_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_GUZZLE_ENABLED": [ { "implementation": "A", @@ -1350,26 +1103,6 @@ "default": "100" } ], - "DD_TRACE_HTTPSTREAM_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_HTTPSTREAM_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_HTTPSTREAM_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_HTTPSTREAM_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_HTTPSTREAM_ENABLED": [ { "implementation": "A", @@ -1426,26 +1159,6 @@ "default": "false" } ], - "DD_TRACE_KAFKA_ANALYTICS_ENABLED": [ - { - "implementation": "B", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_KAFKA_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_KAFKA_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_KAFKA_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_KAFKA_DISTRIBUTED_TRACING": [ { "implementation": "A", @@ -1460,26 +1173,6 @@ "default": "true" } ], - "DD_TRACE_LAMINAS_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_LAMINAS_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_LAMINAS_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_LAMINAS_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_LAMINAS_ENABLED": [ { "implementation": "A", @@ -1487,26 +1180,6 @@ "default": "true" } ], - "DD_TRACE_LARAVELQUEUE_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_LARAVELQUEUE_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_LARAVELQUEUE_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_LARAVELQUEUE_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_LARAVELQUEUE_ENABLED": [ { "implementation": "A", @@ -1514,26 +1187,6 @@ "default": "true" } ], - "DD_TRACE_LARAVEL_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_LARAVEL_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_LARAVEL_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_LARAVEL_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_LARAVEL_ENABLED": [ { "implementation": "A", @@ -1548,26 +1201,6 @@ "default": "true" } ], - "DD_TRACE_LOGS_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_LOGS_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_LOGS_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_LOGS_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_LOGS_ENABLED": [ { "implementation": "A", @@ -1592,26 +1225,6 @@ "default": "error" } ], - "DD_TRACE_LUMEN_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_LUMEN_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_LUMEN_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_LUMEN_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_LUMEN_ENABLED": [ { "implementation": "A", @@ -1619,26 +1232,6 @@ "default": "true" } ], - "DD_TRACE_MAGENTO_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_MAGENTO_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_MAGENTO_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_MAGENTO_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_MAGENTO_ENABLED": [ { "implementation": "A", @@ -1660,26 +1253,6 @@ "default": "true" } ], - "DD_TRACE_MEMCACHED_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_MEMCACHED_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_MEMCACHED_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_MEMCACHED_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_MEMCACHED_ENABLED": [ { "implementation": "A", @@ -1694,26 +1267,6 @@ "default": "true" } ], - "DD_TRACE_MEMCACHE_ANALYTICS_ENABLED": [ - { - "implementation": "B", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_MEMCACHE_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_MEMCACHE_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_MEMCACHE_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_MEMCACHE_ENABLED": [ { "implementation": "A", @@ -1725,217 +1278,77 @@ { "implementation": "A", "type": "string", - "default": "" - } - ], - "DD_TRACE_MONGODB_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_MONGODB_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_MONGODB_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_MONGODB_ANALYTICS_SAMPLE_RATE" - ] - } - ], - "DD_TRACE_MONGODB_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "true" - } - ], - "DD_TRACE_MONGODB_OBFUSCATION": [ - { - "implementation": "A", - "type": "boolean", - "default": "true" - } - ], - "DD_TRACE_MONGO_ANALYTICS_ENABLED": [ - { - "implementation": "B", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_MONGO_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_MONGO_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_MONGO_ANALYTICS_SAMPLE_RATE" - ] - } - ], - "DD_TRACE_MONGO_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "true" - } - ], - "DD_TRACE_MYSQLI_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_MYSQLI_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_MYSQLI_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_MYSQLI_ANALYTICS_SAMPLE_RATE" - ] - } - ], - "DD_TRACE_MYSQLI_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "true" - } - ], - "DD_TRACE_NETTE_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_NETTE_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_NETTE_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_NETTE_ANALYTICS_SAMPLE_RATE" - ] - } - ], - "DD_TRACE_NETTE_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "true" - } - ], - "DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP": [ - { - "implementation": "G", - "type": "string", - "default": "(?i)(?:(?:\"|%22)?)(?:(?:old[-_]?|new[-_]?)?p(?:ass)?w(?:or)?d(?:1|2)?|pass(?:[-_]?phrase)?|secret|(?:api[-_]?|private[-_]?|public[-_]?|access[-_]?|secret[-_]?|app(?:lication)?[-_]?)key(?:[-_]?id)?|token|consumer[-_]?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:(?:\\s|%20)*(?:=|%3D)[^&]+|(?:\"|%22)(?:\\s|%20)*(?::|%3A)(?:\\s|%20)*(?:\"|%22)(?:%2[^2]|%[^2]|[^\"%])+(?:\"|%22))|(?:bearer(?:\\s|%20)+[a-z0-9._\\-]+|token(?::|%3A)[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|(^|[^\\w%-]|%[0-9a-f]{2})ey[I-L][\\w-]+(?:=|%3D)*\\.ey[I-L][\\w-]+(?:=|%3D)*(?:\\.(?:[\\w.+/=-]|%3D|%2F|%2B)+)?|-{5}BEGIN(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY-{5}[^\\-]+-{5}END(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY(?:-{5})?(?:\\n|%0A)?|(?:ssh-(?:rsa|dss)|ecdsa-[a-z0-9]+-[a-z0-9]+)(?:\\s|%20|%09)+(?:[a-z0-9/.+]|%2F|%5C|%2B){100,}(?:=|%3D)*(?:(?:\\s|%20|%09)+[a-z0-9._-]+)?)" + "default": "" } ], - "DD_TRACE_ONCE_LOGS": [ + "DD_TRACE_MONGODB_ENABLED": [ { "implementation": "A", "type": "boolean", "default": "true" } ], - "DD_TRACE_OPENAI_ANALYTICS_ENABLED": [ + "DD_TRACE_MONGODB_OBFUSCATION": [ { "implementation": "A", "type": "boolean", - "default": "false", - "aliases": [ - "DD_OPENAI_ANALYTICS_ENABLED" - ] + "default": "true" } ], - "DD_TRACE_OPENAI_ANALYTICS_SAMPLE_RATE": [ + "DD_TRACE_MONGO_ENABLED": [ { "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_OPENAI_ANALYTICS_SAMPLE_RATE" - ] + "type": "boolean", + "default": "true" } ], - "DD_TRACE_OPENAI_ENABLED": [ + "DD_TRACE_MYSQLI_ENABLED": [ { "implementation": "A", "type": "boolean", "default": "true" } ], - "DD_TRACE_OTEL_ENABLED": [ + "DD_TRACE_NETTE_ENABLED": [ { "implementation": "A", "type": "boolean", - "default": "false" + "default": "true" } ], - "DD_TRACE_PCNTL_ANALYTICS_ENABLED": [ + "DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP": [ { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_PCNTL_ANALYTICS_ENABLED" - ] + "implementation": "G", + "type": "string", + "default": "(?i)(?:(?:\"|%22)?)(?:(?:old[-_]?|new[-_]?)?p(?:ass)?w(?:or)?d(?:1|2)?|pass(?:[-_]?phrase)?|secret|(?:api[-_]?|private[-_]?|public[-_]?|access[-_]?|secret[-_]?|app(?:lication)?[-_]?)key(?:[-_]?id)?|token|consumer[-_]?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:(?:\\s|%20)*(?:=|%3D)[^&]+|(?:\"|%22)(?:\\s|%20)*(?::|%3A)(?:\\s|%20)*(?:\"|%22)(?:%2[^2]|%[^2]|[^\"%])+(?:\"|%22))|(?:bearer(?:\\s|%20)+[a-z0-9._\\-]+|token(?::|%3A)[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|(^|[^\\w%-]|%[0-9a-f]{2})ey[I-L][\\w-]+(?:=|%3D)*\\.ey[I-L][\\w-]+(?:=|%3D)*(?:\\.(?:[\\w.+/=-]|%3D|%2F|%2B)+)?|-{5}BEGIN(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY-{5}[^\\-]+-{5}END(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY(?:-{5})?(?:\\n|%0A)?|(?:ssh-(?:rsa|dss)|ecdsa-[a-z0-9]+-[a-z0-9]+)(?:\\s|%20|%09)+(?:[a-z0-9/.+]|%2F|%5C|%2B){100,}(?:=|%3D)*(?:(?:\\s|%20|%09)+[a-z0-9._-]+)?)" } ], - "DD_TRACE_PCNTL_ANALYTICS_SAMPLE_RATE": [ + "DD_TRACE_ONCE_LOGS": [ { "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_PCNTL_ANALYTICS_SAMPLE_RATE" - ] + "type": "boolean", + "default": "true" } ], - "DD_TRACE_PCNTL_ENABLED": [ + "DD_TRACE_OPENAI_ENABLED": [ { "implementation": "A", "type": "boolean", "default": "true" } ], - "DD_TRACE_PDO_ANALYTICS_ENABLED": [ + "DD_TRACE_OTEL_ENABLED": [ { "implementation": "A", "type": "boolean", - "default": "false", - "aliases": [ - "DD_PDO_ANALYTICS_ENABLED" - ] + "default": "false" } ], - "DD_TRACE_PDO_ANALYTICS_SAMPLE_RATE": [ + "DD_TRACE_PCNTL_ENABLED": [ { "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_PDO_ANALYTICS_SAMPLE_RATE" - ] + "type": "boolean", + "default": "true" } ], "DD_TRACE_PDO_ENABLED": [ @@ -1959,26 +1372,6 @@ "default": "" } ], - "DD_TRACE_PHPREDIS_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_PHPREDIS_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_PHPREDIS_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_PHPREDIS_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_PHPREDIS_ENABLED": [ { "implementation": "A", @@ -1986,26 +1379,6 @@ "default": "true" } ], - "DD_TRACE_PREDIS_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_PREDIS_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_PREDIS_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_PREDIS_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_PREDIS_ENABLED": [ { "implementation": "A", @@ -2055,26 +1428,6 @@ "default": "datadog,tracecontext,baggage" } ], - "DD_TRACE_PSR18_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_PSR18_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_PSR18_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_PSR18_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_PSR18_ENABLED": [ { "implementation": "A", @@ -2082,26 +1435,6 @@ "default": "true" } ], - "DD_TRACE_RATCHET_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_RATCHET_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_RATCHET_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_RATCHET_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_RATCHET_ENABLED": [ { "implementation": "A", @@ -2214,26 +1547,6 @@ "default": "100" } ], - "DD_TRACE_ROADRUNNER_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_ROADRUNNER_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_ROADRUNNER_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_ROADRUNNER_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_ROADRUNNER_ENABLED": [ { "implementation": "A", @@ -2304,26 +1617,6 @@ "default": "true" } ], - "DD_TRACE_SLIM_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_SLIM_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_SLIM_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_SLIM_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_SLIM_ENABLED": [ { "implementation": "A", @@ -2345,26 +1638,6 @@ "default": "1000" } ], - "DD_TRACE_SQLSRV_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_SQLSRV_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_SQLSRV_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_SQLSRV_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_SQLSRV_ENABLED": [ { "implementation": "A", @@ -2386,26 +1659,6 @@ "default": "false" } ], - "DD_TRACE_STRIPE_ANALYTICS_ENABLED": [ - { - "implementation": "B", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_STRIPE_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_STRIPE_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "B", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_STRIPE_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_STRIPE_ENABLED": [ { "implementation": "A", @@ -2413,26 +1666,6 @@ "default": "true" } ], - "DD_TRACE_SWOOLE_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_SWOOLE_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_SWOOLE_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_SWOOLE_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_SWOOLE_ENABLED": [ { "implementation": "A", @@ -2440,26 +1673,6 @@ "default": "true" } ], - "DD_TRACE_SYMFONYMESSENGER_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_SYMFONYMESSENGER_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_SYMFONYMESSENGER_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_SYMFONYMESSENGER_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_SYMFONYMESSENGER_ENABLED": [ { "implementation": "A", @@ -2467,26 +1680,6 @@ "default": "true" } ], - "DD_TRACE_SYMFONY_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_SYMFONY_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_SYMFONY_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_SYMFONY_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_SYMFONY_ENABLED": [ { "implementation": "A", @@ -2550,26 +1743,6 @@ "default": "true" } ], - "DD_TRACE_WEB_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_WEB_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_WEB_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_WEB_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_WEB_ENABLED": [ { "implementation": "A", @@ -2584,26 +1757,6 @@ "default": "" } ], - "DD_TRACE_WORDPRESS_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_WORDPRESS_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_WORDPRESS_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_WORDPRESS_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_WORDPRESS_CALLBACKS": [ { "implementation": "A", @@ -2625,26 +1778,6 @@ "default": "512" } ], - "DD_TRACE_YII_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_YII_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_YII_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_YII_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_YII_ENABLED": [ { "implementation": "A", @@ -2652,26 +1785,6 @@ "default": "true" } ], - "DD_TRACE_ZENDFRAMEWORK_ANALYTICS_ENABLED": [ - { - "implementation": "A", - "type": "boolean", - "default": "false", - "aliases": [ - "DD_ZENDFRAMEWORK_ANALYTICS_ENABLED" - ] - } - ], - "DD_TRACE_ZENDFRAMEWORK_ANALYTICS_SAMPLE_RATE": [ - { - "implementation": "A", - "type": "decimal", - "default": "1.0", - "aliases": [ - "DD_ZENDFRAMEWORK_ANALYTICS_SAMPLE_RATE" - ] - } - ], "DD_TRACE_ZENDFRAMEWORK_ENABLED": [ { "implementation": "A", diff --git a/src/DDTrace/Integrations/AMQP/AMQPIntegration.php b/src/DDTrace/Integrations/AMQP/AMQPIntegration.php index 7e5861d9fd0..d5441193439 100644 --- a/src/DDTrace/Integrations/AMQP/AMQPIntegration.php +++ b/src/DDTrace/Integrations/AMQP/AMQPIntegration.php @@ -5,8 +5,10 @@ use DDTrace\Integrations\Integration; use DDTrace\Propagator; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\SpanLink; use DDTrace\Tag; +use DDTrace\Util\BaseConverter; use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Wire\AMQPTable; @@ -22,36 +24,6 @@ class AMQPIntegration extends Integration const SYSTEM = 'rabbitmq'; public static $protocolVersion = ""; - // Source: https://magp.ie/2015/09/30/convert-large-integer-to-hexadecimal-without-php-math-extension/ - public static function largeBaseConvert($numString, $fromBase, $toBase) - { - $chars = "0123456789abcdefghijklmnopqrstuvwxyz"; - $toString = substr($chars, 0, $toBase); - - $length = strlen($numString); - $result = ''; - for ($i = 0; $i < $length; $i++) { - $number[$i] = strpos($chars, $numString[$i]); - } - do { - $divide = 0; - $newLen = 0; - for ($i = 0; $i < $length; $i++) { - $divide = $divide * $fromBase + $number[$i]; - if ($divide >= $toBase) { - $number[$newLen++] = (int)($divide / $toBase); - $divide = $divide % $toBase; - } elseif ($newLen > 0) { - $number[$newLen++] = 0; - } - } - $length = $newLen; - $result = $toString[$divide] . $result; - } while ($newLen != 0); - - return $result; - } - /** * Add instrumentation to AMQP requests */ @@ -89,14 +61,14 @@ static function($This) { self::setGenericTags( $span, 'basic.deliver', - 'consumer', + SpanKind::CONSUMER, "$exchangeDisplayName -> $routingKeyDisplayName" ); - $span->meta[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = $message->getBodySize(); - $span->meta[Tag::MQ_OPERATION] = 'receive'; - $span->meta[Tag::MQ_CONSUMER_ID] = $message->getConsumerTag(); - $span->meta[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; - $span->meta[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; + $span->attributes[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = $message->getBodySize(); + $span->attributes[Tag::MQ_OPERATION] = 'receive'; + $span->attributes[Tag::MQ_CONSUMER_ID] = $message->getConsumerTag(); + $span->attributes[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; + $span->attributes[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; self::setOptionalMessageTags($span, $message); @@ -105,14 +77,14 @@ static function($This) { self::setGenericTags( $newTrace, 'basic.deliver', - 'consumer', + SpanKind::CONSUMER, "$exchangeDisplayName -> $routingKeyDisplayName" ); - $newTrace->meta[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = $message->getBodySize(); - $newTrace->meta[Tag::MQ_OPERATION] = 'receive'; - $newTrace->meta[Tag::MQ_CONSUMER_ID] = $message->getConsumerTag(); - $newTrace->meta[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; - $newTrace->meta[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; + $newTrace->attributes[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = $message->getBodySize(); + $newTrace->attributes[Tag::MQ_OPERATION] = 'receive'; + $newTrace->attributes[Tag::MQ_CONSUMER_ID] = $message->getConsumerTag(); + $newTrace->attributes[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; + $newTrace->attributes[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; self::setOptionalMessageTags($newTrace, $message); // Close the created root span in the prehook @@ -147,17 +119,17 @@ static function($This) { self::setGenericTags( $span, 'basic.publish', - 'producer', + SpanKind::PRODUCER, "$exchangeDisplayName -> $routingKeyDisplayName", $exception ); - $span->meta[Tag::MQ_OPERATION] = 'send'; + $span->attributes[Tag::MQ_OPERATION] = 'send'; - $span->meta[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; - $span->meta[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; + $span->attributes[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; + $span->attributes[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; if (!is_null($message)) { - $span->meta[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = strlen($message->getBody()); + $span->attributes[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = strlen($message->getBody()); self::setOptionalMessageTags($span, $message); } } @@ -189,16 +161,16 @@ static function($This) { self::setGenericTags( $span, 'batch_basic.add', - 'producer', + SpanKind::PRODUCER, "$exchangeDisplayName -> $routingKeyDisplayName", $exception ); - $span->meta[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; - $span->meta[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; + $span->attributes[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; + $span->attributes[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; if (!is_null($message)) { - $span->meta[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = strlen($message->getBody()); + $span->attributes[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = strlen($message->getBody()); self::setOptionalMessageTags($span, $message); } } @@ -212,11 +184,11 @@ static function (SpanData $span, $args, $exception) { self::setGenericTags( $span, 'publish_batch', - 'producer', + SpanKind::PRODUCER, null, $exception ); - $span->meta[Tag::MQ_OPERATION] = 'send'; + $span->attributes[Tag::MQ_OPERATION] = 'send'; } ); @@ -234,13 +206,13 @@ static function (SpanData $span, $args, $retval, $exception) { self::setGenericTags( $span, 'basic.consume', - 'client', + SpanKind::CLIENT, $queueDisplayName, $exception ); - $span->meta[Tag::MQ_DESTINATION] = $queueDisplayName; - $span->meta[Tag::MQ_OPERATION] = 'receive'; - $span->meta[Tag::MQ_CONSUMER_ID] = $retval ?? $consumerTag; + $span->attributes[Tag::MQ_DESTINATION] = $queueDisplayName; + $span->attributes[Tag::MQ_OPERATION] = 'receive'; + $span->attributes[Tag::MQ_CONSUMER_ID] = $retval ?? $consumerTag; } ); @@ -256,11 +228,11 @@ static function (SpanData $span, $args, $retval, $exception) { self::setGenericTags( $span, 'exchange.declare', - 'client', + SpanKind::CLIENT, $exchangeDisplayName, $exception ); - $span->meta[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; + $span->attributes[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; } ); @@ -279,11 +251,11 @@ static function (SpanData $span, $args, $retval, $exception) { self::setGenericTags( $span, 'queue.declare', - 'client', + SpanKind::CLIENT, $queueDisplayName, $exception ); - $span->meta[Tag::MQ_DESTINATION] = $queueDisplayName; + $span->attributes[Tag::MQ_DESTINATION] = $queueDisplayName; } ); @@ -306,14 +278,14 @@ static function (SpanData $span, $args, $retval, $exception) { self::setGenericTags( $span, 'queue.bind', - 'client', + SpanKind::CLIENT, "$queueDisplayName $exchangeDisplayName -> $routingKeyDisplayName", $exception ); - $span->meta[Tag::MQ_DESTINATION] = $queueDisplayName; + $span->attributes[Tag::MQ_DESTINATION] = $queueDisplayName; - $span->meta[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; - $span->meta[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; + $span->attributes[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; + $span->attributes[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; } ); @@ -321,9 +293,9 @@ static function (SpanData $span, $args, $retval, $exception) { 'PhpAmqpLib\Channel\AMQPChannel', 'basic_consume_ok', static function (SpanData $span) { - self::setGenericTags($span, 'basic.consume_ok', 'server'); + self::setGenericTags($span, 'basic.consume_ok', SpanKind::SERVER); - $span->meta[Tag::MQ_OPERATION] = 'process'; + $span->attributes[Tag::MQ_OPERATION] = 'process'; } ); @@ -337,11 +309,11 @@ static function (SpanData $span, $args, $retval, $exception) { self::setGenericTags( $span, 'basic.cancel', - 'client', + SpanKind::CLIENT, $consumerTag, $exception ); - $span->meta[Tag::MQ_CONSUMER_ID] = $consumerTag; + $span->attributes[Tag::MQ_CONSUMER_ID] = $consumerTag; } ); @@ -349,7 +321,7 @@ static function (SpanData $span, $args, $retval, $exception) { 'PhpAmqpLib\Channel\AMQPChannel', 'basic_cancel_ok', static function (SpanData $span, $args, $retval, $exception) { - self::setGenericTags($span, 'basic.cancel_ok', 'server', null, $exception); + self::setGenericTags($span, 'basic.cancel_ok', SpanKind::SERVER, null, $exception); } ); @@ -357,7 +329,7 @@ static function (SpanData $span, $args, $retval, $exception) { 'PhpAmqpLib\Connection\AbstractConnection', 'connect', static function (SpanData $span, $args, $retval, $exception) { - self::setGenericTags($span, 'connect', 'client', null, $exception); + self::setGenericTags($span, 'connect', SpanKind::CLIENT, null, $exception); } ); @@ -365,7 +337,7 @@ static function (SpanData $span, $args, $retval, $exception) { 'PhpAmqpLib\Connection\AbstractConnection', 'reconnect', static function (SpanData $span, $args, $retval, $exception) { - self::setGenericTags($span, 'reconnect', 'client', null, $exception); + self::setGenericTags($span, 'reconnect', SpanKind::CLIENT, null, $exception); } ); @@ -376,7 +348,8 @@ static function (SpanData $span, $args, $retval, $exception) { /** @var int $deliveryTag */ $deliveryTag = $args[0]; - self::setGenericTags($span, 'basic.ack', 'process', $deliveryTag, $exception); + self::setGenericTags($span, 'basic.ack', SpanKind::UNSPECIFIED, $deliveryTag, $exception); + $span->attributes[Tag::SPAN_KIND] = 'process'; // not a canonical span kind, kept as an attribute } ); @@ -387,7 +360,8 @@ static function (SpanData $span, $args, $retval, $exception) { /** @var int $deliveryTag */ $deliveryTag = $args[0]; - self::setGenericTags($span, 'basic.nack', 'process', $deliveryTag, $exception); + self::setGenericTags($span, 'basic.nack', SpanKind::UNSPECIFIED, $deliveryTag, $exception); + $span->attributes[Tag::SPAN_KIND] = 'process'; // not a canonical span kind, kept as an attribute } ); @@ -403,12 +377,12 @@ static function (SpanData $span, $args, $message, $exception) { self::setGenericTags( $span, 'basic.get', - 'consumer', + SpanKind::CONSUMER, $queueDisplayName, $exception ); - $span->meta[Tag::MQ_OPERATION] = 'receive'; - $span->meta[Tag::MQ_DESTINATION] = $queueDisplayName; + $span->attributes[Tag::MQ_OPERATION] = 'receive'; + $span->attributes[Tag::MQ_DESTINATION] = $queueDisplayName; if (!is_null($message)) { /** @var AMQPMessage $message */ @@ -418,10 +392,10 @@ static function (SpanData $span, $args, $message, $exception) { $exchangeDisplayName = self::formatExchangeName($exchange); $routingKeyDisplayName = self::formatRoutingKey($routingKey); - $span->meta[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = $message->getBodySize(); + $span->attributes[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = $message->getBodySize(); - $span->meta[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; - $span->meta[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; + $span->attributes[Tag::RABBITMQ_ROUTING_KEY] = $routingKeyDisplayName; + $span->attributes[Tag::RABBITMQ_EXCHANGE] = $exchangeDisplayName; self::setOptionalMessageTags($span, $message); @@ -436,14 +410,14 @@ static function (SpanData $span, $args, $message, $exception) { if (preg_match('/^[a-fA-F0-9]{32}$/', $traceId)) { $traceId = strtolower($traceId); } else { - $traceId = self::largeBaseConvert($traceId, 10, 16); + $traceId = BaseConverter::convert($traceId, 10, 16); $traceId = str_pad(strtolower($traceId), 32, '0', STR_PAD_LEFT); } if (preg_match('/^[a-fA-F0-9]{16}$/', $parentId)) { $parentId = strtolower($parentId); } else { - $parentId = self::largeBaseConvert($parentId, 10, 16); + $parentId = BaseConverter::convert($parentId, 10, 16); $parentId = str_pad(strtolower($parentId), 16, '0', STR_PAD_LEFT); } @@ -482,22 +456,22 @@ public static function formatRoutingKey($routingKey) public static function setGenericTags( SpanData $span, string $name, - string $spanKind, + int $spanKind, $resourceDetail = null, $exception = null ) { $span->name = "amqp.$name"; $span->resource = "$name" . ($resourceDetail === null ? "" : " $resourceDetail"); - $span->meta[Tag::SPAN_KIND] = $spanKind; + $span->spanKind = $spanKind; $span->type = 'queue'; $span->service = 'amqp'; $span->attributes['_dd.svc_src'] = AMQPIntegration::NAME; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; - $span->meta[Tag::MQ_SYSTEM] = self::SYSTEM; - $span->meta[Tag::MQ_DESTINATION_KIND] = 'queue'; - $span->meta[Tag::MQ_PROTOCOL] = 'AMQP'; - $span->meta[Tag::MQ_PROTOCOL_VERSION] = self::$protocolVersion; + $span->attributes[Tag::MQ_SYSTEM] = self::SYSTEM; + $span->attributes[Tag::MQ_DESTINATION_KIND] = 'queue'; + $span->attributes[Tag::MQ_PROTOCOL] = 'AMQP'; + $span->attributes[Tag::MQ_PROTOCOL_VERSION] = self::$protocolVersion; if ($exception) { $span->exception = $exception; @@ -507,19 +481,19 @@ public static function setGenericTags( public static function setOptionalMessageTags(SpanData $span, AMQPMessage $message) { if ($message->has('delivery_mode')) { - $span->meta[Tag::RABBITMQ_DELIVERY_MODE] = $message->get('delivery_mode'); + $span->attributes[Tag::RABBITMQ_DELIVERY_MODE] = $message->get('delivery_mode'); } if ($message->has('message_id')) { - $span->meta[Tag::MQ_MESSAGE_ID] = $message->get('message_id'); + $span->attributes[Tag::MQ_MESSAGE_ID] = $message->get('message_id'); } if ($message->has('correlation_id')) { - $span->meta[Tag::MQ_CONVERSATION_ID] = $message->get('correlation_id'); + $span->attributes[Tag::MQ_CONVERSATION_ID] = $message->get('correlation_id'); } } public static function injectContext(AMQPMessage $message) { - if (\ddtrace_config_distributed_tracing_enabled() === false) { + if (\dd_trace_env_config('DD_DISTRIBUTED_TRACING') === false) { return; } diff --git a/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php b/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php index 4ea47027515..e95059db135 100644 --- a/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php +++ b/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php @@ -5,6 +5,7 @@ use DDTrace\Integrations\CakePHP\V2\CakePHPIntegrationLoader as CakePHPIntegrationLoaderV2; use DDTrace\Integrations\CakePHP\V3\CakePHPIntegrationLoader as CakePHPIntegrationLoaderV3; use DDTrace\Integrations\Integration; +use DDTrace\SpanKind; use DDTrace\Tag; class CakePHPIntegration extends Integration @@ -26,7 +27,7 @@ public static function init(): int return; } - self::$appName = \ddtrace_config_app_name(CakePHPIntegration::NAME); + self::$appName = \dd_trace_env_config('DD_SERVICE') ?: CakePHPIntegration::NAME; $rootSpan->service = self::$appName; Integration::tagFrameworkServiceSource($rootSpan, CakePHPIntegration::NAME); if ('cli' === PHP_SAPI) { @@ -36,9 +37,9 @@ public static function init(): int : 'cake_console'; } else { $rootSpan->name = 'cakephp.request'; - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; + $rootSpan->spanKind = SpanKind::SERVER; } - $rootSpan->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; + $rootSpan->component = CakePHPIntegration::NAME; }; self::$handleExceptionFn = static function ($This, $scope, $args) { @@ -51,7 +52,7 @@ public static function init(): int self::$setStatusCodeFn = static function ($This, $scope, $args, $retval) { $rootSpan = \DDTrace\root_span(); if ($rootSpan) { - $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = $retval; + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = (string)$retval; } }; @@ -62,7 +63,7 @@ public static function init(): int $rootSpan = \DDTrace\root_span(); if ($rootSpan !== null) { - $rootSpan->meta[Tag::HTTP_ROUTE] = $app->template; + $rootSpan->attributes[Tag::HTTP_ROUTE] = $app->template; } }; diff --git a/src/DDTrace/Integrations/CakePHP/V2/CakePHPIntegrationLoader.php b/src/DDTrace/Integrations/CakePHP/V2/CakePHPIntegrationLoader.php index 732030ae3ee..e9f16e8eb72 100644 --- a/src/DDTrace/Integrations/CakePHP/V2/CakePHPIntegrationLoader.php +++ b/src/DDTrace/Integrations/CakePHP/V2/CakePHPIntegrationLoader.php @@ -47,10 +47,10 @@ function (SpanData $span, array $args) { $rootSpan->attributes[Tag::HTTP_URL] = Router::url($request->here, true) . Normalizer::sanitizedQueryString(); } - $rootSpan->meta['cakephp.route.controller'] = $request->params['controller']; - $rootSpan->meta['cakephp.route.action'] = $request->params['action']; + $rootSpan->attributes['cakephp.route.controller'] = $request->params['controller']; + $rootSpan->attributes['cakephp.route.action'] = $request->params['action']; if (isset($request->params['plugin'])) { - $rootSpan->meta['cakephp.plugin'] = $request->params['plugin']; + $rootSpan->attributes['cakephp.plugin'] = $request->params['plugin']; } } ); @@ -81,7 +81,7 @@ function (SpanData $span, array $args) { $span->type = Type::WEB_SERVLET; $file = $this->viewPath . '/' . $this->view . $this->ext; $span->resource = $file; - $span->meta = ['cakephp.view' => $file]; + $span->attributes['cakephp.view'] = $file; Integration::setComponentMetadata($span, CakePHPIntegration::NAME, CakePHPIntegration::$appName); }); diff --git a/src/DDTrace/Integrations/CakePHP/V3/CakePHPIntegrationLoader.php b/src/DDTrace/Integrations/CakePHP/V3/CakePHPIntegrationLoader.php index acb36e83ae1..a3228be60bd 100644 --- a/src/DDTrace/Integrations/CakePHP/V3/CakePHPIntegrationLoader.php +++ b/src/DDTrace/Integrations/CakePHP/V3/CakePHPIntegrationLoader.php @@ -44,11 +44,11 @@ function (SpanData $span) { $rootSpan->attributes[Tag::HTTP_URL] = Router::url($request->getAttribute('here'), true) . Normalizer::sanitizedQueryString(); } - $rootSpan->meta['cakephp.route.controller'] = $request->getParam('controller'); - $rootSpan->meta['cakephp.route.action'] = $request->getParam('action'); + $rootSpan->attributes['cakephp.route.controller'] = $request->getParam('controller'); + $rootSpan->attributes['cakephp.route.action'] = $request->getParam('action'); $plugin = $request->getParam('plugin'); if ($plugin) { - $rootSpan->meta['cakephp.plugin'] = $plugin; + $rootSpan->attributes['cakephp.plugin'] = $plugin; } } ); @@ -97,16 +97,16 @@ static function (HookData $hook) use ($renderHook) { /** @var \Cake\View\View $this */ $file = $this->getTemplatePath() . '/' . $this->getTemplate() . $fileExtension; $span->resource = $file; - $span->meta['cakephp.view'] = $file; + $span->attributes['cakephp.view'] = $file; $plugin = $this->getPlugin(); if ($plugin) { - $span->meta['cakephp.plugin'] = $plugin; + $span->attributes['cakephp.plugin'] = $plugin; } $theme = $this->getTheme(); if ($theme) { - $span->meta['cakephp.theme'] = $theme; + $span->attributes['cakephp.theme'] = $theme; } }); diff --git a/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php b/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php index c92a90f1370..7903e34dbc3 100644 --- a/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php +++ b/src/DDTrace/Integrations/CodeIgniter/V2/CodeIgniterIntegration.php @@ -4,6 +4,7 @@ use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\Normalizer; @@ -21,7 +22,7 @@ public static function init($router = null): int if (null === $rootSpan) { return Integration::NOT_LOADED; } - $service = \ddtrace_config_app_name(self::NAME); + $service = \dd_trace_env_config('DD_SERVICE') ?: self::NAME; if (!\defined('CI_VERSION') || !isset($router)) { return Integration::NOT_LOADED; @@ -42,8 +43,8 @@ public static function registerIntegration(\CI_Router $router, SpanData $rootSpa $rootSpan->name = 'codeigniter.request'; $rootSpan->service = $service; $rootSpan->type = Type::WEB_SERVLET; - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; - $rootSpan->meta[Tag::COMPONENT] = self::NAME; + $rootSpan->spanKind = SpanKind::SERVER; + $rootSpan->component = self::NAME; $controller = $router->fetch_class(); $method = $router->fetch_method(); @@ -56,7 +57,7 @@ function (SpanData $span) use ($rootSpan, $method, $service) { $span->name = $span->resource = "{$class}.{$method}"; $span->service = $service; $span->type = Type::WEB_SERVLET; - $span->meta[Tag::COMPONENT] = CodeIgniterIntegration::NAME; + $span->component = CodeIgniterIntegration::NAME; // We took the assumption that all controllers will extend CI_Controller. // But we've at least seen one healthcheck controller not extending it. @@ -67,7 +68,7 @@ function (SpanData $span) use ($rootSpan, $method, $service) { $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize(base_url(uri_string())) . Normalizer::sanitizedQueryString(); } - $rootSpan->meta['app.endpoint'] = "{$class}::{$method}"; + $rootSpan->attributes['app.endpoint'] = "{$class}::{$method}"; } } ); @@ -89,7 +90,7 @@ function (SpanData $span, $args, $retval, $ex) use ($rootSpan, $service) { $span->resource = !$ex && isset($args[0]) ? $args[0] : $span->name; $span->service = $service; $span->type = Type::WEB_SERVLET; - $span->meta[Tag::COMPONENT] = CodeIgniterIntegration::NAME; + $span->component = CodeIgniterIntegration::NAME; // We took the assumption that all controllers will extend CI_Controller. // But we've at least seen one healthcheck case where it wasn't the case. @@ -98,7 +99,7 @@ function (SpanData $span, $args, $retval, $ex) use ($rootSpan, $service) { $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize(base_url(uri_string())) . Normalizer::sanitizedQueryString(); - $rootSpan->meta['app.endpoint'] = "{$class}::_remap"; + $rootSpan->attributes['app.endpoint'] = "{$class}::_remap"; } } ); @@ -111,7 +112,7 @@ static function (SpanData $span, $args, $retval, $ex) use ($service) { $span->service = $service; $span->resource = !$ex && isset($args[0]) ? $args[0] : $span->name; $span->type = Type::WEB_SERVLET; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; } ); @@ -128,7 +129,7 @@ function (SpanData $span, $args, $retval, $ex) use ($service) { $span->service = $service; $span->type = Type::SQL; $span->resource = !$ex && isset($args[0]) ? $args[0] : $span->name; - $span->meta[Tag::COMPONENT] = CodeIgniterIntegration::NAME; + $span->component = CodeIgniterIntegration::NAME; } ); @@ -151,7 +152,7 @@ static function (SpanData $span, $args, $retval, $ex) use ($service, &$registere $registered_cache_adapters[$class] = true; } } - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; return false; } ); @@ -174,7 +175,7 @@ function (SpanData $span, $args, $retval, $ex) use ($adapter, $service) { $span->service = $service; $span->type = Type::CACHE; $span->resource = !$ex && isset($args[0]) ? $args[0] : $span->name; - $span->meta[Tag::COMPONENT] = CodeIgniterIntegration::NAME; + $span->component = CodeIgniterIntegration::NAME; } ); @@ -187,7 +188,7 @@ function (SpanData $span, $args, $retval, $ex) use ($adapter, $service) { $span->service = $service; $span->type = Type::CACHE; $span->resource = !$ex && isset($args[0]) ? $args[0] : $span->name; - $span->meta[Tag::COMPONENT] = CodeIgniterIntegration::NAME; + $span->component = CodeIgniterIntegration::NAME; } ); @@ -200,7 +201,7 @@ function (SpanData $span, $args, $retval, $ex) use ($adapter, $service) { $span->service = $service; $span->type = Type::CACHE; $span->resource = !$ex && isset($args[0]) ? $args[0] : $span->name; - $span->meta[Tag::COMPONENT] = CodeIgniterIntegration::NAME; + $span->component = CodeIgniterIntegration::NAME; } ); @@ -213,7 +214,7 @@ function (SpanData $span, $args, $retval, $ex) use ($adapter, $service) { $span->service = $service; $span->type = Type::CACHE; $span->resource = $span->name; - $span->meta[Tag::COMPONENT] = CodeIgniterIntegration::NAME; + $span->component = CodeIgniterIntegration::NAME; } ); } @@ -228,7 +229,7 @@ private static function setHttpRoute($router, $rootSpan) { // Is there a literal match? If so we're done if (isset($router->routes[$uri])) { - $rootSpan->meta[Tag::HTTP_ROUTE] = $uri; + $rootSpan->attributes[Tag::HTTP_ROUTE] = $uri; return; } @@ -242,13 +243,13 @@ private static function setHttpRoute($router, $rootSpan) { // Does the RegEx match? if (preg_match('#^'.$key.'$#', $uri)) { - $rootSpan->meta[Tag::HTTP_ROUTE] = $origKey; + $rootSpan->attributes[Tag::HTTP_ROUTE] = $origKey; return; } } // If we got this far it means we didn't encounter a // matching route so we'll set the site default route - $rootSpan->meta[Tag::HTTP_ROUTE] = $uri; + $rootSpan->attributes[Tag::HTTP_ROUTE] = $uri; } } diff --git a/src/DDTrace/Integrations/Curl/CurlIntegration.php b/src/DDTrace/Integrations/Curl/CurlIntegration.php index bbc2e3b2402..d1775fc578b 100644 --- a/src/DDTrace/Integrations/Curl/CurlIntegration.php +++ b/src/DDTrace/Integrations/Curl/CurlIntegration.php @@ -7,6 +7,7 @@ use DDTrace\Integrations\HttpClientIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\ObjectKVStore; @@ -23,7 +24,7 @@ function addSpanDataTagFromCurlInfo($span, &$info, $tagName, $curlInfoOpt) { if (isset($info[$curlInfoOpt]) && !\trim($info[$curlInfoOpt]) !== '') { - $span->meta[$tagName] = $info[$curlInfoOpt]; + $span->attributes[$tagName] = $info[$curlInfoOpt]; unset($info[$curlInfoOpt]); } } @@ -41,19 +42,19 @@ public function __destruct() { foreach ($this->spans as $requestSpan) { list($ch, $requestSpan) = $requestSpan; - if (isset($requestSpan->meta[Tag::ERROR_MSG])) { + if (isset($requestSpan->attributes[Tag::ERROR_MSG])) { continue; } - if (isset($requestSpan->meta[Tag::NETWORK_DESTINATION_NAME]) && $requestSpan->meta[Tag::NETWORK_DESTINATION_NAME] !== 'unparsable-host') { + if (isset($requestSpan->attributes[Tag::NETWORK_DESTINATION_NAME]) && $requestSpan->attributes[Tag::NETWORK_DESTINATION_NAME] !== 'unparsable-host') { continue; } $info = curl_getinfo($ch); $errorMsg = curl_error($ch); if (empty($info['http_code']) && $errorMsg !== 'No error') { $error_trace = \DDTrace\get_sanitized_exception_trace(new \Exception(), 1); - $requestSpan->meta[Tag::ERROR_MSG] = $errorMsg; - $requestSpan->meta[Tag::ERROR_TYPE] = 'curl error'; - $requestSpan->meta[Tag::ERROR_STACK] = $error_trace; + $requestSpan->attributes[Tag::ERROR_MSG] = $errorMsg; + $requestSpan->attributes[Tag::ERROR_TYPE] = 'curl error'; + $requestSpan->attributes[Tag::ERROR_STACK] = $error_trace; } CurlIntegration::set_curl_attributes($requestSpan, $info); if (isset($info["total_time"])) { @@ -90,9 +91,9 @@ public static function init(): int $ch = $args[0]; if (isset($retval) && $retval === false) { - $span->meta[Tag::ERROR_MSG] = \curl_error($ch); - $span->meta[Tag::ERROR_TYPE] = 'curl error'; - $span->meta[Tag::ERROR_STACK] = \DDTrace\get_sanitized_exception_trace(new \Exception, 1); + $span->attributes[Tag::ERROR_MSG] = \curl_error($ch); + $span->attributes[Tag::ERROR_TYPE] = 'curl error'; + $span->attributes[Tag::ERROR_STACK] = \DDTrace\get_sanitized_exception_trace(new \Exception, 1); } self::set_curl_attributes($span, \curl_getinfo($ch)); @@ -132,7 +133,7 @@ public static function init(): int $span->service = "curl"; $span->type = Type::HTTP_CLIENT; Integration::handleInternalSpanServiceName($span, self::NAME); - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; $span->peerServiceSources = HttpClientIntegrationHelper::PEER_SERVICE_SOURCES; \DDTrace\collect_code_origins(1); @@ -173,13 +174,13 @@ public static function init(): int // finished foreach ($spans as $requestSpan) { list($ch, $requestSpan) = $requestSpan; - $requestSpan->metrics["_dd.measured"] = 1; + $requestSpan->attributes["_dd.measured"] = 1; $info = curl_getinfo($ch); if (empty($info["http_code"])) { $saveSpans = true; } - if (isset($requestSpan->meta[Tag::NETWORK_DESTINATION_NAME]) && $requestSpan->meta[Tag::NETWORK_DESTINATION_NAME] !== 'unparsable-host') { + if (isset($requestSpan->attributes[Tag::NETWORK_DESTINATION_NAME]) && $requestSpan->attributes[Tag::NETWORK_DESTINATION_NAME] !== 'unparsable-host') { continue; } @@ -187,11 +188,11 @@ public static function init(): int if (!isset($error_trace)) { $error_trace = \DDTrace\get_sanitized_exception_trace(new \Exception(), 1); } - if (!isset($requestSpan->meta[Tag::ERROR_MSG])) { - $requestSpan->meta[Tag::ERROR_MSG] = "CURL request failure"; + if (!isset($requestSpan->attributes[Tag::ERROR_MSG])) { + $requestSpan->attributes[Tag::ERROR_MSG] = "CURL request failure"; } - $requestSpan->meta[Tag::ERROR_TYPE] = 'curl error'; - $requestSpan->meta[Tag::ERROR_STACK] = $error_trace; + $requestSpan->attributes[Tag::ERROR_TYPE] = 'curl error'; + $requestSpan->attributes[Tag::ERROR_STACK] = $error_trace; } self::set_curl_attributes($requestSpan, $info); if (isset($info["total_time"])) { @@ -214,9 +215,9 @@ public static function init(): int if (!isset($error_trace)) { $error_trace = \DDTrace\get_sanitized_exception_trace(new \Exception(), 1); } - $requestSpan->meta[Tag::ERROR_MSG] = curl_multi_strerror($hook->returned); - $requestSpan->meta[Tag::ERROR_TYPE] = 'curl_multi error'; - $requestSpan->meta[Tag::ERROR_STACK] = $error_trace; + $requestSpan->attributes[Tag::ERROR_MSG] = curl_multi_strerror($hook->returned); + $requestSpan->attributes[Tag::ERROR_TYPE] = 'curl_multi error'; + $requestSpan->attributes[Tag::ERROR_STACK] = $error_trace; } }); @@ -242,18 +243,18 @@ public static function init(): int foreach ($spans as $requestSpan) { list($ch, $requestSpan) = $requestSpan; if ($ch === $handle) { - if (isset($requestSpan->meta[Tag::NETWORK_DESTINATION_NAME]) && $requestSpan->meta[Tag::NETWORK_DESTINATION_NAME] !== 'unparsable-host') { + if (isset($requestSpan->attributes[Tag::NETWORK_DESTINATION_NAME]) && $requestSpan->attributes[Tag::NETWORK_DESTINATION_NAME] !== 'unparsable-host') { continue; } $info = curl_getinfo($ch); $errorMsg = curl_strerror($hook->returned["result"]); if (empty($info['http_code']) && $errorMsg !== 'No error') { $error_trace = \DDTrace\get_sanitized_exception_trace(new \Exception(), 1); - if (!isset($requestSpan->meta[Tag::ERROR_MSG])) { - $requestSpan->meta[Tag::ERROR_MSG] = $errorMsg; + if (!isset($requestSpan->attributes[Tag::ERROR_MSG])) { + $requestSpan->attributes[Tag::ERROR_MSG] = $errorMsg; } - $requestSpan->meta[Tag::ERROR_TYPE] = 'curl error'; - $requestSpan->meta[Tag::ERROR_STACK] = $error_trace; + $requestSpan->attributes[Tag::ERROR_TYPE] = 'curl error'; + $requestSpan->attributes[Tag::ERROR_STACK] = $error_trace; } self::set_curl_attributes($requestSpan, $info); if (isset($info["total_time"])) { @@ -268,15 +269,15 @@ public static function init(): int foreach ($spans as $requestSpan) { list($ch, $requestSpan) = $requestSpan; if ($ch === $handle) { - $requestSpan->meta[Tag::ERROR_MSG] = curl_strerror($hook->returned["result"]); + $requestSpan->attributes[Tag::ERROR_MSG] = curl_strerror($hook->returned["result"]); $info = curl_getinfo($ch); - if (isset($requestSpan->meta[Tag::NETWORK_DESTINATION_NAME]) - && 'unparsable-host' !== $requestSpan->meta[Tag::NETWORK_DESTINATION_NAME]) { + if (isset($requestSpan->attributes[Tag::NETWORK_DESTINATION_NAME]) + && 'unparsable-host' !== $requestSpan->attributes[Tag::NETWORK_DESTINATION_NAME]) { continue; } - $requestSpan->meta[Tag::ERROR_TYPE] = 'curl error'; - $requestSpan->meta[Tag::ERROR_STACK] = \DDTrace\get_sanitized_exception_trace(new \Exception(), 1); + $requestSpan->attributes[Tag::ERROR_TYPE] = 'curl error'; + $requestSpan->attributes[Tag::ERROR_STACK] = \DDTrace\get_sanitized_exception_trace(new \Exception(), 1); self::set_curl_attributes($requestSpan, $info); if (isset($info["total_time"])) { $endTime = $info["total_time"] + $requestSpan->getStartTime() / 1e9; @@ -294,15 +295,15 @@ public static function setup_curl_span($span) { $span->type = Type::HTTP_CLIENT; $span->service = 'curl'; Integration::handleInternalSpanServiceName($span, self::NAME); - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_CLIENT; + $span->component = self::NAME; + $span->spanKind = SpanKind::CLIENT; } public static function set_curl_attributes($span, $info) { $sanitizedUrl = \DDTrace\Util\Normalizer::urlSanitize($info['url']); $normalizedPath = \DDTrace\Util\Normalizer::uriNormalizeOutgoingPath($info['url']); $host = Urls::hostname($sanitizedUrl); - $span->meta[Tag::NETWORK_DESTINATION_NAME] = $host; + $span->attributes[Tag::NETWORK_DESTINATION_NAME] = $host; unset($info['url']); if (\dd_trace_env_config("DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN")) { @@ -315,8 +316,8 @@ public static function set_curl_attributes($span, $info) { /* Special case the Datadog Standard Attributes * See https://docs.datadoghq.com/logs/processing/attributes_naming_convention/ */ - if (!array_key_exists(Tag::HTTP_URL, $span->meta)) { - $span->meta[Tag::HTTP_URL] = $sanitizedUrl; + if (!array_key_exists(Tag::HTTP_URL, $span->attributes)) { + $span->attributes[Tag::HTTP_URL] = $sanitizedUrl; } $span->peerServiceSources = HttpClientIntegrationHelper::PEER_SERVICE_SOURCES; @@ -326,7 +327,10 @@ public static function set_curl_attributes($span, $info) { HttpClientIntegrationHelper::setClientError($span, (int)$info['http_code']); } - addSpanDataTagFromCurlInfo($span, $info, Tag::HTTP_STATUS_CODE, 'http_code'); + if (isset($info['http_code'])) { + $span->attributes[Tag::HTTP_STATUS_CODE] = (string)$info['http_code']; + unset($info['http_code']); + } addSpanDataTagFromCurlInfo($span, $info, 'network.client.ip', 'local_ip'); addSpanDataTagFromCurlInfo($span, $info, 'network.client.port', 'local_port'); @@ -345,7 +349,7 @@ public static function set_curl_attributes($span, $info) { if (\substr_compare($key, '_time', -5) === 0) { $val *= 1000000000; } - $span->meta["curl.{$key}"] = $val; + $span->attributes["curl.{$key}"] = $val; } } diff --git a/src/DDTrace/Integrations/DatabaseIntegrationHelper.php b/src/DDTrace/Integrations/DatabaseIntegrationHelper.php index dad67703467..368be140206 100644 --- a/src/DDTrace/Integrations/DatabaseIntegrationHelper.php +++ b/src/DDTrace/Integrations/DatabaseIntegrationHelper.php @@ -44,16 +44,16 @@ public static function injectDatabaseIntegrationData(HookData $hook, $backend, $ } $span = $hook->span(); - $targetHost = $span->meta[Tag::TARGET_HOST] ?? ''; - $dbName = $span->meta[Tag::DB_NAME] ?? $span->meta[Tag::DB_INSTANCE] ?? ''; - $peerService = $span->meta['peer.service'] ?? ''; + $targetHost = $span->attributes[Tag::TARGET_HOST] ?? ''; + $dbName = $span->attributes[Tag::DB_NAME] ?? $span->attributes[Tag::DB_INSTANCE] ?? ''; + $peerService = $span->attributes['peer.service'] ?? ''; // Inject base hash into span tags if enabled if (\dd_trace_env_config("DD_DBM_INJECT_SQL_BASEHASH") || $propagationMode == \DDTrace\DBM_PROPAGATION_DYNAMIC_SERVICE) { $baseHash = \DDTrace\System\process_tags_base_hash(); if ($baseHash !== null) { - $span->meta[Tag::PROPAGATED_HASH] = $baseHash; + $span->attributes[Tag::PROPAGATED_HASH] = $baseHash; } } @@ -71,7 +71,7 @@ public static function injectDatabaseIntegrationData(HookData $hook, $backend, $ $hook->args[$argNum] = $query; $hook->overrideArguments($hook->args); if ($propagationMode == \DDTrace\DBM_PROPAGATION_FULL) { - $hook->span()->meta["_dd.dbm_trace_injected"] = "true"; + $hook->span()->attributes["_dd.dbm_trace_injected"] = "true"; } } } @@ -98,7 +98,7 @@ public static function propagateViaSqlComments( $tags["dddbs"] = $databaseService; } - $env = $rootSpan->attributes["env"] ?? $rootSpan->meta["env"] ?? $rootSpan->env ?? ""; + $env = $rootSpan->env ?? ""; if ($env == "") { $env = ini_get("datadog.env"); } @@ -116,7 +116,7 @@ public static function propagateViaSqlComments( $service = $rootSpan->service ?? ""; if ($service == "") { - $service = ddtrace_config_app_name(); + $service = \dd_trace_env_config('DD_SERVICE'); } if ($service != "") { $mapping = dd_trace_env_config('DD_SERVICE_MAPPING'); @@ -126,7 +126,7 @@ public static function propagateViaSqlComments( $tags["ddps"] = $service; } - $version = $rootSpan->attributes["version"] ?? $rootSpan->meta["version"] ?? $rootSpan->version ?? ""; + $version = $rootSpan->version ?? ""; if ($version == "") { $version = ini_get("datadog.version"); } diff --git a/src/DDTrace/Integrations/Drupal/DrupalIntegration.php b/src/DDTrace/Integrations/Drupal/DrupalIntegration.php index cd4f1423fa1..8a384876848 100644 --- a/src/DDTrace/Integrations/Drupal/DrupalIntegration.php +++ b/src/DDTrace/Integrations/Drupal/DrupalIntegration.php @@ -5,6 +5,7 @@ use DDTrace\HookData; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\ObjectKVStore; @@ -31,21 +32,21 @@ public static function init(): int 'prehook' => static function (SpanData $span) { // A pre-hook is used here to ensure that the root span name is set before the symfony integration // checks for it. - $service = \ddtrace_config_app_name('drupal'); + $service = \dd_trace_env_config('DD_SERVICE') ?: 'drupal'; $rootSpan = \DDTrace\root_span(); $rootSpan->name = 'drupal.request'; $rootSpan->service = $service; Integration::tagFrameworkServiceSource($rootSpan, 'drupal'); - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; - $rootSpan->meta[Tag::COMPONENT] = self::NAME; + $rootSpan->spanKind = SpanKind::SERVER; + $rootSpan->component = self::NAME; $span->name = 'drupal.kernel.handle'; $span->type = Type::WEB_SERVLET; $span->service = $service; Integration::tagFrameworkServiceSource($span, 'drupal'); - $span->attributes[Tag::SPAN_KIND] = 'server'; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->spanKind = SpanKind::SERVER; + $span->component = self::NAME; } ] ); @@ -117,9 +118,9 @@ static function (HookData $fnHookData) use ($hook, $module, $functionName) { $span->type = Type::WEB_SERVLET; Integration::setComponentMetadata($span, 'drupal'); - $span->meta['drupal.hook'] = $hook; - $span->meta['drupal.module'] = $module; - $span->meta['drupal.function'] = $functionName; + $span->attributes['drupal.hook'] = $hook; + $span->attributes['drupal.module'] = $module; + $span->attributes['drupal.function'] = $functionName; remove_hook($fnHookData->id); } @@ -158,9 +159,9 @@ static function (HookData $fnHookData) use ($hook, $module, $functionName) { Integration::setComponentMetadata($span, 'drupal'); $span->resource = $functionName; - $span->meta['drupal.hook'] = $hook; - $span->meta['drupal.module'] = $module; - $span->meta['drupal.function'] = $functionName; + $span->attributes['drupal.hook'] = $hook; + $span->attributes['drupal.module'] = $module; + $span->attributes['drupal.function'] = $functionName; remove_hook($fnHookData->id); } @@ -192,7 +193,7 @@ function (HookData $hook) { if (method_exists($storage, 'label')) { $label = $storage->label(); if (is_string($label)) { - $span->meta['drupal.view'] = $label; + $span->attributes['drupal.view'] = $label; } } } @@ -225,7 +226,7 @@ static function ($registry, $scope, $args) { $tagTemplateFile = static function ($file) use (&$renderSpan) { if ($renderSpan) { - $renderSpan->meta['drupal.template.file'] = $file; + $renderSpan->attributes['drupal.template.file'] = $file; } }; @@ -265,10 +266,10 @@ function (HookData $hookData) use (&$renderSpan, &$legacyRenderHooks, $tagLegacy $renderSpan = $span; $span->name = 'drupal.theme.render'; - $span->service = \ddtrace_config_app_name('drupal'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'drupal'; Integration::tagFrameworkServiceSource($span, 'drupal'); $span->type = Type::WEB_SERVLET; - $span->meta[Tag::COMPONENT] = DrupalIntegration::NAME; + $span->component = DrupalIntegration::NAME; /** @var \Drupal\Core\Theme\ThemeManager $this */ $activeTheme = $this->getActiveTheme(); @@ -276,13 +277,13 @@ function (HookData $hookData) use (&$renderSpan, &$legacyRenderHooks, $tagLegacy $themeEngine = $activeTheme->getEngine(); if (!empty($themeName)) { - $span->meta['drupal.render.theme'] = $themeName; + $span->attributes['drupal.render.theme'] = $themeName; } if (empty($themeEngine)) { return; } - $span->meta['drupal.render.engine'] = $themeEngine; + $span->attributes['drupal.render.engine'] = $themeEngine; // Drupal <= 11.2 renders through the {engine}_render_template() global. One hook per // engine name for the whole request; $renderSpan does the attribution. @@ -332,31 +333,31 @@ function (HookData $hookData) use (&$renderSpan) { } if (!$runtimeThemeRegistry->has($hook)) { - $span->meta['drupal.render.hook'] = $span->resource = $originalHook; + $span->attributes['drupal.render.hook'] = $span->resource = $originalHook; return; } - $span->meta['drupal.render.hook'] = $span->resource = $hook; + $span->attributes['drupal.render.hook'] = $span->resource = $hook; $info = $runtimeThemeRegistry->get($hook); if (isset($info['base hook'])) { - $span->meta['drupal.render.base_hook'] = $info['base hook']; + $span->attributes['drupal.render.base_hook'] = $info['base hook']; } if (isset($info['type'])) { - $span->meta['drupal.render.type'] = $info['type']; + $span->attributes['drupal.render.type'] = $info['type']; } if (isset($info['render element'])) { - $span->meta['drupal.render.element'] = $info['render element']; + $span->attributes['drupal.render.element'] = $info['render element']; } if (isset($info['template'])) { - $span->meta['drupal.template.template'] = $info['template']; + $span->attributes['drupal.template.template'] = $info['template']; } if (isset($info['function'])) { - $span->meta['drupal.render.theme_function'] = $info['function']; + $span->attributes['drupal.render.theme_function'] = $info['function']; } if (isset($info['path'])) { @@ -367,7 +368,7 @@ function (HookData $hookData) use (&$renderSpan) { if ($themePathStart !== false) { $themePath = substr($path, $themePathStart + 8); // Between '/themes/', 8 = strlen('/themes/') $themePath = substr($themePath, 0, strpos($themePath, '/')); // Until the next '/' - $span->meta['drupal.template.theme'] = $themePath; + $span->attributes['drupal.template.theme'] = $themePath; } } } @@ -427,10 +428,10 @@ static function ($mainContViewSubscriber, $scope, $args) { 'send', static function (SpanData $span) { $span->name = 'symfony.response.send'; - $span->service = \ddtrace_config_app_name('drupal'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'drupal'; Integration::tagFrameworkServiceSource($span, 'drupal'); $span->type = Type::WEB_SERVLET; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; } ); diff --git a/src/DDTrace/Integrations/ElasticSearch/V1/ElasticSearchIntegration.php b/src/DDTrace/Integrations/ElasticSearch/V1/ElasticSearchIntegration.php index 2e9d95c0907..ffe1af02f67 100644 --- a/src/DDTrace/Integrations/ElasticSearch/V1/ElasticSearchIntegration.php +++ b/src/DDTrace/Integrations/ElasticSearch/V1/ElasticSearchIntegration.php @@ -5,6 +5,7 @@ use DDTrace\Integrations\ElasticSearch\ElasticSearchCommon; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; @@ -38,7 +39,7 @@ public static function init(): int Integration::handleInternalSpanServiceName($span, ElasticSearchIntegration::NAME); $span->type = Type::ELASTICSEARCH; $span->resource = "__construct"; - $span->meta[Tag::COMPONENT] = ElasticSearchIntegration::NAME; + $span->component = ElasticSearchIntegration::NAME; } ]); @@ -100,17 +101,17 @@ public static function init(): int $span->resource = 'performRequest'; Integration::handleInternalSpanServiceName($span, ElasticSearchIntegration::NAME); $span->type = Type::ELASTICSEARCH; - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = ElasticSearchIntegration::NAME; + $span->spanKind = SpanKind::CLIENT; + $span->component = ElasticSearchIntegration::NAME; try { - $span->meta[Tag::ELASTICSEARCH_URL] = $this->getURI(); - $span->meta[Tag::ELASTICSEARCH_METHOD] = $this->getMethod(); + $span->attributes[Tag::ELASTICSEARCH_URL] = $this->getURI(); + $span->attributes[Tag::ELASTICSEARCH_METHOD] = $this->getMethod(); if (is_array($this->params)) { - $span->meta[Tag::ELASTICSEARCH_PARAMS] = json_encode($this->params); + $span->attributes[Tag::ELASTICSEARCH_PARAMS] = json_encode($this->params); } if ($this->getMethod() === 'GET' && $body = $this->getBody()) { - $span->meta[Tag::ELASTICSEARCH_BODY] = json_encode($body); + $span->attributes[Tag::ELASTICSEARCH_BODY] = json_encode($body); } } catch (\Exception $ex) { } @@ -120,15 +121,15 @@ public static function init(): int $span->resource = 'performRequest'; Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::ELASTICSEARCH; - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; - $span->meta[Tag::ELASTICSEARCH_URL] = $args[1]; - $span->meta[Tag::ELASTICSEARCH_METHOD] = $args[0]; - $span->meta[Tag::ELASTICSEARCH_PARAMS] = json_encode($args[2]); + $span->attributes[Tag::ELASTICSEARCH_URL] = $args[1]; + $span->attributes[Tag::ELASTICSEARCH_METHOD] = $args[0]; + $span->attributes[Tag::ELASTICSEARCH_PARAMS] = json_encode($args[2]); $recordBody = $args[0] === 'GET' || preg_match("(/_m?search.*$)", $args[1]); if ($recordBody && null !== $body = $args[3]) { - $span->meta[Tag::ELASTICSEARCH_BODY] = json_encode($body); + $span->attributes[Tag::ELASTICSEARCH_BODY] = json_encode($body); } }); @@ -154,11 +155,11 @@ public static function traceClientMethod($name) 'prehook' => static function (SpanData $span, $args) use ($name) { $span->name = "Elasticsearch.Client.$name"; - $span->meta[Tag::SPAN_KIND] = 'client'; + $span->spanKind = SpanKind::CLIENT; Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::ELASTICSEARCH; $span->resource = ElasticSearchCommon::buildResourceName($name, isset($args[0]) ? $args[0] : []); - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; } ] ); @@ -176,7 +177,7 @@ public static function traceSimpleMethod($class, $name) $span->resource = $operationName; Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::ELASTICSEARCH; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; }); } @@ -198,7 +199,7 @@ public static function traceNamespaceMethod($namespace, $name) $span->resource = ElasticSearchCommon::buildResourceName($name, $params); Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::ELASTICSEARCH; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; }); } } diff --git a/src/DDTrace/Integrations/ElasticSearch/V8/ElasticSearchIntegration.php b/src/DDTrace/Integrations/ElasticSearch/V8/ElasticSearchIntegration.php index bd9eeff386d..f0dae27632d 100644 --- a/src/DDTrace/Integrations/ElasticSearch/V8/ElasticSearchIntegration.php +++ b/src/DDTrace/Integrations/ElasticSearch/V8/ElasticSearchIntegration.php @@ -6,6 +6,7 @@ use DDTrace\Integrations\ElasticSearch\ElasticSearchCommon; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; @@ -60,7 +61,7 @@ public static function init(): int Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::ELASTICSEARCH; $span->resource = "__construct"; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; } ]); @@ -82,7 +83,7 @@ public static function init(): int $span->resource = 'performRequest'; Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::ELASTICSEARCH; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; /** @var Psr\Http\Message\RequestInterface $request */ $request = $args[0]; @@ -90,17 +91,17 @@ public static function init(): int try { $uri = $request->getUri(); $query = $uri->getQuery(); - $span->meta[Tag::ELASTICSEARCH_URL] = (string)$uri->withQuery(""); - $span->meta[Tag::ELASTICSEARCH_METHOD] = $request->getMethod(); - $span->meta[Tag::SPAN_KIND] = 'client'; + $span->attributes[Tag::ELASTICSEARCH_URL] = (string)$uri->withQuery(""); + $span->attributes[Tag::ELASTICSEARCH_METHOD] = $request->getMethod(); + $span->spanKind = SpanKind::CLIENT; if ($query) { parse_str($query, $queryParts); - $span->meta[Tag::ELASTICSEARCH_PARAMS] = json_encode($queryParts); + $span->attributes[Tag::ELASTICSEARCH_PARAMS] = json_encode($queryParts); } if (self::$logNextBody && ($body = $request->getBody()) && $body->isSeekable()) { $pos = $body->tell(); $body->seek(0); - $span->meta[Tag::ELASTICSEARCH_BODY] = $body->getContents(); + $span->attributes[Tag::ELASTICSEARCH_BODY] = $body->getContents(); $body->seek($pos); } } catch (\Exception $ex) { @@ -135,11 +136,11 @@ public static function traceClientMethod($name, $isTraceAnalyticsCandidate = fal self::$logNextBody = true; } - $span->meta[Tag::SPAN_KIND] = 'client'; + $span->spanKind = SpanKind::CLIENT; Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::ELASTICSEARCH; $span->resource = ElasticSearchCommon::buildResourceName($name, isset($args[0]) ? $args[0] : []); - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; }, 'posthook' => static function () { self::$logNextBody = false; @@ -160,7 +161,7 @@ public static function traceSimpleMethod($class, $name) $span->resource = $operationName; Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::ELASTICSEARCH; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; }); } @@ -182,7 +183,7 @@ public static function traceNamespaceMethod($class, $name) $span->resource = ElasticSearchCommon::buildResourceName($name, $params); Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::ELASTICSEARCH; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; }); } } diff --git a/src/DDTrace/Integrations/Eloquent/EloquentIntegration.php b/src/DDTrace/Integrations/Eloquent/EloquentIntegration.php index 4fbedb459a6..41fd2872f5d 100644 --- a/src/DDTrace/Integrations/Eloquent/EloquentIntegration.php +++ b/src/DDTrace/Integrations/Eloquent/EloquentIntegration.php @@ -4,6 +4,7 @@ use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; @@ -28,7 +29,7 @@ function (SpanData $span) { $span->name = 'eloquent.get'; $sql = $this->getQuery()->toSql(); $span->resource = $sql; - $span->meta[Tag::DB_STATEMENT] = $sql; + $span->attributes[Tag::DB_STATEMENT] = $sql; EloquentIntegration::setCommonValues($span); } ); @@ -95,9 +96,9 @@ public static function setCommonValues(SpanData $span) { $span->type = Type::SQL; Integration::handleInternalSpanServiceName($span, self::getAppName()); - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::DB_SYSTEM] = 'other_sql'; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; + $span->attributes[Tag::DB_SYSTEM] = 'other_sql'; } /** @@ -109,7 +110,7 @@ public static function getAppName() return $name; } - $name = \ddtrace_config_app_name(); + $name = \dd_trace_env_config('DD_SERVICE'); if (empty($name) && is_callable('config')) { $name = config('app.name'); } diff --git a/src/DDTrace/Integrations/Exec/ExecIntegration.php b/src/DDTrace/Integrations/Exec/ExecIntegration.php index 6d94c164129..6750f1eccfe 100644 --- a/src/DDTrace/Integrations/Exec/ExecIntegration.php +++ b/src/DDTrace/Integrations/Exec/ExecIntegration.php @@ -156,9 +156,9 @@ static function (HookData $hook) { if ($hook->returned['signaled']) { $span->attributes[Tag::ERROR_MSG] = 'The process was terminated by a signal'; - $span->attributes[Tag::EXEC_EXIT_CODE] = (string)$hook->returned['termsig']; + $span->attributes[Tag::EXEC_EXIT_CODE] = $hook->returned['termsig']; } else { - $span->attributes[Tag::EXEC_EXIT_CODE] = (string)$hook->returned['exitcode']; + $span->attributes[Tag::EXEC_EXIT_CODE] = $hook->returned['exitcode']; } self::finishSpanRestoreStack($span); @@ -197,7 +197,7 @@ static function (HookData $hook) { $exitCode = $span->attributes[Tag::EXEC_EXIT_CODE] ?? null; if ($hook->returned === -1 && $exitCode !== null) { - $hook->overrideReturnValue((int)$exitCode); + $hook->overrideReturnValue($exitCode); } } ); @@ -266,7 +266,7 @@ private static function postHookShell($variant) isset($hook->args[$retCodeArg]) && $hook->args[$retCodeArg] !== null ) { - $span->attributes[Tag::EXEC_EXIT_CODE] = (string)$hook->args[$retCodeArg]; + $span->attributes[Tag::EXEC_EXIT_CODE] = $hook->args[$retCodeArg]; } self::finishSpanRestoreStack($span); @@ -278,7 +278,8 @@ private static function createSpan(array $tags, string $resource) create_stack(); $span = start_span(); $span->name = 'command_execution'; - $span->meta = $tags; + $span->attributes = $tags + $span->attributes; + $span->component = 'subprocess'; $span->type = Type::SYSTEM; $span->resource = $resource; \DDTrace\collect_code_origins(2); // manually collect origin, otherwise the top frame will be this integration @@ -307,7 +308,6 @@ private static function createTagsShellString($cmd) $ret = [ Tag::EXEC_CMDLINE_SHELL => $cmd, - Tag::COMPONENT => 'subprocess', ]; if ($truncated) { $ret[Tag::EXEC_TRUNCATED] = true; @@ -341,7 +341,6 @@ private static function createTagsExec(array $cmd) $ret = [ Tag::EXEC_CMDLINE_EXEC => self::encodeArray($cmd), - Tag::COMPONENT => 'subprocess', ]; if ($truncated) { $ret[Tag::EXEC_TRUNCATED] = true; diff --git a/src/DDTrace/Integrations/Frankenphp/FrankenphpIntegration.php b/src/DDTrace/Integrations/Frankenphp/FrankenphpIntegration.php index 17753f0d515..23124bc7278 100644 --- a/src/DDTrace/Integrations/Frankenphp/FrankenphpIntegration.php +++ b/src/DDTrace/Integrations/Frankenphp/FrankenphpIntegration.php @@ -5,6 +5,7 @@ use DDTrace\HookData; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\SpanStack; use DDTrace\Tag; use DDTrace\Type; @@ -42,11 +43,11 @@ static function (HookData $hook) use (&$blockingException, &$rootSpan) { $blockingException = null; $rootSpan = $hook->span(new SpanStack()); $rootSpan->name = "web.request"; - $rootSpan->service = \ddtrace_config_app_name('frankenphp'); + $rootSpan->service = \dd_trace_env_config('DD_SERVICE') ?: 'frankenphp'; Integration::tagFrameworkServiceSource($rootSpan, self::NAME); $rootSpan->type = Type::WEB_SERVLET; - $rootSpan->meta[Tag::COMPONENT] = self::NAME; - $rootSpan->attributes[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_SERVER; + $rootSpan->component = self::NAME; + $rootSpan->spanKind = SpanKind::SERVER; unset($rootSpan->attributes["closure.declaration"]); consume_distributed_tracing_headers(null); diff --git a/src/DDTrace/Integrations/GoogleSpanner/GoogleSpannerIntegration.php b/src/DDTrace/Integrations/GoogleSpanner/GoogleSpannerIntegration.php index 1d73d6f1bfd..64741440823 100644 --- a/src/DDTrace/Integrations/GoogleSpanner/GoogleSpannerIntegration.php +++ b/src/DDTrace/Integrations/GoogleSpanner/GoogleSpannerIntegration.php @@ -5,6 +5,7 @@ use DDTrace\Integrations\DatabaseIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\ObjectKVStore; @@ -20,20 +21,20 @@ public static function init(): int { \DDTrace\trace_method('Google\Cloud\Spanner\SpannerClient', 'instance', function (SpanData $span, $args) { $instanceName = $args[0]; - $span->meta[Tag::DB_INSTANCE] = $instanceName; + $span->attributes[Tag::DB_INSTANCE] = $instanceName; GoogleSpannerIntegration::setDefaultAttributes($span, 'google_spanner.instance', $args[0]); ObjectKVStore::put($this, GoogleSpannerIntegration::KEY_INSTANCE_NAME, $instanceName); }); \DDTrace\trace_method('Google\Cloud\Spanner\Instance', 'database', function (SpanData $span, $args) { $dbName =$args[0]; - $span->meta[Tag::DB_NAME] = $dbName; + $span->attributes[Tag::DB_NAME] = $dbName; GoogleSpannerIntegration::setDefaultAttributes($span, 'google_spanner.database', $args[0]); ObjectKVStore::put($this, GoogleSpannerIntegration::KEY_DATABASE_NAME, $dbName); }); \DDTrace\trace_method('Google\Cloud\Spanner\Database', 'execute', function (SpanData $span, $args) { - $span->meta[Tag::DB_NAME] = $this->name(); + $span->attributes[Tag::DB_NAME] = $this->name(); GoogleSpannerIntegration::setDefaultAttributes($span, 'google_spanner.execute', $args[0]); }); @@ -66,9 +67,9 @@ public static function setDefaultAttributes(SpanData $span, $name, $resource) $span->resource = $resource; $span->type = Type::SQL; Integration::handleInternalSpanServiceName($span, self::NAME); - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::DB_SYSTEM] = self::SYSTEM; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; + $span->attributes[Tag::DB_SYSTEM] = self::SYSTEM; } } diff --git a/src/DDTrace/Integrations/Guzzle/GuzzleIntegration.php b/src/DDTrace/Integrations/Guzzle/GuzzleIntegration.php index 4e26f9f1695..32f70214142 100644 --- a/src/DDTrace/Integrations/Guzzle/GuzzleIntegration.php +++ b/src/DDTrace/Integrations/Guzzle/GuzzleIntegration.php @@ -7,6 +7,7 @@ use DDTrace\Integrations\HttpClientIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use GuzzleHttp; @@ -51,7 +52,7 @@ static function ($reason) use ($span) { public static function setStatusCode(SpanData $span, $response, $setClientError = true) { $statusCode = $response->getStatusCode(); - $span->meta[Tag::HTTP_STATUS_CODE] = $statusCode; + $span->attributes[Tag::HTTP_STATUS_CODE] = (string)$statusCode; if ($setClientError) { HttpClientIntegrationHelper::setClientError($span, $statusCode, $response->getReasonPhrase()); } @@ -74,8 +75,8 @@ static function (HookData $hook) { $span->name = 'GuzzleHttp\Client.transfer'; Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::HTTP_CLIENT; - $span->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_CLIENT; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; $span->peerServiceSources = HttpClientIntegrationHelper::PEER_SERVICE_SOURCES; if (isset($hook->args[0])) { @@ -85,7 +86,7 @@ static function (HookData $hook) { // Note: We must ALWAYS call overrideArguments() to prevent JIT compilation issues. // See ext/hook/uhook.c: "hooks wishing to override args must do so unconditionally" - if (\ddtrace_config_distributed_tracing_enabled() !== false) { + if (\dd_trace_env_config('DD_DISTRIBUTED_TRACING') !== false) { if (isset($hook->args[0])) { $request = $hook->args[0]; @@ -131,8 +132,8 @@ static function (SpanData $span, $args, $retval, $exception) { $span->name = 'GuzzleHttp\Client.send'; Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::HTTP_CLIENT; - $span->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_CLIENT; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; if ( \defined('GuzzleHttp\ClientInterface::VERSION') @@ -170,31 +171,31 @@ public static function addRequestInfo(SpanData $span, $request) if ($request instanceof \Psr\Http\Message\RequestInterface) { $url = $request->getUri(); $host = Urls::hostname($url); - $span->meta[Tag::NETWORK_DESTINATION_NAME] = $host; + $span->attributes[Tag::NETWORK_DESTINATION_NAME] = $host; if (\dd_trace_env_config("DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN")) { $span->service = Urls::hostnameForTag($url); $span->attributes['_dd.svc_src'] = 'opt.http_client_split_by_domain'; } - $span->meta[Tag::HTTP_METHOD] = $request->getMethod(); + $span->attributes[Tag::HTTP_METHOD] = $request->getMethod(); - if (!array_key_exists(Tag::HTTP_URL, $span->meta)) { - $span->meta[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($url); + if (!array_key_exists(Tag::HTTP_URL, $span->attributes)) { + $span->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($url); } } elseif ($request instanceof \GuzzleHttp\Message\RequestInterface) { $url = $request->getUrl(); $host = Urls::hostname($url); if ($host) { - $span->meta[Tag::NETWORK_DESTINATION_NAME] = $host; + $span->attributes[Tag::NETWORK_DESTINATION_NAME] = $host; } if (\dd_trace_env_config("DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN")) { $span->service = Urls::hostnameForTag($url); $span->attributes['_dd.svc_src'] = 'opt.http_client_split_by_domain'; } - $span->meta[Tag::HTTP_METHOD] = $request->getMethod(); + $span->attributes[Tag::HTTP_METHOD] = $request->getMethod(); - if (!array_key_exists(Tag::HTTP_URL, $span->meta)) { - $span->meta[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($url); + if (!array_key_exists(Tag::HTTP_URL, $span->attributes)) { + $span->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($url); } } } diff --git a/src/DDTrace/Integrations/HttpClientIntegrationHelper.php b/src/DDTrace/Integrations/HttpClientIntegrationHelper.php index d373dd0cd82..72173600860 100644 --- a/src/DDTrace/Integrations/HttpClientIntegrationHelper.php +++ b/src/DDTrace/Integrations/HttpClientIntegrationHelper.php @@ -70,20 +70,20 @@ public static function isClientError($statusCode) { */ public static function setClientError($span, $statusCode, $reasonPhrase = null) { // Preserve more specific errors, such as a cURL timeout after receiving HTTP headers. - if (isset($span->meta[Tag::ERROR]) - || isset($span->meta[Tag::ERROR_TYPE]) - || isset($span->meta[Tag::ERROR_MSG]) + if (isset($span->attributes[Tag::ERROR]) + || isset($span->attributes[Tag::ERROR_TYPE]) + || isset($span->attributes[Tag::ERROR_MSG]) ) { return false; } if (self::isClientError($statusCode)) { - $span->meta[Tag::ERROR_TYPE] = 'http_error'; + $span->attributes[Tag::ERROR_TYPE] = 'http_error'; if ($reasonPhrase) { - $span->meta[Tag::ERROR_MSG] = "HTTP $statusCode: $reasonPhrase"; + $span->attributes[Tag::ERROR_MSG] = "HTTP $statusCode: $reasonPhrase"; } else { - $span->meta[Tag::ERROR_MSG] = "HTTP $statusCode Error"; + $span->attributes[Tag::ERROR_MSG] = "HTTP $statusCode Error"; } return true; diff --git a/src/DDTrace/Integrations/Integration.php b/src/DDTrace/Integrations/Integration.php index 61c06f79469..99d5139a646 100644 --- a/src/DDTrace/Integrations/Integration.php +++ b/src/DDTrace/Integrations/Integration.php @@ -65,7 +65,7 @@ public static function handleInternalSpanServiceName(SpanData $span, string $fal $rootSpan = null; if ($flatServiceNames) { $rootSpan = \DDTrace\root_span(); - $service = $rootSpan ? $rootSpan->service : \ddtrace_config_app_name($fallbackName); + $service = $rootSpan ? $rootSpan->service : (\dd_trace_env_config('DD_SERVICE') ?: $fallbackName); } else { $service = $fallbackName; } @@ -109,7 +109,7 @@ public static function setComponentMetadata(SpanData $span, $component, $service $span->service = $service ?? $component; $span->attributes['_dd.svc_src'] = $component; } - $span->meta[Tag::COMPONENT] = $component; + $span->component = $component; } public static function handleOrphan(SpanData $span) diff --git a/src/DDTrace/Integrations/Kafka/KafkaIntegration.php b/src/DDTrace/Integrations/Kafka/KafkaIntegration.php index 99d8e0550ec..79b5344627e 100644 --- a/src/DDTrace/Integrations/Kafka/KafkaIntegration.php +++ b/src/DDTrace/Integrations/Kafka/KafkaIntegration.php @@ -4,6 +4,7 @@ use DDTrace\HookData; use DDTrace\Integrations\Integration; +use DDTrace\SpanKind; use DDTrace\SpanLink; use DDTrace\Tag; use DDTrace\Type; @@ -46,15 +47,15 @@ static function (HookData $hook) { public static function setupKafkaProduceSpan(HookData $hook, \RdKafka\ProducerTopic $producerTopic) { $span = $hook->span(); - self::setupCommonSpanMetadata($span, Tag::KAFKA_PRODUCE, Tag::SPAN_KIND_VALUE_PRODUCER, Tag::MQ_OPERATION_SEND); + self::setupCommonSpanMetadata($span, Tag::KAFKA_PRODUCE, SpanKind::PRODUCER, Tag::MQ_OPERATION_SEND); - $span->meta[Tag::MQ_DESTINATION] = $producerTopic->getName(); - $span->meta[Tag::MQ_DESTINATION_KIND] = Type::QUEUE; + $span->attributes[Tag::MQ_DESTINATION] = $producerTopic->getName(); + $span->attributes[Tag::MQ_DESTINATION_KIND] = Type::QUEUE; $conf = ObjectKVStore::get($producerTopic, 'conf'); self::addProducerSpanMetadata($span, $conf, $hook->args); - if (\ddtrace_config_distributed_tracing_enabled()) { + if (\dd_trace_env_config('DD_DISTRIBUTED_TRACING')) { $headers = \DDTrace\generate_distributed_tracing_headers(); $hook->args = self::injectHeadersIntoArgs($hook->args, $headers); $hook->overrideArguments($hook->args); @@ -64,10 +65,10 @@ public static function setupKafkaProduceSpan(HookData $hook, \RdKafka\ProducerTo public static function addProducerSpanMetadata($span, $conf, $args) { self::addMetadataToSpan($span, $conf); - $span->metrics[Tag::KAFKA_PARTITION] = $args[0]; - $span->metrics[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = strlen($args[2]); + $span->attributes[Tag::KAFKA_PARTITION] = $args[0]; + $span->attributes[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = strlen($args[2]); if (isset($args[3])) { - $span->meta[Tag::KAFKA_MESSAGE_KEY] = $args[3]; + $span->attributes[Tag::KAFKA_MESSAGE_KEY] = $args[3]; } } @@ -124,17 +125,17 @@ static function (HookData $hook) { $span = \DDTrace\start_span($hook->data['start']); } - $span->meta[Tag::MQ_DESTINATION] = $message->topic_name; - $span->meta[Tag::MQ_DESTINATION_KIND] = Type::QUEUE; - $span->metrics[Tag::KAFKA_PARTITION] = $message->partition; - $span->metrics[Tag::KAFKA_MESSAGE_OFFSET] = $message->offset; - $span->metrics[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = strlen($message->payload ?? ''); + $span->attributes[Tag::MQ_DESTINATION] = $message->topic_name; + $span->attributes[Tag::MQ_DESTINATION_KIND] = Type::QUEUE; + $span->attributes[Tag::KAFKA_PARTITION] = $message->partition; + $span->attributes[Tag::KAFKA_MESSAGE_OFFSET] = $message->offset; + $span->attributes[Tag::MQ_MESSAGE_PAYLOAD_SIZE] = strlen($message->payload ?? ''); } else { $span = \DDTrace\start_span($hook->data['start']); } if (!$message || $message->payload === null || $message->err === RD_KAFKA_RESP_ERR__PARTITION_EOF) { - $span->meta[Tag::KAFKA_TOMBSTONE] = true; + $span->attributes[Tag::KAFKA_TOMBSTONE] = true; } $hook->data['span'] = $span; @@ -149,7 +150,7 @@ static function (HookData $hook) { public static function setupKafkaConsumeSpan(HookData $hook, $consumer) { $span = $hook->data['span']; - self::setupCommonSpanMetadata($span, Tag::KAFKA_CONSUME, Tag::SPAN_KIND_VALUE_CONSUMER, Tag::MQ_OPERATION_RECEIVE); + self::setupCommonSpanMetadata($span, Tag::KAFKA_CONSUME, SpanKind::CONSUMER, Tag::MQ_OPERATION_RECEIVE); $conf = ObjectKVStore::get($consumer, 'conf'); self::addMetadataToSpan($span, $conf); @@ -159,19 +160,19 @@ private static function addMetadataToSpan($span, $conf) { foreach (self::METADATA_MAPPING as $configKey => $tagKey) { if (isset($conf[$configKey])) { - $span->meta[$tagKey] = $conf[$configKey]; + $span->attributes[$tagKey] = $conf[$configKey]; } } } - public static function setupCommonSpanMetadata($span, string $name, string $spanKind, string $operation) + public static function setupCommonSpanMetadata($span, string $name, int $spanKind, string $operation) { $span->name = $name; $span->type = Type::QUEUE; - $span->meta[Tag::SPAN_KIND] = $spanKind; - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::MQ_SYSTEM] = self::NAME; - $span->meta[Tag::MQ_OPERATION] = $operation; + $span->spanKind = $spanKind; + $span->component = self::NAME; + $span->attributes[Tag::MQ_SYSTEM] = self::NAME; + $span->attributes[Tag::MQ_OPERATION] = $operation; } private static function installConfigurationHooks() diff --git a/src/DDTrace/Integrations/Laminas/LaminasIntegration.php b/src/DDTrace/Integrations/Laminas/LaminasIntegration.php index d148f4af9d9..7f0bc90ab5e 100644 --- a/src/DDTrace/Integrations/Laminas/LaminasIntegration.php +++ b/src/DDTrace/Integrations/Laminas/LaminasIntegration.php @@ -6,6 +6,7 @@ use DDTrace\Integrations\Integration; use DDTrace\Integrations\Logs\LogsIntegration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\Normalizer; @@ -175,10 +176,10 @@ static function (SpanData $span) { $rootSpan = root_span(); $rootSpan->name = 'laminas.request'; - $rootSpan->service = \ddtrace_config_app_name('laminas'); + $rootSpan->service = \dd_trace_env_config('DD_SERVICE') ?: 'laminas'; Integration::tagFrameworkServiceSource($rootSpan, 'laminas'); - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; - $rootSpan->meta[Tag::COMPONENT] = self::NAME; + $rootSpan->spanKind = SpanKind::SERVER; + $rootSpan->component = self::NAME; } ); @@ -217,7 +218,7 @@ static function (SpanData $span) { 'run', [ 'prehook' => static function (SpanData $span) { - $service = \ddtrace_config_app_name('laminas'); + $service = \dd_trace_env_config('DD_SERVICE') ?: 'laminas'; $span->name = 'laminas.application.run'; $span->type = Type::WEB_SERVLET; Integration::setComponentMetadata($span, 'laminas', $service); @@ -232,14 +233,14 @@ static function (SpanData $span) { function (SpanData $span, $args, $retval) { $span->name = 'laminas.route.match'; $span->resource = \get_class($this) . '@match'; - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; /** @var RequestInterface $request */ $request = $args[0]; $rootSpan = root_span(); $rootSpan->attributes[Tag::HTTP_METHOD] = $request->getMethod(); - $rootSpan->meta[Tag::HTTP_VERSION] = $request->getVersion(); + $rootSpan->attributes[Tag::HTTP_VERSION] = $request->getVersion(); $rootSpan->attributes[Tag::HTTP_URL] = Normalizer::urlSanitize($request->getUriString()); $routeMatch = $retval; @@ -260,7 +261,7 @@ function (SpanData $span, $args, $retval) { static function (SpanData $span) use ($controller, $action) { $span->name = 'laminas.controller.action'; $span->resource = "$controller@{$action}Action"; - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; } ); } @@ -268,8 +269,8 @@ static function (SpanData $span) use ($controller, $action) { if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { $rootSpan->resource = "$controller@$action $routeName"; } - $rootSpan->meta['laminas.route.name'] = $routeName; - $rootSpan->meta['laminas.route.action'] = "$controller@$action"; + $rootSpan->attributes['laminas.route.name'] = $routeName; + $rootSpan->attributes['laminas.route.action'] = "$controller@$action"; $isTopLevelRouterMatch = $this instanceof \Laminas\Router\Http\TreeRouteStack && !($this instanceof \Laminas\Router\Http\Part); @@ -281,7 +282,7 @@ static function (SpanData $span) use ($controller, $action) { ) { $httpRoute = LaminasIntegration::httpRouteTemplateFromNamedRouteStack($this, (string) $routeName); if ($httpRoute !== null && $httpRoute !== '') { - $rootSpan->meta[Tag::HTTP_ROUTE] = $httpRoute; + $rootSpan->attributes[Tag::HTTP_ROUTE] = $httpRoute; } } @@ -354,7 +355,7 @@ static function ($This, $scope, $args) { function (SpanData $span) { $span->name = 'laminas.controller.dispatch'; $span->resource = \get_class($this); - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; } ); @@ -384,10 +385,10 @@ static function ($This, $score, $args) { 'completeRequest', static function (SpanData $span, $args) { $span->name = 'laminas.application.completeRequest'; - $span->service = \ddtrace_config_app_name('laminas'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'laminas'; Integration::tagFrameworkServiceSource($span, 'laminas'); $span->type = Type::WEB_SERVLET; - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; /** @var MvcEvent $event */ $event = $args[0]; @@ -407,10 +408,10 @@ static function (SpanData $span, $args) { [ 'prehook' => static function (SpanData $span, $args) { $span->name = 'laminas.templating.render'; - $span->service = \ddtrace_config_app_name('laminas'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'laminas'; Integration::tagFrameworkServiceSource($span, 'laminas'); $span->type = Type::WEB_SERVLET; - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; $nameOrModel = $args[0]; if (is_string($nameOrModel)) { @@ -428,10 +429,10 @@ static function (SpanData $span, $args) { 'render', static function (SpanData $span) { $span->name = 'laminas.view.render'; - $span->service = \ddtrace_config_app_name('laminas'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'laminas'; Integration::tagFrameworkServiceSource($span, 'laminas'); $span->type = Type::WEB_SERVLET; - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; } ); @@ -440,10 +441,10 @@ static function (SpanData $span) { 'serialize', function (SpanData $span) { $span->name = 'laminas.view.model.serialize'; - $span->service = \ddtrace_config_app_name('laminas'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'laminas'; Integration::tagFrameworkServiceSource($span, 'laminas'); $span->resource = \get_class($this); - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; } ); @@ -452,11 +453,11 @@ function (SpanData $span) { 'render', function (SpanData $span, $args) { $span->name = 'laminas.view.http.renderer'; - $span->service = \ddtrace_config_app_name('laminas'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'laminas'; Integration::tagFrameworkServiceSource($span, 'laminas'); $span->type = Type::WEB_SERVLET; $span->resource = \get_class($this) . '@render'; - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; /** @var MvcEvent $event */ $event = $args[0]; @@ -473,11 +474,11 @@ function (SpanData $span, $args) { 'render', function (SpanData $span, $args) { $span->name = 'laminas.view.console.renderer'; - $span->service = \ddtrace_config_app_name('laminas'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'laminas'; Integration::tagFrameworkServiceSource($span, 'laminas'); $span->type = Type::WEB_SERVLET; $span->resource = \get_class($this) . '@render'; - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; /** @var MvcEvent $event */ $event = $args[0]; @@ -495,10 +496,10 @@ function (SpanData $span, $args) { 'setError', static function (SpanData $span, $args, $retval) { $span->name = 'laminas.mvcEvent.setError'; - $span->service = \ddtrace_config_app_name('laminas'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'laminas'; Integration::tagFrameworkServiceSource($span, 'laminas'); $span->type = Type::WEB_SERVLET; - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; /** @var MvcEvent $event */ $event = $retval; @@ -522,10 +523,10 @@ static function (SpanData $span, $args, $retval) { 'get', static function (SpanData $span, $args) { $span->name = 'laminas.controller.pluginManager.get'; - $span->service = \ddtrace_config_app_name('laminas'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'laminas'; Integration::tagFrameworkServiceSource($span, 'laminas'); $span->resource = $args[0]; - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; } ); @@ -563,8 +564,8 @@ static function ($This, $scope, $args) { $routeName = $event->getRouteMatch()->getMatchedRouteName(); $rootSpan->resource = "$controller@$eventName $routeName"; - $rootSpan->meta['laminas.route.name'] = $routeName; - $rootSpan->meta['laminas.route.action'] = $controller . '@' . $eventName; + $rootSpan->attributes['laminas.route.name'] = $routeName; + $rootSpan->attributes['laminas.route.action'] = $controller . '@' . $eventName; if (isset($eventName, self::$EVENT_TYPES)) { install_hook( @@ -573,7 +574,7 @@ static function (HookData $hook) use ($controller, $eventName) { $span = $hook->span(); $span->name = 'laminas.controller.action'; $span->resource = "$controller@$eventName"; - $span->meta[Tag::COMPONENT] = 'laminas'; + $span->component = 'laminas'; remove_hook($hook->id); } ); @@ -602,9 +603,9 @@ static function (HookData $hook) { ObjectKVStore::put($hook->instance, 'backtrace', $backtrace); if ($activeSpan !== null && !Integration::hasTag($activeSpan, Tag::ERROR_TYPE)) { - $activeSpan->meta[Tag::ERROR_TYPE] = 'ApiProblem'; - $activeSpan->meta[Tag::ERROR_MSG] = $detail; - $activeSpan->meta[Tag::ERROR_STACK] = $backtrace; + $activeSpan->attributes[Tag::ERROR_TYPE] = 'ApiProblem'; + $activeSpan->attributes[Tag::ERROR_MSG] = $detail; + $activeSpan->attributes[Tag::ERROR_STACK] = $backtrace; } } // There shouldn't be any other case, per the ApiProblem spec } @@ -635,12 +636,12 @@ static function ($This, $scope, $args) { $rootSpan->exception = $detail; } elseif (is_string($detail)) { $title = $apiProblem->title; // __get - $rootSpan->meta[Tag::ERROR_TYPE] = $title ?: 'ApiProblem'; - $rootSpan->meta[Tag::ERROR_MSG] = $detail; + $rootSpan->attributes[Tag::ERROR_TYPE] = $title ?: 'ApiProblem'; + $rootSpan->attributes[Tag::ERROR_MSG] = $detail; $backtrace = ObjectKVStore::get($apiProblem, 'backtrace'); if ($backtrace !== null) { - $rootSpan->meta[Tag::ERROR_STACK] = $backtrace; + $rootSpan->attributes[Tag::ERROR_STACK] = $backtrace; } } // There shouldn't be any other case, per the ApiProblem spec } diff --git a/src/DDTrace/Integrations/Laravel/LaravelIntegration.php b/src/DDTrace/Integrations/Laravel/LaravelIntegration.php index aaa393a9937..3b8ba63cbd5 100644 --- a/src/DDTrace/Integrations/Laravel/LaravelIntegration.php +++ b/src/DDTrace/Integrations/Laravel/LaravelIntegration.php @@ -5,6 +5,7 @@ use DDTrace\HookData; use DDTrace\Integrations\Lumen\LumenIntegration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Integrations\Integration; use DDTrace\Tag; use DDTrace\Type; @@ -55,19 +56,19 @@ static function (SpanData $span, $args, $response) { $span->service = self::getServiceName(); Integration::tagFrameworkServiceSource($span, LaravelIntegration::NAME); $span->resource = 'Illuminate\Foundation\Application@handle'; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; $rootSpan = \DDTrace\root_span(); // Overwriting the default web integration $rootSpan->name = 'laravel.request'; if (\method_exists($response, 'getStatusCode')) { - $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = $response->getStatusCode(); + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = (string)$response->getStatusCode(); } $rootSpan->service = self::getServiceName(); Integration::tagFrameworkServiceSource($rootSpan, LaravelIntegration::NAME); - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; - $rootSpan->meta[Tag::COMPONENT] = self::NAME; + $rootSpan->spanKind = SpanKind::SERVER; + $rootSpan->component = self::NAME; } ); @@ -75,7 +76,7 @@ static function (SpanData $span, $args, $response) { 'Illuminate\Contracts\Foundation\Application', 'bootstrapWith', static function ($app) { - self::$serviceName = ddtrace_config_app_name(); + self::$serviceName = \dd_trace_env_config('DD_SERVICE'); if (self::$serviceName == "" && file_exists($app->environmentPath() . '/' . $app->environmentFile())) { $app->make('Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables')->bootstrap($app); $configPath = realpath($app->configPath()); @@ -122,14 +123,14 @@ static function ($This, $scope, $args, $route) { } } - $rootSpan->meta['laravel.route.name'] = $routeName; - $rootSpan->meta['laravel.route.action'] = $route->getActionName(); + $rootSpan->attributes['laravel.route.name'] = $routeName; + $rootSpan->attributes['laravel.route.action'] = $route->getActionName(); if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($request->fullUrl()); } if (\method_exists($route, 'uri')) { - $rootSpan->meta[Tag::HTTP_ROUTE] = $route->uri(); + $rootSpan->attributes[Tag::HTTP_ROUTE] = $route->uri(); } if (\method_exists($route, 'parameters') && function_exists('\datadog\appsec\push_addresses')) { $parameters = $route->parameters(); @@ -138,7 +139,7 @@ static function ($This, $scope, $args, $route) { } } $rootSpan->attributes[Tag::HTTP_METHOD] = $request->method(); - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; + $rootSpan->spanKind = SpanKind::SERVER; if (!\DDTrace\are_endpoints_collected()) { $routeCollection = $This->getRoutes(); @@ -163,7 +164,7 @@ function (SpanData $span) { $span->service = LaravelIntegration::getServiceName(); Integration::tagFrameworkServiceSource($span, LaravelIntegration::NAME); $span->resource = $this->uri; - $span->meta[Tag::COMPONENT] = LaravelIntegration::NAME; + $span->component = LaravelIntegration::NAME; } ); @@ -195,7 +196,7 @@ function ($This, $scope, $args) { $span->service = self::getServiceName(); Integration::tagFrameworkServiceSource($span, LaravelIntegration::NAME); $span->resource = $args[0]; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; //New user created, assume sign up if ($span->resource == 'eloquent.created: User') { @@ -235,7 +236,7 @@ function ($This, $scope, $args) { $span->service = self::getServiceName(); Integration::tagFrameworkServiceSource($span, LaravelIntegration::NAME); $span->resource = is_object($args[0]) ? get_class($args[0]) : $args[0]; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; }, 'recurse' => true, ] @@ -247,7 +248,7 @@ function ($This, $scope, $args) { $span->service = LaravelIntegration::getServiceName(); Integration::tagFrameworkServiceSource($span, LaravelIntegration::NAME); $span->resource = $this->view; - $span->meta[Tag::COMPONENT] = LaravelIntegration::NAME; + $span->component = LaravelIntegration::NAME; }); \DDTrace\trace_method( @@ -259,7 +260,7 @@ static function (SpanData $span, $args) { // This is used by both laravel and lumen. For consistency we rename it for lumen traces as otherwise // users would see a span changing name as they upgrade to the new version. $span->name = self::isLumen($rootSpan) ? 'lumen.view' : 'laravel.view'; - $span->meta[Tag::COMPONENT] = $span->name === 'laravel.view' + $span->component = $span->name === 'laravel.view' ? self::NAME : LumenIntegration::NAME; $span->type = Type::WEB_SERVLET; @@ -282,7 +283,7 @@ static function (SpanData $span) { $span->service = $serviceName; Integration::tagFrameworkServiceSource($span, LaravelIntegration::NAME); $span->resource = 'Illuminate\Foundation\ProviderRepository::load'; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; Integration::handleOrphan($span); @@ -303,8 +304,8 @@ static function () { $rootSpan->name = 'laravel.artisan'; $rootSpan->resource = !empty($_SERVER['argv'][1]) ? 'artisan ' . $_SERVER['argv'][1] : 'artisan'; - unset($rootSpan->attributes[Tag::SPAN_KIND]); - $rootSpan->meta[Tag::COMPONENT] = self::NAME; + $rootSpan->spanKind = SpanKind::UNSPECIFIED; + $rootSpan->component = self::NAME; } ); @@ -643,7 +644,7 @@ public static function getServiceName() if (!empty(self::$serviceName)) { return self::$serviceName; } - self::$serviceName = \ddtrace_config_app_name(); + self::$serviceName = \dd_trace_env_config('DD_SERVICE'); try { if (empty(self::$serviceName) && is_callable('config')) { self::$serviceName = config('app.name'); diff --git a/src/DDTrace/Integrations/LaravelQueue/LaravelQueueIntegration.php b/src/DDTrace/Integrations/LaravelQueue/LaravelQueueIntegration.php index b3e6f624795..92b75e6d2e3 100644 --- a/src/DDTrace/Integrations/LaravelQueue/LaravelQueueIntegration.php +++ b/src/DDTrace/Integrations/LaravelQueue/LaravelQueueIntegration.php @@ -6,6 +6,7 @@ use DDTrace\Integrations\Integration; use DDTrace\Propagator; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\SpanLink; use DDTrace\Tag; use DDTrace\Util\ObjectKVStore; @@ -168,10 +169,10 @@ function (HookData $hook) use ($class, $method, $fireHook) { $span->service = LaravelQueueIntegration::getServiceName(); Integration::tagFrameworkServiceSource($span, LaravelQueueIntegration::NAME); $span->resource = $class . '@' . $method; - $span->meta[Tag::COMPONENT] = LaravelQueueIntegration::NAME; + $span->component = LaravelQueueIntegration::NAME; if (isset($this->batchId)) { // Uses the Batchable trait; Laravel 8 - $span->meta[Tag::LARAVELQ_BATCH_ID] = $this->batchId ?? null; + $span->attributes[Tag::LARAVELQ_BATCH_ID] = $this->batchId ?? null; } if (isset($this->job)) { @@ -277,7 +278,7 @@ function (SpanData $span, $args, $retval, $exception) { get_class($this) ); if ($retval) { - $span->meta[Tag::LARAVELQ_BATCH_ID] = $retval->id; + $span->attributes[Tag::LARAVELQ_BATCH_ID] = $retval->id; } } ); @@ -298,17 +299,17 @@ public static function setSpanAttributes( $span->service = self::getServiceName(); Integration::tagFrameworkServiceSource($span, LaravelQueueIntegration::NAME); $span->type = 'queue'; - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; if ($operation) { - $span->meta[Tag::MQ_OPERATION] = $operation; + $span->attributes[Tag::MQ_OPERATION] = $operation; } if ($job instanceof Job) { $jobName = $job->resolveName(); - $span->meta = array_merge( - $span->meta, + $span->attributes = array_merge( + $span->attributes, self::getMetadataFromJob($job) ); $queue = $queue ?? $job->getQueue(); @@ -317,11 +318,11 @@ public static function setSpanAttributes( $connectionName = $job->connection ?? config('queue.default'); $queue = $queue ?? ($job->queue ?? (config("queue.connections.$connectionName.queue") ?? 'default')); - $span->meta[Tag::LARAVELQ_NAME] = $jobName; - $span->meta[Tag::LARAVELQ_CONNECTION] = $connectionName; - $span->meta[Tag::MQ_DESTINATION] = $queue; - $span->meta = array_merge( - $span->meta, + $span->attributes[Tag::LARAVELQ_NAME] = $jobName; + $span->attributes[Tag::LARAVELQ_CONNECTION] = $connectionName; + $span->attributes[Tag::MQ_DESTINATION] = $queue; + $span->attributes = array_merge( + $span->attributes, self::getMetadataFromObject($job) ); } else { @@ -348,7 +349,7 @@ public static function getMetadataFromJob(Job $job) Tag::LARAVELQ_TIMEOUT => $job->timeout(), Tag::LARAVELQ_NAME => $job->resolveName(), Tag::MQ_SYSTEM => 'laravel', - Tag::MQ_MESSAGE_ID => $job->getJobId(), + Tag::MQ_MESSAGE_ID => (string)$job->getJobId(), Tag::MQ_DESTINATION => $job->getQueue(), Tag::MQ_DESTINATION_KIND => 'queue', ]; @@ -380,7 +381,7 @@ public static function getMetadataFromObject($job) public static function injectContext(array $payload) { - if (!\ddtrace_config_distributed_tracing_enabled()) { + if (!\dd_trace_env_config('DD_DISTRIBUTED_TRACING')) { return $payload; } @@ -401,7 +402,7 @@ public static function getServiceName() if (!empty(self::$serviceName)) { return self::$serviceName; } - self::$serviceName = \ddtrace_config_app_name(); + self::$serviceName = \dd_trace_env_config('DD_SERVICE'); try { if (empty(self::$serviceName) && is_callable('config')) { self::$serviceName = config('app.name'); diff --git a/src/DDTrace/Integrations/Logs/LogsIntegration.php b/src/DDTrace/Integrations/Logs/LogsIntegration.php index 77e142241f1..4177a5a7250 100644 --- a/src/DDTrace/Integrations/Logs/LogsIntegration.php +++ b/src/DDTrace/Integrations/Logs/LogsIntegration.php @@ -46,22 +46,23 @@ public static function getPlaceholders( '%dd.span_id%' => 'dd.span_id="' . ($spanIdSubstitute ?? dd_trace_peek_span_id()) . '"', ]; - $appName = ddtrace_config_app_name(); + $appName = \dd_trace_env_config('DD_SERVICE'); if ($appName) { $placeholders['%dd.service%'] = 'dd.service="' . $appName . '"'; } else { $placeholders['%dd.service%'] = ''; } - $currentContext = \DDTrace\current_context(); - if ($currentContext['version']) { - $placeholders['%dd.version%'] = 'dd.version="' . $currentContext['version'] . '"'; + $version = \dd_trace_env_config('DD_VERSION'); + if ($version) { + $placeholders['%dd.version%'] = 'dd.version="' . $version . '"'; } else { $placeholders['%dd.version%'] = ''; } - if ($currentContext['env']) { - $placeholders['%dd.env%'] = 'dd.env="' . $currentContext['env'] . '"'; + $env = \dd_trace_env_config('DD_ENV'); + if ($env) { + $placeholders['%dd.env%'] = 'dd.env="' . $env . '"'; } else { $placeholders['%dd.env%'] = ''; } @@ -131,18 +132,19 @@ public static function addTraceIdentifiersToContext( $context['dd.span_id'] = $spanIdSubstitute ?? dd_trace_peek_span_id(); } - $service = ddtrace_config_app_name(); + $service = \dd_trace_env_config('DD_SERVICE'); if ($service && !isset($context['dd.service'])) { $context['dd.service'] = $service; } - $currentContext = \DDTrace\current_context(); - if ($currentContext['version'] && !isset($context['dd.version'])) { - $context['dd.version'] = $currentContext['version']; + $version = \dd_trace_env_config('DD_VERSION'); + if ($version && !isset($context['dd.version'])) { + $context['dd.version'] = $version; } - if ($currentContext['env'] && !isset($context['dd.env'])) { - $context['dd.env'] = $currentContext['env']; + $env = \dd_trace_env_config('DD_ENV'); + if ($env && !isset($context['dd.env'])) { + $context['dd.env'] = $env; } return $context; diff --git a/src/DDTrace/Integrations/Lumen/LumenIntegration.php b/src/DDTrace/Integrations/Lumen/LumenIntegration.php index 0e8045defa7..c4ec11f4d52 100644 --- a/src/DDTrace/Integrations/Lumen/LumenIntegration.php +++ b/src/DDTrace/Integrations/Lumen/LumenIntegration.php @@ -3,6 +3,7 @@ namespace DDTrace\Integrations\Lumen; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Integrations\Integration; use DDTrace\Tag; @@ -24,8 +25,8 @@ public static function init(): int static function () { $rootSpan = \DDTrace\root_span(); if ($rootSpan !== null) { - $rootSpan->meta[Tag::COMPONENT] = self::NAME; - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; + $rootSpan->component = self::NAME; + $rootSpan->spanKind = SpanKind::SERVER; } } ); @@ -34,12 +35,12 @@ static function () { 'Laravel\Lumen\Application', 'prepareRequest', static function (SpanData $span, $args) { - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; $rootSpan = \DDTrace\root_span(); $request = $args[0]; $rootSpan->name = 'lumen.request'; - $rootSpan->service = \ddtrace_config_app_name(self::NAME); + $rootSpan->service = \dd_trace_env_config('DD_SERVICE') ?: self::NAME; Integration::tagFrameworkServiceSource($rootSpan, LumenIntegration::NAME); if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($request->getUri()); @@ -60,7 +61,7 @@ static function (SpanData $span, $args) { $hook => static function (SpanData $span, $args) { $rootSpan = \DDTrace\root_span(); - $span->service = \ddtrace_config_app_name(self::NAME); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: self::NAME; Integration::tagFrameworkServiceSource($span, LumenIntegration::NAME); $span->type = 'web'; @@ -69,15 +70,15 @@ static function (SpanData $span, $args) { } $routeInfo = $args[0]; $resourceName = null; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; if (isset($routeInfo[1]['uses'])) { $action = $routeInfo[1]['uses']; - $rootSpan->meta['lumen.route.action'] = $action; - $span->meta['lumen.route.action'] = $action; + $rootSpan->attributes['lumen.route.action'] = $action; + $span->attributes['lumen.route.action'] = $action; } if (isset($routeInfo[1]['as'])) { $routeAlias = $routeInfo[1]['as']; - $rootSpan->meta['lumen.route.name'] = $routeAlias; + $rootSpan->attributes['lumen.route.name'] = $routeAlias; $span->resource = $routeAlias; $resourceName = $routeAlias; } @@ -86,7 +87,7 @@ static function (SpanData $span, $args) { && !\dd_trace_env_config("DD_TRACE_URL_AS_RESOURCE_NAMES_ENABLED") && \dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING") ) { - $method = $rootSpan->attributes[Tag::HTTP_METHOD] ?? $rootSpan->meta[Tag::HTTP_METHOD]; + $method = $rootSpan->attributes[Tag::HTTP_METHOD]; $rootSpan->resource = $method . ' ' . $resourceName; } }, @@ -94,14 +95,14 @@ static function (SpanData $span, $args) { ); $exceptionRender = static function (SpanData $span, $args) { - $span->service = \ddtrace_config_app_name(self::NAME); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: self::NAME; Integration::tagFrameworkServiceSource($span, LumenIntegration::NAME); $span->type = 'web'; if (count($args) < 1 || !\is_a($args[0], 'Throwable')) { return; } - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; $rootSpan = \DDTrace\root_span(); $exception = $args[0]; diff --git a/src/DDTrace/Integrations/Magento/MagentoIntegration.php b/src/DDTrace/Integrations/Magento/MagentoIntegration.php index 89073e57ccd..af45613a377 100644 --- a/src/DDTrace/Integrations/Magento/MagentoIntegration.php +++ b/src/DDTrace/Integrations/Magento/MagentoIntegration.php @@ -5,6 +5,7 @@ use DDTrace\HookData; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use Magento\Framework\Interception\InterceptorInterface; @@ -35,8 +36,8 @@ public static function setCommonSpanInfo(SpanData $span, $name, $resource = null { $span->name = $name; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name('magento'); - $span->meta[Tag::COMPONENT] = 'magento'; + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'magento'; + $span->component = 'magento'; $span->resource = $resource ?? $span->resource; } @@ -73,13 +74,13 @@ static function (SpanData $span, $args, $area) { self::setCommonSpanInfo($span, 'magento.area.get'); $frontName = $args[0]; - $span->meta['magento.area'] = root_span()->meta['magento.area'] = $area; + $span->attributes['magento.area'] = root_span()->attributes['magento.area'] = $area; if (empty($frontName)) { $span->resource = $area; } else { $span->resource = "$frontName:$area"; - $span->meta['magento.frontname'] = $frontName; + $span->attributes['magento.frontname'] = $frontName; } } ); @@ -92,11 +93,11 @@ static function (SpanData $span, $args, $area) { static function ($staticResource, $scope, $args, $retval) { $rootSpan = root_span(); if ($rootSpan !== null) { - $rootSpan->meta['magento.static.path'] = $args[0]; - $rootSpan->meta['magento.static.area'] = $retval['area']; - $rootSpan->meta['magento.static.theme'] = $retval['theme']; - $rootSpan->meta['magento.static.locale'] = $retval['locale']; - $rootSpan->meta['magento.static.file'] = $retval['file']; + $rootSpan->attributes['magento.static.path'] = $args[0]; + $rootSpan->attributes['magento.static.area'] = $retval['area']; + $rootSpan->attributes['magento.static.theme'] = $retval['theme']; + $rootSpan->attributes['magento.static.locale'] = $retval['locale']; + $rootSpan->attributes['magento.static.file'] = $retval['file']; } } ); @@ -108,7 +109,7 @@ static function ($staticResource, $scope, $args, $retval) { static function ($media, $scope, $args) { $rootSpan = root_span(); if ($rootSpan !== null) { - $rootSpan->meta['magento.media.file'] = $args[6]; + $rootSpan->attributes['magento.media.file'] = $args[6]; } } ); @@ -119,7 +120,7 @@ static function ($media, $scope, $args) { static function (SpanData $span, $args) { $originalImageName = $args[0]; self::setCommonSpanInfo($span, 'magento.media.resize', $originalImageName); - root_span()->meta['magento.media.name'] = $originalImageName; + root_span()->attributes['magento.media.name'] = $originalImageName; } ); @@ -129,7 +130,7 @@ static function (SpanData $span, $args) { 'find', static function (SpanData $span, $args) { self::setCommonSpanInfo($span, 'magento.console.find', $args[0]); - $span->meta['magento.console.command'] = root_span()->resource = $args[0]; + $span->attributes['magento.console.command'] = root_span()->resource = $args[0]; } ); @@ -140,15 +141,15 @@ static function (SpanData $span, $args) { self::setCommonSpanInfo($span, 'magento.cron.run'); // _runJob($scheduledTime, $currentTime, $jobConfig, $schedule, $groupId) - $span->meta['magento.cron.scheduled_time'] = $args[0]; - $span->meta['magento.cron.current_time'] = $args[1]; - $span->meta['magento.cron.group_id'] = $args[4]; + $span->attributes['magento.cron.scheduled_time'] = $args[0]; + $span->attributes['magento.cron.current_time'] = $args[1]; + $span->attributes['magento.cron.group_id'] = $args[4]; $jobConfig = $args[2]; if (isset($jobConfig['instance'], $jobConfig['method'])) { $span->resource = $jobConfig['instance'] . '::' . $jobConfig['method']; - $span->meta['magento.cron.class'] = $jobConfig['instance']; - $span->meta['magento.cron.method'] = $jobConfig['method']; + $span->attributes['magento.cron.class'] = $jobConfig['instance']; + $span->attributes['magento.cron.method'] = $jobConfig['method']; } } ); @@ -171,10 +172,10 @@ function (SpanData $span) use (&$fullPageCached) { $rootSpan = root_span(); MagentoIntegration::setCommonSpanInfo($rootSpan, 'magento.request', $resource); - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; + $rootSpan->spanKind = SpanKind::SERVER; - if (!$fullPageCached && isset($rootSpan->meta['magento.pathinfo'])) { - $rootSpan->resource = $rootSpan->meta['magento.pathinfo']; + if (!$fullPageCached && isset($rootSpan->attributes['magento.pathinfo'])) { + $rootSpan->resource = $rootSpan->attributes['magento.pathinfo']; } } ); @@ -193,7 +194,7 @@ static function (SpanData $span, $args, $retval) { $rootSpan = root_span(); $fullActionName = $request->getFullActionName('/'); - $span->resource = $rootSpan->meta['magento.pathinfo'] = $fullActionName; + $span->resource = $rootSpan->attributes['magento.pathinfo'] = $fullActionName; $isViewRequest = $retval // If an exception is thrown, retval will be null and get_class will fail ? self::getRealClass($retval) === 'Magento\Framework\View\Result\Page' @@ -202,11 +203,11 @@ static function (SpanData $span, $args, $retval) { $rootSpan->resource = $fullActionName; } - $span->meta['magento.module'] = $request->getModuleName(); - $span->meta['magento.controller'] = $request->getControllerName(); - $span->meta['magento.action'] = $request->getActionName(); - $span->meta['magento.frontname'] = $rootSpan->meta['magento.frontname'] = $request->getFrontName(); - $span->meta['magento.route'] = $rootSpan->meta['magento.route'] = $request->getRouteName(); + $span->attributes['magento.module'] = $request->getModuleName(); + $span->attributes['magento.controller'] = $request->getControllerName(); + $span->attributes['magento.action'] = $request->getActionName(); + $span->attributes['magento.frontname'] = $rootSpan->attributes['magento.frontname'] = $request->getFrontName(); + $span->attributes['magento.route'] = $rootSpan->attributes['magento.route'] = $request->getRouteName(); } ); @@ -226,8 +227,7 @@ static function () use (&$fullPageCached) { static function ($kernel, $scope, $args, $retval) { $rootSpan = root_span(); if ($rootSpan !== null) { - $rootSpan->meta['magento.cached'] = $retval instanceof \Magento\Framework\App\Response\Http - ? "true" : "false"; + $rootSpan->attributes['magento.cached'] = $retval instanceof \Magento\Framework\App\Response\Http; } } ); @@ -291,22 +291,22 @@ static function (SpanData $span, $args) { $meta = array_filter($meta, static function ($value) { return $value !== null; }); - $span->meta = array_merge($span->meta, $meta); + $span->attributes = array_merge($span->attributes, $meta); if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING") && $module !== null && $controller !== null && $action !== null ) { - $span->resource = root_span()->meta['magento.pathinfo'] = "$module/$controller/$action"; + $span->resource = root_span()->attributes['magento.pathinfo'] = "$module/$controller/$action"; } if ($routeName !== null) { - root_span()->meta['magento.route'] = $meta['magento.router.route']; + root_span()->attributes['magento.route'] = $meta['magento.router.route']; } if (method_exists($request, 'getFrontName')) { $frontName = $request->getFrontName(); if ($frontName !== null) { - $span->meta['magento.router.frontname'] = root_span()->meta['magento.frontname'] = $frontName; + $span->attributes['magento.router.frontname'] = root_span()->attributes['magento.frontname'] = $frontName; } } } @@ -323,7 +323,7 @@ function (SpanData $span, $args, $action) { ); if ($action) { - $span->meta['magento.action'] = MagentoIntegration::getRealClass($action); + $span->attributes['magento.action'] = MagentoIntegration::getRealClass($action); } } ); @@ -340,11 +340,11 @@ static function (SpanData $span, $args) { $pathInfo = $request->getPathInfo(); if ($alias !== null) { - $span->meta['magento.urlrewrite.alias'] = $alias; + $span->attributes['magento.urlrewrite.alias'] = $alias; } if ($pathInfo !== null) { - $span->meta['magento.urlrewrite.path'] = $pathInfo; + $span->attributes['magento.urlrewrite.path'] = $pathInfo; } } ); @@ -358,8 +358,8 @@ static function (SpanData $span, $args) { 'prehook' => function (SpanData $span, $args) { $span->name = 'magento.plugin.call'; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name('magento'); - $span->meta[Tag::COMPONENT] = 'magento'; + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'magento'; + $span->component = 'magento'; $method = $args[0]; $span->resource = $method . ' (plugin)'; @@ -369,7 +369,7 @@ static function (SpanData $span, $args) { $pluginList = ObjectManager::getInstance()->get(PluginListInterface::class); $type = get_parent_class($this); - $span->meta['magento.plugin.type'] = $type; + $span->attributes['magento.plugin.type'] = $type; $capMethod = ucfirst($method); // Install hooks if (isset($pluginInfo[\Magento\Framework\Interception\DefinitionInterface::LISTENER_BEFORE])) { @@ -386,11 +386,11 @@ static function (HookData $hook) use ($pluginInstance, $pluginMethod, $code) { $span = $hook->span(); $span->name = 'magento.plugin.before'; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name('magento'); - $span->meta[Tag::COMPONENT] = 'magento'; + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'magento'; + $span->component = 'magento'; $span->resource = "$pluginInstance::$pluginMethod"; - $span->meta['magento.plugin.code'] = $code; + $span->attributes['magento.plugin.code'] = $code; remove_hook($hook->id); } @@ -416,11 +416,11 @@ static function (HookData $hook) use ($pluginInstance, $pluginMethod, $code) { $span = $hook->span(); $span->name = 'magento.plugin.around'; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name('magento'); - $span->meta[Tag::COMPONENT] = 'magento'; + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'magento'; + $span->component = 'magento'; $span->resource = "$pluginInstance::$pluginMethod"; - $span->meta['magento.plugin.code'] = $code; + $span->attributes['magento.plugin.code'] = $code; remove_hook($hook->id); } @@ -435,8 +435,8 @@ static function (HookData $hook) use ($type, $method) { $span = $hook->span(); $span->name = 'magento.plugin.original'; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name('magento'); - $span->meta[Tag::COMPONENT] = 'magento'; + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'magento'; + $span->component = 'magento'; $span->resource = "$type::$method"; remove_hook($hook->id); @@ -461,11 +461,11 @@ static function (HookData $hook) use ($pluginInstance, $pluginMethod, $code) { $span = $hook->span(); $span->name = 'magento.plugin.after'; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name('magento'); - $span->meta[Tag::COMPONENT] = 'magento'; + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'magento'; + $span->component = 'magento'; $span->resource = "$pluginInstance::$pluginMethod"; - $span->meta['magento.plugin.code'] = $code; + $span->attributes['magento.plugin.code'] = $code; remove_hook($hook->id); } @@ -506,11 +506,11 @@ function (SpanData $span) { $template = $this; $templateFile = $template->getTemplate(); - $span->meta['magento.template'] = $span->resource = $templateFile; + $span->attributes['magento.template'] = $span->resource = $templateFile; $module = $template->getModuleName(); - $span->meta['magento.module'] = $module ?: substr($templateFile, 0, strpos($templateFile, '::')); - $span->meta['magento.area'] = $template->getArea(); + $span->attributes['magento.module'] = $module ?: substr($templateFile, 0, strpos($templateFile, '::')); + $span->attributes['magento.area'] = $template->getArea(); } ] ); @@ -523,7 +523,7 @@ static function (SpanData $span, $args) { $imageId = $args[1]; self::setCommonSpanInfo($span, 'magento.image.get', $product->getName()); - $span->meta['magento.image.id'] = $imageId; + $span->attributes['magento.image.id'] = $imageId; } ); @@ -554,10 +554,10 @@ function (SpanData $span) { if ($block instanceof \Magento\Framework\View\Element\Template) { $template = $block->getTemplate(); if ($template !== null) { - $span->meta['magento.block.template'] = $template; + $span->attributes['magento.block.template'] = $template; $moduleName = $moduleName ?: substr($template, 0, strpos($template, '::')); } - $span->meta['magento.block.area'] = $block->getArea(); + $span->attributes['magento.block.area'] = $block->getArea(); } $moduleName = empty($moduleName) ? '' : $moduleName; @@ -565,16 +565,16 @@ function (SpanData $span) { $blockName = $block->getNameInLayout(); $span->resource = "{$moduleName}:{$blockName}"; - $span->meta['magento.block.module'] = $moduleName; - $span->meta['magento.block.name'] = $blockName; + $span->attributes['magento.block.module'] = $moduleName; + $span->attributes['magento.block.name'] = $blockName; $cacheLifetime = $block->getCacheLifetime(); if ($cacheLifetime !== null) { - $span->meta['magento.block.cache_lifetime'] = $cacheLifetime; + $span->attributes['magento.block.cache_lifetime'] = (int)$cacheLifetime; } $class = MagentoIntegration::getRealClass($block); - $span->meta['magento.block.class'] = $class; + $span->attributes['magento.block.class'] = $class; // For Legacy, see Magento\Widget\Model\Widget\Instance::generateLayoutUpdateXml if (strlen($blockName) === 32 @@ -635,7 +635,7 @@ function (SpanData $span, $args) { /** @var \Magento\Framework\Event\Observer $observer */ $observer = $args[0]; - $span->meta['magento.event.name'] = $observer->getEvent()->getName(); + $span->attributes['magento.event.name'] = $observer->getEvent()->getName(); } else { // If this is an instance of \Magento\PageCache\Observer\ProcessLayoutRenderElement, then return false // to prevent the original execute method from being traced. @@ -653,15 +653,15 @@ static function (SpanData $span, $args) { /** @var \Magento\Sales\Api\Data\OrderInterface $order */ $order = $args[0]; - $span->meta['magento.order.item_count'] = $order->getTotalItemCount() ?? $order->getTotalQtyOrdered(); - $span->meta['magento.order.customer_id'] = $order->getCustomerId(); - $span->meta['magento.order.total'] = $order->getGrandTotal(); - $span->meta['magento.order.total_base'] = $order->getBaseGrandTotal(); - $span->meta['magento.order.id'] = $order->getRealOrderId(); - $span->meta['magento.order.currency'] = $order->getOrderCurrencyCode(); + $span->attributes['magento.order.item_count'] = $order->getTotalItemCount() ?? $order->getTotalQtyOrdered(); + $span->attributes['magento.order.customer_id'] = $order->getCustomerId(); + $span->attributes['magento.order.total'] = $order->getGrandTotal(); + $span->attributes['magento.order.total_base'] = $order->getBaseGrandTotal(); + $span->attributes['magento.order.id'] = $order->getRealOrderId(); + $span->attributes['magento.order.currency'] = $order->getOrderCurrencyCode(); if (($address = $order->getShippingAddress()) !== null) { - $span->meta['magento.order.shipping_city'] = $address->getCity(); - $span->meta['magento.order.shipping_country'] = $address->getCountryId(); + $span->attributes['magento.order.shipping_city'] = $address->getCity(); + $span->attributes['magento.order.shipping_country'] = $address->getCountryId(); } $i = 0; @@ -670,10 +670,10 @@ static function (SpanData $span, $args) { // Indexes do not necessarily increment by 1 per item // It depends on their initial cart position if ($item->getPrice()) { - $span->meta["magento.order.items.$i.sku"] = $item->getSku(); - $span->meta["magento.order.items.$i.name"] = $item->getName(); - $span->meta["magento.order.items.$i.price"] = $item->getPrice(); - $span->meta["magento.order.items.$i.qty"] = $item->getQtyOrdered(); + $span->attributes["magento.order.items.$i.sku"] = $item->getSku(); + $span->attributes["magento.order.items.$i.name"] = $item->getName(); + $span->attributes["magento.order.items.$i.price"] = $item->getPrice(); + $span->attributes["magento.order.items.$i.qty"] = $item->getQtyOrdered(); } $i++; } @@ -689,8 +689,8 @@ static function (SpanData $span, $args) { /** @var Magento\Sales\Model\Order $order */ $order = $args[0]; - $span->meta['magento.email.address'] = $order->getCustomerEmail();; - $span->meta['magento.email.order_id'] = $order->getRealOrderId(); + $span->attributes['magento.email.address'] = $order->getCustomerEmail();; + $span->attributes['magento.email.order_id'] = $order->getRealOrderId(); } ); diff --git a/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php b/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php index 0706a599099..8a222f299d1 100644 --- a/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php +++ b/src/DDTrace/Integrations/Memcache/MemcacheIntegration.php @@ -5,6 +5,7 @@ use DDTrace\Integrations\DatabaseIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\Obfuscation; @@ -72,9 +73,9 @@ public static function init(): int $memcache_cas = function (SpanData $span, $args) { MemcacheIntegration::setCommonData($span, 'cas'); if (isset($args[4])) { - $span->meta['memcache.cas_token'] = $args[4]; + $span->attributes['memcache.cas_token'] = $args[4]; } - $span->meta['memcache.query'] = 'cas ?'; + $span->attributes['memcache.query'] = 'cas ?'; $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; MemcacheIntegration::setServerTags($span, $this); }; @@ -90,13 +91,13 @@ public static function traceCommand($command) $trace = function (SpanData $span, $args, $retval) use ($command) { MemcacheIntegration::setCommonData($span, $command); if ($command === 'get') { - $span->metrics[Tag::DB_ROW_COUNT] = empty($retval) ? 0 : 1; + $span->attributes[Tag::DB_ROW_COUNT] = empty($retval) ? 0 : 1; } if (!is_array($args[0])) { MemcacheIntegration::setServerTags($span, $this); $queryParams = dd_trace_env_config("DD_TRACE_MEMCACHED_OBFUSCATION") ? Obfuscation::toObfuscatedString($args[0]) : $args[0]; - $span->meta['memcache.query'] = $command . ' ' . $queryParams; + $span->attributes['memcache.query'] = $command . ' ' . $queryParams; } $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; }; @@ -132,10 +133,10 @@ public static function setCommonData(SpanData $span, $command) $span->type = Type::MEMCACHED; Integration::handleInternalSpanServiceName($span, self::NAME); $span->resource = $command; - $span->meta['memcache.command'] = $command; - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::DB_SYSTEM] = 'memcached'; + $span->attributes['memcache.command'] = $command; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; + $span->attributes[Tag::DB_SYSTEM] = 'memcached'; } /** @@ -154,7 +155,7 @@ public static function setCommonData(SpanData $span, $command) public static function setServerTags(SpanData $span, \Memcache $memcache) { if ($server = ObjectKVStore::get($memcache, 'server')) { - list($span->meta[Tag::TARGET_HOST], $span->meta[Tag::TARGET_PORT]) = $server; + list($span->attributes[Tag::TARGET_HOST], $span->attributes[Tag::TARGET_PORT]) = $server; } } diff --git a/src/DDTrace/Integrations/Memcached/MemcachedIntegration.php b/src/DDTrace/Integrations/Memcached/MemcachedIntegration.php index 2e431a51f63..54d32e8426a 100644 --- a/src/DDTrace/Integrations/Memcached/MemcachedIntegration.php +++ b/src/DDTrace/Integrations/Memcached/MemcachedIntegration.php @@ -5,6 +5,7 @@ use DDTrace\Integrations\DatabaseIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\Obfuscation; @@ -76,17 +77,17 @@ public static function init(): int \DDTrace\trace_method('Memcached', 'cas', function (SpanData $span, $args) { MemcachedIntegration::setCommonData($span, 'cas'); - $span->meta['memcached.cas_token'] = $args[0]; - $span->meta['memcached.query'] = 'cas ?'; + $span->attributes['memcached.cas_token'] = $args[0]; + $span->attributes['memcached.query'] = 'cas ?'; $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; MemcachedIntegration::setServerTags($span, $this); }); \DDTrace\trace_method('Memcached', 'casByKey', function (SpanData $span, $args) { MemcachedIntegration::setCommonData($span, 'casByKey'); - $span->meta['memcached.cas_token'] = $args[0]; - $span->meta['memcached.query'] = 'casByKey ?'; - $span->meta['memcached.server_key'] = $args[1]; + $span->attributes['memcached.cas_token'] = $args[0]; + $span->attributes['memcached.query'] = 'casByKey ?'; + $span->attributes['memcached.server_key'] = $args[1]; $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; MemcachedIntegration::setServerTags($span, $this); @@ -103,11 +104,11 @@ public static function traceCommand($command) function (SpanData $span, $args, $retval) use ($command) { MemcachedIntegration::setCommonData($span, $command); if ($command === 'get') { - $span->metrics[Tag::DB_ROW_COUNT] = empty($retval) ? 0 : 1; + $span->attributes[Tag::DB_ROW_COUNT] = empty($retval) ? 0 : 1; } if (!is_array($args[0])) { MemcachedIntegration::setServerTags($span, $this); - $span->meta['memcached.query'] = $command . ' ' . MemcachedIntegration::obfuscateIfNeeded($args[0]); + $span->attributes['memcached.query'] = $command . ' ' . MemcachedIntegration::obfuscateIfNeeded($args[0]); } $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; @@ -123,12 +124,12 @@ public static function traceCommandByKey($command) function (SpanData $span, $args, $retval) use ($command) { MemcachedIntegration::setCommonData($span, $command); if ($command === 'getByKey') { - $span->metrics[Tag::DB_ROW_COUNT] = empty($retval) ? 0 : 1; + $span->attributes[Tag::DB_ROW_COUNT] = empty($retval) ? 0 : 1; } if (!is_array($args[0])) { MemcachedIntegration::setServerTags($span, $this); - $span->meta['memcached.query'] = $command . ' ' . MemcachedIntegration::obfuscateIfNeeded($args[0]); - $span->meta['memcached.server_key'] = $args[0]; + $span->attributes['memcached.query'] = $command . ' ' . MemcachedIntegration::obfuscateIfNeeded($args[0]); + $span->attributes['memcached.server_key'] = $args[0]; } $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; @@ -144,10 +145,10 @@ public static function traceMulti($command) function (SpanData $span, $args, $retval) use ($command) { MemcachedIntegration::setCommonData($span, $command); if ($command === 'getMulti') { - $span->metrics[Tag::DB_ROW_COUNT] = isset($retval) ? (is_array($retval) ? count($retval) : 1) : 0; + $span->attributes[Tag::DB_ROW_COUNT] = isset($retval) ? (is_array($retval) ? count($retval) : 1) : 0; } MemcachedIntegration::setServerTags($span, $this); - $span->meta['memcached.query'] = $command . ' ' . MemcachedIntegration::obfuscateIfNeeded($args[0], ','); + $span->attributes['memcached.query'] = $command . ' ' . MemcachedIntegration::obfuscateIfNeeded($args[0], ','); $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; } ); @@ -161,12 +162,12 @@ public static function traceMultiByKey($command) function (SpanData $span, $args, $retval) use ($command) { MemcachedIntegration::setCommonData($span, $command); if ($command === 'getMultiByKey') { - $span->metrics[Tag::DB_ROW_COUNT] = isset($retval) ? (is_array($retval) ? count($retval) : 1) : 0; + $span->attributes[Tag::DB_ROW_COUNT] = isset($retval) ? (is_array($retval) ? count($retval) : 1) : 0; } - $span->meta['memcached.server_key'] = $args[0]; + $span->attributes['memcached.server_key'] = $args[0]; MemcachedIntegration::setServerTags($span, $this); $query = "$command " . MemcachedIntegration::obfuscateIfNeeded($args[1], ','); - $span->meta['memcached.query'] = $query; + $span->attributes['memcached.query'] = $query; $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; } ); @@ -185,10 +186,10 @@ public static function setCommonData(SpanData $span, $command) $span->service = 'memcached'; Integration::handleInternalSpanServiceName($span, self::NAME); $span->resource = $command; - $span->meta['memcached.command'] = $command; - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::DB_SYSTEM] = self::NAME; + $span->attributes['memcached.command'] = $command; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; + $span->attributes[Tag::DB_SYSTEM] = self::NAME; } /** @@ -212,8 +213,8 @@ public static function setServerTags(SpanData $span, \Memcached $memcached) * top one to keep memory overhead low. */ if (isset($servers[0]['host'], $servers[0]['port'])) { - $span->meta[Tag::TARGET_HOST] = $servers[0]['host']; - $span->meta[Tag::TARGET_PORT] = $servers[0]['port']; + $span->attributes[Tag::TARGET_HOST] = $servers[0]['host']; + $span->attributes[Tag::TARGET_PORT] = $servers[0]['port']; } } diff --git a/src/DDTrace/Integrations/Mongo/MongoIntegration.php b/src/DDTrace/Integrations/Mongo/MongoIntegration.php index 5bc2c000f54..28a975edb34 100644 --- a/src/DDTrace/Integrations/Mongo/MongoIntegration.php +++ b/src/DDTrace/Integrations/Mongo/MongoIntegration.php @@ -9,6 +9,7 @@ use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\Obfuscation; @@ -31,38 +32,38 @@ public static function init(): int \DDTrace\trace_method('MongoClient', '__construct', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoClient', '__construct'); if (isset($args[0])) { - $span->meta[Tag::MONGODB_SERVER] = Obfuscation::dsn($args[0]); + $span->attributes[Tag::MONGODB_SERVER] = Obfuscation::dsn($args[0]); $dbName = self::extractDatabaseNameFromDsn($args[0]); if (null !== $dbName) { - $span->meta[Tag::MONGODB_DATABASE] = Integration::toString($dbName); + $span->attributes[Tag::MONGODB_DATABASE] = Integration::toString($dbName); } } if (isset($args[1]['db'])) { - $span->meta[Tag::MONGODB_DATABASE] = $args[1]['db']; + $span->attributes[Tag::MONGODB_DATABASE] = $args[1]['db']; } }); \DDTrace\trace_method('MongoClient', 'selectCollection', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoClient', 'selectCollection'); if (isset($args[0])) { - $span->meta[Tag::MONGODB_DATABASE] = $args[0]; + $span->attributes[Tag::MONGODB_DATABASE] = $args[0]; } if (isset($args[1])) { - $span->meta[Tag::MONGODB_COLLECTION] = $args[1]; + $span->attributes[Tag::MONGODB_COLLECTION] = $args[1]; } }); \DDTrace\trace_method('MongoClient', 'selectDB', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoClient', 'selectDB'); if (isset($args[0])) { - $span->meta[Tag::MONGODB_DATABASE] = $args[0]; + $span->attributes[Tag::MONGODB_DATABASE] = $args[0]; } }); \DDTrace\trace_method('MongoClient', 'setReadPreference', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoClient', 'setReadPreference'); if (isset($args[0])) { - $span->meta[Tag::MONGODB_READ_PREFERENCE] = $args[0]; + $span->attributes[Tag::MONGODB_READ_PREFERENCE] = $args[0]; } }); @@ -79,10 +80,10 @@ public static function init(): int \DDTrace\trace_method('MongoCollection', '__construct', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoCollection', '__construct'); if (isset($args[0])) { - $span->meta[Tag::MONGODB_DATABASE] = Integration::toString($args[0]); + $span->attributes[Tag::MONGODB_DATABASE] = Integration::toString($args[0]); } if (isset($args[1])) { - $span->meta[Tag::MONGODB_COLLECTION] = Integration::toString($args[1]); + $span->attributes[Tag::MONGODB_COLLECTION] = Integration::toString($args[1]); } }); @@ -95,10 +96,10 @@ static function (SpanData $span, $args, $return) { return; } if (isset($return['$id'])) { - $span->meta[Tag::MONGODB_BSON_ID] = Integration::toString($return['$id']); + $span->attributes[Tag::MONGODB_BSON_ID] = Integration::toString($return['$id']); } if (isset($return['$ref'])) { - $span->meta[Tag::MONGODB_COLLECTION] = Integration::toString($return['$ref']); + $span->attributes[Tag::MONGODB_COLLECTION] = Integration::toString($return['$ref']); } } ); @@ -107,17 +108,17 @@ static function (SpanData $span, $args, $return) { self::addSpanDefaultMetadata($span, 'MongoCollection', 'getDBRef'); if (isset($args[0]['$id'])) { - $span->meta[Tag::MONGODB_BSON_ID] = $args[0]['$id']; + $span->attributes[Tag::MONGODB_BSON_ID] = $args[0]['$id']; } if (isset($args[0]['$ref'])) { - $span->meta[Tag::MONGODB_COLLECTION] = $args[0]['$ref']; + $span->attributes[Tag::MONGODB_COLLECTION] = $args[0]['$ref']; } }); \DDTrace\trace_method('MongoCollection', 'distinct', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoCollection', 'distinct'); if (isset($args[1])) { - $span->meta[Tag::MONGODB_QUERY] = json_encode($args[1]); + $span->attributes[Tag::MONGODB_QUERY] = json_encode($args[1]); } }); @@ -127,7 +128,7 @@ static function (SpanData $span, $args, $return) { static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoCollection', 'setReadPreference'); if (isset($args[0])) { - $span->meta[Tag::MONGODB_READ_PREFERENCE] = $args[0]; + $span->attributes[Tag::MONGODB_READ_PREFERENCE] = $args[0]; } } ); @@ -164,57 +165,57 @@ static function (SpanData $span, $args) { \DDTrace\trace_method('MongoDB', 'setReadPreference', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoDB', 'setReadPreference'); if (isset($args[0])) { - $span->meta[Tag::MONGODB_READ_PREFERENCE] = $args[0]; + $span->attributes[Tag::MONGODB_READ_PREFERENCE] = $args[0]; } }); \DDTrace\trace_method('MongoDB', 'setProfilingLevel', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoDB', 'setProfilingLevel'); if (isset($args[0])) { - $span->meta[Tag::MONGODB_PROFILING_LEVEL] = json_encode($args[0]); + $span->attributes[Tag::MONGODB_PROFILING_LEVEL] = (int)$args[0]; } }); \DDTrace\trace_method('MongoDB', 'command', static function (SpanData $span, $args, $return) { self::addSpanDefaultMetadata($span, 'MongoDB', 'command'); if (isset($args[0]['query'])) { - $span->meta[Tag::MONGODB_QUERY] = json_encode($args[0]['query']); + $span->attributes[Tag::MONGODB_QUERY] = json_encode($args[0]['query']); } if (isset($args[1]['socketTimeoutMS'])) { - $span->meta[Tag::MONGODB_TIMEOUT] = $args[1]['socketTimeoutMS']; + $span->attributes[Tag::MONGODB_TIMEOUT] = $args[1]['socketTimeoutMS']; } elseif (isset($args[1]['timeout'])) { - $span->meta[Tag::MONGODB_TIMEOUT] = $args[1]['timeout']; + $span->attributes[Tag::MONGODB_TIMEOUT] = $args[1]['timeout']; } }); \DDTrace\trace_method('MongoDB', 'createDBRef', static function (SpanData $span, $args, $return) { self::addSpanDefaultMetadata($span, 'MongoDB', 'createDBRef'); if (isset($args[0])) { - $span->meta[Tag::MONGODB_COLLECTION] = Integration::toString($args[0]); + $span->attributes[Tag::MONGODB_COLLECTION] = Integration::toString($args[0]); } if (isset($return['$id'])) { - $span->meta[Tag::MONGODB_BSON_ID] = Integration::toString($return['$id']); + $span->attributes[Tag::MONGODB_BSON_ID] = Integration::toString($return['$id']); } }); \DDTrace\trace_method('MongoDB', 'getDBRef', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoDB', 'getDBRef'); if (isset($args[0]['$ref'])) { - $span->meta[Tag::MONGODB_COLLECTION] = Integration::toString($args[0]['$ref']); + $span->attributes[Tag::MONGODB_COLLECTION] = Integration::toString($args[0]['$ref']); } }); \DDTrace\trace_method('MongoDB', 'createCollection', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoDB', 'createCollection'); if (isset($args[0])) { - $span->meta[Tag::MONGODB_COLLECTION] = Integration::toString($args[0]); + $span->attributes[Tag::MONGODB_COLLECTION] = Integration::toString($args[0]); } }); \DDTrace\trace_method('MongoDB', 'selectCollection', static function (SpanData $span, $args) { self::addSpanDefaultMetadata($span, 'MongoDB', 'selectCollection'); if (isset($args[0])) { - $span->meta[Tag::MONGODB_COLLECTION] = Integration::toString($args[0]); + $span->attributes[Tag::MONGODB_COLLECTION] = Integration::toString($args[0]); } }); @@ -263,7 +264,7 @@ public static function traceMongoQuery($class, $method) static function (SpanData $span, $args) use ($class, $method) { self::addSpanDefaultMetadata($span, $class, $method); if (isset($args[0])) { - $span->meta[Tag::MONGODB_QUERY] = json_encode($args[0]); + $span->attributes[Tag::MONGODB_QUERY] = json_encode($args[0]); } } ); @@ -282,9 +283,9 @@ public static function addSpanDefaultMetadata(SpanData $span, $class, $method) $span->resource = $method; $span->type = Type::MONGO; $span->service = self::NAME; - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::DB_SYSTEM] = self::SYSTEM; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; + $span->attributes[Tag::DB_SYSTEM] = self::SYSTEM; } /** diff --git a/src/DDTrace/Integrations/MongoDB/DatadogSubscriberWithReturnTypes.php b/src/DDTrace/Integrations/MongoDB/DatadogSubscriberWithReturnTypes.php index b67ee9f1b1a..e83e3ec7ced 100644 --- a/src/DDTrace/Integrations/MongoDB/DatadogSubscriberWithReturnTypes.php +++ b/src/DDTrace/Integrations/MongoDB/DatadogSubscriberWithReturnTypes.php @@ -16,11 +16,11 @@ public function commandStarted(\MongoDB\Driver\Monitoring\CommandStartedEvent $e } if (self::$useDeprecatedMethods) { - $span->meta['out.host'] = $event->getServer()->getHost(); - $span->meta['out.port'] = $event->getServer()->getPort(); + $span->attributes['out.host'] = $event->getServer()->getHost(); + $span->attributes['out.port'] = $event->getServer()->getPort(); } else { - $span->meta['out.host'] = $event->getHost(); - $span->meta['out.port'] = $event->getPort(); + $span->attributes['out.host'] = $event->getHost(); + $span->attributes['out.port'] = $event->getPort(); } } } diff --git a/src/DDTrace/Integrations/MongoDB/DatadogSubscriberWithoutReturnTypes.php b/src/DDTrace/Integrations/MongoDB/DatadogSubscriberWithoutReturnTypes.php index 4a704e7c29d..e1fff1320f0 100644 --- a/src/DDTrace/Integrations/MongoDB/DatadogSubscriberWithoutReturnTypes.php +++ b/src/DDTrace/Integrations/MongoDB/DatadogSubscriberWithoutReturnTypes.php @@ -16,11 +16,11 @@ public function commandStarted(\MongoDB\Driver\Monitoring\CommandStartedEvent $e } if (self::$useDeprecatedMethods) { - $span->meta['out.host'] = $event->getServer()->getHost(); - $span->meta['out.port'] = $event->getServer()->getPort(); + $span->attributes['out.host'] = $event->getServer()->getHost(); + $span->attributes['out.port'] = $event->getServer()->getPort(); } else { - $span->meta['out.host'] = $event->getHost(); - $span->meta['out.port'] = $event->getPort(); + $span->attributes['out.host'] = $event->getHost(); + $span->attributes['out.port'] = $event->getPort(); } } } diff --git a/src/DDTrace/Integrations/MongoDB/MongoDBIntegration.php b/src/DDTrace/Integrations/MongoDB/MongoDBIntegration.php index 42b8be9fc65..561856eb43c 100644 --- a/src/DDTrace/Integrations/MongoDB/MongoDBIntegration.php +++ b/src/DDTrace/Integrations/MongoDB/MongoDBIntegration.php @@ -5,6 +5,7 @@ use DDTrace\Integrations\DatabaseIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\ObjectKVStore; @@ -414,16 +415,16 @@ public static function traceExecuteBulkWrite($class, $method) if (isset($args[1])) { $deletes = ObjectKVStore::get($args[1], 'deletes', []); for ($index = 0; $index < \count($deletes); $index++) { - $span->meta['mongodb.deletes.' . $index . '.filter'] = $deletes[$index]; + $span->attributes['mongodb.deletes.' . $index . '.filter'] = $deletes[$index]; } $updates = ObjectKVStore::get($args[1], 'updates', []); for ($index = 0; $index < \count($updates); $index++) { - $span->meta['mongodb.updates.' . $index . '.filter'] = $updates[$index]; + $span->attributes['mongodb.updates.' . $index . '.filter'] = $updates[$index]; } $insertsCount = ObjectKVStore::get($args[1], 'insertsCount', 0); - $span->meta['mongodb.insertsCount'] = $insertsCount; + $span->attributes['mongodb.insertsCount'] = $insertsCount; } }); } @@ -593,27 +594,27 @@ public static function setMetadata( $span->service = 'mongodb'; Integration::handleInternalSpanServiceName($span, self::NAME); $span->type = Type::MONGO; - $span->meta[Tag::SPAN_KIND] = 'client'; + $span->spanKind = SpanKind::CLIENT; $serializedQuery = $rawQuery ? self::serializeQuery($rawQuery) : null; $span->resource = \implode(' ', array_filter([$method, $database, $collection, $command, $serializedQuery])); - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::DB_SYSTEM] = self::SYSTEM; + $span->component = self::NAME; + $span->attributes[Tag::DB_SYSTEM] = self::SYSTEM; if ($database) { - $span->meta[Tag::MONGODB_DATABASE] = $database; + $span->attributes[Tag::MONGODB_DATABASE] = $database; } if ($collection) { - $span->meta[Tag::MONGODB_COLLECTION] = $collection; + $span->attributes[Tag::MONGODB_COLLECTION] = $collection; } if ($host) { - $span->meta[Tag::TARGET_HOST] = $host; + $span->attributes[Tag::TARGET_HOST] = $host; } if ($port) { - $span->meta[Tag::TARGET_PORT] = $port; + $span->attributes[Tag::TARGET_PORT] = (int)$port; } if ($rawQuery && !\dd_trace_env_config("DD_TRACE_MONGODB_OBFUSCATION")) { - $span->meta[Tag::MONGODB_QUERY] = MongoDBIntegration::serializeQuery($rawQuery, false); + $span->attributes[Tag::MONGODB_QUERY] = MongoDBIntegration::serializeQuery($rawQuery, false); } elseif ($serializedQuery) { - $span->meta[Tag::MONGODB_QUERY] = $serializedQuery; + $span->attributes[Tag::MONGODB_QUERY] = $serializedQuery; } $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; } diff --git a/src/DDTrace/Integrations/Mysqli/MysqliCommon.php b/src/DDTrace/Integrations/Mysqli/MysqliCommon.php index cca327d44b6..4bdc6fbb2ae 100644 --- a/src/DDTrace/Integrations/Mysqli/MysqliCommon.php +++ b/src/DDTrace/Integrations/Mysqli/MysqliCommon.php @@ -37,7 +37,7 @@ public static function parseHostInfo($hostString) $parts = explode(':', $hostString); $host = $parts[0]; - $port = isset($parts[1]) ? $parts[1] : '3306'; + $port = isset($parts[1]) ? (int)$parts[1] : 3306; return [ Tag::DB_TYPE => 'mysql', Tag::TARGET_HOST => $host, diff --git a/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php b/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php index 389d2ad808c..eafa473f8a7 100644 --- a/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php +++ b/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php @@ -6,6 +6,7 @@ use DDTrace\Integrations\DatabaseIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\ObjectKVStore; @@ -40,10 +41,10 @@ public static function init(): int // In case of a procedural connect, we set the database name here so it works also in case of connection // error ($misqli == false). However, we also add it to the returned instance (in case of success) to // propagate it to the queries. - $span->meta[Tag::DB_NAME] = $args[3]; + $span->attributes[Tag::DB_NAME] = $args[3]; } self::setDefaultAttributes($span, 'mysqli_connect', 'mysqli_connect'); - $span->meta += MysqliCommon::parseHostInfo($host ?: self::DEFAULT_MYSQLI_HOST); + $span->attributes += MysqliCommon::parseHostInfo($host ?: self::DEFAULT_MYSQLI_HOST); if ($result === false) { self::trackPotentialError($span); @@ -83,7 +84,7 @@ function (SpanData $span, $args) { } self::setDefaultAttributes($span, 'mysqli_real_connect', 'mysqli_real_connect'); if ($host) { - $span->meta += MysqliCommon::parseHostInfo($host ?: self::DEFAULT_MYSQLI_HOST); + $span->attributes += MysqliCommon::parseHostInfo($host ?: self::DEFAULT_MYSQLI_HOST); } self::trackPotentialError($span); @@ -122,7 +123,7 @@ function (SpanData $span, $args) { ObjectKVStore::put($hook->returned, 'host_info', MysqliCommon::extractHostInfo($mysqli)); if (is_object($hook->returned) && property_exists($hook->returned, 'num_rows')) { - $span->metrics[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; + $span->attributes[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; } }); @@ -166,7 +167,7 @@ function (SpanData $span, $args) { ObjectKVStore::put($hook->returned, self::KEY_MYSQLI_INSTANCE, $mysqli); if (is_object($hook->returned) && property_exists($hook->returned, 'num_rows')) { - $span->metrics[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; + $span->attributes[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; } }); @@ -192,7 +193,7 @@ function (SpanData $span, $args) { ObjectKVStore::put($hook->returned, 'query', $query); if (is_object($hook->returned) && property_exists($hook->returned, 'num_rows')) { - $span->metrics[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; + $span->attributes[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; } }); @@ -237,7 +238,7 @@ function (SpanData $span, $args) { ObjectKVStore::put($hook->returned, MysqliIntegration::KEY_MYSQLI_INSTANCE, $instance); if (is_object($hook->returned) && property_exists($hook->returned, 'num_rows')) { - $span->metrics[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; + $span->attributes[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; } }); @@ -272,7 +273,7 @@ function (SpanData $span, $args) { ObjectKVStore::put($hook->returned, 'query', $query); if (is_object($hook->returned) && property_exists($hook->returned, 'num_rows')) { - $span->metrics[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; + $span->attributes[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; } }); @@ -297,7 +298,7 @@ function (SpanData $span, $args) { ObjectKVStore::put($hook->returned, 'query', $query); if (is_object($hook->returned) && property_exists($hook->returned, 'num_rows')) { - $span->metrics[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; + $span->attributes[Tag::DB_ROW_COUNT] = $hook->returned->num_rows; } }); } @@ -323,7 +324,7 @@ static function (HookData $hook) { self::setConnectionInfo($span, $mysqli); if (isset($args[2])) { - $span->meta['db.transaction_name'] = $args[2]; + $span->attributes['db.transaction_name'] = $args[2]; } }); @@ -353,7 +354,7 @@ static function (HookData $hook) { MysqliIntegration::setConnectionInfo($span, $this); if (isset($args[1])) { - $span->meta['db.transaction_name'] = $args[1]; + $span->attributes['db.transaction_name'] = $args[1]; } }); @@ -390,11 +391,11 @@ public static function setDefaultAttributes(SpanData $span, $name, $resource, $r $span->resource = $resource; $span->type = Type::SQL; Integration::handleInternalSpanServiceName($span, self::NAME); - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::DB_SYSTEM] = self::SYSTEM; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; + $span->attributes[Tag::DB_SYSTEM] = self::SYSTEM; if (is_object($result) && property_exists($result, 'num_rows')) { - $span->metrics[Tag::DB_ROW_COUNT] = $result->num_rows; + $span->attributes[Tag::DB_ROW_COUNT] = $result->num_rows; } } @@ -412,7 +413,7 @@ public static function setConnectionInfo(SpanData $span, $mysqli) $hostInfo = MysqliCommon::extractHostInfo($mysqli); foreach ($hostInfo as $tagName => $value) { - $span->meta[$tagName] = $value; + $span->attributes[$tagName] = $value; } if (\dd_trace_env_config("DD_TRACE_DB_CLIENT_SPLIT_BY_INSTANCE")) { if (isset($hostInfo[Tag::TARGET_HOST])) { @@ -423,7 +424,7 @@ public static function setConnectionInfo(SpanData $span, $mysqli) } $dbName = ObjectKVStore::get($mysqli, self::KEY_DATABASE_NAME); if ($dbName) { - $span->meta[Tag::DB_NAME] = $dbName; + $span->attributes[Tag::DB_NAME] = $dbName; } } @@ -436,9 +437,9 @@ public static function trackPotentialError(SpanData $span) { $errorCode = mysqli_connect_errno(); if ($errorCode > 0) { - $span->meta[Tag::ERROR_MSG] = mysqli_connect_error(); - $span->meta[Tag::ERROR_TYPE] = 'mysqli error'; - $span->meta[Tag::ERROR_STACK] = \DDTrace\get_sanitized_exception_trace(new \Exception, 2); + $span->attributes[Tag::ERROR_MSG] = mysqli_connect_error(); + $span->attributes[Tag::ERROR_TYPE] = 'mysqli error'; + $span->attributes[Tag::ERROR_STACK] = \DDTrace\get_sanitized_exception_trace(new \Exception, 2); } } diff --git a/src/DDTrace/Integrations/Nette/NetteIntegration.php b/src/DDTrace/Integrations/Nette/NetteIntegration.php index 6a774b58d1e..8296cf76d82 100644 --- a/src/DDTrace/Integrations/Nette/NetteIntegration.php +++ b/src/DDTrace/Integrations/Nette/NetteIntegration.php @@ -4,6 +4,7 @@ use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; @@ -16,7 +17,7 @@ class NetteIntegration extends Integration */ public static function init(): int { - $service = \ddtrace_config_app_name(self::NAME); + $service = \dd_trace_env_config('DD_SERVICE') ?: self::NAME; $setRootSpanFn = static function () use ($service) { $rootSpan = \DDTrace\root_span(); @@ -24,10 +25,10 @@ public static function init(): int return; } - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; + $rootSpan->spanKind = SpanKind::SERVER; $rootSpan->service = $service; - $rootSpan->meta[Tag::COMPONENT] = self::NAME; + $rootSpan->component = self::NAME; }; \DDTrace\hook_method('Nette\Configurator', '__construct', $setRootSpanFn); @@ -40,7 +41,7 @@ static function (SpanData $span) use ($service) { $span->name = 'nette.configurator.createRobotLoader'; $span->type = Type::WEB_SERVLET; $span->service = $service; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; } ); @@ -51,10 +52,10 @@ static function (SpanData $span) use ($service) { $span->name = 'nette.application.run'; $span->type = Type::WEB_SERVLET; $span->service = $service; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; $rootSpan = \DDTrace\root_span(); - $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = http_response_code(); + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = (string)http_response_code(); } ); @@ -65,7 +66,7 @@ static function (SpanData $span, $args) use ($service) { $span->name = 'nette.presenter.run'; $span->type = Type::WEB_SERVLET; $span->service = $service; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; if (count($args) < 1 || !\is_a($args[0], '\Nette\Application\Request')) { return; @@ -77,8 +78,8 @@ static function (SpanData $span, $args) use ($service) { $rootSpan = \DDTrace\root_span(); $rootSpan->attributes[Tag::HTTP_METHOD] = $request->getMethod(); - $rootSpan->meta['nette.route.presenter'] = $presenter; - $rootSpan->meta['nette.route.action'] = $action; + $rootSpan->attributes['nette.route.presenter'] = $presenter; + $rootSpan->attributes['nette.route.action'] = $action; } ); @@ -90,10 +91,10 @@ static function (SpanData $span, $args) use ($service) { $span->name = 'nette.latte.createTemplate'; $span->type = Type::WEB_SERVLET; $span->service = $service; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; if (count($args) >= 1) { - $span->meta['nette.latte.templateName'] = $args[0]; + $span->attributes['nette.latte.templateName'] = $args[0]; } } ); @@ -105,10 +106,10 @@ static function (SpanData $span, $args) use ($service) { $span->name = 'nette.latte.render'; $span->type = Type::WEB_SERVLET; $span->service = $service; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; if (count($args) >= 1) { - $span->meta['nette.latte.templateName'] = $args[0]; + $span->attributes['nette.latte.templateName'] = $args[0]; } } ); @@ -120,10 +121,10 @@ static function (SpanData $span, $args) use ($service) { $span->name = 'nette.latte.render'; $span->type = Type::WEB_SERVLET; $span->service = $service; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; if (count($args) >= 1) { - $span->meta['nette.latte.templateName'] = $args[0]; + $span->attributes['nette.latte.templateName'] = $args[0]; } } ); diff --git a/src/DDTrace/Integrations/OpenAI/OpenAIIntegration.php b/src/DDTrace/Integrations/OpenAI/OpenAIIntegration.php index 32a21d74da9..682ab91d96d 100644 --- a/src/DDTrace/Integrations/OpenAI/OpenAIIntegration.php +++ b/src/DDTrace/Integrations/OpenAI/OpenAIIntegration.php @@ -6,6 +6,7 @@ use DDTrace\Integrations\Integration; use DDTrace\Log\DatadogLogger; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\ObjectKVStore; @@ -356,14 +357,14 @@ public static function handleRequest( $span->name = 'openai.request'; $span->resource = $operationID; $span->type = Type::OPENAI; - $span->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_CLIENT; - $span->meta['openai.user.api_key'] = $apiKey; - $span->meta['openai.api_base'] = $basePath; - $span->metrics['_dd.measured'] = 1; + $span->spanKind = SpanKind::CLIENT; + $span->attributes['openai.user.api_key'] = $apiKey; + $span->attributes['openai.api_base'] = $basePath; + $span->attributes['_dd.measured'] = 1; foreach ($payload as $key => $value) { if (isset(self::COMMON_PARAMETERS[$key]) && !\is_null($value)) { - $span->meta["openai.request.$key"] = $value; + $span->attributes["openai.request.$key"] = $value; } } @@ -373,10 +374,10 @@ public static function handleRequest( if (array_key_exists('prompt', $payload)) { $prompt = $payload['prompt']; if (\is_string($prompt)) { - $span->meta["openai.request.prompt"] = self::normalizeStringOrTokenArray($prompt); + $span->attributes["openai.request.prompt"] = self::normalizeStringOrTokenArray($prompt); } elseif (\is_array($prompt)) { foreach ($prompt as $idx => $value) { - $span->meta["openai.request.prompt.$idx"] = self::normalizeStringOrTokenArray($value); + $span->attributes["openai.request.prompt.$idx"] = self::normalizeStringOrTokenArray($value); } } @@ -402,10 +403,10 @@ public static function handleRequest( if (array_key_exists('input', $payload)) { $input = $payload['input']; if (\is_string($input)) { - $span->meta["openai.request.input"] = self::normalizeStringOrTokenArray($input); + $span->attributes["openai.request.input"] = self::normalizeStringOrTokenArray($input); } else { foreach ($input as $idx => $value) { - $span->meta["openai.request.input.$idx"] = self::normalizeStringOrTokenArray($value); + $span->attributes["openai.request.input.$idx"] = self::normalizeStringOrTokenArray($value); } } } @@ -413,7 +414,7 @@ public static function handleRequest( // createChatCompletion, createCompletion if (array_key_exists('logit_bias', $payload) && \is_array($payload['logit_bias'])) { foreach ($payload['logit_bias'] as $tokenID => $bias) { - $span->meta["openai.request.logit_bias.$tokenID"] = $bias; + $span->attributes["openai.request.logit_bias.$tokenID"] = $bias; } } @@ -581,39 +582,39 @@ public static function getLogTags( 'env' => $span->env, 'version' => $span->version, 'service' => $span->service, - 'openai.request.method' => $span->meta['openai.request.method'] ?? null, - 'openai.request.endpoint' => $span->meta['openai.request.endpoint'] ?? null, - 'openai.request.model' => $span->meta['openai.request.model'] ?? null, - 'openai.organization.name' => $span->meta['openai.organization.name'] ?? null, - 'openai.user.api_key' => $span->meta['openai.user.api_key'] ?? null, + 'openai.request.method' => $span->attributes['openai.request.method'] ?? null, + 'openai.request.endpoint' => $span->attributes['openai.request.endpoint'] ?? null, + 'openai.request.model' => $span->attributes['openai.request.model'] ?? null, + 'openai.organization.name' => $span->attributes['openai.organization.name'] ?? null, + 'openai.user.api_key' => $span->attributes['openai.user.api_key'] ?? null, ]; switch ($operationID) { case 'createCompletion': $tags += [ - 'choices.0.finish_reason' => $span->meta['openai.response.choices.0.finish_reason'] ?? null, + 'choices.0.finish_reason' => $span->attributes['openai.response.choices.0.finish_reason'] ?? null, ]; break; case 'createChatCompletion': $tags += [ - 'messages.0.content' => $span->meta['openai.request.message.0.content'] ?? null, - 'completion.0.finish_reason' => $span->meta['openai.response.choices.0.finish_reason'] ?? null, + 'messages.0.content' => $span->attributes['openai.request.message.0.content'] ?? null, + 'completion.0.finish_reason' => $span->attributes['openai.response.choices.0.finish_reason'] ?? null, ]; break; case 'createImage': case 'createImageEdit': case 'createImageVariation': $tags += [ - 'image' => $span->meta['openai.request.image'] ?? null, - 'mask' => $span->meta['openai.request.mask'] ?? null, - 'choices.0.b64_json' => $span->meta['openai.response.images.0.b64_json'] ?? null, - 'choices.0.url' => $span->meta['openai.response.images.0.url'] ?? null, + 'image' => $span->attributes['openai.request.image'] ?? null, + 'mask' => $span->attributes['openai.request.mask'] ?? null, + 'choices.0.b64_json' => $span->attributes['openai.response.images.0.b64_json'] ?? null, + 'choices.0.url' => $span->attributes['openai.response.images.0.url'] ?? null, ]; break; case 'createTranscription': case 'createTranslation': $tags += [ - 'file' => $span->meta['openai.request.file'] ?? null, + 'file' => $span->attributes['openai.request.file'] ?? null, ]; break; } @@ -624,21 +625,21 @@ public static function getLogTags( case 'createTranscription': case 'createTranslation': $tags += [ - 'prompt' => $span->meta['openai.request.prompt'] ?? null, - 'choices.0.text' => $span->meta['openai.response.choices.0.text'] ?? null, + 'prompt' => $span->attributes['openai.request.prompt'] ?? null, + 'choices.0.text' => $span->attributes['openai.response.choices.0.text'] ?? null, ]; break; case 'createChatCompletion': $tags += [ - 'messages.0.content' => $span->meta['openai.request.message.0.content'] ?? null, - 'completion.0.message.content' => $span->meta['openai.response.choices.0.message.content'] ?? null, + 'messages.0.content' => $span->attributes['openai.request.message.0.content'] ?? null, + 'completion.0.message.content' => $span->attributes['openai.response.choices.0.message.content'] ?? null, ]; break; case 'createImage': case 'createImageEdit': case 'createImageVariation': $tags += [ - 'prompt' => $span->meta['openai.request.prompt'] ?? null, + 'prompt' => $span->attributes['openai.request.prompt'] ?? null, ]; break; } @@ -701,11 +702,11 @@ public static function sendMetrics( 'env' => $span->env, 'service' => $span->service, 'version' => $span->version, - 'openai.request.model' => $span->meta['openai.request.model'] ?? null, - 'openai.organization.id' => $span->meta['openai.organization.id'] ?? null, - 'openai.organization.name' => $span->meta['openai.organization.name'] ?? null, - 'openai.user.api_key' => $span->meta['openai.user.api_key'] ?? null, - 'openai.request.endpoint' => $span->meta['openai.request.endpoint'] ?? null, + 'openai.request.model' => $span->attributes['openai.request.model'] ?? null, + 'openai.organization.id' => $span->attributes['openai.organization.id'] ?? null, + 'openai.organization.name' => $span->attributes['openai.organization.name'] ?? null, + 'openai.user.api_key' => $span->attributes['openai.user.api_key'] ?? null, + 'openai.request.endpoint' => $span->attributes['openai.request.endpoint'] ?? null, 'openai.estimated' => $estimated, 'openai.request.error' => $span->exception ? 1 : 0, 'error_type' => $errorType, @@ -1156,7 +1157,7 @@ public static function commonStreamedCreateChatResponseExtraction(SpanData $span public static function commonStreamedResponseExtraction(SpanData $span, array $response, callable $estimateTokens): array { $numCompletionTokens = 0; - $numPromptTokens = $span->metrics['openai.response.usage.prompt_tokens'] ?? 0; + $numPromptTokens = $span->attributes['openai.response.usage.prompt_tokens'] ?? 0; foreach ($response as $current) { $numCompletionTokens += $estimateTokens($current->toArray()); @@ -1193,12 +1194,8 @@ public static function estimateTokens(string|array $prompt): int public static function applyTags(SpanData $span, array $tags) { foreach ($tags as $key => $value) { - if (\is_null($value)) { - continue; - } elseif (\is_numeric($value)) { - $span->metrics[$key] = $value; - } else { - $span->meta[$key] = $value; + if (!\is_null($value)) { + $span->attributes[$key] = $value; } } } @@ -1224,10 +1221,10 @@ public static function applyPromptAndCompletionSampling(SpanData $span) return; // We KEEP the tags } - $tags = $span->meta; + $tags = $span->attributes; foreach ($tags as $key => $value) { if (preg_match('/(prompt|text|content|input)$/i', $key)) { - unset($span->meta[$key]); + unset($span->attributes[$key]); } } } diff --git a/src/DDTrace/Integrations/PDO/PDOIntegration.php b/src/DDTrace/Integrations/PDO/PDOIntegration.php index aaac87b80bf..346388cc2cc 100644 --- a/src/DDTrace/Integrations/PDO/PDOIntegration.php +++ b/src/DDTrace/Integrations/PDO/PDOIntegration.php @@ -6,6 +6,7 @@ use DDTrace\Integrations\DatabaseIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\ObjectKVStore; @@ -79,7 +80,7 @@ public static function init(): int }, static function (HookData $hook) { $span = $hook->span(); if (is_numeric($hook->returned)) { - $span->metrics[Tag::DB_ROW_COUNT] = $hook->returned; + $span->attributes[Tag::DB_ROW_COUNT] = $hook->returned; } PDOIntegration::detectError($hook->instance, $span); }); @@ -104,7 +105,7 @@ public static function init(): int $span = $hook->span(); $instance = $hook->instance; if ($hook->returned instanceof \PDOStatement) { - $span->metrics[Tag::DB_ROW_COUNT] = $hook->returned->rowCount(); + $span->attributes[Tag::DB_ROW_COUNT] = $hook->returned->rowCount(); ObjectKVStore::propagate($instance, $hook->returned, PDOIntegration::CONNECTION_TAGS_KEY); } PDOIntegration::detectError($instance, $span); @@ -158,7 +159,7 @@ static function (HookData $hook) { $span->resource = $instance->queryString; if ($hook->returned === true) { try { - $span->metrics[Tag::DB_ROW_COUNT] = $instance->rowCount(); + $span->attributes[Tag::DB_ROW_COUNT] = $instance->rowCount(); } catch (\Exception $e) { // Ignore exception thrown by rowCount() method. // Drupal PDOStatement::rowCount() method throws an exception if the query is not a SELECT. @@ -196,17 +197,17 @@ public static function detectError($pdoOrStatement, SpanData $span) return; } $errorInfo = $pdoOrStatement->errorInfo(); - $span->meta[Tag::ERROR_MSG] = 'SQL error: ' . $errorCode . '. Driver error: ' . $errorInfo[1]; + $span->attributes[Tag::ERROR_MSG] = 'SQL error: ' . $errorCode . '. Driver error: ' . $errorInfo[1]; // Driver-specific error message will be in the rest of the array // The spec suggests the error message to be at pos 2 only, // ODBC: the SQLSTATE in [3] (but e.g. SQLServer doc states that the array can contain monre than 3 elements) // DBLIB: [3] an OSerror (int), [4] a severity and optionally a string representation of the OSerror in [5] if (count($errorInfo) > 2) { - $span->meta[Tag::ERROR_MSG] .= '. Driver-specific error data: ' . implode('. ', array_slice($errorInfo, 2)); + $span->attributes[Tag::ERROR_MSG] .= '. Driver-specific error data: ' . implode('. ', array_slice($errorInfo, 2)); } - $span->meta[Tag::ERROR_TYPE] = get_class($pdoOrStatement) . ' error'; + $span->attributes[Tag::ERROR_TYPE] = get_class($pdoOrStatement) . ' error'; } const DSN_REGEX = <<<'REGEX' @@ -255,7 +256,7 @@ private static function parseDsn($dsn) $tags[Tag::TARGET_HOST] = $host; } if ($port !== "") { - $tags[Tag::TARGET_PORT] = $port; + $tags[Tag::TARGET_PORT] = (int)$port; } if ($driver !== "") { $tags[Tag::DB_SYSTEM] = strtolower($driver); @@ -311,8 +312,8 @@ public static function setCommonSpanInfo($source, SpanData $span) $span->type = Type::SQL; $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; if (\dd_trace_env_config("DD_TRACE_DB_CLIENT_SPLIT_BY_INSTANCE") && isset($storedConnectionInfo[Tag::TARGET_HOST]) ) { @@ -325,7 +326,7 @@ public static function setCommonSpanInfo($source, SpanData $span) } foreach ($storedConnectionInfo as $tag => $value) { - $span->meta[$tag] = $value; + $span->attributes[$tag] = $value; } } diff --git a/src/DDTrace/Integrations/PHPRedis/PHPRedisIntegration.php b/src/DDTrace/Integrations/PHPRedis/PHPRedisIntegration.php index de7c0d50a49..cc4f0f566ef 100644 --- a/src/DDTrace/Integrations/PHPRedis/PHPRedisIntegration.php +++ b/src/DDTrace/Integrations/PHPRedis/PHPRedisIntegration.php @@ -5,6 +5,7 @@ use DDTrace\Integrations\DatabaseIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\ObjectKVStore; @@ -39,11 +40,11 @@ public static function init(): int Integration::handleOrphan($span); $hostOrUDS = (isset($args[0]) && \is_string($args[0])) ? $args[0] : PHPRedisIntegration::DEFAULT_HOST; - $span->meta[Tag::TARGET_HOST] = $hostOrUDS; - $span->meta[Tag::TARGET_PORT] = isset($args[1]) && \is_numeric($args[1]) ? - $args[1] : + $span->attributes[Tag::TARGET_HOST] = $hostOrUDS; + $span->attributes[Tag::TARGET_PORT] = isset($args[1]) && \is_numeric($args[1]) ? + (int)$args[1] : PHPRedisIntegration::DEFAULT_PORT; - $span->meta[Tag::SPAN_KIND] = 'client'; + $span->spanKind = SpanKind::CLIENT; // While we would have access to Redis::getHost() from the instance to retrieve it later, we compute the // service name here and store in the instance for later because of the following reasons: @@ -86,8 +87,8 @@ public static function init(): int $firstConfiguredHost = is_array($url) && isset($url["host"]) ? $url["host"] : PHPRedisIntegration::DEFAULT_HOST; - $span->meta[Tag::TARGET_HOST] = $firstConfiguredHost; - $span->meta[Tag::TARGET_PORT] = is_array($url) && isset($url["port"]) ? + $span->attributes[Tag::TARGET_HOST] = $firstConfiguredHost; + $span->attributes[Tag::TARGET_PORT] = is_array($url) && isset($url["port"]) ? $url["port"] : PHPRedisIntegration::DEFAULT_PORT; ObjectKVStore::put($this, PHPRedisIntegration::KEY_FIRST_HOST, $firstConfiguredHost); @@ -114,11 +115,11 @@ public static function init(): int PHPRedisIntegration::enrichSpan($span, $this, 'Redis'); if (isset($args[0]) && \is_numeric($args[0])) { - $span->meta['db.index'] = $args[0]; + $span->attributes['db.index'] = $args[0]; } $host = ObjectKVStore::get($this, PHPRedisIntegration::KEY_HOST); - $span->meta[Tag::TARGET_HOST] = $host; + $span->attributes[Tag::TARGET_HOST] = $host; $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; }); @@ -346,9 +347,9 @@ public static function enrichSpan(SpanData $span, $instance, $class, $method = n } $span->type = Type::REDIS; - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::DB_SYSTEM] = self::SYSTEM; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; + $span->attributes[Tag::DB_SYSTEM] = self::SYSTEM; if (null !== $method) { // method names for internal functions are lowered so we need to explitly set them if we want to have the // proper case. @@ -364,7 +365,7 @@ public static function traceMethodNoArgs($method) PHPRedisIntegration::enrichSpan($span, $this, 'Redis', $method); $host = ObjectKVStore::get($this, PHPRedisIntegration::KEY_HOST); - $span->meta[Tag::TARGET_HOST] = $host; + $span->attributes[Tag::TARGET_HOST] = $host; $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; }); \DDTrace\trace_method('RedisCluster', $method, function (SpanData $span, $args) use ($method) { @@ -372,9 +373,9 @@ public static function traceMethodNoArgs($method) PHPRedisIntegration::enrichSpan($span, $this, 'RedisCluster', $method); if ($clusterName = ObjectKVStore::get($this, PHPRedisIntegration::KEY_CLUSTER_NAME)) { - $span->meta[PHPRedisIntegration::INTERNAL_ONLY_TAG_CLUSTER_NAME] = $clusterName; + $span->attributes[PHPRedisIntegration::INTERNAL_ONLY_TAG_CLUSTER_NAME] = $clusterName; } elseif ($firstHost = ObjectKVStore::get($this, PHPRedisIntegration::KEY_FIRST_HOST)) { - $span->meta[PHPRedisIntegration::INTERNAL_ONLY_TAG_FIRST_HOST] = $firstHost; + $span->attributes[PHPRedisIntegration::INTERNAL_ONLY_TAG_FIRST_HOST] = $firstHost; } $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; }); @@ -388,11 +389,11 @@ public static function traceMethodAsCommand($method) PHPRedisIntegration::enrichSpan($span, $this, 'Redis', $method); $normalizedArgs = PHPRedisIntegration::normalizeArgs($args); // Obfuscable methods: see https://github.com/DataDog/datadog-agent/blob/master/pkg/trace/obfuscate/redis.go - $span->meta[Tag::REDIS_RAW_COMMAND] + $span->attributes[Tag::REDIS_RAW_COMMAND] = empty($normalizedArgs) ? $method : ($method . ' ' . $normalizedArgs); $host = ObjectKVStore::get($this, PHPRedisIntegration::KEY_HOST); - $span->meta[Tag::TARGET_HOST] = $host; + $span->attributes[Tag::TARGET_HOST] = $host; $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; }); \DDTrace\trace_method('RedisCluster', $method, function (SpanData $span, $args) use ($method) { @@ -401,12 +402,12 @@ public static function traceMethodAsCommand($method) PHPRedisIntegration::enrichSpan($span, $this, 'RedisCluster', $method); $normalizedArgs = PHPRedisIntegration::normalizeArgs($args); // Obfuscable methods: see https://github.com/DataDog/datadog-agent/blob/master/pkg/trace/obfuscate/redis.go - $span->meta[Tag::REDIS_RAW_COMMAND] + $span->attributes[Tag::REDIS_RAW_COMMAND] = empty($normalizedArgs) ? $method : ($method . ' ' . $normalizedArgs); if ($clusterName = ObjectKVStore::get($this, PHPRedisIntegration::KEY_CLUSTER_NAME)) { - $span->meta[PHPRedisIntegration::INTERNAL_ONLY_TAG_CLUSTER_NAME] = $clusterName; + $span->attributes[PHPRedisIntegration::INTERNAL_ONLY_TAG_CLUSTER_NAME] = $clusterName; } elseif ($firstHost = ObjectKVStore::get($this, PHPRedisIntegration::KEY_FIRST_HOST)) { - $span->meta[PHPRedisIntegration::INTERNAL_ONLY_TAG_FIRST_HOST] = $firstHost; + $span->attributes[PHPRedisIntegration::INTERNAL_ONLY_TAG_FIRST_HOST] = $firstHost; } $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; }); diff --git a/src/DDTrace/Integrations/Pcntl/PcntlIntegration.php b/src/DDTrace/Integrations/Pcntl/PcntlIntegration.php index 90b752ef019..d53560ca3ab 100644 --- a/src/DDTrace/Integrations/Pcntl/PcntlIntegration.php +++ b/src/DDTrace/Integrations/Pcntl/PcntlIntegration.php @@ -22,12 +22,12 @@ public static function init(): int $trace_fork = static function (SpanData $span, $args, $retval) { $span->name = $span->resource = 'pcntl_fork'; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; if ($retval > 0) { - $span->meta["fork.pid"] = $retval; + $span->attributes["fork.pid"] = $retval; } else { - $span->meta["fork.errno"] = $errno = pcntl_get_last_error(); - $span->meta["fork.error"] = pcntl_strerror($errno); + $span->attributes["fork.errno"] = $errno = pcntl_get_last_error(); + $span->attributes["fork.error"] = pcntl_strerror($errno); } }; \DDTrace\trace_function('pcntl_fork', $trace_fork); diff --git a/src/DDTrace/Integrations/Predis/PredisIntegration.php b/src/DDTrace/Integrations/Predis/PredisIntegration.php index f36ac8ab54b..c21355e79cc 100644 --- a/src/DDTrace/Integrations/Predis/PredisIntegration.php +++ b/src/DDTrace/Integrations/Predis/PredisIntegration.php @@ -5,6 +5,7 @@ use DDTrace\Integrations\DatabaseIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\ObjectKVStore; @@ -72,10 +73,10 @@ public static function init(): int $command = $args[0]; $arguments = $command->getArguments(); array_unshift($arguments, $command->getId()); - $span->meta['redis.args_length'] = count($arguments); + $span->attributes['redis.args_length'] = count($arguments); $query = PredisIntegration::formatArguments($arguments); $span->resource = $query; - $span->meta['redis.raw_command'] = $query; + $span->attributes['redis.raw_command'] = $query; }); \DDTrace\trace_method('Predis\Client', 'executeRaw', function (SpanData $span, $args) { @@ -95,8 +96,8 @@ public static function init(): int $arguments = $args[0]; $query = PredisIntegration::formatArguments($arguments); $span->resource = $query; - $span->meta['redis.args_length'] = count($arguments); - $span->meta['redis.raw_command'] = $query; + $span->attributes['redis.args_length'] = count($arguments); + $span->attributes['redis.raw_command'] = $query; }); \DDTrace\trace_method( @@ -114,7 +115,7 @@ public static function init(): int return; } $commands = $args[1]; - $span->meta['redis.pipeline_length'] = count($commands); + $span->attributes['redis.pipeline_length'] = count($commands); }, ] ); @@ -236,17 +237,17 @@ public static function setMetaAndServiceFromConnection($predis, SpanData $span) { $service = ObjectKVStore::get($predis->getConnection(), 'service'); if ($service) { - $span->meta[Tag::SERVICE_NAME] = $service; + $span->service = $service; } else { Integration::handleInternalSpanServiceName($span, self::DEFAULT_SERVICE_NAME); } - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::DB_SYSTEM] = self::SYSTEM; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; + $span->attributes[Tag::DB_SYSTEM] = self::SYSTEM; $span->peerServiceSources = DatabaseIntegrationHelper::PEER_SERVICE_SOURCES; foreach (ObjectKVStore::get($predis->getConnection(), 'connection_meta', []) as $tag => $value) { - $span->meta[$tag] = $value; + $span->attributes[$tag] = $value; } } diff --git a/src/DDTrace/Integrations/Psr18/Psr18Integration.php b/src/DDTrace/Integrations/Psr18/Psr18Integration.php index c1ce8eb702c..9e46bdbf79b 100644 --- a/src/DDTrace/Integrations/Psr18/Psr18Integration.php +++ b/src/DDTrace/Integrations/Psr18/Psr18Integration.php @@ -6,6 +6,7 @@ use DDTrace\Integrations\HttpClientIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; @@ -26,8 +27,8 @@ static function (SpanData $span, $args, $retval) { $span->resource = 'sendRequest'; $span->name = 'Psr\Http\Client\ClientInterface.sendRequest'; $span->type = Type::HTTP_CLIENT; - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; if (isset($args[0])) { self::addRequestInfo($span, $args[0]); @@ -36,7 +37,7 @@ static function (SpanData $span, $args, $retval) { if (isset($retval)) { /** @var \Psr\Http\Message\ResponseInterface $retval */ $statusCode = $retval->getStatusCode(); - $span->meta[Tag::HTTP_STATUS_CODE] = $statusCode; + $span->attributes[Tag::HTTP_STATUS_CODE] = (string)$statusCode; HttpClientIntegrationHelper::setClientError($span, $statusCode, $retval->getReasonPhrase()); } } @@ -52,7 +53,7 @@ public static function addRequestInfo(SpanData $span, $request) $host = Urls::hostname($url); if ($host) { - $span->meta[Tag::NETWORK_DESTINATION_NAME] = $host; + $span->attributes[Tag::NETWORK_DESTINATION_NAME] = $host; } if (\dd_trace_env_config("DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN")) { @@ -60,10 +61,10 @@ public static function addRequestInfo(SpanData $span, $request) $span->attributes['_dd.svc_src'] = 'opt.http_client_split_by_domain'; } - $span->meta[Tag::HTTP_METHOD] = $request->getMethod(); + $span->attributes[Tag::HTTP_METHOD] = $request->getMethod(); - if (!array_key_exists(Tag::HTTP_URL, $span->meta)) { - $span->meta[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($url); + if (!array_key_exists(Tag::HTTP_URL, $span->attributes)) { + $span->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($url); } } } diff --git a/src/DDTrace/Integrations/Ratchet/RatchetIntegration.php b/src/DDTrace/Integrations/Ratchet/RatchetIntegration.php index c7feb8c6f5d..6f2b3ab6fc2 100644 --- a/src/DDTrace/Integrations/Ratchet/RatchetIntegration.php +++ b/src/DDTrace/Integrations/Ratchet/RatchetIntegration.php @@ -8,6 +8,7 @@ use DDTrace\Integrations\Integration; use DDTrace\RootSpanData; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\SpanLink; use DDTrace\SpanStack; use DDTrace\Tag; @@ -62,11 +63,11 @@ public static function init(): int $span->type = Type::HTTP_CLIENT; Integration::handleInternalSpanServiceName($span, self::NAME); $span->peerServiceSources = HttpClientIntegrationHelper::PEER_SERVICE_SOURCES; - $span->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_CLIENT; - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::HTTP_METHOD] = "GET"; - $span->meta[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($url); - $span->meta[Tag::NETWORK_DESTINATION_NAME] = Urls::hostname($url); + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; + $span->attributes[Tag::HTTP_METHOD] = "GET"; + $span->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize($url); + $span->attributes[Tag::NETWORK_DESTINATION_NAME] = Urls::hostname($url); \DDTrace\collect_code_origins(1); if (\dd_trace_env_config("DD_TRACE_HTTP_CLIENT_SPLIT_BY_DOMAIN")) { $span->service = Urls::hostnameForTag($url); @@ -83,8 +84,8 @@ public static function init(): int ObjectKVStore::put($websocket, "handshake", $span); ObjectKVStore::put($websocket, "handshake_root", $rootSpan); - $span->meta[Tag::HTTP_STATUS_CODE] = $websocket->response->getStatusCode(); - $span->meta["http.upgraded"] = '1'; + $span->attributes[Tag::HTTP_STATUS_CODE] = (string)$websocket->response->getStatusCode(); + $span->attributes["http.upgraded"] = true; $stackBefore = active_stack(); switch_stack($span); @@ -96,9 +97,9 @@ public static function init(): int // has the http status line as message $parts = explode(" ", $exception->getMessage()); if (count($parts) == 3 && is_numeric($parts[1])) { - $span->meta[Tag::HTTP_STATUS_CODE] = (int)$parts[1]; + $span->attributes[Tag::HTTP_STATUS_CODE] = (string)(int)$parts[1]; } else { - $span->meta[Tag::HTTP_STATUS_CODE] = 101; + $span->attributes[Tag::HTTP_STATUS_CODE] = '101'; } } $span->exception = $exception; @@ -169,12 +170,12 @@ public static function init(): int $pseudoglobals['_FILES'] = []; $activeSpan = $hook->span(new SpanStack); - $activeSpan->service = \ddtrace_config_app_name('ratchet'); + $activeSpan->service = \dd_trace_env_config('DD_SERVICE') ?: 'ratchet'; Integration::tagFrameworkServiceSource($activeSpan, 'ratchet'); $activeSpan->name = "web.request"; $activeSpan->type = Type::WEB_SERVLET; - $activeSpan->meta[Tag::COMPONENT] = self::NAME; - $activeSpan->attributes[Tag::SPAN_KIND] = 'server'; + $activeSpan->component = self::NAME; + $activeSpan->spanKind = SpanKind::SERVER; ObjectKVStore::put($parentConn, "handshake", $activeSpan); @@ -192,7 +193,7 @@ public static function init(): int \DDTrace\install_hook(CloseResponseTrait::class . "::close", static function (HookData $hook) { if ($rootSpan = \DDTrace\root_span()) { - $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = $hook->args[1] ?? 400; + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = (string)($hook->args[1] ?? 400); notify_commit($rootSpan, 400, []); } }); @@ -202,7 +203,7 @@ public static function init(): int /** @var ResponseInterface $response */ $response = $hook->returned; if ($response->getStatusCode() === 101) { - $span->meta["http.upgraded"] = '1'; + $span->attributes["http.upgraded"] = true; } notify_commit($span, $response->getStatusCode(), $response->getHeaders()); } @@ -253,27 +254,26 @@ public static function init(): int $span = $hook->span($rootTrace ? new SpanStack : null); $span->type = Type::WEBSOCKET; $span->service = $handshake->service; - $handshakeServiceSource = $handshake->attributes['_dd.svc_src'] - ?? $handshake->meta['_dd.svc_src'] ?? null; + $handshakeServiceSource = $handshake->attributes['_dd.svc_src'] ?? null; if ($handshakeServiceSource !== null) { $span->attributes['_dd.svc_src'] = $handshakeServiceSource; } $resourceParts = explode(" ", $handshake->resource, 2); $span->resource = "websocket " . end($resourceParts); - $span->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_CONSUMER; - $span->meta[Tag::COMPONENT] = RatchetIntegration::NAME; + $span->spanKind = SpanKind::CONSUMER; + $span->component = RatchetIntegration::NAME; if ($rootTrace && \dd_trace_env_config("DD_TRACE_WEBSOCKET_MESSAGES_INHERIT_SAMPLING")) { $span->samplingPriority = $rootSpan->samplingPriority; if (isset($rootSpan->origin)) { $span->origin = $rootSpan->origin; } - $span->metrics["_dd.dm.inherited"] = 1; + $span->attributes["_dd.dm.inherited"] = 1; if (!isset($rootSpan->parentId)) { - $span->meta["_dd.dm.service"] = $rootSpan->service; - $span->meta["_dd.dm.resource"] = $rootSpan->resource; + $span->attributes["_dd.dm.service"] = $rootSpan->service; + $span->attributes["_dd.dm.resource"] = $rootSpan->resource; } foreach ($rootSpan->propagatedTags as $key => $_) { - $value = $rootSpan->attributes[$key] ?? $rootSpan->meta[$key] ?? null; + $value = $rootSpan->attributes[$key] ?? null; if ($value !== null) { $span->attributes[$key] = $value; } @@ -285,14 +285,14 @@ public static function init(): int $span->name = "websocket.close"; $closePayload = $message->getPayload(); if (\strlen($closePayload) >= 2) { - $span->meta["websocket.close.code"] = unpack("n", $closePayload)[1]; + $span->attributes["websocket.close.code"] = unpack("n", $closePayload)[1]; if (\strlen($closePayload) > 2) { - $span->meta["websocket.close.reason"] = substr($closePayload, 2); + $span->attributes["websocket.close.reason"] = substr($closePayload, 2); } } } else { $span->name = "websocket.receive"; - $span->meta["websocket.message.type"] = $message->isBinary() ? "binary" : "text"; + $span->attributes["websocket.message.type"] = $message->isBinary() ? "binary" : "text"; } if ($isServer) { @@ -306,8 +306,8 @@ public static function init(): int \DDTrace\install_hook($onMessage, $hookFn(false), static function (HookData $hook) { $span = $hook->span(); $message = $hook->args[0]; - $span->metrics["websocket.message.length"] = $message->getPayloadLength(); - $span->metrics["websocket.message.frames"] = $message->count(); + $span->attributes["websocket.message.length"] = $message->getPayloadLength(); + $span->attributes["websocket.message.frames"] = $message->count(); }, \DDTrace\HOOK_INSTANCE); \DDTrace\install_hook($onControl, $hookFn(true), null, \DDTrace\HOOK_INSTANCE); @@ -355,12 +355,12 @@ public static function init(): int $span->type = Type::WEBSOCKET; $resourceParts = explode(" ", $handshake->resource, 2); $span->resource = "websocket " . end($resourceParts); - $span->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_PRODUCER; - $span->meta[Tag::COMPONENT] = RatchetIntegration::NAME; + $span->spanKind = SpanKind::PRODUCER; + $span->component = RatchetIntegration::NAME; $span->name = "websocket.close"; - $span->meta["websocket.close.code"] = $code; + $span->attributes["websocket.close.code"] = $code; if ($reason != "") { - $span->meta["websocket.close.reason"] = $reason; + $span->attributes["websocket.close.reason"] = $reason; } $frameNum = ObjectKVStore::get($handshake, "frameNum"); RatchetIntegration::addLink($span, $handshake, false, false, $frameNum); @@ -386,7 +386,7 @@ public static function outgoingMessage($msg, $hook, $handshakeContainer, $isServ } if ($opcode === Frame::OP_CONTINUE) { if (null !== $sendSpan = ObjectKVStore::get($handshakeContainer, "lastSendSpan")) { - ++$sendSpan->metrics["websocket.message.frames"]; + ++$sendSpan->attributes["websocket.message.frames"]; } return; } @@ -400,21 +400,21 @@ public static function outgoingMessage($msg, $hook, $handshakeContainer, $isServ $span->type = Type::WEBSOCKET; $resourceParts = explode(" ", $handshake->resource, 2); $span->resource = "websocket " . end($resourceParts); - $span->meta[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_PRODUCER; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->spanKind = SpanKind::PRODUCER; + $span->component = self::NAME; if ($opcode === Frame::OP_CLOSE) { $span->name = "websocket.close"; if (\strlen($closePayload) >= 2) { - $span->meta["websocket.close.code"] = unpack("n", $closePayload)[1]; + $span->attributes["websocket.close.code"] = unpack("n", $closePayload)[1]; if (\strlen($closePayload) > 2) { - $span->meta["websocket.close.reason"] = substr($closePayload, 2); + $span->attributes["websocket.close.reason"] = substr($closePayload, 2); } } } else { $span->name = "websocket.send"; - $span->meta["websocket.message.type"] = $opcode === Frame::OP_BINARY ? "binary" : "text"; - $span->metrics["websocket.message.length"] = $msgLen; - $span->metrics["websocket.message.frames"] = 1; + $span->attributes["websocket.message.type"] = $opcode === Frame::OP_BINARY ? "binary" : "text"; + $span->attributes["websocket.message.length"] = $msgLen; + $span->attributes["websocket.message.frames"] = 1; ObjectKVStore::put($handshakeContainer, "lastSendSpan", $span); } $frameNum = ObjectKVStore::get($handshake, "frameNum"); diff --git a/src/DDTrace/Integrations/Roadrunner/RoadrunnerIntegration.php b/src/DDTrace/Integrations/Roadrunner/RoadrunnerIntegration.php index e03033bec7a..6925f671e29 100644 --- a/src/DDTrace/Integrations/Roadrunner/RoadrunnerIntegration.php +++ b/src/DDTrace/Integrations/Roadrunner/RoadrunnerIntegration.php @@ -4,6 +4,7 @@ use DDTrace\HookData; use DDTrace\Integrations\Integration; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use function DDTrace\UserRequest\notify_commit; @@ -120,7 +121,7 @@ public static function init(): int ini_set("datadog.trace.auto_flush_enabled", 1); ini_set("datadog.trace.generate_root_span", 0); - $service = \ddtrace_config_app_name('roadrunner'); + $service = \dd_trace_env_config('DD_SERVICE') ?: 'roadrunner'; $suppressResponse = null; $recCall = 0; @@ -150,8 +151,8 @@ function (HookData $hook) use (&$activeSpan, &$suppressResponse, $service, &$rec Integration::tagFrameworkServiceSource($activeSpan, 'roadrunner'); $activeSpan->name = "web.request"; $activeSpan->type = Type::WEB_SERVLET; - $activeSpan->meta[Tag::COMPONENT] = RoadrunnerIntegration::NAME; - $activeSpan->attributes[Tag::SPAN_KIND] = 'server'; + $activeSpan->component = RoadrunnerIntegration::NAME; + $activeSpan->spanKind = SpanKind::SERVER; if ($hook->exception) { $activeSpan->exception = $hook->exception; \DDTrace\close_span(); @@ -243,7 +244,7 @@ static function ($res) use (&$activeSpan, &$suppressResponse, $thiz) { /** @var int $status */ $status = $hook->args[0]; - $activeSpan->meta[Tag::COMPONENT] = RoadrunnerIntegration::NAME; + $activeSpan->component = RoadrunnerIntegration::NAME; if ($hook->exception && empty($activeSpan->exception)) { $activeSpan->exception = $hook->exception; } elseif ($status >= 500 && $ex = \DDTrace\find_active_exception()) { diff --git a/src/DDTrace/Integrations/SQLSRV/SQLSRVIntegration.php b/src/DDTrace/Integrations/SQLSRV/SQLSRVIntegration.php index 48694ad984b..ed2c59891c2 100644 --- a/src/DDTrace/Integrations/SQLSRV/SQLSRVIntegration.php +++ b/src/DDTrace/Integrations/SQLSRV/SQLSRVIntegration.php @@ -6,6 +6,7 @@ use DDTrace\Integrations\DatabaseIntegrationHelper; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; @@ -130,11 +131,9 @@ public static function extractConnectionMetadata($connectionArguments) $connectionMetadata[Tag::DB_INSTANCE] = $instanceName; } - $port = ''; if (preg_match('/,\s?(\d+)/', $serverName, $matches)) { - $port = $matches[1]; + $connectionMetadata[Tag::TARGET_PORT] = (int)$matches[1]; } - $connectionMetadata[Tag::TARGET_PORT] = empty($port) ? '' : $port; $connectionInfo = $connectionArguments[1]; if (is_array($connectionInfo)) { @@ -168,12 +167,12 @@ public static function setDefaultAttributes($source, SpanData $span, $name, $que $span->resource = $query ?? $name; $span->type = Type::SQL; Integration::handleInternalSpanServiceName($span, self::NAME); - $span->meta[Tag::SPAN_KIND] = 'client'; - $span->meta[Tag::COMPONENT] = self::NAME; - $span->meta[Tag::DB_SYSTEM] = self::SYSTEM; + $span->spanKind = SpanKind::CLIENT; + $span->component = self::NAME; + $span->attributes[Tag::DB_SYSTEM] = self::SYSTEM; foreach ($storedConnectionInfo as $tag => $value) { - $span->meta[$tag] = $value; + $span->attributes[$tag] = $value; } $targetName = $storedConnectionInfo[Tag::DB_INSTANCE] ?? $storedConnectionInfo[Tag::TARGET_HOST] ?? ""; @@ -208,8 +207,8 @@ public static function detectError($SQLSRVRetval, SpanData $span) ); }, $errors)); - $span->meta[Tag::ERROR_MSG] = $errorMessages; - $span->meta[Tag::ERROR_TYPE] = 'SQLSRV error'; + $span->attributes[Tag::ERROR_MSG] = $errorMessages; + $span->attributes[Tag::ERROR_TYPE] = 'SQLSRV error'; } protected static function setMetrics(SpanData $span, $stmt) @@ -221,7 +220,7 @@ protected static function setMetrics(SpanData $span, $stmt) // in a result set can be retrieved only after all rows in the result set // have been read, and we cannot do that without fetching all the rows, which // could lead to some non-negligible overhead. - $span->metrics[Tag::DB_ROW_COUNT] = $numRows; + $span->attributes[Tag::DB_ROW_COUNT] = $numRows; } else { self::setMetricRowsAffected($span, $stmt); } @@ -234,7 +233,7 @@ protected static function setMetricRowsAffected(SpanData $span, $stmt) $rowsAffected = \sqlsrv_rows_affected($stmt); if ($rowsAffected !== false && $rowsAffected !== -1) { // If the function returns -1, the number of rows cannot be determined. - $span->metrics[Tag::DB_ROW_COUNT] = $rowsAffected; + $span->attributes[Tag::DB_ROW_COUNT] = $rowsAffected; } } } diff --git a/src/DDTrace/Integrations/Slim/SlimIntegration.php b/src/DDTrace/Integrations/Slim/SlimIntegration.php index a6a20fab08e..37275f9919a 100644 --- a/src/DDTrace/Integrations/Slim/SlimIntegration.php +++ b/src/DDTrace/Integrations/Slim/SlimIntegration.php @@ -4,6 +4,7 @@ use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use Psr\Http\Message\ServerRequestInterface; @@ -31,10 +32,10 @@ function ($app) { // Overwrite root span info $rootSpan = \DDTrace\root_span(); $rootSpan->name = 'slim.request'; - $rootSpan->service = \ddtrace_config_app_name(SlimIntegration::NAME); + $rootSpan->service = \dd_trace_env_config('DD_SERVICE') ?: SlimIntegration::NAME; Integration::tagFrameworkServiceSource($rootSpan, SlimIntegration::NAME); - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; - $rootSpan->meta[Tag::COMPONENT] = SlimIntegration::NAME; + $rootSpan->spanKind = SpanKind::SERVER; + $rootSpan->component = SlimIntegration::NAME; if ('4' === $majorVersion) { \DDTrace\hook_method('Slim\\MiddlewareDispatcher', 'addMiddleware', function ($This, $self, $args) { @@ -74,7 +75,7 @@ static function ($errorMiddleware, $self, $args) use ($rootSpan, $integration) { null, static function ($router, $scope, $args, $return) use ($rootSpan) { /** @var \Slim\Interfaces\RouteInterface $return */ - $rootSpan->meta[Tag::HTTP_ROUTE] = $return->getPattern(); + $rootSpan->attributes[Tag::HTTP_ROUTE] = $return->getPattern(); if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { $rootSpan->resource = @@ -91,7 +92,7 @@ static function ($router, $scope, $args, $return) use ($rootSpan) { static function ($router, $scope, $args, $return) use ($rootSpan) { /** @var \Slim\Interfaces\RouteInterface $route */ $route = $return; - $rootSpan->meta[Tag::HTTP_ROUTE] = $route->getPattern(); + $rootSpan->attributes[Tag::HTTP_ROUTE] = $route->getPattern(); } ); } @@ -121,18 +122,18 @@ static function ($router, $scope, $args, $return) use ($rootSpan) { if ('4' === $majorVersion) { $span->name = 'slim.route'; - $rootSpan->meta['slim.route.handler'] = $callableName; + $rootSpan->attributes['slim.route.handler'] = $callableName; $route = $request->getAttribute(RouteContext::ROUTE); if ($route && $route instanceof \Slim\Interfaces\RouteInterface) { $routeName = $route->getName(); if ($routeName) { - $span->meta['slim.route.name'] = $routeName; - $rootSpan->meta['slim.route.name'] = $routeName; + $span->attributes['slim.route.name'] = $routeName; + $rootSpan->attributes['slim.route.name'] = $routeName; } } } else { - $rootSpan->meta['slim.route.controller'] = $callableName; + $rootSpan->attributes['slim.route.controller'] = $callableName; $span->name = 'slim.route.controller'; } }; @@ -149,13 +150,13 @@ static function ($router, $scope, $args, $return) use ($rootSpan) { // Handling Twig views \DDTrace\trace_method('Slim\Views\Twig', 'render', static function (SpanData $span, $args) { $span->name = 'slim.view'; - $span->service = \ddtrace_config_app_name(SlimIntegration::NAME); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: SlimIntegration::NAME; Integration::tagFrameworkServiceSource($span, SlimIntegration::NAME); $span->type = Type::WEB_SERVLET; $template = $args[1]; $span->resource = $template; - $span->meta['slim.view'] = $template; - $span->meta[Tag::COMPONENT] = SlimIntegration::NAME; + $span->attributes['slim.view'] = $template; + $span->component = SlimIntegration::NAME; }); } ); diff --git a/src/DDTrace/Integrations/Swoole/SwooleIntegration.php b/src/DDTrace/Integrations/Swoole/SwooleIntegration.php index dcd95f38aaa..d989347b2b8 100644 --- a/src/DDTrace/Integrations/Swoole/SwooleIntegration.php +++ b/src/DDTrace/Integrations/Swoole/SwooleIntegration.php @@ -4,6 +4,7 @@ use DDTrace\HookData; use DDTrace\Integrations\Integration; +use DDTrace\SpanKind; use DDTrace\SpanStack; use DDTrace\Tag; use DDTrace\Type; @@ -28,11 +29,11 @@ public static function instrumentRequestStart(callable $callback, Server $server static function (HookData $hook) use ($server, $scheme) { $rootSpan = $hook->span(new SpanStack()); $rootSpan->name = "web.request"; - $rootSpan->service = \ddtrace_config_app_name('swoole'); + $rootSpan->service = \dd_trace_env_config('DD_SERVICE') ?: 'swoole'; Integration::tagFrameworkServiceSource($rootSpan, self::NAME); $rootSpan->type = Type::WEB_SERVLET; - $rootSpan->meta[Tag::COMPONENT] = self::NAME; - $rootSpan->attributes[Tag::SPAN_KIND] = Tag::SPAN_KIND_VALUE_SERVER; + $rootSpan->component = self::NAME; + $rootSpan->spanKind = SpanKind::SERVER; $args = $hook->args; /** @var Request $request */ @@ -53,7 +54,7 @@ static function (HookData $hook) use ($server, $scheme) { if (\dd_trace_env_config("DD_TRACE_CLIENT_IP_ENABLED")) { $res = extract_ip_from_headers($headers + ['REMOTE_ADDR' => $request->server['remote_addr']]); - $rootSpan->meta += $res; + $rootSpan->attributes += $res; } if (isset($headers["user-agent"])) { @@ -77,7 +78,7 @@ static function (HookData $hook) use ($server, $scheme) { if (!empty($postFields)) { $postFields = Normalizer::sanitizePostFields($postFields); foreach ($postFields as $key => $value) { - $rootSpan->meta["http.request.post.$key"] = $value; + $rootSpan->attributes["http.request.post.$key"] = $value; } } @@ -164,8 +165,7 @@ static function ($response, $scope, $args) { // Note: The response's body can be retrieved here, from the args if (!$rootSpan->exception - && ((int)($rootSpan->attributes[Tag::HTTP_STATUS_CODE] - ?? $rootSpan->meta[Tag::HTTP_STATUS_CODE] ?? 0)) >= 500 + && (int)($rootSpan->attributes[Tag::HTTP_STATUS_CODE] ?? 0) >= 500 && $ex = \DDTrace\find_active_exception() ) { $rootSpan->exception = $ex; @@ -199,7 +199,7 @@ static function ($response, $scope, $args) { static function ($response, $scope, $args) { $rootSpan = \DDTrace\root_span(); if ($rootSpan && \count($args) > 0) { - $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = $args[0]; + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = (string)$args[0]; } } ); diff --git a/src/DDTrace/Integrations/Symfony/SymfonyIntegration.php b/src/DDTrace/Integrations/Symfony/SymfonyIntegration.php index 2e8c7fc9ba2..02675039a61 100644 --- a/src/DDTrace/Integrations/Symfony/SymfonyIntegration.php +++ b/src/DDTrace/Integrations/Symfony/SymfonyIntegration.php @@ -6,6 +6,7 @@ use DDTrace\Integrations\Drupal\DrupalIntegration; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\Normalizer; @@ -39,20 +40,20 @@ public static function init(): int return false; } - $service = \ddtrace_config_app_name('symfony'); + $service = \dd_trace_env_config('DD_SERVICE') ?: 'symfony'; $rootSpan->name = 'symfony.request'; $rootSpan->service = $service; Integration::tagFrameworkServiceSource($rootSpan, SymfonyIntegration::NAME); - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; - $rootSpan->meta[Tag::COMPONENT] = SymfonyIntegration::NAME; + $rootSpan->spanKind = SpanKind::SERVER; + $rootSpan->component = SymfonyIntegration::NAME; $span->name = 'symfony.httpkernel.kernel.handle'; $span->resource = \get_class($this); $span->type = Type::WEB_SERVLET; $span->service = $service; Integration::tagFrameworkServiceSource($span, SymfonyIntegration::NAME); - $span->attributes[Tag::SPAN_KIND] = 'server'; - $span->meta[Tag::COMPONENT] = SymfonyIntegration::NAME; + $span->spanKind = SpanKind::SERVER; + $span->component = SymfonyIntegration::NAME; }, ] ); @@ -69,9 +70,9 @@ public static function init(): int $span->name = 'symfony.httpkernel.kernel.boot'; $span->resource = \get_class($this); $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name('symfony'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'symfony'; Integration::tagFrameworkServiceSource($span, SymfonyIntegration::NAME); - $span->meta[Tag::COMPONENT] = SymfonyIntegration::NAME; + $span->component = SymfonyIntegration::NAME; }, ] ); @@ -319,11 +320,11 @@ static function($This, $scope, $args, $result) { $span->name = 'symfony.console.command.run'; $span->resource = $commandName ?: $span->name; - $span->service = \ddtrace_config_app_name(SymfonyIntegration::$frameworkPrefix); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: SymfonyIntegration::$frameworkPrefix; Integration::tagFrameworkServiceSource($span, SymfonyIntegration::$frameworkPrefix); $span->type = Type::CLI; - $span->meta['symfony.console.command.class'] = \get_class($this); - $span->meta[Tag::COMPONENT] = SymfonyIntegration::NAME; + $span->attributes['symfony.console.command.class'] = \get_class($this); + $span->component = SymfonyIntegration::NAME; } ] ); @@ -390,7 +391,7 @@ static function(SpanData $span) use ($class, $methodname) { $span->name = "{$replaced}.{$methodname}"; $span->resource = "{$class}::{$methodname}"; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name('doctrine'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'doctrine'; } ); } @@ -446,7 +447,7 @@ static function() { } if ($path !== null) { - $rootSpan->meta[Tag::HTTP_ROUTE] = $path; + $rootSpan->attributes[Tag::HTTP_ROUTE] = $path; } }; } else { @@ -461,21 +462,21 @@ static function(SpanData $span, $args, $response) use ($handle_http_route) { list($request) = $args; $span->name = 'symfony.kernel.handle'; - $span->service = \ddtrace_config_app_name(self::$frameworkPrefix); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: self::$frameworkPrefix; Integration::tagFrameworkServiceSource($span, self::$frameworkPrefix); $span->type = Type::WEB_SERVLET; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; $rootSpan = \DDTrace\root_span(); $rootSpan->attributes[Tag::HTTP_METHOD] = $request->getMethod(); - $rootSpan->meta[Tag::COMPONENT] = self::$frameworkPrefix; - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; + $rootSpan->component = self::$frameworkPrefix; + $rootSpan->spanKind = SpanKind::SERVER; if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { $rootSpan->attributes[Tag::HTTP_URL] = Normalizer::urlSanitize($request->getUri()); } if (isset($response)) { - $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = $response->getStatusCode(); + $rootSpan->attributes[Tag::HTTP_STATUS_CODE] = (string)$response->getStatusCode(); } $route_name = $request->attributes->get('_route'); @@ -483,7 +484,7 @@ static function(SpanData $span, $args, $response) use ($handle_http_route) { if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { $rootSpan->resource = $route_name; } - $rootSpan->meta['symfony.route.name'] = $route_name; + $rootSpan->attributes['symfony.route.name'] = $route_name; $handle_http_route($route_name, $request, $rootSpan); } @@ -541,9 +542,9 @@ static function(HookData $hook) use ($controllerName) { $span->name = 'symfony.controller'; $span->resource = $controllerName; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name(self::$frameworkPrefix); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: self::$frameworkPrefix; Integration::tagFrameworkServiceSource($span, self::$frameworkPrefix); - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; \DDTrace\remove_hook($hook->id); } @@ -557,9 +558,9 @@ static function(HookData $hook) use ($controllerName) { $span->name = 'symfony.controller'; $span->resource = $controllerName; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name(self::$frameworkPrefix); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: self::$frameworkPrefix; Integration::tagFrameworkServiceSource($span, self::$frameworkPrefix); - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; \DDTrace\remove_hook($hook->id); } @@ -570,9 +571,9 @@ static function(HookData $hook) use ($controllerName) { } $span->name = $span->resource = 'symfony.' . $eventName; - $span->service = \ddtrace_config_app_name(self::$frameworkPrefix); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: self::$frameworkPrefix; Integration::tagFrameworkServiceSource($span, self::$frameworkPrefix); - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; if ($event === null) { return; } @@ -616,9 +617,9 @@ static function(HookData $hook) use ($controllerName) { // Handling exceptions $exceptionHandlingTracer = static function(SpanData $span, $args, $retval) { $span->name = $span->resource = 'symfony.kernel.handleException'; - $span->service = \ddtrace_config_app_name(self::$frameworkPrefix); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: self::$frameworkPrefix; Integration::tagFrameworkServiceSource($span, self::$frameworkPrefix); - $span->meta[Tag::COMPONENT] = self::NAME; + $span->component = self::NAME; \DDTrace\root_span()->exception = $args[0]; if (isset($retval) && \method_exists($retval, 'getStatusCode') && $retval->getStatusCode() < 500) { @@ -635,13 +636,13 @@ static function(HookData $hook) use ($controllerName) { // Tracing templating engines $traceRender = function(SpanData $span, $args) { $span->name = 'symfony.templating.render'; - $span->service = \ddtrace_config_app_name(SymfonyIntegration::$frameworkPrefix); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: SymfonyIntegration::$frameworkPrefix; Integration::tagFrameworkServiceSource($span, SymfonyIntegration::$frameworkPrefix); $span->type = Type::WEB_SERVLET; $resourceName = count($args) > 0 ? get_class($this) . ' ' . $args[0] : get_class($this); $span->resource = $resourceName; - $span->meta[Tag::COMPONENT] = SymfonyIntegration::NAME; + $span->component = SymfonyIntegration::NAME; }; \DDTrace\trace_method('Symfony\Bridge\Twig\TwigEngine', 'render', $traceRender); \DDTrace\trace_method('Symfony\Bundle\FrameworkBundle\Templating\TimedPhpEngine', 'render', $traceRender); @@ -755,7 +756,7 @@ public static function injectActionInfo($event, $eventName, SpanData $requestSpa } $action = get_class($controllerAndAction[0]) . '@' . $controllerAndAction[1]; - $requestSpan->meta['symfony.route.action'] = $action; + $requestSpan->attributes['symfony.route.action'] = $action; return true; } diff --git a/src/DDTrace/Integrations/SymfonyMessenger/SymfonyMessengerIntegration.php b/src/DDTrace/Integrations/SymfonyMessenger/SymfonyMessengerIntegration.php index e72cf290341..bfa0c9df551 100644 --- a/src/DDTrace/Integrations/SymfonyMessenger/SymfonyMessengerIntegration.php +++ b/src/DDTrace/Integrations/SymfonyMessenger/SymfonyMessengerIntegration.php @@ -5,6 +5,7 @@ use DDTrace\HookData; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Util\ObjectKVStore; use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsReceivedStamp; @@ -56,7 +57,7 @@ static function (HookData $hook) { /** @var \Symfony\Component\Messenger\Envelope $envelope */ $envelope = $hook->args[0]; - if (\ddtrace_config_distributed_tracing_enabled()) { + if (\dd_trace_env_config('DD_DISTRIBUTED_TRACING')) { $tracingHeaders = \DDTrace\generate_distributed_tracing_headers(); $datadogHeaders = ['datadog' => $tracingHeaders]; $hook->overrideArguments([ @@ -228,12 +229,12 @@ public static function setSpanAttributes( } $span->name = $name; - $span->service = \ddtrace_config_app_name('symfony'); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: 'symfony'; Integration::tagFrameworkServiceSource($span, 'symfony'); $span->type = 'queue'; - $span->meta[Tag::MQ_SYSTEM] = 'symfony'; - $span->meta[Tag::MQ_DESTINATION_KIND] = 'queue'; - $span->meta[Tag::COMPONENT] = self::NAME; + $span->attributes[Tag::MQ_SYSTEM] = 'symfony'; + $span->attributes[Tag::MQ_DESTINATION_KIND] = 'queue'; + $span->component = self::NAME; } public static function resolveMetadataFromEnvelope( @@ -285,9 +286,8 @@ public static function resolveMetadataFromEnvelope( 'messaging.symfony.redelivered_at' => $redeliveryStamp ? $redeliveryStamp->getRedeliveredAt()->format('Y-m-d\TH:i:sP') : null, 'messaging.symfony.sender' => $senderClass, Tag::MQ_DESTINATION => $transportName, - Tag::MQ_MESSAGE_ID => $transportMessageId, + Tag::MQ_MESSAGE_ID => $transportMessageId === null ? null : (string)$transportMessageId, Tag::MQ_OPERATION => $operation, - Tag::SPAN_KIND => self::determineSpanKind($operation), ]; $metrics = [ @@ -308,39 +308,42 @@ public static function resolveMetadataFromEnvelope( } } $span->resource = $resource; - $span->meta = \array_merge($span->meta, \array_filter($metadata)); - $span->metrics = \array_merge($span->metrics, \array_filter($metrics)); + $span->attributes = \array_merge($span->attributes, \array_filter($metadata), \array_filter($metrics)); + $spanKind = self::determineSpanKind($operation); + if ($spanKind) { + $span->spanKind = $spanKind; + } } public static function tryResolveMetadataFromMessage(SpanData $span, $message, $resource, $transportName, $operation) { if ($message) { $messageName = \get_class($message); $resource = $resource ?? $messageName; - $span->meta['messaging.symfony.message'] = $messageName; + $span->attributes['messaging.symfony.message'] = $messageName; } if ($resource) { $span->resource = $resource; } if ($transportName) { - $span->meta[Tag::MQ_DESTINATION] = $transportName; + $span->attributes[Tag::MQ_DESTINATION] = $transportName; } if ($operation) { - $span->meta[Tag::MQ_OPERATION] = $operation; + $span->attributes[Tag::MQ_OPERATION] = $operation; } $spanKind = self::determineSpanKind($operation); if ($spanKind) { - $span->meta[Tag::SPAN_KIND] = $spanKind; + $span->spanKind = $spanKind; } } public static function determineSpanKind($operation) { switch ($operation) { case 'receive': - return Tag::SPAN_KIND_VALUE_CONSUMER; + return SpanKind::CONSUMER; case 'send': - return Tag::SPAN_KIND_VALUE_PRODUCER; + return SpanKind::PRODUCER; default: return null; // Internal operation is implicit } diff --git a/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php b/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php index a407df5771b..f13c2858ce6 100644 --- a/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php +++ b/src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php @@ -5,6 +5,7 @@ use DDTrace\HookData; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\Normalizer; @@ -122,8 +123,8 @@ public static function setCommonTags( $span->name = $name; $span->resource = $resource ?: $name; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name(WordPressIntegration::NAME); - $span->meta[Tag::COMPONENT] = WordPressIntegration::NAME; + $span->service = \dd_trace_env_config('DD_SERVICE') ?: WordPressIntegration::NAME; + $span->component = WordPressIntegration::NAME; } public static function getInterestingActions() @@ -205,9 +206,9 @@ public static function load() $rootSpan = \DDTrace\root_span(); if ($rootSpan) { $rootSpan->name = 'wordpress.request'; - $rootSpan->service = \ddtrace_config_app_name(WordPressIntegration::NAME);; - $rootSpan->meta[Tag::COMPONENT] = WordPressIntegration::NAME; - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; + $rootSpan->service = \dd_trace_env_config('DD_SERVICE') ?: WordPressIntegration::NAME;; + $rootSpan->component = WordPressIntegration::NAME; + $rootSpan->spanKind = SpanKind::SERVER; if ('cli' !== PHP_SAPI) { $normalizedPath = Normalizer::uriNormalizeincomingPath($_SERVER['REQUEST_URI']); $rootSpan->resource = $_SERVER['REQUEST_METHOD'] . ' ' . $normalizedPath; @@ -254,7 +255,7 @@ static function (HookData $hook) use ($themeRoot, $dir) { 'load_theme', "$themeName (theme)" ); - $span->meta['wordpress.theme'] = $themeName; + $span->attributes['wordpress.theme'] = $themeName; remove_hook($hook->id); } @@ -384,7 +385,7 @@ static function (HookData $hook) use ($themeRoot, $dir) { ); if (isset($this->name)) { - $span->meta['wordpress.widget'] = $this->name; + $span->attributes['wordpress.widget'] = $this->name; } }); }); @@ -419,9 +420,9 @@ static function (HookData $hook) use ($themeRoot, $dir) { $templateFile = $args[0]; if ($plugin = self::extractPluginNameFromFile($templateFile)) { - $span->meta['wordpress.plugin'] = $plugin; + $span->attributes['wordpress.plugin'] = $plugin; } elseif ($theme = self::extractThemeNameFromFile($templateFile)) { - $span->meta['wordpress.theme'] = $theme; + $span->attributes['wordpress.theme'] = $theme; } if (substr($templateFile, -4) === '.php') { @@ -429,7 +430,7 @@ static function (HookData $hook) use ($themeRoot, $dir) { $templatePart = end($templatePart); $templatePart = substr($templatePart, 0, -4); $span->resource = "$templatePart (template)"; - $span->meta['wordpress.template_part'] = $templatePart; + $span->attributes['wordpress.template_part'] = $templatePart; } }); @@ -438,7 +439,7 @@ static function (HookData $hook) use ($themeRoot, $dir) { $postID = get_the_ID(); if ($postID) { - $span->meta['wordpress.post.id'] = $postID; + $span->attributes['wordpress.post.id'] = $postID; } }); @@ -454,7 +455,7 @@ static function (HookData $hook) use ($themeRoot, $dir) { self::setCommonTags($span, 'the_post_thumbnail'); if (isset($args[0]) && is_string($args[0])) { - $span->meta['wordpress.post.thumbnail_size'] = $args[0]; + $span->attributes['wordpress.post.thumbnail_size'] = $args[0]; } }); @@ -487,7 +488,7 @@ static function (HookData $hook) use ($themeRoot, $dir) { "$blockName (block)" ); - $span->meta['wordpress.block.name'] = $blockName; + $span->attributes['wordpress.block.name'] = $blockName; $attrs = $block->attributes; foreach ($attrs as $attr => $value) { @@ -495,9 +496,9 @@ static function (HookData $hook) use ($themeRoot, $dir) { if (empty($value)) { continue; } elseif (is_string($value) || is_int($value) || is_bool($value)) { - $span->meta["wordpress.block.attr.$attr"] = $value; + $span->attributes["wordpress.block.attr.$attr"] = $value; } elseif (is_array($value)) { - $span->meta["wordpress.block.attr.$attr"] = json_encode($value); + $span->attributes["wordpress.block.attr.$attr"] = json_encode($value); } // Note: Purposefully ignoring objects because of the unpredictability nature of their // __toString() implementation, if any. In reality, there shouldn't be any objects in @@ -509,9 +510,9 @@ static function (HookData $hook) use ($themeRoot, $dir) { if ($namespaceName !== 'core') { $themeName = wp_get_theme()->get('Name'); if (strtolower($namespaceName) === strtolower($themeName)) { - $span->meta['wordpress.theme'] = $themeName; + $span->attributes['wordpress.theme'] = $themeName; } else { - $span->meta['wordpress.plugin'] = $namespaceName; + $span->attributes['wordpress.plugin'] = $namespaceName; } } @@ -528,7 +529,7 @@ static function (HookData $hook) use ($themeRoot, $dir) { ); if (isset($args[0]) && is_string($args[0])) { - $span->meta['wordpress.template_part'] = $args[0]; + $span->attributes['wordpress.template_part'] = $args[0]; } }); @@ -541,11 +542,11 @@ static function (HookData $hook) use ($themeRoot, $dir) { $themeName = self::extractThemeNameFromFile($path); if ($themeName) { - $span->meta['wordpress.theme'] = $themeName; + $span->attributes['wordpress.theme'] = $themeName; } if (isset($args[0]) && is_string($args[0])) { - $span->meta['wordpress.template_type'] = $args[0]; + $span->attributes['wordpress.template_type'] = $args[0]; } }); @@ -588,11 +589,11 @@ static function (HookData $hook) use ( } $span->resource = "$hookName (hook)"; - $span->meta['wordpress.hook'] = $hookName; + $span->attributes['wordpress.hook'] = $hookName; if (isset($actionHookToPlugin[$hookName])) { // Don't waste time if it gave null before if ($actionHookToPlugin[$hookName]) { - $span->meta['wordpress.plugin'] = $actionHookToPlugin[$hookName]; + $span->attributes['wordpress.plugin'] = $actionHookToPlugin[$hookName]; } } else { $file = $hook->getSourceFile(); @@ -603,7 +604,7 @@ static function (HookData $hook) use ( $actionHookToPlugin ) ) { - $span->meta['wordpress.plugin'] = $plugin; + $span->attributes['wordpress.plugin'] = $plugin; } elseif ( $theme = self::extractAndSaveThemeNameFromSpan( $file, @@ -611,7 +612,7 @@ static function (HookData $hook) use ( $actionHookToTheme ) ) { - $span->meta['wordpress.theme'] = $theme; + $span->attributes['wordpress.theme'] = $theme; } } } @@ -655,7 +656,7 @@ static function (HookData $hook) use (&$plugins, $plugin, $getPrettyPluginNameFn 'load_plugin', "$pluginName (plugin)" ); - $span->meta['wordpress.plugin'] = $pluginName; + $span->attributes['wordpress.plugin'] = $pluginName; }, static function ($hook) use (&$plugins) { $top = \array_pop($plugins); @@ -703,16 +704,16 @@ static function (HookData $hook) use ( 'callback', $callbackName . ' (callback)' ); - $span->meta['wordpress.callback'] = $callbackName; - $span->meta['wordpress.hook'] = $action; + $span->attributes['wordpress.callback'] = $callbackName; + $span->attributes['wordpress.hook'] = $action; $file = $hook->getSourceFile(); if ($plugin = self::extractPluginNameFromFile($file)) { - $span->meta['wordpress.plugin'] = $plugin; + $span->attributes['wordpress.plugin'] = $plugin; } elseif ($themeName = self::extractThemeNameFromFile($file)) { - $span->meta['wordpress.theme'] = $themeName; + $span->attributes['wordpress.theme'] = $themeName; } elseif ($pluginName) { - $span->meta['wordpress.plugin'] = $pluginName; + $span->attributes['wordpress.plugin'] = $pluginName; } remove_hook($hook->id); @@ -730,7 +731,7 @@ static function (HookData $hook) use ( function_exists('is_404') && is_404() === false) { $rootSpan = \DDTrace\root_span(); if (\property_exists($This, 'matched_rule')) { - $rootSpan->meta[Tag::HTTP_ROUTE] = $This->matched_rule; + $rootSpan->attributes[Tag::HTTP_ROUTE] = $This->matched_rule; } } }); diff --git a/src/DDTrace/Integrations/Yii/YiiIntegration.php b/src/DDTrace/Integrations/Yii/YiiIntegration.php index 6bbb54c95b6..eee1a925715 100644 --- a/src/DDTrace/Integrations/Yii/YiiIntegration.php +++ b/src/DDTrace/Integrations/Yii/YiiIntegration.php @@ -4,6 +4,7 @@ use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Tag; use DDTrace\Type; use DDTrace\Util\Versions; @@ -28,8 +29,8 @@ public static function init(): int static function () { $rootSpan = \DDTrace\root_span(); if ($rootSpan !== null) { - $rootSpan->meta[Tag::COMPONENT] = self::NAME; - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; + $rootSpan->component = self::NAME; + $rootSpan->spanKind = SpanKind::SERVER; } } ); @@ -40,8 +41,8 @@ static function () { function (SpanData $span) { $span->name = $span->resource = \get_class($this) . '.run'; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name(YiiIntegration::NAME); - $span->meta[Tag::COMPONENT] = YiiIntegration::NAME; + $span->service = \dd_trace_env_config('DD_SERVICE') ?: YiiIntegration::NAME; + $span->component = YiiIntegration::NAME; } ); @@ -68,9 +69,9 @@ static function ($app, $appClass, $args, $retval) use (&$firstController) { function (SpanData $span, $args) { $span->name = \get_class($this) . '.runAction'; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name(YiiIntegration::NAME); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: YiiIntegration::NAME; $span->resource = YiiIntegration::extractResourceNameFromRunAction($args) ?: $span->name; - $span->meta[Tag::COMPONENT] = YiiIntegration::NAME; + $span->component = YiiIntegration::NAME; } ); @@ -80,26 +81,26 @@ function (SpanData $span, $args) { function (SpanData $span, $args) use (&$firstController) { $span->name = \get_class($this) . '.runAction'; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name(YiiIntegration::NAME); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: YiiIntegration::NAME; $span->resource = YiiIntegration::extractResourceNameFromRunAction($args) ?: $span->name; - $span->meta[Tag::COMPONENT] = YiiIntegration::NAME; + $span->component = YiiIntegration::NAME; $rootSpan = \DDTrace\root_span(); if ( $firstController === $this - && empty($rootSpan->meta['app.endpoint']) + && empty($rootSpan->attributes['app.endpoint']) && isset($this->action->actionMethod) ) { $controller = \get_class($this); $endpoint = "{$controller}::{$this->action->actionMethod}"; - $rootSpan->meta["app.endpoint"] = $endpoint; + $rootSpan->attributes["app.endpoint"] = $endpoint; $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize(Url::base(true) . Url::current()); } - if (empty($rootSpan->meta['app.route.path'])) { + if (empty($rootSpan->attributes['app.route.path'])) { $placeholder = '__dd_route_param'; // When controllers are directly set in the app, @@ -145,8 +146,8 @@ function (SpanData $span, $args) use (&$firstController) { true ); - $rootSpan->meta['app.route.path'] = $routePath; - $rootSpan->meta[Tag::HTTP_ROUTE] = $routePath; + $rootSpan->attributes['app.route.path'] = $routePath; + $rootSpan->attributes[Tag::HTTP_ROUTE] = $routePath; if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { $resourceName = \str_replace( @@ -166,9 +167,9 @@ function (SpanData $span, $args) use (&$firstController) { function (SpanData $span, $args) { $span->name = \get_class($this) . '.renderFile'; $span->type = Type::WEB_SERVLET; - $span->service = \ddtrace_config_app_name(YiiIntegration::NAME); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: YiiIntegration::NAME; $span->resource = isset($args[0]) && \is_string($args[0]) ? $args[0] : $span->name; - $span->meta[Tag::COMPONENT] = YiiIntegration::NAME; + $span->component = YiiIntegration::NAME; } ); diff --git a/src/DDTrace/Integrations/ZendFramework/V1/Ddtrace.php b/src/DDTrace/Integrations/ZendFramework/V1/Ddtrace.php index 48e4a4c3793..cc7c73f3629 100644 --- a/src/DDTrace/Integrations/ZendFramework/V1/Ddtrace.php +++ b/src/DDTrace/Integrations/ZendFramework/V1/Ddtrace.php @@ -19,7 +19,7 @@ public function init() $span = \DDTrace\root_span(); $span->name = self::getOperationName(); - $span->service = \ddtrace_config_app_name(self::NAME); + $span->service = \dd_trace_env_config('DD_SERVICE') ?: self::NAME; Integration::tagFrameworkServiceSource($span, self::NAME); } diff --git a/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php b/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php index 38b3487241f..eeb50950c4e 100644 --- a/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php +++ b/src/DDTrace/Integrations/ZendFramework/V1/TraceRequest.php @@ -4,6 +4,7 @@ use DDTrace\Integrations\Integration; use DDTrace\Integrations\ZendFramework\ZendFrameworkIntegration; +use DDTrace\SpanKind; use DDTrace\Tag; use Zend_Controller_Front; use Zend_Controller_Plugin_Abstract; @@ -25,15 +26,15 @@ public function preDispatch(Zend_Controller_Request_Abstract $request) $controller = $request->getControllerName(); $action = $request->getActionName(); $route = Zend_Controller_Front::getInstance()->getRouter()->getCurrentRouteName(); - $span->meta['zf1.controller'] = $controller; - $span->meta['zf1.action'] = $action; - $span->meta['zf1.route_name'] = $route; + $span->attributes['zf1.controller'] = $controller; + $span->attributes['zf1.action'] = $action; + $span->attributes['zf1.route_name'] = $route; if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { $span->resource = $controller . '@' . $action . ' ' . $route; } $span->attributes[Tag::HTTP_METHOD] = $request->getMethod(); - $span->attributes[Tag::SPAN_KIND] = 'server'; - $span->meta[Tag::COMPONENT] = ZendFrameworkIntegration::NAME; + $span->spanKind = SpanKind::SERVER; + $span->component = ZendFrameworkIntegration::NAME; if (!Integration::hasTag($span, Tag::HTTP_URL)) { $span->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize( @@ -53,6 +54,6 @@ public function postDispatch(Zend_Controller_Request_Abstract $request) if (null === $span) { return; } - $span->attributes[Tag::HTTP_STATUS_CODE] = $this->getResponse()->getHttpResponseCode(); + $span->attributes[Tag::HTTP_STATUS_CODE] = (string)$this->getResponse()->getHttpResponseCode(); } } diff --git a/src/DDTrace/Integrations/ZendFramework/ZendFrameworkIntegration.php b/src/DDTrace/Integrations/ZendFramework/ZendFrameworkIntegration.php index 25c27e606c0..8a996000eda 100644 --- a/src/DDTrace/Integrations/ZendFramework/ZendFrameworkIntegration.php +++ b/src/DDTrace/Integrations/ZendFramework/ZendFrameworkIntegration.php @@ -5,6 +5,7 @@ use DDTrace\Tag; use DDTrace\Integrations\Integration; use DDTrace\SpanData; +use DDTrace\SpanKind; use DDTrace\Util\Runtime; use Zend_Controller_Front; @@ -43,20 +44,20 @@ static function ($broker, $scope, $args) { $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. - $rootSpan->service = \ddtrace_config_app_name('zf1'); + $rootSpan->service = \dd_trace_env_config('DD_SERVICE') ?: 'zf1'; Integration::tagFrameworkServiceSource($rootSpan, 'zf1'); $controller = $request->getControllerName(); $action = $request->getActionName(); $route = Zend_Controller_Front::getInstance()->getRouter()->getCurrentRouteName(); - $rootSpan->meta['zf1.controller'] = $controller; - $rootSpan->meta['zf1.action'] = $action; - $rootSpan->meta['zf1.route_name'] = $route; + $rootSpan->attributes['zf1.controller'] = $controller; + $rootSpan->attributes['zf1.action'] = $action; + $rootSpan->attributes['zf1.route_name'] = $route; if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { $rootSpan->resource = $controller . '@' . $action . ' ' . $route; } $rootSpan->attributes[Tag::HTTP_METHOD] = $request->getMethod(); - $rootSpan->attributes[Tag::SPAN_KIND] = 'server'; - $rootSpan->meta[Tag::COMPONENT] = self::NAME; + $rootSpan->spanKind = SpanKind::SERVER; + $rootSpan->component = self::NAME; if (!Integration::hasTag($rootSpan, Tag::HTTP_URL)) { $rootSpan->attributes[Tag::HTTP_URL] = \DDTrace\Util\Normalizer::urlSanitize( diff --git a/src/DDTrace/OpenTelemetry/Context.php b/src/DDTrace/OpenTelemetry/Context.php index be653be3a6a..5bb7e427523 100644 --- a/src/DDTrace/OpenTelemetry/Context.php +++ b/src/DDTrace/OpenTelemetry/Context.php @@ -5,7 +5,7 @@ namespace OpenTelemetry\Context; use DDTrace\SpanData; -use DDTrace\Tag; +use DDTrace\SpanKind; use DDTrace\Util\ObjectKVStore; use OpenTelemetry\API\Trace as API; use OpenTelemetry\API\Baggage\Baggage; @@ -144,18 +144,18 @@ private static function deactivateEndedParents(?SpanData $currentSpan) self::deactivateEndedParents($currentSpan->parent); } - private static function convertDDSpanKindToOtel(string $spanKind) + private static function convertDDSpanKindToOtel(int $spanKind) { switch ($spanKind) { - case Tag::SPAN_KIND_VALUE_CLIENT: + case SpanKind::CLIENT: return API\SpanKind::KIND_CLIENT; - case Tag::SPAN_KIND_VALUE_SERVER: + case SpanKind::SERVER: return API\SpanKind::KIND_SERVER; - case Tag::SPAN_KIND_VALUE_PRODUCER: + case SpanKind::PRODUCER: return API\SpanKind::KIND_PRODUCER; - case Tag::SPAN_KIND_VALUE_CONSUMER: + case SpanKind::CONSUMER: return API\SpanKind::KIND_CONSUMER; - case Tag::SPAN_KIND_VALUE_INTERNAL: + case SpanKind::INTERNAL: default: return API\SpanKind::KIND_INTERNAL; } @@ -211,11 +211,7 @@ private static function activateParent(?SpanData $currentSpan): ContextInterface $currentSpan, API\SpanContext::create($currentTraceId, $currentSpanId, $traceFlags, $traceState), // $context self::getDDInstrumentationScope(), // $instrumentationScope - isset($currentSpan->attributes[Tag::SPAN_KIND]) || isset($currentSpan->meta[Tag::SPAN_KIND]) - ? self::convertDDSpanKindToOtel( - $currentSpan->attributes[Tag::SPAN_KIND] ?? $currentSpan->meta[Tag::SPAN_KIND] - ) - : API\SpanKind::KIND_INTERNAL, // $kind + self::convertDDSpanKindToOtel($currentSpan->spanKind), // $kind API\Span::fromContext($parentContext), // $parentSpan (TODO: Handle null parent span) ? $parentContext, // $parentContext NoopSpanProcessor::getInstance(), // $spanProcessor diff --git a/src/DDTrace/OpenTelemetry/Convention.php b/src/DDTrace/OpenTelemetry/Convention.php index 95121cbc156..0492b905984 100644 --- a/src/DDTrace/OpenTelemetry/Convention.php +++ b/src/DDTrace/OpenTelemetry/Convention.php @@ -4,23 +4,25 @@ use DDTrace\SpanData; use DDTrace\Tag; +use DDTrace\Util\SpanKindNames; // Operation Name Conventions class Convention { public static function defaultOperationName(SpanData $span): string { - $meta = $span->attributes + $span->meta; - $spanKind = $meta[Tag::SPAN_KIND] ?? null; + $attributes = $span->attributes; + // A non-canonical span.kind stays a plain attribute + $spanKind = SpanKindNames::NAMES[$span->spanKind] ?? $attributes[Tag::SPAN_KIND] ?? null; switch (true) { - case isset($meta['http.request.method']) && $spanKind === Tag::SPAN_KIND_VALUE_SERVER: // HTTP Server + case isset($attributes['http.request.method']) && $spanKind === Tag::SPAN_KIND_VALUE_SERVER: // HTTP Server return 'http.server.request'; - case isset($meta['http.request.method']) && $spanKind === Tag::SPAN_KIND_VALUE_CLIENT: // HTTP Client + case isset($attributes['http.request.method']) && $spanKind === Tag::SPAN_KIND_VALUE_CLIENT: // HTTP Client return 'http.client.request'; - case isset($meta['db.system']) && $spanKind === Tag::SPAN_KIND_VALUE_CLIENT: // Database - return strtolower($meta['db.system']) . '.query'; - case isset($meta['messaging.system'], $meta['messaging.operation']) + case isset($attributes['db.system']) && $spanKind === Tag::SPAN_KIND_VALUE_CLIENT: // Database + return strtolower($attributes['db.system']) . '.query'; + case isset($attributes['messaging.system'], $attributes['messaging.operation']) && (in_array( $spanKind, [ Tag::SPAN_KIND_VALUE_CONSUMER, @@ -29,27 +31,27 @@ public static function defaultOperationName(SpanData $span): string Tag::SPAN_KIND_VALUE_CLIENT ] )): - return strtolower($meta['messaging.system']) . '.' . strtolower($meta['messaging.operation']); - case isset($meta['rpc.system']) && $meta['rpc.system'] === 'aws-api' + return strtolower($attributes['messaging.system']) . '.' . strtolower($attributes['messaging.operation']); + case isset($attributes['rpc.system']) && $attributes['rpc.system'] === 'aws-api' && $spanKind === Tag::SPAN_KIND_VALUE_CLIENT: // AWS Client - return isset($meta['rpc.service']) - ? 'aws.' . strtolower($meta['rpc.service']) . '.request' + return isset($attributes['rpc.service']) + ? 'aws.' . strtolower($attributes['rpc.service']) . '.request' : 'aws.client.request'; - case isset($meta['rpc.system']) && $spanKind === Tag::SPAN_KIND_VALUE_CLIENT: // RPC Client - return strtolower($meta['rpc.system']) . '.client.request'; - case isset($meta['rpc.system']) && $spanKind === Tag::SPAN_KIND_VALUE_SERVER: // RPC Server - return strtolower($meta['rpc.system']) . '.server.request'; - case isset($meta['faas.trigger']) && $spanKind === Tag::SPAN_KIND_VALUE_SERVER: // FaaS Server - return strtolower($meta['faas.trigger']) . '.invoke'; - case isset($meta['faas.invoked_provider'], $meta['faas.invoked_name']) + case isset($attributes['rpc.system']) && $spanKind === Tag::SPAN_KIND_VALUE_CLIENT: // RPC Client + return strtolower($attributes['rpc.system']) . '.client.request'; + case isset($attributes['rpc.system']) && $spanKind === Tag::SPAN_KIND_VALUE_SERVER: // RPC Server + return strtolower($attributes['rpc.system']) . '.server.request'; + case isset($attributes['faas.trigger']) && $spanKind === Tag::SPAN_KIND_VALUE_SERVER: // FaaS Server + return strtolower($attributes['faas.trigger']) . '.invoke'; + case isset($attributes['faas.invoked_provider'], $attributes['faas.invoked_name']) && $spanKind === Tag::SPAN_KIND_VALUE_CLIENT: // FaaS Client - return strtolower($meta['faas.invoked_provider']) . '.' . strtolower($meta['faas.invoked_name']) . '.invoke'; - case isset($meta['graphql.operation.type']): + return strtolower($attributes['faas.invoked_provider']) . '.' . strtolower($attributes['faas.invoked_name']) . '.invoke'; + case isset($attributes['graphql.operation.type']): return 'graphql.server.request'; case $spanKind === Tag::SPAN_KIND_VALUE_SERVER: // Generic case $spanKind === Tag::SPAN_KIND_VALUE_CLIENT: - return isset($meta['network.protocol.name']) - ? strtolower($meta['network.protocol.name']) . ".$spanKind.request" + return isset($attributes['network.protocol.name']) + ? strtolower($attributes['network.protocol.name']) . ".$spanKind.request" : "$spanKind.request"; case !empty($spanKind): return $spanKind; diff --git a/src/DDTrace/OpenTelemetry/Detectors/Service.php b/src/DDTrace/OpenTelemetry/Detectors/Service.php index 7efacaf4e32..91a78f3ab54 100644 --- a/src/DDTrace/OpenTelemetry/Detectors/Service.php +++ b/src/DDTrace/OpenTelemetry/Detectors/Service.php @@ -12,7 +12,7 @@ function (\DDTrace\HookData $hook) { if ($rootSpan) { $attributes['service.name'] = $rootSpan->service; } else { - $appName = \ddtrace_config_app_name(); + $appName = \dd_trace_env_config('DD_SERVICE'); if ($appName === '') { return; } diff --git a/src/DDTrace/OpenTelemetry/Span.php b/src/DDTrace/OpenTelemetry/Span.php index 1b5317d39db..feb8d3aa5cb 100644 --- a/src/DDTrace/OpenTelemetry/Span.php +++ b/src/DDTrace/OpenTelemetry/Span.php @@ -11,6 +11,7 @@ use DDTrace\Tag; use DDTrace\OpenTelemetry\Convention; use DDTrace\Util\ObjectKVStore; +use DDTrace\Util\SpanKindNames; use OpenTelemetry\API\Trace as API; use OpenTelemetry\SDK\Trace\LinkInterface; use OpenTelemetry\API\Trace\SpanContextInterface; @@ -28,6 +29,14 @@ final class Span extends API\Span implements ReadWriteSpanInterface { + /** Attributes stored on a SpanData string property rather than in $attributes. */ + private const PROPERTY_ATTRIBUTES = [ + 'resource.name' => 'resource', + 'operation.name' => 'name', + 'span.type' => 'type', + Tag::COMPONENT => 'component', + ]; + private SpanData $span; /** @readonly */ @@ -180,6 +189,11 @@ public static function startSpan( $isRemapped ); + // operation.name wins over the default operation name set by the constructor + if (isset($attributes['operation.name'])) { + self::_setAttribute($span, 'operation.name', $attributes['operation.name']); + } + ObjectKVStore::put($span, 'otel_span', $OTelSpan); // Call onStart here to ensure the span is fully initialized. @@ -233,7 +247,7 @@ public function toSpanData(): SpanDataInterface $this->getName(), $this->links, $this->events, - Attributes::create(array_merge($this->span->meta, $this->span->metrics)), + Attributes::create($this->getAttributes()), $this->totalRecordedEvents, $this->totalRecordedLinks, StatusData::create($this->status->getCode(), $this->status->getDescription()), @@ -246,7 +260,7 @@ public function toSpanData(): SpanDataInterface $this->getName(), $this->links, $this->events, - Attributes::create(array_merge($this->span->meta, $this->span->metrics)), + Attributes::create($this->getAttributes()), $this->totalRecordedEvents, StatusData::create($this->status->getCode(), $this->status->getDescription()), $hasEnded ? $this->span->getStartTime() + $this->span->getDuration() : 0, @@ -276,7 +290,33 @@ public function getKind(): int */ public function getAttribute(string $key): mixed { - return $this->span->attributes[$key] ?? null; + return $this->propertyAttribute($key) ?? $this->span->attributes[$key] ?? null; + } + + /** $attributes overlaid with the attributes stored on span properties by _setAttribute. */ + private function getAttributes(): array + { + $attributes = $this->span->attributes; + foreach ([...\array_keys(self::PROPERTY_ATTRIBUTES), Tag::SPAN_KIND] as $key) { + if (($value = $this->propertyAttribute($key)) !== null) { + $attributes[$key] = $value; + } + } + return $attributes; + } + + /** The attribute _setAttribute stored on a span property, or null. */ + private function propertyAttribute(string $key): ?string + { + if ($key === Tag::SPAN_KIND) { + return SpanKindNames::NAMES[$this->span->spanKind] ?? null; + } + if (!isset(self::PROPERTY_ATTRIBUTES[$key])) { + return null; + } + $value = $this->span->{self::PROPERTY_ATTRIBUTES[$key]} ?? ''; + // Only component is a tag on every span; the other properties show when set through setAttribute. + return $value !== '' && ($key === Tag::COMPONENT || ObjectKVStore::get($this->span, $key)) ? $value : null; } public function getStartEpochNanos(): int @@ -306,11 +346,32 @@ private static function _setAttribute(SpanData $span, string $key, $value): void { if ($value === null) { unset($span->attributes[$key]); + if ($key === Tag::COMPONENT) { + $span->component = ''; + } elseif (isset(self::PROPERTY_ATTRIBUTES[$key])) { + ObjectKVStore::put($span, $key, false); + } elseif ($key === Tag::SPAN_KIND) { + $span->spanKind = \DDTrace\SpanKind::UNSPECIFIED; + } } elseif ($key[0] === '_' && \strncmp($key, '_dd.p.', 6) === 0) { $distributedKey = \substr($key, 6); // strlen('_dd.p.') === 6 \DDTrace\add_distributed_tag($distributedKey, $value); } elseif ($key === 'service.name') { $span->service = $value; + } elseif (isset(self::PROPERTY_ATTRIBUTES[$key]) && \is_scalar($value)) { + $value = (string)$value; + $span->{self::PROPERTY_ATTRIBUTES[$key]} = $key === 'operation.name' ? \strtolower($value) : $value; + ObjectKVStore::put($span, $key, true); + } elseif ($key === Tag::SPAN_KIND && ($kind = \array_search($value, SpanKindNames::NAMES, true)) !== false) { + $span->spanKind = $kind; + } elseif ($key === 'http.response.status_code' && !\is_string($value)) { + // OTel's numeric status code becomes the (string) http.status_code and wins over it in any order + $span->attributes[Tag::HTTP_STATUS_CODE] = (string)$value; + ObjectKVStore::put($span, 'http.response.status_code', true); + } elseif ($key === Tag::HTTP_STATUS_CODE) { + if (!ObjectKVStore::get($span, 'http.response.status_code')) { + $span->attributes[Tag::HTTP_STATUS_CODE] = (string)$value; + } } else { $span->attributes[$key] = $value; } @@ -536,7 +597,7 @@ private function updateSpanLinks() private function updateSpanEvents() { $datadogSpanEvents = $this->span->events; - $this->span->meta["events"] = count($this->events); + $this->span->attributes["events"] = count($this->events); $otel = []; foreach ($datadogSpanEvents as $datadogSpanEvent) { diff --git a/src/DDTrace/ScopeManager.php b/src/DDTrace/ScopeManager.php index bfbbcb63c14..605f0b1abae 100644 --- a/src/DDTrace/ScopeManager.php +++ b/src/DDTrace/ScopeManager.php @@ -5,6 +5,7 @@ use DDTrace\Contracts\Scope as ScopeInterface; use DDTrace\Contracts\ScopeManager as ScopeManagerInterface; use DDTrace\Contracts\Span as SpanInterface; +use DDTrace\Util\BaseConverter; use DDTrace\Util\ObjectKVStore; final class ScopeManager implements ScopeManagerInterface @@ -125,7 +126,7 @@ private function reconcileInternalAndUserland() if (empty($this->scopes)) { if ($internalRootSpan = root_span()) { - $traceId = trace_id(); + $traceId = BaseConverter::convert($internalRootSpan->traceId, 16, 10); if ($this->rootContext) { $parentId = $this->rootContext->spanId; } else { @@ -142,7 +143,8 @@ private function reconcileInternalAndUserland() $currentSpanId = $topScope->getSpan()->getSpanId(); $newScopes = []; for ($span = active_span(); $span && ($span->id != $currentSpanId); $span = $span->parent) { - $scope = new Scope($this, new Span($span, new SpanContext(trace_id(), $span->id, $span->parent ? $span->parent->id : null)), true); + $traceId = $traceId ?? BaseConverter::convert(root_span()->traceId, 16, 10); + $scope = new Scope($this, new Span($span, new SpanContext($traceId, $span->id, $span->parent ? $span->parent->id : null)), true); $newScopes[] = $scope; } foreach (array_reverse($newScopes) as $scope) { diff --git a/src/DDTrace/Span.php b/src/DDTrace/Span.php index a928f23e0bc..cc274d2a1bb 100644 --- a/src/DDTrace/Span.php +++ b/src/DDTrace/Span.php @@ -7,7 +7,6 @@ use DDTrace\Log\LoggingTrait; use DDTrace\SpanContext as SpanContext; use DDTrace\Http\Urls; -use DDTrace\Processing\TraceAnalyticsProcessor; use Exception; use InvalidArgumentException; use Throwable; @@ -146,7 +145,7 @@ public function setTag($key, $value, $setIfFinished = false) } if ($key === Tag::ERROR_MSG) { - $this->internalSpan->attributes[$key] = (string)$value; + $this->internalSpan->attributes[$key] = $value; $this->setError(true); return; } @@ -176,7 +175,7 @@ public function setTag($key, $value, $setIfFinished = false) return; } - if ($key === Tag::HTTP_URL) { + if ($key === Tag::HTTP_URL && $value !== null) { $value = Urls::sanitize((string)$value); } @@ -198,7 +197,11 @@ public function setTag($key, $value, $setIfFinished = false) } } - $this->internalSpan->attributes[$key] = (string)$value; + if ($value === null) { + unset($this->internalSpan->meta[$key]); + return; + } + $this->internalSpan->meta[$key] = $value; } /** @@ -240,12 +243,14 @@ public function hasTag($name) public function setMetric($key, $value) { if ($key === Tag::ANALYTICS_KEY) { - TraceAnalyticsProcessor::normalizeAnalyticsValue($this->internalSpan->metrics, $value); - return; + return; // App Analytics is deprecated and a no-op } - // As a double, which is what the metrics bucket held on the wire. - $this->internalSpan->attributes[$key] = is_array($value) ? $value : (float)$value; + if ($value === null) { + unset($this->internalSpan->metrics[$key]); + return; + } + $this->internalSpan->metrics[$key] = $value; } /** @@ -378,7 +383,7 @@ public function log(array $fields = [], $timestamp = null) // messages, and logging multiple messages is not prohibited by the OpenTracing spec: // https://opentracing.io/docs/overview/tags-logs-baggage/#logs // We want to deprecate this behavior and change it. In the meantime we apply this workaround. - $this->internalSpan->attributes[Tag::ERROR_MSG] = (string)$value; + $this->internalSpan->attributes[Tag::ERROR_MSG] = $value; } elseif ($key === Tag::LOG_STACK) { $this->setTag(Tag::ERROR_STACK, $value); } diff --git a/src/DDTrace/Tracer.php b/src/DDTrace/Tracer.php index 63cc4be519b..0de79b7d25d 100644 --- a/src/DDTrace/Tracer.php +++ b/src/DDTrace/Tracer.php @@ -12,6 +12,7 @@ use DDTrace\Transport\Internal; use DDTrace\Transport\Noop; use DDTrace\Transport\Noop as NoopTransport; +use DDTrace\Util\BaseConverter; use DDTrace\Util\ObjectKVStore; final class Tracer implements TracerInterface @@ -94,12 +95,23 @@ public function __construct($transport = null, $propagators = null, array $confi $this->serviceVersion = \dd_trace_env_config("DD_VERSION"); $this->environment = \dd_trace_env_config("DD_ENV"); - $context = current_context(); - if (isset($context["distributed_tracing_parent_id"])) { - $parentId = $context["distributed_tracing_parent_id"]; - $this->rootContext = new SpanContext($context["trace_id"], $parentId, null, [], true); - if (isset($context["distributed_tracing_origin"])) { - $this->rootContext->origin = $context["distributed_tracing_origin"]; + $activeStack = active_stack(); + if ($activeStack && $activeStack->active && ($rootSpan = root_span())) { + $traceId = $rootSpan->traceId; + $parentId = isset($rootSpan->parentId) && $rootSpan->parentId !== "" ? $rootSpan->parentId : null; + $origin = isset($rootSpan->origin) && $rootSpan->origin !== "" ? $rootSpan->origin : null; + } else { + // Without an active span, the distributed context is only readable through the propagation headers + $headers = generate_distributed_tracing_headers(["datadog", "tracecontext"]); + $traceId = isset($headers["traceparent"]) ? substr($headers["traceparent"], 3, 32) : null; + $parentId = $headers["x-datadog-parent-id"] ?? null; + $origin = $headers["x-datadog-origin"] ?? null; + } + if ($traceId !== null && $parentId !== null) { + $traceId = BaseConverter::convert($traceId, 16, 10); + $this->rootContext = new SpanContext($traceId, $parentId, null, [], true); + if ($origin !== null) { + $this->rootContext->origin = $origin; } } @@ -116,7 +128,7 @@ public function limited() */ public function reset() { - if ($this->config['enabled'] && \ddtrace_config_trace_enabled()) { + if ($this->config['enabled'] && \dd_trace_env_config('DD_TRACE_ENABLED')) { // Do a full shutdown and re-startup of the tracer, which implies clearing the internal span stack ini_set("datadog.trace.enabled", 0); ini_set("datadog.trace.enabled", 1); @@ -145,7 +157,7 @@ public static function noop() */ public function startSpan($operationName, $options = []) { - if (!$this->config['enabled'] || !\ddtrace_config_trace_enabled()) { + if (!$this->config['enabled'] || !\dd_trace_env_config('DD_TRACE_ENABLED')) { return NoopSpan::create(); } @@ -171,12 +183,6 @@ public function startSpan($operationName, $options = []) $internalSpan->name = (string) $operationName; $internalSpan->service = $service; $internalSpan->resource = $resource; - if (!isset($internalSpan->metrics)) { - $internalSpan->metrics = []; - } - if (!isset($internalSpan->meta)) { - $internalSpan->meta = []; - } $span = new Span($internalSpan, $context); foreach ($options->getTags() as $key => $val) { @@ -329,8 +335,7 @@ public function getActiveSpan() */ public function getTracesAsArray() { - $trace = \dd_trace_serialize_closed_spans(); - return $trace ? [$trace] : $trace; + return \dd_trace_serialize_closed_spans()['chunks']; } public function addUrlAsResourceNameToSpan(Contracts\Span $span) diff --git a/src/DDTrace/Util/BaseConverter.php b/src/DDTrace/Util/BaseConverter.php new file mode 100644 index 00000000000..145834ba670 --- /dev/null +++ b/src/DDTrace/Util/BaseConverter.php @@ -0,0 +1,39 @@ += $toBase) { + $number[$newLen++] = (int)($divide / $toBase); + $divide = $divide % $toBase; + } elseif ($newLen > 0) { + $number[$newLen++] = 0; + } + } + $length = $newLen; + $result = $toString[$divide] . $result; + } while ($newLen != 0); + + return $result; + } +} diff --git a/src/DDTrace/Util/SpanKindNames.php b/src/DDTrace/Util/SpanKindNames.php new file mode 100644 index 00000000000..d6ee1def586 --- /dev/null +++ b/src/DDTrace/Util/SpanKindNames.php @@ -0,0 +1,18 @@ + Tag::SPAN_KIND_VALUE_INTERNAL, + SpanKind::SERVER => Tag::SPAN_KIND_VALUE_SERVER, + SpanKind::CLIENT => Tag::SPAN_KIND_VALUE_CLIENT, + SpanKind::PRODUCER => Tag::SPAN_KIND_VALUE_PRODUCER, + SpanKind::CONSUMER => Tag::SPAN_KIND_VALUE_CONSUMER, + ]; +} diff --git a/src/api/FeatureFlags/SpanEnrichmentAccumulator.php b/src/api/FeatureFlags/SpanEnrichmentAccumulator.php index 7bfa9c5c41b..0712df1a033 100644 --- a/src/api/FeatureFlags/SpanEnrichmentAccumulator.php +++ b/src/api/FeatureFlags/SpanEnrichmentAccumulator.php @@ -14,7 +14,7 @@ * * Lifecycle: one instance per root span. SpanEnrichmentRegistry::record() * lazily attaches it to the root span (via ObjectKVStore) on first evaluation - * and encodes its state onto the root span's meta; it is released with the span. + * and encodes its state onto the root span's attributes; it is released with the span. */ final class SpanEnrichmentAccumulator { diff --git a/src/api/FeatureFlags/SpanEnrichmentRegistry.php b/src/api/FeatureFlags/SpanEnrichmentRegistry.php index 4194d9243e7..64ebaeb001c 100644 --- a/src/api/FeatureFlags/SpanEnrichmentRegistry.php +++ b/src/api/FeatureFlags/SpanEnrichmentRegistry.php @@ -17,7 +17,7 @@ * accumulator, concurrently-open roots each keep their own, and everything is * released with the span -- no manual root-id tracking or reset lifecycle. * - * The encoded ffe_* tags are written directly onto the root span's meta (the + * The encoded ffe_* tags are written directly onto the root span's attributes (the * same mechanism the rest of the tracer uses to set tags); there is no native * staging layer. * @@ -50,7 +50,7 @@ public static function gateEnabled() /** * Record one evaluation's enrichment onto the current root span, then write - * the encoded ffe_* tags onto the root's meta. No-op when the gate is off or + * the encoded ffe_* tags onto the root's attributes. No-op when the gate is off or * there is no active root span. Never throws into flag evaluation. * * Mirrors the frozen Node reference branch: a present serial id is recorded @@ -100,10 +100,10 @@ public static function record($flagKey, $details, $targetingKey) // Only re-encode + rewrite the tags when this evaluation actually // changed the accumulated state; a repeated/duplicate evaluation adds - // nothing new and the meta already holds the current union. + // nothing new and the attributes already hold the current union. if ($accumulator->consumeDirty()) { foreach ($accumulator->toSpanTags() as $key => $value) { - $root->meta[$key] = $value; + $root->attributes[$key] = $value; } } } catch (\Throwable $e) { diff --git a/src/api/GlobalTracer.php b/src/api/GlobalTracer.php index 339535b453e..d0539e792da 100644 --- a/src/api/GlobalTracer.php +++ b/src/api/GlobalTracer.php @@ -9,8 +9,8 @@ use DDTrace\Contracts\Tracer as TracerInterface; -/* - * @deprecated This class is deprecated, you should use the Otel or the extension API instead. +/** + * @deprecated This class is deprecated, you should use the OpenTelemetry or the extension API instead. */ final class GlobalTracer { diff --git a/src/ddtrace_php_api.stubs.php b/src/ddtrace_php_api.stubs.php index 16c79106d15..512825f1eeb 100644 --- a/src/ddtrace_php_api.stubs.php +++ b/src/ddtrace_php_api.stubs.php @@ -1677,6 +1677,9 @@ class Format */ const HTTP_HEADERS = 'http_headers'; } + /** + * @deprecated This class is deprecated, you should use the OpenTelemetry or the extension API instead. + */ final class GlobalTracer { /** diff --git a/tests/Common/CLITestCase.php b/tests/Common/CLITestCase.php index a48bcdfaddf..f17ddf9fac7 100644 --- a/tests/Common/CLITestCase.php +++ b/tests/Common/CLITestCase.php @@ -75,14 +75,7 @@ public function getTracesFromCommand($arguments = '', $overrideEnvs = []) public function getAgentRequestFromCommand($arguments = '', $overrideEnvs = []) { $this->executeCommand($arguments, $overrideEnvs); - // retrieveDumpedTraceData()'s v0.4/v0.7-only filter misses a v1-sidecar trace - // (/v1.0/traces) and falls through to this runner's own command_execution span. - $isTraceRequest = function ($request) { - $uri = $request['uri'] ?? ''; - return strpos($uri, '/v0.4/traces') === 0 - || strpos($uri, '/v0.7/traces') === 0 - || strpos($uri, '/v1.0/traces') === 0; - }; + $isTraceRequest = $this->untilFirstTraceRequest(); foreach ($this->retrieveDumpedData($isTraceRequest) as $request) { if ($isTraceRequest($request)) { return $request; @@ -117,10 +110,6 @@ public function loadTraces($request) if (!isset($request['body'])) { return []; } - $traces = json_decode($request['body'], true); - if (isset($traces['chunks'])) { - $traces = array_map(function($chunk) { return $chunk["spans"]; }, $traces["chunks"]); - } - return $traces; + return $this->parseRawDumpedTraces(json_decode($request['body'], true)); } } diff --git a/tests/Common/SnapshotTestTrait.php b/tests/Common/SnapshotTestTrait.php index e39be05fc2b..1e7621633d7 100644 --- a/tests/Common/SnapshotTestTrait.php +++ b/tests/Common/SnapshotTestTrait.php @@ -85,12 +85,13 @@ private function startSnapshotSession(string $token, $logsFile = null) * * @param string $token The token associated with the snapshotting session * @param int $numExpectedTraces The number of traces to wait for. Defaults to 0 (won't check for traces) - * @return void + * @param callable|null $filter If given, only the traces it accepts are counted + * @return array The traces counted, with ids above PHP_INT_MAX as strings */ - private function waitForTraces(string $token, int $numExpectedTraces = 0) + private function waitForTraces(string $token, int $numExpectedTraces = 0, $filter = null) { if ($numExpectedTraces === 0) { - return; + return []; } $tracesUrl = self::$testAgentUrl . '/test/session/traces?test_session_token=' . $token; @@ -99,9 +100,12 @@ private function waitForTraces(string $token, int $numExpectedTraces = 0) $ch = curl_init($tracesUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); - $traces = json_decode($response, true); + $traces = json_decode($response, true, 512, JSON_BIGINT_AS_STRING); + if ($traces && $filter) { + $traces = array_values(array_filter($traces, $filter)); + } if ($traces && count($traces) === $numExpectedTraces) { - return; + return $traces; } usleep(100000); // 100ms } catch (\Exception $e) { @@ -142,6 +146,13 @@ private function stopAndCompareSnapshotSession( if (!in_array('meta._dd.sdk.otlp_export', $fieldsToIgnore, true)) { $fieldsToIgnore[] = 'meta._dd.sdk.otlp_export'; } + // The test agent doesn't rebuild _dd.p.dm from a V1 chunk's sampling_mechanism 0, and copies the chunk + // priority onto every span (APMAPI-1545) + foreach (['meta._dd.p.dm', 'metrics._sampling_priority_v1'] as $v1Field) { + if (!in_array($v1Field, $fieldsToIgnore, true)) { + $fieldsToIgnore[] = $v1Field; + } + } $url = self::$testAgentUrl . '/test/session/snapshot?ignores=' . implode(',', $fieldsToIgnore) . '&test_session_token=' . $token; @@ -357,10 +368,7 @@ public function isolateTracerSnapshot( \DDTrace\dogstatsd_count("tracer-snapshot-end." . $token, 1); } - $traces = $this->flushAndGetTraces($tracer); - if (!empty($traces)) { - $this->sendTracesToTestAgent($traces); - } + $this->flushAndSendTracesToTestAgent(); $this->stopAndCompareSnapshotSession( $token, @@ -378,47 +386,73 @@ public function isolateTracerSnapshot( self::putEnv('DD_CODE_ORIGIN_MAX_USER_FRAMES'); } + /** + * Snapshots the traces the tracer sends while $fn runs; $fn returns them as parsed from the replayer. + * With $filter, only the traces it accepts are snapshotted: they are read back from the test agent + * and re-posted to the snapshot session. Long-running servers need a $filter. + * + * @return array The traces returned by $fn, filtered + */ public function snapshotFromTraces( - $traces, - $fieldsToIgnore = ['metrics.php.compilation.total_time_ms', 'metrics.php.memory.peak_usage_bytes', 'metrics.php.memory.peak_real_usage_bytes', 'meta.error.stack', 'meta._dd.p.tid'], + callable $fn, + $fieldsToIgnore = null, $tokenSubstitute = null, - $ignoreSampledAway = false + $filter = null ) { + $fieldsToIgnore = $fieldsToIgnore ?? ['metrics.php.compilation.total_time_ms', 'metrics.php.memory.peak_usage_bytes', 'metrics.php.memory.peak_real_usage_bytes', 'meta.error.stack', 'meta._dd.p.tid']; $token = $tokenSubstitute ?: $this->generateToken(); - $this->startSnapshotSession($token); $originalToken = ini_get("datadog.trace.agent_test_session_token"); - update_test_agent_session_token($token); - - if ($ignoreSampledAway) { - $traces = $this->ignoreSampledTraces($traces); + // Long-running servers keep the token they were started with, so filtered runs stay on it. + $runToken = $filter ? $originalToken : $token; + $this->startSnapshotSession($runToken); + update_test_agent_session_token($runToken); + + $traces = $fn(); + + if ($filter) { + $traces = array_values(array_filter($traces, $filter)); + $traceIds = array_map([SpanChecker::class, 'traceIdLow'], $traces); + $agentTraces = $this->waitForTraces($runToken, \count($traceIds), function ($trace) use ($traceIds) { + return isset($trace[0]['trace_id']) && \in_array((string)$trace[0]['trace_id'], $traceIds, true); + }); + $this->startSnapshotSession($token); + $this->postTracesToTestAgent($token, $agentTraces); } - $this->sendTracesToTestAgent($traces); - $this->stopAndCompareSnapshotSession($token, $fieldsToIgnore, \count($traces)); update_test_agent_session_token($originalToken); + + return $traces; } - protected function ignoreSampledTraces($traces) { - $filteredSpans = []; - $sampledTraceIDs = []; - foreach ($traces as $trace) { - foreach ($trace as $span) { - list(, $metrics) = SpanChecker::extractMetaMetrics($span); - if (isset($metrics['_sampling_priority_v1']) && (int) $metrics['_sampling_priority_v1'] === 0) { - $sampledTraceIDs[$span['trace_id']] = true; - } - } - } + protected function isNotSampledAway($chunk) + { + return ($chunk['priority'] ?? null) !== 0; + } - foreach ($traces as $trace) { - foreach ($trace as $span) { - if (!isset($sampledTraceIDs[$span['trace_id']])) { - $filteredSpans[] = $span; - } - } + private function postTracesToTestAgent(string $token, array $traces) + { + // Ids above PHP_INT_MAX were decoded as strings; the test agent wants them as numbers. + $json = preg_replace('/"(trace_id|span_id|parent_id)":"(\d+)"/', '"$1":$2', json_encode($traces)); + $headers = [ + 'Content-Type: application/json', + 'Datadog-Meta-Lang: php', + 'X-Datadog-Agent-Proxy-Disabled: true', + 'X-Datadog-Trace-Count: ' . \count($traces), + 'X-Datadog-Test-Session-Token: ' . $token, + ]; + $envHeader = getHeaderWithEnvironment(); + if ($envHeader) { + $headers[] = 'X-Datadog-Trace-Env-Variables: ' . $envHeader; + } + $ch = curl_init(self::$testAgentUrl . '/v0.4/traces'); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $json); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + $response = curl_exec($ch); + if (curl_getinfo($ch, CURLINFO_HTTP_CODE) !== 200) { + TestCase::fail('Error re-posting traces to the test agent: ' . $response); } - - return [$filteredSpans]; } } diff --git a/tests/Common/SpanAssertion.php b/tests/Common/SpanAssertion.php index 5ce86aee349..c5649853626 100644 --- a/tests/Common/SpanAssertion.php +++ b/tests/Common/SpanAssertion.php @@ -12,14 +12,16 @@ final class SpanAssertion private $operationName; private $hasError; - /** @var string[] Tags the MUST match in both key and value */ - private $exactTags = SpanAssertion::NOT_TESTED; - /** @var string[] Tags the MUST be present but with any value */ - private $existingTags = ['process_id']; - /** @var string[] Ignore any tags that match these regexp patterns */ - private $skipTagPatterns = []; - /** @var array Exact metrics set on the span */ - private $exactMetrics = SpanAssertion::NOT_TESTED; + /** @var array Attributes that MUST match in both key and (typed) value */ + private $exactAttributes = SpanAssertion::NOT_TESTED; + /** @var string[] Attributes that MUST be present but with any value */ + private $existingAttributes = ['process_id']; + /** @var string[] Ignore any attributes that match these regexp patterns */ + private $skipAttributePatterns = []; + /** @var array Fields of the span's chunk (priority, sampling_mechanism, origin) */ + private $chunkFields = []; + /** @var bool Whether the span MUST have span links */ + private $spanLinks = false; private $service = SpanAssertion::NOT_TESTED; private $type = SpanAssertion::NOT_TESTED; private $resource = SpanAssertion::NOT_TESTED; @@ -79,10 +81,9 @@ public static function exists( * @param string $service * @param string $type * @param string $resource - * @param array $exactTags + * @param array $exactAttributes * @param null $parent * @param bool $error - * @param array|string $extactMetrics * @return SpanAssertion */ public static function build( @@ -90,17 +91,15 @@ public static function build( $service, $type, $resource, - $exactTags = [], + $exactAttributes = [], $parent = null, - $error = false, - $extactMetrics = SpanAssertion::NOT_TESTED + $error = false ) { return SpanAssertion::forOperation($name, $error) ->service($service) ->resource($resource) ->type($type) - ->withExactTags($exactTags) - ->withExactMetrics($extactMetrics) + ->withExactAttributes($exactAttributes) ; } @@ -124,24 +123,24 @@ public static function forOperation($name, $error = false, $onlyCheckExistence = public function setError($errorType = null, $errorMessage = null, $exceptionThrown = false) { $this->hasError = true; - if (!is_array($this->exactTags)) { - $this->exactTags = []; + if (!is_array($this->exactAttributes)) { + $this->exactAttributes = []; } - if (isset($this->exactTags[Tag::ERROR_TYPE])) { + if (isset($this->exactAttributes[Tag::ERROR_TYPE])) { return $this; } if (null !== $errorType) { - $this->exactTags[Tag::ERROR_TYPE] = $errorType; + $this->exactAttributes[Tag::ERROR_TYPE] = $errorType; } else { - $this->existingTags[] = Tag::ERROR_TYPE; + $this->existingAttributes[] = Tag::ERROR_TYPE; } if (null !== $errorMessage) { // commonly contains file/line info, use global format // we do not want to test the specific formatting of exceptions here - $this->exactTags[Tag::ERROR_MSG] = "%S$errorMessage%S"; + $this->exactAttributes[Tag::ERROR_MSG] = "%S$errorMessage%S"; } if ($exceptionThrown) { - $this->existingTags[] = Tag::ERROR_STACK; + $this->existingAttributes[] = Tag::ERROR_STACK; } return $this; } @@ -163,69 +162,117 @@ public function withChildren($children) } /** - * Mark all provided tags as mandatory. If multiple arrays are provided, they will be merged with the right-most - * ones taking precedence over the lest-most ones. + * The span's attributes (and env, version, component and span.kind) must be exactly these, compared + * with their type; string values are formats (see assertStringMatchesFormat). If multiple arrays are + * provided, they will be merged with the right-most ones taking precedence over the left-most ones. * - * @param array|string[]... $tags + * @param array... $attributes * @return $this */ - public function withExactTags(...$tags) + public function withExactAttributes(...$attributes) { - if ($tags[0] === self::NOT_TESTED) { - $this->exactTags = self::NOT_TESTED; + if ($attributes[0] === self::NOT_TESTED) { + $this->exactAttributes = self::NOT_TESTED; return $this; } - foreach ($tags as $tag) { - if (!is_array($tag)) { + foreach ($attributes as $attribute) { + if (!is_array($attribute)) { throw new Exception( - 'All arguments provided to ::withExactTags MUST be arrays: ' . \var_export($tag, true) + 'All arguments provided to ::withExactAttributes MUST be arrays: ' . \var_export($attribute, true) ); } } - $this->exactTags = array_merge( - \is_array($this->exactTags) ? $this->exactTags : [], - ...$tags + $this->exactAttributes = array_merge( + \is_array($this->exactAttributes) ? $this->exactAttributes : [], + ...$attributes ); return $this; } /** - * @param array|string $metrics + * @param array $names + * @param bool $merge If true, the provided names are merged with the default ones * @return $this */ - public function withExactMetrics($metrics) + public function withExistingAttributeNames(array $names, $merge = true) { - $this->exactMetrics = $metrics; + $this->existingAttributes = $merge ? array_merge($names, $this->existingAttributes) : $names; return $this; } /** - * @param array $tagNames - * @param bool $merge If true, the provided tags are nmerged with the default ones + * @param string $pattern regular expression * @return $this */ - public function withExistingTagsNames(array $tagNames, $merge = true) + public function skipAttributesLike($pattern) { - $this->existingTags = $merge ? array_merge($tagNames, $this->existingTags) : $tagNames; + $this->skipAttributePatterns[] = $pattern; return $this; } + public function getSkippedAttributePatterns() + { + return $this->skipAttributePatterns; + } + /** - * @param string $pattern regular expression + * The span MUST have span links. + * * @return $this */ - public function skipTagsLike($pattern) + public function withSpanLinks() { - $this->skipTagPatterns[] = $pattern; + $this->spanLinks = true; return $this; } - public function getSkippedTagPatterns() + /** + * @return bool + */ + public function hasSpanLinks() + { + return $this->spanLinks; + } + + /** + * @param int $priority The chunk's sampling priority + * @return $this + */ + public function samplingPriority($priority) { - return $this->skipTagPatterns; + $this->chunkFields['priority'] = $priority; + return $this; + } + + /** + * @param int $mechanism The chunk's sampling mechanism (the _dd.p.dm decision maker) + * @return $this + */ + public function samplingMechanism($mechanism) + { + $this->chunkFields['sampling_mechanism'] = $mechanism; + return $this; + } + + /** + * @param string $origin The chunk's origin + * @return $this + */ + public function origin($origin) + { + $this->chunkFields['origin'] = $origin; + return $this; + } + + /** + * @return array + */ + public function getExactChunkFields() + { + return $this->chunkFields; } /** @@ -283,25 +330,25 @@ public function hasError() } /** - * @return string[] + * @return array|string */ - public function getExactTags() + public function getExactAttributes() { - return $this->exactTags; + return $this->exactAttributes; } /** * @param bool $isChildSpan * @return string[] */ - public function getExistingTagNames($isChildSpan = false) + public function getExistingAttributeNames($isChildSpan = false) { if ($isChildSpan) { - return array_filter($this->existingTags, function ($name) { + return array_filter($this->existingAttributes, function ($name) { return $name !== 'process_id'; }); } - return $this->existingTags; + return $this->existingAttributes; } /** @@ -344,14 +391,6 @@ public function isOnlyCheckExistence() return $this->onlyCheckExistence; } - /** - * @return array - */ - public function getExactMetrics() - { - return $this->exactMetrics; - } - /** * @return bool */ diff --git a/tests/Common/SpanAssertionTrait.php b/tests/Common/SpanAssertionTrait.php index 489b22df13d..130f3b6d702 100644 --- a/tests/Common/SpanAssertionTrait.php +++ b/tests/Common/SpanAssertionTrait.php @@ -63,29 +63,28 @@ public function assertOneExpectedSpan($traces, SpanAssertion $expectedSpan) */ public function assertError(array $span, $message, array $expectedStackLinesGroups) { - $this->assertSame(1, $span['error']); + $this->assertTrue($span['error']); - // Normalize the V1 introspection shape (attributes) and the flat v0.4 wire to a meta view. - list($meta,) = SpanChecker::extractMetaMetrics($span); + $attributes = SpanChecker::attributeView($span); // message assertion supports '*' wildcard but DOES NOT enforce order. $messagePartsByWildcard = \explode('*', $message); foreach ($messagePartsByWildcard as $messagePart) { $this->assertNotSame( false, - \strpos($meta[Tag::ERROR_MSG], $messagePart), - \sprintf('Message "%s" does not contain "%s"', $meta[Tag::ERROR_MSG], $message) + \strpos($attributes[Tag::ERROR_MSG], $messagePart), + \sprintf('Message "%s" does not contain "%s"', $attributes[Tag::ERROR_MSG], $message) ); } - $stackGroups = \explode('stack groups separator', $meta['error.stack']); + $stackGroups = \explode('stack groups separator', $attributes['error.stack']); if (count($stackGroups) !== count($expectedStackLinesGroups)) { $this->fail( \sprintf( 'Found %d stack groups, expected %d: %s', count($stackGroups), count($expectedStackLinesGroups), - $meta['error.stack'] + $attributes['error.stack'] ) ); } diff --git a/tests/Common/SpanChecker.php b/tests/Common/SpanChecker.php index 0e2ea51e46b..ca86fdef940 100644 --- a/tests/Common/SpanChecker.php +++ b/tests/Common/SpanChecker.php @@ -2,7 +2,8 @@ namespace DDTrace\Tests\Common; -use DDTrace\Tag; +use DDTrace\Util\BaseConverter; +use DDTrace\Util\SpanKindNames; use PHPUnit\Framework\TestCase; function array_filter_by_key($fn, array $input) @@ -21,6 +22,9 @@ function array_filter_by_key($fn, array $input) */ final class SpanChecker { + /** @var array The chunk fields of each flattened span's chunk, by span id */ + private $chunkFields = []; + /** * Asserts a flame graph with parent child relations. * @@ -63,162 +67,100 @@ public static function dumpTracesGraph(array $traces) return self::dumpSpansGraph($actualGraph); } + /** Test-side mapping: expectations name these span properties by their legacy tag key, as $span->meta does. */ + const PROPERTY_KEYS = ['env' => 'env', 'version' => 'version', 'component' => 'component', 'span.kind' => 'span_kind']; + + /** Attributes not compared unless an assertion names them: sampler and runtime bookkeeping. */ + const IGNORED_UNLESS_EXPECTED = [ + '_dd.agent_psr', '_dd.rule_psr', '_dd.limit_psr', '_dd.p.ksr', '_dd.top_level', '_top_level', + 'runtime-id', 'http.client_ip', 'php.compilation.total_time_ms', + 'php.memory.peak_usage_bytes', 'php.memory.peak_real_usage_bytes', + // Builds bundling AppSec report the WAF version while awaiting remote activation + '_dd.appsec.waf.version', + ]; + /** - * Derives the legacy flat `meta` (string tags) and `metrics` (numeric tags) views from a span. - * - * The V1 introspection shape (`dd_trace_serialize_closed_spans()`) merges the old string `meta` - * and numeric `metrics` maps into a single typed `attributes` map, and promotes some keys to - * top-level span fields. The v0.4 agent wire (parsed from the request replayer) keeps the old - * flat `meta`/`metrics`. Tests assert against the legacy model, so normalize both shapes to it. - * - * Reconstruction is the exact inverse of the reshape, so the derived `meta`/`metrics` match what - * master's introspection returned for the same span. - * - * @return array{0: array, 1: array} `[$meta, $metrics]` + * The typed attributes of a span, plus the span properties that the legacy tag API exposes under + * a tag name (env, version, component and span.kind), so assertions can name them as attributes. + * With $strict, a property key written as a raw attribute fails; a non-canonical span.kind has no + * property, so it stays a valid attribute. */ - public static function extractMetaMetrics(array $span) + public static function attributeView(array $span, $strict = true) { - // Old flat shape (v0.4 wire): already split into meta/metrics. - if (\array_key_exists('meta', $span) || \array_key_exists('metrics', $span)) { - return [ - isset($span['meta']) ? $span['meta'] : [], - isset($span['metrics']) ? $span['metrics'] : [], - ]; - } - - // New V1 introspection shape: split attributes back by type and restore promoted keys. - $meta = []; - $metrics = []; - foreach (isset($span['attributes']) ? $span['attributes'] : [] as $key => $value) { - if (\is_int($value) || \is_float($value)) { - $metrics[$key] = $value; - } else { - // Strings and nested array/map attributes belong to the meta view. - $meta[$key] = $value; + $attributes = isset($span['attributes']) ? $span['attributes'] : []; + foreach (self::PROPERTY_KEYS as $key => $field) { + if ($strict && \array_key_exists($key, $attributes) + && ($field !== 'span_kind' || \in_array($attributes[$key], SpanKindNames::NAMES, true))) { + TestCase::fail(\sprintf( + "'%s' must be set through the span property, not as a raw attribute: %s", + $key, + print_r($span, true) + )); } - } - // Promoted string keys move back into meta under their original tag names. - if (isset($span['env'])) { - $meta['env'] = $span['env']; - } - if (isset($span['version'])) { - $meta['version'] = $span['version']; - } - if (isset($span['component'])) { - $meta['component'] = $span['component']; - } - // span_kind is an int enum, ALWAYS present; 1 (Internal) is the default and was not emitted - // as a `span.kind` meta tag in the old shape, so only restore the explicit kinds (2-5). - if (isset($span['span_kind'])) { - $kinds = [2 => 'server', 3 => 'client', 4 => 'producer', 5 => 'consumer']; - if (isset($kinds[$span['span_kind']])) { - $meta['span.kind'] = $kinds[$span['span_kind']]; + $value = isset($span[$field]) ? $span[$field] : ''; + if ($field === 'span_kind') { + $value = isset(SpanKindNames::NAMES[$value]) ? SpanKindNames::NAMES[$value] : ''; + } + if ($value !== '') { + $attributes[$key] = $value; } } - // Chunk-level keys: introspection only emits these on the chunk's local root (as the wire). - if (isset($span['origin'])) { - $meta['_dd.origin'] = $span['origin']; - } - if (isset($span['trace_id_high'])) { - $meta['_dd.p.tid'] = $span['trace_id_high']; - } - // sampling_mechanism is the unsigned _dd.p.dm value (sign is always '-'). - if (isset($span['sampling_mechanism'])) { - $meta['_dd.p.dm'] = '-' . $span['sampling_mechanism']; - } - // sampling_priority (int) was the numeric _sampling_priority_v1 metric. - if (isset($span['sampling_priority'])) { - $metrics['_sampling_priority_v1'] = (float) $span['sampling_priority']; - } - return [$meta, $metrics]; + return $attributes; } /** - * Converts a V1 introspection span into the flat v0.4 shape the test agent expects, so - * introspection traces (from `flushAndGetTraces()`) can be sent to the agent for snapshotting. - * Old flat spans are returned unchanged. + * Typed attributes in the v0.4 wire's form, as libdatadog's v0.4 downgrade writes them: lists and maps + * flatten into dotted keys and bools become "true"/"false". Spans from that wire compare loosely. */ - public static function spanToWireShape(array $span) + private static function toV04Attributes(array $attributes) { - if (\array_key_exists('meta', $span) || \array_key_exists('metrics', $span)) { - return $span; + $out = []; + foreach ($attributes as $key => $value) { + self::flattenV04((string)$key, $value, $out); } - list($meta, $metrics) = self::extractMetaMetrics($span); - unset( - $span['attributes'], - $span['span_kind'], - $span['env'], - $span['version'], - $span['component'], - $span['origin'], - $span['trace_id_high'], - $span['sampling_priority'], - $span['sampling_mechanism'] - ); - if ($meta) { - $span['meta'] = $meta; - } - if ($metrics) { - $span['metrics'] = $metrics; + return $out; + } + + private static function flattenV04($key, $value, array &$out) + { + if (\is_array($value)) { + foreach ($value as $member => $item) { + self::flattenV04("$key.$member", $item, $out); + } + } else { + $out[$key] = \is_bool($value) ? ($value ? 'true' : 'false') : $value; } - return $span; } /** - * Moves native `span_links` (v0.4 downgrade wire, or V1 introspection) into the legacy - * `meta['_dd.span_links']` JSON string that the test agent accepts and that the stored - * snapshots were captured with. The test agent cannot decode a native `span_links` list. + * A span link's ids as hex (32-digit trace_id, 16-digit span_id) plus its trace state, from the + * v0.4 shape (decimal ids, trace_id_high). */ - public static function spanLinksToLegacyMeta(array $span) + public static function hexSpanLink(array $link) { - if (empty($span['span_links'])) { - unset($span['span_links']); - return $span; - } - $links = []; - foreach ($span['span_links'] as $link) { - $high = isset($link['trace_id_high']) ? $link['trace_id_high'] : 0; - // Introspection renders the high half as 16 hex digits, the wire as a decimal integer. - $highHex = \is_string($high) && \strlen($high) === 16 ? $high : self::decimalToHex($high, 16); - $legacy = [ - 'trace_id' => $highHex . self::decimalToHex($link['trace_id'], 16), - 'span_id' => self::decimalToHex($link['span_id'], 16), - ]; - if (!empty($link['trace_state'])) { - $legacy['trace_state'] = $link['trace_state']; - } elseif (!empty($link['tracestate'])) { - $legacy['trace_state'] = $link['tracestate']; - } - if (!empty($link['attributes'])) { - $legacy['attributes'] = $link['attributes']; + $high = isset($link['trace_id_high']) ? $link['trace_id_high'] : 0; + $hex = [ + 'trace_id' => self::decimalToHex($high, 16) . self::decimalToHex($link['trace_id'], 16), + 'span_id' => self::decimalToHex($link['span_id'], 16), + ]; + foreach (['trace_state', 'tracestate'] as $key) { + if (!empty($link[$key])) { + $hex['tracestate'] = $link[$key]; } - if (!empty($link['flags'])) { - $legacy['flags'] = $link['flags']; - } - $links[] = $legacy; } - unset($span['span_links']); - $span['meta']['_dd.span_links'] = json_encode($links); - return $span; + return $hex; + } + + /** The low 64 bits of a chunk's trace_id in decimal, as x-datadog-trace-id carries it. */ + public static function traceIdLow(array $chunk) + { + return BaseConverter::convert(substr($chunk['trace_id'], 16), 16, 10); } /** Decimal (int or numeric string, possibly above PHP_INT_MAX) to zero-padded lowercase hex. */ - private static function decimalToHex($decimal, $width) + public static function decimalToHex($decimal, $width) { - $digits = (string)$decimal; - $hex = ''; - while ($digits !== '' && $digits !== '0') { - $quotient = ''; - $carry = 0; - foreach (str_split($digits) as $d) { - $carry = $carry * 10 + (int)$d; - $quotient .= intdiv($carry, 16); - $carry %= 16; - } - $hex = dechex($carry) . $hex; - $digits = ltrim($quotient, '0'); - } - return str_pad($hex, $width, '0', STR_PAD_LEFT); + return str_pad(BaseConverter::convert((string)$decimal, 10, 16), $width, '0', STR_PAD_LEFT); } public static function dumpSpansGraph(array $spansGraph, int $indent = 0) @@ -243,20 +185,13 @@ public static function dumpSpansGraph(array $spansGraph, int $indent = 0) $out .= ' (' . implode(', ', $values) . ')'; } $out .= "\n"; - list($dumpMeta, $dumpMetrics) = self::extractMetaMetrics($span); - unset($dumpMeta['_dd.p.dm']); - unset($dumpMeta['_dd.p.tid']); - unset($dumpMeta['_dd.sdk.otlp_export']); - unset($dumpMeta['http.client_ip']); - foreach ($dumpMeta as $k => $v) { - $out .= str_repeat(' ', $indent) . ' ' . $k . ' => ' . (is_scalar($v) ? $v : json_encode($v)) . "\n"; + $dumpAttributes = self::attributeView($span, false); + foreach (['http.client_ip', 'process_id', + 'php.compilation.total_time_ms', 'php.memory.peak_usage_bytes', 'php.memory.peak_real_usage_bytes'] as $key) { + unset($dumpAttributes[$key]); } - unset($dumpMetrics['php.compilation.total_time_ms']); - unset($dumpMetrics['php.memory.peak_usage_bytes']); - unset($dumpMetrics['php.memory.peak_real_usage_bytes']); - unset($dumpMetrics['process_id']); - foreach ($dumpMetrics as $k => $v) { - $out .= str_repeat(' ', $indent) . ' ' . $k . ' => ' . (is_scalar($v) ? $v : json_encode($v)) . "\n"; + foreach ($dumpAttributes as $k => $v) { + $out .= str_repeat(' ', $indent) . ' ' . $k . ' => ' . (is_scalar($v) ? var_export($v, true) : json_encode($v)) . "\n"; } $out .= self::dumpSpansGraph($node['children'], $indent + 2); } @@ -543,19 +478,21 @@ public function assertSpan($span, SpanAssertion $exp) { TestCase::assertNotNull($span, 'Expected span was not found \'' . $exp->getOperationName() . '\'.'); - list($spanMeta, $spanMetrics) = self::extractMetaMetrics($span); + $attributes = self::attributeView($span); + // A span parsed from the v0.4 wire only carries the v0.4 form of its attributes. + $isV04 = isset($span['_wire']); $namePrefix = $exp->getOperationName() . ': '; // Checking status code here because this can be tested also when we want to check only for existence if ($exp->getStatusCode() !== SpanAssertion::NOT_TESTED) { $actualStatusCode - = isset($spanMeta['http.status_code']) ? $spanMeta['http.status_code'] : ''; + = isset($attributes['http.status_code']) ? $attributes['http.status_code'] : ''; $expectedStatusCode = strval($exp->getStatusCode()); if ($actualStatusCode !== $expectedStatusCode) { TestCase::assertSame( $exp->getStatusCode(), - isset($spanMeta['http.status_code']) ? $spanMeta['http.status_code'] : '', + $actualStatusCode, $namePrefix . "Wrong value for 'status code'. " . "Expected: $expectedStatusCode. Actual: $actualStatusCode" . print_r($span, true) @@ -578,7 +515,7 @@ public function assertSpan($span, SpanAssertion $exp) if ($exp->hasError() !== SpanAssertion::NOT_TESTED) { TestCase::assertSame( $exp->hasError(), - isset($span['error']) && 1 === $span['error'], + !empty($span['error']), $namePrefix . "Wrong value for 'error': " . print_r($span, true) ); } @@ -598,155 +535,106 @@ public function assertSpan($span, SpanAssertion $exp) . print_r($span, true) ); } + foreach ($exp->getExactChunkFields() as $field => $value) { + $chunk = isset($this->chunkFields[$span['span_id']]) ? $this->chunkFields[$span['span_id']] : []; + TestCase::assertSame( + $value, + isset($chunk[$field]) ? $chunk[$field] : null, + $namePrefix . "Wrong value for chunk field '$field' " . print_r($chunk, true) + ); + } - foreach ($exp->getExistingTagNames(true) as $key) { - if ($key === '_dd.span_links') { - // Links live in the top-level native span_links (V1 introspection / dd_trace_serialize_closed_spans) - // OR the legacy '_dd.span_links' meta tag (v0.4 wire). Accept either so both paths pass. - TestCase::assertTrue( - !empty($span['span_links']) || isset($spanMeta['_dd.span_links']), - $exp->getOperationName() . ": expected span links but neither top-level span_links nor meta['_dd.span_links'] is present" + // A list or map attribute only has dotted keys on the v0.4 wire. + $isOrUnder = function ($key, $name) { + return $key === $name || strpos($key, "$name.") === 0; + }; + $assertExisting = function ($names) use ($attributes, $isOrUnder, $namePrefix) { + foreach ($names as $name) { + TestCase::assertNotEmpty( + array_filter_by_key(function ($key) use ($name, $isOrUnder) { + return $isOrUnder($key, $name); + }, $attributes), + $namePrefix . "Expected attribute $name not found" ); - } else { - TestCase::assertArrayHasKey($key, $spanMeta); } + }; + $assertExisting($exp->getExistingAttributeNames(true)); + if ($exp->hasSpanLinks()) { + TestCase::assertNotEmpty($span['span_links'] ?? null, $namePrefix . 'Expected span links'); } if ($exp->isOnlyCheckExistence()) { return; } - if ($exp->getExactTags() !== SpanAssertion::NOT_TESTED) { - $filtered = []; - foreach ($spanMeta as $key => $value) { - if (!in_array($key, $exp->getExistingTagNames())) { - $filtered[$key] = $value; + if ($exp->getExactAttributes() !== SpanAssertion::NOT_TESTED) { + $assertExisting($exp->getExistingAttributeNames(isset($span['parent_id']))); + $expected = $isV04 ? self::toV04Attributes($exp->getExactAttributes()) : $exp->getExactAttributes(); + $filtered = array_filter_by_key(function ($key) use ($exp, $expected, $isOrUnder) { + if (\array_key_exists($key, $expected)) { + return true; + } + foreach ($exp->getExistingAttributeNames() as $name) { + if ($isOrUnder($key, $name)) { + return false; + } + } + return true; + }, $attributes); + foreach ($exp->getSkippedAttributePatterns() as $pattern) { + $filtered = array_filter_by_key(function ($key) use ($pattern) { + // keep if it *doesn't* match + return !\preg_match($pattern, $key); + }, $filtered); + } + foreach (self::IGNORED_UNLESS_EXPECTED as $key) { + if (!\array_key_exists($key, $expected)) { + unset($filtered[$key]); } } - - $skipPatterns = $exp->getSkippedTagPatterns(); - $out = $filtered; - foreach ($skipPatterns as $pattern) { - $out = array_filter_by_key( - function ($key) use ($pattern) { - // keep if it *doesn't* match - return !\preg_match($pattern, $key); - }, - $out - ); - } - - $filtered = $out; - $expectedTags = $exp->getExactTags(); - // Ignore _dd.p.dm unless explicitly tested - if (!isset($expectedTags['_dd.p.dm'])) { - unset($filtered['_dd.p.dm']); - } - // Ignore _dd.p.ksr unless explicitly tested - if (!isset($expectedTags['_dd.p.ksr'])) { - unset($filtered['_dd.p.ksr']); - } - // Ignore _dd.p.tid unless explicitly tested - if (!isset($expectedTags['_dd.p.tid'])) { - unset($filtered['_dd.p.tid']); - } - // Ignore runtime-id unless explicitly tested - if (!isset($expectedTags['runtime-id'])) { - unset($filtered['runtime-id']); - } - // Ignore _dd.sdk.otlp_export unless explicitly tested - if (!isset($expectedTags['_dd.sdk.otlp_export'])) { - unset($filtered['_dd.sdk.otlp_export']); - } - // http.client_ip is present depending on target SAPI and not helpful here to test - if (!isset($expectedTags['http.client_ip'])) { - unset($filtered['http.client_ip']); - } - // Builds bundling AppSec report the WAF version while awaiting remote activation - if (!isset($expectedTags['_dd.appsec.waf.version'])) { - unset($filtered['_dd.appsec.waf.version']); - } - if (!isset($expectedTags['_dd.code_origin.type'])) { + if (!isset($expected['_dd.code_origin.type'])) { foreach ($filtered as $key => $value) { if (strpos($key, '_dd.code_origin.') === 0) { unset($filtered[$key]); } } } - foreach ($expectedTags as $tagName => $tagValue) { + foreach ($expected as $name => $value) { TestCase::assertArrayHasKey( - $tagName, + $name, $filtered, - $namePrefix . 'Expected tag name ' . $tagName . ' not found' + $namePrefix . 'Expected attribute ' . $name . ' not found' ); - if (!isset($filtered[$tagName])) { - continue; - } - if (is_string($tagValue)) { + if (is_string($value)) { + TestCase::assertTrue( + is_string($filtered[$name]), + $namePrefix . "Expected a string for '$name', got " . var_export($filtered[$name], true) + ); TestCase::assertStringMatchesFormat( - $tagValue, - $filtered[$tagName], - $namePrefix . "Expected tag format for '$tagName' does not match actual value" + $value, + $filtered[$name], + $namePrefix . "Expected format for '$name' does not match actual value" ); - } else { - $actual = $filtered[$tagName]; + } elseif ($isV04) { TestCase::assertEquals( - $tagValue, - $actual, - $namePrefix . "Exp. value for '$tagName' does not match actual | '$tagValue' != '$actual'" + $value, + $filtered[$name], + $namePrefix . "Exp. value for '$name' does not match actual | " + . var_export($value, true) . ' != ' . var_export($filtered[$name], true) + ); + } else { + TestCase::assertSame( + $value, + $filtered[$name], + $namePrefix . "Exp. value for '$name' does not match actual | " + . var_export($value, true) . ' !== ' . var_export($filtered[$name], true) ); } - unset($filtered[$tagName]); + unset($filtered[$name]); } TestCase::assertEmpty( $filtered, - $namePrefix . "Unexpected extra values for 'tags':\n" . print_r($filtered, true) - ); - foreach ($exp->getExistingTagNames(isset($span['parent_id'])) as $tagName) { - if ($tagName === Tag::PID) { - TestCase::assertArrayHasKey($tagName, $spanMetrics); - unset($spanMetrics[Tag::PID]); - } elseif ($tagName === '_dd.span_links') { - // Links: top-level native span_links (introspection) OR legacy _dd.span_links meta (v0.4 wire). - TestCase::assertTrue( - !empty($span['span_links']) || isset($spanMeta['_dd.span_links']), - $exp->getOperationName() . ": expected span links but neither top-level span_links nor meta['_dd.span_links'] is present" - ); - } else { - TestCase::assertArrayHasKey($tagName, $spanMeta); - } - } - } - $metrics = $exp->getExactMetrics(); - if ($metrics !== SpanAssertion::NOT_TESTED) { - // Ignore compilation-time metric unless explicitly tested - if (!isset($metrics['php.compilation.total_time_ms'])) { - unset($spanMetrics['php.compilation.total_time_ms']); - } - if (!isset($metrics['php.memory.peak_usage_bytes'])) { - unset($spanMetrics['php.memory.peak_usage_bytes']); - } - if (!isset($metrics['php.memory.peak_real_usage_bytes'])) { - unset($spanMetrics['php.memory.peak_real_usage_bytes']); - } - if (isset($metrics['process_id'])) { - unset($metrics['process_id']); - } - if (isset($spanMetrics["process_id"])) { - unset($spanMetrics['process_id']); - } - if (isset($spanMetrics["_top_level"])) { - // Set by sidecar only - unset($spanMetrics['_top_level']); - } - if (!isset($metrics['_dd.top_level'])) { - // Set by the sidecar on the V1 path unless explicitly tested - unset($spanMetrics['_dd.top_level']); - } - TestCase::assertEquals( - $metrics, - $spanMetrics, - $namePrefix . "Wrong value for 'metrics' " . print_r($span, true) + $namePrefix . "Unexpected extra attributes:\n" . var_export($filtered, true) ); } if ($exp->getType() != SpanAssertion::NOT_TESTED) { @@ -782,9 +670,12 @@ public function flattenTraces($traces) $index )); } - array_walk($trace, function (array $span) use (&$result) { + $chunkFields = $trace; + unset($chunkFields['spans']); + foreach ($trace['spans'] ?? [] as $span) { + $this->chunkFields[$span['span_id']] = $chunkFields; $result[] = $span; - }); + } } return $result; diff --git a/tests/Common/TracerTestTrait.php b/tests/Common/TracerTestTrait.php index be51045449d..b43cab67fe9 100644 --- a/tests/Common/TracerTestTrait.php +++ b/tests/Common/TracerTestTrait.php @@ -10,6 +10,7 @@ use DDTrace\Tests\Frameworks\Util\Request\RequestSpec; use DDTrace\Tests\WebServer; use DDTrace\Tracer; +use DDTrace\Util\SpanKindNames; use Exception; use PHPUnit\Framework\TestCase; @@ -20,6 +21,12 @@ trait TracerTestTrait protected static $webserverPort = 6666 + GLOBAL_PORT_OFFSET; + /** @var array The payload fields (without chunks) of the trace dumps parsed since the last dumper reset */ + protected $dumpedPayload = []; + + /** Payload attributes that the v0.4 wire carries on spans instead (see libdatadog's v0.4 downgrade). */ + private static $v04PayloadAttributes = ['_dd.tags.process', '_dd.sdk.otlp_export', '_dd.git.commit.sha', '_dd.git.repository_url']; + public function resetTracer($tracer = null, $config = []) { // Reset the current C-level array of generated spans @@ -66,10 +73,7 @@ public function isolateTracer($fn, $tracer = null, $config = []) } $fn($tracer); - $traces = $this->flushAndGetTraces(); - if (!empty($traces)) { - $this->sendTracesToTestAgent($traces); - } + $traces = $this->flushAndSendTracesToTestAgent(); self::putEnv('DD_TRACE_SHUTDOWN_TIMEOUT'); self::putEnv('DD_TRACE_AGENT_RETRIES'); @@ -77,29 +81,28 @@ public function isolateTracer($fn, $tracer = null, $config = []) return $traces; } - public function sendTracesToTestAgent($traces) + /** + * Like flushAndGetTraces(), and also sends the closed spans to the test agent, as the v0.4 msgpack + * payloads that the in-process sender's downgrade produces. + */ + protected function flushAndSendTracesToTestAgent() { - // flushAndGetTraces() returns the V1 introspection shape (attributes + promoted keys). - // The test agent negotiates the v0.4 wire, so convert each span to the flat shape it - // expects (and that the stored snapshots were captured in) before sending. Native - // span_links become the legacy `_dd.span_links` meta JSON: the test agent rejects the list. - foreach ($traces as &$trace) { - foreach ($trace as &$span) { - $span = SpanChecker::spanLinksToLegacyMeta(SpanChecker::spanToWireShape($span)); - } - unset($span); + list($payload, $v04Payloads) = \DDTrace\Testing\serialize_closed_spans_v04(); + foreach ($v04Payloads as $v04Payload) { + $this->sendTracesToTestAgent($v04Payload); } - unset($trace); - - // The data to be sent in the POST request - $data_json = json_encode($traces); + return $payload['chunks']; + } + /** @param string $v04Payload A v0.4 msgpack payload with a single trace */ + public function sendTracesToTestAgent($v04Payload) + { // The headers to be included in the request $headers = array( - 'Content-Type: application/json', + 'Content-Type: application/msgpack', 'Datadog-Meta-Lang: php', 'X-Datadog-Agent-Proxy-Disabled: true', - 'X-Datadog-Trace-Count: ' . count($traces), + 'X-Datadog-Trace-Count: 1', 'X-Datadog-Test-Session-Token: ' . ini_get("datadog.trace.agent_test_session_token"), ); @@ -115,7 +118,7 @@ public function sendTracesToTestAgent($traces) // Set the cURL options curl_setopt($curl, CURLOPT_URL, 'http://test-agent:9126/v0.4/traces'); // The URL to send the request to curl_setopt($curl, CURLOPT_POST, true); // Use POST method - curl_setopt($curl, CURLOPT_POSTFIELDS, $data_json); // Set the POST data + curl_setopt($curl, CURLOPT_POSTFIELDS, $v04Payload); // Set the POST data curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // Return the response instead of outputting it curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); // Set the headers @@ -323,6 +326,7 @@ public function executeCli($scriptPath, $customEnvs = [], $customInis = [], $arg */ public function resetRequestDumper() { + $this->dumpedPayload = []; $curl = curl_init(self::$agentRequestDumperUrl . '/clear-dumped-data'); curl_setopt($curl, CURLOPT_HTTPHEADER, ['x-datadog-test-session-token: ' . ini_get("datadog.trace.agent_test_session_token")]); self::curlWithoutSpan($curl); @@ -360,36 +364,117 @@ public function tracesFromWebRequest($fn, $tracer = null, $until = null) return $this->parseTracesFromDumpedData($until); } - private function parseRawDumpedTraces($rawTraces) + /** + * Parses a dumped trace payload into the chunks of the V1 view (as dd_trace_serialize_closed_spans() + * returns them), whatever the wire: the replayer's JSON view of the v1 payload, or a v0.4 (list of + * traces) / v0.7 (chunks of v0.4 spans) payload. + */ + protected function parseRawDumpedTraces($rawTraces) { - // error_log('RawTraces: ' . print_r($rawTraces, 1)); - - if (empty($rawTraces['chunks'])) { - return $this->parseRawDumpedTraces04($rawTraces); - } else { - return $this->parseRawDumpedTraces07($rawTraces); + $chunks = []; + if (!$rawTraces || isset($rawTraces[0])) { + $chunks = array_map([$this, 'fromV04Trace'], $rawTraces ?: []); + } elseif (isset($rawTraces['chunks'])) { + $payload = $rawTraces; + unset($payload['chunks']); + $this->dumpedPayload = array_replace_recursive($this->dumpedPayload, $payload); + foreach ($rawTraces['chunks'] as $chunk) { + $spans = $chunk['spans'] ?? []; + $chunks[] = isset($spans[0]['trace_id']) ? $this->fromV04Trace($spans) : $chunk; + } } + foreach ($chunks as &$chunk) { + if (trim($chunk['trace_id'] ?? '', '0') === '') { + TestCase::fail('Chunk has zero trace_id'); + } + $chunk['spans'] = $this->parseRawDumpedSpans($chunk['spans'] ?? []); + } + unset($chunk); + return $chunks; } - private function parseRawDumpedTraces04($rawTraces) + /** + * A v0.4 trace as a V1 chunk: the trace-level tags v0.4 keeps on spans become chunk fields, and + * the payload-level ones go to $dumpedPayload. + */ + private function fromV04Trace(array $spans) { - $traces = []; - - foreach ($rawTraces as $spansInTrace) { - $traces[] = $this->parseRawDumpedSpans($spansInTrace); + $chunk = []; + $traceIdHigh = 0; + foreach ($spans as &$span) { + $meta = $span['meta'] ?? []; + $metrics = $span['metrics'] ?? []; + foreach (self::$v04PayloadAttributes as $key) { + if (isset($meta[$key])) { + $this->dumpedPayload['attributes'][$key] = $meta[$key]; + unset($span['meta'][$key]); + } + } + if (isset($meta['_dd.hostname'])) { + $this->dumpedPayload['hostname'] = $meta['_dd.hostname']; + unset($span['meta']['_dd.hostname']); + } + if (isset($meta['_dd.p.tid'])) { + $traceIdHigh = $meta['_dd.p.tid']; + } + if (isset($metrics['_sampling_priority_v1'])) { + $chunk['priority'] = (int)$metrics['_sampling_priority_v1']; + } + if (isset($meta['_dd.origin'])) { + $chunk['origin'] = $meta['_dd.origin']; + } + if (isset($meta['_dd.p.dm'])) { + // "-N" (legacy "-N"): the digits after the last '-'. + $chunk['sampling_mechanism'] = (int)substr(strrchr('-' . $meta['_dd.p.dm'], '-'), 1); + } } - - return $traces; + unset($span); + $traceIdLow = isset($spans[0]['trace_id']) ? SpanChecker::decimalToHex($spans[0]['trace_id'], 16) : ''; + $chunk = ['trace_id' => str_pad($traceIdHigh, 16, '0', STR_PAD_LEFT) . $traceIdLow] + $chunk; + $chunk['spans'] = array_map([$this, 'fromV04Span'], $spans); + return $chunk; } - private function parseRawDumpedTraces07($rawTraces) + /** + * A v0.4 span in the V1 view shape. The fields v0.4 keeps in meta/metrics move back to the span, + * links get hex ids. Attribute values stay in their (lossy) v0.4 form, so the span is marked for + * SpanChecker to compare expectations in that form too. + */ + private function fromV04Span(array $span) { - $traces = []; - - foreach ($rawTraces['chunks'] as $chunk) { - $traces[] = $this->parseRawDumpedSpans($chunk['spans']); + $attributes = ($span['meta'] ?? []) + ($span['metrics'] ?? []); + unset($span['meta'], $span['metrics'], $span['trace_id']); + unset($attributes['_dd.origin'], $attributes['_dd.p.tid'], $attributes['_dd.p.dm'], $attributes['_sampling_priority_v1']); + foreach (['env', 'version', 'component'] as $field) { + if (isset($attributes[$field])) { + $span[$field] = $attributes[$field]; + unset($attributes[$field]); + } } - return $traces; + $kind = array_search($attributes['span.kind'] ?? null, SpanKindNames::NAMES, true); + if ($kind !== false) { + $span['span_kind'] = $kind; + unset($attributes['span.kind']); + } + if (!empty($span['error'])) { + $span['error'] = true; + } else { + unset($span['error']); + } + if (isset($attributes['events']) && is_array($events = json_decode($attributes['events'], true))) { + $span['span_events'] = $events; + unset($attributes['events']); + } + $links = $span['span_links'] ?? []; + unset($span['span_links']); + foreach ($links as $link) { + $span['span_links'][] = SpanChecker::hexSpanLink($link) + array_intersect_key($link, ['attributes' => 1]); + } + if ($attributes) { + $span['attributes'] = $attributes; + } + $span['_wire'] = 'v0.4'; + return $span; } private function parseRawDumpedSpans($rawSpans) @@ -401,11 +486,6 @@ private function parseRawDumpedSpans($rawSpans) return; } - if ($rawSpan['trace_id'] == "0") { - TestCase::fail(sprintf("Span '%s' has zero trace_id", $rawSpan['name'])); - return; - } - if (($rawSpan['parent_id'] ?? "") == "0") { unset($rawSpan['parent_id']); } @@ -452,7 +532,7 @@ private function parseTracesFromDumpedData($until = null, $throw = false) // Ensure stable sorting; sort order isn't guaranteed with sidecar trace sender // Sorting by end of root span usort($dumps, function ($a, $b) { - return $a[0]["start"] + $a[0]["duration"] <=> $b[0]["start"] + $b[0]["duration"]; + return $a['spans'][0]["start"] + $a['spans'][0]["duration"] <=> $b['spans'][0]["start"] + $b['spans'][0]["duration"]; }); return $dumps; @@ -548,11 +628,17 @@ public function retrieveDumpedTraceData($until = null, $throw = false) { return array_values(array_filter($this->retrieveDumpedData($until, $throw), function ($request) { // Only return actual trace requests, filtering out telemetry, remote config, etc. - $uri = $request["uri"] ?? ""; - return strpos($uri, "/v0.4/traces") === 0 || strpos($uri, "/v0.7/traces") === 0; + return self::isTraceUri($request["uri"] ?? ""); })); } + private static function isTraceUri($uri) + { + return strpos($uri, "/v0.4/traces") === 0 + || strpos($uri, "/v0.7/traces") === 0 + || strpos($uri, "/v1.0/traces") === 0; + } + function untilNumberOfTraces($number) { $count = 0; return function ($request) use (&$count, $number) { @@ -563,9 +649,7 @@ function untilNumberOfTraces($number) { function untilFirstTraceRequest() { return function ($request) { - return (strpos($request["uri"] ?? "", "/v0.4/traces") === 0) - || (strpos($request["uri"] ?? "", "/v0.7/traces") === 0) - ; + return self::isTraceUri($request["uri"] ?? ""); }; } @@ -579,9 +663,7 @@ function untilTelemetryRequest($metricName) { function untilSpan(SpanAssertion $assertion) { return function ($request) use ($assertion) { - $uri = $request["uri"] ?? ""; - $isTrace = strpos($uri, "/v0.4/traces") === 0 || strpos($uri, "/v0.7/traces") === 0; - if (!$isTrace || !isset($request['body'])) { + if (!self::isTraceUri($request["uri"] ?? "") || !isset($request['body'])) { return false; } $traces = $this->parseRawDumpedTraces(json_decode($request['body'], true)); @@ -665,8 +747,7 @@ public function simulateWebRequestTracer($fn) */ protected function flushAndGetTraces() { - $traces = \dd_trace_serialize_closed_spans(); - return $traces ? [$traces] : []; + return \dd_trace_serialize_closed_spans()['chunks']; } /** diff --git a/tests/Composer/ComposerInteroperabilityTest.php b/tests/Composer/ComposerInteroperabilityTest.php index 24468d824f7..20f5da6ec77 100644 --- a/tests/Composer/ComposerInteroperabilityTest.php +++ b/tests/Composer/ComposerInteroperabilityTest.php @@ -98,12 +98,12 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'web.request', 'web', 'GET /no-manual-tracing') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ]); } @@ -134,16 +134,16 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'web.request', 'web', 'GET /manual-tracing') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]) ->withChildren([ SpanAssertion::build('my_operation', 'web.request', 'memcached', 'my_resource') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', '_dd.svc_src' => 'm', ]), @@ -177,16 +177,16 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'web.request', 'web', 'GET /manual-tracing') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]) ->withChildren([ SpanAssertion::build('my_operation', 'web.request', 'memcached', 'my_resource') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', '_dd.svc_src' => 'm', ]), @@ -220,12 +220,12 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'web.request', 'web', 'GET /no-manual-tracing') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ]); } @@ -256,16 +256,16 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'web.request', 'web', 'GET /manual-tracing') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]) ->withChildren([ SpanAssertion::build('my_operation', 'web.request', 'memcached', 'my_resource') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', '_dd.svc_src' => 'm', ]), @@ -293,12 +293,12 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'web.request', 'web', 'GET /no-manual-tracing') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-manual-tracing', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ]); } @@ -323,12 +323,12 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'web.request', 'web', 'GET /no-composer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-composer', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ]); } @@ -358,12 +358,12 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'web.request', 'web', 'GET /no-composer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-composer', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ]); } @@ -395,12 +395,12 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'web.request', 'web', 'GET /no-composer-autoload-fails') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/no-composer-autoload-fails', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ]); } @@ -432,12 +432,12 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'web.request', 'web', 'GET /composer-autoload-fails') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://127.0.0.1:' . self::$webserverPort . '/composer-autoload-fails', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ]); } diff --git a/tests/DistributedTracing/DistributedTraceTest.php b/tests/DistributedTracing/DistributedTraceTest.php index 5f64e69b332..a437424226a 100644 --- a/tests/DistributedTracing/DistributedTraceTest.php +++ b/tests/DistributedTracing/DistributedTraceTest.php @@ -2,6 +2,7 @@ namespace DDTrace\Tests\DistributedTracing; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\WebFrameworkTestCase; use DDTrace\Tests\Frameworks\Util\Request\RequestSpec; @@ -43,8 +44,8 @@ public function testDistributedTrace() $this->call($spec); }); - $this->assertSame('1042', $traces[0][0]['trace_id']); - $this->assertSame('1000', $traces[0][0]['parent_id']); + $this->assertSame('1042', SpanChecker::traceIdLow($traces[0])); + $this->assertSame('1000', $traces[0]['spans'][0]['parent_id']); } public function testDistributedTraceUint64() @@ -62,8 +63,8 @@ public function testDistributedTraceUint64() $this->call($spec); }); - $this->assertSame('12222222222222222222', $traces[0][0]['trace_id']); - $this->assertSame('11133333333333333333', $traces[0][0]['parent_id']); + $this->assertSame('12222222222222222222', SpanChecker::traceIdLow($traces[0])); + $this->assertSame('11133333333333333333', $traces[0]['spans'][0]['parent_id']); } // Synthetics requests have "0" as the parent ID @@ -82,8 +83,8 @@ public function testDistributedTraceWithNoParent() $this->call($spec); }); - $this->assertSame('6017420907356617206', $traces[0][0]['trace_id']); - $this->assertArrayNotHasKey('parent_id', $traces[0][0]); + $this->assertSame('6017420907356617206', SpanChecker::traceIdLow($traces[0])); + $this->assertArrayNotHasKey('parent_id', $traces[0]['spans'][0]); } public function testInvalidTraceId() @@ -101,9 +102,9 @@ public function testInvalidTraceId() $this->call($spec); }); - $this->assertNotSame('this-is-not-valid', $traces[0][0]['trace_id']); - $this->assertNotSame('0', $traces[0][0]['trace_id']); - $this->assertArrayNotHasKey('parent_id', $traces[0][0]); + $this->assertNotSame('this-is-not-valid', SpanChecker::traceIdLow($traces[0])); + $this->assertNotSame('0', SpanChecker::traceIdLow($traces[0])); + $this->assertArrayNotHasKey('parent_id', $traces[0]['spans'][0]); } public function testInvalidParentId() @@ -121,7 +122,7 @@ public function testInvalidParentId() $this->call($spec); }); - $this->assertSame('42', $traces[0][0]['trace_id']); - $this->assertArrayNotHasKey('parent_id', $traces[0][0]); + $this->assertSame('42', SpanChecker::traceIdLow($traces[0])); + $this->assertArrayNotHasKey('parent_id', $traces[0]['spans'][0]); } } diff --git a/tests/DistributedTracing/SamplingPriorityTest.php b/tests/DistributedTracing/SamplingPriorityTest.php index 3c071e875f4..dbc31d56b9e 100644 --- a/tests/DistributedTracing/SamplingPriorityTest.php +++ b/tests/DistributedTracing/SamplingPriorityTest.php @@ -43,11 +43,9 @@ public function testKeepPriority() 'web.request', 'web', 'GET /index.php' - )->withExactTags( + )->withExactAttributes( SpanAssertion::NOT_TESTED - )->withExactMetrics([ - '_sampling_priority_v1' => 2, - ]) + )->samplingPriority(2) ); } @@ -73,11 +71,9 @@ public function testDropPriority() 'web.request', 'web', 'GET /index.php' - )->withExactTags( + )->withExactAttributes( SpanAssertion::NOT_TESTED - )->withExactMetrics([ - '_sampling_priority_v1' => 0, - ]) + )->samplingPriority(0) ); } } diff --git a/tests/DistributedTracing/SandboxAndLegacyTest.php b/tests/DistributedTracing/SandboxAndLegacyTest.php index 8792df3175c..0911b4b51ab 100644 --- a/tests/DistributedTracing/SandboxAndLegacyTest.php +++ b/tests/DistributedTracing/SandboxAndLegacyTest.php @@ -2,6 +2,7 @@ namespace DDTrace\Tests\DistributedTracing; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\WebFrameworkTestCase; use DDTrace\Tests\Frameworks\Util\Request\RequestSpec; @@ -44,14 +45,13 @@ public function testDistributedTrace() }); $this->assertCount(1, $traces); - $this->assertCount(2, $traces[0]); + $this->assertCount(2, $traces[0]['spans']); + $this->assertSame('1042', SpanChecker::traceIdLow($traces[0])); // Root span (userland) - $rootSpan = $traces[0][0]; - $this->assertSame('1042', $rootSpan['trace_id']); + $rootSpan = $traces[0]['spans'][0]; $this->assertSame('1000', $rootSpan['parent_id']); // Child span (internal) - $childSpan = $traces[0][1]; - $this->assertSame('1042', $childSpan['trace_id']); + $childSpan = $traces[0]['spans'][1]; $this->assertSame($rootSpan['span_id'], $childSpan['parent_id']); } @@ -70,8 +70,8 @@ public function testDistributedTraceUint64() $this->call($spec); }); - $this->assertSame('12222222222222222222', $traces[0][0]['trace_id']); - $this->assertSame('11133333333333333333', $traces[0][0]['parent_id']); + $this->assertSame('12222222222222222222', SpanChecker::traceIdLow($traces[0])); + $this->assertSame('11133333333333333333', $traces[0]['spans'][0]['parent_id']); } // Synthetics requests have "0" as the parent ID @@ -90,13 +90,12 @@ public function testDistributedTraceWithNoParent() $this->call($spec); }); + $this->assertSame('6017420907356617206', SpanChecker::traceIdLow($traces[0])); // Root span (userland) - $rootSpan = $traces[0][0]; - $this->assertSame('6017420907356617206', $rootSpan['trace_id']); + $rootSpan = $traces[0]['spans'][0]; $this->assertArrayNotHasKey('parent_id', $rootSpan); // Child span (internal) - $childSpan = $traces[0][1]; - $this->assertSame('6017420907356617206', $childSpan['trace_id']); + $childSpan = $traces[0]['spans'][1]; $this->assertSame($rootSpan['span_id'], $childSpan['parent_id']); } @@ -108,11 +107,10 @@ public function testNonDistributedTest() }); // Root span (userland) - $rootSpan = $traces[0][0]; + $rootSpan = $traces[0]['spans'][0]; $this->assertArrayNotHasKey('parent_id', $rootSpan); // Child span (internal) - $childSpan = $traces[0][1]; - $this->assertSame($rootSpan['trace_id'], $childSpan['trace_id']); + $childSpan = $traces[0]['spans'][1]; $this->assertSame($rootSpan['span_id'], $childSpan['parent_id']); } } diff --git a/tests/DistributedTracing/SyntheticsTest.php b/tests/DistributedTracing/SyntheticsTest.php index f379128f5db..6a0452307bd 100644 --- a/tests/DistributedTracing/SyntheticsTest.php +++ b/tests/DistributedTracing/SyntheticsTest.php @@ -3,6 +3,7 @@ namespace DDTrace\Tests\DistributedTracing; use DDTrace\Tests\Common\SpanAssertion; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\WebFrameworkTestCase; use DDTrace\Tests\Frameworks\Util\Request\RequestSpec; @@ -49,17 +50,14 @@ public function testSyntheticsRequest() 'web.request', 'web', 'GET /index.php' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/index.php', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), - '_dd.origin' => 'synthetics-browser', - ])->withExactMetrics([ - '_sampling_priority_v1' => 1, - ]) + 'component' => 'web', + ])->origin('synthetics-browser')->samplingPriority(1) ); - $this->assertSame('123456', $traces[0][0]['trace_id']); + $this->assertSame('123456', SpanChecker::traceIdLow($traces[0])); } } diff --git a/tests/Frameworks/Custom/Version_Autoloaded/no-root-span b/tests/Frameworks/Custom/Version_Autoloaded/no-root-span index e627853f793..d3751faac30 100755 --- a/tests/Frameworks/Custom/Version_Autoloaded/no-root-span +++ b/tests/Frameworks/Custom/Version_Autoloaded/no-root-span @@ -19,7 +19,7 @@ function my_app() } } -\dd_trace_function('my_app', function (\DDTrace\SpanData $span) { +\DDTrace\trace_function('my_app', function (\DDTrace\SpanData $span) { $span->name = 'my_app'; $span->service = 'foo_service'; $span->resource = 'foo_resource'; diff --git a/tests/Frameworks/Custom/Version_Not_Autoloaded/sandbox.php b/tests/Frameworks/Custom/Version_Not_Autoloaded/sandbox.php index c9468de379e..cf8302afb68 100644 --- a/tests/Frameworks/Custom/Version_Not_Autoloaded/sandbox.php +++ b/tests/Frameworks/Custom/Version_Not_Autoloaded/sandbox.php @@ -1,6 +1,6 @@ name = $span->resource = 'myWebsite'; $span->type = 'web'; $span->service = 'foo_service'; diff --git a/tests/Integration/CurrentContextAccess/CurrentContextAccessTest.php b/tests/Integration/CurrentContextAccess/CurrentContextAccessTest.php index 3b17469a993..c0a192611a0 100644 --- a/tests/Integration/CurrentContextAccess/CurrentContextAccessTest.php +++ b/tests/Integration/CurrentContextAccess/CurrentContextAccessTest.php @@ -3,40 +3,11 @@ namespace DDTrace\Tests\Integration\CurrentContextAccess; use DDTrace\Tests\Common\IntegrationTestCase; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; final class CurrentContextAccessTest extends IntegrationTestCase { - // Source: https://magp.ie/2015/09/30/convert-large-integer-to-hexadecimal-without-php-math-extension/ - public function largeBaseConvert($numString, $fromBase, $toBase) - { - $chars = "0123456789abcdefghijklmnopqrstuvwxyz"; - $toString = substr($chars, 0, $toBase); - - $length = strlen($numString); - $result = ''; - for ($i = 0; $i < $length; $i++) { - $number[$i] = strpos($chars, $numString[$i]); - } - do { - $divide = 0; - $newLen = 0; - for ($i = 0; $i < $length; $i++) { - $divide = $divide * $fromBase + $number[$i]; - if ($divide >= $toBase) { - $number[$newLen++] = (int)($divide / $toBase); - $divide = $divide % $toBase; - } elseif ($newLen > 0) { - $number[$newLen++] = 0; - } - } - $length = $newLen; - $result = $toString[$divide] . $result; - } while ($newLen != 0); - - return $result; - } - public function testInWebRequest() { $traces = $this->inWebServer( @@ -50,21 +21,15 @@ function ($execute) { ] ); - $trace = $traces[0]; - $this->assertCount(2, $trace); - - $traceId = $trace[0]['trace_id']; - $tid = $trace[0]['meta']['_dd.p.tid']; - $this->assertNotEquals(0, $traceId); - - $traceIdHex = str_pad(self::largeBaseConvert($traceId, 10, 16), 16, '0', STR_PAD_LEFT); + $chunk = $traces[0]; + $this->assertCount(2, $chunk['spans']); + $this->assertNotEquals(0, SpanChecker::traceIdLow($chunk)); - foreach ($trace as $span) { + foreach ($chunk['spans'] as $span) { $spanId = $span['span_id']; $this->assertNotEquals(0, $spanId); - $this->assertSame($traceId, $span['trace_id']); - $this->assertSame($spanId, $span['meta']['extracted_span_id']); - $this->assertSame($tid . $traceIdHex, $span['meta']['extracted_trace_id']); + $this->assertSame($spanId, $span['attributes']['extracted_span_id']); + $this->assertSame($chunk['trace_id'], $span['attributes']['extracted_trace_id']); } } @@ -72,18 +37,17 @@ public function testInShortRunningCliScript() { list($traces) = $this->inCli(__DIR__ . '/short-running.php', ['DD_TRACE_GENERATE_ROOT_SPAN' => 'true']); - $trace = $traces[0]; - $this->assertCount(2, $trace); + $chunk = $traces[0]; + $this->assertCount(2, $chunk['spans']); - $traceId = $trace[0]['trace_id']; + $traceId = SpanChecker::traceIdLow($chunk); $this->assertNotEquals(0, $traceId); - foreach ($trace as $span) { + foreach ($chunk['spans'] as $span) { $spanId = $span['span_id']; $this->assertNotEquals(0, $spanId); - $this->assertSame($traceId, $span['trace_id']); - $this->assertSame($spanId, $span['meta']['extracted_span_id']); - $this->assertSame($traceId, $span['meta']['extracted_trace_id']); + $this->assertSame($spanId, $span['attributes']['extracted_span_id']); + $this->assertSame($traceId, $span['attributes']['extracted_trace_id']); } } @@ -97,20 +61,19 @@ public function testInLongRunningCliScript() ] ); - $trace = $traces[0]; - $this->assertCount(2, $trace); + $chunk = $traces[0]; + $this->assertCount(2, $chunk['spans']); - $traceId = $trace[0]['trace_id']; + $traceId = SpanChecker::traceIdLow($chunk); $this->assertNotEquals(0, $traceId); - $this->assertSame('root_span', $trace[0]['name']); - $this->assertSame('internal_span', $trace[1]['name']); + $this->assertSame('root_span', $chunk['spans'][0]['name']); + $this->assertSame('internal_span', $chunk['spans'][1]['name']); - foreach ($trace as $span) { + foreach ($chunk['spans'] as $span) { $spanId = $span['span_id']; $this->assertNotEquals(0, $spanId); - $this->assertSame($traceId, $span['trace_id']); - $this->assertSame($spanId, $span['meta']['extracted_span_id']); - $this->assertSame($traceId, $span['meta']['extracted_trace_id']); + $this->assertSame($spanId, $span['attributes']['extracted_span_id']); + $this->assertSame($traceId, $span['attributes']['extracted_trace_id']); } } } diff --git a/tests/Integration/DatabaseMonitoringTest.php b/tests/Integration/DatabaseMonitoringTest.php index 68b6b4c378d..1150425a60c 100644 --- a/tests/Integration/DatabaseMonitoringTest.php +++ b/tests/Integration/DatabaseMonitoringTest.php @@ -55,7 +55,7 @@ public function testInjection() // phpcs:enable Generic.Files.LineLength.TooLong $this->assertFlameGraph($traces, [ SpanAssertion::exists("phpunit")->withChildren([ - SpanAssertion::exists('instrumented')->withExactTags([ + SpanAssertion::exists('instrumented')->withExactAttributes([ "_dd.dbm_trace_injected" => "true", "_dd.base_service" => "phpunit", ]) @@ -87,7 +87,7 @@ public function testInjectionServiceMappingOnce() $this->assertRegularExpression('/^\/\*dddbs=\'mapped-service\',ddps=\'phpunit\',traceparent=\'00-[0-9a-f]{16}c151df7d6ee5e2d6-a3978fb9b92502a8-03\'\*\/ SELECT 1$/', $commentedQuery); $this->assertFlameGraph($traces, [ SpanAssertion::exists("phpunit")->withChildren([ - SpanAssertion::exists('instrumented')->withExactTags([ + SpanAssertion::exists('instrumented')->withExactAttributes([ "_dd.dbm_trace_injected" => "true", "_dd.base_service" => "mapped-service", ]) @@ -117,7 +117,7 @@ public function testInjectionServiceMappingTwice() $this->assertRegularExpression('/^\/\*dddbs=\'mapped-service\',ddps=\'mapped-service\',traceparent=\'00-[0-9a-f]{16}c151df7d6ee5e2d6-c151df7d6ee5e2d6-03\'\*\/ SELECT 1$/', $commentedQuery); $this->assertFlameGraph($traces, [ - SpanAssertion::exists('instrumented')->withExactTags([ + SpanAssertion::exists('instrumented')->withExactAttributes([ "_dd.dbm_trace_injected" => "true", "_dd.base_service" => "mapped-service", ]) @@ -146,7 +146,7 @@ public function testInjectionServiceMappingService() $this->assertRegularExpression('/^\/\*dddbs=\'mapped-service\',ddps=\'mapped-service\'\*\/ SELECT 1$/', $commentedQuery); $this->assertFlameGraph($traces, [ - SpanAssertion::exists('instrumented')->withExactTags([ + SpanAssertion::exists('instrumented')->withExactAttributes([ "_dd.dbm_trace_injected" => "true", "_dd.base_service" => "mapped-service", ]) @@ -175,7 +175,7 @@ public function testInjectionServiceMappingNone() $this->assertSame('SELECT 1', $commentedQuery); $this->assertFlameGraph($traces, [ - SpanAssertion::exists('instrumented')->withExactTags([ + SpanAssertion::exists('instrumented')->withExactAttributes([ "_dd.dbm_trace_injected" => "true", "_dd.base_service" => "mapped-service", ]) @@ -210,7 +210,7 @@ public function testInjectionPeerService() // phpcs:enable Generic.Files.LineLength.TooLong $this->assertFlameGraph($traces, [ SpanAssertion::exists("phpunit")->withChildren([ - SpanAssertion::exists('instrumented')->withExactTags([ + SpanAssertion::exists('instrumented')->withExactAttributes([ "_dd.dbm_trace_injected" => "true", "peer.service" => "dbinstance", "_dd.base_service" => "mapped-service", @@ -325,7 +325,7 @@ public function testBaseHashInjection() $this->assertNotEmpty($matches, 'ddsh not found in SQL comment'); $ddshValue = $matches[1]; - $propagatedHash = $traces[0][1]['attributes']['_dd.propagated_hash'] ?? null; + $propagatedHash = $traces[0]['spans'][1]['attributes']['_dd.propagated_hash'] ?? null; $this->assertNotNull($propagatedHash, '_dd.propagated_hash not found in span'); $this->assertSame($ddshValue, $propagatedHash, 'ddsh in SQL comment does not match _dd.propagated_hash in span'); } @@ -361,7 +361,7 @@ public function testBaseHashInjectionWithoutContainerTagsHash() $this->assertNotEmpty($matches, 'ddsh not found in SQL comment'); $ddshValue = $matches[1]; - $propagatedHash = $traces[0][1]['attributes']['_dd.propagated_hash'] ?? null; + $propagatedHash = $traces[0]['spans'][1]['attributes']['_dd.propagated_hash'] ?? null; $this->assertNotNull($propagatedHash, '_dd.propagated_hash not found in span'); $this->assertSame($ddshValue, $propagatedHash, 'ddsh in SQL comment does not match _dd.propagated_hash in span'); } @@ -400,7 +400,7 @@ public function testBaseHashNotInjectedWhenDisabled() // The span should NOT have the _dd.propagated_hash tag $this->assertFlameGraph($traces, [ SpanAssertion::exists("phpunit")->withChildren([ - SpanAssertion::exists('instrumented')->withExactTags([ + SpanAssertion::exists('instrumented')->withExactAttributes([ "_dd.dbm_trace_injected" => "true", "_dd.base_service" => "phpunit", ]) @@ -445,11 +445,11 @@ public function testDynamicServiceMode() ); $ddshValue = preg_replace('/^.*ddsh=\'([^\']+)\'.*$/', '$1', $commentedQuery); - $propagatedHash = $traces[0][1]['attributes']['_dd.propagated_hash'] ?? null; + $propagatedHash = $traces[0]['spans'][1]['attributes']['_dd.propagated_hash'] ?? null; $this->assertNotNull($propagatedHash, '_dd.propagated_hash not found in span'); $this->assertSame($ddshValue, $propagatedHash, 'ddsh in SQL comment does not match _dd.propagated_hash in span'); // dynamic_service is not full mode, so the trace-injected marker must be absent - $this->assertArrayNotHasKey('_dd.dbm_trace_injected', $traces[0][1]['attributes']); + $this->assertArrayNotHasKey('_dd.dbm_trace_injected', $traces[0]['spans'][1]['attributes']); } } diff --git a/tests/Integration/ErrorReporting/ErrorReportingTest.php b/tests/Integration/ErrorReporting/ErrorReportingTest.php index 87b97fd83db..d17cc079a6a 100644 --- a/tests/Integration/ErrorReporting/ErrorReportingTest.php +++ b/tests/Integration/ErrorReporting/ErrorReportingTest.php @@ -30,9 +30,9 @@ public function testUnhandledUserErrorIndex() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-user-error-index')); }); - $this->assertError($traces[0][0], "Index message", [['index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Index message", [['index.php', '{main}']]); // open task: depends on internal status code tracking (separate PR) - // $this->assertSame('500', $traces[0][0]['meta']['http.status_code']); + // $this->assertSame('500', $traces[0]['spans'][0]['attributes']['http.status_code']); } public function testUnhandledExceptionIndex() @@ -40,9 +40,9 @@ public function testUnhandledExceptionIndex() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-exception-index')); }); - $this->assertError($traces[0][0], "Exception in index*index.php", [['{main}']]); + $this->assertError($traces[0]['spans'][0], "Exception in index*index.php", [['{main}']]); // open task: depends on internal status code tracking (separate PR) - // $this->assertSame('500', $traces[0][0]['meta']['http.status_code']); + // $this->assertSame('500', $traces[0]['spans'][0]['attributes']['http.status_code']); } public function testUnhandledUserErrorExternal() @@ -54,7 +54,7 @@ public function testUnhandledUserErrorExternal() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-user-error-external')); }); - $this->assertError($traces[0][0], "Triggered error", [['trigger_user_error.php', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Triggered error", [['trigger_user_error.php', 'index.php', '{main}']]); } public function testUnhandledExceptionExternal() @@ -63,7 +63,7 @@ public function testUnhandledExceptionExternal() $this->call(GetSpec::create('', '/unhandled-exception-external')); }); $this->assertError( - $traces[0][0], + $traces[0]['spans'][0], "Exception generated in external file*trigger_exception.php:5", [['trigger_exception.php', 'index.php', '{main}']] ); @@ -78,7 +78,7 @@ public function testUnhandledUserErrorInFunction() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-user-error-in-function')); }); - $this->assertError($traces[0][0], "Triggered error in function", [['trigger_error', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Triggered error in function", [['trigger_error', 'index.php', '{main}']]); } public function testUnhandledExceptionInFunction() @@ -86,7 +86,7 @@ public function testUnhandledExceptionInFunction() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-exception-in-function')); }); - $this->assertError($traces[0][0], "Uncaught Exception: Exception in external file in */functions.php:20", [['index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Uncaught Exception: Exception in external file in */functions.php:20", [['index.php', '{main}']]); } public function testUnhandledUserErrorInNestedFunction() @@ -98,7 +98,7 @@ public function testUnhandledUserErrorInNestedFunction() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-user-error-in-nested-function')); }); - $this->assertError($traces[0][0], "Triggered error in function", [['trigger_error', 'do_trigger_error', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Triggered error in function", [['trigger_error', 'do_trigger_error', 'index.php', '{main}']]); } public function testUnhandledUserErrorWithErrorHandlerNotHandlingIt() @@ -110,7 +110,7 @@ public function testUnhandledUserErrorWithErrorHandlerNotHandlingIt() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-user-error-run-through-handler-continuing-handling')); }); - $this->assertError($traces[0][0], "Triggered error in function", [['trigger_error', 'do_trigger_error', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Triggered error in function", [['trigger_error', 'do_trigger_error', 'index.php', '{main}']]); } public function testUnhandledExceptionInNestedFunction() @@ -118,7 +118,7 @@ public function testUnhandledExceptionInNestedFunction() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-exception-in-nested-function')); }); - $this->assertError($traces[0][0], "Exception in external file", [['do_throw_exception', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Exception in external file", [['do_throw_exception', 'index.php', '{main}']]); } public function testUnhandledExceptionInClass() @@ -126,7 +126,7 @@ public function testUnhandledExceptionInClass() $traces = $this->tracesFromWebRequest(function () { $response = $this->call(GetSpec::create('', '/unhandled-exception-class')); }); - $this->assertError($traces[0][0], "Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); } public function testUnhandledExceptionRethrownInClass() @@ -134,7 +134,7 @@ public function testUnhandledExceptionRethrownInClass() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-exception-rethrown-class')); }); - $this->assertError($traces[0][0], "Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); } public function testUnhandledThrowableInClass() @@ -142,7 +142,7 @@ public function testUnhandledThrowableInClass() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-throwable-class')); }); - $this->assertError($traces[0][0], "Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); } public function testUnhandledThrowableMultipleCatches() @@ -150,7 +150,7 @@ public function testUnhandledThrowableMultipleCatches() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-throwable-multiple-catch')); }); - $this->assertError($traces[0][0], "Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); } public function testNestedHeaderHandledExceptionInClass() @@ -158,7 +158,7 @@ public function testNestedHeaderHandledExceptionInClass() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/unhandled-nested-exception-class')); }); - $this->assertError($traces[0][0], "Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); } public function testHandledExceptionInFunction() @@ -166,7 +166,7 @@ public function testHandledExceptionInFunction() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/handled-exception-function-header')); }); - $this->assertError($traces[0][0], "Exception in external file", [['do_throw_exception', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Exception in external file", [['do_throw_exception', 'index.php', '{main}']]); } public function testPreviousExceptionDisplay() @@ -175,7 +175,7 @@ public function testPreviousExceptionDisplay() $this->call(GetSpec::create('', '/display-previous-exception-in-output')); }); $this->assertError( - $traces[0][0], + $traces[0]['spans'][0], "Exception thrown by inner service", [['doThrow', 'dispatchWithPreviousException', '{main}', '', 'Next ErrorException: Rethrown Exception in random file:2', @@ -207,7 +207,7 @@ public function testHandledExceptionViaTryCatchInClassHeaderFunction() $this->call(GetSpec::create('', '/handled-exception-try-catch-class-header')); }); $this->assertError( - $traces[0][0], + $traces[0]['spans'][0], "Internal Server Obfuscated Error*Exception thrown by inner service*service_throwing_exception.php", [['dispatcher.php*doThrow()', 'index.php*dispatchWithException()', '{main}']] ); @@ -223,7 +223,7 @@ public function testHandledExceptionRethrownInClassHeaderFunction() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/handled-exception-rethrow-class-header')); }); - $this->assertError($traces[0][0], "Obfuscated*Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Obfuscated*Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); } /** @@ -240,7 +240,7 @@ public function testHandledThrowableInClassHeaderFunction() $this->call(GetSpec::create('', '/handled-throwable-class-header')); }); $this->assertError( - $traces[0][0], + $traces[0]['spans'][0], "Internal Server Obfuscated Error*thrown by inner service*service_throwing_exception.php", [['dispatcher.php*doThrow()', 'index.php*dispatchWithThrowable()', '{main}']] ); @@ -251,7 +251,7 @@ public function testHandledExceptionConvertedUserErrorInClass() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/handled-exception-class-converted-user-error')); }); - $this->assertError($traces[0][0], "Obfuscated*Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Obfuscated*Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); } public function testHandledThrowableConvertedUserErrorInClass() @@ -259,7 +259,7 @@ public function testHandledThrowableConvertedUserErrorInClass() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/handled-throwable-class-converted-user-error')); }); - $this->assertError($traces[0][0], "Obfuscated*Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Obfuscated*Exception thrown by inner service", [['doThrow', 'index.php', '{main}']]); } public function testHandledExceptionConvertedUserErrorInFunction() @@ -267,7 +267,7 @@ public function testHandledExceptionConvertedUserErrorInFunction() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/handled-exception-function-converted-user-error')); }); - $this->assertError($traces[0][0], "Obfuscated*Exception in external file", [['do_throw_exception', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Obfuscated*Exception in external file", [['do_throw_exception', 'index.php', '{main}']]); } /** @@ -279,7 +279,7 @@ public function testHandledExceptionWhileRenderingPreviousException() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/handled-exception-generated-while-rendering-exception')); }); - $this->assertError($traces[0][0], "Obfuscated*Inner handling error", [['throw_handling_error', 'index.php', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Obfuscated*Inner handling error", [['throw_handling_error', 'index.php', '{main}']]); } public function testFirst500HandledExceptionGetsAttachedAsPreviousExceptionToFutureUncaughtExceptions() @@ -287,7 +287,7 @@ public function testFirst500HandledExceptionGetsAttachedAsPreviousExceptionToFut $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/caught-exception-with-500-followed-by-uncaught-exception')); }); - $this->assertError($traces[0][0], "Exception thrown by inner service", [['doThrow', 'nestedDispatchWithException', '{main}', '', + $this->assertError($traces[0]['spans'][0], "Exception thrown by inner service", [['doThrow', 'nestedDispatchWithException', '{main}', '', 'Next Exception: Exception in external file', 'trace', 'do_throw_exception', 'main']]); } @@ -296,7 +296,7 @@ public function testFirst500HandledExceptionTakesPriorityOverFutureHandledExcept $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/caught-exception-with-500-followed-by-other-handled-exception')); }); - $this->assertError($traces[0][0], "Exception thrown by inner service", [['doThrow', 'nestedDispatchWithException', '{main}']]); + $this->assertError($traces[0]['spans'][0], "Exception thrown by inner service", [['doThrow', 'nestedDispatchWithException', '{main}']]); } public function testImmediatelyCaughtException() @@ -304,7 +304,7 @@ public function testImmediatelyCaughtException() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/immediately-caught-exception')); }); - $this->assertError($traces[0][0], "Caught Exception (501): top-level exception", [['{main}']]); + $this->assertError($traces[0]['spans'][0], "Caught Exception (501): top-level exception", [['{main}']]); } public function testInternalExceptionThatShouldNotResultInError() @@ -312,7 +312,7 @@ public function testInternalExceptionThatShouldNotResultInError() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/internal-exception-not-resulting-in-error')); }); - $this->assertArrayNotHasKey("error", $traces[0][0]); + $this->assertArrayNotHasKey("error", $traces[0]['spans'][0]); } public function testInternalExceptionUsedForRedirect() @@ -320,8 +320,8 @@ public function testInternalExceptionUsedForRedirect() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/internal-exception-used-for-redirect')); }); - $this->assertSame('303', $traces[0][0]['meta']['http.status_code']); - $this->assertArrayNotHasKey("error", $traces[0][0]); + $this->assertSame('303', $traces[0]['spans'][0]['attributes']['http.status_code']); + $this->assertArrayNotHasKey("error", $traces[0]['spans'][0]); } @@ -330,6 +330,6 @@ public function testInternalUserErrorThatShouldNotResultInError() $traces = $this->tracesFromWebRequest(function () { $this->call(GetSpec::create('', '/internal-user-error-not-resulting-in-error')); }); - $this->assertArrayNotHasKey("error", $traces[0][0]); + $this->assertArrayNotHasKey("error", $traces[0]['spans'][0]); } } diff --git a/tests/Integration/LongRunning/LongRunningScriptTest.php b/tests/Integration/LongRunning/LongRunningScriptTest.php index d0e3b7c985f..9ede7fb53e5 100644 --- a/tests/Integration/LongRunning/LongRunningScriptTest.php +++ b/tests/Integration/LongRunning/LongRunningScriptTest.php @@ -36,24 +36,29 @@ public function testMultipleTracesFromLongRunningScriptSetCorrectTraceCountHeade public function testTracesFromLongRunningFunctionWithMixedTracing() { $this->script = 'long_running_script_with_trace_function.php'; - $traces = $this->getTracesFromCommand('', [ + $this->executeCommand('', [ 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', 'DD_TRACE_GENERATE_ROOT_SPAN' => 'false', 'DD_TRACE_BGS_TIMEOUT' => 3000, 'DD_TRACE_TRACED_INTERNAL_FUNCTIONS' => 'array_sum', ]); + // The traces can span several V1 requests: the first one's process tags lack svc.auto (manual root service). + $traces = []; + foreach ($this->retrieveDumpedTraceData($this->untilNumberOfTraces(3)) as $request) { + $traces = array_merge($traces, $this->loadTraces($request)); + } - $this->assertNotEquals($traces[1][0]["trace_id"], $traces[2][0]["trace_id"], "The trace id is reused"); + $this->assertNotEquals($traces[1]["trace_id"], $traces[2]["trace_id"], "The trace id is reused"); $rootTraceAssertion = function ($i) { return SpanAssertion::exists("do_manual_instrumentation_within_root_trace_function", "run $i") ->withChildren([ SpanAssertion::exists("first_sub_operation")->withChildren( SpanAssertion::exists("array_sum") - )->withExactTags(["result" => "42"]), + )->withExactAttributes(["result" => "42"]), SpanAssertion::exists("second_sub_operation")->withChildren( SpanAssertion::exists("array_sum") - )->withExactTags(["result" => "42"]), + )->withExactAttributes(["result" => "42"]), ]); }; diff --git a/tests/Integration/OrphansTest.php b/tests/Integration/OrphansTest.php index e2badd1c331..83131acb127 100644 --- a/tests/Integration/OrphansTest.php +++ b/tests/Integration/OrphansTest.php @@ -32,10 +32,8 @@ protected function envsToCleanUpAtTearDown() ]; } - static function getSampling($response) { - $root = json_decode($response[0]["body"], true); - $spans = $root["chunks"][0]["spans"] ?? $root[0]; - return $spans[0]["metrics"]["_sampling_priority_v1"]; + function getSampling($response) { + return $this->parseRawDumpedTraces(json_decode($response[0]["body"], true))[0]["priority"]; } function testOrphansRemovalWithAgentSampling() @@ -55,7 +53,7 @@ function testOrphansRemovalWithAgentSampling() usleep(333 * 2 * 1000); // DD_TRACE_AGENT_FLUSH_INTERVAL * 2 * 1000 } $response = $this->retrieveDumpedTraceData(); - $this->assertEquals(0, self::getSampling($response)); + $this->assertEquals(0, $this->getSampling($response)); $this->setResponse(["rate_by_service" => ["service:,env:" => 0]]); self::foo(); @@ -65,7 +63,7 @@ function testOrphansRemovalWithAgentSampling() usleep(333 * 2 * 1000); // DD_TRACE_AGENT_FLUSH_INTERVAL * 2 * 1000 } $response = $this->retrieveDumpedTraceData(); - $this->assertEquals(0, self::getSampling($response)); + $this->assertEquals(0, $this->getSampling($response)); $this->setResponse(["rate_by_service" => ["service:,env:" => 0.5]]); self::foo(); @@ -75,7 +73,7 @@ function testOrphansRemovalWithAgentSampling() usleep(333 * 2 * 1000); // DD_TRACE_AGENT_FLUSH_INTERVAL * 2 * 1000 } $response = $this->retrieveDumpedTraceData(); - $this->assertEquals(0, self::getSampling($response)); + $this->assertEquals(0, $this->getSampling($response)); }); } } diff --git a/tests/Integration/ResponseStatusCodeTest.php b/tests/Integration/ResponseStatusCodeTest.php index 8e5b1053661..b839d62ce67 100644 --- a/tests/Integration/ResponseStatusCodeTest.php +++ b/tests/Integration/ResponseStatusCodeTest.php @@ -35,12 +35,12 @@ function () { $this->assertExpectedSpans( $traces, [ - SpanAssertion::build('web.request', 'web.request', 'web', 'GET /success')->withExactTags([ + SpanAssertion::build('web.request', 'web.request', 'web', 'GET /success')->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/success', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ] ); @@ -61,13 +61,13 @@ function () { $this->assertExpectedSpans( $traces, [ - SpanAssertion::build('web.request', 'web.request', 'web', 'GET /error')->withExactTags( + SpanAssertion::build('web.request', 'web.request', 'web', 'GET /error')->withExactAttributes( [ 'http.method' => 'GET', 'http.url' => 'http://localhost/error', 'http.status_code' => '500', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ] )->setError(), ] diff --git a/tests/Integration/TracerTest.php b/tests/Integration/TracerTest.php index 27be186cadb..8d17232de57 100644 --- a/tests/Integration/TracerTest.php +++ b/tests/Integration/TracerTest.php @@ -43,10 +43,10 @@ public function testGlobalTagsArePresentOnLegacySpansByFlushTime() $scope->getSpan()->finish(); }); - $this->assertSame('custom.name', $traces[0][0]['name']); - $this->assertSame('local', $traces[0][0]['attributes']['local_tag']); - $this->assertSame('global', $traces[0][0]['attributes']['global_tag']); - $this->assertSame('span_wins', $traces[0][0]['attributes']['also_in_span']); + $this->assertSame('custom.name', $traces[0]['spans'][0]['name']); + $this->assertSame('local', $traces[0]['spans'][0]['attributes']['local_tag']); + $this->assertSame('global', $traces[0]['spans'][0]['attributes']['global_tag']); + $this->assertSame('span_wins', $traces[0]['spans'][0]['attributes']['also_in_span']); } public function testGlobalTagsArePresentOnInternalSpansByFlushTime() @@ -69,10 +69,10 @@ function (SpanData $span) { $test->dummyMethodGlobalTags(); }); - $this->assertSame('custom.name', $traces[0][0]['name']); - $this->assertSame('local', $traces[0][0]['attributes']['local_tag']); - $this->assertSame('global', $traces[0][0]['attributes']['global_tag']); - $this->assertSame('span_wins', $traces[0][0]['attributes']['also_in_span']); + $this->assertSame('custom.name', $traces[0]['spans'][0]['name']); + $this->assertSame('local', $traces[0]['spans'][0]['attributes']['local_tag']); + $this->assertSame('global', $traces[0]['spans'][0]['attributes']['global_tag']); + $this->assertSame('span_wins', $traces[0]['spans'][0]['attributes']['also_in_span']); } /** @@ -85,7 +85,7 @@ public function testResourceNormalizationCLILegacyApiExplicitViaOptionsDefault() $scope->close(); }, null, ['resource' => 'explicit']); - $this->assertSame('explicit', $traces[0][0]['resource']); + $this->assertSame('explicit', $traces[0]['spans'][0]['resource']); } /** @@ -98,7 +98,7 @@ public function testResourceNormalizationCLILegacyApiImplicitDefault() $scope->close(); }); - $this->assertSame('custom.operation', $traces[0][0]['resource']); + $this->assertSame('custom.operation', $traces[0]['spans'][0]['resource']); } /** @@ -112,7 +112,7 @@ public function testResourceNormalizationCLILegacyApiImplicitViaRequestToResourc $scope->close(); }); - $this->assertSame('custom.operation', $traces[0][0]['resource']); + $this->assertSame('custom.operation', $traces[0]['spans'][0]['resource']); } /** @@ -126,7 +126,7 @@ public function testResourceNormalizationCLILegacyApiImplicitViaRequestToResourc $scope->close(); }); - $this->assertSame('custom.operation', $traces[0][0]['resource']); + $this->assertSame('custom.operation', $traces[0]['spans'][0]['resource']); } /** @@ -152,7 +152,7 @@ function (SpanData $span) { $scope->close(); }); - $this->assertSame('custom.internal', $traces[0][1]['resource']); + $this->assertSame('custom.internal', $traces[0]['spans'][1]['resource']); } /** @@ -168,7 +168,7 @@ public function testResourceNormalizationNonRootSpanLegacyApi() $scope->close(); }); - $this->assertSame('custom.internal', $traces[0][1]['resource']); + $this->assertSame('custom.internal', $traces[0]['spans'][1]['resource']); } public function testResourceNormalizationWebDefault() @@ -184,7 +184,7 @@ function ($execute) { ] ); - $this->assertSame('GET /', $traces[0][0]['resource']); + $this->assertSame('GET /', $traces[0]['spans'][0]['resource']); } public function testResourceNormalizationWebON() @@ -201,7 +201,7 @@ function ($execute) { ] ); - $this->assertSame('GET /', $traces[0][0]['resource']); + $this->assertSame('GET /', $traces[0]['spans'][0]['resource']); } public function testResourceNormalizationWebOFF() @@ -218,7 +218,7 @@ function ($execute) { ] ); - $this->assertSame('web.request', $traces[0][0]['resource']); + $this->assertSame('web.request', $traces[0]['spans'][0]['resource']); } public function testResourceNormalizationWebHonorOverride() @@ -235,7 +235,7 @@ function ($execute) { ] ); - $this->assertSame('custom-resource', $traces[0][0]['resource']); + $this->assertSame('custom-resource', $traces[0]['spans'][0]['resource']); } public function testEnvironmentIsAddedToASpan() @@ -246,7 +246,7 @@ public function testEnvironmentIsAddedToASpan() $scope->close(); }); - $this->assertSame('my-env', $traces[0][0]['env']); + $this->assertSame('my-env', $traces[0]['spans'][0]['env']); } public function testEnvironmentIsOptional() @@ -257,7 +257,7 @@ public function testEnvironmentIsOptional() $scope->close(); }); - $this->assertTrue(empty($traces[0][0]['env'])); + $this->assertTrue(empty($traces[0]['spans'][0]['env'])); } public function testServiceVersionIsAddedToASpan() @@ -268,7 +268,7 @@ public function testServiceVersionIsAddedToASpan() $scope->close(); }); - $this->assertSame('1.2.3', $traces[0][0]['version']); + $this->assertSame('1.2.3', $traces[0]['spans'][0]['version']); } public function testServiceVersionIsOptional() @@ -279,7 +279,7 @@ public function testServiceVersionIsOptional() $scope->close(); }); - $this->assertTrue(empty($traces[0][0]['version'])); + $this->assertTrue(empty($traces[0]['spans'][0]['version'])); } public function testTracerReset() @@ -313,7 +313,7 @@ public function testTracerResetPreservesHooks() // exactly one preserved_hook self::assertSame(1, \count($traces)); - self::assertSame(1, \count($traces[0])); + self::assertSame(1, \count($traces[0]['spans'])); } public function testServiceMappingNoEnvMapping() @@ -324,7 +324,7 @@ public function testServiceMappingNoEnvMapping() $scope->close(); }); - $this->assertSame('original_service', $traces[0][0]['service']); + $this->assertSame('original_service', $traces[0]['spans'][0]['service']); } public function testServiceMappingRootSpan() @@ -337,7 +337,7 @@ public function testServiceMappingRootSpan() $scope->close(); }); - $this->assertSame('changed_service', $traces[0][0]['service']); + $this->assertSame('changed_service', $traces[0]['spans'][0]['service']); } public function testServiceMappingNestedSpanLegacyApi() @@ -354,8 +354,8 @@ public function testServiceMappingNestedSpanLegacyApi() $scope->close(); }); - $this->assertSame('root_service', $traces[0][0]['service']); - $this->assertSame('changed_service', $traces[0][1]['service']); + $this->assertSame('root_service', $traces[0]['spans'][0]['service']); + $this->assertSame('changed_service', $traces[0]['spans'][1]['service']); } public function testServiceMappingInternalApi() @@ -379,7 +379,7 @@ function (SpanData $span) { $test->dummyMethodServiceMappingInternalApi(); }); - $this->assertSame('changed_service', $traces[0][0]['service']); + $this->assertSame('changed_service', $traces[0]['spans'][0]['service']); } public function testServiceMappingHttpClientsSplitByDomainHost() @@ -397,7 +397,7 @@ function ($execute) { ] ); - $this->assertSame('changed_service', $traces[0][1]['service']); + $this->assertSame('changed_service', $traces[0]['spans'][1]['service']); } public function testServiceMappingHttpClientsSplitByDomainIp() @@ -415,7 +415,7 @@ function ($execute) { ] ); - $this->assertSame('changed_service', $traces[0][1]['service']); + $this->assertSame('changed_service', $traces[0]['spans'][1]['service']); } public function testBaseService() @@ -430,8 +430,8 @@ public function testBaseService() \DDTrace\close_span(); }); - $this->assertSame('changed_child', $traces[0][1]['service']); - $this->assertSame('original_service', $traces[0][1]['attributes']['_dd.base_service']); + $this->assertSame('changed_child', $traces[0]['spans'][1]['service']); + $this->assertSame('original_service', $traces[0]['spans'][1]['attributes']['_dd.base_service']); } public function testBaseServiceWithMapping() @@ -447,8 +447,8 @@ public function testBaseServiceWithMapping() \DDTrace\close_span(); }); - $this->assertSame('changed_child', $traces[0][1]['service']); - $this->assertSame('changed_service', $traces[0][1]['attributes']['_dd.base_service']); + $this->assertSame('changed_child', $traces[0]['spans'][1]['service']); + $this->assertSame('changed_service', $traces[0]['spans'][1]['attributes']['_dd.base_service']); } public function dummyMethodGlobalTags() diff --git a/tests/Integrations/AMQP/V2/AMQPTest.php b/tests/Integrations/AMQP/V2/AMQPTest.php index 155b9441239..b23a886a3e8 100644 --- a/tests/Integrations/AMQP/V2/AMQPTest.php +++ b/tests/Integrations/AMQP/V2/AMQPTest.php @@ -42,7 +42,7 @@ public function testConnectError() 'PhpAmqpLib\Exception\AMQPIOException', 'Connection refused', true - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -90,7 +90,7 @@ public function testHelloWorld() 'amqp', 'queue', 'connect' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -104,7 +104,7 @@ public function testHelloWorld() 'amqp', 'queue', 'queue.declare hello' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -119,7 +119,7 @@ public function testHelloWorld() 'amqp', 'queue', 'basic.consume hello' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -129,7 +129,7 @@ public function testHelloWorld() Tag::MQ_PROTOCOL_VERSION => AMQPChannel::getProtocolVersion(), Tag::MQ_OPERATION => 'receive', Tag::MQ_DESTINATION => 'hello', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::MQ_CONSUMER_ID ])->withChildren([ SpanAssertion::build( @@ -137,7 +137,7 @@ public function testHelloWorld() 'amqp', 'queue', 'basic.consume_ok' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'server', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -153,7 +153,7 @@ public function testHelloWorld() 'amqp', 'queue', 'connect' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -167,7 +167,7 @@ public function testHelloWorld() 'amqp', 'queue', 'queue.declare hello' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -182,7 +182,7 @@ public function testHelloWorld() 'amqp', 'queue', 'basic.publish -> hello' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'producer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -200,7 +200,7 @@ public function testHelloWorld() 'amqp', 'queue', 'basic.deliver -> hello' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'consumer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -212,18 +212,16 @@ public function testHelloWorld() Tag::MQ_MESSAGE_PAYLOAD_SIZE => 12, Tag::MQ_OPERATION => 'receive', Tag::RABBITMQ_EXCHANGE => '', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::MQ_CONSUMER_ID, - '_dd.span_links', - '_dd.p.tid' - ]) + ])->withSpanLinks() ]), SpanAssertion::build( 'amqp.basic.deliver', 'amqp', 'queue', 'basic.deliver -> hello' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'consumer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -235,10 +233,9 @@ public function testHelloWorld() Tag::MQ_MESSAGE_PAYLOAD_SIZE => 12, Tag::MQ_OPERATION => 'receive', Tag::RABBITMQ_EXCHANGE => '', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::MQ_CONSUMER_ID, - '_dd.span_links' - ]) + ])->withSpanLinks() ]); $this->assertTrue($receivedMessage); @@ -294,7 +291,7 @@ public function testRouting() 'amqp', 'queue', 'connect' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -308,7 +305,7 @@ public function testRouting() 'amqp', 'queue', 'exchange.declare direct_logs' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -323,7 +320,7 @@ public function testRouting() 'amqp', 'queue', 'queue.declare ' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -338,7 +335,7 @@ public function testRouting() 'amqp', 'queue', 'queue.bind direct_logs -> info' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -355,7 +352,7 @@ public function testRouting() 'amqp', 'queue', 'queue.bind direct_logs -> warning' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -372,7 +369,7 @@ public function testRouting() 'amqp', 'queue', 'queue.bind direct_logs -> error' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -389,7 +386,7 @@ public function testRouting() 'amqp', 'queue', 'basic.consume ' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -399,7 +396,7 @@ public function testRouting() Tag::MQ_PROTOCOL_VERSION => AMQPChannel::getProtocolVersion(), Tag::MQ_DESTINATION => '', Tag::MQ_OPERATION => 'receive', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::MQ_CONSUMER_ID ])->withChildren([ SpanAssertion::build( @@ -407,7 +404,7 @@ public function testRouting() 'amqp', 'queue', 'basic.consume_ok' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'server', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -423,7 +420,7 @@ public function testRouting() 'amqp', 'queue', 'connect' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -437,7 +434,7 @@ public function testRouting() 'amqp', 'queue', 'exchange.declare direct_logs' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -452,7 +449,7 @@ public function testRouting() 'amqp', 'queue', 'basic.publish direct_logs -> error' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'producer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -470,7 +467,7 @@ public function testRouting() 'amqp', 'queue', 'basic.deliver direct_logs -> error' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'consumer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -482,18 +479,16 @@ public function testRouting() Tag::RABBITMQ_ROUTING_KEY => 'error', Tag::MQ_MESSAGE_PAYLOAD_SIZE => 29, Tag::MQ_OPERATION => 'receive', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::MQ_CONSUMER_ID, - '_dd.span_links', - '_dd.p.tid' - ]) + ])->withSpanLinks() ]), SpanAssertion::build( 'amqp.basic.deliver', 'amqp', 'queue', 'basic.deliver direct_logs -> error' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'consumer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -505,10 +500,9 @@ public function testRouting() Tag::RABBITMQ_ROUTING_KEY => 'error', Tag::MQ_MESSAGE_PAYLOAD_SIZE => 29, Tag::MQ_OPERATION => 'receive', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::MQ_CONSUMER_ID, - '_dd.span_links' - ]) + ])->withSpanLinks() ]); $this->assertTrue($receivedMessage); @@ -539,7 +533,7 @@ public function testCancel() 'amqp', 'queue', 'connect' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -553,7 +547,7 @@ public function testCancel() 'amqp', 'queue', 'queue.declare hello' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -568,7 +562,7 @@ public function testCancel() 'amqp', 'queue', 'basic.consume hello' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -578,7 +572,7 @@ public function testCancel() Tag::MQ_PROTOCOL_VERSION => AMQPChannel::getProtocolVersion(), Tag::MQ_DESTINATION => 'hello', Tag::MQ_OPERATION => 'receive', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::MQ_CONSUMER_ID ])->withChildren([ SpanAssertion::build( @@ -586,7 +580,7 @@ public function testCancel() 'amqp', 'queue', 'basic.consume_ok' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'server', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -597,7 +591,7 @@ public function testCancel() Tag::MQ_OPERATION => 'process', ]) ]), - SpanAssertion::exists('amqp.basic.cancel')->withExactTags([ + SpanAssertion::exists('amqp.basic.cancel')->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -612,7 +606,7 @@ public function testCancel() 'amqp', 'queue', 'basic.cancel_ok' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'server', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -650,7 +644,7 @@ public function testPublishOnClosedChannel() 'amqp', 'queue', 'connect' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -664,7 +658,7 @@ public function testPublishOnClosedChannel() 'amqp', 'queue', 'queue.declare hello' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -679,7 +673,7 @@ public function testPublishOnClosedChannel() 'amqp', 'queue', 'basic.publish -> hello' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'producer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -694,7 +688,7 @@ public function testPublishOnClosedChannel() ])->setError( 'PhpAmqpLib\Exception\AMQPChannelClosedException', 'Channel connection is closed' - )->withExistingTagsNames([ + )->withExistingAttributeNames([ Tag::ERROR_STACK ]) ]); @@ -719,7 +713,7 @@ public function testReconnect() 'amqp', 'queue', 'connect' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -733,7 +727,7 @@ public function testReconnect() 'amqp', 'queue', 'queue.declare hello' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -748,7 +742,7 @@ public function testReconnect() 'amqp', 'queue', 'reconnect' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -762,7 +756,7 @@ public function testReconnect() 'amqp', 'queue', 'connect' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -803,7 +797,7 @@ public function testBasicGet() 'amqp', 'queue', 'connect' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -817,7 +811,7 @@ public function testBasicGet() 'amqp', 'queue', 'queue.declare basic_get_queue' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -832,7 +826,7 @@ public function testBasicGet() 'amqp', 'queue', 'exchange.declare basic_get_test' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -847,7 +841,7 @@ public function testBasicGet() 'amqp', 'queue', 'queue.bind basic_get_queue basic_get_test -> ' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -864,7 +858,7 @@ public function testBasicGet() 'amqp', 'queue', 'basic.publish basic_get_test -> ' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'producer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -876,14 +870,14 @@ public function testBasicGet() Tag::MQ_OPERATION => 'send', Tag::RABBITMQ_ROUTING_KEY => '', Tag::RABBITMQ_EXCHANGE => 'basic_get_test', - Tag::RABBITMQ_DELIVERY_MODE => '2' + Tag::RABBITMQ_DELIVERY_MODE => 2 ]), SpanAssertion::build( 'amqp.basic.get', 'amqp', 'queue', 'basic.get basic_get_queue' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'consumer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -896,16 +890,14 @@ public function testBasicGet() Tag::MQ_OPERATION => 'receive', Tag::RABBITMQ_ROUTING_KEY => '', Tag::RABBITMQ_EXCHANGE => 'basic_get_test', - Tag::RABBITMQ_DELIVERY_MODE => '2' - ])->withExistingTagsNames([ - '_dd.span_links' - ]), + Tag::RABBITMQ_DELIVERY_MODE => 2 + ])->withSpanLinks(), SpanAssertion::build( 'amqp.basic.ack', 'amqp', 'queue', 'basic.ack 1' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'process', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -950,20 +942,20 @@ public function testDistributedTracing() // Assess that user headers weren't lost $this->assertSame("", trim(preg_replace("(.*\[ddtrace].*)", "", $output))); - $sendTraces = $sendTraces[0][0]; // There is a root span + $sendTrace = $sendTraces[0][0]; // There is a root span // Spans: send.php -> basic_publish -> queue_declare -> connect - $basicPublishSpan = $sendTraces[1]; + $basicPublishSpan = $sendTrace['spans'][1]; foreach ($receiveTraces as $receiveTrace) { // Spans: connect -> queue_declare -> basic_consume & basic_consume_ok -> basic_deliver - if ($receiveTrace[0]["name"] == "amqp.basic.deliver" && isset($receiveTrace[0]["parent_id"])) { - $basicDeliverSpan = $receiveTrace[0]; + if ($receiveTrace['spans'][0]["name"] == "amqp.basic.deliver" && isset($receiveTrace['spans'][0]["parent_id"])) { + $basicDeliverTrace = $receiveTrace; break; } } - $this->assertSame($basicPublishSpan['trace_id'], $basicDeliverSpan['trace_id']); - $this->assertSame($basicPublishSpan['span_id'], $basicDeliverSpan['parent_id']); + $this->assertSame($sendTrace['trace_id'], $basicDeliverTrace['trace_id']); + $this->assertSame($basicPublishSpan['span_id'], $basicDeliverTrace['spans'][0]['parent_id']); } public function testDistributedTracingIsNotPropagatedIfDisabled() @@ -997,15 +989,13 @@ public function testDistributedTracingIsNotPropagatedIfDisabled() // Assess that user headers weren't lost $this->assertSame("", trim(preg_replace("(.*\[ddtrace].*)", "", $output))); - $sendTraces = $sendTraces[0][0]; // There is a root span - // Spans: send.php -> basic_publish -> queue_declare -> connect - $basicPublishSpan = $sendTraces[1]; + $sendTrace = $sendTraces[0][0]; // There is a root span - $receiveTraces = $receiveTraces[3]; // There isn't a root span + $receiveTrace = $receiveTraces[3]; // There isn't a root span // Spans: connect -> queue_declare -> basic_consume & basic_consume_ok -> basic_deliver - $basicDeliverSpan = $receiveTraces[0]; + $basicDeliverSpan = $receiveTrace['spans'][0]; - $this->assertNotSame($basicPublishSpan['trace_id'], $basicDeliverSpan['trace_id']); + $this->assertNotSame($sendTrace['trace_id'], $receiveTrace['trace_id']); $this->assertArrayNotHasKey('parent_id', $basicDeliverSpan); } @@ -1034,7 +1024,7 @@ public function testBatchedPublishing() 'amqp', 'queue', 'connect' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -1048,7 +1038,7 @@ public function testBatchedPublishing() 'amqp', 'queue', 'queue.declare hello-1' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -1063,7 +1053,7 @@ public function testBatchedPublishing() 'amqp', 'queue', 'queue.declare hello-2' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -1078,7 +1068,7 @@ public function testBatchedPublishing() 'amqp', 'queue', 'batch_basic.add -> hello-1' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'producer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -1095,7 +1085,7 @@ public function testBatchedPublishing() 'amqp', 'queue', 'batch_basic.add -> hello-2' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'producer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', @@ -1112,7 +1102,7 @@ public function testBatchedPublishing() 'amqp', 'queue', 'publish_batch' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'producer', Tag::COMPONENT => 'amqp', '_dd.svc_src' => 'amqp', diff --git a/tests/Integrations/CLI/CakePHP/V2_8/CommonScenariosTest.php b/tests/Integrations/CLI/CakePHP/V2_8/CommonScenariosTest.php index dcd31525a56..9f4af71fcb1 100644 --- a/tests/Integrations/CLI/CakePHP/V2_8/CommonScenariosTest.php +++ b/tests/Integrations/CLI/CakePHP/V2_8/CommonScenariosTest.php @@ -31,7 +31,7 @@ public function testCommandWithNoArguments() 'cake_console_test_app', 'cli', 'cake_console' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]) ]); @@ -47,7 +47,7 @@ public function testCommandWithArgument() 'cake_console_test_app', 'cli', 'cake_console command_list' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]) ]); @@ -68,7 +68,7 @@ public function testCommandWithError() 'cake_console_test_app', 'cli', 'cake_console foo_error' - )->withExistingTagsNames([ + )->withExistingAttributeNames([ 'error.message', 'error.stack' ])->setError() diff --git a/tests/Integrations/CLI/CakePHP/V3_10/CommonScenariosTest.php b/tests/Integrations/CLI/CakePHP/V3_10/CommonScenariosTest.php index 140c64eb4ee..06f6ec60d8f 100644 --- a/tests/Integrations/CLI/CakePHP/V3_10/CommonScenariosTest.php +++ b/tests/Integrations/CLI/CakePHP/V3_10/CommonScenariosTest.php @@ -31,7 +31,7 @@ public function testCommandWithNoArguments() 'cake_console_test_app', 'cli', 'cake_console' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]) ]); @@ -47,7 +47,7 @@ public function testCommandWithArgument() 'cake_console_test_app', 'cli', 'cake_console routes' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]) ]); diff --git a/tests/Integrations/CLI/Custom/Autoloaded/NoRootSpanTest.php b/tests/Integrations/CLI/Custom/Autoloaded/NoRootSpanTest.php index b64516caf89..9ea40847983 100644 --- a/tests/Integrations/CLI/Custom/Autoloaded/NoRootSpanTest.php +++ b/tests/Integrations/CLI/Custom/Autoloaded/NoRootSpanTest.php @@ -36,14 +36,14 @@ public function testCommandWillAutoFlush() 'foo_service', 'custom', 'foo_resource' - )->withExactTags([ + )->withExactAttributes([ 'foo' => 'bar', '_dd.code_origin.frames.0.method' => 'my_app', '_dd.code_origin.type' => 'entry', - '_dd.code_origin.frames.1.line' => '30', + '_dd.code_origin.frames.1.line' => 30, '_dd.code_origin.frames.1.file' => '%s', '_dd.code_origin.frames.0.file' => '%s', - '_dd.code_origin.frames.0.line' => '6', + '_dd.code_origin.frames.0.line' => 6, '_dd.svc_src' => 'm', ])->withChildren([ SpanAssertion::exists( diff --git a/tests/Integrations/CLI/Laravel/Latest/CommonScenariosTest.php b/tests/Integrations/CLI/Laravel/Latest/CommonScenariosTest.php index 8a63dd917a9..d3d42decb52 100644 --- a/tests/Integrations/CLI/Laravel/Latest/CommonScenariosTest.php +++ b/tests/Integrations/CLI/Laravel/Latest/CommonScenariosTest.php @@ -38,7 +38,7 @@ public function testCommandWithNoArguments() 'artisan_test_app', 'cli', 'artisan' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -78,7 +78,7 @@ public function testCommandWithArgument() 'artisan_test_app', 'cli', 'artisan route:list' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -118,10 +118,10 @@ public function testCommandWithError() 'artisan_test_app', 'cli', 'artisan foo:error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::ERROR_MSG, 'error.stack' ])->withChildren([ diff --git a/tests/Integrations/CLI/Laravel/V10_X/CommonScenariosTest.php b/tests/Integrations/CLI/Laravel/V10_X/CommonScenariosTest.php index b20d92dc85d..78a87799e83 100644 --- a/tests/Integrations/CLI/Laravel/V10_X/CommonScenariosTest.php +++ b/tests/Integrations/CLI/Laravel/V10_X/CommonScenariosTest.php @@ -25,10 +25,10 @@ public function testCommandWithError() 'artisan_test_app', 'cli', 'artisan foo:error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::ERROR_MSG, 'error.stack' ])->withChildren([ diff --git a/tests/Integrations/CLI/Laravel/V5_8/CommonScenariosTest.php b/tests/Integrations/CLI/Laravel/V5_8/CommonScenariosTest.php index 69b4fa2a27f..3c027d53ffb 100644 --- a/tests/Integrations/CLI/Laravel/V5_8/CommonScenariosTest.php +++ b/tests/Integrations/CLI/Laravel/V5_8/CommonScenariosTest.php @@ -31,7 +31,7 @@ public function testCommandWithNoArguments() 'artisan_test_app', 'cli', 'artisan' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -70,7 +70,7 @@ public function testCommandWithArgument() 'artisan_test_app', 'cli', 'artisan route:list' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -109,10 +109,10 @@ public function testCommandWithError() 'artisan_test_app', 'cli', 'artisan foo:error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::ERROR_MSG, 'error.stack' ])->withChildren([ diff --git a/tests/Integrations/CLI/Laravel/V8_X/CommonScenariosTest.php b/tests/Integrations/CLI/Laravel/V8_X/CommonScenariosTest.php index fe473e7979c..138b136de3b 100644 --- a/tests/Integrations/CLI/Laravel/V8_X/CommonScenariosTest.php +++ b/tests/Integrations/CLI/Laravel/V8_X/CommonScenariosTest.php @@ -38,7 +38,7 @@ public function testCommandWithNoArguments() 'artisan_test_app', 'cli', 'artisan' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -77,7 +77,7 @@ public function testCommandWithArgument() 'artisan_test_app', 'cli', 'artisan route:list' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -116,10 +116,10 @@ public function testCommandWithError() 'artisan_test_app', 'cli', 'artisan foo:error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::ERROR_MSG, 'error.stack' ])->withChildren([ diff --git a/tests/Integrations/CLI/Laravel/V9_X/CommonScenariosTest.php b/tests/Integrations/CLI/Laravel/V9_X/CommonScenariosTest.php index 4987fb4a915..eda6cf66c2c 100644 --- a/tests/Integrations/CLI/Laravel/V9_X/CommonScenariosTest.php +++ b/tests/Integrations/CLI/Laravel/V9_X/CommonScenariosTest.php @@ -38,7 +38,7 @@ public function testCommandWithNoArguments() 'artisan_test_app', 'cli', 'artisan' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -78,7 +78,7 @@ public function testCommandWithArgument() 'artisan_test_app', 'cli', 'artisan route:list' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -118,10 +118,10 @@ public function testCommandWithError() 'artisan_test_app', 'cli', 'artisan foo:error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::ERROR_MSG, 'error.stack' ])->withChildren([ diff --git a/tests/Integrations/CLI/Symfony/V4_4/CommonScenariosTest.php b/tests/Integrations/CLI/Symfony/V4_4/CommonScenariosTest.php index cac535a8d45..31e779c56e7 100644 --- a/tests/Integrations/CLI/Symfony/V4_4/CommonScenariosTest.php +++ b/tests/Integrations/CLI/Symfony/V4_4/CommonScenariosTest.php @@ -14,7 +14,7 @@ class CommonScenariosTest extends IntegrationTestCase 'metrics.php.memory.peak_real_usage_bytes', 'meta.error.stack', 'meta._dd.p.tid', - 'meta.cmd.exit_code', + 'metrics.cmd.exit_code', ]; public static function getConsoleScript() @@ -24,14 +24,16 @@ public static function getConsoleScript() public function testSilencedSpansAreDropped() { - list($traces) = $this->inCli(static::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_GENERATE_ROOT_SPAN' => 'true', - 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'true', - ], [], 'app:stty', false, null, true, true); - - $this->snapshotFromTraces($traces, self::FIELDS_TO_IGNORE); + $this->snapshotFromTraces(function () { + list($traces) = $this->inCli(static::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_GENERATE_ROOT_SPAN' => 'true', + 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'true', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], 'app:stty', false, null, true, true); + return $traces; + }, self::FIELDS_TO_IGNORE); } public function testThrowCommand() @@ -57,7 +59,7 @@ public function testThrowCommand() 'symfony', 'cli', 'symfony.console.terminate' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -67,7 +69,7 @@ public function testThrowCommand() 'symfony', 'cli', 'app:throw' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', 'symfony.console.command.class' => 'App\\Command\\ThrowCommand', @@ -82,7 +84,7 @@ public function testThrowCommand() 'symfony', 'cli', 'symfony.console.error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -92,7 +94,7 @@ public function testThrowCommand() 'symfony', 'cli', 'symfony.console.command' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -102,7 +104,7 @@ public function testThrowCommand() 'symfony', 'web', 'App\Kernel' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -135,7 +137,7 @@ public function testCommand() 'symfony', 'cli', 'symfony.console.terminate' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -145,7 +147,7 @@ public function testCommand() 'symfony', 'cli', 'about' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', 'symfony.console.command.class' => 'Symfony\Bundle\FrameworkBundle\Command\AboutCommand', @@ -156,7 +158,7 @@ public function testCommand() 'symfony', 'cli', 'symfony.console.command' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -166,7 +168,7 @@ public function testCommand() 'symfony', 'web', 'App\Kernel' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', diff --git a/tests/Integrations/CLI/Symfony/V5_2/CommonScenariosTest.php b/tests/Integrations/CLI/Symfony/V5_2/CommonScenariosTest.php index 8efa79b1f7b..fcb4ec8e25f 100644 --- a/tests/Integrations/CLI/Symfony/V5_2/CommonScenariosTest.php +++ b/tests/Integrations/CLI/Symfony/V5_2/CommonScenariosTest.php @@ -14,7 +14,7 @@ class CommonScenariosTest extends IntegrationTestCase 'metrics.php.memory.peak_real_usage_bytes', 'meta.error.stack', 'meta._dd.p.tid', - 'meta.cmd.exit_code', + 'metrics.cmd.exit_code', ]; public static function getConsoleScript() @@ -24,14 +24,16 @@ public static function getConsoleScript() public function testSilencedSpansAreDropped() { - list($traces) = $this->inCli(static::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_GENERATE_ROOT_SPAN' => 'true', - 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'true', - ], [], 'app:stty', false, null, true, true); - - $this->snapshotFromTraces($traces, self::FIELDS_TO_IGNORE); + $this->snapshotFromTraces(function () { + list($traces) = $this->inCli(static::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_GENERATE_ROOT_SPAN' => 'true', + 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'true', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], 'app:stty', false, null, true, true); + return $traces; + }, self::FIELDS_TO_IGNORE); } public function testThrowCommand() @@ -57,7 +59,7 @@ public function testThrowCommand() 'symfony', 'cli', 'symfony.console.terminate' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -67,7 +69,7 @@ public function testThrowCommand() 'symfony', 'cli', 'app:throw' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', 'symfony.console.command.class' => 'App\\Command\\ThrowCommand', @@ -82,7 +84,7 @@ public function testThrowCommand() 'symfony', 'cli', 'symfony.console.error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -92,7 +94,7 @@ public function testThrowCommand() 'symfony', 'cli', 'symfony.console.command' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -102,7 +104,7 @@ public function testThrowCommand() 'symfony', 'web', 'App\Kernel' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -135,7 +137,7 @@ public function testCommand() 'symfony', 'cli', 'symfony.console.terminate' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -145,7 +147,7 @@ public function testCommand() 'symfony', 'cli', 'about' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', 'symfony.console.command.class' => 'Symfony\Bundle\FrameworkBundle\Command\AboutCommand', @@ -156,7 +158,7 @@ public function testCommand() 'symfony', 'cli', 'symfony.console.command' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -166,7 +168,7 @@ public function testCommand() 'symfony', 'web', 'App\Kernel' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', diff --git a/tests/Integrations/CLI/Symfony/V6_2/CommonScenariosTest.php b/tests/Integrations/CLI/Symfony/V6_2/CommonScenariosTest.php index 858d3cdb716..2a1cbcc9a62 100644 --- a/tests/Integrations/CLI/Symfony/V6_2/CommonScenariosTest.php +++ b/tests/Integrations/CLI/Symfony/V6_2/CommonScenariosTest.php @@ -14,7 +14,7 @@ class CommonScenariosTest extends IntegrationTestCase 'metrics.php.memory.peak_real_usage_bytes', 'meta.error.stack', 'meta._dd.p.tid', - 'meta.cmd.exit_code', + 'metrics.cmd.exit_code', ]; public static function getConsoleScript() @@ -29,14 +29,16 @@ public static function getTestedLibrary() public function testSilencedSpansAreDropped() { - list($traces) = $this->inCli(static::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_GENERATE_ROOT_SPAN' => 'true', - 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'true', - ], [], 'app:stty', false, null, true, true); - - $this->snapshotFromTraces($traces, self::FIELDS_TO_IGNORE); + $this->snapshotFromTraces(function () { + list($traces) = $this->inCli(static::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_GENERATE_ROOT_SPAN' => 'true', + 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'true', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], 'app:stty', false, null, true, true); + return $traces; + }, self::FIELDS_TO_IGNORE); } public function testThrowCommand() @@ -62,7 +64,7 @@ public function testThrowCommand() 'symfony', 'cli', 'symfony.console.terminate' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -72,7 +74,7 @@ public function testThrowCommand() 'symfony', 'cli', 'app:throw' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', 'symfony.console.command.class' => 'App\\Command\\ThrowCommand', @@ -87,7 +89,7 @@ public function testThrowCommand() 'symfony', 'cli', 'symfony.console.error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -97,7 +99,7 @@ public function testThrowCommand() 'symfony', 'cli', 'symfony.console.command' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -107,7 +109,7 @@ public function testThrowCommand() 'symfony', 'web', 'App\Kernel' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -140,7 +142,7 @@ public function testCommand() 'symfony', 'cli', 'symfony.console.terminate' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -150,7 +152,7 @@ public function testCommand() 'symfony', 'cli', 'about' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', 'symfony.console.command.class' => 'Symfony\Bundle\FrameworkBundle\Command\AboutCommand', @@ -161,7 +163,7 @@ public function testCommand() 'symfony', 'cli', 'symfony.console.command' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', @@ -171,7 +173,7 @@ public function testCommand() 'symfony', 'web', 'App\Kernel' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', '_dd.base_service' => 'console', diff --git a/tests/Integrations/CakePHP/V2_8/CommonScenariosTest.php b/tests/Integrations/CakePHP/V2_8/CommonScenariosTest.php index 506df7debe9..b0c5ed18f05 100644 --- a/tests/Integrations/CakePHP/V2_8/CommonScenariosTest.php +++ b/tests/Integrations/CakePHP/V2_8/CommonScenariosTest.php @@ -51,7 +51,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET SimpleController@index' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'simple', 'cakephp.route.action' => 'index', 'http.method' => 'GET', @@ -66,7 +66,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]) ]), @@ -77,7 +77,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET SimpleViewController@index' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'simple_view', 'cakephp.route.action' => 'index', 'http.method' => 'GET', @@ -92,7 +92,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]), SpanAssertion::build( @@ -100,7 +100,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'SimpleView/index.ctp' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.view' => 'SimpleView/index.ctp', Tag::COMPONENT => 'cakephp', ]), @@ -112,7 +112,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET ErrorController@index' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'error', 'cakephp.route.action' => 'index', 'http.method' => 'GET', @@ -121,7 +121,7 @@ public function provideSpecs() 'http.route' => '/:controller', Tag::SPAN_KIND => 'server', Tag::COMPONENT => 'cakephp', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack' ])->setError( null, @@ -132,9 +132,9 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack', ])->setError(null, 'Foo error'), SpanAssertion::build( @@ -142,7 +142,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Errors/index.ctp' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.view' => 'Errors/index.ctp', Tag::COMPONENT => 'cakephp', ]), @@ -154,7 +154,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET ParameterizedController@customAction' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'Parameterized', 'cakephp.route.action' => 'customAction', 'http.method' => 'GET', @@ -169,7 +169,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]) ]), diff --git a/tests/Integrations/CakePHP/V3_10/CommonScenariosTest.php b/tests/Integrations/CakePHP/V3_10/CommonScenariosTest.php index 76a6440d449..7df82d21549 100644 --- a/tests/Integrations/CakePHP/V3_10/CommonScenariosTest.php +++ b/tests/Integrations/CakePHP/V3_10/CommonScenariosTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET SimpleController@index' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'Simple', 'cakephp.route.action' => 'index', 'http.method' => 'GET', @@ -67,7 +67,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]) ]), @@ -78,7 +78,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET Simple_viewController@index' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'Simple_view', 'cakephp.route.action' => 'index', 'http.method' => 'GET', @@ -93,7 +93,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]), SpanAssertion::build( @@ -101,7 +101,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Simple_view/index.ctp' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.view' => 'Simple_view/index.ctp', Tag::COMPONENT => 'cakephp', ]), @@ -113,7 +113,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET ErrorController@index' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'Error', 'cakephp.route.action' => 'index', 'http.method' => 'GET', @@ -122,7 +122,7 @@ public function provideSpecs() 'http.route' => '/{controller}', Tag::SPAN_KIND => 'server', Tag::COMPONENT => 'cakephp', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack' ])->setError( 'Exception', @@ -133,9 +133,9 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack', ])->setError('Exception', 'Foo error'), SpanAssertion::build( @@ -143,7 +143,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Error/index.ctp' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.view' => 'Error/index.ctp', Tag::COMPONENT => 'cakephp', ]), @@ -155,7 +155,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET ParameterizedController@customAction' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'Parameterized', 'cakephp.route.action' => 'customAction', 'http.method' => 'GET', @@ -170,7 +170,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]) ]), diff --git a/tests/Integrations/CakePHP/V4_5/CommonScenariosTest.php b/tests/Integrations/CakePHP/V4_5/CommonScenariosTest.php index f1e85015734..15215772230 100644 --- a/tests/Integrations/CakePHP/V4_5/CommonScenariosTest.php +++ b/tests/Integrations/CakePHP/V4_5/CommonScenariosTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET SimpleController@index' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'Simple', 'cakephp.route.action' => 'index', 'http.method' => 'GET', @@ -67,7 +67,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]) ]), @@ -78,7 +78,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET Simple_viewController@index' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'Simple_view', 'cakephp.route.action' => 'index', 'http.method' => 'GET', @@ -93,7 +93,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ])->withChildren([ SpanAssertion::build( @@ -101,7 +101,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Simple_view/index.php' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.view' => 'Simple_view/index.php', Tag::COMPONENT => 'cakephp', ]), @@ -114,7 +114,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET ErrorController@index' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'Error', 'cakephp.route.action' => 'index', 'http.method' => 'GET', @@ -123,7 +123,7 @@ public function provideSpecs() 'http.route' => '/{controller}', Tag::SPAN_KIND => 'server', Tag::COMPONENT => 'cakephp', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack' ])->setError( 'Exception', @@ -134,9 +134,9 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack', ])->setError('Exception', 'Foo error'), SpanAssertion::build( @@ -144,7 +144,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Error/error500.php' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.view' => 'Error/error500.php', Tag::COMPONENT => 'cakephp', ]), @@ -156,7 +156,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'GET ParameterizedController@customAction' - )->withExactTags([ + )->withExactAttributes([ 'cakephp.route.controller' => 'Parameterized', 'cakephp.route.action' => 'customAction', 'http.method' => 'GET', @@ -171,7 +171,7 @@ public function provideSpecs() 'cakephp_test_app', 'web', 'Controller.invokeAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'cakephp', ]) ]), diff --git a/tests/Integrations/CodeIgniter/V2_2/CommonScenariosTest.php b/tests/Integrations/CodeIgniter/V2_2/CommonScenariosTest.php index 69e022c6fc8..3d11b3495ee 100644 --- a/tests/Integrations/CodeIgniter/V2_2/CommonScenariosTest.php +++ b/tests/Integrations/CodeIgniter/V2_2/CommonScenariosTest.php @@ -48,7 +48,7 @@ public function provideSpecs() 'codeigniter_test_app', 'web', 'GET /simple' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/simple?key=value&', Tag::HTTP_STATUS_CODE => '200', @@ -62,7 +62,7 @@ public function provideSpecs() 'codeigniter_test_app', Type::WEB_SERVLET, 'Simple.index' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'codeigniter', ]) ]), @@ -73,7 +73,7 @@ public function provideSpecs() 'codeigniter_test_app', 'web', 'GET /simple_view' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/simple_view?key=value&', Tag::HTTP_STATUS_CODE => '200', @@ -87,7 +87,7 @@ public function provideSpecs() 'codeigniter_test_app', Type::WEB_SERVLET, 'Simple_View.index' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'codeigniter', ])->withChildren([ SpanAssertion::build( @@ -95,7 +95,7 @@ public function provideSpecs() 'codeigniter_test_app', Type::WEB_SERVLET, 'simple_view' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'codeigniter', ]), ]) @@ -107,7 +107,7 @@ public function provideSpecs() 'codeigniter_test_app', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/error?key=value&', // CodeIgniter's error handler does not adjust the status code @@ -118,14 +118,14 @@ public function provideSpecs() Tag::HTTP_ROUTE => 'error' ]) ->setError("Exception", "Uncaught Exception: datadog in %s:%d") - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::build( 'Error_.index', 'codeigniter_test_app', Type::WEB_SERVLET, 'Error_.index' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'codeigniter', ])->setError('Exception', 'datadog', true), ]), @@ -136,7 +136,7 @@ public function provideSpecs() 'codeigniter_test_app', 'web', 'GET /parameterized/paramValue' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/parameterized/paramValue', Tag::HTTP_STATUS_CODE => '200', @@ -150,7 +150,7 @@ public function provideSpecs() 'codeigniter_test_app', Type::WEB_SERVLET, 'Parameterized.customAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'codeigniter', ]) ]), diff --git a/tests/Integrations/CodeIgniter/V2_2/ExitTest.php b/tests/Integrations/CodeIgniter/V2_2/ExitTest.php index c7d0603228b..4df7eb5cdcd 100644 --- a/tests/Integrations/CodeIgniter/V2_2/ExitTest.php +++ b/tests/Integrations/CodeIgniter/V2_2/ExitTest.php @@ -36,7 +36,7 @@ public function testScenario() 'codeigniter_test_app', 'web', 'GET /exits' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/exits', Tag::HTTP_STATUS_CODE => '200', @@ -50,7 +50,7 @@ public function testScenario() 'codeigniter_test_app', Type::WEB_SERVLET, 'Exits.index' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'codeigniter', ]) ]) diff --git a/tests/Integrations/CodeIgniter/V2_2/NoCI_ControllertTest.php b/tests/Integrations/CodeIgniter/V2_2/NoCI_ControllertTest.php index ebdee1225e2..61b3033c0f6 100644 --- a/tests/Integrations/CodeIgniter/V2_2/NoCI_ControllertTest.php +++ b/tests/Integrations/CodeIgniter/V2_2/NoCI_ControllertTest.php @@ -36,7 +36,7 @@ public function testScenario() 'codeigniter_test_app', 'web', 'GET /health_check/ping' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/health_check/ping', Tag::HTTP_STATUS_CODE => '200', @@ -49,7 +49,7 @@ public function testScenario() 'codeigniter_test_app', Type::WEB_SERVLET, 'Health_check.ping' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'codeigniter', ]) ]), diff --git a/tests/Integrations/Curl/CurlIntegrationTest.php b/tests/Integrations/Curl/CurlIntegrationTest.php index 3b914b393da..e708dec38e5 100644 --- a/tests/Integrations/Curl/CurlIntegrationTest.php +++ b/tests/Integrations/Curl/CurlIntegrationTest.php @@ -6,6 +6,7 @@ use DDTrace\Sampling\PrioritySampling; use DDTrace\Tests\Common\IntegrationTestCase; use DDTrace\Tests\Common\SpanAssertion; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; class PrivateCallbackRequest @@ -84,7 +85,7 @@ public function testLoad200UrlOnInit() $this->assertSpans($traces, [ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://' . HTTPBIN_INTEGRATION . '/status/?') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => self::URL . '/status/200', 'http.status_code' => '200', 'span.kind' => 'client', @@ -92,8 +93,8 @@ public function testLoad200UrlOnInit() Tag::COMPONENT => 'curl', '_dd.svc_src' => 'curl', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), ]); } @@ -110,7 +111,7 @@ public function testLoad200UrlAsOpt() $this->assertSpans($traces, [ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://' . HTTPBIN_INTEGRATION . '/status/?') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => self::URL . '/status/200', 'http.status_code' => '200', 'span.kind' => 'client', @@ -118,8 +119,8 @@ public function testLoad200UrlAsOpt() Tag::COMPONENT => 'curl', '_dd.svc_src' => 'curl', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), ]); } @@ -136,7 +137,7 @@ public function testInlineCredentials() $this->assertSpans($traces, [ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://?:?@' . HTTPBIN_INTEGRATION . '/basic-auth/my_user/my_password') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => 'http://?:?@' . HTTPBIN_INTEGRATION . '/basic-auth/my_user/my_password', 'http.status_code' => '200', 'span.kind' => 'client', @@ -144,8 +145,8 @@ public function testInlineCredentials() Tag::COMPONENT => 'curl', '_dd.svc_src' => 'curl', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), ]); } @@ -163,7 +164,7 @@ public function testCredentialsViaBasicAuth() $this->assertSpans($traces, [ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://' . HTTPBIN_INTEGRATION . '/basic-auth/my_user/my_password') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => self::URL . '/basic-auth/my_user/my_password', 'http.status_code' => '200', 'span.kind' => 'client', @@ -171,8 +172,8 @@ public function testCredentialsViaBasicAuth() Tag::COMPONENT => 'curl', '_dd.svc_src' => 'curl', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), ]); } @@ -192,10 +193,10 @@ function ($execute) { $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', 'component']) + ->withExistingAttributeNames(['http.method', 'http.url', 'http.status_code', 'span.kind', 'component']) ->withChildren([ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://' . HTTPBIN_INTEGRATION . '/status/?') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => self::URL . '/status/200', 'http.status_code' => '200', 'span.kind' => 'client', @@ -204,8 +205,8 @@ function ($execute) { '_dd.svc_src' => 'curl', '_dd.base_service' => 'top_level_app', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), ]), ]); } @@ -220,7 +221,7 @@ public function testPrivateCallbackForResponseHeaders() $this->assertSpans($traces, [ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://' . HTTPBIN_INTEGRATION . '/status/?') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => self::URL . '/status/200', 'http.status_code' => '200', 'span.kind' => 'client', @@ -228,8 +229,8 @@ public function testPrivateCallbackForResponseHeaders() Tag::COMPONENT => 'curl', '_dd.svc_src' => 'curl', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), ]); } @@ -246,7 +247,7 @@ public function testLoad404UrlOnInit() $this->assertSpans($traces, [ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://' . HTTPBIN_INTEGRATION . '/status/?') ->setError('http_error', 'HTTP 404 Error') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => self::URL . '/status/404', 'http.status_code' => '404', 'span.kind' => 'client', @@ -254,8 +255,8 @@ public function testLoad404UrlOnInit() Tag::COMPONENT => 'curl', '_dd.svc_src' => 'curl', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), ]); } @@ -271,7 +272,7 @@ public function testLoadUnroutableIP() $this->assertSpans($traces, [ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://10.255.255.1/') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => 'http://10.255.255.1/', 'http.status_code' => '0', 'span.kind' => 'client', @@ -279,10 +280,10 @@ public function testLoadUnroutableIP() Tag::COMPONENT => 'curl', '_dd.svc_src' => 'curl', ]) - ->withExistingTagsNames([Tag::ERROR_MSG]) - ->withExistingTagsNames([Tag::ERROR_STACK]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/') + ->withExistingAttributeNames([Tag::ERROR_MSG]) + ->withExistingAttributeNames([Tag::ERROR_STACK]) + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/') ->setError('curl error'), ]); } @@ -299,7 +300,7 @@ public function testLoadOperationTimeout() $this->assertSpans($traces, [ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://10.255.255.1/') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => 'http://10.255.255.1/', 'http.status_code' => '0', 'span.kind' => 'client', @@ -307,10 +308,10 @@ public function testLoadOperationTimeout() Tag::COMPONENT => 'curl', '_dd.svc_src' => 'curl', ]) - ->withExistingTagsNames([Tag::ERROR_MSG]) - ->withExistingTagsNames([Tag::ERROR_STACK]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/') + ->withExistingAttributeNames([Tag::ERROR_MSG]) + ->withExistingAttributeNames([Tag::ERROR_STACK]) + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/') ->setError('curl error'), ]); } @@ -327,7 +328,7 @@ public function testNonExistingHost() $this->assertSpans($traces, [ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://__i_am_not_real__.invalid/') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => 'http://__i_am_not_real__.invalid/', 'http.status_code' => '0', 'span.kind' => 'client', @@ -335,8 +336,8 @@ public function testNonExistingHost() Tag::COMPONENT => 'curl', '_dd.svc_src' => 'curl', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/') + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/') ->setError('curl error', 'Could not resolve host: __i_am_not_real__.invalid', true), ]); } @@ -365,7 +366,7 @@ function ($execute) use (&$found) { ); $this->assertSame('foo_origin', $found['headers']['X-Datadog-Origin']); - $this->assertSame('foo_origin', $traces[0][0]['meta']['_dd.origin']); + $this->assertSame('foo_origin', $traces[0]['origin']); } public function testDistributedTracingIsPropagatedOnCopiedHandle() @@ -389,9 +390,9 @@ function ($execute) use (&$found) { ); // trace is: custom - $this->assertSame($traces[0][0]['trace_id'], $found['headers']['X-Datadog-Trace-Id']); + $this->assertSame(SpanChecker::traceIdLow($traces[0]), $found['headers']['X-Datadog-Trace-Id']); // parent is: curl_exec - $this->assertSame($traces[0][1]['span_id'], $found['headers']['X-Datadog-Parent-Id']); + $this->assertSame($traces[0]['spans'][1]['span_id'], $found['headers']['X-Datadog-Parent-Id']); $this->assertSame('1', $found['headers']['X-Datadog-Sampling-Priority']); // existing headers are honored $this->assertSame('preserved_value', $found['headers']['Honored']); @@ -450,12 +451,12 @@ function ($execute) use (&$found) { // existing headers are honored $this->assertSame('preserved_value', $found['headers']['Honored']); - $this->assertEquals(1, sizeof($traces[0])); + $this->assertEquals(1, sizeof($traces[0]['spans'])); // trace is: custom - $this->assertSame($traces[0][0]['trace_id'], $found['headers']['X-Datadog-Trace-Id']); + $this->assertSame(SpanChecker::traceIdLow($traces[0]), $found['headers']['X-Datadog-Trace-Id']); // parent is: custom - $this->assertSame($traces[0][0]['span_id'], $found['headers']['X-Datadog-Parent-Id']); + $this->assertSame($traces[0]['spans'][0]['span_id'], $found['headers']['X-Datadog-Parent-Id']); } public function testAppendHostnameToServiceName() @@ -477,7 +478,7 @@ public function testAppendHostnameToServiceName() 'http', 'http://' . HTTPBIN_INTEGRATION . '/status/?' ) - ->withExactTags([ + ->withExactAttributes([ 'http.url' => self::URL . '/status/200', 'http.status_code' => '200', 'span.kind' => 'client', @@ -485,8 +486,8 @@ public function testAppendHostnameToServiceName() Tag::COMPONENT => 'curl', '_dd.svc_src' => 'opt.http_client_split_by_domain', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), ]); } @@ -509,7 +510,7 @@ public function testAppendHostnameToServiceNameInlineCredentials() 'http', 'http://?:?@' . HTTPBIN_INTEGRATION . '/status/?' ) - ->withExactTags([ + ->withExactAttributes([ 'http.url' => 'http://?:?@' . HTTPBIN_INTEGRATION . '/status/200', 'http.status_code' => '200', 'span.kind' => 'client', @@ -517,8 +518,8 @@ public function testAppendHostnameToServiceNameInlineCredentials() Tag::COMPONENT => 'curl', '_dd.svc_src' => 'opt.http_client_split_by_domain', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), ]); } @@ -575,34 +576,36 @@ public function testMulti($withRootSpan) $this->assertFlameGraph($traces, [ SpanAssertion::build('curl_multi_exec', 'curl', 'http', 'curl_multi_exec') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'curl', '_dd.svc_src' => 'curl', ])->withChildren([ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://' . HTTPBIN_INTEGRATION . '/status/?') - ->withExactTags([ + ->withExactAttributes([ '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.measured' => 1, ]) - ->withExistingTagsNames(($withRootSpan ? [-1 => "_dd.base_service"] : []) + self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(($withRootSpan ? [-1 => "_dd.base_service"] : []) + self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), SpanAssertion::build('curl_exec', 'curl', 'http', 'http://__i_am_not_real__.invalid/') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => 'http://__i_am_not_real__.invalid/', 'http.status_code' => '0', 'span.kind' => 'client', 'network.destination.name' => '__i_am_not_real__.invalid', Tag::COMPONENT => 'curl', '_dd.svc_src' => 'curl', + '_dd.measured' => 1, ]) - ->withExistingTagsNames(($withRootSpan ? [-1 => "_dd.base_service"] : []) + self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/') + ->withExistingAttributeNames(($withRootSpan ? [-1 => "_dd.base_service"] : []) + self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/') ->setError('curl error', "Couldn't resolve host name", true), - ])->withExistingTagsNames($withRootSpan ? ["_dd.base_service"] : []), + ])->withExistingAttributeNames($withRootSpan ? ["_dd.base_service"] : []), ]); } @@ -627,7 +630,7 @@ public function testPeerServiceEnabled() $this->assertSpans($traces, [ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://' . HTTPBIN_INTEGRATION . '/status/?') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => self::URL . '/status/200', 'http.status_code' => '200', 'span.kind' => 'client', @@ -637,8 +640,8 @@ public function testPeerServiceEnabled() 'peer.service' => HTTPBIN_SERVICE_HOST, '_dd.peer.service.source' => 'network.destination.name', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), ]); } @@ -660,15 +663,15 @@ public function testNoFakeServices() $this->assertSpans($traces, [ SpanAssertion::build('curl_exec', 'configured_service', 'http', 'http://' . HTTPBIN_INTEGRATION . '/status/?') - ->withExactTags([ + ->withExactAttributes([ 'http.url' => self::URL . '/status/200', 'http.status_code' => '200', 'span.kind' => 'client', 'network.destination.name' => HTTPBIN_SERVICE_HOST, Tag::COMPONENT => 'curl', ]) - ->withExistingTagsNames(self::commonCurlInfoTags()) - ->skipTagsLike('/^curl\..*/'), + ->withExistingAttributeNames(self::commonCurlInfoTags()) + ->skipAttributesLike('/^curl\..*/'), ], false); } } diff --git a/tests/Integrations/Custom/Autoloaded/AgentUrlEnvVarTest.php b/tests/Integrations/Custom/Autoloaded/AgentUrlEnvVarTest.php index 45035f56605..de0d6e4e53b 100644 --- a/tests/Integrations/Custom/Autoloaded/AgentUrlEnvVarTest.php +++ b/tests/Integrations/Custom/Autoloaded/AgentUrlEnvVarTest.php @@ -28,6 +28,6 @@ public function testAgentUrlEnvVarTakesPrecedence() $this->call($spec); }); - self::assertSame('GET /simple', $traces[0][0]['resource']); + self::assertSame('GET /simple', $traces[0]['spans'][0]['resource']); } } diff --git a/tests/Integrations/Custom/Autoloaded/CommonScenariosTest.php b/tests/Integrations/Custom/Autoloaded/CommonScenariosTest.php index 5102883537c..c588429379b 100644 --- a/tests/Integrations/Custom/Autoloaded/CommonScenariosTest.php +++ b/tests/Integrations/Custom/Autoloaded/CommonScenariosTest.php @@ -45,12 +45,12 @@ public function provideSpecs() 'web.request', 'web', 'GET /simple' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/simple?key=value&', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ], 'A simple GET request with a view' => [ @@ -59,12 +59,12 @@ public function provideSpecs() 'web.request', 'web', 'GET /simple_view' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/simple_view?key=value&', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ], 'A GET request with an exception' => [ @@ -73,12 +73,12 @@ public function provideSpecs() 'web.request', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/error?key=value&', 'http.status_code' => '500', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ])->setError(), ], ] diff --git a/tests/Integrations/Custom/Autoloaded/CompileTimeDisabledTest.php b/tests/Integrations/Custom/Autoloaded/CompileTimeDisabledTest.php index d573145285c..4ec1b0ac038 100644 --- a/tests/Integrations/Custom/Autoloaded/CompileTimeDisabledTest.php +++ b/tests/Integrations/Custom/Autoloaded/CompileTimeDisabledTest.php @@ -46,8 +46,8 @@ public function testScenario() $this->call($spec); }); - self::assertFalse(isset($traces[0][0]['metrics']['php.compilation.total_time_ms'])); - self::assertFalse(isset($traces[0][0]['metrics']['php.memory.peak_usage_bytes'])); - self::assertFalse(isset($traces[0][0]['metrics']['php.memory.peak_real_usage_bytes'])); + self::assertFalse(isset($traces[0]['spans'][0]['attributes']['php.compilation.total_time_ms'])); + self::assertFalse(isset($traces[0]['spans'][0]['attributes']['php.memory.peak_usage_bytes'])); + self::assertFalse(isset($traces[0]['spans'][0]['attributes']['php.memory.peak_real_usage_bytes'])); } } diff --git a/tests/Integrations/Custom/Autoloaded/CompileTimeEnabledTest.php b/tests/Integrations/Custom/Autoloaded/CompileTimeEnabledTest.php index 14dab0590e7..171efa49772 100644 --- a/tests/Integrations/Custom/Autoloaded/CompileTimeEnabledTest.php +++ b/tests/Integrations/Custom/Autoloaded/CompileTimeEnabledTest.php @@ -46,8 +46,8 @@ public function testScenario() $this->call($spec); }); - self::assertTrue(isset($traces[0][0]['metrics']['php.compilation.total_time_ms'])); - self::assertTrue(isset($traces[0][0]['metrics']['php.memory.peak_usage_bytes'])); - self::assertTrue(isset($traces[0][0]['metrics']['php.memory.peak_real_usage_bytes'])); + self::assertTrue(isset($traces[0]['spans'][0]['attributes']['php.compilation.total_time_ms'])); + self::assertTrue(isset($traces[0]['spans'][0]['attributes']['php.memory.peak_usage_bytes'])); + self::assertTrue(isset($traces[0]['spans'][0]['attributes']['php.memory.peak_real_usage_bytes'])); } } diff --git a/tests/Integrations/Custom/Autoloaded/FatalErrorTest.php b/tests/Integrations/Custom/Autoloaded/FatalErrorTest.php index 4078e731b2e..e0b4a7730e3 100644 --- a/tests/Integrations/Custom/Autoloaded/FatalErrorTest.php +++ b/tests/Integrations/Custom/Autoloaded/FatalErrorTest.php @@ -42,15 +42,15 @@ public function testScenario() 'autoload', 'web', 'GET /fatal' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/fatal', 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]) ->setError("E_ERROR", "Intentional E_ERROR") - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ] ); } diff --git a/tests/Integrations/Custom/Autoloaded/GitMetadataTest.php b/tests/Integrations/Custom/Autoloaded/GitMetadataTest.php index 36c2458f81e..9efcd72f438 100644 --- a/tests/Integrations/Custom/Autoloaded/GitMetadataTest.php +++ b/tests/Integrations/Custom/Autoloaded/GitMetadataTest.php @@ -112,65 +112,63 @@ public function testSourceCodeIntegrationInvalidThenValid() { $this->generateInvalidFakeGitFolder(); - $trace1 = $this->tracesFromWebRequest(function () { + $this->tracesFromWebRequest(function () { $spec = GetSpec::create('Source Code Integration test', '/simple'); $this->call($spec); }); + $payload1Attributes = $this->dumpedPayload['attributes'] ?? []; system("rm -rf " . self::GIT_DIR); $this->generateFullFakeGitFolder(); - $trace2 = $this->tracesFromWebRequest(function () { + $this->tracesFromWebRequest(function () { $spec = GetSpec::create('Source Code Integration test', '/simple'); $this->call($spec); }); + $payload2Attributes = $this->dumpedPayload['attributes']; - $trace1Meta = $trace1[0][0]['meta']; - $trace2Meta = $trace2[0][0]['meta']; + $this->assertArrayNotHasKey('_dd.git.commit.sha', $payload1Attributes); + $this->assertEquals('https://github.com/user/repo_new', $payload1Attributes['_dd.git.repository_url']); - $this->assertArrayNotHasKey('_dd.git.commit.sha', $trace1Meta); - $this->assertEquals('https://github.com/user/repo_new', $trace1Meta['_dd.git.repository_url']); - - $this->assertEquals('123456', $trace2Meta['_dd.git.commit.sha']); - $this->assertEquals('https://github.com/user/repo_new', $trace2Meta['_dd.git.repository_url']); + $this->assertEquals('123456', $payload2Attributes['_dd.git.commit.sha']); + $this->assertEquals('https://github.com/user/repo_new', $payload2Attributes['_dd.git.repository_url']); } public function testSourceCodeIntegration() { - $traces = $this->tracesFromWebRequest(function () { + $this->tracesFromWebRequest(function () { $spec = GetSpec::create('Source Code Integration test', '/simple'); $this->call($spec); }); - $rootSpanMeta = $traces[0][0]['meta']; + $payloadAttributes = $this->dumpedPayload['attributes']; $gitCommitSha = trim(shell_exec('git rev-parse HEAD')); $gitRepositoryURL = preg_replace('((?<=//)[^@]+@)', '', trim(shell_exec('git config --get remote.origin.url'))); - $this->assertEquals($gitCommitSha, $rootSpanMeta['_dd.git.commit.sha']); - $this->assertEquals($gitRepositoryURL, $rootSpanMeta['_dd.git.repository_url']); + $this->assertEquals($gitCommitSha, $payloadAttributes['_dd.git.commit.sha']); + $this->assertEquals($gitRepositoryURL, $payloadAttributes['_dd.git.repository_url']); } public function testSourceCodeIntegrationChangeCommitSha() { $this->generateFullFakeGitFolder(); - $trace1 = $this->tracesFromWebRequest(function () { + $this->tracesFromWebRequest(function () { $spec = GetSpec::create('Source Code Integration test', '/simple'); $this->call($spec); }); + $payload1Attributes = $this->dumpedPayload['attributes']; $this->changeRefsHeadsMaster('abc123def456'); - $trace2 = $this->tracesFromWebRequest(function () { + $this->tracesFromWebRequest(function () { $spec = GetSpec::create('Source Code Integration test', '/simple'); $this->call($spec); }); + $payload2Attributes = $this->dumpedPayload['attributes']; - $trace1Meta = $trace1[0][0]['meta']; - $trace2Meta = $trace2[0][0]['meta']; - - $this->assertEquals('123456', $trace1Meta['_dd.git.commit.sha']); - $this->assertEquals('abc123def456', $trace2Meta['_dd.git.commit.sha']); + $this->assertEquals('123456', $payload1Attributes['_dd.git.commit.sha']); + $this->assertEquals('abc123def456', $payload2Attributes['_dd.git.commit.sha']); } } diff --git a/tests/Integrations/Custom/Autoloaded/ProcessTagsWebTest.php b/tests/Integrations/Custom/Autoloaded/ProcessTagsWebTest.php index 480bad3f37a..620dc1cefdc 100644 --- a/tests/Integrations/Custom/Autoloaded/ProcessTagsWebTest.php +++ b/tests/Integrations/Custom/Autoloaded/ProcessTagsWebTest.php @@ -34,11 +34,10 @@ public function testProcessTagsEnabledForWebSapi() }); $this->assertCount(1, $traces); - $rootSpan = $traces[0][0]; // Verify _dd.tags.process exists - $this->assertArrayHasKey('_dd.tags.process', $rootSpan['meta']); - $processTags = $rootSpan['meta']['_dd.tags.process']; + $this->assertArrayHasKey('_dd.tags.process', $this->dumpedPayload['attributes']); + $processTags = $this->dumpedPayload['attributes']['_dd.tags.process']; // Parse the process tags $tags = []; @@ -75,17 +74,17 @@ public function testProcessTagsEnabledForWebSapi() */ public function testSvcTagDoesNotLeakBetweenRequests() { - $tracesUser = $this->tracesFromWebRequest(function () { + $this->tracesFromWebRequest(function () { return $this->call(new RequestSpec(__FUNCTION__ . '_user', 'GET', '/set_service', [])); }); - $userTags = $tracesUser[0][0]['meta']['_dd.tags.process']; + $userTags = $this->dumpedPayload['attributes']['_dd.tags.process']; $this->assertStringContains('svc.user:true', $userTags); $this->assertStringNotContains('svc.auto:', $userTags); - $tracesAuto = $this->tracesFromWebRequest(function () { + $this->tracesFromWebRequest(function () { return $this->call(new RequestSpec(__FUNCTION__ . '_auto', 'GET', '/simple', [])); }); - $autoTags = $tracesAuto[0][0]['meta']['_dd.tags.process']; + $autoTags = $this->dumpedPayload['attributes']['_dd.tags.process']; $this->assertStringNotContains('svc.user', $autoTags); $this->assertStringContains('svc.auto:', $autoTags); } diff --git a/tests/Integrations/Custom/Autoloaded/SidecarThreadModeRootTest.php b/tests/Integrations/Custom/Autoloaded/SidecarThreadModeRootTest.php index 6c2134babb3..6a123503705 100644 --- a/tests/Integrations/Custom/Autoloaded/SidecarThreadModeRootTest.php +++ b/tests/Integrations/Custom/Autoloaded/SidecarThreadModeRootTest.php @@ -77,8 +77,8 @@ public function testTracesAreSubmittedWithRootMasterAndUnprivilegedWorker() }); $this->assertNotEmpty($traces, 'No traces received — worker likely failed to access SHM after fchown()'); - $this->assertSame('web.request', $traces[0][0]['name']); - $this->assertSame('sidecar-thread-mode-root-test', $traces[0][0]['service']); + $this->assertSame('web.request', $traces[0]['spans'][0]['name']); + $this->assertSame('sidecar-thread-mode-root-test', $traces[0]['spans'][0]['service']); } /** diff --git a/tests/Integrations/Custom/Autoloaded/SidecarThreadModeTest.php b/tests/Integrations/Custom/Autoloaded/SidecarThreadModeTest.php index bc892414143..b3b95ae6136 100644 --- a/tests/Integrations/Custom/Autoloaded/SidecarThreadModeTest.php +++ b/tests/Integrations/Custom/Autoloaded/SidecarThreadModeTest.php @@ -52,9 +52,9 @@ public function testThreadModeTracesAreSubmitted() // Verify traces were submitted $this->assertNotEmpty($traces, 'Expected traces to be submitted through thread-based sidecar'); - $this->assertCount(1, $traces[0], 'Expected one span in the trace'); + $this->assertCount(1, $traces[0]['spans'], 'Expected one span in the trace'); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame('web.request', $span['name']); $this->assertSame('sidecar-thread-mode-test', $span['service']); } @@ -78,8 +78,8 @@ public function testThreadModeMultipleRequests() $this->assertGreaterThanOrEqual(3, count($traces), 'Expected at least 3 traces from multiple requests'); foreach ($traces as $trace) { - $this->assertNotEmpty($trace); - $this->assertSame('web.request', $trace[0]['name']); + $this->assertNotEmpty($trace['spans']); + $this->assertSame('web.request', $trace['spans'][0]['name']); } } } diff --git a/tests/Integrations/Custom/NotAutoloaded/HttpHeadersConfiguredTest.php b/tests/Integrations/Custom/NotAutoloaded/HttpHeadersConfiguredTest.php index 7e33955d87d..ac2d3a458fe 100644 --- a/tests/Integrations/Custom/NotAutoloaded/HttpHeadersConfiguredTest.php +++ b/tests/Integrations/Custom/NotAutoloaded/HttpHeadersConfiguredTest.php @@ -39,12 +39,12 @@ public function testSelectedHeadersAreIncluded() $tags = [ 'http.method' => 'GET', 'http.url' => 'http://localhost/', - 'http.status_code' => 200, + 'http.status_code' => '200', 'http.request.headers.first-header' => 'some value: with colon', 'http.request.headers.forth-header' => '123', 'http.response.headers.third-header' => 'separated: with : colon', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]; if (\getenv('DD_TRACE_TEST_SAPI') != 'apache2handler') { $tags['http.request.headers.w__rd-header'] = 'foo'; @@ -58,7 +58,7 @@ public function testSelectedHeadersAreIncluded() 'my-service', 'web', 'GET /' - )->withExactTags($tags), + )->withExactAttributes($tags), ] ); } diff --git a/tests/Integrations/Custom/NotAutoloaded/HttpHeadersNotConfiguredTest.php b/tests/Integrations/Custom/NotAutoloaded/HttpHeadersNotConfiguredTest.php index 49c5ba56d8d..ee992722f77 100644 --- a/tests/Integrations/Custom/NotAutoloaded/HttpHeadersNotConfiguredTest.php +++ b/tests/Integrations/Custom/NotAutoloaded/HttpHeadersNotConfiguredTest.php @@ -42,12 +42,12 @@ public function testSelectedHeadersAreIncluded() 'my-service', 'web', 'GET /' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/', - 'http.status_code' => 200, + 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ] ); diff --git a/tests/Integrations/Custom/NotAutoloaded/IncomingUserInfoTest.php b/tests/Integrations/Custom/NotAutoloaded/IncomingUserInfoTest.php index 5d7251fcad3..384b431d84a 100644 --- a/tests/Integrations/Custom/NotAutoloaded/IncomingUserInfoTest.php +++ b/tests/Integrations/Custom/NotAutoloaded/IncomingUserInfoTest.php @@ -33,12 +33,12 @@ public function testSelectedHeadersAreIncluded() 'my-service', 'web', 'GET /' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/', - 'http.status_code' => 200, + 'http.status_code' => '200', 'span.kind' => 'server', - 'component' => \DDTrace\Tests\WebServer::defaultSapiName(), + 'component' => 'web', ]), ] ); diff --git a/tests/Integrations/Elasticsearch/V1/ElasticSearchIntegrationTest.php b/tests/Integrations/Elasticsearch/V1/ElasticSearchIntegrationTest.php index 77223ff268c..67add838778 100644 --- a/tests/Integrations/Elasticsearch/V1/ElasticSearchIntegrationTest.php +++ b/tests/Integrations/Elasticsearch/V1/ElasticSearchIntegrationTest.php @@ -69,7 +69,7 @@ public function testConstructor() 'elasticsearch', 'elasticsearch', '__construct' - )->withExactTags([Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch']) + )->withExactAttributes([Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch']) ]); } @@ -86,7 +86,7 @@ public function testCount() 'elasticsearch', 'elasticsearch', 'count' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -126,7 +126,7 @@ public function testDelete() 'elasticsearch', 'elasticsearch', 'delete index:my_index7 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -166,7 +166,7 @@ public function testExists() 'elasticsearch', 'elasticsearch', 'exists index:my_index7 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -214,7 +214,7 @@ public function testExplain() 'elasticsearch', 'elasticsearch', 'explain index:my_index7 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -258,7 +258,7 @@ public function testGet() 'elasticsearch', 'elasticsearch', 'get index:my_index7 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -294,7 +294,7 @@ public function testIndex() 'elasticsearch', 'elasticsearch', 'index index:my_index7 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -432,7 +432,7 @@ public function testScroll() 'elasticsearch', 'elasticsearch', 'scroll' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -447,7 +447,7 @@ public function testScroll() 'elasticsearch', 'elasticsearch', 'scroll' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -488,7 +488,7 @@ public function testSearch() 'elasticsearch', 'elasticsearch', 'search index:' . 'my_index7' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -538,7 +538,7 @@ public function testPerformRequest() 'elasticsearch', 'elasticsearch', 'performRequest' - )->withExactTags([ + )->withExactAttributes([ 'elasticsearch.url' => '/my_index7/_search', 'elasticsearch.method' => \PHP_VERSION_ID >= 70300 ? 'POST' : 'GET', 'elasticsearch.params' => '[]', @@ -585,7 +585,7 @@ public function testUpdate() 'elasticsearch', 'elasticsearch', 'update index:my_index7 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', diff --git a/tests/Integrations/Elasticsearch/V8/ElasticSearchIntegrationTest.php b/tests/Integrations/Elasticsearch/V8/ElasticSearchIntegrationTest.php index 28656e8036f..2f0bc1bc670 100644 --- a/tests/Integrations/Elasticsearch/V8/ElasticSearchIntegrationTest.php +++ b/tests/Integrations/Elasticsearch/V8/ElasticSearchIntegrationTest.php @@ -68,7 +68,7 @@ public function testConstructor() 'elasticsearch', 'elasticsearch', '__construct' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', ]), @@ -88,7 +88,7 @@ public function testCount() 'elasticsearch', 'elasticsearch', 'count' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -125,7 +125,7 @@ public function testDelete() 'elasticsearch', 'elasticsearch', 'delete index:my_index8 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -162,7 +162,7 @@ public function testExists() 'elasticsearch', 'elasticsearch', 'exists index:my_index8 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -206,7 +206,7 @@ public function testExplain() 'elasticsearch', 'elasticsearch', 'explain index:my_index8 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -244,7 +244,7 @@ public function testGet() 'elasticsearch', 'elasticsearch', 'get index:my_index8 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -277,7 +277,7 @@ public function testIndex() 'elasticsearch', 'elasticsearch', 'index index:my_index8 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -413,7 +413,7 @@ public function testScroll() 'elasticsearch', 'elasticsearch', 'scroll' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -428,7 +428,7 @@ public function testScroll() 'elasticsearch', 'elasticsearch', 'scroll' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -469,7 +469,7 @@ public function testSearch() 'elasticsearch', 'elasticsearch', 'search index:' . 'my_index8' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', @@ -513,7 +513,7 @@ public function testPerformRequest() 'elasticsearch', 'elasticsearch', 'performRequest' - )->withExactTags([ + )->withExactAttributes([ 'elasticsearch.url' => '/my_index8/_search', 'elasticsearch.method' => 'POST', 'elasticsearch.body' => '{"query":{"match_all":{}}}', @@ -552,7 +552,7 @@ public function testUpdate() 'elasticsearch', 'elasticsearch', 'update index:my_index8 type:my_type' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'elasticsearch', '_dd.svc_src' => 'elasticsearch', diff --git a/tests/Integrations/Exec/ExecIntegrationTest.php b/tests/Integrations/Exec/ExecIntegrationTest.php index 4cf99aff87e..214985b2183 100644 --- a/tests/Integrations/Exec/ExecIntegrationTest.php +++ b/tests/Integrations/Exec/ExecIntegrationTest.php @@ -38,11 +38,11 @@ public function testBasicShell($sf) 'component' => 'subprocess', ]; if ($sf != 'shell_exec') { - $expectedTags['cmd.exit_code'] = '33'; + $expectedTags['cmd.exit_code'] = 33; } $this->assertSpans($traces, [ - SpanAssertion::build('command_execution', $traces[0][0]['service'], 'system', 'sh') - ->withExactTags($expectedTags) + SpanAssertion::build('command_execution', $traces[0]['spans'][0]['service'], 'system', 'sh') + ->withExactAttributes($expectedTags) ]); } @@ -65,11 +65,11 @@ public function testShellUnpassedArguments($sf) $expectedTags = [ 'cmd.shell' => 'echo -n foo; exit 33', 'component' => 'subprocess', - 'cmd.exit_code' => '33', + 'cmd.exit_code' => 33, ]; $spanAssertion = SpanAssertion::build( 'command_execution', - $traces[0][0]['service'], + $traces[0]['spans'][0]['service'], 'system', 'sh', $expectedTags @@ -95,11 +95,11 @@ public function testUnsetShell($sf) $expectedTags = [ 'cmd.shell' => 'echo -n foo; exit 33', 'component' => 'subprocess', - 'cmd.exit_code' => '33' + 'cmd.exit_code' => 33 ]; $this->assertSpans($traces, [ - SpanAssertion::build('command_execution', $traces[0][0]['service'], 'system', 'sh') - ->withExactTags($expectedTags) + SpanAssertion::build('command_execution', $traces[0]['spans'][0]['service'], 'system', 'sh') + ->withExactAttributes($expectedTags) ]); } @@ -127,14 +127,14 @@ public function testKillShell($sf) 'component' => 'subprocess', ]; if ($sf != 'shell_exec') { - $expectedTags['cmd.exit_code'] = '9'; + $expectedTags['cmd.exit_code'] = 9; } if ($sf == 'proc_open') { $expectedTags['error.message'] = 'The process was terminated by a signal'; } $spanAssertion = SpanAssertion::build( 'command_execution', - $traces[0][0]['service'], + $traces[0]['spans'][0]['service'], 'system', 'sh', $expectedTags, @@ -167,7 +167,7 @@ public function testProcOpenUnfinished() ]; $spanAssertion = SpanAssertion::build( 'command_execution', - $traces[0][0]['service'], + $traces[0]['spans'][0]['service'], 'system', 'sh', $expectedTags @@ -218,13 +218,13 @@ public function testPopenRshutdownClosing() $spanAssertion = SpanAssertion::build( 'command_execution', - $traces[0][0]['service'], + $traces[0]['spans'][0]['service'], 'system', 'sh', [ 'cmd.shell' => 'exit 33', 'component' => 'subprocess', - 'cmd.exit_code' => '33', + 'cmd.exit_code' => 33, ] ); @@ -247,13 +247,13 @@ public function testProcOpenRshutdownClosing() $spanAssertion = SpanAssertion::build( 'command_execution', - $traces[0][0]['service'], + $traces[0]['spans'][0]['service'], 'system', 'sh', [ 'cmd.shell' => 'exit 33', 'component' => 'subprocess', - 'cmd.exit_code' => '33', + 'cmd.exit_code' => 33, ] ); @@ -273,13 +273,13 @@ public function testProcGetStatus() $spanAssertion = SpanAssertion::build( 'command_execution', - $traces[0][0]['service'], + $traces[0]['spans'][0]['service'], 'system', 'sh', [ 'cmd.shell' => 'exit 33', 'component' => 'subprocess', - 'cmd.exit_code' => '33', + 'cmd.exit_code' => 33, ] ); @@ -300,13 +300,13 @@ public function testProcGetStatusSignal() $spanAssertion = SpanAssertion::build( 'command_execution', - $traces[0][0]['service'], + $traces[0]['spans'][0]['service'], 'system', 'sh', [ 'cmd.shell' => 'kill -9 $$', 'component' => 'subprocess', - 'cmd.exit_code' => '9', + 'cmd.exit_code' => 9, 'error.message' => 'The process was terminated by a signal', ], null, @@ -340,13 +340,13 @@ public function testDirectExecution() $spanAssertion = SpanAssertion::build( 'command_execution', - $traces[0][0]['service'], + $traces[0]['spans'][0]['service'], 'system', 'exit_33.sh', [ 'cmd.exec' => '["' . __DIR__ . '/exit_33.sh","foo$","bar"]', 'component' => 'subprocess', - 'cmd.exit_code' => '33', + 'cmd.exit_code' => 33, ] ); @@ -372,13 +372,13 @@ public function testDirectExecutionRedaction() $spanAssertion = SpanAssertion::build( 'command_execution', - $traces[0][0]['service'], + $traces[0]['spans'][0]['service'], 'system', 'exit_33.sh', [ 'cmd.exec' => '["' . __DIR__ . '/exit_33.sh","--password=?","-pass","?"]', 'component' => 'subprocess', - 'cmd.exit_code' => '33', + 'cmd.exit_code' => 33, ] ); @@ -436,7 +436,7 @@ public function testShellCommandWithNul($sf) $spanAssertion = SpanAssertion::build( 'command_execution', - $traces[0][0]['service'], + $traces[0]['spans'][0]['service'], 'system', 'sh', [ @@ -446,7 +446,7 @@ public function testShellCommandWithNul($sf) null, true ); - $spanAssertion->withExistingTagsNames(['error.message', 'error.type', 'error.stack']); + $spanAssertion->withExistingAttributeNames(['error.message', 'error.type', 'error.stack']); $this->assertSpans($traces, [$spanAssertion]); } @@ -480,7 +480,7 @@ public function testShellOtherBadArguments($sf) } else { $spanAssertion = SpanAssertion::build( 'command_execution', - $traces[0][0]['service'], + $traces[0]['spans'][0]['service'], 'system', 'sh', [ @@ -490,7 +490,7 @@ public function testShellOtherBadArguments($sf) null, true ); - $spanAssertion->withExistingTagsNames(['error.message', 'error.type', 'error.stack']); + $spanAssertion->withExistingAttributeNames(['error.message', 'error.type', 'error.stack']); $this->assertSpans($traces, [$spanAssertion]); } @@ -514,8 +514,8 @@ public function testShellExecNullReturnIsNotAnError() }); $this->assertSpans($traces, [ - SpanAssertion::build('command_execution', $traces[0][0]['service'], 'system', 'sh') - ->withExactTags([ + SpanAssertion::build('command_execution', $traces[0]['spans'][0]['service'], 'system', 'sh') + ->withExactAttributes([ 'cmd.shell' => 'true', 'component' => 'subprocess', ]) @@ -537,7 +537,7 @@ public function testShellRedaction($sf) $this->assertEquals( "md5(){ return; }; FOO=? BAR=? echo foo -- --password=? -pass ?; md5 ? ?", - $traces[0][0]['attributes']['cmd.shell'] + $traces[0]['spans'][0]['attributes']['cmd.shell'] ); } @@ -554,9 +554,9 @@ public function testShellTruncation() $this->assertEquals( 4 * 1024, - strlen($traces[0][0]['attributes']['cmd.shell']) + strlen($traces[0]['spans'][0]['attributes']['cmd.shell']) ); - $this->assertSame('true', $traces[0][0]['attributes']['cmd.truncated']); + $this->assertTrue($traces[0]['spans'][0]['attributes']['cmd.truncated']); } /** @@ -583,9 +583,9 @@ public function testExecTruncation() $this->assertEquals( '["echo","' . str_repeat('a', 4092) . '",""]', - $traces[0][0]['attributes']['cmd.exec'] + $traces[0]['spans'][0]['attributes']['cmd.exec'] ); - $this->assertSame('true', $traces[0][0]['attributes']['cmd.truncated']); + $this->assertTrue($traces[0]['spans'][0]['attributes']['cmd.truncated']); } public function testProcOpenInjectsSessionIds() diff --git a/tests/Integrations/Frankenphp/CommonScenariosTest.php b/tests/Integrations/Frankenphp/CommonScenariosTest.php index 6d716cf507e..dd9ed88a200 100644 --- a/tests/Integrations/Frankenphp/CommonScenariosTest.php +++ b/tests/Integrations/Frankenphp/CommonScenariosTest.php @@ -44,7 +44,7 @@ public function provideSpecs() 'frankenphp', 'web', 'GET /simple' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/simple?key=value&', 'http.status_code' => '200', @@ -59,7 +59,7 @@ public function provideSpecs() 'frankenphp', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/error?key=value&', 'http.status_code' => '500', diff --git a/tests/Integrations/Frankenphp/DistributedTracingTest.php b/tests/Integrations/Frankenphp/DistributedTracingTest.php index 71292f36dfc..96d6f60d7e0 100644 --- a/tests/Integrations/Frankenphp/DistributedTracingTest.php +++ b/tests/Integrations/Frankenphp/DistributedTracingTest.php @@ -2,6 +2,7 @@ namespace DDTrace\Tests\Integrations\Frankenphp; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\WebFrameworkTestCase; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; use DDTrace\Tests\Frameworks\Util\Request\PostSpec; @@ -38,12 +39,12 @@ public function testDistributedTracing() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame($traceId, $trace["trace_id"]); - $this->assertSame("42", $trace["meta"]["_dd.p.user_id"]); - $this->assertSame("Test", $trace["meta"]["http.useragent"]); - $this->assertSame("somevalue", $trace["meta"]["http.request.headers.x-header"]); - $this->assertArrayNotHasKey('http.client_ip', $trace["meta"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame($traceId, SpanChecker::traceIdLow($traces[0])); + $this->assertSame("42", $trace["attributes"]["_dd.p.user_id"]); + $this->assertSame("Test", $trace["attributes"]["http.useragent"]); + $this->assertSame("somevalue", $trace["attributes"]["http.request.headers.x-header"]); + $this->assertArrayNotHasKey('http.client_ip', $trace["attributes"]); } public function testDistributedTracingPostWithAllowedParams() @@ -64,16 +65,16 @@ public function testDistributedTracingPostWithAllowedParams() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame($traceId, $trace["trace_id"]); - $this->assertSame("42", $trace["meta"]["_dd.p.user_id"]); - $this->assertSame("Test", $trace["meta"]["http.useragent"]); - $this->assertSame("somevalue", $trace["meta"]["http.request.headers.x-header"]); - $this->assertSame("", $trace["meta"]["http.request.post.pass_word"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.foo.password"]); - $this->assertSame("value1", $trace["meta"]["http.request.post.bar.key1"]); - $this->assertSame("value2", $trace["meta"]["http.request.post.bar.key2.baz"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.bar.key2.password"]); - $this->assertArrayNotHasKey('http.client_ip', $trace["meta"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame($traceId, SpanChecker::traceIdLow($traces[0])); + $this->assertSame("42", $trace["attributes"]["_dd.p.user_id"]); + $this->assertSame("Test", $trace["attributes"]["http.useragent"]); + $this->assertSame("somevalue", $trace["attributes"]["http.request.headers.x-header"]); + $this->assertSame("", $trace["attributes"]["http.request.post.pass_word"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.foo.password"]); + $this->assertSame("value1", $trace["attributes"]["http.request.post.bar.key1"]); + $this->assertSame("value2", $trace["attributes"]["http.request.post.bar.key2.baz"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.bar.key2.password"]); + $this->assertArrayNotHasKey('http.client_ip', $trace["attributes"]); } } diff --git a/tests/Integrations/Guzzle/Latest/GuzzleIntegrationTest.php b/tests/Integrations/Guzzle/Latest/GuzzleIntegrationTest.php index ce22bc192bf..2ddb3ffa3ef 100644 --- a/tests/Integrations/Guzzle/Latest/GuzzleIntegrationTest.php +++ b/tests/Integrations/Guzzle/Latest/GuzzleIntegrationTest.php @@ -19,7 +19,7 @@ public function testSendRequest() }); $this->assertFlameGraph($traces, [ SpanAssertion::build('Psr\Http\Client\ClientInterface.sendRequest', 'phpunit', 'http', 'sendRequest') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'PUT', 'http.url' => 'http://example.com', 'http.status_code' => '200', @@ -29,7 +29,7 @@ public function testSendRequest() ]) ->withChildren([ SpanAssertion::build('GuzzleHttp\Client.transfer', 'guzzle', 'http', 'transfer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'PUT', 'http.url' => 'http://example.com', 'http.status_code' => '200', @@ -89,35 +89,35 @@ public function testMultiExec() 'metrics.php.memory.peak_real_usage_bytes', 'meta.error.stack', 'meta._dd.p.tid', - 'meta.curl.appconnect_time_us', + 'metrics.curl.appconnect_time_us', 'meta.curl.cainfo', 'meta.curl.capath', - 'meta.curl.connect_time', - 'meta.curl.connect_time_us', - 'meta.curl.download_content_length', + 'metrics.curl.connect_time', + 'metrics.curl.connect_time_us', + 'metrics.curl.download_content_length', 'meta.curl.effective_method', // PHP 8.2+ only - 'meta.curl.filetime', - 'meta.curl.header_size', - 'meta.curl.namelookup_time', - 'meta.curl.namelookup_time_us', - 'meta.curl.pretransfer_time', - 'meta.curl.pretransfer_time_us', - 'meta.curl.redirect_time', - 'meta.curl.redirect_time_us', - 'meta.curl.request_size', - 'meta.curl.speed_download', - 'meta.curl.speed_upload', - 'meta.curl.starttransfer_time', - 'meta.curl.starttransfer_time_us', - 'meta.curl.total_time', - 'meta.curl.total_time_us', - 'meta.curl.upload_content_length', - 'meta.network.bytes_read', - 'meta.network.bytes_written', + 'metrics.curl.filetime', + 'metrics.curl.header_size', + 'metrics.curl.namelookup_time', + 'metrics.curl.namelookup_time_us', + 'metrics.curl.pretransfer_time', + 'metrics.curl.pretransfer_time_us', + 'metrics.curl.redirect_time', + 'metrics.curl.redirect_time_us', + 'metrics.curl.request_size', + 'metrics.curl.speed_download', + 'metrics.curl.speed_upload', + 'metrics.curl.starttransfer_time', + 'metrics.curl.starttransfer_time_us', + 'metrics.curl.total_time', + 'metrics.curl.total_time_us', + 'metrics.curl.upload_content_length', + 'metrics.network.bytes_read', + 'metrics.network.bytes_written', 'meta.network.client.ip', - 'meta.network.client.port', + 'metrics.network.client.port', 'meta.network.destination.ip', - 'meta.network.destination.port', + 'metrics.network.destination.port', 'meta._dd.base_service', ]); } diff --git a/tests/Integrations/Guzzle/V5/GuzzleIntegrationTest.php b/tests/Integrations/Guzzle/V5/GuzzleIntegrationTest.php index 3faddda75ec..d320547a791 100644 --- a/tests/Integrations/Guzzle/V5/GuzzleIntegrationTest.php +++ b/tests/Integrations/Guzzle/V5/GuzzleIntegrationTest.php @@ -3,6 +3,7 @@ namespace DDTrace\Tests\Integrations\Guzzle\V5; use DDTrace\Sampling\PrioritySampling; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tracer; use DDTrace\Tag; use GuzzleHttp\Client; @@ -15,7 +16,7 @@ function find_span_name(array $trace, $name) { - foreach ($trace as $span) { + foreach ($trace['spans'] as $span) { if ($span['name'] == $name) { return $span; } @@ -63,7 +64,7 @@ public function testAliasMethods($method) }); $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => strtoupper($method), 'http.url' => 'http://example.com/?foo=secret', 'http.status_code' => '200', @@ -96,7 +97,7 @@ public function testSend() }); $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'PUT', 'http.url' => 'http://example.com', 'http.status_code' => '200', @@ -115,7 +116,7 @@ public function testGet() }); $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://example.com', 'http.status_code' => '200', @@ -135,7 +136,7 @@ public function testGetInlineCredentials() $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://?:?@example.com', 'http.status_code' => '200', @@ -169,7 +170,7 @@ public function testDistributedTracingIsPropagated() }); // trace is: custom - self::assertSame($traces[0][0]['trace_id'], $found['headers']['X-Datadog-Trace-Id']); + self::assertSame(SpanChecker::traceIdLow($traces[0]), $found['headers']['X-Datadog-Trace-Id']); // Find either the guzzle or curl span; prefer the latter $guzzleSpan = find_span_name($traces[0], 'GuzzleHttp\\Client.send'); @@ -238,13 +239,12 @@ function ($execute) use (&$headers1, &$headers2) { ]) ); - $rootSpan = $traces[0][0]; self::assertSame( - (float) $rootSpan['metrics']['_sampling_priority_v1'], + (float) $traces[0]['priority'], (float) $headers1['headers']['X-Datadog-Sampling-Priority'] ); self::assertSame( - (float) $rootSpan['metrics']['_sampling_priority_v1'], + (float) $traces[0]['priority'], (float) $headers2['headers']['X-Datadog-Sampling-Priority'] ); @@ -253,18 +253,18 @@ function ($execute) use (&$headers1, &$headers2) { * without an event loop. * @see https://github.com/guzzle/guzzle/issues/1439 */ - self::assertDistributedTracingSpan($traces[0][6], $headers1['headers']); - self::assertDistributedTracingSpan($traces[0][4], $headers2['headers']); + self::assertDistributedTracingSpan($traces[0], 6, $headers1['headers']); + self::assertDistributedTracingSpan($traces[0], 4, $headers2['headers']); } - private static function assertDistributedTracingSpan($span, $headers) + private static function assertDistributedTracingSpan($chunk, $spanIdx, $headers) { self::assertSame( - $span['span_id'], + $chunk['spans'][$spanIdx]['span_id'], $headers['X-Datadog-Parent-Id'] ); self::assertSame( - $span['trace_id'], + SpanChecker::traceIdLow($chunk), $headers['X-Datadog-Trace-Id'] ); self::assertSame('preserved_value', $headers['Honored']); @@ -303,11 +303,11 @@ public function testLimitedTracerDistributedTracingIsPropagated() $span->finish(); }); - self::assertEquals(1, sizeof($traces[0])); + self::assertEquals(1, sizeof($traces[0]['spans'])); // trace is: custom - self::assertSame($traces[0][0]['trace_id'], $found['headers']['X-Datadog-Trace-Id']); - self::assertSame($traces[0][0]['span_id'], $found['headers']['X-Datadog-Parent-Id']); + self::assertSame(SpanChecker::traceIdLow($traces[0]), $found['headers']['X-Datadog-Trace-Id']); + self::assertSame($traces[0]['spans'][0]['span_id'], $found['headers']['X-Datadog-Parent-Id']); self::assertSame('1', $found['headers']['X-Datadog-Sampling-Priority']); // existing headers are honored @@ -323,7 +323,7 @@ public function testAppendHostnameToServiceName() }); $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.send', 'host-example.com', 'http', 'send') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://example.com', 'http.status_code' => '200', @@ -344,7 +344,7 @@ public function testAppendHostnameToServiceNameInlineCredentials() }); $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.send', 'host-example.com', 'http', 'send') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://?:?@example.com', 'http.status_code' => '200', @@ -372,10 +372,10 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'top_level_app', 'web', 'GET /guzzle_in_web_request.php') - ->withExistingTagsNames(['http.method', 'http.url', 'http.status_code', 'span.kind', 'component']) + ->withExistingAttributeNames(['http.method', 'http.url', 'http.status_code', 'span.kind', 'component']) ->withChildren([ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => self::URL . '/status/200', 'http.status_code' => '200', @@ -402,7 +402,7 @@ public function testPeerServiceEnabled() }); $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'PUT', 'http.url' => 'http://example.com', 'http.status_code' => '200', diff --git a/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php b/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php index 4c79851f2c3..8ed0987c691 100644 --- a/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php +++ b/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php @@ -4,6 +4,7 @@ use DDTrace\Sampling\PrioritySampling; use DDTrace\Tests\Common\SnapshotTestTrait; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tracer; use DDTrace\Tag; use GuzzleHttp\Client; @@ -62,7 +63,7 @@ public function testAliasMethods($method) }); $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.transfer', 'guzzle', 'http', 'transfer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => strtoupper($method), 'http.url' => 'http://example.com/?foo=secret', 'http.status_code' => '200', @@ -90,13 +91,14 @@ public function providerHttpMethods() public function testSend() { self::putenv('DD_CODE_ORIGIN_MAX_USER_FRAMES=1'); - $traces = $this->isolateTracer(function () { + $traces = $this->isolateTracer(function () use (&$line) { $request = new Request('put', 'http://example.com'); + $line = __LINE__ + 1; $this->getMockedClient()->send($request); }); $this->assertFlameGraph($traces, [ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'PUT', 'http.url' => 'http://example.com', 'http.status_code' => '200', @@ -106,14 +108,14 @@ public function testSend() '_dd.svc_src' => 'guzzle', // Note that the leaf span is guzzle, not the curl inside '_dd.code_origin.frames.1.file' => '%s/GuzzleIntegrationTest.php', - '_dd.code_origin.frames.1.line' => '%d', + '_dd.code_origin.frames.1.line' => $line, '_dd.code_origin.frames.1.method' => '%s}', // closure format differs on PHP versions '_dd.code_origin.frames.1.type' => 'DDTrace\Tests\Integrations\Guzzle\%s\GuzzleIntegrationTest', '_dd.code_origin.type' => 'exit', ]) ->withChildren([ SpanAssertion::build('GuzzleHttp\Client.transfer', 'guzzle', 'http', 'transfer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'PUT', 'http.url' => 'http://example.com', 'network.destination.name' => 'example.com', @@ -141,7 +143,7 @@ public function testSendHttpErrorException() $this->assertFlameGraph($traces, [ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') ->setError('GuzzleHttp\Exception\ClientException', '404 Not Found', true) - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'PUT', 'http.url' => 'http://example.com', 'http.status_code' => '404', @@ -153,7 +155,7 @@ public function testSendHttpErrorException() ->withChildren([ SpanAssertion::build('GuzzleHttp\Client.transfer', 'guzzle', 'http', 'transfer') ->setError('http_error', 'HTTP 404: Not Found') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'PUT', 'http.url' => 'http://example.com', 'network.destination.name' => 'example.com', @@ -173,7 +175,7 @@ public function testGet() }); $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.transfer', 'guzzle', 'http', 'transfer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://example.com', 'http.status_code' => '200', @@ -193,7 +195,7 @@ public function testGetInlineCredentials() $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.transfer', 'guzzle', 'http', 'transfer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://?:?@example.com', 'http.status_code' => '200', @@ -227,11 +229,11 @@ public function testDistributedTracingIsPropagated() }); // trace is: custom - self::assertSame($traces[0][0]['trace_id'], $found['headers']['X-Datadog-Trace-Id']); + self::assertSame(SpanChecker::traceIdLow($traces[0]), $found['headers']['X-Datadog-Trace-Id']); // parent is: curl_exec, used under the hood $curl_exec = null; - foreach ($traces[0] as $span) { + foreach ($traces[0]['spans'] as $span) { if ($span['name'] === 'curl_exec') { $curl_exec = $span; break; @@ -295,18 +297,17 @@ function ($execute) use (&$found) { ); foreach ($found as $data) { - $rootSpan = $traces[0][0]; self::assertContains($data['headers']['X-Datadog-Parent-Id'], array_map(function($span) { return $span['span_id']; - }, array_filter($traces[0], function($span) { + }, array_filter($traces[0]['spans'], function($span) { return $span['name'] === 'curl_exec'; }))); self::assertSame( - $rootSpan['trace_id'], + SpanChecker::traceIdLow($traces[0]), $data['headers']['X-Datadog-Trace-Id'] ); self::assertSame( - (float) $rootSpan['metrics']['_sampling_priority_v1'], + (float) $traces[0]['priority'], (float) $data['headers']['X-Datadog-Sampling-Priority'] ); self::assertSame('preserved_value', $data['headers']['Honored']); @@ -336,7 +337,7 @@ public function testAppendHostnameToServiceNameNoSchema() $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.transfer', 'host-example.com', 'http', 'transfer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'example.com', 'http.status_code' => '200', @@ -370,9 +371,9 @@ public function testLimitedTracerDistributedTracingIsPropagated() }); // trace is: custom - self::assertSame($traces[0][0]['trace_id'], $found['headers']['X-Datadog-Trace-Id']); - self::assertSame($traces[0][0]['span_id'], $found['headers']['X-Datadog-Parent-Id']); - self::assertEquals(1, sizeof($traces[0])); + self::assertSame(SpanChecker::traceIdLow($traces[0]), $found['headers']['X-Datadog-Trace-Id']); + self::assertSame($traces[0]['spans'][0]['span_id'], $found['headers']['X-Datadog-Parent-Id']); + self::assertEquals(1, sizeof($traces[0]['spans'])); self::assertSame('1', $found['headers']['X-Datadog-Sampling-Priority']); // existing headers are honored @@ -388,7 +389,7 @@ public function testAppendHostnameToServiceName() }); $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.transfer', 'host-example.com', 'http', 'transfer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://example.com', 'http.status_code' => '200', @@ -409,7 +410,7 @@ public function testAppendHostnameToServiceNameInlineCredentials() }); $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.transfer', 'host-example.com', 'http', 'transfer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://?:?@example.com', 'http.status_code' => '200', @@ -437,10 +438,10 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'top_level_app', 'web', 'GET /guzzle_in_web_request.php') - ->withExistingTagsNames(['http.method', 'http.url', 'http.status_code', 'span.kind', 'component']) + ->withExistingAttributeNames(['http.method', 'http.url', 'http.status_code', 'span.kind', 'component']) ->withChildren([ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => self::URL . '/status/200', 'http.status_code' => '200', @@ -471,7 +472,7 @@ public function testPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::build('GuzzleHttp\Client.send', 'guzzle', 'http', 'send') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'PUT', 'http.url' => 'http://example.com', 'http.status_code' => '200', @@ -482,7 +483,7 @@ public function testPeerServiceEnabled() ]) ->withChildren([ SpanAssertion::build('GuzzleHttp\Client.transfer', 'guzzle', 'http', 'transfer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'PUT', 'http.url' => 'http://example.com', 'network.destination.name' => 'example.com', @@ -511,7 +512,7 @@ public function testNoFakeServices() $this->assertSpans($traces, [ SpanAssertion::build('GuzzleHttp\Client.transfer', 'configured_service', 'http', 'transfer') - ->withExactTags([ + ->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://example.com', 'http.status_code' => '200', @@ -564,36 +565,36 @@ public function testMultiExec() 'metrics.php.memory.peak_real_usage_bytes', 'meta.error.stack', 'meta._dd.p.tid', - 'meta.curl.appconnect_time_us', - 'meta.curl.connect_time', - 'meta.curl.connect_time_us', - 'meta.curl.download_content_length', - 'meta.curl.filetime', - 'meta.curl.header_size', - 'meta.curl.http_version', - 'meta.curl.namelookup_time', - 'meta.curl.namelookup_time_us', - 'meta.curl.pretransfer_time', - 'meta.curl.pretransfer_time_us', - 'meta.curl.protocol', - 'meta.curl.redirect_time', - 'meta.curl.redirect_time_us', - 'meta.curl.request_size', + 'metrics.curl.appconnect_time_us', + 'metrics.curl.connect_time', + 'metrics.curl.connect_time_us', + 'metrics.curl.download_content_length', + 'metrics.curl.filetime', + 'metrics.curl.header_size', + 'metrics.curl.http_version', + 'metrics.curl.namelookup_time', + 'metrics.curl.namelookup_time_us', + 'metrics.curl.pretransfer_time', + 'metrics.curl.pretransfer_time_us', + 'metrics.curl.protocol', + 'metrics.curl.redirect_time', + 'metrics.curl.redirect_time_us', + 'metrics.curl.request_size', 'meta.curl.scheme', - 'meta.curl.speed_download', - 'meta.curl.speed_upload', - 'meta.curl.ssl_verifyresult', - 'meta.curl.starttransfer_time', - 'meta.curl.starttransfer_time_us', - 'meta.curl.total_time', - 'meta.curl.total_time_us', - 'meta.curl.upload_content_length', - 'meta.network.bytes_read', - 'meta.network.bytes_written', + 'metrics.curl.speed_download', + 'metrics.curl.speed_upload', + 'metrics.curl.ssl_verifyresult', + 'metrics.curl.starttransfer_time', + 'metrics.curl.starttransfer_time_us', + 'metrics.curl.total_time', + 'metrics.curl.total_time_us', + 'metrics.curl.upload_content_length', + 'metrics.network.bytes_read', + 'metrics.network.bytes_written', 'meta.network.client.ip', - 'meta.network.client.port', + 'metrics.network.client.port', 'meta.network.destination.ip', - 'meta.network.destination.port', + 'metrics.network.destination.port', 'meta._dd.base_service', ]); } diff --git a/tests/Integrations/Kafka/KafkaTest.php b/tests/Integrations/Kafka/KafkaTest.php index 6f529a70107..e56f8adcb60 100644 --- a/tests/Integrations/Kafka/KafkaTest.php +++ b/tests/Integrations/Kafka/KafkaTest.php @@ -58,9 +58,9 @@ public function testDistributedTracingHighLevel() true ); - $producerTrace = $producerTraces[0][0]; + $producerTrace = $producerTraces[0]['spans'][0]; $kafkaProduceSpanID = $producerTrace['span_id']; - $kafkaProduceTraceID = $producerTrace['trace_id']; + $kafkaProduceTraceID = $producerTraces[0]['trace_id']; list($consumerTraces, $output) = $this->inCli( __DIR__ . '/scripts/consumer-highlevel.php', @@ -80,12 +80,12 @@ public function testDistributedTracingHighLevel() true ); - $distributedKafkaConsumeTraceID = $consumerTraces[0][0]['trace_id']; - $distributedKafkaConsumeParentID = $consumerTraces[0][0]['parent_id']; + $distributedKafkaConsumeTraceID = $consumerTraces[0]['trace_id']; + $distributedKafkaConsumeParentID = $consumerTraces[0]['spans'][0]['parent_id']; $this->assertEquals($kafkaProduceTraceID, $distributedKafkaConsumeTraceID); $this->assertEquals($kafkaProduceSpanID, $distributedKafkaConsumeParentID); - $this->assertCount(1, $consumerTraces[0]); + $this->assertCount(1, $consumerTraces[0]['spans']); } public function testSpanLinksLowLevel() @@ -105,111 +105,103 @@ public function testSpanLinksLowLevel() echo "Low: $low, High: $high\n"; - list($producerTraces, $output) = $this->inCli( - __DIR__ . '/scripts/producer.php', - [ - 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', - 'DD_TRACE_GENERATE_ROOT_SPAN' => 'false', - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_SERVICE' => 'kafka_test', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED' => 'false', - 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', - ], - [], - 'test-lowlevel', - true - ); + $this->snapshotFromTraces(function () use (&$output) { + list($traces, $output) = $this->inCli( + __DIR__ . '/scripts/producer.php', + [ + 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', + 'DD_TRACE_GENERATE_ROOT_SPAN' => 'false', + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_SERVICE' => 'kafka_test', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED' => 'false', + 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], + [], + 'test-lowlevel', + true + ); + return $traces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.kafka_test.test_span_links_low_level_producer'); echo $output; - $this->snapshotFromTraces( - $producerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.kafka_test.test_span_links_low_level_producer' - ); - - list($consumerTraces, $output) = $this->inCli( - __DIR__ . '/scripts/consumer-lowlevel.php', - [ - 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', - 'DD_TRACE_GENERATE_ROOT_SPAN' => 'false', - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_SERVICE' => 'kafka_test', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED' => 'false', - 'DD_TRACE_KAFKA_DISTRIBUTED_TRACING' => 'false', - 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', - ], - [], - $high, - true - ); + $this->snapshotFromTraces(function () use (&$output, $high) { + list($traces, $output) = $this->inCli( + __DIR__ . '/scripts/consumer-lowlevel.php', + [ + 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', + 'DD_TRACE_GENERATE_ROOT_SPAN' => 'false', + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_SERVICE' => 'kafka_test', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED' => 'false', + 'DD_TRACE_KAFKA_DISTRIBUTED_TRACING' => 'false', + 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], + [], + $high, + true + ); + return $traces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.kafka_test.test_span_links_low_level_consumer'); echo $output; - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.kafka_test.test_span_links_low_level_consumer' - ); } public function testSpanLinksHighLevel() { self::putEnv('DD_TRACE_DEBUG_PRNG_SEED=42'); - list($producerTraces, $output) = $this->inCli( - __DIR__ . '/scripts/producerv.php', - [ - 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', - 'DD_TRACE_GENERATE_ROOT_SPAN' => 'false', - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_SERVICE' => 'kafka_test', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED' => 'false', - 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', - ], - [], - 'test-highlevel', - true - ); + $this->snapshotFromTraces(function () use (&$output) { + list($traces, $output) = $this->inCli( + __DIR__ . '/scripts/producerv.php', + [ + 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', + 'DD_TRACE_GENERATE_ROOT_SPAN' => 'false', + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_SERVICE' => 'kafka_test', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED' => 'false', + 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], + [], + 'test-highlevel', + true + ); + return $traces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.kafka_test.test_span_links_high_level_producer'); echo $output; - $this->snapshotFromTraces( - $producerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.kafka_test.test_span_links_high_level_producer' - ); - - list($consumerTraces, $output) = $this->inCli( - __DIR__ . '/scripts/consumer-highlevel.php', - [ - 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_SERVICE' => 'kafka_test', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_TRACE_GENERATE_ROOT_SPAN' => 'false', - 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED' => 'false', - 'DD_TRACE_KAFKA_DISTRIBUTED_TRACING' => 'false', - 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', - ], - [], - null, - true - ); + $this->snapshotFromTraces(function () use (&$output) { + list($traces, $output) = $this->inCli( + __DIR__ . '/scripts/consumer-highlevel.php', + [ + 'DD_TRACE_AUTO_FLUSH_ENABLED' => 'true', + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_SERVICE' => 'kafka_test', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_TRACE_GENERATE_ROOT_SPAN' => 'false', + 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED' => 'false', + 'DD_TRACE_KAFKA_DISTRIBUTED_TRACING' => 'false', + 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], + [], + null, + true + ); + return $traces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.kafka_test.test_span_links_high_level_consumer'); echo $output; - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.kafka_test.test_span_links_high_level_consumer' - ); } } diff --git a/tests/Integrations/Laravel/Octane/APIGWTest.php b/tests/Integrations/Laravel/Octane/APIGWTest.php index ed72199289c..9a5c15ec823 100644 --- a/tests/Integrations/Laravel/Octane/APIGWTest.php +++ b/tests/Integrations/Laravel/Octane/APIGWTest.php @@ -43,17 +43,23 @@ protected static function getEnvs() 'DD_VERSION' => '1.0', 'DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED' => 'true', 'DD_TRACE_HEADER_TAGS' => 'x-dd-proxy-domain-name,x-dd-proxy,x-dd-proxy-httpmethod,x-dd-proxy-path,x-dd-proxy-request-time-ms,x-dd-proxy-stage', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', ]); } + public static function isApigwTrace($trace) + { + return \in_array('aws.apigateway', array_column($trace['spans'], 'name'), true); + } + public function testInferredProxy() { $until = function ($request) { $body = $request["body"] ?? []; - $traces = empty($body) ? [[]] : json_decode($body, true); + $traces = empty($body) ? [] : $this->parseRawDumpedTraces(json_decode($body, true)); foreach ($traces as $trace) { - foreach ($trace as $span) { + foreach ($trace['spans'] as $span) { if ($span && isset($span["name"]) && $span["name"] === "laravel.request" @@ -67,42 +73,34 @@ public function testInferredProxy() return false; }; - $traces = $this->tracesFromWebRequest(function () { - $this->call( - GetSpec::create( - 'A simple GET request returning a string', - '/simple?key=value&pwd=should_redact', - [ - 'x-dd-proxy: aws-apigateway', - 'x-dd-proxy-request-time-ms: 1739261376000', - 'x-dd-proxy-path: /test', - 'x-dd-proxy-httpmethod: GET', - 'x-dd-proxy-domain-name: example.com', - 'x-dd-proxy-stage: aws-prod', - ] - ) - ); - }, null, $until); - - $apigwTrace = null; - foreach ($traces as $trace) { - if ($trace[0]["name"] === "aws.apigateway") { - $apigwTrace = $trace; - break; - } - } - - $this->snapshotFromTraces([$apigwTrace]); + $this->snapshotFromTraces(function () use ($until) { + return $this->tracesFromWebRequest(function () { + $this->call( + GetSpec::create( + 'A simple GET request returning a string', + '/simple?key=value&pwd=should_redact', + [ + 'x-dd-proxy: aws-apigateway', + 'x-dd-proxy-request-time-ms: 1739261376000', + 'x-dd-proxy-path: /test', + 'x-dd-proxy-httpmethod: GET', + 'x-dd-proxy-domain-name: example.com', + 'x-dd-proxy-stage: aws-prod', + ] + ) + ); + }, null, $until); + }, null, null, [self::class, 'isApigwTrace']); } public function testInferredProxyException() { $until = function ($request) { $body = $request["body"] ?? []; - $traces = empty($body) ? [[]] : json_decode($body, true); + $traces = empty($body) ? [] : $this->parseRawDumpedTraces(json_decode($body, true)); foreach ($traces as $trace) { - foreach ($trace as $span) { + foreach ($trace['spans'] as $span) { if ($span && isset($span["name"]) && $span["name"] === "laravel.request" @@ -116,31 +114,23 @@ public function testInferredProxyException() return false; }; - $traces = $this->tracesFromWebRequest(function () { - $this->call( - GetSpec::create( - 'A GET throwing an exception', - '/error?key=value&pwd=should_redact', - [ - 'x-dd-proxy: aws-apigateway', - 'x-dd-proxy-request-time-ms: 1739261376000', - 'x-dd-proxy-path: /test', - 'x-dd-proxy-httpmethod: GET', - 'x-dd-proxy-domain-name: example.com', - 'x-dd-proxy-stage: aws-prod', - ] - ) - ); - }, null, $until); - - $apigwTrace = null; - foreach ($traces as $trace) { - if ($trace[0]["name"] === "aws.apigateway") { - $apigwTrace = $trace; - break; - } - } - - $this->snapshotFromTraces([$apigwTrace]); + $this->snapshotFromTraces(function () use ($until) { + return $this->tracesFromWebRequest(function () { + $this->call( + GetSpec::create( + 'A GET throwing an exception', + '/error?key=value&pwd=should_redact', + [ + 'x-dd-proxy: aws-apigateway', + 'x-dd-proxy-request-time-ms: 1739261376000', + 'x-dd-proxy-path: /test', + 'x-dd-proxy-httpmethod: GET', + 'x-dd-proxy-domain-name: example.com', + 'x-dd-proxy-stage: aws-prod', + ] + ) + ); + }, null, $until); + }, null, null, [self::class, 'isApigwTrace']); } } \ No newline at end of file diff --git a/tests/Integrations/Laravel/Octane/Latest/CommonScenariosTest.php b/tests/Integrations/Laravel/Octane/Latest/CommonScenariosTest.php index a787ff2574c..5e322b7fc08 100644 --- a/tests/Integrations/Laravel/Octane/Latest/CommonScenariosTest.php +++ b/tests/Integrations/Laravel/Octane/Latest/CommonScenariosTest.php @@ -58,10 +58,10 @@ public function testScenarioGetReturnString() { $until = function ($request) { $body = $request["body"] ?? []; - $traces = empty($body) ? [[]] : json_decode($body, true); + $traces = empty($body) ? [] : $this->parseRawDumpedTraces(json_decode($body, true)); foreach ($traces as $trace) { - foreach ($trace as $span) { + foreach ($trace['spans'] as $span) { if ($span && isset($span["name"]) && $span["name"] === "laravel.request" @@ -86,7 +86,7 @@ public function testScenarioGetReturnString() $webRequestTrace = null; foreach ($traces as $trace) { - if ($trace[0]["name"] === "laravel.request" && str_contains($trace[0]["resource"], 'App\\Http\\Controllers')) { + if ($trace["spans"][0]["name"] === "laravel.request" && str_contains($trace["spans"][0]["resource"], 'App\\Http\\Controllers')) { $webRequestTrace = $trace; break; } @@ -98,7 +98,7 @@ public function testScenarioGetReturnString() 'swoole_test_app', 'web', 'App\Http\Controllers\CommonSpecsController@simple simple_route' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/simple?key=value&', Tag::HTTP_ROUTE => 'simple', @@ -108,7 +108,7 @@ public function testScenarioGetReturnString() 'laravel.route.name' => 'simple_route', 'laravel.route.action' => 'App\Http\Controllers\CommonSpecsController@simple', ])->withChildren([ - SpanAssertion::build('laravel.action', 'swoole_test_app', 'web', 'simple')->withExactTags([ + SpanAssertion::build('laravel.action', 'swoole_test_app', 'web', 'simple')->withExactAttributes([ Tag::COMPONENT => 'laravel', ]), SpanAssertion::exists('laravel.event.handle', null, null, 'swoole_test_app'), @@ -130,10 +130,10 @@ public function testScenarioGetWithView() { $until = function ($request) { $body = $request["body"] ?? []; - $traces = empty($body) ? [[]] : json_decode($body, true); + $traces = empty($body) ? [] : $this->parseRawDumpedTraces(json_decode($body, true)); foreach ($traces as $trace) { - foreach ($trace as $span) { + foreach ($trace['spans'] as $span) { if ($span && isset($span["name"]) && $span["name"] === "laravel.request" @@ -158,7 +158,7 @@ public function testScenarioGetWithView() $webRequestTrace = null; foreach ($traces as $trace) { - if ($trace[0]["name"] === "laravel.request" && str_contains($trace[0]["resource"], 'App\\Http\\Controllers')) { + if ($trace["spans"][0]["name"] === "laravel.request" && str_contains($trace["spans"][0]["resource"], 'App\\Http\\Controllers')) { $webRequestTrace = $trace; break; } @@ -170,7 +170,7 @@ public function testScenarioGetWithView() 'swoole_test_app', 'web', 'App\Http\Controllers\CommonSpecsController@simple_view simple_view' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/simple_view?key=value&', Tag::HTTP_ROUTE => 'simple_view', @@ -180,7 +180,7 @@ public function testScenarioGetWithView() 'laravel.route.name' => 'unnamed_route', 'laravel.route.action' => 'App\Http\Controllers\CommonSpecsController@simple_view', ])->withChildren([ - SpanAssertion::build('laravel.action', 'swoole_test_app', 'web', 'simple_view')->withExactTags([ + SpanAssertion::build('laravel.action', 'swoole_test_app', 'web', 'simple_view')->withExactAttributes([ Tag::COMPONENT => 'laravel', ]), SpanAssertion::build( @@ -188,7 +188,7 @@ public function testScenarioGetWithView() 'swoole_test_app', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', ])->withChildren([ SpanAssertion::build( @@ -196,7 +196,7 @@ public function testScenarioGetWithView() 'swoole_test_app', 'web', '*/resources/views/simple_view.blade.php' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', ]) ]), @@ -219,10 +219,10 @@ public function testScenarioGetWithException() { $until = function ($request) { $body = $request["body"] ?? []; - $traces = empty($body) ? [[]] : json_decode($body, true); + $traces = empty($body) ? [] : $this->parseRawDumpedTraces(json_decode($body, true)); foreach ($traces as $trace) { - foreach ($trace as $span) { + foreach ($trace['spans'] as $span) { if ($span && isset($span["name"]) && $span["name"] === "laravel.request" @@ -247,7 +247,7 @@ public function testScenarioGetWithException() $webRequestTrace = null; foreach ($traces as $trace) { - if ($trace[0]["name"] === "laravel.request" && str_contains($trace[0]["resource"], 'App\\Http\\Controllers')) { + if ($trace["spans"][0]["name"] === "laravel.request" && str_contains($trace["spans"][0]["resource"], 'App\\Http\\Controllers')) { $webRequestTrace = $trace; break; } @@ -259,7 +259,7 @@ public function testScenarioGetWithException() 'swoole_test_app', 'web', 'App\Http\Controllers\CommonSpecsController@error error' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/error?key=value&', Tag::HTTP_ROUTE => 'error', @@ -269,7 +269,7 @@ public function testScenarioGetWithException() 'laravel.route.name' => 'unnamed_route', 'laravel.route.action' => 'App\Http\Controllers\CommonSpecsController@error', ])->setError('Exception', 'Controller error', true)->withChildren([ - SpanAssertion::build('laravel.action', 'swoole_test_app', 'web', 'error')->withExactTags([ + SpanAssertion::build('laravel.action', 'swoole_test_app', 'web', 'error')->withExactAttributes([ Tag::COMPONENT => 'laravel', ])->setError('Exception', 'Controller error', true), SpanAssertion::exists('laravel.event.handle', null, null, 'swoole_test_app'), @@ -290,10 +290,10 @@ public function testScenarioGetToMissingRoute() { $until = function ($request) { $body = $request["body"] ?? []; - $traces = empty($body) ? [[]] : json_decode($body, true); + $traces = empty($body) ? [] : $this->parseRawDumpedTraces(json_decode($body, true)); foreach ($traces as $trace) { - foreach ($trace as $span) { + foreach ($trace['spans'] as $span) { if ($span && isset($span["name"]) && $span["name"] === "laravel.request" && $span["resource"] === 'GET /does_not_exist') { return true; } @@ -314,7 +314,7 @@ public function testScenarioGetToMissingRoute() $webRequestTrace = null; foreach ($traces as $trace) { - if ($trace[0]["name"] === "laravel.request") { + if ($trace["spans"][0]["name"] === "laravel.request") { $webRequestTrace = $trace; break; } @@ -326,7 +326,7 @@ public function testScenarioGetToMissingRoute() 'swoole_test_app', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/does_not_exist?key=value&', Tag::HTTP_STATUS_CODE => '404', @@ -338,7 +338,7 @@ public function testScenarioGetToMissingRoute() 'swoole_test_app', 'web', 'errors::404' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', ])->withChildren([ SpanAssertion::build( @@ -346,7 +346,7 @@ public function testScenarioGetToMissingRoute() 'swoole_test_app', 'web', '*/views/404.blade.php' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', ]) ]), diff --git a/tests/Integrations/Laravel/V4/CommonScenariosTest.php b/tests/Integrations/Laravel/V4/CommonScenariosTest.php index 122a6947175..8852212fe83 100644 --- a/tests/Integrations/Laravel/V4/CommonScenariosTest.php +++ b/tests/Integrations/Laravel/V4/CommonScenariosTest.php @@ -50,7 +50,7 @@ public function provideSpecs() [ 'A simple GET request returning a string' => [ SpanAssertion::build('laravel.request', 'laravel', 'web', 'HomeController@simple simple_route') - ->withExactTags([ + ->withExactAttributes([ 'laravel.route.name' => 'simple_route', 'laravel.route.action' => 'HomeController@simple', 'http.method' => 'GET', @@ -67,7 +67,7 @@ public function provideSpecs() SpanAssertion::exists('laravel.application.handle') ->withChildren([ SpanAssertion::build('laravel.action', 'laravel', 'web', 'simple') - ->withExactTags([ + ->withExactAttributes([ 'some.key1' => 'value', 'some.key2' => 'value2', Tag::COMPONENT => 'laravel', @@ -111,7 +111,7 @@ public function provideSpecs() ]), SpanAssertion::exists('laravel.event.handle', null, null, 'laravel'), SpanAssertion::build('laravel.view.render', 'laravel', 'web', 'simple_view') - ->withExactTags([ + ->withExactAttributes([ 'some.key1' => 'value', 'some.key2' => 'value2', Tag::COMPONENT => 'laravel', @@ -142,7 +142,7 @@ public function provideSpecs() ], 'A GET request with an exception' => [ SpanAssertion::build('laravel.request', 'laravel', 'web', 'HomeController@error error') - ->withExactTags([ + ->withExactAttributes([ 'laravel.route.name' => 'error', 'laravel.route.action' => 'HomeController@error', 'http.method' => 'GET', @@ -158,13 +158,13 @@ public function provideSpecs() SpanAssertion::exists('laravel.application.handle') ->withChildren([ SpanAssertion::build('laravel.action', 'laravel', 'web', 'error') - ->withExactTags([ + ->withExactAttributes([ 'some.key1' => 'value', 'some.key2' => 'value2', Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ]) - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->setError('Exception', 'Controller error'), SpanAssertion::exists('laravel.event.handle', null, null, 'laravel'), SpanAssertion::exists('laravel.event.handle', null, null, 'laravel'), @@ -192,7 +192,7 @@ public function provideSpecs() ], 'A GET request to a dynamic route returning a string' => [ SpanAssertion::build('laravel.request', 'laravel', 'web', 'HomeController@dynamicRoute dynamic_route/{param01}/static/{param02?}') - ->withExactTags([ + ->withExactAttributes([ 'laravel.route.name' => 'unnamed_route', 'laravel.route.action' => 'HomeController@dynamicRoute', 'http.method' => 'GET', @@ -209,7 +209,7 @@ public function provideSpecs() SpanAssertion::exists('laravel.application.handle') ->withChildren([ SpanAssertion::build('laravel.action', 'laravel', 'web', 'dynamic_route/{param01}/static/{param02?}') - ->withExactTags([ + ->withExactAttributes([ 'some.key1' => 'value', 'some.key2' => 'value2', Tag::COMPONENT => 'laravel', diff --git a/tests/Integrations/Laravel/V4/EloquentTest.php b/tests/Integrations/Laravel/V4/EloquentTest.php index bb9becf8156..ce3c9342eb7 100644 --- a/tests/Integrations/Laravel/V4/EloquentTest.php +++ b/tests/Integrations/Laravel/V4/EloquentTest.php @@ -37,7 +37,7 @@ public function testDestroy() 'laravel', 'sql', 'User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', Tag::COMPONENT => 'eloquent', '_dd.svc_src' => 'laravel', @@ -56,7 +56,7 @@ public function testGet() 'laravel', 'sql', 'select * from `users`' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', 'sql.query' => 'select * from `users`', Tag::COMPONENT => 'eloquent', @@ -76,7 +76,7 @@ public function testInsert() 'laravel', 'sql', 'User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', Tag::COMPONENT => 'eloquent', '_dd.svc_src' => 'laravel', @@ -96,7 +96,7 @@ public function testUpdate() 'laravel', 'sql', 'User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', Tag::COMPONENT => 'eloquent', '_dd.svc_src' => 'laravel', @@ -116,7 +116,7 @@ public function testDelete() 'laravel', 'sql', 'User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', Tag::COMPONENT => 'eloquent', '_dd.svc_src' => 'laravel', diff --git a/tests/Integrations/Laravel/V5_7/EloquentTest.php b/tests/Integrations/Laravel/V5_7/EloquentTest.php index 592b3a0fa2b..f80b09d9803 100644 --- a/tests/Integrations/Laravel/V5_7/EloquentTest.php +++ b/tests/Integrations/Laravel/V5_7/EloquentTest.php @@ -37,7 +37,7 @@ public function testDestroy() 'Laravel', 'sql', 'App\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', Tag::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -57,7 +57,7 @@ public function testRefresh() 'Laravel', 'sql', 'App\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', Tag::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -76,7 +76,7 @@ public function testGet() 'Laravel', 'sql', 'select * from `users`' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', 'sql.query' => 'select * from `users`', Tag::COMPONENT => 'eloquent', @@ -96,7 +96,7 @@ public function testInsert() 'Laravel', 'sql', 'App\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', Tag::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -116,7 +116,7 @@ public function testUpdate() 'Laravel', 'sql', 'App\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', Tag::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -136,7 +136,7 @@ public function testDelete() 'Laravel', 'sql', 'App\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', Tag::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', diff --git a/tests/Integrations/Laravel/V5_7/PipelineTracingTest.php b/tests/Integrations/Laravel/V5_7/PipelineTracingTest.php index c4f22c77e4d..f35a88fcbb3 100644 --- a/tests/Integrations/Laravel/V5_7/PipelineTracingTest.php +++ b/tests/Integrations/Laravel/V5_7/PipelineTracingTest.php @@ -32,7 +32,7 @@ public function testPipeline() 'laravel_test_app', 'web', 'Tests\Integration\DummyPipe::someHandler' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ]), @@ -56,7 +56,7 @@ public function testPipelineCalledTwiceProperlyTraced() 'laravel_test_app', 'web', 'Tests\Integration\DummyPipe::someHandler' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ]), @@ -65,7 +65,7 @@ public function testPipelineCalledTwiceProperlyTraced() 'laravel_test_app', 'web', 'Tests\Integration\DummyPipe::someHandler' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ]), diff --git a/tests/Integrations/Laravel/V5_8/EloquentTest.php b/tests/Integrations/Laravel/V5_8/EloquentTest.php index 1baebe87148..780577ef173 100644 --- a/tests/Integrations/Laravel/V5_8/EloquentTest.php +++ b/tests/Integrations/Laravel/V5_8/EloquentTest.php @@ -34,7 +34,7 @@ public function testDestroy() 'Laravel', 'sql', 'App\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', TAG::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -54,7 +54,7 @@ public function testRefresh() 'Laravel', 'sql', 'App\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', TAG::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -73,7 +73,7 @@ public function testGet() 'Laravel', 'sql', 'select * from `users`' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', 'sql.query' => 'select * from `users`', TAG::COMPONENT => 'eloquent', @@ -93,7 +93,7 @@ public function testInsert() 'Laravel', 'sql', 'App\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', TAG::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -113,7 +113,7 @@ public function testUpdate() 'Laravel', 'sql', 'App\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', TAG::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -133,7 +133,7 @@ public function testDelete() 'Laravel', 'sql', 'App\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', TAG::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', diff --git a/tests/Integrations/Laravel/V5_8/QueueTest.php b/tests/Integrations/Laravel/V5_8/QueueTest.php index b98993a42da..8ec0b169d76 100644 --- a/tests/Integrations/Laravel/V5_8/QueueTest.php +++ b/tests/Integrations/Laravel/V5_8/QueueTest.php @@ -4,6 +4,7 @@ use DDTrace\Tag; use DDTrace\Tests\Common\SpanAssertion; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\WebFrameworkTestCase; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; @@ -31,36 +32,6 @@ protected function ddSetUp() $this->resetQueue(); } - // Source: https://magp.ie/2015/09/30/convert-large-integer-to-hexadecimal-without-php-math-extension/ - protected static function largeBaseConvert($numString, $fromBase, $toBase) - { - $chars = "0123456789abcdefghijklmnopqrstuvwxyz"; - $toString = substr($chars, 0, $toBase); - - $length = strlen($numString); - $result = ''; - for ($i = 0; $i < $length; $i++) { - $number[$i] = strpos($chars, $numString[$i]); - } - do { - $divide = 0; - $newLen = 0; - for ($i = 0; $i < $length; $i++) { - $divide = $divide * $fromBase + $number[$i]; - if ($divide >= $toBase) { - $number[$newLen++] = (int)($divide / $toBase); - $divide = $divide % $toBase; - } elseif ($newLen > 0) { - $number[$newLen++] = 0; - } - } - $length = $newLen; - $result = $toString[$divide] . $result; - } while ($newLen != 0); - - return $result; - } - public function testSimplePushAndProcess() { $createTraces = $this->tracesFromWebRequest(function () { @@ -82,7 +53,7 @@ public function testSimplePushAndProcess() SpanAssertion::exists('laravel.request') ->withChildren([ SpanAssertion::exists('laravel.action') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -112,47 +83,34 @@ public function testSimplePushAndProcess() ]) ], false); - $processSpanFromArtisanTrace = array_filter($artisanTrace[0], function ($span) { + $processSpanFromArtisanTrace = array_filter($artisanTrace[0]['spans'], function ($span) { return $span['name'] === 'laravel.queue.process'; }); $processSpanFromArtisanTrace = array_values($processSpanFromArtisanTrace)[0]; - // v0.4 carries native span_links (ids as decimal integers); render them as hex. - $spanLinks = $processSpanFromArtisanTrace['span_links'][0]; - $toHex = function ($id) { - return str_pad(self::largeBaseConvert((string) $id, 10, 16), 16, '0', STR_PAD_LEFT); - }; - $spanLinksTraceId = $toHex($spanLinks['trace_id_high'] ?? 0) . $toHex($spanLinks['trace_id']); - $spanLinksSpanId = $toHex($spanLinks['span_id']); + // The parsed traces carry span links with hex ids. + $spanLinksTraceId = $processSpanFromArtisanTrace['span_links'][0]['trace_id']; + $spanLinksSpanId = $processSpanFromArtisanTrace['span_links'][0]['span_id']; - $processSpanFromProcessTrace = array_filter($processTrace1[0], function ($span) { + $processSpanFromProcessTrace = array_filter($processTrace1[0]['spans'], function ($span) { return $span['name'] === 'laravel.queue.process'; }); $processSpanFromProcessTrace = array_values($processSpanFromProcessTrace)[0]; - $processTraceId = $processSpanFromProcessTrace['trace_id']; + $processTraceId = $processTrace1[0]['trace_id']; $processSpanId = $processSpanFromProcessTrace['span_id']; $processParentId = $processSpanFromProcessTrace['parent_id']; - $tid = $processSpanFromProcessTrace["meta"]['_dd.p.tid']; - $hexProcessTraceId = str_pad(self::largeBaseConvert($processTraceId, 10, 16), 16, '0', STR_PAD_LEFT); - $hexProcessSpanId = str_pad(self::largeBaseConvert($processSpanId, 10, 16), 16, '0', STR_PAD_LEFT); - - print("spanLinksTraceId: " . $spanLinksTraceId . "\n"); - print("tid: " . $tid . "\n"); - print("hexProcessTraceId: " . $hexProcessTraceId . "\n"); - print("hexProcessSpanId: " . $hexProcessSpanId . "\n"); - print("processTraceId: " . $processTraceId . "\n"); - print("processSpanId: " . $processSpanId . "\n"); + $hexProcessSpanId = SpanChecker::decimalToHex($processSpanId, 16); - $this->assertTrue($spanLinksTraceId == $tid . $hexProcessTraceId); - $this->assertTrue($spanLinksSpanId == $hexProcessSpanId); + $this->assertSame($spanLinksTraceId, $processTraceId); + $this->assertSame($spanLinksSpanId, $hexProcessSpanId); - $pushSpanFromCreateTrace = array_filter($createTraces[0], function ($span) { + $pushSpanFromCreateTrace = array_filter($createTraces[0]['spans'], function ($span) { return $span['name'] === 'laravel.queue.push'; }); $pushSpanFromCreateTrace = array_values($pushSpanFromCreateTrace)[0]; - $this->assertSame($pushSpanFromCreateTrace['trace_id'], $processTraceId); + $this->assertSame($createTraces[0]['trace_id'], $processTraceId); $this->assertSame($pushSpanFromCreateTrace['span_id'], $processParentId); } @@ -177,7 +135,7 @@ public function testJobFailure() SpanAssertion::exists('laravel.request') ->withChildren([ SpanAssertion::exists('laravel.action') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -203,7 +161,7 @@ public function testJobFailure() ->setError('Exception', 'Triggered Exception', true) ->withChildren([ $this->spanQueueAction('database', 'emails') - ->withExistingTagsNames([Tag::MQ_MESSAGE_ID]) + ->withExistingAttributeNames([Tag::MQ_MESSAGE_ID]) ->setError('Exception', 'Triggered Exception', true) ]) ]) @@ -246,7 +204,7 @@ protected function spanEventJobProcessing() 'laravel_queue_test', 'web', 'Illuminate\Queue\Events\JobProcessing' - )->withExistingTagsNames([ + )->withExistingAttributeNames([ Tag::COMPONENT, '_dd.svc_src', ]); @@ -259,7 +217,7 @@ protected function spanEventJobProcessed() 'laravel_queue_test', 'web', 'Illuminate\Queue\Events\JobProcessed' - )->withExistingTagsNames([ + )->withExistingAttributeNames([ Tag::COMPONENT, '_dd.svc_src', ]); @@ -308,7 +266,7 @@ protected function spanQueueAction( 'laravel_queue_test', 'queue', 'App\Jobs\SendVerificationEmail@handle' - )->withExactTags( + )->withExactAttributes( $this->getCommonTags(null, $queue, $connection) ); } @@ -323,14 +281,14 @@ protected function spanQueueResolve( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('process', $queue, $connection) ); if ($queue === 'sync') { return $span; } else { - return $span->withExistingTagsNames([ + return $span->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID ]); } @@ -346,14 +304,14 @@ protected function spanQueueFire( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('process', $queue, $connection) ); if ($queue === 'sync') { return $span; } else { - return $span->withExistingTagsNames([ + return $span->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID ]); } @@ -369,17 +327,16 @@ protected function spanQueueProcess( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('receive', $queue, $connection) ); if ($queue === 'sync') { return $span; } else { - return $span->withExistingTagsNames([ + return $span->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID, - '_dd.span_links' - ]); + ])->withSpanLinks(); } } @@ -394,18 +351,17 @@ protected function spanProcessOneJob( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('receive', $queue, $connection) - )->withExistingTagsNames([ + )->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID, - '_dd.span_links' - ])->withChildren([ + ])->withSpanLinks()->withChildren([ $this->spanEventJobProcessing(), $this->spanQueueFire($connection, $queue, $resourceDetails) ->withChildren([ $this->spanQueueResolve($connection, $queue, $resourceDetails), $this->spanQueueAction($connection, $queue, $resourceDetails) - ->withExistingTagsNames([ + ->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID ]) ]), @@ -423,7 +379,7 @@ protected function spanQueuePush( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('send', $queue, $connection) ); } @@ -438,7 +394,7 @@ protected function spanQueueLater( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('send', $queue, $connection) ); } diff --git a/tests/Integrations/Laravel/V8_x/EloquentTest.php b/tests/Integrations/Laravel/V8_x/EloquentTest.php index 8731dbea3f9..7bf6cc4451e 100644 --- a/tests/Integrations/Laravel/V8_x/EloquentTest.php +++ b/tests/Integrations/Laravel/V8_x/EloquentTest.php @@ -34,7 +34,7 @@ public function testDestroy() 'Laravel', 'sql', 'App\\Models\\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', TAG::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -54,7 +54,7 @@ public function testRefresh() 'Laravel', 'sql', 'App\\Models\\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', TAG::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -73,7 +73,7 @@ public function testGet() 'Laravel', 'sql', 'select * from `users`' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', 'sql.query' => 'select * from `users`', TAG::COMPONENT => 'eloquent', @@ -93,7 +93,7 @@ public function testInsert() 'Laravel', 'sql', 'App\\Models\\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', TAG::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -113,7 +113,7 @@ public function testUpdate() 'Laravel', 'sql', 'App\\Models\\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', TAG::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', @@ -133,7 +133,7 @@ public function testDelete() 'Laravel', 'sql', 'App\\Models\\User' - )->withExactTags([ + )->withExactAttributes([ TAG::SPAN_KIND => 'client', TAG::COMPONENT => 'eloquent', '_dd.svc_src' => 'Laravel', diff --git a/tests/Integrations/Laravel/V8_x/HttpHideRouteTest.php b/tests/Integrations/Laravel/V8_x/HttpHideRouteTest.php index 10fe86f26ff..62ce5853b1d 100644 --- a/tests/Integrations/Laravel/V8_x/HttpHideRouteTest.php +++ b/tests/Integrations/Laravel/V8_x/HttpHideRouteTest.php @@ -31,7 +31,7 @@ public function testDefaultPath() { $this->call(GetSpec::create('A simple GET request returning a string', '/simple')); }); - foreach ($traces[0] as $span) { + foreach ($traces[0]['spans'] as $span) { if (empty($span["parent_id"])) { $this->assertEquals("GET /simple", $span["resource"]); } diff --git a/tests/Integrations/Laravel/V8_x/InternalExceptionsTest.php b/tests/Integrations/Laravel/V8_x/InternalExceptionsTest.php index 8441164c14d..23963597168 100644 --- a/tests/Integrations/Laravel/V8_x/InternalExceptionsTest.php +++ b/tests/Integrations/Laravel/V8_x/InternalExceptionsTest.php @@ -39,7 +39,7 @@ public function testNotImplemented() 'web', 'App\Http\Controllers\InternalErrorController@notImplemented not-implemented' ) - ->withExactTags([ + ->withExactAttributes([ 'laravel.route.name' => 'not-implemented', 'laravel.route.action' => 'App\Http\Controllers\InternalErrorController@notImplemented', 'http.method' => 'GET', @@ -50,19 +50,16 @@ public function testNotImplemented() TAG::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ]) - ->withExactMetrics([ - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) + ->samplingPriority(1) ->withChildren([ SpanAssertion::build('laravel.action', 'laravel_test_app', 'web', 'not-implemented') - ->withExactTags([ + ->withExactAttributes([ TAG::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', 'track_error' => 'false', ]) ->setError('Symfony\Component\HttpKernel\Exception\HttpException') - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.stack']), + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.stack']), SpanAssertion::exists( 'laravel.provider.load', 'Illuminate\Foundation\ProviderRepository::load' @@ -102,7 +99,7 @@ public function testUnauthorized() 'web', 'App\Http\Controllers\InternalErrorController@unauthorized unauthorized' ) - ->withExactTags([ + ->withExactAttributes([ 'laravel.route.name' => 'unauthorized', 'laravel.route.action' => 'App\Http\Controllers\InternalErrorController@unauthorized', 'http.method' => 'GET', @@ -113,17 +110,14 @@ public function testUnauthorized() TAG::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ]) - ->withExactMetrics([ - '_sampling_priority_v1' => 1, - 'process_id' => getmypid(), - ]) + ->samplingPriority(1) ->withChildren([ SpanAssertion::build( 'laravel.view.render', 'laravel_test_app', 'web', 'errors::403' - )->withExactTags([ + )->withExactAttributes([ TAG::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -134,13 +128,13 @@ public function testUnauthorized() SpanAssertion::exists('laravel.event.handle'), ]), SpanAssertion::build('laravel.action', 'laravel_test_app', 'web', 'unauthorized') - ->withExactTags([ + ->withExactAttributes([ TAG::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', 'track_error' => 'false', ]) ->setError() - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.stack']), + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.stack']), SpanAssertion::exists( 'laravel.provider.load', 'Illuminate\Foundation\ProviderRepository::load' diff --git a/tests/Integrations/Laravel/V8_x/QueueTest.php b/tests/Integrations/Laravel/V8_x/QueueTest.php index be831f7f63f..62b036564cc 100644 --- a/tests/Integrations/Laravel/V8_x/QueueTest.php +++ b/tests/Integrations/Laravel/V8_x/QueueTest.php @@ -4,6 +4,7 @@ use DDTrace\Tag; use DDTrace\Tests\Common\SpanAssertion; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\WebFrameworkTestCase; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; @@ -33,36 +34,6 @@ protected function ddSetUp() $this->resetQueue(); } - // Source: https://magp.ie/2015/09/30/convert-large-integer-to-hexadecimal-without-php-math-extension/ - protected static function largeBaseConvert($numString, $fromBase, $toBase) - { - $chars = "0123456789abcdefghijklmnopqrstuvwxyz"; - $toString = substr($chars, 0, $toBase); - - $length = strlen($numString); - $result = ''; - for ($i = 0; $i < $length; $i++) { - $number[$i] = strpos($chars, $numString[$i]); - } - do { - $divide = 0; - $newLen = 0; - for ($i = 0; $i < $length; $i++) { - $divide = $divide * $fromBase + $number[$i]; - if ($divide >= $toBase) { - $number[$newLen++] = (int)($divide / $toBase); - $divide = $divide % $toBase; - } elseif ($newLen > 0) { - $number[$newLen++] = 0; - } - } - $length = $newLen; - $result = $toString[$divide] . $result; - } while ($newLen != 0); - - return $result; - } - protected function envsToCleanUpAtTearDown() { return [ @@ -100,7 +71,7 @@ public function testSimplePushAndProcess() SpanAssertion::exists('laravel.request') ->withChildren([ SpanAssertion::exists('laravel.action') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -133,47 +104,34 @@ public function testSimplePushAndProcess() ]) ], false); - $processSpanFromArtisanTrace = array_filter($artisanTrace[0], function ($span) { + $processSpanFromArtisanTrace = array_filter($artisanTrace[0]['spans'], function ($span) { return $span['name'] === 'laravel.queue.process'; }); $processSpanFromArtisanTrace = array_values($processSpanFromArtisanTrace)[0]; - // v0.4 carries native span_links (ids as decimal integers); render them as hex. - $spanLinks = $processSpanFromArtisanTrace['span_links'][0]; - $toHex = function ($id) { - return str_pad(self::largeBaseConvert((string) $id, 10, 16), 16, '0', STR_PAD_LEFT); - }; - $spanLinksTraceId = $toHex($spanLinks['trace_id_high'] ?? 0) . $toHex($spanLinks['trace_id']); - $spanLinksSpanId = $toHex($spanLinks['span_id']); + // The parsed traces carry span links with hex ids. + $spanLinksTraceId = $processSpanFromArtisanTrace['span_links'][0]['trace_id']; + $spanLinksSpanId = $processSpanFromArtisanTrace['span_links'][0]['span_id']; - $processSpanFromProcessTrace = array_filter($processTrace1[0], function ($span) { + $processSpanFromProcessTrace = array_filter($processTrace1[0]['spans'], function ($span) { return $span['name'] === 'laravel.queue.process'; }); $processSpanFromProcessTrace = array_values($processSpanFromProcessTrace)[0]; - $processTraceId = $processSpanFromProcessTrace['trace_id']; + $processTraceId = $processTrace1[0]['trace_id']; $processSpanId = $processSpanFromProcessTrace['span_id']; $processParentId = $processSpanFromProcessTrace['parent_id']; - $tid = $processSpanFromProcessTrace["meta"]['_dd.p.tid']; - $hexProcessTraceId = str_pad(self::largeBaseConvert($processTraceId, 10, 16), 16, '0', STR_PAD_LEFT); - $hexProcessSpanId = str_pad(self::largeBaseConvert($processSpanId, 10, 16), 16, '0', STR_PAD_LEFT); - - print("spanLinksTraceId: " . $spanLinksTraceId . "\n"); - print("tid: " . $tid . "\n"); - print("hexProcessTraceId: " . $hexProcessTraceId . "\n"); - print("hexProcessSpanId: " . $hexProcessSpanId . "\n"); - print("processTraceId: " . $processTraceId . "\n"); - print("processSpanId: " . $processSpanId . "\n"); + $hexProcessSpanId = SpanChecker::decimalToHex($processSpanId, 16); - $this->assertSame($spanLinksTraceId, $tid . $hexProcessTraceId); + $this->assertSame($spanLinksTraceId, $processTraceId); $this->assertSame($spanLinksSpanId, $hexProcessSpanId); - $pushSpanFromCreateTrace = array_filter($createTraces[0], function ($span) { + $pushSpanFromCreateTrace = array_filter($createTraces[0]['spans'], function ($span) { return $span['name'] === 'laravel.queue.push'; }); $pushSpanFromCreateTrace = array_values($pushSpanFromCreateTrace)[0]; - $this->assertSame($pushSpanFromCreateTrace['trace_id'], $processTraceId); + $this->assertSame($createTraces[0]['trace_id'], $processTraceId); $this->assertSame($pushSpanFromCreateTrace['span_id'], $processParentId); } @@ -197,7 +155,7 @@ public function testJobFailure() SpanAssertion::exists('laravel.request') ->withChildren([ SpanAssertion::exists('laravel.action') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'laravel', '_dd.svc_src' => 'laravel', ])->withChildren([ @@ -226,7 +184,7 @@ public function testJobFailure() ->setError('Exception', 'Triggered Exception', true) ->withChildren([ $this->spanQueueAction('database', 'emails') - ->withExistingTagsNames([Tag::MQ_MESSAGE_ID]) + ->withExistingAttributeNames([Tag::MQ_MESSAGE_ID]) ->setError('Exception', 'Triggered Exception', true) ]) ]) @@ -267,7 +225,7 @@ public function testDispatchBatchAndProcess() // $workTraces should have 2 traces: One with 2 'laravel.queue.process' and the other with 1 'laravel.artisan' usort($workTraces, function ($a, $b) { - return $a[0]['start'] - $b[0]['start']; + return $a['spans'][0]['start'] - $b['spans'][0]['start']; }); $artisanTrace = [$workTraces[0]]; $processTrace1 = [$workTraces[1]]; @@ -309,26 +267,26 @@ public function testDispatchBatchNowDefault() $this->spanQueueBatchAdd() ->withChildren([ $this->spanQueuePush('sync', 'default', 'Illuminate\Queue\SyncQueue') - ->withExistingTagsNames([Tag::LARAVELQ_BATCH_ID]) + ->withExistingAttributeNames([Tag::LARAVELQ_BATCH_ID]) ->withChildren([ $this->spanEventJobProcessing(), $this->spanQueueFire('sync', 'sync', 'App\Jobs\SendVerificationEmail -> sync') ->withChildren([ $this->spanQueueResolve('sync', 'sync', 'App\Jobs\SendVerificationEmail -> sync'), $this->spanQueueAction('sync', 'sync') - ->withExistingTagsNames([Tag::LARAVELQ_BATCH_ID]) + ->withExistingAttributeNames([Tag::LARAVELQ_BATCH_ID]) ]), $this->spanEventJobProcessed() ]), $this->spanQueuePush('sync', 'default', 'Illuminate\Queue\SyncQueue') - ->withExistingTagsNames([Tag::LARAVELQ_BATCH_ID]) + ->withExistingAttributeNames([Tag::LARAVELQ_BATCH_ID]) ->withChildren([ $this->spanEventJobProcessing(), $this->spanQueueFire('sync', 'sync', 'App\Jobs\SendVerificationEmail -> sync') ->withChildren([ $this->spanQueueResolve('sync', 'sync', 'App\Jobs\SendVerificationEmail -> sync'), $this->spanQueueAction('sync', 'sync') - ->withExistingTagsNames([Tag::LARAVELQ_BATCH_ID]) + ->withExistingAttributeNames([Tag::LARAVELQ_BATCH_ID]) ]), $this->spanEventJobProcessed() ]) @@ -357,7 +315,7 @@ protected function spanEventJobProcessing() 'laravel_queue_test', 'web', 'Illuminate\Queue\Events\JobProcessing' - )->withExistingTagsNames([ + )->withExistingAttributeNames([ Tag::COMPONENT, '_dd.svc_src', ]); @@ -370,7 +328,7 @@ protected function spanEventJobProcessed() 'laravel_queue_test', 'web', 'Illuminate\Queue\Events\JobProcessed' - )->withExistingTagsNames([ + )->withExistingAttributeNames([ Tag::COMPONENT, '_dd.svc_src', ]); @@ -419,7 +377,7 @@ protected function spanQueueAction( 'laravel_queue_test', 'queue', 'App\Jobs\SendVerificationEmail@handle' - )->withExactTags( + )->withExactAttributes( $this->getCommonTags(null, $queue, $connection) ); } @@ -434,14 +392,14 @@ protected function spanQueueResolve( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('process', $queue, $connection) ); if ($queue === 'sync') { return $span; } else { - return $span->withExistingTagsNames([ + return $span->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID ]); } @@ -457,14 +415,14 @@ protected function spanQueueFire( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('process', $queue, $connection) ); if ($queue === 'sync') { return $span; } else { - return $span->withExistingTagsNames([ + return $span->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID ]); } @@ -480,17 +438,16 @@ protected function spanQueueProcess( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('receive', $queue, $connection) ); if ($queue === 'sync') { return $span; } else { - return $span->withExistingTagsNames([ + return $span->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID, - '_dd.span_links' - ]); + ])->withSpanLinks(); } } @@ -505,24 +462,23 @@ protected function spanProcessOneJob( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('receive', $queue, $connection) - )->withExistingTagsNames([ + )->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID, - '_dd.span_links' - ])->withChildren([ + ])->withSpanLinks()->withChildren([ $this->spanEventJobProcessing(), $this->spanQueueFire($connection, $queue, $resourceDetails) ->withChildren([ $this->spanQueueResolve($connection, $queue, $resourceDetails), ($isFromBatch ? $this->spanQueueAction($connection, $queue, $resourceDetails) - ->withExistingTagsNames([ + ->withExistingAttributeNames([ Tag::LARAVELQ_BATCH_ID, Tag::MQ_MESSAGE_ID ]) : $this->spanQueueAction($connection, $queue, $resourceDetails) - ->withExistingTagsNames([ + ->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID ]) ) @@ -541,7 +497,7 @@ protected function spanQueuePush( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('send', $queue, $connection) ); } @@ -556,7 +512,7 @@ protected function spanQueueLater( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('send', $queue, $connection) ); } @@ -571,7 +527,7 @@ protected function spanQueueEnqueue( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags(null, $queue, $connection) ); } @@ -583,12 +539,12 @@ protected function spanQueueBatchAdd() 'laravel_queue_test', 'queue', 'Illuminate\Bus\Batch' - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'laravelqueue', '_dd.svc_src' => 'laravelqueue', Tag::MQ_OPERATION => 'send' - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::LARAVELQ_BATCH_ID ]); } diff --git a/tests/Integrations/Laravel/V8_x/QueueTestNotDistributed.php b/tests/Integrations/Laravel/V8_x/QueueTestNotDistributed.php index 43163b7b74f..627877ab45b 100644 --- a/tests/Integrations/Laravel/V8_x/QueueTestNotDistributed.php +++ b/tests/Integrations/Laravel/V8_x/QueueTestNotDistributed.php @@ -37,7 +37,7 @@ protected static function flattenArray($arr) { $retArr = []; foreach ($arr as $val) { - if (isset($val[0]['trace_id'])) { + if (isset($val['spans'])) { $retArr[] = [$val]; } else { $retArr = array_merge($retArr, self::flattenArray($val)); @@ -134,7 +134,7 @@ protected function spanQueueAction( 'laravel_queue_test', 'queue', 'App\Jobs\SendVerificationEmail@handle' - )->withExactTags( + )->withExactAttributes( $this->getCommonTags(null, $queue, $connection) ); } @@ -149,14 +149,14 @@ protected function spanQueueResolve( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('process', $queue, $connection) ); if ($queue === 'sync') { return $span; } else { - return $span->withExistingTagsNames([ + return $span->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID ]); } @@ -172,14 +172,14 @@ protected function spanQueueFire( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('process', $queue, $connection) ); if ($queue === 'sync') { return $span; } else { - return $span->withExistingTagsNames([ + return $span->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID ]); } @@ -195,17 +195,16 @@ protected function spanQueueProcess( 'laravel_queue_test', 'queue', $resourceDetails - )->withExactTags( + )->withExactAttributes( $this->getCommonTags('receive', $queue, $connection) ); if ($queue === 'sync') { return $span; } else { - return $span->withExistingTagsNames([ + return $span->withExistingAttributeNames([ Tag::MQ_MESSAGE_ID, - '_dd.span_links' - ]); + ])->withSpanLinks(); } } } diff --git a/tests/Integrations/Laravel/V8_x/RouteCachingTest.php b/tests/Integrations/Laravel/V8_x/RouteCachingTest.php index bd32474fc51..688c88ce221 100644 --- a/tests/Integrations/Laravel/V8_x/RouteCachingTest.php +++ b/tests/Integrations/Laravel/V8_x/RouteCachingTest.php @@ -38,7 +38,7 @@ public function testNotCached() 'web', 'App\Http\Controllers\RouteCachingController@unnamed unnamed-route' ) - ->withExactTags([ + ->withExactAttributes([ 'laravel.route.name' => 'unnamed_route', 'laravel.route.action' => 'App\Http\Controllers\RouteCachingController@unnamed', 'http.method' => 'GET', @@ -87,7 +87,7 @@ public function testCached() 'web', 'App\Http\Controllers\RouteCachingController@unnamed unnamed-route' ) - ->withExactTags([ + ->withExactAttributes([ 'laravel.route.name' => 'unnamed_route', 'laravel.route.action' => 'App\Http\Controllers\RouteCachingController@unnamed', 'http.method' => 'GET', diff --git a/tests/Integrations/Lumen/V5_2/CommonScenariosTest.php b/tests/Integrations/Lumen/V5_2/CommonScenariosTest.php index 84f17b9de59..120a02f31c1 100644 --- a/tests/Integrations/Lumen/V5_2/CommonScenariosTest.php +++ b/tests/Integrations/Lumen/V5_2/CommonScenariosTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'GET /simple_view' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simpleView', 'http.method' => 'GET', 'http.url' => 'http://localhost/simple_view?key=value&', @@ -65,7 +65,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'Laravel\Lumen\Application.handleFoundRoute' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simpleView', TAG::COMPONENT => 'lumen' ]) @@ -75,7 +75,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ TAG::COMPONENT => 'laravel' ])->withChildren([ SpanAssertion::build( @@ -83,7 +83,7 @@ public function provideSpecs() 'lumen_test_app', 'web', '*/resources/views/simple_view.blade.php' - )->withExactTags([ + )->withExactAttributes([ TAG::COMPONENT => 'lumen' ]), SpanAssertion::build( @@ -91,7 +91,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'composing: simple_view' - )->withExactTags([ + )->withExactAttributes([ TAG::COMPONENT => 'laravel' ]) ]), @@ -100,7 +100,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'creating: simple_view' - )->withExactTags([ + )->withExactAttributes([ TAG::COMPONENT => 'laravel' ]) ]) @@ -112,14 +112,14 @@ public function provideSpecs() 'lumen_test_app', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@error', 'http.method' => 'GET', 'http.url' => 'http://localhost/error?key=value&', 'http.status_code' => '500', Tag::SPAN_KIND => 'server', TAG::COMPONENT => 'lumen' - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack' ])->setError( 'Exception', @@ -131,11 +131,11 @@ public function provideSpecs() 'lumen_test_app', 'web', 'Laravel\Lumen\Application.handleFoundRoute' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@error', TAG::COMPONENT => 'lumen' ]) - ->withExistingTagsNames([ + ->withExistingAttributeNames([ 'error.stack' ])->setError('Exception', 'Controller error'), SpanAssertion::build( @@ -143,7 +143,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'Laravel\Lumen\Application.sendExceptionToHandler' - )->withExactTags([ + )->withExactAttributes([ TAG::COMPONENT => 'lumen', ]), ]), @@ -160,7 +160,7 @@ protected function getSimpleTrace() 'lumen_test_app', 'web', 'GET /simple' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.name' => 'simple_route', 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', 'http.method' => 'GET', @@ -174,7 +174,7 @@ protected function getSimpleTrace() 'lumen_test_app', 'web', 'simple_route' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', TAG::COMPONENT => 'lumen' ]), @@ -190,7 +190,7 @@ protected function getErrorTrace() 'lumen_test_app', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@error', 'http.method' => 'GET', 'http.url' => 'http://localhost/error?key=value&', @@ -204,10 +204,10 @@ protected function getErrorTrace() 'lumen_test_app', '', 'Laravel\Lumen\Application.handleFoundRoute' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@error', TAG::COMPONENT => 'lumen' - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack' ])->setError('Exception', 'Controller error'), ]), diff --git a/tests/Integrations/Lumen/V5_6/CommonScenariosTest.php b/tests/Integrations/Lumen/V5_6/CommonScenariosTest.php index 56fa51f666d..d41edd2f0a6 100644 --- a/tests/Integrations/Lumen/V5_6/CommonScenariosTest.php +++ b/tests/Integrations/Lumen/V5_6/CommonScenariosTest.php @@ -46,7 +46,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'GET /simple' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.name' => 'simple_route', 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', 'http.method' => 'GET', @@ -60,7 +60,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'simple_route' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', TAG::COMPONENT => 'lumen', ]), @@ -72,7 +72,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'GET /simple_view' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simpleView', 'http.method' => 'GET', 'http.url' => 'http://localhost/simple_view?key=value&', @@ -85,7 +85,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'Laravel\Lumen\Application.handleFoundRoute' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simpleView', TAG::COMPONENT => 'lumen', ])->withChildren([ @@ -94,7 +94,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ TAG::COMPONENT => 'laravel', ])->withChildren([ SpanAssertion::build( @@ -102,7 +102,7 @@ public function provideSpecs() 'lumen_test_app', 'web', '*/resources/views/simple_view.blade.php' - )->withExactTags([ + )->withExactAttributes([ TAG::COMPONENT => 'lumen', ]), SpanAssertion::exists('laravel.event.handle'), @@ -117,14 +117,14 @@ public function provideSpecs() 'lumen_test_app', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@error', 'http.method' => 'GET', 'http.url' => 'http://localhost/error?key=value&', 'http.status_code' => '500', Tag::SPAN_KIND => 'server', TAG::COMPONENT => 'lumen' - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack', ])->setError('Exception', 'Controller error') ->withChildren([ @@ -133,10 +133,10 @@ public function provideSpecs() 'lumen_test_app', 'web', 'Laravel\Lumen\Application.handleFoundRoute' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@error', TAG::COMPONENT => 'lumen' - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack', ])->setError('Exception', 'Controller error'), SpanAssertion::build( @@ -144,7 +144,7 @@ public function provideSpecs() 'lumen_test_app', 'web', 'Laravel\Lumen\Application.sendExceptionToHandler' - )->withExactTags([ + )->withExactAttributes([ TAG::COMPONENT => 'lumen' ])->withChildren([ SpanAssertion::exists('laravel.event.handle'), diff --git a/tests/Integrations/Lumen/V5_6/DeprecatedResourceNameTest.php b/tests/Integrations/Lumen/V5_6/DeprecatedResourceNameTest.php index 59803c874f9..e65dd5336e9 100644 --- a/tests/Integrations/Lumen/V5_6/DeprecatedResourceNameTest.php +++ b/tests/Integrations/Lumen/V5_6/DeprecatedResourceNameTest.php @@ -39,7 +39,7 @@ public function testScenario() 'web', 'GET simple_route' ) - ->withExactTags([ + ->withExactAttributes([ 'lumen.route.name' => 'simple_route', 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', 'http.method' => 'GET', @@ -55,7 +55,7 @@ public function testScenario() 'lumen', 'web', 'simple_route' - )->withExactTags([ + )->withExactAttributes([ 'lumen.route.action' => 'App\Http\Controllers\ExampleController@simple', Tag::COMPONENT => 'lumen', '_dd.svc_src' => 'lumen', diff --git a/tests/Integrations/Memcache/MemcacheTest.php b/tests/Integrations/Memcache/MemcacheTest.php index 787e3387b70..8be29c9c8cb 100644 --- a/tests/Integrations/Memcache/MemcacheTest.php +++ b/tests/Integrations/Memcache/MemcacheTest.php @@ -54,7 +54,7 @@ public function testAdd() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcache.add', 'memcache', 'memcached', 'add') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcache.query' => 'add ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'add', Tag::SPAN_KIND => 'client', @@ -70,7 +70,7 @@ public function testAddNoObfuscation() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcache.add', 'memcache', 'memcached', 'add') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcache.query' => 'add ' . 'key', 'memcache.command' => 'add', Tag::SPAN_KIND => 'client', @@ -85,7 +85,7 @@ public function testAppend() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcache.append', 'memcache', 'memcached', 'append') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcache.query' => 'append ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'append', Tag::SPAN_KIND => 'client', @@ -108,7 +108,7 @@ public function testDelete() SpanAssertion::exists('Memcache.add'), SpanAssertion::exists('Memcache.get'), SpanAssertion::build('Memcache.delete', 'memcache', 'memcached', 'delete') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcache.query' => 'delete ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'delete', Tag::SPAN_KIND => 'client', @@ -131,7 +131,7 @@ public function testDecrement() $this->assertSpans($traces, [ SpanAssertion::exists('Memcache.add'), SpanAssertion::build('Memcache.decrement', 'memcache', 'memcached', 'decrement') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcache.query' => 'decrement ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'decrement', Tag::SPAN_KIND => 'client', @@ -153,7 +153,7 @@ public function testIncrementNonBinaryProtocol() $this->assertSpans($traces, [ SpanAssertion::exists('Memcache.add'), SpanAssertion::build('Memcache.increment', 'memcache', 'memcached', 'increment') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcache.query' => 'increment ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'increment', Tag::SPAN_KIND => 'client', @@ -177,7 +177,7 @@ public function testFlush() SpanAssertion::exists('Memcache.add'), SpanAssertion::exists('Memcache.get'), SpanAssertion::build('Memcache.flush', 'memcache', 'memcached', 'flush') - ->withExactTags([ + ->withExactAttributes([ 'memcache.command' => 'flush', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'memcache', @@ -198,15 +198,14 @@ public function testGet() $this->assertSpans($traces, [ SpanAssertion::exists('Memcache.add'), SpanAssertion::build('Memcache.get', 'memcache', 'memcached', 'get') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcache.query' => 'get ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'get', Tag::SPAN_KIND => 'client', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -220,15 +219,14 @@ public function testGetMissingKey() $this->assertSpans($traces, [ SpanAssertion::exists('Memcache.add'), SpanAssertion::build('Memcache.get', 'memcache', 'memcached', 'get') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcache.query' => 'get ' . Obfuscation::toObfuscatedString('missing_key'), 'memcache.command' => 'get', Tag::SPAN_KIND => 'client', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 0, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -243,7 +241,7 @@ public function testReplace() $this->assertSpans($traces, [ SpanAssertion::exists('Memcache.add'), SpanAssertion::build('Memcache.replace', 'memcache', 'memcached', 'replace') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcache.query' => 'replace ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'replace', Tag::SPAN_KIND => 'client', @@ -259,7 +257,7 @@ public function testSet() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcache.set', 'memcache', 'memcached', 'set') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcache.query' => 'set ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'set', Tag::SPAN_KIND => 'client', @@ -277,12 +275,12 @@ public function testCas() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcache.cas', 'memcache', 'memcached', 'cas') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcache.query' => 'cas ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'cas', Tag::SPAN_KIND => 'client', ])) - ->withExistingTagsNames(['memcache.cas_token']), + ->withExistingAttributeNames(['memcache.cas_token']), ]); } @@ -295,7 +293,7 @@ public function testCommandPeerServiceEnabled() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcache.add', 'memcache', 'memcached', 'add') - ->withExactTags(array_merge(self::baseTags(true), [ + ->withExactAttributes(array_merge(self::baseTags(true), [ 'memcache.query' => 'add ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'add', Tag::SPAN_KIND => 'client', @@ -315,12 +313,12 @@ public function testCasPeerServiceEnabled() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcache.cas', 'memcache', 'memcached', 'cas') - ->withExactTags(array_merge(self::baseTags(true), [ + ->withExactAttributes(array_merge(self::baseTags(true), [ 'memcache.query' => 'cas ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'cas', Tag::SPAN_KIND => 'client', ])) - ->withExistingTagsNames(['memcache.cas_token']), + ->withExistingAttributeNames(['memcache.cas_token']), ]); } @@ -357,7 +355,7 @@ public function testNoFakeServices() $this->assertSpans($traces, [ SpanAssertion::build('Memcache.add', 'configured_service', 'memcached', 'add') - ->withExactTags(array_merge(self::baseTags(false, null), [ + ->withExactAttributes(array_merge(self::baseTags(false, null), [ 'memcache.query' => 'add ' . Obfuscation::toObfuscatedString('key'), 'memcache.command' => 'add', Tag::SPAN_KIND => 'client', diff --git a/tests/Integrations/Memcached/MemcachedTest.php b/tests/Integrations/Memcached/MemcachedTest.php index d0af99e60c3..8db51456d9d 100644 --- a/tests/Integrations/Memcached/MemcachedTest.php +++ b/tests/Integrations/Memcached/MemcachedTest.php @@ -17,7 +17,7 @@ final class MemcachedTest extends IntegrationTestCase private $client; private static $host = 'memcached-integration'; - private static $port = '11211'; + private static $port = 11211; protected function ddSetUp() { @@ -53,7 +53,7 @@ public function testAdd() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.add', 'memcached', 'memcached', 'add') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'add ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'add', Tag::SPAN_KIND => 'client', @@ -68,7 +68,7 @@ public function testAddByKey() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.addByKey', 'memcached', 'memcached', 'addByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'addByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'addByKey', 'memcached.server_key' => 'my_server', @@ -90,12 +90,12 @@ public function testAppendCompressed() $this->assertSpans($traces, [ SpanAssertion::build('Memcached.append', 'memcached', 'memcached', 'append') ->setError() - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'append ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'append', Tag::SPAN_KIND => 'client', ])) - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.type', 'error.stack']), + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.type', 'error.stack']), ]); } @@ -107,7 +107,7 @@ public function testAppendUncompressed() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.append', 'memcached', 'memcached', 'append') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'append ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'append', Tag::SPAN_KIND => 'client', @@ -128,13 +128,13 @@ public function testAppendByKeyCompressed() $this->assertSpans($traces, [ SpanAssertion::build('Memcached.appendByKey', 'memcached', 'memcached', 'appendByKey') ->setError() - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'appendByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'appendByKey', 'memcached.server_key' => 'my_server', Tag::SPAN_KIND => 'client', ])) - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.type', 'error.stack']), + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.type', 'error.stack']), ]); } @@ -147,7 +147,7 @@ public function testAppendByKey() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.appendByKey', 'memcached', 'memcached', 'appendByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'appendByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'appendByKey', 'memcached.server_key' => 'my_server', @@ -171,7 +171,7 @@ public function testDelete() SpanAssertion::exists('Memcached.add'), SpanAssertion::exists('Memcached.get'), SpanAssertion::build('Memcached.delete', 'memcached', 'memcached', 'delete') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'delete ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'delete', Tag::SPAN_KIND => 'client', @@ -195,7 +195,7 @@ public function testDeleteByKey() SpanAssertion::exists('Memcached.addByKey'), SpanAssertion::exists('Memcached.getByKey'), SpanAssertion::build('Memcached.deleteByKey', 'memcached', 'memcached', 'deleteByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'deleteByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'deleteByKey', 'memcached.server_key' => 'my_server', @@ -248,7 +248,7 @@ public function testDeleteMulti() SpanAssertion::exists('Memcached.get'), SpanAssertion::exists('Memcached.get'), SpanAssertion::build('Memcached.deleteMulti', 'memcached', 'memcached', 'deleteMulti') - ->withExactTags(array_merge($this->baseTags(), [ + ->withExactAttributes(array_merge($this->baseTags(), [ 'memcached.query' => 'deleteMulti ' . Obfuscation::toObfuscatedString(['key1', 'key2'], ','), 'memcached.command' => 'deleteMulti', ])), @@ -277,7 +277,7 @@ public function testDeleteMultiByKey() SpanAssertion::exists('Memcached.getByKey'), SpanAssertion::exists('Memcached.getByKey'), SpanAssertion::build('Memcached.deleteMultiByKey', 'memcached', 'memcached', 'deleteMultiByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'deleteMultiByKey ' . Obfuscation::toObfuscatedString(['key1', 'key2'], ','), 'memcached.command' => 'deleteMultiByKey', 'memcached.server_key' => 'my_server', @@ -306,14 +306,14 @@ public function testDecrementBinaryProtocol() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.decrement', 'memcached', 'memcached', 'decrement') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'decrement ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'decrement', Tag::SPAN_KIND => 'client', ])), SpanAssertion::exists('Memcached.get'), SpanAssertion::build('Memcached.decrement', 'memcached', 'memcached', 'decrement') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'decrement ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'decrement', Tag::SPAN_KIND => 'client', @@ -337,7 +337,7 @@ public function testDecrementNonBinaryProtocol() $this->assertSpans($traces, [ SpanAssertion::exists('Memcached.add'), SpanAssertion::build('Memcached.decrement', 'memcached', 'memcached', 'decrement') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'decrement ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'decrement', Tag::SPAN_KIND => 'client', @@ -360,7 +360,7 @@ public function testDecrementByKey() $this->assertSpans($traces, [ SpanAssertion::exists('Memcached.addByKey'), SpanAssertion::build('Memcached.decrementByKey', 'memcached', 'memcached', 'decrementByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'decrementByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'decrementByKey', 'memcached.server_key' => 'my_server', @@ -386,14 +386,14 @@ public function testIncrementBinaryProtocol() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.increment', 'memcached', 'memcached', 'increment') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'increment ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'increment', Tag::SPAN_KIND => 'client', ])), SpanAssertion::exists('Memcached.get'), SpanAssertion::build('Memcached.increment', 'memcached', 'memcached', 'increment') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'increment ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'increment', Tag::SPAN_KIND => 'client', @@ -416,7 +416,7 @@ public function testIncrementNonBinaryProtocol() $this->assertSpans($traces, [ SpanAssertion::exists('Memcached.add'), SpanAssertion::build('Memcached.increment', 'memcached', 'memcached', 'increment') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'increment ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'increment', Tag::SPAN_KIND => 'client', @@ -438,7 +438,7 @@ public function testIncrementByKey() $this->assertSpans($traces, [ SpanAssertion::exists('Memcached.addByKey'), SpanAssertion::build('Memcached.incrementByKey', 'memcached', 'memcached', 'incrementByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'incrementByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'incrementByKey', 'memcached.server_key' => 'my_server', @@ -463,7 +463,7 @@ public function testFlush() SpanAssertion::exists('Memcached.add'), SpanAssertion::exists('Memcached.get'), SpanAssertion::build('Memcached.flush', 'memcached', 'memcached', 'flush') - ->withExactTags(array_merge($this->baseTags(), [ + ->withExactAttributes(array_merge($this->baseTags(), [ 'memcached.command' => 'flush', ])), SpanAssertion::exists('Memcached.get'), @@ -480,15 +480,14 @@ public function testGet() $this->assertSpans($traces, [ SpanAssertion::exists('Memcached.add'), SpanAssertion::build('Memcached.get', 'memcached', 'memcached', 'get') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'get ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'get', Tag::SPAN_KIND => 'client', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -502,15 +501,14 @@ public function testGetMissingKey() $this->assertSpans($traces, [ SpanAssertion::exists('Memcached.add'), SpanAssertion::build('Memcached.get', 'memcached', 'memcached', 'get') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'get ' . Obfuscation::toObfuscatedString('missing_key'), 'memcached.command' => 'get', Tag::SPAN_KIND => 'client', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 0, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -526,14 +524,13 @@ public function testGetMulti() SpanAssertion::exists('Memcached.add'), SpanAssertion::exists('Memcached.add'), SpanAssertion::build('Memcached.getMulti', 'memcached', 'memcached', 'getMulti') - ->withExactTags(array_merge($this->baseTags(), [ + ->withExactAttributes(array_merge($this->baseTags(), [ 'memcached.query' => 'getMulti ' . Obfuscation::toObfuscatedString(['key1', 'key2'], ','), 'memcached.command' => 'getMulti', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 2, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -550,14 +547,13 @@ public function testGetMultiNoObfuscation() SpanAssertion::exists('Memcached.add'), SpanAssertion::exists('Memcached.add'), SpanAssertion::build('Memcached.getMulti', 'memcached', 'memcached', 'getMulti') - ->withExactTags(array_merge($this->baseTags(), [ + ->withExactAttributes(array_merge($this->baseTags(), [ 'memcached.query' => 'getMulti key1,key2', 'memcached.command' => 'getMulti', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 2, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -573,14 +569,13 @@ public function testGetMultiNotAllExist() SpanAssertion::exists('Memcached.add'), SpanAssertion::exists('Memcached.add'), SpanAssertion::build('Memcached.getMulti', 'memcached', 'memcached', 'getMulti') - ->withExactTags(array_merge($this->baseTags(), [ + ->withExactAttributes(array_merge($this->baseTags(), [ 'memcached.query' => 'getMulti ' . Obfuscation::toObfuscatedString(['key1', 'missing_key'], ','), 'memcached.command' => 'getMulti', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -591,14 +586,13 @@ public function testGetMultiNoneExist() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.getMulti', 'memcached', 'memcached', 'getMulti') - ->withExactTags(array_merge($this->baseTags(), [ + ->withExactAttributes(array_merge($this->baseTags(), [ 'memcached.query' => 'getMulti ' . Obfuscation::toObfuscatedString(['key1', 'key2'], ','), 'memcached.command' => 'getMulti', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 0, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -611,16 +605,15 @@ public function testGetByKey() $this->assertSpans($traces, [ SpanAssertion::exists('Memcached.addByKey'), SpanAssertion::build('Memcached.getByKey', 'memcached', 'memcached', 'getByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'getByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'getByKey', 'memcached.server_key' => 'my_server', Tag::SPAN_KIND => 'client', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -639,16 +632,15 @@ public function testGetMultiByKey() SpanAssertion::exists('Memcached.addByKey'), SpanAssertion::exists('Memcached.addByKey'), SpanAssertion::build('Memcached.getMultiByKey', 'memcached', 'memcached', 'getMultiByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'getMultiByKey ' . Obfuscation::toObfuscatedString(['key1', 'key2'], ','), 'memcached.command' => 'getMultiByKey', 'memcached.server_key' => 'my_server', Tag::SPAN_KIND => 'client', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 2, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -663,7 +655,7 @@ public function testReplace() $this->assertSpans($traces, [ SpanAssertion::exists('Memcached.add'), SpanAssertion::build('Memcached.replace', 'memcached', 'memcached', 'replace') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'replace ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'replace', Tag::SPAN_KIND => 'client', @@ -683,7 +675,7 @@ public function testReplaceByKey() $this->assertSpans($traces, [ SpanAssertion::exists('Memcached.addByKey'), SpanAssertion::build('Memcached.replaceByKey', 'memcached', 'memcached', 'replaceByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'replaceByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'replaceByKey', 'memcached.server_key' => 'my_server', @@ -700,7 +692,7 @@ public function testSet() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.set', 'memcached', 'memcached', 'set') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'set ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'set', Tag::SPAN_KIND => 'client', @@ -715,7 +707,7 @@ public function testSetByKey() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.setByKey', 'memcached', 'memcached', 'setByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'setByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'setByKey', 'memcached.server_key' => 'my_server', @@ -733,7 +725,7 @@ public function testSetMulti() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.setMulti', 'memcached', 'memcached', 'setMulti') - ->withExactTags(array_merge($this->baseTags(), [ + ->withExactAttributes(array_merge($this->baseTags(), [ 'memcached.query' => 'setMulti ' . Obfuscation::toObfuscatedString(['key1', 'key2'], ','), 'memcached.command' => 'setMulti', ])), @@ -753,7 +745,7 @@ public function testSetMultiByKey() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.setMultiByKey', 'memcached', 'memcached', 'setMultiByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'setMultiByKey ' . Obfuscation::toObfuscatedString(['key1', 'key2'], ','), 'memcached.command' => 'setMultiByKey', 'memcached.server_key' => 'my_server', @@ -770,7 +762,7 @@ public function testTouch() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.touch', 'memcached', 'memcached', 'touch') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'touch ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'touch', Tag::SPAN_KIND => 'client', @@ -785,7 +777,7 @@ public function testTouchByKey() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.touchByKey', 'memcached', 'memcached', 'touchByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'touchByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'touchByKey', 'memcached.server_key' => 'my_server', @@ -804,12 +796,12 @@ public function testCas() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.cas', 'memcached', 'memcached', 'cas') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'cas ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'cas', Tag::SPAN_KIND => 'client', ])) - ->withExistingTagsNames(['memcached.cas_token']), + ->withExistingAttributeNames(['memcached.cas_token']), ]); } @@ -823,13 +815,13 @@ public function testCasByKey() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.casByKey', 'memcached', 'memcached', 'casByKey') - ->withExactTags(array_merge(self::baseTags(), [ + ->withExactAttributes(array_merge(self::baseTags(), [ 'memcached.query' => 'casByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'casByKey', 'memcached.server_key' => 'my_server', Tag::SPAN_KIND => 'client', ])) - ->withExistingTagsNames(['memcached.cas_token']), + ->withExistingAttributeNames(['memcached.cas_token']), ]); } @@ -857,7 +849,7 @@ public function testCommandPeerServiceEnabled() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.add', 'memcached', 'memcached', 'add') - ->withExactTags(array_merge(self::baseTags(true), [ + ->withExactAttributes(array_merge(self::baseTags(true), [ 'memcached.query' => 'add ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'add', Tag::SPAN_KIND => 'client', @@ -874,7 +866,7 @@ public function testCommandByKeyPeerServiceEnabled() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.addByKey', 'memcached', 'memcached', 'addByKey') - ->withExactTags(array_merge(self::baseTags(true), [ + ->withExactAttributes(array_merge(self::baseTags(true), [ 'memcached.query' => 'addByKey ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'addByKey', 'memcached.server_key' => 'my_server', @@ -897,14 +889,13 @@ public function testMultiPeerServiceEnabled() SpanAssertion::exists('Memcached.add'), SpanAssertion::exists('Memcached.add'), SpanAssertion::build('Memcached.getMulti', 'memcached', 'memcached', 'getMulti') - ->withExactTags(array_merge($this->baseTags(true), [ + ->withExactAttributes(array_merge($this->baseTags(true), [ 'memcached.query' => 'getMulti ' . Obfuscation::toObfuscatedString(['key1', 'key2'], ','), 'memcached.command' => 'getMulti', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 2, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -925,16 +916,15 @@ public function testMultiByKeyPeerServiceEnabled() SpanAssertion::exists('Memcached.addByKey'), SpanAssertion::exists('Memcached.addByKey'), SpanAssertion::build('Memcached.getMultiByKey', 'memcached', 'memcached', 'getMultiByKey') - ->withExactTags(array_merge(self::baseTags(true), [ + ->withExactAttributes(array_merge(self::baseTags(true), [ 'memcached.query' => 'getMultiByKey ' . Obfuscation::toObfuscatedString(['key1', 'key2'], ','), 'memcached.command' => 'getMultiByKey', 'memcached.server_key' => 'my_server', Tag::SPAN_KIND => 'client', - ]))->withExactMetrics([ + ]))->withExactAttributes([ Tag::DB_ROW_COUNT => 2, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -955,7 +945,7 @@ public function testFlushPeerServiceEnabled() SpanAssertion::exists('Memcached.add'), SpanAssertion::exists('Memcached.get'), SpanAssertion::build('Memcached.flush', 'memcached', 'memcached', 'flush') - ->withExactTags(array_merge(self::baseTags(true), [ + ->withExactAttributes(array_merge(self::baseTags(true), [ 'memcached.command' => 'flush', Tag::SPAN_KIND => 'client', ])), @@ -976,12 +966,12 @@ public function testCasPeerServiceEnabled() }); $this->assertSpans($traces, [ SpanAssertion::build('Memcached.cas', 'memcached', 'memcached', 'cas') - ->withExactTags(array_merge(self::baseTags(true), [ + ->withExactAttributes(array_merge(self::baseTags(true), [ 'memcached.query' => 'cas ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'cas', Tag::SPAN_KIND => 'client', ])) - ->withExistingTagsNames(['memcached.cas_token']), + ->withExistingAttributeNames(['memcached.cas_token']), ]); } @@ -1020,7 +1010,7 @@ public function testNoFakeServices() $this->assertSpans($traces, [ SpanAssertion::build('Memcached.add', 'configured_service', 'memcached', 'add') - ->withExactTags(array_merge(self::baseTags(false, null), [ + ->withExactAttributes(array_merge(self::baseTags(false, null), [ 'memcached.query' => 'add ' . Obfuscation::toObfuscatedString('key'), 'memcached.command' => 'add', Tag::SPAN_KIND => 'client', diff --git a/tests/Integrations/Mongo/MongoTest.php b/tests/Integrations/Mongo/MongoTest.php index ce8d036d676..65add7767fb 100644 --- a/tests/Integrations/Mongo/MongoTest.php +++ b/tests/Integrations/Mongo/MongoTest.php @@ -46,7 +46,7 @@ public function testClientConnectAndClose() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoClient.__construct', 'mongo', 'mongodb', '__construct') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.server' => 'mongodb://mongodb-integration:27017', 'mongodb.db' => self::DATABASE, Tag::COMPONENT => 'mongo', @@ -76,7 +76,7 @@ public function testSecretsAreSanitizedFromDsnString() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoClient.__construct', 'mongo', 'mongodb', '__construct') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.server' => 'mongodb://?:?@mongodb-integration:27017', 'mongodb.db' => self::DATABASE, Tag::COMPONENT => 'mongo', @@ -106,7 +106,7 @@ public function testDatabaseNameExtractedFromDsnString() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoClient.__construct', 'mongo', 'mongodb', '__construct') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.server' => 'mongodb://mongodb-integration:27017/' . self::DATABASE, 'mongodb.db' => self::DATABASE, Tag::COMPONENT => 'mongo', @@ -124,7 +124,7 @@ public function testClientSelectCollection() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoClient.selectCollection', 'mongo', 'mongodb', 'selectCollection') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.collection' => 'foo_collection', 'mongodb.db' => self::DATABASE, Tag::COMPONENT => 'mongo', @@ -142,7 +142,7 @@ public function testSelectDB() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoClient.selectDB', 'mongo', 'mongodb', 'selectDB') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.db' => self::DATABASE, Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -159,7 +159,7 @@ public function testClientSetReadPreference() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoClient.setReadPreference', 'mongo', 'mongodb', 'setReadPreference') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.read_preference' => MongoClient::RP_NEAREST, Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -176,7 +176,7 @@ public function testClientSetWriteConcern() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoClient.setWriteConcern', 'mongo', 'mongodb', 'setWriteConcern') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -195,7 +195,7 @@ public function testClientMethods($method) $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoClient.' . $method, 'mongo', 'mongodb', $method) - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -226,9 +226,9 @@ public function testCommandWithQueryAndTimeout() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoDB.command', 'mongo', 'mongodb', 'command') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.query' => '{"age":{"$gte":18}}', - 'mongodb.timeout' => '500', + 'mongodb.timeout' => 500, Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -244,7 +244,7 @@ public function testCreateDBRef() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoDB.createDBRef', 'mongo', 'mongodb', 'createDBRef') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.collection' => 'foo_collection', 'mongodb.bson.id' => '47cc67093475061e3d9536d2', Tag::COMPONENT => 'mongo', @@ -262,7 +262,7 @@ public function testCreateCollection() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoDB.createCollection', 'mongo', 'mongodb', 'createCollection') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.collection' => 'foo_collection', Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -279,7 +279,7 @@ public function testExecute() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoDB.execute', 'mongo', 'mongodb', 'execute') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -298,7 +298,7 @@ public function testGetDBRef() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoDB.getDBRef', 'mongo', 'mongodb', 'getDBRef') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.collection' => 'foo_collection', Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -315,7 +315,7 @@ public function testSelectCollection() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoDB.selectCollection', 'mongo', 'mongodb', 'selectCollection') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.collection' => 'foo_collection', Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -332,8 +332,8 @@ public function testSetProfilingLevel() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoDB.setProfilingLevel', 'mongo', 'mongodb', 'setProfilingLevel') - ->withExactTags([ - 'mongodb.profiling_level' => '2', + ->withExactAttributes([ + 'mongodb.profiling_level' => 2, Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -349,7 +349,7 @@ public function testSetReadPreference() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoDB.setReadPreference', 'mongo', 'mongodb', 'setReadPreference') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.read_preference' => MongoClient::RP_NEAREST, Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -366,7 +366,7 @@ public function testSetWriteConcern() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoDB.setWriteConcern', 'mongo', 'mongodb', 'setWriteConcern') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -385,7 +385,7 @@ public function testDBWithDefaultTags($method) $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoDB.' . $method, 'mongo', 'mongodb', $method) - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -418,7 +418,7 @@ public function testCollection() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.__construct', 'mongo', 'mongodb', '__construct') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'foo_collection', Tag::COMPONENT => 'mongo', @@ -436,7 +436,7 @@ public function testCollectionAggregate() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.aggregate', 'mongo', 'mongodb', 'aggregate') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -466,7 +466,7 @@ public function testCollectionBatchInsert() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.batchInsert', 'mongo', 'mongodb', 'batchInsert') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -482,7 +482,7 @@ public function testCollectionCount() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.count', 'mongo', 'mongodb', 'count') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.query' => '{"title":"Foo"}', Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -499,7 +499,7 @@ public function testCollectionCreateDBRef() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.createDBRef', 'mongo', 'mongodb', 'createDBRef') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.bson.id' => '47cc67093475061e3d9536d2', 'mongodb.collection' => 'foo_collection', Tag::COMPONENT => 'mongo', @@ -517,7 +517,7 @@ public function testCollectionCreateIndex() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.createIndex', 'mongo', 'mongodb', 'createIndex') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -533,7 +533,7 @@ public function testCollectionDeleteIndex() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.deleteIndex', 'mongo', 'mongodb', 'deleteIndex') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -549,7 +549,7 @@ public function testCollectionDistinct() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.distinct', 'mongo', 'mongodb', 'distinct') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.query' => '{"foo":"bar"}', Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -566,7 +566,7 @@ public function testCollectionFind() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.find', 'mongo', 'mongodb', 'find') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.query' => '{"foo":"bar"}', Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -588,7 +588,7 @@ public function testCollectionFindAndModify() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.findAndModify', 'mongo', 'mongodb', 'findAndModify') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.query' => '{"foo":"bar"}', Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -605,7 +605,7 @@ public function testCollectionFindOne() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.findOne', 'mongo', 'mongodb', 'findOne') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.query' => '{"foo":"bar"}', Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -625,7 +625,7 @@ public function testCollectionGetDBRef() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.getDBRef', 'mongo', 'mongodb', 'getDBRef') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.bson.id' => '47cc67093475061e3d9536d2', 'mongodb.collection' => 'foo_collection', Tag::COMPONENT => 'mongo', @@ -647,7 +647,7 @@ public function testCollectionGroup() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.group', 'mongo', 'mongodb', 'group') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -663,7 +663,7 @@ public function testCollectionInsert() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.insert', 'mongo', 'mongodb', 'insert') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -684,7 +684,7 @@ public function testCollectionParallelCollectionScan() 'mongodb', 'parallelCollectionScan' ) - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -700,7 +700,7 @@ public function testCollectionRemove() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.remove', 'mongo', 'mongodb', 'remove') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.query' => '{"foo":"bar"}', Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -717,7 +717,7 @@ public function testCollectionSave() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.save', 'mongo', 'mongodb', 'save') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -733,7 +733,7 @@ public function testCollectionSetReadPreference() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.setReadPreference', 'mongo', 'mongodb', 'setReadPreference') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.read_preference' => MongoClient::RP_NEAREST, Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -750,7 +750,7 @@ public function testCollectionSetWriteConcern() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.setWriteConcern', 'mongo', 'mongodb', 'setWriteConcern') - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', @@ -769,7 +769,7 @@ public function testCollectionUpdate() $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.update', 'mongo', 'mongodb', 'update') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.query' => '{"foo":"bar"}', Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', @@ -789,7 +789,7 @@ public function testCollectionMethods($method) $this->assertFlameGraph($traces, [ SpanAssertion::build('MongoCollection.' . $method, 'mongo', 'mongodb', $method) - ->withExactTags([ + ->withExactAttributes([ Tag::COMPONENT => 'mongo', '_dd.svc_src' => 'mongo', Tag::DB_SYSTEM => 'mongodb', diff --git a/tests/Integrations/MongoDB/Latest/MongoDBTest.php b/tests/Integrations/MongoDB/Latest/MongoDBTest.php index f06ef682878..d4d2dba459b 100644 --- a/tests/Integrations/MongoDB/Latest/MongoDBTest.php +++ b/tests/Integrations/MongoDB/Latest/MongoDBTest.php @@ -15,7 +15,7 @@ class MongoDBTest extends IntegrationTestCase protected static $lockedResource = "mongodb"; const HOST = 'mongodb-integration'; - const PORT = '27017'; + const PORT = 27017; const USER = 'test'; const PASSWORD = 'test'; const DATABASE = 'test'; @@ -52,7 +52,7 @@ public function testFilterNormalizationRegex() { $expected = [ SpanAssertion::build('mongodb.cmd', 'mongodb', 'mongodb', 'find test cars {"brand":"?"}') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'mongodb.query' => '{"brand":"?"}', @@ -97,7 +97,7 @@ public function testFilterAggregation() 'mongodb', 'mongodb', 'aggregate test cars [{"$group":{"_id":"?","count":{"$sum":"?"}}},{"$sort":{"count":"?"}},{"$limit":"?"}]' - )->withExactTags([ + )->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'mongodb.query' => '[{"$group":{"_id":"?","count":{"$sum":"?"}}},{"$sort":{"count":"?"}},{"$limit":"?"}]', @@ -157,7 +157,7 @@ public function testCollectionBulkWrite() 'mongodb', 'mongodb', 'bulkWrite test cars' - )->withExactTags([ + )->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'span.kind' => 'client', @@ -201,9 +201,9 @@ public function testException() } $this->assertFlameGraph($traces, [ SpanAssertion::build('mongodb.cmd', 'mongodb', 'mongodb', 'find test cars "?"') - ->withExactTags($tags) + ->withExactAttributes($tags) ->setError($errorType) - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.stack']), + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.stack']), ]); } @@ -214,7 +214,7 @@ public function testMethodsWithFilter($method, $args) { $expected = [ SpanAssertion::build('mongodb.cmd', 'mongodb', 'mongodb', "$method test cars {\"brand\":\"?\"}") - ->withExactTags([ + ->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'mongodb.query' => '{"brand":"?"}', @@ -297,7 +297,7 @@ public function testMethodsNoArgs($method, $args) { $expected = [ SpanAssertion::build('mongodb.cmd', 'mongodb', 'mongodb', "$method test cars") - ->withExactTags([ + ->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'span.kind' => 'client', @@ -396,9 +396,9 @@ public function testQueryNormalization($query, $expected) }); if (null === $expected) { - $this->assertArrayNotHasKey('mongodb.query', $traces[0][0]['attributes']); + $this->assertArrayNotHasKey('mongodb.query', $traces[0]['spans'][0]['attributes']); } else { - $this->assertSame($expected, $traces[0][0]['attributes']['mongodb.query']); + $this->assertSame($expected, $traces[0]['spans'][0]['attributes']['mongodb.query']); } } @@ -441,7 +441,7 @@ public function testManagerExecuteQuery() { $expected = [ SpanAssertion::build('mongodb.driver.cmd', 'mongodb', 'mongodb', 'executeQuery test cars {"brand":"?"}') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'mongodb.query' => '{"brand":"?"}', @@ -486,7 +486,7 @@ public function testManagerExecuteCommand() 'mongodb', 'mongodb', 'executeCommand test ' . $collectionName . ' create' - )->withExactTags([ + )->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => $collectionName, 'span.kind' => 'client', @@ -531,7 +531,7 @@ public function testManagerExecuteReadCommand() 'mongodb', 'mongodb', 'executeReadCommand test cars find' - )->withExactTags([ + )->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'span.kind' => 'client', @@ -588,7 +588,7 @@ public function testManagerExecuteWriteCommand() 'mongodb', 'mongodb', 'executeWriteCommand test cars insert' - )->withExactTags([ + )->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'span.kind' => 'client', @@ -645,7 +645,7 @@ public function testManagerExecuteReadWriteCommand() 'mongodb', 'mongodb', 'executeReadWriteCommand test cars insert' - )->withExactTags([ + )->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'span.kind' => 'client', @@ -713,7 +713,7 @@ public function testManagerExecuteBulkWrite() 'mongodb', 'mongodb', 'executeBulkWrite test cars' - )->withExactTags([ + )->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'span.kind' => 'client', @@ -750,7 +750,7 @@ public function testManagerFailure() 'mongodb', 'mongodb', 'executeWriteCommand test insert' - )->withExactTags([ + )->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'span.kind' => 'client', 'out.host' => self::HOST, @@ -759,7 +759,7 @@ public function testManagerFailure() '_dd.svc_src' => 'mongodb', Tag::DB_SYSTEM => 'mongodb', ])->setError() - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.stack']), + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.stack']), ]); } @@ -770,7 +770,7 @@ public function testManagerExecuteQueryPeerServiceEnabled() $expected = [ SpanAssertion::build('mongodb.driver.cmd', 'mongodb', 'mongodb', 'executeQuery test cars {"brand":"?"}') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'mongodb.query' => '{"brand":"?"}', @@ -814,7 +814,7 @@ public function testManagerExecuteBulkWritePeerServiceEnabled() 'mongodb', 'mongodb', 'executeBulkWrite test cars' - )->withExactTags([ + )->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'span.kind' => 'client', @@ -844,7 +844,7 @@ public function testManagerExecuteCommandPeerServiceEnabled() 'mongodb', 'mongodb', 'executeCommand test ' . $collectionName . ' create' - )->withExactTags([ + )->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => $collectionName, 'span.kind' => 'client', @@ -873,7 +873,7 @@ public function testMethodsWithFilterPeerServiceEnabled() $expected = [ SpanAssertion::build('mongodb.cmd', 'mongodb', 'mongodb', "count test cars {\"brand\":\"?\"}") - ->withExactTags([ + ->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'mongodb.query' => '{"brand":"?"}', @@ -915,7 +915,7 @@ public function testNoFakeServices() $this->assertFlameGraph( $traces, [SpanAssertion::build('mongodb.cmd', 'configured_service', 'mongodb', 'find test cars {"brand":"?"}') - ->withExactTags([ + ->withExactAttributes([ 'mongodb.db' => self::DATABASE, 'mongodb.collection' => 'cars', 'mongodb.query' => '{"brand":"?"}', diff --git a/tests/Integrations/Mysqli/MysqliTest.php b/tests/Integrations/Mysqli/MysqliTest.php index fc532c77b28..067d65804df 100644 --- a/tests/Integrations/Mysqli/MysqliTest.php +++ b/tests/Integrations/Mysqli/MysqliTest.php @@ -5,6 +5,7 @@ use DDTrace\Tag; use DDTrace\Tests\Common\IntegrationTestCase; use DDTrace\Tests\Common\SpanAssertion; +use DDTrace\Tests\Common\SpanChecker; use function DDTrace\close_span; use function DDTrace\start_trace_span; @@ -12,7 +13,7 @@ class MysqliTest extends IntegrationTestCase { private static $host = 'mysql-integration'; public static $database = 'mysqlitest'; - private static $port = '3306'; + private static $port = 3306; private static $user = 'test'; private static $password = 'test'; @@ -53,7 +54,7 @@ public function testProceduralConnect() $this->assertFlameGraph($traces, [ SpanAssertion::build('mysqli_connect', 'mysqli', 'sql', 'mysqli_connect') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags()), ]); } @@ -70,8 +71,8 @@ public function testProceduralConnectErrorThrowsException() $this->assertFlameGraph($traces, [ SpanAssertion::build('mysqli_connect', 'mysqli', 'sql', 'mysqli_connect') ->setError() - ->withExactTags(self::baseTags(false)) - ->withExistingTagsNames([ + ->withExactAttributes(self::baseTags(false)) + ->withExistingAttributeNames([ Tag::ERROR_MSG, 'error.type', 'error.stack', @@ -92,8 +93,8 @@ public function testProceduralConnectDontReportError() $this->assertFlameGraph($traces, [ SpanAssertion::build('mysqli_connect', 'mysqli', 'sql', 'mysqli_connect') ->setError() - ->withExactTags(self::baseTags(false)) - ->withExistingTagsNames([ + ->withExactAttributes(self::baseTags(false)) + ->withExistingAttributeNames([ Tag::ERROR_MSG, 'error.type', 'error.stack', @@ -110,7 +111,7 @@ public function testConstructorConnect() $this->assertFlameGraph($traces, [ SpanAssertion::build('mysqli.__construct', 'mysqli', 'sql', 'mysqli.__construct') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags()), ]); } @@ -125,12 +126,10 @@ public function testProceduralQuery() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli_connect', 'mysqli_connect'), SpanAssertion::build('mysqli_query', 'mysqli', 'sql', 'SELECT * from tests') - ->withExactTags(self::baseTags(true, false)) - ->withExactMetrics([ + ->withExactAttributes(self::baseTags(true, false), [ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -145,11 +144,9 @@ public function testProceduralRealQuery() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli_connect', 'mysqli_connect'), SpanAssertion::build('mysqli_real_query', 'mysqli', 'sql', 'SELECT * from tests') - ->withExactTags(self::baseTags(true, false)) - ->withExactMetrics([ + ->withExactAttributes(self::baseTags(true, false), [ '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -165,12 +162,10 @@ public function testProceduralQueryPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli_connect', 'mysqli_connect'), SpanAssertion::build('mysqli_query', 'mysqli', 'sql', 'SELECT * from tests') - ->withExactTags(self::baseTags(true, true)) - ->withExactMetrics([ + ->withExactAttributes(self::baseTags(true, true), [ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -189,7 +184,7 @@ public function testProceduralExecuteQuery() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli_connect', 'mysqli_connect'), SpanAssertion::build('mysqli_execute_query', 'mysqli', 'sql', 'SELECT * from tests WHERE 1 = ?') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags(), [Tag::DB_ROW_COUNT => 1]), ]); } @@ -210,7 +205,7 @@ public function testProceduralExecuteQueryPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli_connect', 'mysqli_connect'), SpanAssertion::build('mysqli_execute_query', 'mysqli', 'sql', 'SELECT * from tests WHERE 1 = ?') - ->withExactTags(self::baseTags(true, true)), + ->withExactAttributes(self::baseTags(true, true), [Tag::DB_ROW_COUNT => 1]), ]); } @@ -225,14 +220,12 @@ public function testProceduralQueryRealConnect() $this->assertFlameGraph($traces, [ SpanAssertion::build('mysqli_real_connect', 'mysqli', 'sql', 'mysqli_real_connect') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags()), SpanAssertion::build('mysqli_query', 'mysqli', 'sql', 'SELECT * from tests') - ->withExactTags(self::baseTags()) - ->withExactMetrics([ + ->withExactAttributes(self::baseTags(), [ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -249,14 +242,12 @@ public function testProceduralQueryRealConnectPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::build('mysqli_real_connect', 'mysqli', 'sql', 'mysqli_real_connect') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags()), SpanAssertion::build('mysqli_query', 'mysqli', 'sql', 'SELECT * from tests') - ->withExactTags(self::baseTags(true, true)) - ->withExactMetrics([ + ->withExactAttributes(self::baseTags(true, true), [ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -271,12 +262,10 @@ public function testConstructorQuery() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli.__construct', 'mysqli.__construct'), SpanAssertion::build('mysqli.query', 'mysqli', 'sql', 'SELECT * from tests') - ->withExactTags(self::baseTags()) - ->withExactMetrics([ + ->withExactAttributes(self::baseTags(), [ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -291,11 +280,9 @@ public function testConstructorRealQuery() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli.__construct', 'mysqli.__construct'), SpanAssertion::build('mysqli.real_query', 'mysqli', 'sql', 'SELECT * from tests') - ->withExactTags(self::baseTags()) - ->withExactMetrics([ + ->withExactAttributes(self::baseTags(), [ '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -312,12 +299,10 @@ public function testConstructorQueryPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli.__construct', 'mysqli.__construct'), SpanAssertion::build('mysqli.query', 'mysqli', 'sql', 'SELECT * from tests') - ->withExactTags(self::baseTags(true, true)) - ->withExactMetrics([ + ->withExactAttributes(self::baseTags(true, true), [ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -333,14 +318,12 @@ public function testEmptyConstructorQuery() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli.__construct', 'mysqli.__construct'), SpanAssertion::build('mysqli.real_connect', 'mysqli', 'sql', 'mysqli.real_connect') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags()), SpanAssertion::build('mysqli.query', 'mysqli', 'sql', 'SELECT * from tests') - ->withExactTags(self::baseTags()) - ->withExactMetrics([ + ->withExactAttributes(self::baseTags(), [ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -358,14 +341,12 @@ public function testEmptyConstructorQueryPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli.__construct', 'mysqli.__construct'), SpanAssertion::build('mysqli.real_connect', 'mysqli', 'sql', 'mysqli.real_connect') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags()), SpanAssertion::build('mysqli.query', 'mysqli', 'sql', 'SELECT * from tests') - ->withExactTags(self::baseTags(true, true)) - ->withExactMetrics([ + ->withExactAttributes(self::baseTags(true, true), [ Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -384,7 +365,7 @@ public function testProceduralCommit() SpanAssertion::exists('mysqli_connect', 'mysqli_connect'), SpanAssertion::exists('mysqli_query', $query), SpanAssertion::build('mysqli_commit', 'mysqli', 'sql', $query) - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags()), ]); } @@ -404,9 +385,9 @@ public function testConstructorPreparedStatement() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli.__construct', 'mysqli.__construct'), SpanAssertion::build('mysqli.prepare', 'mysqli', 'sql', 'INSERT INTO tests (id, name) VALUES (?, ?)') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags(), [Tag::DB_ROW_COUNT => 0]), SpanAssertion::build('mysqli_stmt.execute', 'mysqli', 'sql', 'INSERT INTO tests (id, name) VALUES (?, ?)') - ->withExactTags(self::baseTags()) + ->withExactAttributes(self::baseTags()) ]); } @@ -428,9 +409,9 @@ public function testConstructorPreparedStatementPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli.__construct', 'mysqli.__construct'), SpanAssertion::build('mysqli.prepare', 'mysqli', 'sql', 'INSERT INTO tests (id, name) VALUES (?, ?)') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags(), [Tag::DB_ROW_COUNT => 0]), SpanAssertion::build('mysqli_stmt.execute', 'mysqli', 'sql', 'INSERT INTO tests (id, name) VALUES (?, ?)') - ->withExactTags(self::baseTags(true, true)) + ->withExactAttributes(self::baseTags(true, true)) ]); } @@ -448,7 +429,7 @@ public function testProceduralSelectDbPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli_connect', 'mysqli_connect'), SpanAssertion::build('mysqli_query', 'mysqli', 'sql', 'SELECT * from columns limit 1') - ->withExactTags(array_merge( + ->withExactAttributes(array_merge( self::baseTags(true, true), [ 'db.name' => 'information_schema', @@ -457,7 +438,7 @@ public function testProceduralSelectDbPeerServiceEnabled() '_dd.base_service' => 'phpunit', ] )) - ->withExactMetrics([ + ->withExactAttributes([ Tag::DB_ROW_COUNT => 1, ]), ], true, false); @@ -477,7 +458,7 @@ public function testConstructorSelectDbPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli.__construct', 'mysqli.__construct'), SpanAssertion::build('mysqli.query', 'mysqli', 'sql', 'SELECT * from columns limit 1') - ->withExactTags(array_merge( + ->withExactAttributes(array_merge( self::baseTags(true, true), [ 'db.name' => 'information_schema', @@ -486,7 +467,7 @@ public function testConstructorSelectDbPeerServiceEnabled() '_dd.base_service' => 'phpunit' ] )) - ->withExactMetrics([ + ->withExactAttributes([ Tag::DB_ROW_COUNT => 1, ]), ], true, false); @@ -549,9 +530,9 @@ public function testProceduralPreparedStatement() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli_connect', 'mysqli_connect'), SpanAssertion::build('mysqli_prepare', 'mysqli', 'sql', 'INSERT INTO tests (id, name) VALUES (?, ?)') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags(), [Tag::DB_ROW_COUNT => 0]), SpanAssertion::build('mysqli_stmt_execute', 'mysqli', 'sql', 'INSERT INTO tests (id, name) VALUES (?, ?)') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags()), ], true, false); } @@ -574,9 +555,9 @@ public function testProceduralPreparedStatementPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli_connect', 'mysqli_connect'), SpanAssertion::build('mysqli_prepare', 'mysqli', 'sql', 'INSERT INTO tests (id, name) VALUES (?, ?)') - ->withExactTags(self::baseTags()), + ->withExactAttributes(self::baseTags(), [Tag::DB_ROW_COUNT => 0]), SpanAssertion::build('mysqli_stmt_execute', 'mysqli', 'sql', 'INSERT INTO tests (id, name) VALUES (?, ?)') - ->withExactTags(self::baseTags(true, true)), + ->withExactAttributes(self::baseTags(true, true)), ]); } @@ -602,7 +583,7 @@ public function testPreparedStatementUsesServiceModeForDBM() }); // Get the raw spans - $spans = $traces[0]; + $spans = (new SpanChecker())->flattenTraces($traces); // Find prepare and execute spans $constructSpan = null; @@ -654,7 +635,7 @@ public function testConstructorConnectError() $this->assertFlameGraph($traces, [ SpanAssertion::build('mysqli.__construct', 'mysqli', 'sql', 'mysqli.__construct') ->setError() - ->withExistingTagsNames([ + ->withExistingAttributeNames([ Tag::ERROR_MSG, 'error.type', 'error.stack', @@ -683,8 +664,7 @@ public function testNoFakeServices() $this->assertFlameGraph($traces, [ SpanAssertion::exists('mysqli.__construct', 'mysqli.__construct'), SpanAssertion::build('mysqli.query', 'configured_service', 'sql', 'SELECT * from tests') - ->withExactTags(self::baseTags(true, false, null)) - ->withExactMetrics([ + ->withExactAttributes(self::baseTags(true, false, null), [ Tag::DB_ROW_COUNT => 1, ]), ], true, false); diff --git a/tests/Integrations/Nette/Latest/NetteTest.php b/tests/Integrations/Nette/Latest/NetteTest.php index 5551eda3c23..5fcd145ece6 100644 --- a/tests/Integrations/Nette/Latest/NetteTest.php +++ b/tests/Integrations/Nette/Latest/NetteTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'nette_test_app', 'web', 'GET /simple' - )->withExactTags([ + )->withExactAttributes([ 'nette.route.presenter' => 'Homepage', 'nette.route.action' => 'simple', 'http.method' => 'GET', @@ -66,7 +66,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.configurator.createRobotLoader' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]), SpanAssertion::build( @@ -74,7 +74,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ])->withChildren([ SpanAssertion::build( @@ -82,7 +82,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.presenter.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]) ]) @@ -94,7 +94,7 @@ public function provideSpecs() 'nette_test_app', 'web', 'GET /simple_view' - )->withExactTags([ + )->withExactAttributes([ 'nette.route.presenter' => 'Homepage', 'nette.route.action' => 'simpleView', 'http.method' => 'GET', @@ -108,7 +108,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.configurator.createRobotLoader' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]), SpanAssertion::build( @@ -116,7 +116,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ])->withChildren([ SpanAssertion::build( @@ -124,7 +124,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.presenter.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]), SpanAssertion::build( @@ -132,7 +132,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.latte.render' - )->withExactTags([ + )->withExactAttributes([ 'nette.latte.templateName' => '%s', Tag::COMPONENT => 'nette', ])->withChildren([ @@ -148,7 +148,7 @@ public function provideSpecs() 'nette_test_app', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ 'nette.route.presenter' => 'Homepage', 'nette.route.action' => 'errorView', 'http.method' => 'GET', @@ -168,7 +168,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.configurator.createRobotLoader' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]), SpanAssertion::build( @@ -176,7 +176,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ])->withChildren([ SpanAssertion::build( @@ -184,11 +184,11 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.presenter.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]) ]) ], diff --git a/tests/Integrations/Nette/V2_4/NetteTest.php b/tests/Integrations/Nette/V2_4/NetteTest.php index 4fb1fae30dd..b40429be7bf 100644 --- a/tests/Integrations/Nette/V2_4/NetteTest.php +++ b/tests/Integrations/Nette/V2_4/NetteTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'nette_test_app', 'web', 'GET /simple' - )->withExactTags([ + )->withExactAttributes([ 'nette.route.presenter' => 'Homepage', 'nette.route.action' => 'simple', 'http.method' => 'GET', @@ -66,7 +66,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.configurator.createRobotLoader' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]), SpanAssertion::build( @@ -74,7 +74,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ])->withChildren([ SpanAssertion::build( @@ -82,7 +82,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.presenter.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]), ]) @@ -94,7 +94,7 @@ public function provideSpecs() 'nette_test_app', 'web', 'GET /simple_view' - )->withExactTags([ + )->withExactAttributes([ 'nette.route.presenter' => 'Homepage', 'nette.route.action' => 'simpleView', 'http.method' => 'GET', @@ -108,7 +108,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.configurator.createRobotLoader' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]), SpanAssertion::build( @@ -116,7 +116,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ])->withChildren([ SpanAssertion::build( @@ -124,7 +124,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.presenter.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]), SpanAssertion::build( @@ -132,7 +132,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.latte.render' - )->withExactTags([ + )->withExactAttributes([ 'nette.latte.templateName' => '%s', Tag::COMPONENT => 'nette', ])->withChildren([ @@ -148,7 +148,7 @@ public function provideSpecs() 'nette_test_app', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ 'nette.route.presenter' => 'Homepage', 'nette.route.action' => 'errorView', 'http.method' => 'GET', @@ -164,7 +164,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.configurator.createRobotLoader' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]), SpanAssertion::build( @@ -172,7 +172,7 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ])->withChildren([ SpanAssertion::build( @@ -180,11 +180,11 @@ public function provideSpecs() 'nette_test_app', Type::WEB_SERVLET, 'nette.presenter.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'nette', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]) ]) ], diff --git a/tests/Integrations/PCNTL/PCNTLTest.php b/tests/Integrations/PCNTL/PCNTLTest.php index eaf857d263b..f6b7b1aa3a6 100644 --- a/tests/Integrations/PCNTL/PCNTLTest.php +++ b/tests/Integrations/PCNTL/PCNTLTest.php @@ -76,9 +76,9 @@ public function testCliShortRunningTracingWhenEnabled() SpanAssertion::exists('synthetic.php'), ]); - $childSpan = $requests[0][0]; - $parentSpan = $requests[1][1]; - $this->assertSame($childSpan["trace_id"], $parentSpan["trace_id"]); + $childSpan = $requests[0]['spans'][0]; + $parentSpan = $requests[1]['spans'][1]; + $this->assertSame($requests[0]["trace_id"], $requests[1]["trace_id"]); $this->assertSame($childSpan["parent_id"], $parentSpan["span_id"]); } catch (\Exception $e) { echo "Raw requests:\n"; @@ -274,7 +274,7 @@ public function testCliLongRunningMultipleForksManualFlush() // Individual root spans must be their own traces! No merging allowed. $this->assertCount(9, $requests); - usort($requests, function ($a, $b) { return $a[0]["resource"] <=> $b[0]["resource"]; }); + usort($requests, function ($a, $b) { return $a["spans"][0]["resource"] <=> $b["spans"][0]["resource"]; }); for ($i = 0; $i < 3; ++$i) { $this->assertFlameGraph([$requests[$i]], [ diff --git a/tests/Integrations/PDO/PDOTest.php b/tests/Integrations/PDO/PDOTest.php index 6d508bfba84..aabe0abbfc5 100644 --- a/tests/Integrations/PDO/PDOTest.php +++ b/tests/Integrations/PDO/PDOTest.php @@ -6,6 +6,7 @@ use DDTrace\Tag; use DDTrace\Tests\Common\IntegrationTestCase; use DDTrace\Tests\Common\SpanAssertion; +use DDTrace\Tests\Common\SpanChecker; use ReflectionMethod; use function DDTrace\close_span; use function DDTrace\start_trace_span; @@ -81,19 +82,17 @@ public function testCustomPDOPrepareWithStringableStatement() 'pdo', 'sql', $query - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), SpanAssertion::build( 'PDOStatement.execute', 'pdo', 'sql', $query ) - ->withExactTags($this->baseTags()) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes($this->baseTags(), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -123,7 +122,7 @@ public function testBrokenPDOPrepareWithNonStringableStatement() 'object(DDTrace\Tests\Integrations\PDO\BrokenPDOStatement)#' . $objId ) ->setError() - ->withExactTags(SpanAssertion::NOT_TESTED), + ->withExactAttributes(SpanAssertion::NOT_TESTED), ]); } @@ -155,7 +154,7 @@ public function testPDOConstructOk() }); $this->assertSpans($traces, [ SpanAssertion::build('PDO.__construct', 'pdo', 'sql', 'PDO.__construct') - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), ]); } @@ -171,7 +170,7 @@ public function testPDOConnectOk() }); $this->assertSpans($traces, [ SpanAssertion::build('PDO.connect', 'pdo', 'sql', 'PDO.connect') - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), ]); } @@ -184,7 +183,7 @@ public function testPDOConstructPeerServiceEnabled() }); $this->assertSpans($traces, [ SpanAssertion::build('PDO.__construct', 'pdo', 'sql', 'PDO.__construct') - ->withExactTags($this->baseTags(true)), + ->withExactAttributes($this->baseTags(true)), ]); } @@ -202,7 +201,7 @@ public function testPDOConnectPeerServiceEnabled() }); $this->assertSpans($traces, [ SpanAssertion::build('PDO.connect', 'pdo', 'sql', 'PDO.connect') - ->withExactTags($this->baseTags(true)), + ->withExactAttributes($this->baseTags(true)), ]); } @@ -215,7 +214,7 @@ public function testPDOSplitByDomain() $this->assertSpans($traces, [ SpanAssertion::build('PDO.__construct', 'pdo-mysql-integration', 'sql', 'PDO.__construct') - ->withExactTags($this->baseTags(false, 'opt.db_client_split_by_instance')), + ->withExactAttributes($this->baseTags(false, 'opt.db_client_split_by_instance')), ]); } @@ -229,7 +228,7 @@ public function testPDOServiceMappedSplitByDomain() $this->assertSpans($traces, [ SpanAssertion::build('PDO.__construct', 'my-pdo-mysql-integration', 'sql', 'PDO.__construct') - ->withExactTags($this->baseTags(false, 'opt.db_client_split_by_instance')), + ->withExactAttributes($this->baseTags(false, 'opt.db_client_split_by_instance')), ]); } @@ -243,7 +242,7 @@ public function testPDOConstructError() }); $this->assertSpans($traces, [ SpanAssertion::build('PDO.__construct', 'pdo', 'sql', 'PDO.__construct') - ->withExactTags(array_merge($this->baseTags(), [ + ->withExactAttributes(array_merge($this->baseTags(), [ 'db.user' => 'wrong_user', ])) ->setError('PDOException', static::ERROR_CONSTRUCT, true), @@ -263,12 +262,10 @@ public function testPDOExecOk() $this->assertSpans($traces, [ SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.exec', 'pdo', 'sql', $query) - ->withExactTags($this->baseTags()) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes($this->baseTags(), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), SpanAssertion::exists('PDO.commit'), ]); } @@ -290,7 +287,7 @@ public function testPDOExecError() SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.exec', 'pdo', 'sql', $query) ->setError('PDO error', 'SQL error: 42000. Driver error: 1064. Driver-specific error data: You have an error in your SQL syntax') - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), SpanAssertion::exists('PDO.commit'), ]); } @@ -314,7 +311,7 @@ public function testPDOExecException() SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.exec', 'pdo', 'sql', $query) ->setError('PDOException', static::ERROR_EXEC, true) - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), ]); } @@ -329,12 +326,10 @@ public function testPDOQuery() $this->assertSpans($traces, [ SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.query', 'pdo', 'sql', $query) - ->withExactTags($this->baseTags()) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes($this->baseTags(), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -351,12 +346,10 @@ public function testPDOQueryPeerServiceEnabled() $this->assertSpans($traces, [ SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.query', 'pdo', 'sql', $query) - ->withExactTags($this->baseTags(true)) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes($this->baseTags(true), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -375,7 +368,7 @@ public function testPDOQueryError() SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.query', 'pdo', 'sql', $query) ->setError('PDO error', 'SQL error: 42000. Driver error: 1064. Driver-specific error data: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'WRONG QUERY\'') - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), ]); } @@ -395,7 +388,7 @@ public function testPDOQueryException() SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.query', 'pdo', 'sql', $query) ->setError('PDOException', static::ERROR_QUERY, true) - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), ]); } @@ -418,7 +411,7 @@ public function testPDOQueryExceptionPeerServiceEnabled() SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.query', 'pdo', 'sql', $query) ->setError('PDOException', static::ERROR_QUERY, true) - ->withExactTags($this->baseTags(true)), + ->withExactAttributes($this->baseTags(true)), ]); } @@ -436,7 +429,7 @@ public function testPDOCommit() SpanAssertion::exists('PDO.__construct'), SpanAssertion::exists('PDO.exec'), SpanAssertion::build('PDO.commit', 'pdo', 'sql', 'PDO.commit') - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), ]); } @@ -456,7 +449,7 @@ public function testPDOCommitPeerServiceEnabled() SpanAssertion::exists('PDO.__construct'), SpanAssertion::exists('PDO.exec'), SpanAssertion::build('PDO.commit', 'pdo', 'sql', 'PDO.commit') - ->withExactTags($this->baseTags(true)), + ->withExactAttributes($this->baseTags(true)), ]); } @@ -480,19 +473,17 @@ public function testPDOStatementOk() 'pdo', 'sql', "SELECT * FROM tests WHERE id = ?" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), SpanAssertion::build( 'PDOStatement.execute', 'pdo', 'sql', "SELECT * FROM tests WHERE id = ?" ) - ->withExactTags($this->baseTags()) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes($this->baseTags(), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -518,19 +509,17 @@ public function testPDOStatementOkPeerServiceEnabled() 'pdo', 'sql', "SELECT * FROM tests WHERE id = ?" - )->withExactTags($this->baseTags(true)), + )->withExactAttributes($this->baseTags(true)), SpanAssertion::build( 'PDOStatement.execute', 'pdo', 'sql', "SELECT * FROM tests WHERE id = ?" ) - ->withExactTags($this->baseTags(true)) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes($this->baseTags(true), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -555,19 +544,17 @@ public function testPDOStatementSplitByDomain() 'pdo-mysql-integration', 'sql', "SELECT * FROM tests WHERE id = ?" - )->withExactTags($this->baseTags(false, 'opt.db_client_split_by_instance')), + )->withExactAttributes($this->baseTags(false, 'opt.db_client_split_by_instance')), SpanAssertion::build( 'PDOStatement.execute', 'pdo-mysql-integration', 'sql', "SELECT * FROM tests WHERE id = ?" ) - ->withExactTags($this->baseTags(false, 'opt.db_client_split_by_instance')) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes($this->baseTags(false, 'opt.db_client_split_by_instance'), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -593,19 +580,17 @@ public function testPDOStatementSplitByDomainAndServiceFlattening() 'pdo-mysql-integration', 'sql', "SELECT * FROM tests WHERE id = ?" - )->withExactTags($this->baseTags(false, 'opt.db_client_split_by_instance')), + )->withExactAttributes($this->baseTags(false, 'opt.db_client_split_by_instance')), SpanAssertion::build( 'PDOStatement.execute', 'pdo-mysql-integration', 'sql', "SELECT * FROM tests WHERE id = ?" ) - ->withExactTags($this->baseTags(false, 'opt.db_client_split_by_instance')) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes($this->baseTags(false, 'opt.db_client_split_by_instance'), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -665,10 +650,10 @@ public function testPDOStatementError() $this->assertSpans($traces, [ SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.prepare', 'pdo', 'sql', "WRONG QUERY") - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), SpanAssertion::build('PDOStatement.execute', 'pdo', 'sql', "WRONG QUERY") ->seterror('PDOStatement error', 'SQL error: 42000. Driver error: 1064') - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), ]); } @@ -691,10 +676,10 @@ public function testPDOStatementException() $this->assertSpans($traces, [ SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.prepare', 'pdo', 'sql', "WRONG QUERY") - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), SpanAssertion::build('PDOStatement.execute', 'pdo', 'sql', "WRONG QUERY") ->setError('PDOException', static::ERROR_STATEMENT, true) - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), ]); } @@ -719,10 +704,10 @@ public function testPDOStatementExceptionPeerServiceEnabled() $this->assertSpans($traces, [ SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.prepare', 'pdo', 'sql', "WRONG QUERY") - ->withExactTags($this->baseTags(true)), + ->withExactAttributes($this->baseTags(true)), SpanAssertion::build('PDOStatement.execute', 'pdo', 'sql', "WRONG QUERY") ->setError('PDOException', static::ERROR_STATEMENT, true) - ->withExactTags($this->baseTags(true)), + ->withExactAttributes($this->baseTags(true)), ]); } @@ -747,7 +732,7 @@ public function testPreparedStatementUsesServiceModeForDBM() }); // Get the raw spans - $spans = $traces[0]; + $spans = (new SpanChecker())->flattenTraces($traces); // Find prepare and execute spans $constructSpan = null; @@ -796,7 +781,7 @@ public function testDirectQueryHasNoParentIssues() }); // Get the raw spans - $spans = $traces[0]; + $spans = (new SpanChecker())->flattenTraces($traces); // Find construct and query spans $constructSpan = null; @@ -817,12 +802,10 @@ public function testDirectQueryHasNoParentIssues() $this->assertSpans($traces, [ SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.query', 'pdo', 'sql', $query) - ->withExactTags($this->baseTags()) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes($this->baseTags(), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), ]); } @@ -862,8 +845,7 @@ public function testNoFakeServices() $this->assertSpans($traces, [ SpanAssertion::exists('PDO.__construct'), SpanAssertion::build('PDO.exec', 'configured_service', 'sql', $query) - ->withExactTags($this->baseTags(false, null)) - ->withExactMetrics([Tag::DB_ROW_COUNT => 1.0]), + ->withExactAttributes($this->baseTags(false, null), [Tag::DB_ROW_COUNT => 1]), SpanAssertion::exists('PDO.commit'), ], false); } diff --git a/tests/Integrations/PHPRedis/V3/PHPRedisClusterTest.php b/tests/Integrations/PHPRedis/V3/PHPRedisClusterTest.php index db6826bf686..3974b341967 100644 --- a/tests/Integrations/PHPRedis/V3/PHPRedisClusterTest.php +++ b/tests/Integrations/PHPRedis/V3/PHPRedisClusterTest.php @@ -79,7 +79,7 @@ public function testClose() 'phpredis', 'redis', "RedisCluster.close" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); } @@ -102,7 +102,7 @@ public function testMethodsSpansOnly($method, $args, $rawCommand) 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($this->normalizeRawCommand($method, $rawCommand))) + )->withExactAttributes($this->baseTags($this->normalizeRawCommand($method, $rawCommand))) ]); } @@ -158,8 +158,8 @@ public function testMethodsOnlySpan($method, $arg, $canFail = false) null, $hasError ) - ->withExactTags($this->baseTags()) - ->skipTagsLike('/^error\..*/'), + ->withExactAttributes($this->baseTags()) + ->skipAttributesLike('/^error\..*/'), ]); } @@ -204,7 +204,7 @@ public function testStringCommandsSet($method, $args, $expected, $rawCommand, $i 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expected, $redis->get($args[0])); @@ -340,7 +340,7 @@ public function testMSet() 'phpredis', 'redis', "RedisCluster.mSet" - )->withExactTags($this->baseTags('mSet k1 v1 k2 v2')), + )->withExactAttributes($this->baseTags('mSet k1 v1 k2 v2')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -361,7 +361,7 @@ public function testMSetNx() 'phpredis', 'redis', "RedisCluster.mSetNx" - )->withExactTags($this->baseTags('mSetNx k1 v1 k2 v2')), + )->withExactAttributes($this->baseTags('mSetNx k1 v1 k2 v2')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -397,7 +397,7 @@ public function testCommandsWithResult($method, $args, $expected, $rawCommand, a 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expected, $result); } @@ -505,7 +505,7 @@ public function testHashFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expectedResult, $result); @@ -655,7 +655,7 @@ public function testListFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expectedResult, $result); @@ -895,7 +895,7 @@ public function testSetFunctions($method, $args, $expectedResult, $expectedFinal 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_STRING) { @@ -1063,7 +1063,7 @@ public function testSortedSetFunctions($method, $args, $expectedResult, $expecte 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_STRING) { @@ -1231,7 +1231,7 @@ public function testPublish() 'phpredis', 'redis', "RedisCluster.publish" - )->withExactTags($this->baseTags('publish ch1 hi')), + )->withExactAttributes($this->baseTags('publish ch1 hi')), ]); } @@ -1250,25 +1250,25 @@ public function testTransactions() 'phpredis', 'redis', "RedisCluster.multi" - )->withExactTags($this->baseTags('multi')), + )->withExactAttributes($this->baseTags('multi')), SpanAssertion::build( "RedisCluster.set", 'phpredis', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags('set k1 v1')), + )->withExactAttributes($this->baseTags('set k1 v1')), SpanAssertion::build( "RedisCluster.get", 'phpredis', 'redis', "RedisCluster.get" - )->withExactTags($this->baseTags('get k1')), + )->withExactAttributes($this->baseTags('get k1')), SpanAssertion::build( "RedisCluster.exec", 'phpredis', 'redis', "RedisCluster.exec" - )->withExactTags($this->baseTags('exec')), + )->withExactAttributes($this->baseTags('exec')), ]); } @@ -1300,7 +1300,7 @@ public function testScriptingFunctions($method, $args, $expectedResult, /*$expec 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($this->normalizeRawCommand($method, $rawCommand))), + )->withExactAttributes($this->baseTags($this->normalizeRawCommand($method, $rawCommand))), ]); $this->assertEquals($expectedResult, $result); } @@ -1369,13 +1369,13 @@ public function testDumpRestore() 'phpredis', 'redis', "RedisCluster.dump" - )->withExactTags($this->baseTags('dump k1')), + )->withExactAttributes($this->baseTags('dump k1')), SpanAssertion::build( "RedisCluster.restore", 'phpredis', 'redis', "RedisCluster.restore" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); $this->assertSame('v1', $redis->get('k1')); @@ -1412,7 +1412,7 @@ public function testGeocodingFunctions($method, $args, $expectedResult, /*$expec 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_FLOAT) { @@ -1483,15 +1483,15 @@ public function testSetGetWithBinarySafeStringsAsValue() 'phpredis', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), SpanAssertion::build( "RedisCluster.get", 'phpredis', 'redis', "RedisCluster.get" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), ]); } @@ -1509,15 +1509,15 @@ public function testSetGetWithBinarySafeStringsAsKey() 'phpredis', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), SpanAssertion::build( "RedisCluster.get", 'phpredis', 'redis', "RedisCluster.get" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), ]); } @@ -1595,14 +1595,14 @@ public function testSplitByDomainWithClusterName() 'redis-cluster_name', 'redis', "RedisCluster.__construct" - )->withExactTags([Tag::SPAN_KIND => 'client', + )->withExactAttributes([Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'opt.redis_client_split_by_host', Tag::DB_SYSTEM => 'redis', 'out.host' => $this->connection1[0], 'out.port' => $this->connection1[1]]), SpanAssertion::build( "RedisCluster.set", 'redis-cluster_name', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags('set key value', false, false), ['_dd.cluster.name' => 'cluster_name', '_dd.svc_src' => 'opt.redis_client_split_by_host']) + )->withExactAttributes($this->baseTags('set key value', false, false), ['_dd.cluster.name' => 'cluster_name', '_dd.svc_src' => 'opt.redis_client_split_by_host']) ]); $redis->close(); @@ -1627,7 +1627,7 @@ public function testSplitByDomainWithClusterNameAndSeeds() 'redis-cluster_name', 'redis', "RedisCluster.__construct" - )->withExactTags([ + )->withExactAttributes([ 'out.host' => $this->connection1[0], 'out.port' => $this->connection1[1], Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'opt.redis_client_split_by_host', Tag::DB_SYSTEM => 'redis', ]), @@ -1636,7 +1636,7 @@ public function testSplitByDomainWithClusterNameAndSeeds() 'redis-cluster_name', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags('set key value', false, false), ['_dd.cluster.name' => 'cluster_name', '_dd.svc_src' => 'opt.redis_client_split_by_host']) + )->withExactAttributes($this->baseTags('set key value', false, false), ['_dd.cluster.name' => 'cluster_name', '_dd.svc_src' => 'opt.redis_client_split_by_host']) ]); $redis->close(); @@ -1662,13 +1662,13 @@ public function testSplitByDomainWithFirstNodeIP() $serviceName, 'redis', "RedisCluster.__construct" - )->withExactTags($this->baseTags(null, false, false), ['out.host' => $this->connection1[0], 'out.port' => $this->connection1[1], '_dd.svc_src' => 'opt.redis_client_split_by_host']), + )->withExactAttributes($this->baseTags(null, false, false), ['out.host' => $this->connection1[0], 'out.port' => $this->connection1[1], '_dd.svc_src' => 'opt.redis_client_split_by_host']), SpanAssertion::build( "RedisCluster.set", $serviceName, 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags('set key value'), ['_dd.svc_src' => 'opt.redis_client_split_by_host']) + )->withExactAttributes($this->baseTags('set key value'), ['_dd.svc_src' => 'opt.redis_client_split_by_host']) ]); $redis->close(); diff --git a/tests/Integrations/PHPRedis/V3/PHPRedisTest.php b/tests/Integrations/PHPRedis/V3/PHPRedisTest.php index 364b7d114f7..8bad4829f22 100644 --- a/tests/Integrations/PHPRedis/V3/PHPRedisTest.php +++ b/tests/Integrations/PHPRedis/V3/PHPRedisTest.php @@ -22,7 +22,7 @@ class PHPRedisTest extends IntegrationTestCase const SCRIPT_SHA = 'e0e1f9fabfc9d4800c877a703b823ac0578ff8db'; private $host = 'redis-integration'; - private $port = '6379'; + private $port = 6379; private $portSecondInstance = '6380'; /** Redis */ @@ -78,7 +78,7 @@ public function testConnectionOk($method) 'phpredis', 'redis', "Redis.$method" - )->withExactTags([ + )->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', @@ -124,7 +124,7 @@ public function testConnectionError($host, $port, $method) "Redis.$method" ) ->setError() - ->withExactTags([ + ->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', @@ -132,7 +132,7 @@ public function testConnectionError($host, $port, $method) 'out.host' => $host, 'out.port' => $port ?: $this->port, ]) - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.stack']), + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.stack']), ]); } @@ -171,7 +171,7 @@ public function testClose() 'phpredis', 'redis', "Redis.close" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); } @@ -205,7 +205,7 @@ public function testMethodsSpansOnly($method, $args, $rawCommand) 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); } @@ -254,7 +254,7 @@ public function testMethodsOnlySpan($method, $arg) 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); } @@ -285,7 +285,7 @@ public function testSelect() 'phpredis', 'redis', "Redis.select" - )->withExactTags($this->baseTags(), ['db.index' => '1']), + )->withExactAttributes($this->baseTags(), ['db.index' => 1]), ]); } @@ -318,7 +318,7 @@ public function testStringCommandsSet($method, $args, $expected, $rawCommand, $i 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expected, $redis->get($args[0])); @@ -468,7 +468,7 @@ public function testMSet() 'phpredis', 'redis', "Redis.mSet" - )->withExactTags($this->baseTags('mSet k1 v1 k2 v2')), + )->withExactAttributes($this->baseTags('mSet k1 v1 k2 v2')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -489,7 +489,7 @@ public function testMSetNx() 'phpredis', 'redis', "Redis.mSetNx" - )->withExactTags($this->baseTags('mSetNx k1 v1 k2 v2')), + )->withExactAttributes($this->baseTags('mSetNx k1 v1 k2 v2')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -510,7 +510,7 @@ public function testRawCommand() 'phpredis', 'redis', "Redis.rawCommand" - )->withExactTags($this->baseTags('rawCommand set k1 v1')), + )->withExactAttributes($this->baseTags('rawCommand set k1 v1')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -545,7 +545,7 @@ public function testCommandsWithResult($method, $args, $expected, $rawCommand, a 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expected, $result); } @@ -667,7 +667,7 @@ public function testHashFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expectedResult, $result); @@ -816,7 +816,7 @@ public function testListFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expectedResult, $result); @@ -1086,7 +1086,7 @@ public function testSetFunctions($method, $args, $expectedResult, $expectedFinal 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_STRING) { @@ -1282,7 +1282,7 @@ public function testSortedSetFunctions($method, $args, $expectedResult, $expecte 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_STRING) { @@ -1478,7 +1478,7 @@ public function testPublish() 'phpredis', 'redis', "Redis.publish" - )->withExactTags($this->baseTags('publish ch1 hi')), + )->withExactAttributes($this->baseTags('publish ch1 hi')), ]); } @@ -1497,25 +1497,25 @@ public function testTransactions() 'phpredis', 'redis', "Redis.multi" - )->withExactTags($this->baseTags('multi')), + )->withExactAttributes($this->baseTags('multi')), SpanAssertion::build( "Redis.set", 'phpredis', 'redis', "Redis.set" - )->withExactTags($this->baseTags('set k1 v1')), + )->withExactAttributes($this->baseTags('set k1 v1')), SpanAssertion::build( "Redis.get", 'phpredis', 'redis', "Redis.get" - )->withExactTags($this->baseTags('get k1')), + )->withExactAttributes($this->baseTags('get k1')), SpanAssertion::build( "Redis.exec", 'phpredis', 'redis', "Redis.exec" - )->withExactTags($this->baseTags('exec')), + )->withExactAttributes($this->baseTags('exec')), ]); } @@ -1548,7 +1548,7 @@ public function testScriptingFunctions($method, $args, $expectedResult, /*$expec 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertEquals($expectedResult, $result); } @@ -1626,7 +1626,7 @@ public function testIntrospectionFunctions($method, $args, $expectedResult, /*$e 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertEquals($expectedResult, $result); } @@ -1689,13 +1689,13 @@ public function testDumpRestore() 'phpredis', 'redis', "Redis.dump" - )->withExactTags($this->baseTags('dump k1')), + )->withExactAttributes($this->baseTags('dump k1')), SpanAssertion::build( "Redis.restore", 'phpredis', 'redis', "Redis.restore" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); $this->assertSame('v1', $redis->get('k1')); @@ -1721,7 +1721,7 @@ public function testMigrate() 'phpredis', 'redis', "Redis.migrate" - )->withExactTags($this->baseTags("migrate redis-integration 6380 k1 0 3600")), + )->withExactAttributes($this->baseTags("migrate redis-integration 6380 k1 0 3600")), ]); $traces = $this->isolateTracer(function () { @@ -1733,7 +1733,7 @@ public function testMigrate() 'phpredis', 'redis', "Redis.migrate" - )->withExactTags($this->baseTags("migrate redis-integration 6380 k2 k3 0 3600")), + )->withExactAttributes($this->baseTags("migrate redis-integration 6380 k2 k3 0 3600")), ]); $this->assertSame('v1', $this->redisSecondInstance->get('k1')); @@ -1759,7 +1759,7 @@ public function testMove() 'phpredis', 'redis', "Redis.move" - )->withExactTags($this->baseTags("move k1 1")), + )->withExactAttributes($this->baseTags("move k1 1")), ]); $this->assertSame('v1', $this->redis->get('k1')); @@ -1778,7 +1778,7 @@ public function testRenameKey() 'phpredis', 'redis', "Redis.renameKey" - )->withExactTags($this->baseTags("renameKey k1 k2")), + )->withExactAttributes($this->baseTags("renameKey k1 k2")), ]); $this->assertFalse($this->redis->get('k1')); @@ -1798,15 +1798,15 @@ public function testSetGetWithBinarySafeStringsAsValue() 'phpredis', 'redis', "Redis.set" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), SpanAssertion::build( "Redis.get", 'phpredis', 'redis', "Redis.get" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), ]); } @@ -1830,8 +1830,8 @@ public function testSplitByDomainWhenError() "Redis.connect" ) ->setError() - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.stack']) - ->withExactTags($this->baseTags(), ['out.host' => 'non-existing-host', 'out.port' => '6379', '_dd.svc_src' => 'opt.redis_client_split_by_host']), + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.stack']) + ->withExactAttributes($this->baseTags(), ['out.host' => 'non-existing-host', 'out.port' => 6379, '_dd.svc_src' => 'opt.redis_client_split_by_host']), ]); } @@ -1852,14 +1852,14 @@ public function testSplitByDomainWhenSuccess() 'redis', "Redis.connect" ) - ->withExactTags($this->baseTags(), [Tag::TARGET_PORT => '6379', '_dd.svc_src' => 'opt.redis_client_split_by_host']), + ->withExactAttributes($this->baseTags(), [Tag::TARGET_PORT => 6379, '_dd.svc_src' => 'opt.redis_client_split_by_host']), SpanAssertion::build( "Redis.set", 'redis-redis-integration', 'redis', "Redis.set" ) - ->withExactTags($this->baseTags('set key value'), ['_dd.svc_src' => 'opt.redis_client_split_by_host']), + ->withExactAttributes($this->baseTags('set key value'), ['_dd.svc_src' => 'opt.redis_client_split_by_host']), ]); } @@ -1876,15 +1876,15 @@ public function testSetGetWithBinarySafeStringsAsKey() 'phpredis', 'redis', "Redis.set" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), SpanAssertion::build( "Redis.get", 'phpredis', 'redis', "Redis.get" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), ]); } diff --git a/tests/Integrations/PHPRedis/V4/PHPRedisClusterTest.php b/tests/Integrations/PHPRedis/V4/PHPRedisClusterTest.php index 654fc0ac375..4c85692b0c4 100644 --- a/tests/Integrations/PHPRedis/V4/PHPRedisClusterTest.php +++ b/tests/Integrations/PHPRedis/V4/PHPRedisClusterTest.php @@ -79,7 +79,7 @@ public function testClose() 'phpredis', 'redis', "RedisCluster.close" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); } @@ -102,7 +102,7 @@ public function testMethodsSpansOnly($method, $args, $rawCommand) 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($this->normalizeRawCommand($method, $rawCommand))) + )->withExactAttributes($this->baseTags($this->normalizeRawCommand($method, $rawCommand))) ]); } @@ -158,8 +158,8 @@ public function testMethodsOnlySpan($method, $arg, $canFail = false) null, $hasError ) - ->withExactTags($this->baseTags()) - ->skipTagsLike('/^error\..*/'), + ->withExactAttributes($this->baseTags()) + ->skipAttributesLike('/^error\..*/'), ]); } @@ -204,7 +204,7 @@ public function testStringCommandsSet($method, $args, $expected, $rawCommand, $i 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expected, $redis->get($args[0])); @@ -340,7 +340,7 @@ public function testMSet() 'phpredis', 'redis', "RedisCluster.mSet" - )->withExactTags($this->baseTags('mSet k1 v1 k2 v2')), + )->withExactAttributes($this->baseTags('mSet k1 v1 k2 v2')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -361,7 +361,7 @@ public function testMSetNx() 'phpredis', 'redis', "RedisCluster.mSetNx" - )->withExactTags($this->baseTags('mSetNx k1 v1 k2 v2')), + )->withExactAttributes($this->baseTags('mSetNx k1 v1 k2 v2')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -397,7 +397,7 @@ public function testCommandsWithResult($method, $args, $expected, $rawCommand, a 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expected, $result); } @@ -505,7 +505,7 @@ public function testHashFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expectedResult, $result); @@ -655,7 +655,7 @@ public function testListFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expectedResult, $result); @@ -895,7 +895,7 @@ public function testSetFunctions($method, $args, $expectedResult, $expectedFinal 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_STRING) { @@ -1063,7 +1063,7 @@ public function testSortedSetFunctions($method, $args, $expectedResult, $expecte 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_STRING) { @@ -1245,7 +1245,7 @@ public function testPublish() 'phpredis', 'redis', "RedisCluster.publish" - )->withExactTags($this->baseTags('publish ch1 hi')), + )->withExactAttributes($this->baseTags('publish ch1 hi')), ]); } @@ -1264,25 +1264,25 @@ public function testTransactions() 'phpredis', 'redis', "RedisCluster.multi" - )->withExactTags($this->baseTags('multi')), + )->withExactAttributes($this->baseTags('multi')), SpanAssertion::build( "RedisCluster.set", 'phpredis', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags('set k1 v1')), + )->withExactAttributes($this->baseTags('set k1 v1')), SpanAssertion::build( "RedisCluster.get", 'phpredis', 'redis', "RedisCluster.get" - )->withExactTags($this->baseTags('get k1')), + )->withExactAttributes($this->baseTags('get k1')), SpanAssertion::build( "RedisCluster.exec", 'phpredis', 'redis', "RedisCluster.exec" - )->withExactTags($this->baseTags('exec')), + )->withExactAttributes($this->baseTags('exec')), ]); } @@ -1314,7 +1314,7 @@ public function testScriptingFunctions($method, $args, $expectedResult, /*$expec 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($this->normalizeRawCommand($method, $rawCommand))), + )->withExactAttributes($this->baseTags($this->normalizeRawCommand($method, $rawCommand))), ]); $this->assertEquals($expectedResult, $result); } @@ -1383,13 +1383,13 @@ public function testDumpRestore() 'phpredis', 'redis', "RedisCluster.dump" - )->withExactTags($this->baseTags('dump k1')), + )->withExactAttributes($this->baseTags('dump k1')), SpanAssertion::build( "RedisCluster.restore", 'phpredis', 'redis', "RedisCluster.restore" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); $this->assertSame('v1', $redis->get('k1')); @@ -1426,7 +1426,7 @@ public function testGeocodingFunctions($method, $args, $expectedResult, /*$expec 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_FLOAT) { @@ -1501,7 +1501,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xAdd" - )->withExactTags($this->baseTags('xAdd s1 123-456 k1 v1')), + )->withExactAttributes($this->baseTags('xAdd s1 123-456 k1 v1')), ]); // xGroup @@ -1515,7 +1515,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xGroup" - )->withExactTags($this->baseTags('xGroup CREATE s1 group1 0')), + )->withExactAttributes($this->baseTags('xGroup CREATE s1 group1 0')), ]); // xInfo @@ -1529,7 +1529,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xInfo" - )->withExactTags($this->baseTags('xInfo GROUPS s1')), + )->withExactAttributes($this->baseTags('xInfo GROUPS s1')), ]); // xLen @@ -1543,7 +1543,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xLen" - )->withExactTags($this->baseTags('xLen s1')), + )->withExactAttributes($this->baseTags('xLen s1')), ]); // xPending @@ -1557,7 +1557,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xPending" - )->withExactTags($this->baseTags('xPending s1 group1')), + )->withExactAttributes($this->baseTags('xPending s1 group1')), ]); // xRange @@ -1571,7 +1571,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xRange" - )->withExactTags($this->baseTags('xRange s1 - +')), + )->withExactAttributes($this->baseTags('xRange s1 - +')), ]); // xRevRange @@ -1585,7 +1585,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xRevRange" - )->withExactTags($this->baseTags('xRevRange s1 + -')), + )->withExactAttributes($this->baseTags('xRevRange s1 + -')), ]); // xRead @@ -1599,7 +1599,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xRead" - )->withExactTags($this->baseTags('xRead s1 $')), + )->withExactAttributes($this->baseTags('xRead s1 $')), ]); // xReadGroup @@ -1613,7 +1613,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xReadGroup" - )->withExactTags($this->baseTags('xReadGroup group1 consumer1 s1 >')), + )->withExactAttributes($this->baseTags('xReadGroup group1 consumer1 s1 >')), ]); // xAck @@ -1627,7 +1627,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xAck" - )->withExactTags($this->baseTags('xAck s1 group1 s1 123-456')), + )->withExactAttributes($this->baseTags('xAck s1 group1 s1 123-456')), ]); // xClaim @@ -1641,7 +1641,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xClaim" - )->withExactTags($this->baseTags('xClaim s1 group1 consumer1 0 s1 123-456')), + )->withExactAttributes($this->baseTags('xClaim s1 group1 consumer1 0 s1 123-456')), ]); // xDel @@ -1655,7 +1655,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xDel" - )->withExactTags($this->baseTags('xDel s1 123-456')), + )->withExactAttributes($this->baseTags('xDel s1 123-456')), ]); // xTrim @@ -1669,7 +1669,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xTrim" - )->withExactTags($this->baseTags('xTrim s1 0')), + )->withExactAttributes($this->baseTags('xTrim s1 0')), ]); } @@ -1686,15 +1686,15 @@ public function testSetGetWithBinarySafeStringsAsValue() 'phpredis', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), SpanAssertion::build( "RedisCluster.get", 'phpredis', 'redis', "RedisCluster.get" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), ]); } @@ -1712,15 +1712,15 @@ public function testSetGetWithBinarySafeStringsAsKey() 'phpredis', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), SpanAssertion::build( "RedisCluster.get", 'phpredis', 'redis', "RedisCluster.get" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), ]); } @@ -1798,7 +1798,7 @@ public function testSplitByDomainWithClusterName() 'redis-cluster_name', 'redis', "RedisCluster.__construct" - )->withExactTags([ + )->withExactAttributes([ 'out.host' => $this->connection1[0], 'out.port' => $this->connection1[1], Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'opt.redis_client_split_by_host', Tag::DB_SYSTEM => 'redis', ]), @@ -1807,7 +1807,7 @@ public function testSplitByDomainWithClusterName() 'redis-cluster_name', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags('set key value', false, false), ['_dd.cluster.name' => 'cluster_name', '_dd.svc_src' => 'opt.redis_client_split_by_host']) + )->withExactAttributes($this->baseTags('set key value', false, false), ['_dd.cluster.name' => 'cluster_name', '_dd.svc_src' => 'opt.redis_client_split_by_host']) ]); $redis->close(); @@ -1832,7 +1832,7 @@ public function testSplitByDomainWithClusterNameAndSeeds() 'redis-cluster_name', 'redis', "RedisCluster.__construct" - )->withExactTags([ + )->withExactAttributes([ 'out.host' => $this->connection1[0], 'out.port' => $this->connection1[1], Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'opt.redis_client_split_by_host', Tag::DB_SYSTEM => 'redis', ]), @@ -1841,7 +1841,7 @@ public function testSplitByDomainWithClusterNameAndSeeds() 'redis-cluster_name', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags('set key value', false, false), ['_dd.cluster.name' => 'cluster_name', '_dd.svc_src' => 'opt.redis_client_split_by_host']) + )->withExactAttributes($this->baseTags('set key value', false, false), ['_dd.cluster.name' => 'cluster_name', '_dd.svc_src' => 'opt.redis_client_split_by_host']) ]); $redis->close(); @@ -1867,13 +1867,13 @@ public function testSplitByDomainWithFirstNodeIP() $serviceName, 'redis', "RedisCluster.__construct" - )->withExactTags($this->baseTags(null, false, false), ['out.host' => $this->connection1[0], 'out.port' => $this->connection1[1], '_dd.svc_src' => 'opt.redis_client_split_by_host']), + )->withExactAttributes($this->baseTags(null, false, false), ['out.host' => $this->connection1[0], 'out.port' => $this->connection1[1], '_dd.svc_src' => 'opt.redis_client_split_by_host']), SpanAssertion::build( "RedisCluster.set", $serviceName, 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags('set key value'), ['_dd.svc_src' => 'opt.redis_client_split_by_host']) + )->withExactAttributes($this->baseTags('set key value'), ['_dd.svc_src' => 'opt.redis_client_split_by_host']) ]); $redis->close(); diff --git a/tests/Integrations/PHPRedis/V4/PHPRedisTest.php b/tests/Integrations/PHPRedis/V4/PHPRedisTest.php index c29c69dfa0c..6cea10d0b23 100644 --- a/tests/Integrations/PHPRedis/V4/PHPRedisTest.php +++ b/tests/Integrations/PHPRedis/V4/PHPRedisTest.php @@ -23,7 +23,7 @@ class PHPRedisTest extends IntegrationTestCase const SCRIPT_SHA = 'e0e1f9fabfc9d4800c877a703b823ac0578ff8db'; private $host = 'redis-integration'; - private $port = '6379'; + private $port = 6379; private $portSecondInstance = '6380'; /** Redis */ @@ -77,7 +77,7 @@ public function testConnectionOk($method) 'phpredis', 'redis', "Redis.$method" - )->withExactTags([ + )->withExactAttributes([ 'out.host' => $this->host, 'out.port' => $this->port, Tag::SPAN_KIND => 'client', @@ -123,7 +123,7 @@ public function testConnectionError($host, $port, $method) "Redis.$method" ) ->setError() - ->withExactTags([ + ->withExactAttributes([ 'out.host' => $host, 'out.port' => $port ?: $this->port, Tag::SPAN_KIND => 'client', @@ -131,7 +131,7 @@ public function testConnectionError($host, $port, $method) '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', ]) - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.stack']), + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.stack']), ]); } @@ -170,7 +170,7 @@ public function testClose() 'phpredis', 'redis', "Redis.close" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); } @@ -204,7 +204,7 @@ public function testMethodsSpansOnly($method, $args, $rawCommand) 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); } @@ -254,7 +254,7 @@ public function testMethodsOnlySpan($method, $arg) 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); } @@ -285,7 +285,7 @@ public function testSelect() 'phpredis', 'redis', "Redis.select" - )->withExactTags($this->baseTags(), ['db.index' => '1']), + )->withExactAttributes($this->baseTags(), ['db.index' => 1]), ]); } @@ -318,7 +318,7 @@ public function testStringCommandsSet($method, $args, $expected, $rawCommand, $i 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expected, $redis->get($args[0])); @@ -468,7 +468,7 @@ public function testMSet() 'phpredis', 'redis', "Redis.mSet" - )->withExactTags($this->baseTags('mSet k1 v1 k2 v2')), + )->withExactAttributes($this->baseTags('mSet k1 v1 k2 v2')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -489,7 +489,7 @@ public function testMSetNx() 'phpredis', 'redis', "Redis.mSetNx" - )->withExactTags($this->baseTags('mSetNx k1 v1 k2 v2')), + )->withExactAttributes($this->baseTags('mSetNx k1 v1 k2 v2')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -510,7 +510,7 @@ public function testRawCommand() 'phpredis', 'redis', "Redis.rawCommand" - )->withExactTags($this->baseTags('rawCommand set k1 v1')), + )->withExactAttributes($this->baseTags('rawCommand set k1 v1')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -545,7 +545,7 @@ public function testCommandsWithResult($method, $args, $expected, $rawCommand, a 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expected, $result); } @@ -667,7 +667,7 @@ public function testHashFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expectedResult, $result); @@ -816,7 +816,7 @@ public function testListFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expectedResult, $result); @@ -1086,7 +1086,7 @@ public function testSetFunctions($method, $args, $expectedResult, $expectedFinal 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_STRING) { @@ -1282,7 +1282,7 @@ public function testSortedSetFunctions($method, $args, $expectedResult, $expecte 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_STRING) { @@ -1478,7 +1478,7 @@ public function testPublish() 'phpredis', 'redis', "Redis.publish" - )->withExactTags($this->baseTags('publish ch1 hi')), + )->withExactAttributes($this->baseTags('publish ch1 hi')), ]); } @@ -1497,25 +1497,25 @@ public function testTransactions() 'phpredis', 'redis', "Redis.multi" - )->withExactTags($this->baseTags('multi')), + )->withExactAttributes($this->baseTags('multi')), SpanAssertion::build( "Redis.set", 'phpredis', 'redis', "Redis.set" - )->withExactTags($this->baseTags('set k1 v1')), + )->withExactAttributes($this->baseTags('set k1 v1')), SpanAssertion::build( "Redis.get", 'phpredis', 'redis', "Redis.get" - )->withExactTags($this->baseTags('get k1')), + )->withExactAttributes($this->baseTags('get k1')), SpanAssertion::build( "Redis.exec", 'phpredis', 'redis', "Redis.exec" - )->withExactTags($this->baseTags('exec')), + )->withExactAttributes($this->baseTags('exec')), ]); } @@ -1548,7 +1548,7 @@ public function testScriptingFunctions($method, $args, $expectedResult, /*$expec 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertEquals($expectedResult, $result); } @@ -1626,7 +1626,7 @@ public function testIntrospectionFunctions($method, $args, $expectedResult, /*$e 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertEquals($expectedResult, $result); } @@ -1689,13 +1689,13 @@ public function testDumpRestore() 'phpredis', 'redis', "Redis.dump" - )->withExactTags($this->baseTags('dump k1')), + )->withExactAttributes($this->baseTags('dump k1')), SpanAssertion::build( "Redis.restore", 'phpredis', 'redis', "Redis.restore" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); $this->assertSame('v1', $redis->get('k1')); @@ -1721,7 +1721,7 @@ public function testMigrate() 'phpredis', 'redis', "Redis.migrate" - )->withExactTags($this->baseTags("migrate redis-integration 6380 k1 0 3600")), + )->withExactAttributes($this->baseTags("migrate redis-integration 6380 k1 0 3600")), ]); $traces = $this->isolateTracer(function () { @@ -1733,7 +1733,7 @@ public function testMigrate() 'phpredis', 'redis', "Redis.migrate" - )->withExactTags($this->baseTags("migrate redis-integration 6380 k2 k3 0 3600")), + )->withExactAttributes($this->baseTags("migrate redis-integration 6380 k2 k3 0 3600")), ]); $this->assertSame('v1', $this->redisSecondInstance->get('k1')); @@ -1759,7 +1759,7 @@ public function testMove() 'phpredis', 'redis', "Redis.move" - )->withExactTags($this->baseTags("move k1 1")), + )->withExactAttributes($this->baseTags("move k1 1")), ]); $this->assertSame('v1', $this->redis->get('k1')); @@ -1778,7 +1778,7 @@ public function testRenameKey() 'phpredis', 'redis', "Redis.renameKey" - )->withExactTags($this->baseTags("renameKey k1 k2")), + )->withExactAttributes($this->baseTags("renameKey k1 k2")), ]); $this->assertFalse($this->redis->get('k1')); @@ -1815,7 +1815,7 @@ public function testGeocodingFunctions($method, $args, $expectedResult, /*$expec 'phpredis', 'redis', "Redis.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_FLOAT) { @@ -1890,7 +1890,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xAdd" - )->withExactTags($this->baseTags('xAdd s1 123-456 k1 v1')), + )->withExactAttributes($this->baseTags('xAdd s1 123-456 k1 v1')), ]); // xGroup @@ -1904,7 +1904,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xGroup" - )->withExactTags($this->baseTags('xGroup CREATE s1 group1 0')), + )->withExactAttributes($this->baseTags('xGroup CREATE s1 group1 0')), ]); // xInfo @@ -1918,7 +1918,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xInfo" - )->withExactTags($this->baseTags('xInfo GROUPS s1')), + )->withExactAttributes($this->baseTags('xInfo GROUPS s1')), ]); // xLen @@ -1932,7 +1932,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xLen" - )->withExactTags($this->baseTags('xLen s1')), + )->withExactAttributes($this->baseTags('xLen s1')), ]); // xPending @@ -1946,7 +1946,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xPending" - )->withExactTags($this->baseTags('xPending s1 group1')), + )->withExactAttributes($this->baseTags('xPending s1 group1')), ]); // xRange @@ -1960,7 +1960,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xRange" - )->withExactTags($this->baseTags('xRange s1 - +')), + )->withExactAttributes($this->baseTags('xRange s1 - +')), ]); // xRevRange @@ -1974,7 +1974,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xRevRange" - )->withExactTags($this->baseTags('xRevRange s1 + -')), + )->withExactAttributes($this->baseTags('xRevRange s1 + -')), ]); // xRead @@ -1988,7 +1988,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xRead" - )->withExactTags($this->baseTags('xRead s1 $')), + )->withExactAttributes($this->baseTags('xRead s1 $')), ]); // xReadGroup @@ -2002,7 +2002,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xReadGroup" - )->withExactTags($this->baseTags('xReadGroup group1 consumer1 s1 >')), + )->withExactAttributes($this->baseTags('xReadGroup group1 consumer1 s1 >')), ]); // xAck @@ -2016,7 +2016,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xAck" - )->withExactTags($this->baseTags('xAck s1 group1 s1 123-456')), + )->withExactAttributes($this->baseTags('xAck s1 group1 s1 123-456')), ]); // xClaim @@ -2030,7 +2030,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xClaim" - )->withExactTags($this->baseTags('xClaim s1 group1 consumer1 0 s1 123-456')), + )->withExactAttributes($this->baseTags('xClaim s1 group1 consumer1 0 s1 123-456')), ]); // xDel @@ -2044,7 +2044,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xDel" - )->withExactTags($this->baseTags('xDel s1 123-456')), + )->withExactAttributes($this->baseTags('xDel s1 123-456')), ]); // xTrim @@ -2058,7 +2058,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xTrim" - )->withExactTags($this->baseTags('xTrim s1 0')), + )->withExactAttributes($this->baseTags('xTrim s1 0')), ]); } @@ -2075,15 +2075,15 @@ public function testSetGetWithBinarySafeStringsAsValue() 'phpredis', 'redis', "Redis.set" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), SpanAssertion::build( "Redis.get", 'phpredis', 'redis', "Redis.get" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), ]); } @@ -2107,8 +2107,8 @@ public function testSplitByDomainWhenError() "Redis.connect" ) ->setError() - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.stack']) - ->withExactTags($this->baseTags(), ['out.host' => 'non-existing-host', 'out.port' => '6379', '_dd.svc_src' => 'opt.redis_client_split_by_host']), + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.stack']) + ->withExactAttributes($this->baseTags(), ['out.host' => 'non-existing-host', 'out.port' => 6379, '_dd.svc_src' => 'opt.redis_client_split_by_host']), ]); } @@ -2129,14 +2129,14 @@ public function testSplitByDomainWhenSuccess() 'redis', "Redis.connect" ) - ->withExactTags($this->baseTags(), [Tag::TARGET_PORT => '6379', '_dd.svc_src' => 'opt.redis_client_split_by_host']), + ->withExactAttributes($this->baseTags(), [Tag::TARGET_PORT => 6379, '_dd.svc_src' => 'opt.redis_client_split_by_host']), SpanAssertion::build( "Redis.set", 'redis-redis-integration', 'redis', "Redis.set" ) - ->withExactTags($this->baseTags('set key value'), ['_dd.svc_src' => 'opt.redis_client_split_by_host']), + ->withExactAttributes($this->baseTags('set key value'), ['_dd.svc_src' => 'opt.redis_client_split_by_host']), ]); } @@ -2153,15 +2153,15 @@ public function testSetGetWithBinarySafeStringsAsKey() 'phpredis', 'redis', "Redis.set" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), SpanAssertion::build( "Redis.get", 'phpredis', 'redis', "Redis.get" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), ]); } diff --git a/tests/Integrations/PHPRedis/V5/PHPRedisClusterTest.php b/tests/Integrations/PHPRedis/V5/PHPRedisClusterTest.php index 3ce224e95cc..58ca7a3ca15 100644 --- a/tests/Integrations/PHPRedis/V5/PHPRedisClusterTest.php +++ b/tests/Integrations/PHPRedis/V5/PHPRedisClusterTest.php @@ -98,7 +98,7 @@ public function testClose() 'phpredis', 'redis', "RedisCluster.close" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); } @@ -121,7 +121,7 @@ public function testMethodsSpansOnly($method, $args, $rawCommand) 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($this->normalizeRawCommand($method, $rawCommand))), + )->withExactAttributes($this->baseTags($this->normalizeRawCommand($method, $rawCommand))), ]); } @@ -177,8 +177,8 @@ public function testMethodsOnlySpan($method, $arg, $canFail = false) null, $hasError ) - ->withExactTags($this->baseTags()) - ->skipTagsLike('/^error\..*/'), + ->withExactAttributes($this->baseTags()) + ->skipAttributesLike('/^error\..*/'), ]); } @@ -223,7 +223,7 @@ public function testStringCommandsSet($method, $args, $expected, $rawCommand, $i 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expected, $redis->get($args[0])); @@ -359,7 +359,7 @@ public function testMSet() 'phpredis', 'redis', "RedisCluster.mSet" - )->withExactTags($this->baseTags('mSet k1 v1 k2 v2')), + )->withExactAttributes($this->baseTags('mSet k1 v1 k2 v2')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -380,7 +380,7 @@ public function testMSetNx() 'phpredis', 'redis', "RedisCluster.mSetNx" - )->withExactTags($this->baseTags('mSetNx k1 v1 k2 v2')), + )->withExactAttributes($this->baseTags('mSetNx k1 v1 k2 v2')), ]); $this->assertSame('v1', $redis->get('k1')); @@ -416,7 +416,7 @@ public function testCommandsWithResult($method, $args, $expected, $rawCommand, a 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)) + )->withExactAttributes($this->baseTags($rawCommand)) ]); $this->assertSame($expected, $result); } @@ -524,7 +524,7 @@ public function testHashFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expectedResult, $result); @@ -674,7 +674,7 @@ public function testListFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); $this->assertSame($expectedResult, $result); @@ -914,7 +914,7 @@ public function testSetFunctions($method, $args, $expectedResult, $expectedFinal 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_STRING) { @@ -1082,7 +1082,7 @@ public function testSortedSetFunctions($method, $args, $expectedResult, $expecte 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_STRING) { @@ -1264,7 +1264,7 @@ public function testPublish() 'phpredis', 'redis', "RedisCluster.publish" - )->withExactTags($this->baseTags('publish ch1 hi')), + )->withExactAttributes($this->baseTags('publish ch1 hi')), ]); } @@ -1283,25 +1283,25 @@ public function testTransactions() 'phpredis', 'redis', "RedisCluster.multi" - )->withExactTags($this->baseTags('multi')), + )->withExactAttributes($this->baseTags('multi')), SpanAssertion::build( "RedisCluster.set", 'phpredis', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags('set k1 v1')), + )->withExactAttributes($this->baseTags('set k1 v1')), SpanAssertion::build( "RedisCluster.get", 'phpredis', 'redis', "RedisCluster.get" - )->withExactTags($this->baseTags('get k1')), + )->withExactAttributes($this->baseTags('get k1')), SpanAssertion::build( "RedisCluster.exec", 'phpredis', 'redis', "RedisCluster.exec" - )->withExactTags($this->baseTags('exec')), + )->withExactAttributes($this->baseTags('exec')), ]); } @@ -1333,7 +1333,7 @@ public function testScriptingFunctions($method, $args, $expectedResult, /*$expec 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($this->normalizeRawCommand($method, $rawCommand))), + )->withExactAttributes($this->baseTags($this->normalizeRawCommand($method, $rawCommand))), ]); $this->assertEquals($expectedResult, $result); } @@ -1402,13 +1402,13 @@ public function testDumpRestore() 'phpredis', 'redis', "RedisCluster.dump" - )->withExactTags($this->baseTags('dump k1')), + )->withExactAttributes($this->baseTags('dump k1')), SpanAssertion::build( "RedisCluster.restore", 'phpredis', 'redis', "RedisCluster.restore" - )->withExactTags($this->baseTags()), + )->withExactAttributes($this->baseTags()), ]); $this->assertSame('v1', $redis->get('k1')); @@ -1445,7 +1445,7 @@ public function testGeocodingFunctions($method, $args, $expectedResult, /*$expec 'phpredis', 'redis', "RedisCluster.$method" - )->withExactTags($this->baseTags($rawCommand)), + )->withExactAttributes($this->baseTags($rawCommand)), ]); if ($expectedResult === self::A_FLOAT) { @@ -1520,7 +1520,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xAdd" - )->withExactTags($this->baseTags('xAdd s1 123-456 k1 v1')), + )->withExactAttributes($this->baseTags('xAdd s1 123-456 k1 v1')), ]); // xGroup @@ -1534,7 +1534,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xGroup" - )->withExactTags($this->baseTags('xGroup CREATE s1 group1 0')), + )->withExactAttributes($this->baseTags('xGroup CREATE s1 group1 0')), ]); // xInfo @@ -1548,7 +1548,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xInfo" - )->withExactTags($this->baseTags('xInfo GROUPS s1')), + )->withExactAttributes($this->baseTags('xInfo GROUPS s1')), ]); // xLen @@ -1562,7 +1562,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xLen" - )->withExactTags($this->baseTags('xLen s1')), + )->withExactAttributes($this->baseTags('xLen s1')), ]); // xPending @@ -1576,7 +1576,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xPending" - )->withExactTags($this->baseTags('xPending s1 group1')), + )->withExactAttributes($this->baseTags('xPending s1 group1')), ]); // xRange @@ -1590,7 +1590,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xRange" - )->withExactTags($this->baseTags('xRange s1 - +')), + )->withExactAttributes($this->baseTags('xRange s1 - +')), ]); // xRevRange @@ -1604,7 +1604,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xRevRange" - )->withExactTags($this->baseTags('xRevRange s1 + -')), + )->withExactAttributes($this->baseTags('xRevRange s1 + -')), ]); // xRead @@ -1618,7 +1618,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xRead" - )->withExactTags($this->baseTags('xRead s1 $')), + )->withExactAttributes($this->baseTags('xRead s1 $')), ]); // xReadGroup @@ -1632,7 +1632,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xReadGroup" - )->withExactTags($this->baseTags('xReadGroup group1 consumer1 s1 >')), + )->withExactAttributes($this->baseTags('xReadGroup group1 consumer1 s1 >')), ]); // xAck @@ -1646,7 +1646,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xAck" - )->withExactTags($this->baseTags('xAck s1 group1 s1 123-456')), + )->withExactAttributes($this->baseTags('xAck s1 group1 s1 123-456')), ]); // xClaim @@ -1660,7 +1660,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xClaim" - )->withExactTags($this->baseTags('xClaim s1 group1 consumer1 0 s1 123-456')), + )->withExactAttributes($this->baseTags('xClaim s1 group1 consumer1 0 s1 123-456')), ]); // xDel @@ -1674,7 +1674,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xDel" - )->withExactTags($this->baseTags('xDel s1 123-456')), + )->withExactAttributes($this->baseTags('xDel s1 123-456')), ]); // xTrim @@ -1688,7 +1688,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "RedisCluster.xTrim" - )->withExactTags($this->baseTags('xTrim s1 0')), + )->withExactAttributes($this->baseTags('xTrim s1 0')), ]); } @@ -1705,15 +1705,15 @@ public function testSetGetWithBinarySafeStringsAsValue() 'phpredis', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), SpanAssertion::build( "RedisCluster.get", 'phpredis', 'redis', "RedisCluster.get" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), ]); } @@ -1731,15 +1731,15 @@ public function testSetGetWithBinarySafeStringsAsKey() 'phpredis', 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), SpanAssertion::build( "RedisCluster.get", 'phpredis', 'redis', "RedisCluster.get" - )->withExactTags($this->baseTags()) - ->withExistingTagsNames(['redis.raw_command']), + )->withExactAttributes($this->baseTags()) + ->withExistingAttributeNames(['redis.raw_command']), ]); } @@ -1817,7 +1817,7 @@ public function testSplitByDomainWithClusterName() 'redis-cluster_name', 'redis', "RedisCluster.__construct" - )->withExactTags(array_merge( + )->withExactAttributes(array_merge( $this->baseTags(null, false, false, 'opt.redis_client_split_by_host'), ['out.host' => $this->connection1[0], 'out.port' => $this->connection1[1]] )), @@ -1826,7 +1826,7 @@ public function testSplitByDomainWithClusterName() 'redis-cluster_name', 'redis', "RedisCluster.set" - )->withExactTags(array_merge( + )->withExactAttributes(array_merge( $this->baseTags('set key value', false, false, 'opt.redis_client_split_by_host'), [ '_dd.cluster.name' => 'cluster_name', @@ -1857,7 +1857,7 @@ public function testSplitByDomainWithClusterNamePeerServiceEnabled() 'phpredis', 'redis', "RedisCluster.__construct" - )->withExactTags(array_merge( + )->withExactAttributes(array_merge( $this->baseTags(null, false, false), ['out.host' => $this->connection1[0], 'out.port' => $this->connection1[1]] )), @@ -1866,7 +1866,7 @@ public function testSplitByDomainWithClusterNamePeerServiceEnabled() 'phpredis', 'redis', "RedisCluster.set" - )->withExactTags(array_merge( + )->withExactAttributes(array_merge( $this->baseTags('set key value', true, false), [ '_dd.cluster.name' => 'cluster_name', @@ -1897,7 +1897,7 @@ public function testSplitByDomainWithNoClusterNamePeerServiceEnabled() 'phpredis', 'redis', "RedisCluster.__construct" - )->withExactTags(array_merge( + )->withExactAttributes(array_merge( $this->baseTags(null, false, false), ['out.host' => $this->connection1[0], 'out.port' => $this->connection1[1]] )), @@ -1906,7 +1906,7 @@ public function testSplitByDomainWithNoClusterNamePeerServiceEnabled() 'phpredis', 'redis', "RedisCluster.set" - )->withExactTags(array_merge( + )->withExactAttributes(array_merge( $this->baseTags('set key value', true, true) )) ]); @@ -1933,7 +1933,7 @@ public function testSplitByDomainWithClusterNameAndSeeds() 'redis-cluster_name', 'redis', "RedisCluster.__construct" - )->withExactTags(array_merge( + )->withExactAttributes(array_merge( $this->baseTags(null, false, false, 'opt.redis_client_split_by_host'), ['out.host' => $this->connection1[0], 'out.port' => $this->connection1[1]] )), @@ -1942,7 +1942,7 @@ public function testSplitByDomainWithClusterNameAndSeeds() 'redis-cluster_name', 'redis', "RedisCluster.set" - )->withExactTags(array_merge( + )->withExactAttributes(array_merge( $this->baseTags('set key value', false, false, 'opt.redis_client_split_by_host'), [ '_dd.cluster.name' => 'cluster_name', @@ -1973,7 +1973,7 @@ public function testSplitByDomainWithFirstNodeIP() $serviceName, 'redis', "RedisCluster.__construct" - )->withExactTags(array_merge( + )->withExactAttributes(array_merge( $this->baseTags(null, false, false), ['out.host' => $this->connection1[0], 'out.port' => $this->connection1[1], '_dd.svc_src' => 'opt.redis_client_split_by_host'] )), @@ -1982,7 +1982,7 @@ public function testSplitByDomainWithFirstNodeIP() $serviceName, 'redis', "RedisCluster.set" - )->withExactTags($this->baseTags('set key value'), ['_dd.svc_src' => 'opt.redis_client_split_by_host']) + )->withExactAttributes($this->baseTags('set key value'), ['_dd.svc_src' => 'opt.redis_client_split_by_host']) ]); $redis->close(); @@ -2007,7 +2007,7 @@ public function testNoFakeServices() 'configured_service', 'redis', "RedisCluster.mSetNx" - )->withExactTags($this->baseTags('mSetNx k1 v1 k2 v2', false, true, null)), + )->withExactAttributes($this->baseTags('mSetNx k1 v1 k2 v2', false, true, null)), ]); } diff --git a/tests/Integrations/PHPRedis/V5/PHPRedisTest.php b/tests/Integrations/PHPRedis/V5/PHPRedisTest.php index 16008833ce1..1163ac7d507 100644 --- a/tests/Integrations/PHPRedis/V5/PHPRedisTest.php +++ b/tests/Integrations/PHPRedis/V5/PHPRedisTest.php @@ -30,7 +30,7 @@ class PHPRedisTest extends IntegrationTestCase const SCRIPT_SHA = 'e0e1f9fabfc9d4800c877a703b823ac0578ff8db'; private $host = 'redis-integration'; - private $port = '6379'; + private $port = 6379; private $portSecondInstance = '6380'; /** Redis */ @@ -76,7 +76,7 @@ public function testRedisInExtendedClass() 'phpredis', 'redis', 'DDTrace\Tests\Integrations\PHPRedis\V5\CustomRedisClass.connect' - )->withExactTags([ + )->withExactAttributes([ Tag::TARGET_HOST => $this->host, Tag::TARGET_PORT => $this->port, Tag::SPAN_KIND => 'client', @@ -111,7 +111,7 @@ public function testConnectionOk($method) 'phpredis', 'redis', "Redis.$method" - )->withExactTags([ + )->withExactAttributes([ Tag::TARGET_HOST => $this->host, 'out.port' => $this->port, Tag::SPAN_KIND => 'client', @@ -157,7 +157,7 @@ public function testConnectionError($host, $port, $method) "Redis.$method" ) ->setError() - ->withExactTags([ + ->withExactAttributes([ Tag::TARGET_HOST => $host, 'out.port' => $port ?: $this->port, Tag::SPAN_KIND => 'client', @@ -165,7 +165,7 @@ public function testConnectionError($host, $port, $method) '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', ]) - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.stack']), + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.stack']), ]); } @@ -204,7 +204,7 @@ public function testClose() 'phpredis', 'redis', "Redis.close" - )->withExactTags([Tag::SPAN_KIND => 'client', + )->withExactAttributes([Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); } @@ -239,7 +239,7 @@ public function testMethodsSpansOnly($method, $args, $rawCommand) 'phpredis', 'redis', "Redis.$method" - )->withExactTags(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); } @@ -290,7 +290,7 @@ public function testMethodsOnlySpan($method, $arg) 'phpredis', 'redis', "Redis.$method" - )->withExactTags([Tag::SPAN_KIND => 'client', + )->withExactAttributes([Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); } @@ -324,7 +324,7 @@ public function testMethodsNoArgsPeerServiceEnabled() 'phpredis', 'redis', 'Redis.echo' - )->withExactTags([ + )->withExactAttributes([ Tag::TARGET_HOST => $this->host, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', @@ -349,7 +349,7 @@ public function testSelect() 'phpredis', 'redis', "Redis.select" - )->withExactTags(['db.index' => '1', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['db.index' => 1, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); } @@ -369,9 +369,9 @@ public function testSelectPeerServiceEnabled() 'phpredis', 'redis', "Redis.select" - )->withExactTags([ + )->withExactAttributes([ Tag::TARGET_HOST => $this->host, - 'db.index' => '1', + 'db.index' => 1, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', @@ -411,7 +411,7 @@ public function testStringCommandsSet($method, $args, $expected, $rawCommand, $i 'phpredis', 'redis', "Redis.$method" - )->withExactTags(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -564,7 +564,7 @@ public function testMethodAsCommandPeerServiceEnabled() 'phpredis', 'redis', "Redis.set" - )->withExactTags([ + )->withExactAttributes([ Tag::TARGET_HOST => $this->host, 'redis.raw_command' => 'set k1 v1', Tag::SPAN_KIND => 'client', @@ -591,7 +591,7 @@ public function testMSet() 'phpredis', 'redis', "Redis.mSet" - )->withExactTags(['redis.raw_command' => 'mSet k1 v1 k2 v2', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'mSet k1 v1 k2 v2', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -613,7 +613,7 @@ public function testMSetNx() 'phpredis', 'redis', "Redis.mSetNx" - )->withExactTags(['redis.raw_command' => 'mSetNx k1 v1 k2 v2', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'mSetNx k1 v1 k2 v2', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -635,7 +635,7 @@ public function testRawCommand() 'phpredis', 'redis', "Redis.rawCommand" - )->withExactTags(['redis.raw_command' => 'rawCommand set k1 v1', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'rawCommand set k1 v1', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -671,7 +671,7 @@ public function testCommandsWithResult($method, $args, $expected, $rawCommand, a 'phpredis', 'redis', "Redis.$method" - )->withExactTags(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); $this->assertSame($expected, $result); @@ -794,7 +794,7 @@ public function testHashFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "Redis.$method" - )->withExactTags(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -944,7 +944,7 @@ public function testListFunctions($method, $args, $expectedResult, $expectedFina 'phpredis', 'redis', "Redis.$method" - )->withExactTags(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -1215,7 +1215,7 @@ public function testSetFunctions($method, $args, $expectedResult, $expectedFinal 'phpredis', 'redis', "Redis.$method" - )->withExactTags(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -1412,7 +1412,7 @@ public function testSortedSetFunctions($method, $args, $expectedResult, $expecte 'phpredis', 'redis', "Redis.$method" - )->withExactTags(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -1644,7 +1644,7 @@ public function testPublish() 'phpredis', 'redis', "Redis.publish" - )->withExactTags(['redis.raw_command' => 'publish ch1 hi', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'publish ch1 hi', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); } @@ -1664,28 +1664,28 @@ public function testTransactions() 'phpredis', 'redis', "Redis.multi" - )->withExactTags(['redis.raw_command' => 'multi', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'multi', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), SpanAssertion::build( "Redis.set", 'phpredis', 'redis', "Redis.set" - )->withExactTags(['redis.raw_command' => 'set k1 v1', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'set k1 v1', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), SpanAssertion::build( "Redis.get", 'phpredis', 'redis', "Redis.get" - )->withExactTags(['redis.raw_command' => 'get k1', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'get k1', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), SpanAssertion::build( "Redis.exec", 'phpredis', 'redis', "Redis.exec" - )->withExactTags(['redis.raw_command' => 'exec', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'exec', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); } @@ -1719,7 +1719,7 @@ public function testScriptingFunctions($method, $args, $expectedResult, /*$expec 'phpredis', 'redis', "Redis.$method" - )->withExactTags(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); $this->assertEquals($expectedResult, $result); @@ -1798,7 +1798,7 @@ public function testIntrospectionFunctions($method, $args, $expectedResult, /*$e 'phpredis', 'redis', "Redis.$method" - )->withExactTags(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); $this->assertEquals($expectedResult, $result); @@ -1862,14 +1862,14 @@ public function testDumpRestore() 'phpredis', 'redis', "Redis.dump" - )->withExactTags(['redis.raw_command' => 'dump k1', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'dump k1', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), SpanAssertion::build( "Redis.restore", 'phpredis', 'redis', "Redis.restore" - )->withExactTags([Tag::SPAN_KIND => 'client', + )->withExactAttributes([Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -1896,7 +1896,7 @@ public function testMigrate() 'phpredis', 'redis', "Redis.migrate" - )->withExactTags(['redis.raw_command' => "migrate redis-integration 6380 k1 0 3600", Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => "migrate redis-integration 6380 k1 0 3600", Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -1909,7 +1909,7 @@ public function testMigrate() 'phpredis', 'redis', "Redis.migrate" - )->withExactTags(['redis.raw_command' => "migrate redis-integration 6380 k2 k3 0 3600", Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => "migrate redis-integration 6380 k2 k3 0 3600", Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -1936,7 +1936,7 @@ public function testMove() 'phpredis', 'redis', "Redis.move" - )->withExactTags(['redis.raw_command' => "move k1 1", Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => "move k1 1", Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -1956,7 +1956,7 @@ public function testRenameKey() 'phpredis', 'redis', "Redis.renameKey" - )->withExactTags(['redis.raw_command' => "renameKey k1 k2", Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => "renameKey k1 k2", Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -1994,7 +1994,7 @@ public function testGeocodingFunctions($method, $args, $expectedResult, /*$expec 'phpredis', 'redis', "Redis.$method" - )->withExactTags(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => $rawCommand, Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2070,7 +2070,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xAdd" - )->withExactTags(['redis.raw_command' => 'xAdd s1 123-456 k1 v1', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xAdd s1 123-456 k1 v1', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2085,7 +2085,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xGroup" - )->withExactTags(['redis.raw_command' => 'xGroup CREATE s1 group1 0', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xGroup CREATE s1 group1 0', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2100,7 +2100,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xInfo" - )->withExactTags(['redis.raw_command' => 'xInfo GROUPS s1', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xInfo GROUPS s1', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2115,7 +2115,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xLen" - )->withExactTags(['redis.raw_command' => 'xLen s1', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xLen s1', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2130,7 +2130,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xPending" - )->withExactTags(['redis.raw_command' => 'xPending s1 group1', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xPending s1 group1', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2145,7 +2145,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xRange" - )->withExactTags(['redis.raw_command' => 'xRange s1 - +', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xRange s1 - +', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2160,7 +2160,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xRevRange" - )->withExactTags(['redis.raw_command' => 'xRevRange s1 + -', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xRevRange s1 + -', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2175,7 +2175,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xRead" - )->withExactTags(['redis.raw_command' => 'xRead s1 $', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xRead s1 $', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2190,7 +2190,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xReadGroup" - )->withExactTags(['redis.raw_command' => 'xReadGroup group1 consumer1 s1 >', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xReadGroup group1 consumer1 s1 >', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2205,7 +2205,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xAck" - )->withExactTags(['redis.raw_command' => 'xAck s1 group1 s1 123-456', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xAck s1 group1 s1 123-456', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2220,7 +2220,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xClaim" - )->withExactTags(['redis.raw_command' => 'xClaim s1 group1 consumer1 0 s1 123-456', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xClaim s1 group1 consumer1 0 s1 123-456', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2235,7 +2235,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xDel" - )->withExactTags(['redis.raw_command' => 'xDel s1 123-456', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xDel s1 123-456', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); @@ -2250,7 +2250,7 @@ public function testStreamsFunctions() 'phpredis', 'redis', "Redis.xTrim" - )->withExactTags(['redis.raw_command' => 'xTrim s1 0', Tag::SPAN_KIND => 'client', + )->withExactAttributes(['redis.raw_command' => 'xTrim s1 0', Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); } @@ -2275,8 +2275,8 @@ public function testSplitByDomainWhenError() "Redis.connect" ) ->setError() - ->withExistingTagsNames([Tag::ERROR_MSG, 'error.stack', Tag::SPAN_KIND]) - ->withExactTags([ + ->withExistingAttributeNames([Tag::ERROR_MSG, 'error.stack', Tag::SPAN_KIND]) + ->withExactAttributes([ Tag::TARGET_HOST => 'non-existing-host', 'out.port' => $this->port, Tag::COMPONENT => 'phpredis', @@ -2303,7 +2303,7 @@ public function testSplitByDomainWhenSuccess() 'redis', "Redis.connect" ) - ->withExactTags([ + ->withExactAttributes([ Tag::TARGET_HOST => $this->host, Tag::TARGET_PORT => $this->port, Tag::SPAN_KIND => 'client', @@ -2317,7 +2317,7 @@ public function testSplitByDomainWhenSuccess() 'redis', "Redis.set" ) - ->withExactTags([ + ->withExactAttributes([ 'redis.raw_command' => 'set key value', Tag::TARGET_HOST => $this->host, Tag::SPAN_KIND => 'client', @@ -2341,24 +2341,24 @@ public function testSetGetWithBinarySafeStringsAsValue() 'phpredis', 'redis', "Redis.set" - )->withExactTags([ + )->withExactAttributes([ Tag::TARGET_HOST => $this->host, Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', ]) - ->withExistingTagsNames(['redis.raw_command', Tag::SPAN_KIND]), + ->withExistingAttributeNames(['redis.raw_command', Tag::SPAN_KIND]), SpanAssertion::build( "Redis.get", 'phpredis', 'redis', "Redis.get" - )->withExactTags([ + )->withExactAttributes([ Tag::TARGET_HOST => $this->host, Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', - ])->withExistingTagsNames(['redis.raw_command', Tag::SPAN_KIND]), + ])->withExistingAttributeNames(['redis.raw_command', Tag::SPAN_KIND]), ]); } @@ -2376,23 +2376,23 @@ public function testSetGetWithBinarySafeStringsAsKey() 'phpredis', 'redis', "Redis.set" - )->withExactTags([ + )->withExactAttributes([ Tag::TARGET_HOST => $this->host, Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', - ])->withExistingTagsNames(['redis.raw_command', Tag::SPAN_KIND]), + ])->withExistingAttributeNames(['redis.raw_command', Tag::SPAN_KIND]), SpanAssertion::build( "Redis.get", 'phpredis', 'redis', "Redis.get" - )->withExactTags([ + )->withExactAttributes([ Tag::TARGET_HOST => $this->host, Tag::COMPONENT => 'phpredis', '_dd.svc_src' => 'phpredis', Tag::DB_SYSTEM => 'redis', - ])->withExistingTagsNames(['redis.raw_command', Tag::SPAN_KIND]), + ])->withExistingAttributeNames(['redis.raw_command', Tag::SPAN_KIND]), ]); } @@ -2469,7 +2469,7 @@ public function testNoFakeServices() 'configured_service', 'redis', "Redis.save" - )->withExactTags([Tag::SPAN_KIND => 'client', + )->withExactAttributes([Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'phpredis', Tag::DB_SYSTEM => 'redis', Tag::TARGET_HOST => $this->host]), ]); } @@ -2485,8 +2485,7 @@ public function testOrphansRemoval() $redis->save(); }); - $span = $traces[0][0]; - $this->assertEquals(0, $span['sampling_priority']); + $this->assertEquals(0, $traces[0]['priority']); } public function testOrphansRemoval64bit() @@ -2501,7 +2500,6 @@ public function testOrphansRemoval64bit() $redis->save(); }); - $span = $traces[0][0]; - $this->assertEquals(0, $span['sampling_priority']); + $this->assertEquals(0, $traces[0]['priority']); } } diff --git a/tests/Integrations/Predis/Latest/PredisTest.php b/tests/Integrations/Predis/Latest/PredisTest.php index 8238b91dab6..c88f7169d71 100644 --- a/tests/Integrations/Predis/Latest/PredisTest.php +++ b/tests/Integrations/Predis/Latest/PredisTest.php @@ -5,6 +5,7 @@ use DDTrace\Tag; use DDTrace\Tests\Common\IntegrationTestCase; use DDTrace\Tests\Common\SpanAssertion; +use DDTrace\Tests\Common\SpanChecker; use Predis\Configuration\Options; class PredisTest extends IntegrationTestCase @@ -12,7 +13,7 @@ class PredisTest extends IntegrationTestCase protected static $lockedResource = "redis"; protected $host = 'redis-integration'; - private $port = '6379'; + private $port = 6379; public static function ddSetUpBeforeClass() { @@ -51,9 +52,7 @@ public function testPredisIntegrationCreatesSpans() }); $this->assertCount(1, $traces); - $trace = $traces[0]; - - $this->assertGreaterThan(2, count($trace)); # two Redis operations -> at least 2 spans + $this->assertGreaterThan(2, count($traces[0]['spans'])); # two Redis operations -> at least 2 spans } /** @@ -69,9 +68,9 @@ public function testConnectionAndServiceInfo($firstArgument, $host, $port, $serv new \Predis\Client($firstArgument); } }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame($host, $span['attributes']['out.host']); - $this->assertSame("$port", $span['attributes']['out.port']); + $this->assertSame($port, $span['attributes']['out.port']); $this->assertSame('redis', $span['service']); // With split by domain @@ -83,9 +82,9 @@ public function testConnectionAndServiceInfo($firstArgument, $host, $port, $serv new \Predis\Client($firstArgument); } }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame($host, $span['attributes']['out.host']); - $this->assertSame("$port", $span['attributes']['out.port']); + $this->assertSame($port, $span['attributes']['out.port']); $this->assertSame($service, $span['service']); } @@ -135,7 +134,7 @@ public function testPredisConstructOptionsAsArray() $this->assertFlameGraph($traces, [ SpanAssertion::build('Predis.Client.__construct', 'redis', 'redis', 'Predis.Client.__construct') - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), ]); } @@ -151,7 +150,7 @@ public function testPredisConstructOptionsAsObject() $this->assertFlameGraph($traces, [ SpanAssertion::build('Predis.Client.__construct', 'redis', 'redis', 'Predis.Client.__construct') - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), ]); } @@ -165,7 +164,7 @@ public function testPredisConnect() $this->assertFlameGraph($traces, [ SpanAssertion::exists('Predis.Client.__construct'), SpanAssertion::build('Predis.Client.connect', 'redis', 'redis', 'Predis.Client.connect') - ->withExactTags($this->baseTags()), + ->withExactAttributes($this->baseTags()), ]); } @@ -181,7 +180,7 @@ public function testPredisClusterConnect() $this->assertFlameGraph($traces, [ SpanAssertion::exists('Predis.Client.__construct'), SpanAssertion::build('Predis.Client.connect', 'redis', 'redis', 'Predis.Client.connect') - ->withExactTags([ + ->withExactAttributes([ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'predis', '_dd.svc_src' => 'redis', @@ -201,9 +200,9 @@ public function testPredisSetCommand() $this->assertFlameGraph($traces, [ SpanAssertion::exists('Predis.Client.__construct'), SpanAssertion::build('Predis.Client.executeCommand', 'redis', 'redis', 'SET foo value') - ->withExactTags(array_merge([], $this->baseTags(), [ + ->withExactAttributes(array_merge([], $this->baseTags(), [ 'redis.raw_command' => 'SET foo value', - 'redis.args_length' => '3', + 'redis.args_length' => 3, ])), ]); } @@ -220,9 +219,9 @@ public function testPredisGetCommand() SpanAssertion::exists('Predis.Client.__construct'), SpanAssertion::exists('Predis.Client.executeCommand'), SpanAssertion::build('Predis.Client.executeCommand', 'redis', 'redis', 'GET key') - ->withExactTags(array_merge([], $this->baseTags(), [ + ->withExactAttributes(array_merge([], $this->baseTags(), [ 'redis.raw_command' => 'GET key', - 'redis.args_length' => '2', + 'redis.args_length' => 2, ])), ]); } @@ -237,9 +236,9 @@ public function testPredisRawCommand() $this->assertFlameGraph($traces, [ SpanAssertion::exists('Predis.Client.__construct'), SpanAssertion::build('Predis.Client.executeRaw', 'redis', 'redis', 'SET key value') - ->withExactTags(array_merge([], $this->baseTags(), [ + ->withExactAttributes(array_merge([], $this->baseTags(), [ 'redis.raw_command' => 'SET key value', - 'redis.args_length' => '3', + 'redis.args_length' => 3, ])), ]); } @@ -256,12 +255,12 @@ public function testPredisPipeline() $this->assertInstanceOf('Predis\Response\Status', $responseFlush); }); - $exactTags = [ + $exactAttributes = [ Tag::SPAN_KIND => 'client', Tag::COMPONENT => 'predis', '_dd.svc_src' => 'redis', Tag::DB_SYSTEM => 'redis', - 'redis.pipeline_length' => '2', + 'redis.pipeline_length' => 2, Tag::TARGET_HOST => $this->host, Tag::TARGET_PORT => $this->port, ]; @@ -269,7 +268,7 @@ public function testPredisPipeline() $this->assertFlameGraph($traces, [ SpanAssertion::exists('Predis.Client.__construct'), SpanAssertion::build('Predis.Pipeline.executePipeline', 'redis', 'redis', 'Predis.Pipeline.executePipeline') - ->withExactTags($exactTags), + ->withExactAttributes($exactAttributes), ]); } @@ -318,9 +317,10 @@ public function testSplitByHostForSecondarySpans() $this->assertSame('value', $client->get('key')); }); - $this->assertSame('redis-redis-integration', $traces[0][0]['service']); - $this->assertSame('redis-redis-integration', $traces[0][1]['service']); - $this->assertSame('redis-redis-integration', $traces[0][2]['service']); + $spans = (new SpanChecker())->flattenTraces($traces); + $this->assertSame('redis-redis-integration', $spans[0]['service']); + $this->assertSame('redis-redis-integration', $spans[1]['service']); + $this->assertSame('redis-redis-integration', $spans[2]['service']); } public function testSplitByHostForErrorSpans() @@ -335,8 +335,9 @@ public function testSplitByHostForErrorSpans() } }); - $this->assertSame('redis-non_existing', $traces[0][0]['service']); - $this->assertSame('redis-non_existing', $traces[0][1]['service']); + $spans = (new SpanChecker())->flattenTraces($traces); + $this->assertSame('redis-non_existing', $spans[0]['service']); + $this->assertSame('redis-non_existing', $spans[1]['service']); } public function testOrphansRemoval() @@ -349,8 +350,7 @@ public function testOrphansRemoval() new \Predis\Client(["host" => $this->host]); }); - $span = $traces[0][0]; - $this->assertEquals(0, $span['sampling_priority']); + $this->assertEquals(0, $traces[0]['priority']); } public function testOrphansRemoval64bit() @@ -364,8 +364,7 @@ public function testOrphansRemoval64bit() new \Predis\Client(["host" => $this->host]); }); - $span = $traces[0][0]; - $this->assertEquals(0, $span['sampling_priority']); + $this->assertEquals(0, $traces[0]['priority']); } public function testNoFakeServices() @@ -383,7 +382,7 @@ public function testNoFakeServices() $this->assertFlameGraph($traces, [ SpanAssertion::exists('Predis.Client.__construct'), SpanAssertion::build('Predis.Client.connect', 'configured_service', 'redis', 'Predis.Client.connect') - ->withExactTags($this->baseTags(null)), + ->withExactAttributes($this->baseTags(null)), ]); } diff --git a/tests/Integrations/Ratchet/V0_4/RatchetTest.php b/tests/Integrations/Ratchet/V0_4/RatchetTest.php index 8fbf9dfb165..a3e580b32f8 100644 --- a/tests/Integrations/Ratchet/V0_4/RatchetTest.php +++ b/tests/Integrations/Ratchet/V0_4/RatchetTest.php @@ -71,29 +71,33 @@ public function onError(ConnectionInterface $conn, \Exception $e) { }); Loop::set(Factory::create()); // reset event loop - foreach ($traces[0] as &$span) { - $span["resource"] = preg_replace('(:(\d+)$)', ':%d', $span["resource"]); - // Our checker has problems with two root spans being identical in primary attributes - if ($span["resource"] === "websocket /" && ($span["attributes"]['websocket.message.length'] ?? "") == '12') { - $span["resource"] .= 2; + foreach ($traces as &$trace) { + foreach ($trace['spans'] as &$span) { + $span["resource"] = preg_replace('(:(\d+)$)', ':%d', $span["resource"]); + // Our checker has problems with two root spans being identical in primary attributes + if ($span["resource"] === "websocket /" && ($span["attributes"]['websocket.message.length'] ?? "") == '12') { + $span["resource"] .= 2; + } } + unset($span); } + unset($trace); $this->assertFlameGraph($traces, [ SpanAssertion::build('websocket.send', 'phpunit', 'websocket', 'websocket ws://127.0.0.1:%d') - ->withExactTags([ + ->withExactAttributes([ 'span.kind' => 'producer', 'component' => 'ratchet', '_dd.svc_src' => 'm', 'websocket.message.type' => 'text', ]) - ->withExactMetrics([ + ->withExactAttributes([ 'websocket.message.length' => 12, 'websocket.message.frames' => 1, ]) - ->withExistingTagsNames(["_dd.span_links"]), + ->withSpanLinks(), SpanAssertion::build('Ratchet\Client\Connector.__invoke', 'ratchet', 'http', 'ws://127.0.0.1:%d') - ->withExactTags([ + ->withExactAttributes([ 'span.kind' => 'client', 'component' => 'ratchet', '_dd.svc_src' => 'ratchet', @@ -101,129 +105,121 @@ public function onError(ConnectionInterface $conn, \Exception $e) { 'http.url' => 'ws://127.0.0.1:%d', 'network.destination.name' => '127.0.0.1', 'http.status_code' => '101', - 'http.upgraded' => '1', + 'http.upgraded' => true, "_dd.base_service" => "phpunit", ]), SpanAssertion::build('websocket.close', 'ratchet', 'websocket', 'websocket /') - ->withExactTags([ + ->withExactAttributes([ 'span.kind' => 'consumer', 'component' => 'ratchet', '_dd.svc_src' => 'ratchet', - 'websocket.close.code' => '1000', + 'websocket.close.code' => 1000, '_dd.dm.service' => 'ratchet', '_dd.dm.resource' => 'GET /', - '_dd.p.dm' => "-0", - ]) - ->withExactMetrics([ + ])->samplingMechanism(0) + ->withExactAttributes([ '_dd.dm.inherited' => 1, - '_sampling_priority_v1' => 1, - ]) - ->withExistingTagsNames(["_dd.span_links"]) + ])->samplingPriority(1) + ->withSpanLinks() ->withChildren([ SpanAssertion::build('websocket.close', 'ratchet', 'websocket', 'websocket /') - ->withExactTags([ + ->withExactAttributes([ 'span.kind' => 'producer', 'component' => 'ratchet', '_dd.svc_src' => 'ratchet', - 'websocket.close.code' => '1000', + 'websocket.close.code' => 1000, ]) - ->withExistingTagsNames(["_dd.span_links"]) + ->withSpanLinks() ]), SpanAssertion::build('websocket.receive', 'ratchet', 'websocket', 'websocket /') - ->withExactTags([ + ->withExactAttributes([ 'span.kind' => 'consumer', 'component' => 'ratchet', '_dd.svc_src' => 'ratchet', 'websocket.message.type' => 'text', '_dd.dm.service' => 'ratchet', '_dd.dm.resource' => 'GET /', - '_dd.p.dm' => "-0", - ]) - ->withExactMetrics([ + ])->samplingMechanism(0) + ->withExactAttributes([ '_dd.dm.inherited' => 1, 'websocket.message.length' => 14, 'websocket.message.frames' => 1, - '_sampling_priority_v1' => 1, - ]) - ->withExistingTagsNames(["_dd.span_links"]) + ])->samplingPriority(1) + ->withSpanLinks() ->withChildren([ SpanAssertion::build('websocket.send', 'ratchet', 'websocket', 'websocket /') - ->withExactTags([ + ->withExactAttributes([ 'span.kind' => 'producer', 'component' => 'ratchet', '_dd.svc_src' => 'ratchet', 'websocket.message.type' => 'text', ]) - ->withExactMetrics([ + ->withExactAttributes([ 'websocket.message.length' => 14, 'websocket.message.frames' => 1, ]) - ->withExistingTagsNames(["_dd.span_links"]) + ->withSpanLinks() ]), SpanAssertion::build('websocket.receive', 'ratchet', 'websocket', 'websocket ws://127.0.0.1:%d') - ->withExactTags([ + ->withExactAttributes([ 'span.kind' => 'consumer', 'component' => 'ratchet', '_dd.svc_src' => 'ratchet', 'websocket.message.type' => 'text', '_dd.dm.service' => 'phpunit', '_dd.dm.resource' => '', - '_dd.p.dm' => "-0", - ]) - ->withExactMetrics([ + ])->samplingMechanism(0) + ->withExactAttributes([ '_dd.dm.inherited' => 1, 'websocket.message.length' => 12, 'websocket.message.frames' => 1, - '_sampling_priority_v1' => 1, - ]) - ->withExistingTagsNames(["_dd.span_links", 'closure.declaration']) + ])->samplingPriority(1) + ->withExistingAttributeNames(['closure.declaration'])->withSpanLinks() ->withChildren([ SpanAssertion::build('websocket.send', 'ratchet', 'websocket', 'websocket ws://127.0.0.1:%d') - ->withExactTags([ + ->withExactAttributes([ 'span.kind' => 'producer', 'component' => 'ratchet', '_dd.svc_src' => 'ratchet', 'websocket.message.type' => 'text', ]) - ->withExactMetrics([ + ->withExactAttributes([ 'websocket.message.length' => 14, 'websocket.message.frames' => 1, ]) - ->withExistingTagsNames(["_dd.span_links"]) + ->withSpanLinks() ]), SpanAssertion::build('websocket.receive', 'ratchet', 'websocket', 'websocket /2') - ->withExactTags([ + ->withExactAttributes([ 'span.kind' => 'consumer', 'component' => 'ratchet', '_dd.svc_src' => 'ratchet', 'websocket.message.type' => 'text', '_dd.dm.service' => 'ratchet', '_dd.dm.resource' => 'GET /', - '_dd.p.dm' => "-0", - ]) - ->withExactMetrics([ + ])->samplingMechanism(0) + ->withExactAttributes([ '_dd.dm.inherited' => 1, 'websocket.message.length' => 12, 'websocket.message.frames' => 1, - '_sampling_priority_v1' => 1, - ]) - ->withExistingTagsNames(["_dd.span_links"]) + ])->samplingPriority(1) + ->withSpanLinks() ->withChildren([ SpanAssertion::build('websocket.send', 'ratchet', 'websocket', 'websocket /2') - ->withExactTags([ + ->withExactAttributes([ 'span.kind' => 'producer', 'component' => 'ratchet', '_dd.svc_src' => 'ratchet', 'websocket.message.type' => 'text', ]) - ->withExactMetrics([ + ->withExactAttributes([ 'websocket.message.length' => 12, 'websocket.message.frames' => 1, ]) - ->withExistingTagsNames(["_dd.span_links"]) + ->withSpanLinks() ]), SpanAssertion::build('web.request', 'ratchet', 'web', 'GET /') - ->withExactTags([ + ->withExactAttributes([ 'component' => 'ratchet', '_dd.svc_src' => 'ratchet', 'span.kind' => 'server', @@ -231,7 +227,7 @@ public function onError(ConnectionInterface $conn, \Exception $e) { 'http.method' => 'GET', 'http.useragent' => 'Ratchet-Pawl/0.4.1', 'http.status_code' => '101', - 'http.upgraded' => '1', + 'http.upgraded' => true, ]), ]); } @@ -252,7 +248,7 @@ public function testRatchetConnectFail() $this->assertFlameGraph($traces, [ SpanAssertion::build('Ratchet\Client\Connector.__invoke', 'ratchet', 'http', 'ws://127.0.0.1:1') - ->withExactTags([ + ->withExactAttributes([ "span.kind" => "client", "component" => "ratchet", "_dd.svc_src" => "ratchet", diff --git a/tests/Integrations/Roadrunner/APIGWTest.php b/tests/Integrations/Roadrunner/APIGWTest.php index 8bec3ff722a..0ae354488d1 100644 --- a/tests/Integrations/Roadrunner/APIGWTest.php +++ b/tests/Integrations/Roadrunner/APIGWTest.php @@ -37,50 +37,56 @@ protected static function getEnvs() 'DD_VERSION' => '1.0', 'DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED' => 'true', 'DD_TRACE_HEADER_TAGS' => 'x-dd-proxy-domain-name,x-dd-proxy,x-dd-proxy-httpmethod,x-dd-proxy-path,x-dd-proxy-request-time-ms,x-dd-proxy-stage', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', ]); } - public function testInferredProxy() + public static function isApigwTrace($trace) { - $traces = $this->tracesFromWebRequest(function () { - $this->call( - GetSpec::create( - 'A simple GET request returning a string', - '/simple?key=value&pwd=should_redact', - [ - 'x-dd-proxy: aws-apigateway', - 'x-dd-proxy-request-time-ms: 1739261376000', - 'x-dd-proxy-path: /test', - 'x-dd-proxy-httpmethod: GET', - 'x-dd-proxy-domain-name: example.com', - 'x-dd-proxy-stage: aws-prod', - ] - ) - ); - }); + return \in_array('aws.apigateway', array_column($trace['spans'], 'name'), true); + } - $this->snapshotFromTraces($traces); + public function testInferredProxy() + { + $this->snapshotFromTraces(function () { + return $this->tracesFromWebRequest(function () { + $this->call( + GetSpec::create( + 'A simple GET request returning a string', + '/simple?key=value&pwd=should_redact', + [ + 'x-dd-proxy: aws-apigateway', + 'x-dd-proxy-request-time-ms: 1739261376000', + 'x-dd-proxy-path: /test', + 'x-dd-proxy-httpmethod: GET', + 'x-dd-proxy-domain-name: example.com', + 'x-dd-proxy-stage: aws-prod', + ] + ) + ); + }); + }, null, null, [self::class, 'isApigwTrace']); } public function testInferredProxyException() { - $traces = $this->tracesFromWebRequest(function () { - $this->call( - GetSpec::create( - 'A GET throwing an exception', - '/error?key=value&pwd=should_redact', - [ - 'x-dd-proxy: aws-apigateway', - 'x-dd-proxy-request-time-ms: 1739261376000', - 'x-dd-proxy-path: /test', - 'x-dd-proxy-httpmethod: GET', - 'x-dd-proxy-domain-name: example.com', - 'x-dd-proxy-stage: aws-prod', - ] - ) - ); - }); - - $this->snapshotFromTraces($traces); + $this->snapshotFromTraces(function () { + return $this->tracesFromWebRequest(function () { + $this->call( + GetSpec::create( + 'A GET throwing an exception', + '/error?key=value&pwd=should_redact', + [ + 'x-dd-proxy: aws-apigateway', + 'x-dd-proxy-request-time-ms: 1739261376000', + 'x-dd-proxy-path: /test', + 'x-dd-proxy-httpmethod: GET', + 'x-dd-proxy-domain-name: example.com', + 'x-dd-proxy-stage: aws-prod', + ] + ) + ); + }); + }, null, null, [self::class, 'isApigwTrace']); } } diff --git a/tests/Integrations/Roadrunner/V2/CommonScenariosTest.php b/tests/Integrations/Roadrunner/V2/CommonScenariosTest.php index e97f4275a9d..d22b6dff353 100644 --- a/tests/Integrations/Roadrunner/V2/CommonScenariosTest.php +++ b/tests/Integrations/Roadrunner/V2/CommonScenariosTest.php @@ -54,7 +54,7 @@ public function provideSpecs() 'roadrunner', 'web', 'GET /simple' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/simple?key=value&', 'http.status_code' => '200', @@ -69,7 +69,7 @@ public function provideSpecs() 'roadrunner', 'web', 'GET /simple_view' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/simple_view?key=value&', 'http.status_code' => '200', @@ -84,7 +84,7 @@ public function provideSpecs() 'roadrunner', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/error?key=value&', 'http.status_code' => '500', diff --git a/tests/Integrations/Roadrunner/V2/DistributedTracingTest.php b/tests/Integrations/Roadrunner/V2/DistributedTracingTest.php index 423907d5859..d5b380d05a6 100644 --- a/tests/Integrations/Roadrunner/V2/DistributedTracingTest.php +++ b/tests/Integrations/Roadrunner/V2/DistributedTracingTest.php @@ -2,6 +2,7 @@ namespace DDTrace\Tests\Integrations\Roadrunner\V2; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\WebFrameworkTestCase; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; use DDTrace\Tests\Frameworks\Util\Request\PostSpec; @@ -38,12 +39,12 @@ public function testDistributedTracing() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame($traceId, $trace["trace_id"]); - $this->assertSame("42", $trace["meta"]["_dd.p.user_id"]); - $this->assertSame("Test", $trace["meta"]["http.useragent"]); - $this->assertSame("somevalue", $trace["meta"]["http.request.headers.x-header"]); - $this->assertArrayNotHasKey('http.client_ip', $trace["meta"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame($traceId, SpanChecker::traceIdLow($traces[0])); + $this->assertSame("42", $trace["attributes"]["_dd.p.user_id"]); + $this->assertSame("Test", $trace["attributes"]["http.useragent"]); + $this->assertSame("somevalue", $trace["attributes"]["http.request.headers.x-header"]); + $this->assertArrayNotHasKey('http.client_ip', $trace["attributes"]); } public function testDistributedTracingPostWithAllowedParams() @@ -65,16 +66,16 @@ public function testDistributedTracingPostWithAllowedParams() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame($traceId, $trace["trace_id"]); - $this->assertSame("42", $trace["meta"]["_dd.p.user_id"]); - $this->assertSame("Test", $trace["meta"]["http.useragent"]); - $this->assertSame("somevalue", $trace["meta"]["http.request.headers.x-header"]); - $this->assertSame("", $trace["meta"]["http.request.post.pass_word"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.foo.password"]); - $this->assertSame("value1", $trace["meta"]["http.request.post.bar.key1"]); - $this->assertSame("value2", $trace["meta"]["http.request.post.bar.key2.baz"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.bar.key2.password"]); - $this->assertArrayNotHasKey('http.client_ip', $trace["meta"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame($traceId, SpanChecker::traceIdLow($traces[0])); + $this->assertSame("42", $trace["attributes"]["_dd.p.user_id"]); + $this->assertSame("Test", $trace["attributes"]["http.useragent"]); + $this->assertSame("somevalue", $trace["attributes"]["http.request.headers.x-header"]); + $this->assertSame("", $trace["attributes"]["http.request.post.pass_word"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.foo.password"]); + $this->assertSame("value1", $trace["attributes"]["http.request.post.bar.key1"]); + $this->assertSame("value2", $trace["attributes"]["http.request.post.bar.key2.baz"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.bar.key2.password"]); + $this->assertArrayNotHasKey('http.client_ip', $trace["attributes"]); } } diff --git a/tests/Integrations/Roadrunner/V2/IPExtractionTest.php b/tests/Integrations/Roadrunner/V2/IPExtractionTest.php index a3fcc98aa13..42f7b5e6ac1 100644 --- a/tests/Integrations/Roadrunner/V2/IPExtractionTest.php +++ b/tests/Integrations/Roadrunner/V2/IPExtractionTest.php @@ -2,6 +2,7 @@ namespace DDTrace\Tests\Integrations\Roadrunner\V2; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\WebFrameworkTestCase; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; @@ -39,11 +40,11 @@ public function testIpExtraction() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame($traceId, $trace["trace_id"]); - $this->assertSame("42", $trace["meta"]["_dd.p.user_id"]); - $this->assertSame("Test", $trace["meta"]["http.useragent"]); - $this->assertSame("somevalue", $trace["meta"]["http.request.headers.x-header"]); - $this->assertSame("128.12.34.1", $trace["meta"]["http.client_ip"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame($traceId, SpanChecker::traceIdLow($traces[0])); + $this->assertSame("42", $trace["attributes"]["_dd.p.user_id"]); + $this->assertSame("Test", $trace["attributes"]["http.useragent"]); + $this->assertSame("somevalue", $trace["attributes"]["http.request.headers.x-header"]); + $this->assertSame("128.12.34.1", $trace["attributes"]["http.client_ip"]); } } diff --git a/tests/Integrations/Roadrunner/V2/InvalidContentTypeTest.php b/tests/Integrations/Roadrunner/V2/InvalidContentTypeTest.php index 384eb6d01d3..a8d8f4d3aba 100644 --- a/tests/Integrations/Roadrunner/V2/InvalidContentTypeTest.php +++ b/tests/Integrations/Roadrunner/V2/InvalidContentTypeTest.php @@ -35,10 +35,10 @@ public function testContentType() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame("POST", $trace["meta"]["http.method"]); - $this->assertArrayNotHasKey("http.request.post.password", $trace["meta"]); - $this->assertArrayNotHasKey("http.request.post.username", $trace["meta"]); - $this->assertArrayNotHasKey("http.request.post.foo.bar", $trace["meta"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame("POST", $trace["attributes"]["http.method"]); + $this->assertArrayNotHasKey("http.request.post.password", $trace["attributes"]); + $this->assertArrayNotHasKey("http.request.post.username", $trace["attributes"]); + $this->assertArrayNotHasKey("http.request.post.foo.bar", $trace["attributes"]); } } diff --git a/tests/Integrations/Roadrunner/V2/MultipartFormDataTest.php b/tests/Integrations/Roadrunner/V2/MultipartFormDataTest.php index a8a8fc38bd5..f35f901e2e7 100644 --- a/tests/Integrations/Roadrunner/V2/MultipartFormDataTest.php +++ b/tests/Integrations/Roadrunner/V2/MultipartFormDataTest.php @@ -50,9 +50,9 @@ public function testContentType() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame("", $trace["meta"]["http.request.post.password"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.username"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.foo.bar"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame("", $trace["attributes"]["http.request.post.password"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.username"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.foo.bar"]); } } diff --git a/tests/Integrations/Roadrunner/V2/XWwwFormUrlencodedTest.php b/tests/Integrations/Roadrunner/V2/XWwwFormUrlencodedTest.php index 79ee8ec6ddf..a3fef7715fe 100644 --- a/tests/Integrations/Roadrunner/V2/XWwwFormUrlencodedTest.php +++ b/tests/Integrations/Roadrunner/V2/XWwwFormUrlencodedTest.php @@ -35,9 +35,9 @@ public function testContentType() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame("", $trace["meta"]["http.request.post.password"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.username"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.foo.bar"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame("", $trace["attributes"]["http.request.post.password"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.username"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.foo.bar"]); } } diff --git a/tests/Integrations/SQLSRV/SQLSRVTest.php b/tests/Integrations/SQLSRV/SQLSRVTest.php index cad76a91463..390bf327566 100644 --- a/tests/Integrations/SQLSRV/SQLSRVTest.php +++ b/tests/Integrations/SQLSRV/SQLSRVTest.php @@ -6,13 +6,14 @@ use DDTrace\Tag; use DDTrace\Tests\Common\IntegrationTestCase; use DDTrace\Tests\Common\SpanAssertion; +use DDTrace\Tests\Common\SpanChecker; use function DDTrace\close_span; use function DDTrace\start_trace_span; class SQLSRVTest extends IntegrationTestCase { private static $host = 'sqlsrv-integration'; - private static $port = '1433'; + private static $port = 1433; private static $db = 'master'; private static $user = 'sa'; private static $password = 'Password12!'; @@ -113,7 +114,7 @@ public function testConnectOk() $this->assertFlameGraph($traces, [ SpanAssertion::build('sqlsrv_connect', 'sqlsrv', 'sql', 'sqlsrv_connect') - ->withExactTags(self::baseTags()) + ->withExactAttributes(self::baseTags()) ]); } @@ -142,12 +143,10 @@ public function testQueryOk() $this->assertFlameGraph($traces, [ SpanAssertion::exists('sqlsrv_connect'), SpanAssertion::build('sqlsrv_query', 'sqlsrv', 'sql', $query) - ->withExactTags(self::baseTags($query)) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes(self::baseTags($query), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]) + ])->samplingPriority(1) ]); } @@ -165,12 +164,10 @@ public function testQueryOkPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::exists('sqlsrv_connect'), SpanAssertion::build('sqlsrv_query', 'sqlsrv', 'sql', $query) - ->withExactTags(self::baseTags($query, true)) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes(self::baseTags($query, true), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]) + ])->samplingPriority(1) ]); } @@ -187,14 +184,13 @@ public function testQueryError() $this->assertFlameGraph($traces, [ SpanAssertion::exists('sqlsrv_connect'), SpanAssertion::build('sqlsrv_query', 'sqlsrv', 'sql', $query) - ->withExactTags(self::baseTags($query)) + ->withExactAttributes(self::baseTags($query)) ->setError( 'SQLSRV error', self::getArchitecture() === 'x86_64' ? SQLSRVTest::ERROR_QUERY_17 : SQLSRVTest::ERROR_QUERY_18 - )->withExactMetrics([ + )->withExactAttributes([ '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]) + ])->samplingPriority(1) ]); } @@ -213,14 +209,13 @@ public function testQueryErrorPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::exists('sqlsrv_connect'), SpanAssertion::build('sqlsrv_query', 'sqlsrv', 'sql', $query) - ->withExactTags(self::baseTags($query, true)) + ->withExactAttributes(self::baseTags($query, true)) ->setError( 'SQLSRV error', self::getArchitecture() === 'x86_64' ? SQLSRVTest::ERROR_QUERY_17 : SQLSRVTest::ERROR_QUERY_18 - )->withExactMetrics([ + )->withExactAttributes([ '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]) + ])->samplingPriority(1) ]); } @@ -239,14 +234,12 @@ public function testCommitOk() $this->assertFlameGraph($traces, [ SpanAssertion::exists('sqlsrv_connect'), SpanAssertion::build('sqlsrv_query', 'sqlsrv', 'sql', $query) - ->withExactTags(self::baseTags($query)) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes(self::baseTags($query), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]), + ])->samplingPriority(1), SpanAssertion::build('sqlsrv_commit', 'sqlsrv', 'sql', 'sqlsrv_commit') - ->withExactTags(self::baseTags()) + ->withExactAttributes(self::baseTags()) ]); } @@ -263,14 +256,12 @@ public function testPrepareOk() $this->assertFlameGraph($traces, [ SpanAssertion::exists('sqlsrv_connect'), SpanAssertion::build('sqlsrv_prepare', 'sqlsrv', 'sql', $query) - ->withExactTags(self::baseTags($query)), + ->withExactAttributes(self::baseTags($query)), SpanAssertion::build('sqlsrv_execute', 'sqlsrv', 'sql', $query) - ->withExactTags(self::baseTags($query)) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes(self::baseTags($query), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]) + ])->samplingPriority(1) ]); } @@ -289,14 +280,12 @@ public function testPrepareOkPeerServiceEnabled() $this->assertFlameGraph($traces, [ SpanAssertion::exists('sqlsrv_connect'), SpanAssertion::build('sqlsrv_prepare', 'sqlsrv', 'sql', $query) - ->withExactTags(self::baseTags($query)), + ->withExactAttributes(self::baseTags($query)), SpanAssertion::build('sqlsrv_execute', 'sqlsrv', 'sql', $query) - ->withExactTags(self::baseTags($query, true)) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes(self::baseTags($query, true), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]) + ])->samplingPriority(1) ]); } @@ -317,11 +306,9 @@ public function testPrepareError() ->setError( 'SQLSRV error', self::getArchitecture() === 'x86_64' ? SQLSRVTest::ERROR_QUERY_17 : SQLSRVTest::ERROR_QUERY_18 - )->withExactTags(self::baseTags($query)) - ->withExactMetrics([ + )->withExactAttributes(self::baseTags($query), [ '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]) + ])->samplingPriority(1) ]); } @@ -344,11 +331,9 @@ public function testPrepareErrorPeerServiceEnabled() ->setError( 'SQLSRV error', self::getArchitecture() === 'x86_64' ? SQLSRVTest::ERROR_QUERY_17 : SQLSRVTest::ERROR_QUERY_18 - )->withExactTags(self::baseTags($query, true)) - ->withExactMetrics([ + )->withExactAttributes(self::baseTags($query, true), [ '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]) + ])->samplingPriority(1) ]); } @@ -369,7 +354,7 @@ public function testPreparedStatementUsesServiceModeForDBM() }); // Get the raw spans - $spans = $traces[0]; + $spans = (new SpanChecker())->flattenTraces($traces); // Find prepare and execute spans $connectSpan = null; @@ -427,7 +412,7 @@ public function testExecError() ->setError( 'SQLSRV error', self::getArchitecture() === 'x86_64' ? SQLSRVTest::ERROR_QUERY_17 : SQLSRVTest::ERROR_QUERY_18 - )->withExactTags(self::baseTags($query)), + )->withExactAttributes(self::baseTags($query)), SpanAssertion::exists('sqlsrv_commit') ]); } @@ -487,14 +472,12 @@ public function testConnectPrepareStatement() $this->assertFlameGraph($traces, [ SpanAssertion::exists('sqlsrv_connect'), SpanAssertion::build('sqlsrv_prepare', 'sqlsrv', 'sql', $query) - ->withExactTags(self::baseTags($query)), + ->withExactAttributes(self::baseTags($query)), SpanAssertion::build('sqlsrv_execute', 'sqlsrv', 'sql', $query) - ->withExactTags(self::baseTags($query)) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes(self::baseTags($query), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]) + ])->samplingPriority(1) ], true, false); } @@ -515,15 +498,22 @@ public function testNoFakeServices() $this->assertFlameGraph($traces, [ SpanAssertion::exists('sqlsrv_connect'), SpanAssertion::build('sqlsrv_query', 'configured_service', 'sql', $query) - ->withExactTags(self::baseTags($query, false, null)) - ->withExactMetrics([ - Tag::DB_ROW_COUNT => 1.0, + ->withExactAttributes(self::baseTags($query, false, null), [ + Tag::DB_ROW_COUNT => 1, '_dd.agent_psr' => 1.0, - '_sampling_priority_v1' => 1.0, - ]) + ])->samplingPriority(1) ]); } + public function testConnectionMetadataPort() + { + $withoutPort = SQLSRVIntegration::extractConnectionMetadata(['host\\inst', []]); + $this->assertArrayNotHasKey(Tag::TARGET_PORT, $withoutPort); + + $withPort = SQLSRVIntegration::extractConnectionMetadata(['host, 1433', []]); + $this->assertSame(1433, $withPort[Tag::TARGET_PORT]); + } + private function createConnection() { $conn = sqlsrv_connect( diff --git a/tests/Integrations/Slim/Latest/CommonScenariosTest.php b/tests/Integrations/Slim/Latest/CommonScenariosTest.php index e801ed8b350..1ae551c3170 100644 --- a/tests/Integrations/Slim/Latest/CommonScenariosTest.php +++ b/tests/Integrations/Slim/Latest/CommonScenariosTest.php @@ -49,7 +49,7 @@ private function wrapMiddleware(array $children, array $setError = []): SpanAsse 'slim_test_app', 'web', 'Slim\\Middleware\\ErrorMiddleware' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', ])->withChildren([ SpanAssertion::build( @@ -57,7 +57,7 @@ private function wrapMiddleware(array $children, array $setError = []): SpanAsse 'slim_test_app', 'web', 'Slim\Middleware\RoutingMiddleware' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', ])->withChildren([ SpanAssertion::build( @@ -65,13 +65,13 @@ private function wrapMiddleware(array $children, array $setError = []): SpanAsse 'slim_test_app', 'web', 'Slim\\Views\\TwigMiddleware' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', ]) ->withChildren($children) - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->setError(...$setError) - ])->withExistingTagsNames(['error.stack'])->setError(...$setError), + ])->withExistingAttributeNames(['error.stack'])->setError(...$setError), ])/* ->setError(...$setError) ; no error on ErrorMiddleware*/; } else { return SpanAssertion::build( @@ -79,7 +79,7 @@ private function wrapMiddleware(array $children, array $setError = []): SpanAsse 'slim_test_app', 'web', 'Slim\\Middleware\\ErrorMiddleware' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', ])->withChildren([ SpanAssertion::build( @@ -87,7 +87,7 @@ private function wrapMiddleware(array $children, array $setError = []): SpanAsse 'slim_test_app', 'web', 'Slim\Middleware\RoutingMiddleware' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', ])->withChildren([ SpanAssertion::build( @@ -95,7 +95,7 @@ private function wrapMiddleware(array $children, array $setError = []): SpanAsse 'slim_test_app', 'web', 'Slim\\Views\\TwigMiddleware' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', ])->withChildren($children) ]), @@ -113,7 +113,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'GET /simple' - )->withExactTags([ + )->withExactAttributes([ 'slim.route.name' => 'simple-route', 'slim.route.handler' => 'Closure::__invoke', 'http.method' => 'GET', @@ -129,7 +129,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'Closure::__invoke' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', 'slim.route.name' => 'simple-route', ]) @@ -142,7 +142,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'GET /simple_view' - )->withExactTags([ + )->withExactAttributes([ 'slim.route.handler' => 'Closure::__invoke', 'http.method' => 'GET', 'http.url' => 'http://localhost/simple_view?key=value&', @@ -157,7 +157,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'Closure::__invoke' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', ])->withChildren([ SpanAssertion::build( @@ -165,7 +165,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'simple_view.phtml' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', 'slim.view' => 'simple_view.phtml', ]), @@ -179,7 +179,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ 'slim.route.handler' => 'Closure::__invoke', 'http.method' => 'GET', 'http.url' => 'http://localhost/error?key=value&', @@ -197,9 +197,9 @@ public function provideSpecs() 'slim_test_app', 'web', 'Closure::__invoke' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack', ])->setError(null, 'Foo error') ], @@ -213,7 +213,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'GET /parameterized/paramValue' - )->withExactTags([ + )->withExactAttributes([ 'slim.route.handler' => 'Closure::__invoke', 'http.method' => 'GET', 'http.url' => 'http://localhost/parameterized/paramValue', @@ -228,7 +228,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'Closure::__invoke' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', ]) ]), diff --git a/tests/Integrations/Slim/V3_12/CommonScenariosTest.php b/tests/Integrations/Slim/V3_12/CommonScenariosTest.php index b97d16527f0..b8fbd041e94 100644 --- a/tests/Integrations/Slim/V3_12/CommonScenariosTest.php +++ b/tests/Integrations/Slim/V3_12/CommonScenariosTest.php @@ -51,7 +51,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'GET simple-route' - )->withExactTags([ + )->withExactAttributes([ 'slim.route.controller' => 'Closure::__invoke', 'http.method' => 'GET', 'http.url' => 'http://localhost/simple?key=value&', @@ -65,7 +65,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'Closure::__invoke' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', ]) ]), @@ -76,7 +76,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'GET /simple_view' - )->withExactTags([ + )->withExactAttributes([ 'slim.route.controller' => 'App\SimpleViewController::index', 'http.method' => 'GET', 'http.url' => 'http://localhost/simple_view?key=value&', @@ -90,7 +90,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'App\SimpleViewController::index' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', ])->withChildren([ SpanAssertion::build( @@ -98,7 +98,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'simple_view.phtml' - )->withExactTags([ + )->withExactAttributes([ 'slim.view' => 'simple_view.phtml', Tag::COMPONENT => 'slim', ]) @@ -111,7 +111,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ 'slim.route.controller' => 'Closure::__invoke', 'http.method' => 'GET', 'http.url' => 'http://localhost/error?key=value&', @@ -126,9 +126,9 @@ public function provideSpecs() 'slim_test_app', 'web', 'Closure::__invoke' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ 'error.stack', ])->setError(null, 'Foo error') ]), @@ -139,7 +139,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'GET /parameterized/{value}' - )->withExactTags([ + )->withExactAttributes([ 'slim.route.controller' => 'Closure::__invoke', 'http.method' => 'GET', 'http.url' => 'http://localhost/parameterized/paramValue', @@ -153,7 +153,7 @@ public function provideSpecs() 'slim_test_app', 'web', 'Closure::__invoke' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'slim', ]) ]), diff --git a/tests/Integrations/Swoole/CommonScenariosTest.php b/tests/Integrations/Swoole/CommonScenariosTest.php index d72e0702665..e4685a65c25 100644 --- a/tests/Integrations/Swoole/CommonScenariosTest.php +++ b/tests/Integrations/Swoole/CommonScenariosTest.php @@ -69,7 +69,7 @@ public function provideSpecs() 'swoole_test_app', 'web', 'GET /simple' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/simple?key=value&', 'http.status_code' => '200', @@ -83,7 +83,7 @@ public function provideSpecs() 'swoole_test_app', 'web', 'GET /simple_view' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/simple_view?key=value&', 'http.status_code' => '200', @@ -97,7 +97,7 @@ public function provideSpecs() 'swoole_test_app', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/error?key=value&', 'http.status_code' => '500', diff --git a/tests/Integrations/Swoole/DistributedTracingTest.php b/tests/Integrations/Swoole/DistributedTracingTest.php index de570b6aa12..3a5bea182da 100644 --- a/tests/Integrations/Swoole/DistributedTracingTest.php +++ b/tests/Integrations/Swoole/DistributedTracingTest.php @@ -2,6 +2,7 @@ namespace DDTrace\Tests\Integrations\Swoole; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\WebFrameworkTestCase; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; use DDTrace\Tests\Frameworks\Util\Request\PostSpec; @@ -49,12 +50,12 @@ public function testDistributedTracing() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame($traceId, $trace["trace_id"]); - $this->assertSame("42", $trace["meta"]["_dd.p.user_id"]); - $this->assertSame("Test", $trace["meta"]["http.useragent"]); - $this->assertSame("somevalue", $trace["meta"]["http.request.headers.x-header"]); - $this->assertArrayNotHasKey('http.client_ip', $trace["meta"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame($traceId, SpanChecker::traceIdLow($traces[0])); + $this->assertSame("42", $trace["attributes"]["_dd.p.user_id"]); + $this->assertSame("Test", $trace["attributes"]["http.useragent"]); + $this->assertSame("somevalue", $trace["attributes"]["http.request.headers.x-header"]); + $this->assertArrayNotHasKey('http.client_ip', $trace["attributes"]); } public function testDistributedTracingPostWithAllowedParams() @@ -76,16 +77,16 @@ public function testDistributedTracingPostWithAllowedParams() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame($traceId, $trace["trace_id"]); - $this->assertSame("42", $trace["meta"]["_dd.p.user_id"]); - $this->assertSame("Test", $trace["meta"]["http.useragent"]); - $this->assertSame("somevalue", $trace["meta"]["http.request.headers.x-header"]); - $this->assertSame("", $trace["meta"]["http.request.post.pass_word"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.foo.password"]); - $this->assertSame("value1", $trace["meta"]["http.request.post.bar.key1"]); - $this->assertSame("value2", $trace["meta"]["http.request.post.bar.key2.baz"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.bar.key2.password"]); - $this->assertArrayNotHasKey('http.client_ip', $trace["meta"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame($traceId, SpanChecker::traceIdLow($traces[0])); + $this->assertSame("42", $trace["attributes"]["_dd.p.user_id"]); + $this->assertSame("Test", $trace["attributes"]["http.useragent"]); + $this->assertSame("somevalue", $trace["attributes"]["http.request.headers.x-header"]); + $this->assertSame("", $trace["attributes"]["http.request.post.pass_word"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.foo.password"]); + $this->assertSame("value1", $trace["attributes"]["http.request.post.bar.key1"]); + $this->assertSame("value2", $trace["attributes"]["http.request.post.bar.key2.baz"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.bar.key2.password"]); + $this->assertArrayNotHasKey('http.client_ip', $trace["attributes"]); } } diff --git a/tests/Integrations/Swoole/IPExtractionTest.php b/tests/Integrations/Swoole/IPExtractionTest.php index 74642010227..024ed330a68 100644 --- a/tests/Integrations/Swoole/IPExtractionTest.php +++ b/tests/Integrations/Swoole/IPExtractionTest.php @@ -2,6 +2,7 @@ namespace DDTrace\Tests\Integrations\Swoole; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\WebFrameworkTestCase; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; @@ -48,11 +49,11 @@ public function testIpExtraction() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame($traceId, $trace["trace_id"]); - $this->assertSame("42", $trace["meta"]["_dd.p.user_id"]); - $this->assertSame("Test", $trace["meta"]["http.useragent"]); - $this->assertSame("somevalue", $trace["meta"]["http.request.headers.x-header"]); - $this->assertSame("127.0.0.1", $trace["meta"]["http.client_ip"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame($traceId, SpanChecker::traceIdLow($traces[0])); + $this->assertSame("42", $trace["attributes"]["_dd.p.user_id"]); + $this->assertSame("Test", $trace["attributes"]["http.useragent"]); + $this->assertSame("somevalue", $trace["attributes"]["http.request.headers.x-header"]); + $this->assertSame("127.0.0.1", $trace["attributes"]["http.client_ip"]); } } diff --git a/tests/Integrations/Swoole/InvalidContentTypeTest.php b/tests/Integrations/Swoole/InvalidContentTypeTest.php index 109d67b3158..5c603de6198 100644 --- a/tests/Integrations/Swoole/InvalidContentTypeTest.php +++ b/tests/Integrations/Swoole/InvalidContentTypeTest.php @@ -46,10 +46,10 @@ public function testContentType() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame("POST", $trace["meta"]["http.method"]); - $this->assertArrayNotHasKey("http.request.post.password", $trace["meta"]); - $this->assertArrayNotHasKey("http.request.post.username", $trace["meta"]); - $this->assertArrayNotHasKey("http.request.post.foo.bar", $trace["meta"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame("POST", $trace["attributes"]["http.method"]); + $this->assertArrayNotHasKey("http.request.post.password", $trace["attributes"]); + $this->assertArrayNotHasKey("http.request.post.username", $trace["attributes"]); + $this->assertArrayNotHasKey("http.request.post.foo.bar", $trace["attributes"]); } } diff --git a/tests/Integrations/Swoole/SecurityTestingHeadersTest.php b/tests/Integrations/Swoole/SecurityTestingHeadersTest.php index 6a774f724d7..8b0288e489e 100644 --- a/tests/Integrations/Swoole/SecurityTestingHeadersTest.php +++ b/tests/Integrations/Swoole/SecurityTestingHeadersTest.php @@ -41,14 +41,14 @@ public function testSecurityTestingHeadersCollectedUnconditionally() $this->call($spec); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame( 'endpoint-scan-uuid', - $span['meta']['http.request.headers.x-datadog-endpoint-scan'] + $span['attributes']['http.request.headers.x-datadog-endpoint-scan'] ); $this->assertSame( 'security-test-uuid', - $span['meta']['http.request.headers.x-datadog-security-test'] + $span['attributes']['http.request.headers.x-datadog-security-test'] ); } @@ -58,14 +58,14 @@ public function testSecurityTestingHeadersAbsentWhenNotSent() $this->call(GetSpec::create('request', '/')); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertArrayNotHasKey( 'http.request.headers.x-datadog-endpoint-scan', - $span['meta'] + $span['attributes'] ); $this->assertArrayNotHasKey( 'http.request.headers.x-datadog-security-test', - $span['meta'] + $span['attributes'] ); } } diff --git a/tests/Integrations/Swoole/XWwwFormUrlencodedTest.php b/tests/Integrations/Swoole/XWwwFormUrlencodedTest.php index 5728f2b4c1d..c71efe8a5e5 100644 --- a/tests/Integrations/Swoole/XWwwFormUrlencodedTest.php +++ b/tests/Integrations/Swoole/XWwwFormUrlencodedTest.php @@ -46,9 +46,9 @@ public function testContentType() $this->call($spec); }); - $trace = $traces[0][0]; - $this->assertSame("", $trace["meta"]["http.request.post.password"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.username"]); - $this->assertSame("should_not_redact", $trace["meta"]["http.request.post.foo.bar"]); + $trace = $traces[0]['spans'][0]; + $this->assertSame("", $trace["attributes"]["http.request.post.password"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.username"]); + $this->assertSame("should_not_redact", $trace["attributes"]["http.request.post.foo.bar"]); } } diff --git a/tests/Integrations/Symfony/Latest/CommonScenariosTest.php b/tests/Integrations/Symfony/Latest/CommonScenariosTest.php index f7a1571c7af..88ccae1ba45 100644 --- a/tests/Integrations/Symfony/Latest/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/Latest/CommonScenariosTest.php @@ -65,7 +65,7 @@ public function provideSpecs() 'test_symfony_latest', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', 'http.route' => '/simple', @@ -90,7 +90,7 @@ public function provideSpecs() 'test_symfony_latest', 'web', 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ]), @@ -104,7 +104,7 @@ public function provideSpecs() 'test_symfony_latest', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', 'http.route' => '/simple_view', @@ -126,7 +126,7 @@ public function provideSpecs() 'test_symfony_latest', 'web', 'App\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -134,7 +134,7 @@ public function provideSpecs() 'test_symfony_latest', 'web', 'Twig\Environment twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -150,7 +150,7 @@ public function provideSpecs() 'test_symfony_latest', 'web', 'error' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', 'http.route' => '/error', @@ -161,7 +161,7 @@ public function provideSpecs() Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.kernel.terminate'), SpanAssertion::exists('symfony.httpkernel.kernel.handle') @@ -176,11 +176,11 @@ public function provideSpecs() 'test_symfony_latest', 'web', 'App\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.controller'), @@ -203,7 +203,7 @@ public function provideSpecs() 'test_symfony_latest', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', 'http.status_code' => '404', @@ -231,7 +231,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), ]), diff --git a/tests/Integrations/Symfony/Latest/MessengerTest.php b/tests/Integrations/Symfony/Latest/MessengerTest.php index e0867b9c134..1ff63a668d1 100644 --- a/tests/Integrations/Symfony/Latest/MessengerTest.php +++ b/tests/Integrations/Symfony/Latest/MessengerTest.php @@ -56,22 +56,19 @@ public function testAsyncSuccess() $this->call($spec); }, self::FIELDS_TO_IGNORE); - list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_SERVICE' => 'symfony_messenger_test', - 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', - 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', - 'DD_TRACE_DEBUG' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - ], [], ['messenger:consume', 'async', '--limit=1']); - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.symfony.latest.messenger_test.test_async_success_consumer', - true - ); + $this->snapshotFromTraces(function () { + list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_SERVICE' => 'symfony_messenger_test', + 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', + 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', + 'DD_TRACE_DEBUG' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], ['messenger:consume', 'async', '--limit=1']); + return $consumerTraces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.symfony.latest.messenger_test.test_async_success_consumer', [$this, 'isNotSampledAway']); } public function testAsyncFailure() @@ -81,22 +78,19 @@ public function testAsyncFailure() $this->call($spec); }, self::FIELDS_TO_IGNORE); - list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_SERVICE' => 'symfony_messenger_test', - 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', - 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', - ], [], ['messenger:consume', 'async', '--limit=1']); - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.symfony.latest.messenger_test.test_async_failure_consumer', - true - ); + $this->snapshotFromTraces(function () { + list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_SERVICE' => 'symfony_messenger_test', + 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', + 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], ['messenger:consume', 'async', '--limit=1']); + return $consumerTraces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.symfony.latest.messenger_test.test_async_failure_consumer', [$this, 'isNotSampledAway']); } public function testAsyncWithTracerDisabledOnConsume() diff --git a/tests/Integrations/Symfony/V3_0/CommonScenariosTest.php b/tests/Integrations/Symfony/V3_0/CommonScenariosTest.php index 6170e3069e6..731502e271c 100644 --- a/tests/Integrations/Symfony/V3_0/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/V3_0/CommonScenariosTest.php @@ -49,7 +49,7 @@ public function provideSpecs() 'symfony', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', 'http.method' => 'GET', @@ -71,7 +71,7 @@ public function provideSpecs() 'symfony', 'web', 'AppBundle\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]), @@ -88,7 +88,7 @@ public function provideSpecs() 'symfony', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', 'http.method' => 'GET', @@ -110,7 +110,7 @@ public function provideSpecs() 'symfony', 'web', 'AppBundle\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ])->withChildren([ @@ -119,7 +119,7 @@ public function provideSpecs() 'symfony', 'web', 'Symfony\Bundle\TwigBundle\TwigEngine twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]), @@ -137,7 +137,7 @@ public function provideSpecs() 'symfony', 'web', 'error' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', 'http.method' => 'GET', @@ -148,7 +148,7 @@ public function provideSpecs() '_dd.svc_src' => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ SpanAssertion::exists('symfony.httpkernel.kernel.boot'), @@ -162,12 +162,12 @@ public function provideSpecs() 'symfony', 'web', 'AppBundle\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.kernel.request'), @@ -177,7 +177,7 @@ public function provideSpecs() 'symfony', 'web', 'Symfony\Bundle\TwigBundle\Controller\ExceptionController::showAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ])->withChildren([ @@ -186,7 +186,7 @@ public function provideSpecs() 'symfony', 'web', 'Twig\Environment @Twig/Exception/error.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]), @@ -208,7 +208,7 @@ public function provideSpecs() 'symfony', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'Symfony\Bundle\TwigBundle\Controller\ExceptionController@showAction', 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', @@ -231,7 +231,7 @@ public function provideSpecs() 'symfony', 'web', 'Symfony\Bundle\TwigBundle\Controller\ExceptionController::showAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ])->withChildren([ @@ -240,7 +240,7 @@ public function provideSpecs() 'symfony', 'web', 'Twig\Environment @Twig/Exception/error.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]), @@ -254,7 +254,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), SpanAssertion::exists('symfony.kernel.terminate'), diff --git a/tests/Integrations/Symfony/V3_3/CommonScenariosTest.php b/tests/Integrations/Symfony/V3_3/CommonScenariosTest.php index 9641cbf0767..853ebdda0be 100644 --- a/tests/Integrations/Symfony/V3_3/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/V3_3/CommonScenariosTest.php @@ -49,7 +49,7 @@ public function provideSpecs() 'symfony', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', @@ -73,7 +73,7 @@ public function provideSpecs() 'symfony', 'web', 'AppBundle\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]), @@ -90,7 +90,7 @@ public function provideSpecs() 'symfony', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', @@ -114,7 +114,7 @@ public function provideSpecs() 'symfony', 'web', 'AppBundle\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ])->withChildren([ @@ -123,7 +123,7 @@ public function provideSpecs() 'symfony', 'web', 'Symfony\Bundle\TwigBundle\TwigEngine twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]), @@ -141,7 +141,7 @@ public function provideSpecs() 'symfony', 'web', 'error' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', @@ -153,7 +153,7 @@ public function provideSpecs() '_dd.svc_src' => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.kernel.terminate'), SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ @@ -169,12 +169,12 @@ public function provideSpecs() 'symfony', 'web', 'AppBundle\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.kernel.request'), @@ -185,7 +185,7 @@ public function provideSpecs() 'symfony', 'web', 'Symfony\Bundle\TwigBundle\Controller\ExceptionController::showAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ])->withChildren([ @@ -194,7 +194,7 @@ public function provideSpecs() 'symfony', 'web', 'Twig\Environment @Twig/Exception/error.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]), @@ -215,7 +215,7 @@ public function provideSpecs() 'symfony', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'Symfony\Bundle\TwigBundle\Controller\ExceptionController@showAction', 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', @@ -240,7 +240,7 @@ public function provideSpecs() 'symfony', 'web', 'Symfony\Bundle\TwigBundle\Controller\ExceptionController::showAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ])->withChildren([ @@ -249,7 +249,7 @@ public function provideSpecs() 'symfony', 'web', 'Twig\Environment @Twig/Exception/error.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]), @@ -263,7 +263,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), ]), diff --git a/tests/Integrations/Symfony/V3_4/AutofinishedTracesSymfony34Test.php b/tests/Integrations/Symfony/V3_4/AutofinishedTracesSymfony34Test.php index b74a1774c79..dff7e124872 100644 --- a/tests/Integrations/Symfony/V3_4/AutofinishedTracesSymfony34Test.php +++ b/tests/Integrations/Symfony/V3_4/AutofinishedTracesSymfony34Test.php @@ -33,7 +33,7 @@ public function testEndpointThatExitsWithNoProcess() 'symfony', 'web', 'terminated_by_exit' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'AppBundle\Controller\HomeController@actionBeingTerminatedByExit', 'symfony.route.name' => 'terminated_by_exit', @@ -57,7 +57,7 @@ public function testEndpointThatExitsWithNoProcess() 'symfony', 'web', 'AppBundle\Controller\HomeController::actionBeingTerminatedByExit' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]), diff --git a/tests/Integrations/Symfony/V3_4/CommonScenariosTest.php b/tests/Integrations/Symfony/V3_4/CommonScenariosTest.php index ac2f4768c52..ff1f7d5cf0b 100644 --- a/tests/Integrations/Symfony/V3_4/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/V3_4/CommonScenariosTest.php @@ -56,7 +56,7 @@ public function provideSpecs() 'test_symfony_34', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', @@ -79,7 +79,7 @@ public function provideSpecs() 'test_symfony_34', 'web', 'AppBundle\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), SpanAssertion::exists('symfony.kernel.response'), @@ -95,7 +95,7 @@ public function provideSpecs() 'test_symfony_34', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', @@ -119,7 +119,7 @@ public function provideSpecs() 'test_symfony_34', 'web', 'AppBundle\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -127,7 +127,7 @@ public function provideSpecs() 'test_symfony_34', 'web', 'Twig\Environment twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -145,7 +145,7 @@ public function provideSpecs() 'web', 'error' ) - ->withExactTags([ + ->withExactAttributes([ 'symfony.route.action' => 'AppBundle\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', @@ -156,7 +156,7 @@ public function provideSpecs() Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ SpanAssertion::exists('symfony.httpkernel.kernel.boot'), @@ -171,11 +171,11 @@ public function provideSpecs() 'test_symfony_34', 'web', 'AppBundle\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.controller')->withChildren([ @@ -202,7 +202,7 @@ public function provideSpecs() 'web', 'GET /does_not_exist' ) - ->withExactTags([ + ->withExactAttributes([ 'symfony.route.action' => 'Symfony\Bundle\TwigBundle\Controller\ExceptionController@showAction', 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', @@ -233,7 +233,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), SpanAssertion::exists('symfony.kernel.terminate'), diff --git a/tests/Integrations/Symfony/V3_4/TemplateEnginesTest.php b/tests/Integrations/Symfony/V3_4/TemplateEnginesTest.php index 9a730a1fb7e..22e86730003 100644 --- a/tests/Integrations/Symfony/V3_4/TemplateEnginesTest.php +++ b/tests/Integrations/Symfony/V3_4/TemplateEnginesTest.php @@ -26,7 +26,7 @@ public function testAlternateTemplatingEngine() 'symfony', 'web', 'alternate_templating' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'AppBundle\Controller\HomeController@indexAction', 'symfony.route.name' => 'alternate_templating', @@ -50,7 +50,7 @@ public function testAlternateTemplatingEngine() 'symfony', 'web', 'AppBundle\Controller\HomeController::indexAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ])->withChildren([ @@ -59,7 +59,7 @@ public function testAlternateTemplatingEngine() 'symfony', 'web', 'Symfony\Component\Templating\PhpEngine php_template.template.php' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', ]), diff --git a/tests/Integrations/Symfony/V4_0/CommonScenariosTest.php b/tests/Integrations/Symfony/V4_0/CommonScenariosTest.php index 9f3431270ae..d073885b81e 100644 --- a/tests/Integrations/Symfony/V4_0/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/V4_0/CommonScenariosTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'test_symfony_40', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', @@ -76,7 +76,7 @@ public function provideSpecs() 'test_symfony_40', 'web', 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), SpanAssertion::exists('symfony.kernel.response'), @@ -91,7 +91,7 @@ public function provideSpecs() 'test_symfony_40', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', @@ -115,7 +115,7 @@ public function provideSpecs() 'test_symfony_40', 'web', 'App\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -123,7 +123,7 @@ public function provideSpecs() 'test_symfony_40', 'web', 'Twig\Environment twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -139,7 +139,7 @@ public function provideSpecs() 'test_symfony_40', 'web', 'error' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', @@ -150,7 +150,7 @@ public function provideSpecs() Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.kernel.terminate'), SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ @@ -166,11 +166,11 @@ public function provideSpecs() 'test_symfony_40', 'web', 'App\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.kernel.request'), @@ -181,7 +181,7 @@ public function provideSpecs() 'test_symfony_40', 'web', 'Symfony\Bundle\TwigBundle\Controller\ExceptionController::showAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -189,7 +189,7 @@ public function provideSpecs() 'test_symfony_40', 'web', 'Twig\Environment @Twig/Exception/error.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -209,7 +209,7 @@ public function provideSpecs() 'test_symfony_40', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'Symfony\Bundle\TwigBundle\Controller\ExceptionController@showAction', 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', @@ -233,7 +233,7 @@ public function provideSpecs() 'test_symfony_40', 'web', 'Symfony\Bundle\TwigBundle\Controller\ExceptionController::showAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -241,7 +241,7 @@ public function provideSpecs() 'test_symfony_40', 'web', 'Twig\Environment @Twig/Exception/error.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -254,7 +254,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), ]), diff --git a/tests/Integrations/Symfony/V4_2/CommonScenariosTest.php b/tests/Integrations/Symfony/V4_2/CommonScenariosTest.php index c93c8f3e6d7..bca4b05f590 100644 --- a/tests/Integrations/Symfony/V4_2/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/V4_2/CommonScenariosTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'test_symfony_42', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', @@ -78,7 +78,7 @@ public function provideSpecs() 'test_symfony_42', 'web', 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ]), @@ -91,7 +91,7 @@ public function provideSpecs() 'test_symfony_42', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', @@ -113,7 +113,7 @@ public function provideSpecs() 'test_symfony_42', 'web', 'App\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -121,7 +121,7 @@ public function provideSpecs() 'test_symfony_42', 'web', 'Twig\Environment twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -139,7 +139,7 @@ public function provideSpecs() 'test_symfony_42', 'web', 'error' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', @@ -149,7 +149,7 @@ public function provideSpecs() Tag::SPAN_KIND => 'server', Tag::COMPONENT => 'symfony', ])->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.kernel.terminate'), SpanAssertion::exists('symfony.httpkernel.kernel.handle')->withChildren([ @@ -165,10 +165,10 @@ public function provideSpecs() 'test_symfony_42', 'web', 'App\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.kernel.request'), @@ -179,7 +179,7 @@ public function provideSpecs() 'test_symfony_42', 'web', 'Symfony\Bundle\TwigBundle\Controller\ExceptionController::showAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -187,7 +187,7 @@ public function provideSpecs() 'test_symfony_42', 'web', 'Twig\Environment @Twig/Exception/error.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -207,7 +207,7 @@ public function provideSpecs() 'test_symfony_42', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'Symfony\Bundle\TwigBundle\Controller\ExceptionController@showAction', 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', @@ -231,7 +231,7 @@ public function provideSpecs() 'test_symfony_42', 'web', 'Symfony\Bundle\TwigBundle\Controller\ExceptionController::showAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -239,7 +239,7 @@ public function provideSpecs() 'test_symfony_42', 'web', 'Twig\Environment @Twig/Exception/error.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -252,7 +252,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), ]), diff --git a/tests/Integrations/Symfony/V4_4/CommonScenariosTest.php b/tests/Integrations/Symfony/V4_4/CommonScenariosTest.php index 67aa59f88e8..9dfe68e2b4b 100644 --- a/tests/Integrations/Symfony/V4_4/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/V4_4/CommonScenariosTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'test_symfony_44', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', 'http.route' => '/simple', @@ -79,7 +79,7 @@ public function provideSpecs() 'test_symfony_44', 'web', 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ]), @@ -93,7 +93,7 @@ public function provideSpecs() 'test_symfony_44', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', 'http.route' => '/simple_view', @@ -115,7 +115,7 @@ public function provideSpecs() 'test_symfony_44', 'web', 'App\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -123,7 +123,7 @@ public function provideSpecs() 'test_symfony_44', 'web', 'Twig\Environment twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -141,7 +141,7 @@ public function provideSpecs() 'test_symfony_44', 'web', 'error' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', 'http.route' => '/error', @@ -152,7 +152,7 @@ public function provideSpecs() Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.kernel.terminate'), SpanAssertion::exists('symfony.httpkernel.kernel.handle') @@ -167,11 +167,11 @@ public function provideSpecs() 'test_symfony_44', 'web', 'App\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.controller'), @@ -198,7 +198,7 @@ public function provideSpecs() 'test_symfony_44', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', 'http.status_code' => '404', @@ -228,7 +228,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), ]), diff --git a/tests/Integrations/Symfony/V4_4/MessengerTest.php b/tests/Integrations/Symfony/V4_4/MessengerTest.php index c9f076a00c0..c9285eb9887 100644 --- a/tests/Integrations/Symfony/V4_4/MessengerTest.php +++ b/tests/Integrations/Symfony/V4_4/MessengerTest.php @@ -56,24 +56,21 @@ public function testAsyncSuccess() $this->call($spec); }, self::FIELDS_TO_IGNORE); - list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_SERVICE' => 'symfony_messenger_test', - 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', - 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', - 'DD_TRACE_DEBUG' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', - 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', - ], [], ['messenger:consume', 'async', '--limit=1']); - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.symfony.v4_4.messenger_test.test_async_success_consumer', - true - ); + $this->snapshotFromTraces(function () { + list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_SERVICE' => 'symfony_messenger_test', + 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', + 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', + 'DD_TRACE_DEBUG' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', + 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], ['messenger:consume', 'async', '--limit=1']); + return $consumerTraces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.symfony.v4_4.messenger_test.test_async_success_consumer', [$this, 'isNotSampledAway']); } public function testAsyncFailure() @@ -83,23 +80,20 @@ public function testAsyncFailure() $this->call($spec); }, self::FIELDS_TO_IGNORE); - list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_SERVICE' => 'symfony_messenger_test', - 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', - 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', - 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', - ], [], ['messenger:consume', 'async', '--limit=1']); - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.symfony.v4_4.messenger_test.test_async_failure_consumer', - true - ); + $this->snapshotFromTraces(function () { + list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_SERVICE' => 'symfony_messenger_test', + 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', + 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', + 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], ['messenger:consume', 'async', '--limit=1']); + return $consumerTraces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.symfony.v4_4.messenger_test.test_async_failure_consumer', [$this, 'isNotSampledAway']); } public function testAsyncWithTracerDisabledOnConsume() diff --git a/tests/Integrations/Symfony/V5_0/CommonScenariosTest.php b/tests/Integrations/Symfony/V5_0/CommonScenariosTest.php index 88ae9321a31..2292f847b77 100644 --- a/tests/Integrations/Symfony/V5_0/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/V5_0/CommonScenariosTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'test_symfony_50', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', 'http.route' => '/simple', @@ -79,7 +79,7 @@ public function provideSpecs() 'test_symfony_50', 'web', 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ]), @@ -93,7 +93,7 @@ public function provideSpecs() 'test_symfony_50', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', 'http.route' => '/simple_view', @@ -115,7 +115,7 @@ public function provideSpecs() 'test_symfony_50', 'web', 'App\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -123,7 +123,7 @@ public function provideSpecs() 'test_symfony_50', 'web', 'Twig\Environment twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -141,7 +141,7 @@ public function provideSpecs() 'test_symfony_50', 'web', 'error' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', 'http.route' => '/error', @@ -152,7 +152,7 @@ public function provideSpecs() Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.kernel.terminate'), SpanAssertion::exists('symfony.httpkernel.kernel.handle') @@ -167,11 +167,11 @@ public function provideSpecs() 'test_symfony_50', 'web', 'App\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.controller'), @@ -198,7 +198,7 @@ public function provideSpecs() 'test_symfony_50', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', 'http.status_code' => '404', @@ -228,7 +228,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), ]), diff --git a/tests/Integrations/Symfony/V5_1/CommonScenariosTest.php b/tests/Integrations/Symfony/V5_1/CommonScenariosTest.php index 66558d82595..3862991958c 100644 --- a/tests/Integrations/Symfony/V5_1/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/V5_1/CommonScenariosTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'test_symfony_51', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', 'http.route' => '/simple', @@ -79,7 +79,7 @@ public function provideSpecs() 'test_symfony_51', 'web', 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ]), @@ -93,7 +93,7 @@ public function provideSpecs() 'test_symfony_51', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', 'http.route' => '/simple_view', @@ -115,7 +115,7 @@ public function provideSpecs() 'test_symfony_51', 'web', 'App\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -123,7 +123,7 @@ public function provideSpecs() 'test_symfony_51', 'web', 'Twig\Environment twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -141,7 +141,7 @@ public function provideSpecs() 'test_symfony_51', 'web', 'error' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', 'http.route' => '/error', @@ -152,7 +152,7 @@ public function provideSpecs() Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.kernel.terminate'), SpanAssertion::exists('symfony.httpkernel.kernel.handle') @@ -167,11 +167,11 @@ public function provideSpecs() 'test_symfony_51', 'web', 'App\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.controller'), @@ -198,7 +198,7 @@ public function provideSpecs() 'test_symfony_51', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', 'http.status_code' => '404', @@ -228,7 +228,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), ]), diff --git a/tests/Integrations/Symfony/V5_2/CommonScenariosTest.php b/tests/Integrations/Symfony/V5_2/CommonScenariosTest.php index b3df1fbe337..af1126637a0 100644 --- a/tests/Integrations/Symfony/V5_2/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/V5_2/CommonScenariosTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'test_symfony_52', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', 'http.route' => '/simple', @@ -77,7 +77,7 @@ public function provideSpecs() 'test_symfony_52', 'web', 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ]), @@ -91,7 +91,7 @@ public function provideSpecs() 'test_symfony_52', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', 'http.route' => '/simple_view', @@ -113,7 +113,7 @@ public function provideSpecs() 'test_symfony_52', 'web', 'App\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -121,7 +121,7 @@ public function provideSpecs() 'test_symfony_52', 'web', 'Twig\Environment twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -137,7 +137,7 @@ public function provideSpecs() 'test_symfony_52', 'web', 'error' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', 'http.route' => '/error', @@ -148,7 +148,7 @@ public function provideSpecs() Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.kernel.terminate'), SpanAssertion::exists('symfony.httpkernel.kernel.handle') @@ -163,11 +163,11 @@ public function provideSpecs() 'test_symfony_52', 'web', 'App\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.controller'), @@ -190,7 +190,7 @@ public function provideSpecs() 'test_symfony_52', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', 'http.status_code' => '404', @@ -218,7 +218,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), ]), diff --git a/tests/Integrations/Symfony/V5_2/ConsoleCommandTest.php b/tests/Integrations/Symfony/V5_2/ConsoleCommandTest.php index cbae029cfe1..82a62c69c6f 100644 --- a/tests/Integrations/Symfony/V5_2/ConsoleCommandTest.php +++ b/tests/Integrations/Symfony/V5_2/ConsoleCommandTest.php @@ -31,7 +31,7 @@ public function testScenario() SpanAssertion::build('console', 'console', 'cli', 'console') ->withChildren([ SpanAssertion::build('symfony.console.command.run', 'symfony', 'cli', 'about') - ->withExactTags([ + ->withExactAttributes([ 'symfony.console.command.class' => 'Symfony\Bundle\FrameworkBundle\Command\AboutCommand', Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', diff --git a/tests/Integrations/Symfony/V5_2/MessengerTest.php b/tests/Integrations/Symfony/V5_2/MessengerTest.php index 5299da5d5e5..25c000d2e31 100644 --- a/tests/Integrations/Symfony/V5_2/MessengerTest.php +++ b/tests/Integrations/Symfony/V5_2/MessengerTest.php @@ -56,24 +56,21 @@ public function testAsyncSuccess() $this->call($spec); }, self::FIELDS_TO_IGNORE); - list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_SERVICE' => 'symfony_messenger_test', - 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', - 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', - 'DD_TRACE_DEBUG' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', - 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', - ], [], ['messenger:consume', 'async', '--limit=1']); - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.symfony.v5_2.messenger_test.test_async_success_consumer', - true - ); + $this->snapshotFromTraces(function () { + list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_SERVICE' => 'symfony_messenger_test', + 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', + 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', + 'DD_TRACE_DEBUG' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', + 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], ['messenger:consume', 'async', '--limit=1']); + return $consumerTraces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.symfony.v5_2.messenger_test.test_async_success_consumer', [$this, 'isNotSampledAway']); } public function testAsyncFailure() @@ -83,24 +80,20 @@ public function testAsyncFailure() $this->call($spec); }, self::FIELDS_TO_IGNORE); - list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_SERVICE' => 'symfony_messenger_test', - 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', - 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', - 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', - ], [], ['messenger:consume', 'async', '--limit=1']); - - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.symfony.v5_2.messenger_test.test_async_failure_consumer', - true - ); + $this->snapshotFromTraces(function () { + list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_SERVICE' => 'symfony_messenger_test', + 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', + 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', + 'DD_CODE_ORIGIN_MAX_USER_FRAMES' => '0', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], ['messenger:consume', 'async', '--limit=1']); + return $consumerTraces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.symfony.v5_2.messenger_test.test_async_failure_consumer', [$this, 'isNotSampledAway']); } public function testAsyncWithTracerDisabledOnConsume() diff --git a/tests/Integrations/Symfony/V6_2/CommonScenariosTest.php b/tests/Integrations/Symfony/V6_2/CommonScenariosTest.php index 09c7927a953..25596a3fe20 100644 --- a/tests/Integrations/Symfony/V6_2/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/V6_2/CommonScenariosTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'test_symfony_62', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', 'http.route' => '/simple', @@ -77,7 +77,7 @@ public function provideSpecs() 'test_symfony_62', 'web', 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ]), @@ -91,7 +91,7 @@ public function provideSpecs() 'test_symfony_62', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', 'http.route' => '/simple_view', @@ -113,7 +113,7 @@ public function provideSpecs() 'test_symfony_62', 'web', 'App\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -121,7 +121,7 @@ public function provideSpecs() 'test_symfony_62', 'web', 'Twig\Environment twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -137,7 +137,7 @@ public function provideSpecs() 'test_symfony_62', 'web', 'error' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', 'http.route' => '/error', @@ -148,7 +148,7 @@ public function provideSpecs() Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.kernel.terminate'), SpanAssertion::exists('symfony.httpkernel.kernel.handle') @@ -163,11 +163,11 @@ public function provideSpecs() 'test_symfony_62', 'web', 'App\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.controller'), @@ -190,7 +190,7 @@ public function provideSpecs() 'test_symfony_62', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', 'http.status_code' => '404', @@ -218,7 +218,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), ]), diff --git a/tests/Integrations/Symfony/V6_2/ConsoleCommandTest.php b/tests/Integrations/Symfony/V6_2/ConsoleCommandTest.php index 7024e4ba9ff..bf140ac7919 100644 --- a/tests/Integrations/Symfony/V6_2/ConsoleCommandTest.php +++ b/tests/Integrations/Symfony/V6_2/ConsoleCommandTest.php @@ -31,7 +31,7 @@ public function testScenario() SpanAssertion::build('console', 'console', 'cli', 'console') ->withChildren([ SpanAssertion::build('symfony.console.command.run', 'symfony', 'cli', 'about') - ->withExactTags([ + ->withExactAttributes([ 'symfony.console.command.class' => 'Symfony\Bundle\FrameworkBundle\Command\AboutCommand', Tag::COMPONENT => 'symfony', '_dd.svc_src' => 'symfony', diff --git a/tests/Integrations/Symfony/V6_2/MessengerTest.php b/tests/Integrations/Symfony/V6_2/MessengerTest.php index 0fc145b54ac..2bba9b379ba 100644 --- a/tests/Integrations/Symfony/V6_2/MessengerTest.php +++ b/tests/Integrations/Symfony/V6_2/MessengerTest.php @@ -44,7 +44,7 @@ protected static function getEnvs() 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', - 'DD_TRACE_PHPREDIS_ENABLED' => 'false' // We are NOT testing the phpredis integration + 'DD_TRACE_PHPREDIS_ENABLED' => 'false', // We are NOT testing the phpredis integration ]); } @@ -55,24 +55,21 @@ public function testAsyncSuccess() $this->call($spec); }, self::FIELDS_TO_IGNORE); - list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_SERVICE' => 'symfony_messenger_test', - 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', - 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', - 'DD_TRACE_DEBUG' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', - 'DD_TRACE_PHPREDIS_ENABLED' => 'false' // We are NOT testing the phpredis integration - ], [], ['mess:cons', 'async', '--limit=1']); - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.symfony.v6_2.messenger_test.test_async_success_consumer', - true - ); + $this->snapshotFromTraces(function () { + list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_SERVICE' => 'symfony_messenger_test', + 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', + 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', + 'DD_TRACE_DEBUG' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', + 'DD_TRACE_PHPREDIS_ENABLED' => 'false', // We are NOT testing the phpredis integration + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], ['mess:cons', 'async', '--limit=1']); + return $consumerTraces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.symfony.v6_2.messenger_test.test_async_success_consumer', [$this, 'isNotSampledAway']); } public function testAsyncFailure() @@ -82,23 +79,20 @@ public function testAsyncFailure() $this->call($spec); }, self::FIELDS_TO_IGNORE); - list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_SERVICE' => 'symfony_messenger_test', - 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', - 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', - 'DD_TRACE_PHPREDIS_ENABLED' => 'false' // We are NOT testing the phpredis integration - ], [], ['messenger:consume', 'async', '--limit=1']); - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.symfony.v6_2.messenger_test.test_async_failure_consumer', - true - ); + $this->snapshotFromTraces(function () { + list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_SERVICE' => 'symfony_messenger_test', + 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', + 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', + 'DD_TRACE_PHPREDIS_ENABLED' => 'false', // We are NOT testing the phpredis integration + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], ['messenger:consume', 'async', '--limit=1']); + return $consumerTraces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.symfony.v6_2.messenger_test.test_async_failure_consumer', [$this, 'isNotSampledAway']); } public function testAsyncWithTracerDisabledOnConsume() diff --git a/tests/Integrations/Symfony/V7_3/CommonScenariosTest.php b/tests/Integrations/Symfony/V7_3/CommonScenariosTest.php index 9d80fac2810..80902c4714f 100644 --- a/tests/Integrations/Symfony/V7_3/CommonScenariosTest.php +++ b/tests/Integrations/Symfony/V7_3/CommonScenariosTest.php @@ -65,7 +65,7 @@ public function provideSpecs() 'test_symfony_73', 'web', 'simple' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleAction', 'symfony.route.name' => 'simple', 'http.route' => '/simple', @@ -90,7 +90,7 @@ public function provideSpecs() 'test_symfony_73', 'web', 'App\Controller\CommonScenariosController::simpleAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ]), @@ -104,7 +104,7 @@ public function provideSpecs() 'test_symfony_73', 'web', 'simple_view' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@simpleViewAction', 'symfony.route.name' => 'simple_view', 'http.route' => '/simple_view', @@ -126,7 +126,7 @@ public function provideSpecs() 'test_symfony_73', 'web', 'App\Controller\CommonScenariosController::simpleViewAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ])->withChildren([ SpanAssertion::build( @@ -134,7 +134,7 @@ public function provideSpecs() 'test_symfony_73', 'web', 'Twig\Environment twig_template.html.twig' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]), ]), @@ -150,7 +150,7 @@ public function provideSpecs() 'test_symfony_73', 'web', 'error' - )->withExactTags([ + )->withExactAttributes([ 'symfony.route.action' => 'App\Controller\CommonScenariosController@errorAction', 'symfony.route.name' => 'error', 'http.route' => '/error', @@ -161,7 +161,7 @@ public function provideSpecs() Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']) + ->withExistingAttributeNames(['error.stack']) ->withChildren([ SpanAssertion::exists('symfony.kernel.terminate'), SpanAssertion::exists('symfony.httpkernel.kernel.handle') @@ -176,11 +176,11 @@ public function provideSpecs() 'test_symfony_73', 'web', 'App\Controller\CommonScenariosController::errorAction' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => 'symfony', ]) ->setError('Exception', 'An exception occurred') - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), SpanAssertion::exists('symfony.kernel.handleException')->withChildren([ SpanAssertion::exists('symfony.kernel.exception')->withChildren([ SpanAssertion::exists('symfony.controller'), @@ -203,7 +203,7 @@ public function provideSpecs() 'test_symfony_73', 'web', 'GET /does_not_exist' - )->withExactTags([ + )->withExactAttributes([ 'http.method' => 'GET', 'http.url' => 'http://localhost/does_not_exist?key=value&', 'http.status_code' => '404', @@ -231,7 +231,7 @@ public function provideSpecs() 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException', 'No route found for "GET /does_not_exist"' ) - ->withExistingTagsNames(['error.stack']), + ->withExistingAttributeNames(['error.stack']), ]), ]), ]), diff --git a/tests/Integrations/Symfony/V7_3/MessengerTest.php b/tests/Integrations/Symfony/V7_3/MessengerTest.php index d11b39f76f1..59a3ca14e09 100644 --- a/tests/Integrations/Symfony/V7_3/MessengerTest.php +++ b/tests/Integrations/Symfony/V7_3/MessengerTest.php @@ -56,22 +56,19 @@ public function testAsyncSuccess() $this->call($spec); }, self::FIELDS_TO_IGNORE); - list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_SERVICE' => 'symfony_messenger_test', - 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', - 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', - 'DD_TRACE_DEBUG' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - ], [], ['messenger:consume', 'async', '--limit=1']); - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.symfony.v7_3.messenger_test.test_async_success_consumer', - true - ); + $this->snapshotFromTraces(function () { + list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_SERVICE' => 'symfony_messenger_test', + 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', + 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', + 'DD_TRACE_DEBUG' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], ['messenger:consume', 'async', '--limit=1']); + return $consumerTraces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.symfony.v7_3.messenger_test.test_async_success_consumer', [$this, 'isNotSampledAway']); } public function testAsyncFailure() @@ -81,22 +78,19 @@ public function testAsyncFailure() $this->call($spec); }, self::FIELDS_TO_IGNORE); - list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_EXEC_ENABLED' => 'false', - 'DD_SERVICE' => 'symfony_messenger_test', - 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', - 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', - 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', - 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', - ], [], ['messenger:consume', 'async', '--limit=1']); - - $this->snapshotFromTraces( - $consumerTraces, - self::FIELDS_TO_IGNORE, - 'tests.integrations.symfony.v7_3.messenger_test.test_async_failure_consumer', - true - ); + $this->snapshotFromTraces(function () { + list($consumerTraces) = $this->inCli(self::getConsoleScript(), [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_EXEC_ENABLED' => 'false', + 'DD_SERVICE' => 'symfony_messenger_test', + 'DD_TRACE_REMOVE_AUTOINSTRUMENTATION_ORPHANS' => 'true', + 'DD_TRACE_SYMFONY_MESSENGER_MIDDLEWARES' => 'true', + 'DD_INSTRUMENTATION_TELEMETRY_ENABLED' => 'false', + 'DD_TRACE_SIDECAR_TRACE_SENDER' => 'false', + 'DD_TRACE_AGENT_PROTOCOL_VERSION' => '0.4', + ], [], ['messenger:consume', 'async', '--limit=1']); + return $consumerTraces; + }, self::FIELDS_TO_IGNORE, 'tests.integrations.symfony.v7_3.messenger_test.test_async_failure_consumer', [$this, 'isNotSampledAway']); } public function testAsyncWithTracerDisabledOnConsume() diff --git a/tests/Integrations/Yii/Latest/CommonScenariosTest.php b/tests/Integrations/Yii/Latest/CommonScenariosTest.php index 62410148e30..d29ba43c69e 100644 --- a/tests/Integrations/Yii/Latest/CommonScenariosTest.php +++ b/tests/Integrations/Yii/Latest/CommonScenariosTest.php @@ -52,7 +52,7 @@ public function provideSpecs() 'yii2_test_app', 'web', 'GET /simple' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/simple?key=value&', Tag::HTTP_STATUS_CODE => '200', @@ -67,7 +67,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'yii\web\Application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -75,7 +75,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'simple/index' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -83,7 +83,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'index' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ]), ]), @@ -96,7 +96,7 @@ public function provideSpecs() 'yii2_test_app', 'web', 'GET /simple_view' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/simple_view?key=value&', Tag::HTTP_STATUS_CODE => '200', @@ -111,7 +111,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'yii\web\Application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -119,7 +119,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'simple/view' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -127,7 +127,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'view' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::exists('yii\web\View.renderFile'), @@ -143,7 +143,7 @@ public function provideSpecs() 'yii2_test_app', 'web', 'GET /error' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/error?key=value&', Tag::HTTP_STATUS_CODE => '500', @@ -164,7 +164,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'site/error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -172,7 +172,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::exists('yii\web\View.renderFile'), @@ -184,7 +184,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'yii\web\Application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->setError('Exception', 'datadog', true) ->withChildren([ @@ -193,7 +193,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'simple/error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->setError('Exception', 'datadog', true) ->withChildren([ @@ -202,7 +202,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'error' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->setError('Exception', 'datadog', true), ]), @@ -215,7 +215,7 @@ public function provideSpecs() 'yii2_test_app', 'web', 'GET /parameterized/?' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/parameterized/paramValue', Tag::HTTP_STATUS_CODE => '200', @@ -230,7 +230,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'yii\web\Application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -238,7 +238,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'simple/parameterized' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -246,7 +246,7 @@ public function provideSpecs() 'yii2_test_app', Type::WEB_SERVLET, 'parameterized' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ]), ]), diff --git a/tests/Integrations/Yii/Latest/LazyLoadingIntegrationsFromYiiTest.php b/tests/Integrations/Yii/Latest/LazyLoadingIntegrationsFromYiiTest.php index 7f78b327371..eeb6786663f 100644 --- a/tests/Integrations/Yii/Latest/LazyLoadingIntegrationsFromYiiTest.php +++ b/tests/Integrations/Yii/Latest/LazyLoadingIntegrationsFromYiiTest.php @@ -38,7 +38,7 @@ public function testRootIndexRoute() 'yii2_test_app', Type::WEB_SERVLET, 'GET /site/index' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/site/index', Tag::HTTP_STATUS_CODE => '200', @@ -53,7 +53,7 @@ public function testRootIndexRoute() 'yii2_test_app', Type::WEB_SERVLET, 'yii\web\Application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -61,7 +61,7 @@ public function testRootIndexRoute() 'yii2_test_app', Type::WEB_SERVLET, 'index' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -69,7 +69,7 @@ public function testRootIndexRoute() 'yii2_test_app', Type::WEB_SERVLET, 'index' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ]), ]), diff --git a/tests/Integrations/Yii/Latest/ModuleTest.php b/tests/Integrations/Yii/Latest/ModuleTest.php index 8cadc7e3b84..4fe2c271b9d 100644 --- a/tests/Integrations/Yii/Latest/ModuleTest.php +++ b/tests/Integrations/Yii/Latest/ModuleTest.php @@ -37,7 +37,7 @@ public function testGet() 'yii2_test_app', Type::WEB_SERVLET, 'GET /forum/?/?/?' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/forum/new-york/new-york/manhattan?key=value&', Tag::HTTP_STATUS_CODE => '200', @@ -52,7 +52,7 @@ public function testGet() 'yii2_test_app', Type::WEB_SERVLET, 'yii\web\Application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -60,7 +60,7 @@ public function testGet() 'yii2_test_app', Type::WEB_SERVLET, 'forum/module/view' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -68,7 +68,7 @@ public function testGet() 'yii2_test_app', Type::WEB_SERVLET, 'view' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ]) ]) diff --git a/tests/Integrations/Yii/Latest/ParameterizedRouteTest.php b/tests/Integrations/Yii/Latest/ParameterizedRouteTest.php index 82a4af944c5..8ed0807644d 100644 --- a/tests/Integrations/Yii/Latest/ParameterizedRouteTest.php +++ b/tests/Integrations/Yii/Latest/ParameterizedRouteTest.php @@ -37,7 +37,7 @@ public function testGet() 'yii2_test_app', Type::WEB_SERVLET, 'GET /homes/?/?/?' - )->withExactTags([ + )->withExactAttributes([ Tag::HTTP_METHOD => 'GET', Tag::HTTP_URL => 'http://localhost/homes/new-york/new-york/manhattan?key=value&', Tag::HTTP_STATUS_CODE => '200', @@ -52,7 +52,7 @@ public function testGet() 'yii2_test_app', Type::WEB_SERVLET, 'yii\web\Application.run' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -60,7 +60,7 @@ public function testGet() 'yii2_test_app', Type::WEB_SERVLET, 'homes/view' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ])->withChildren([ SpanAssertion::build( @@ -68,7 +68,7 @@ public function testGet() 'yii2_test_app', Type::WEB_SERVLET, 'view' - )->withExactTags([ + )->withExactAttributes([ Tag::COMPONENT => "yii", ]) ]) diff --git a/tests/Integrations/ZendFramework/V1/CommonScenariosTest.php b/tests/Integrations/ZendFramework/V1/CommonScenariosTest.php index a2b52b6920c..fe86278745f 100644 --- a/tests/Integrations/ZendFramework/V1/CommonScenariosTest.php +++ b/tests/Integrations/ZendFramework/V1/CommonScenariosTest.php @@ -53,7 +53,7 @@ public function provideSpecs() $specs = [ 'A simple GET request returning a string' => [ SpanAssertion::build('zf1.request', 'zf1', 'web', 'simple@index default') - ->withExactTags([ + ->withExactAttributes([ 'zf1.controller' => 'simple', 'zf1.action' => 'index', 'zf1.route_name' => 'default', @@ -67,7 +67,7 @@ public function provideSpecs() ], 'A simple GET request with a view' => [ SpanAssertion::build('zf1.request', 'zf1', 'web', 'simple@view my_simple_view_route') - ->withExactTags([ + ->withExactAttributes([ 'zf1.controller' => 'simple', 'zf1.action' => 'view', 'zf1.route_name' => 'my_simple_view_route', @@ -81,7 +81,7 @@ public function provideSpecs() ], 'A GET request with an exception' => [ SpanAssertion::build('zf1.request', 'zf1', 'web', 'error@error default') - ->withExactTags([ + ->withExactAttributes([ 'zf1.controller' => 'error', 'zf1.action' => 'error', 'zf1.route_name' => 'default', diff --git a/tests/Integrations/ZendFramework/V1_21/CommonScenariosTest.php b/tests/Integrations/ZendFramework/V1_21/CommonScenariosTest.php index 5837b868ca0..da6f5cdc607 100644 --- a/tests/Integrations/ZendFramework/V1_21/CommonScenariosTest.php +++ b/tests/Integrations/ZendFramework/V1_21/CommonScenariosTest.php @@ -44,7 +44,7 @@ public function provideSpecs() $specs = [ 'A simple GET request returning a string' => [ SpanAssertion::build('zf1.request', 'zf1', 'web', 'simple@index default') - ->withExactTags([ + ->withExactAttributes([ 'zf1.controller' => 'simple', 'zf1.action' => 'index', 'zf1.route_name' => 'default', @@ -58,7 +58,7 @@ public function provideSpecs() ], 'A simple GET request with a view' => [ SpanAssertion::build('zf1.request', 'zf1', 'web', 'simple@view my_simple_view_route') - ->withExactTags([ + ->withExactAttributes([ 'zf1.controller' => 'simple', 'zf1.action' => 'view', 'zf1.route_name' => 'my_simple_view_route', @@ -72,7 +72,7 @@ public function provideSpecs() ], 'A GET request with an exception' => [ SpanAssertion::build('zf1.request', 'zf1', 'web', 'error@error default') - ->withExactTags([ + ->withExactAttributes([ 'zf1.controller' => 'error', 'zf1.action' => 'error', 'zf1.route_name' => 'default', diff --git a/tests/OpenTelemetry/Integration/API/BaggageTest.php b/tests/OpenTelemetry/Integration/API/BaggageTest.php index 7e1dc5bb87a..1105513971f 100644 --- a/tests/OpenTelemetry/Integration/API/BaggageTest.php +++ b/tests/OpenTelemetry/Integration/API/BaggageTest.php @@ -6,6 +6,7 @@ use DDTrace\Tests\Common\BaseTestCase; use DDTrace\Tests\Common\SpanAssertion; use DDTrace\Tests\Common\SpanAssertionTrait; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\TracerTestTrait; use OpenTelemetry\API\Baggage\Baggage; use OpenTelemetry\API\Baggage\Propagation\BaggagePropagator; @@ -92,7 +93,7 @@ public function testSpansAndBaggage() $parentSpan->end(); }); - list($parent, $child) = $traces[0]; + list($parent, $child) = (new SpanChecker())->flattenTraces($traces); $this->assertSame(2, $parent['span_kind']); // span_kind enum: Server=2 $this->assertSame('GET', $parent['attributes']['http.method']); $this->assertSame('/parent', $parent['attributes']['http.uri']); diff --git a/tests/OpenTelemetry/Integration/API/TracerTest.php b/tests/OpenTelemetry/Integration/API/TracerTest.php index b56a7bc76fd..cf9ca5c7c4a 100644 --- a/tests/OpenTelemetry/Integration/API/TracerTest.php +++ b/tests/OpenTelemetry/Integration/API/TracerTest.php @@ -7,6 +7,7 @@ use DDTrace\Tests\Common\BaseTestCase; use DDTrace\Tests\Common\SpanAssertion; use DDTrace\Tests\Common\SpanAssertionTrait; +use DDTrace\Tests\Common\SpanChecker; use DDTrace\Tests\Common\TracerTestTrait; use OpenTelemetry\API\Trace\NonRecordingSpan; use OpenTelemetry\API\Trace\SpanContext; @@ -65,7 +66,7 @@ public function testOtelSetSpanStatusError() $errorSpan->end(); }); - $this->assertSame('error_desc', $traces[0][0]['attributes']['error.message']); + $this->assertSame('error_desc', $traces[0]['spans'][0]['attributes']['error.message']); } public function testUnorderedOtelSpanActivation() @@ -105,13 +106,12 @@ public function testManuallyCreatedSpanWithNoCustomTags() $span->end(); }); - $span = $traces[0][0]; - $this->assertNotEmpty($span['trace_id']); - $this->assertSame($span['trace_id'], $span['span_id']); + $span = $traces[0]['spans'][0]; + $this->assertSame(SpanChecker::traceIdLow($traces[0]), $span['span_id']); $this->assertNotEquals(0, $span['duration']); $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); - $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['sampling_priority']); + $this->assertEquals(PrioritySampling::AUTO_KEEP, $traces[0]['priority']); } public function testManuallyCreatedSpanWithCustomTags() @@ -127,13 +127,12 @@ public function testManuallyCreatedSpanWithCustomTags() $span->end(); }); - $span = $traces[0][0]; - $this->assertNotEmpty($span['trace_id']); - $this->assertSame($span['trace_id'], $span['span_id']); + $span = $traces[0]['spans'][0]; + $this->assertSame(SpanChecker::traceIdLow($traces[0]), $span['span_id']); $this->assertNotEquals(0, $span['duration']); $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); - $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['sampling_priority']); + $this->assertEquals(PrioritySampling::AUTO_KEEP, $traces[0]['priority']); $this->assertSame('bar', $span['attributes']['foo']); $this->assertSame('baz', $span['attributes']['bar']); } @@ -151,13 +150,12 @@ public function testManuallyCreatedSpanWithNestedAttributes() $span->end(); }); - $span = $traces[0][0]; - $this->assertNotEmpty($span['trace_id']); - $this->assertSame($span['trace_id'], $span['span_id']); + $span = $traces[0]['spans'][0]; + $this->assertSame(SpanChecker::traceIdLow($traces[0]), $span['span_id']); $this->assertNotEquals(0, $span['duration']); $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); - $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['sampling_priority']); + $this->assertEquals(PrioritySampling::AUTO_KEEP, $traces[0]['priority']); $this->assertSame('bar', $span['attributes']['foo']); $this->assertSame('baz', $span['attributes']['bar']); $this->assertSame('bar', $span['attributes']['nested']['foo']); @@ -181,14 +179,11 @@ public function testManuallyCreatedNestedSpansBasic() } }); - $spans = $traces[0]; - list($parentSpan, $childSpan) = $spans; - $this->assertNotEmpty($parentSpan['trace_id']); - $this->assertSame($parentSpan['trace_id'], $parentSpan['span_id']); - $this->assertSame($parentSpan['trace_id'], $childSpan['trace_id']); - $this->assertSame($parentSpan['span_id'], $childSpan['trace_id']); + list($parentSpan, $childSpan) = (new SpanChecker())->flattenTraces($traces); + foreach ($traces as $trace) { + $this->assertSame(SpanChecker::traceIdLow($trace), $parentSpan['span_id']); + } $this->assertNotSame($parentSpan['span_id'], $childSpan['span_id']); - $this->assertNotSame($childSpan['trace_id'], $childSpan['span_id']); } public function testCreateSpanWithParentContext() @@ -204,14 +199,11 @@ public function testCreateSpanWithParentContext() $parent->end(); }); - $spans = $traces[0]; - list($parentSpan, $childSpan) = $spans; - $this->assertNotEmpty($parentSpan['trace_id']); - $this->assertSame($parentSpan['trace_id'], $parentSpan['span_id']); - $this->assertSame($parentSpan['trace_id'], $childSpan['trace_id']); - $this->assertSame($parentSpan['span_id'], $childSpan['trace_id']); + list($parentSpan, $childSpan) = (new SpanChecker())->flattenTraces($traces); + foreach ($traces as $trace) { + $this->assertSame(SpanChecker::traceIdLow($trace), $parentSpan['span_id']); + } $this->assertNotSame($parentSpan['span_id'], $childSpan['span_id']); - $this->assertNotSame($childSpan['trace_id'], $childSpan['span_id']); } public function testCreateSpanInvalidParent() @@ -224,11 +216,10 @@ public function testCreateSpanInvalidParent() $child->end(); }); - $span = $traces[0][0]; - $this->assertNotEmpty($span['trace_id']); - $this->assertSame($span['trace_id'], $span['span_id']); + $span = $traces[0]['spans'][0]; + $this->assertSame(SpanChecker::traceIdLow($traces[0]), $span['span_id']); $this->assertArrayNotHasKey('parent_id', $span); - $this->assertEquals(PrioritySampling::AUTO_KEEP, $span['sampling_priority']); + $this->assertEquals(PrioritySampling::AUTO_KEEP, $traces[0]['priority']); } public function testCreateANewTraceInTheSameProcess() @@ -256,17 +247,14 @@ public function testCreateANewTraceInTheSameProcess() $scope->detach(); }); - $spans = $traces[0]; - list($span, $rootSpan, $childSpan) = $spans; - - $this->assertNotEmpty($rootSpan['trace_id']); - $this->assertSame($rootSpan['trace_id'], $rootSpan['span_id']); - $this->assertSame($rootSpan['trace_id'], $childSpan['trace_id']); + list($span, $rootSpan, $childSpan) = (new SpanChecker())->flattenTraces($traces); $this->assertSame($rootSpan['span_id'], $childSpan['parent_id']); - $this->assertNotEmpty($span['trace_id']); - $this->assertSame($span['trace_id'], $span['span_id']); - $this->assertNotSame($rootSpan['trace_id'], $span['trace_id']); + // Both root spans start their own trace, so their span ids are the two trace ids. + $traceIds = array_map([SpanChecker::class, 'traceIdLow'], $traces); + $this->assertContains($rootSpan['span_id'], $traceIds); + $this->assertContains($span['span_id'], $traceIds); + $this->assertCount(2, array_unique(array_column($traces, 'trace_id'))); } public function testSpanAttributes() @@ -290,7 +278,7 @@ public function testSpanAttributes() $span->end(); }); - $attributes = $traces[0][0]['attributes']; + $attributes = $traces[0]['spans'][0]['attributes']; $this->assertSame("a", $attributes['string']); $this->assertArrayNotHasKey("null-string", $attributes); $this->assertSame("", $attributes['empty_string']); @@ -320,7 +308,7 @@ public function testSpanKind($otelSpanKind, $tagSpanKind) $span->end(); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame($tagSpanKind, $span['span_kind']); } @@ -336,50 +324,43 @@ public function providerSpanKind() ]; } - public function providerAnalyticsEvent() + public function providerHttpStatusCode() { 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] + 'numeric http.status_code' => [['http.status_code' => 200], ['http.status_code' => '200']], + 'string http.status_code' => [['http.status_code' => '201'], ['http.status_code' => '201']], + 'numeric http.response.status_code' => [['http.response.status_code' => 300], ['http.status_code' => '300']], + // Only the numeric (semconv) form is remapped + 'string http.response.status_code' => [['http.response.status_code' => '300'], ['http.response.status_code' => '300']], + 'response status code set first wins' => [ + ['http.response.status_code' => 300, 'http.status_code' => 302], + ['http.status_code' => '300'], + ], + 'response status code set last wins' => [ + ['http.status_code' => 302, 'http.response.status_code' => 300], + ['http.status_code' => '300'], + ], ]; } /** - * @dataProvider providerAnalyticsEvent + * @dataProvider providerHttpStatusCode */ - public function testReservedAttributesOverridesAnalyticsEvent($analyticsEventValue, $expectedMetricValue) + public function testHttpStatusCodeRemapping($attributes, $expected) { - $traces = $this->isolateTracer(function () use ($analyticsEventValue) { - $tracer = self::getTracer(); - $span = $tracer->spanBuilder('operation') - ->setSpanKind(SpanKind::KIND_SERVER) - ->startSpan(); - $span->setAttribute('analytics.event', $analyticsEventValue); + $traces = $this->isolateTracer(function () use ($attributes) { + $span = self::getTracer()->spanBuilder('test.span')->startSpan(); + foreach ($attributes as $key => $value) { + $span->setAttribute($key, $value); + } $span->end(); }); - $span = $traces[0][0]; - if ($expectedMetricValue !== null) { - $actualMetricValue = $span['attributes']['_dd1.sr.eausr']; - $this->assertEquals($expectedMetricValue, $actualMetricValue); - } else { - $this->assertArrayNotHasKey('_dd1.sr.eausr', $span['attributes']); - } + $actual = array_intersect_key( + $traces[0]['spans'][0]['attributes'], + ['http.status_code' => true, 'http.response.status_code' => true] + ); + $this->assertSame($expected, $actual); } public function testSpanErrorStatus() @@ -391,11 +372,11 @@ public function testSpanErrorStatus() $span->end(); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); $this->assertSame('error message', $span['attributes']['error.message']); - $this->assertEquals(1, $span['error']); + $this->assertTrue($span['error']); } public function testSpanStatusTransition() @@ -414,7 +395,7 @@ public function testSpanStatusTransition() $span->end(); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertArrayNotHasKey("error", $span); $this->assertArrayNotHasKey("error.message", $span['attributes']); $this->assertSame("internal", $span['name']); @@ -430,7 +411,7 @@ public function testRecordException() $span->end(); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); $this->assertNotEmpty($span['attributes'][Tag::ERROR_STACK]); @@ -445,7 +426,7 @@ public function testSpanNameUpdate() $span->end(); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame('new.name', $span['resource']); } @@ -466,11 +447,11 @@ public function testSpanUpdateAfterEnd() ]); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame('internal', $span['name']); $this->assertSame('test.span', $span['resource']); $this->assertSame('error message', $span['attributes']['error.message']); - $this->assertEquals(1, $span['error']); + $this->assertTrue($span['error']); $this->assertSame('bar', $span['attributes']['foo']); } @@ -507,18 +488,16 @@ public function testConcurrentSpans() } }); - $spans = $traces[0]; + $spans = (new SpanChecker())->flattenTraces($traces); $rootSpan = $spans[0]; $httpSpans = [$spans[3], $spans[2], $spans[1]]; $this->assertCount(4, $spans); - $traceId = $rootSpan['trace_id']; - $this->assertNotEmpty($traceId); - - $this->assertSame($traceId, $rootSpan['span_id']); + foreach ($traces as $trace) { + $this->assertSame(SpanChecker::traceIdLow($trace), $rootSpan['span_id']); + } for ($i = 1; $i <= 3; $i++) { $httpSpan = $httpSpans[$i - 1]; - $this->assertSame($traceId, $httpSpan['trace_id']); $this->assertSame($rootSpan['span_id'], $httpSpan['parent_id']); $this->assertSame("http-$i", $httpSpan['resource']); @@ -543,7 +522,7 @@ public function testGetSpanContextWithMultipleTraceStates() $this->assertRegularExpression('/^dd=p:[0-9a-f]{16};t.congo:t61rcWkgMzE;t.some_val:tehehe;t.dm:-0,ot=rv:[0-9a-f]{14};th:0$/', (string)$span->getContext()->getTraceState()); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame('t61rcWkgMzE', $span['attributes']['_dd.p.congo']); $this->assertSame('tehehe', $span['attributes']['_dd.p.some_val']); } @@ -553,12 +532,9 @@ public function testGetSpanContextWithMultipleTraceStates() */ public function testGetSpanContextWithRemoteParent(int $traceFlags, ?TraceState $traceState) { - // 128-bit trace id = low-64 trace_id (as decimal) + high-64 _dd.p.tid (as hex) * 2^64 - $low = "11803532876627986230"; - $high = "4bf92f3577b34da6"; $decSpanId = "67667974448284343"; - $traces = $this->isolateTracer(function () use ($traceFlags, $traceState, $low, $decSpanId) { + $traces = $this->isolateTracer(function () use ($traceFlags, $traceState, $decSpanId) { $remoteContext = SpanContext::createFromRemoteParent( '4bf92f3577b34da6a3ce929d0e0e4736', '00f067aa0ba902b7', @@ -587,10 +563,8 @@ public function testGetSpanContextWithRemoteParent(int $traceFlags, ?TraceState $this->assertSame("dd=p:" . $child->getContext()->getSpanID() . ";t.dm:-0" . ($traceState ? ",$traceState" : ""), (string)$childContext->getTraceState()); }); - $span = $traces[0][0]; - $this->assertSame($low, $span['trace_id']); - $this->assertSame($high, $span['trace_id_high']); - $this->assertSame($decSpanId, $span['parent_id']); + $this->assertSame('4bf92f3577b34da6a3ce929d0e0e4736', $traces[0]['trace_id']); + $this->assertSame($decSpanId, $traces[0]['spans'][0]['parent_id']); } public function providerRemoteParent() @@ -698,14 +672,11 @@ public function getDescription(): string } }); - $spans = $traces[0]; - list($parentSpan, $childSpan) = $spans; - $this->assertNotEmpty($parentSpan['trace_id']); - $this->assertSame($parentSpan['trace_id'], $parentSpan['span_id']); - $this->assertSame($parentSpan['trace_id'], $childSpan['trace_id']); - $this->assertSame($parentSpan['span_id'], $childSpan['trace_id']); + list($parentSpan, $childSpan) = (new SpanChecker())->flattenTraces($traces); + foreach ($traces as $trace) { + $this->assertSame(SpanChecker::traceIdLow($trace), $parentSpan['span_id']); + } $this->assertNotSame($parentSpan['span_id'], $childSpan['span_id']); - $this->assertNotSame($childSpan['trace_id'], $childSpan['span_id']); } public function testMultipleTraceStateRemote() @@ -831,11 +802,8 @@ public function getDescription(): string } }); - $spans = $traces[0]; - list($childSpan) = $spans; - $this->assertSame("11803532876627986230", $childSpan['trace_id']); - $this->assertSame("4bf92f3577b34da6", $childSpan['trace_id_high']); - $this->assertSame("67667974448284343", $childSpan['parent_id']); + $this->assertSame("4bf92f3577b34da6a3ce929d0e0e4736", $traces[0]['trace_id']); + $this->assertSame("67667974448284343", $traces[0]['spans'][0]['parent_id']); } public function testAddItemToTracestate() @@ -871,13 +839,13 @@ public function testAddItemToTracestate() $span->end(); }); - $span = $traces[0]; - list($childSpan, $span) = $span; + list($childSpan, $span) = (new SpanChecker())->flattenTraces($traces); $this->assertSame('t61rcWkgMzE', $span['attributes']['_dd.p.congo']); $this->assertSame('t61rcWkgMzE', $childSpan['attributes']['_dd.p.congo']); - $this->assertSame(0, $span['sampling_mechanism']); // _dd.p.dm '-0' promotes to sampling_mechanism=0 - $this->assertSame(0, $childSpan['sampling_mechanism']); + foreach ($traces as $trace) { + $this->assertSame(0, $trace['sampling_mechanism']); // _dd.p.dm '-0' is sampling_mechanism 0 + } $this->assertFlameGraph($traces, [ SpanAssertion::exists('internal', 'test.span') @@ -910,7 +878,7 @@ public function testUpdateOperationNameOnTheFly() $span->end(); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame('kafka.receive', $span['name']); $this->assertSame('operation', $span['resource']); } diff --git a/tests/OpenTelemetry/Integration/Context/Fiber/FiberTest.php b/tests/OpenTelemetry/Integration/Context/Fiber/FiberTest.php index 2eb9c8166e1..3d6f0ca446e 100644 --- a/tests/OpenTelemetry/Integration/Context/Fiber/FiberTest.php +++ b/tests/OpenTelemetry/Integration/Context/Fiber/FiberTest.php @@ -163,7 +163,7 @@ public function testFiberInteroperabilityStackSwitch() SpanAssertion::exists('dd.otherFiber')->withChildren([ SpanAssertion::exists('fiber.suspend') ]) - ])->withExistingTagsNames([ + ])->withExistingAttributeNames([ Tag::ERROR_TYPE, Tag::ERROR_STACK, Tag::ERROR_MSG ]), SpanAssertion::exists('fiber.suspend') @@ -171,7 +171,7 @@ public function testFiberInteroperabilityStackSwitch() ]) ]), SpanAssertion::exists('fiber.resume'), - SpanAssertion::exists('fiber.resume')->withExistingTagsNames([ + SpanAssertion::exists('fiber.resume')->withExistingAttributeNames([ Tag::ERROR_TYPE, Tag::ERROR_STACK, Tag::ERROR_MSG ]) ]) diff --git a/tests/OpenTelemetry/Integration/InteroperabilityTest.php b/tests/OpenTelemetry/Integration/InteroperabilityTest.php index 58a16797a01..2998a18890c 100644 --- a/tests/OpenTelemetry/Integration/InteroperabilityTest.php +++ b/tests/OpenTelemetry/Integration/InteroperabilityTest.php @@ -118,7 +118,7 @@ public function testActivateAnAlreadyActiveDatadogSpan() $this->assertSame(SpanContextValidator::INVALID_TRACE, $currentSpan->getContext()->getTraceId()); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame('dd.span', $span['name']); $this->assertArrayNotHasKey('parent_id', $span['attributes']); } @@ -165,7 +165,7 @@ public function testMixingOpenTelemetrylAndDatadogBasic() $span->end(); }); - $spans = $traces[0]; + $spans = $traces[0]['spans']; $this->assertCount(2, $spans); list($parent, $child) = $spans; @@ -174,7 +174,6 @@ public function testMixingOpenTelemetrylAndDatadogBasic() $this->assertSame('other.span', $child['name']); $this->assertSame('other.span', $child['resource']); $this->assertSame($parent['span_id'], $child['parent_id']); - $this->assertSame($parent['trace_id'], $child['trace_id']); $this->assertSame('bar', $child['attributes']['foo']); $this->assertArrayNotHasKey('foo', $parent['attributes']); } @@ -209,8 +208,6 @@ public function testActivateSpanWithAnotherActiveNonActivatedDatadogSpan() $ddOTelSpan->end(); }); - $spans = $traces[0]; - $this->assertFlameGraph($traces, [ SpanAssertion::exists('dd.span', 'dd.span') ->withChildren([ @@ -238,14 +235,13 @@ public function testCloseSpansUntilWithOnlyDatadogSpans() $this->assertSame($span1, $currentSpan->getDDSpan()); }); - $spans = $traces[0]; + $spans = $traces[0]['spans']; $this->assertCount(2, $spans); list($span2, $span3) = $spans; $this->assertSame('dd.span2', $span2['name']); $this->assertSame('dd.span3', $span3['name']); $this->assertSame($span2['span_id'], $span3['parent_id']); - $this->assertSame($span2['trace_id'], $span3['trace_id']); } public function testActivateOtelAfterDatadogSpan() @@ -269,8 +265,7 @@ public function testActivateOtelAfterDatadogSpan() Span::getCurrent()->end(); }); - $spans = $traces[0]; - $this->assertCount(2, $spans); + $this->assertCount(2, $traces[0]['spans']); $this->assertFlameGraph($traces, [ SpanAssertion::exists('internal', 'otel.span') @@ -593,13 +588,13 @@ public function testMixingMultipleTraces() $this->assertFlameGraph($traces, [ SpanAssertion::exists('internal', 'otel.trace1', null, (PHP_VERSION_ID < 80100) ? 'datadog/dd-trace-tests' : 'unknown_service:php') - ->withExistingTagsNames(['foo1']) + ->withExistingAttributeNames(['foo1']) ->withChildren( SpanAssertion::exists('internal', 'otel.child1', null, 'my.service') - ->withExistingTagsNames(['foo2']) + ->withExistingAttributeNames(['foo2']) ->withChildren( SpanAssertion::exists('internal', 'my.resource', null, (PHP_VERSION_ID < 80100) ? 'datadog/dd-trace-tests' : 'unknown_service:php') - ->withExistingTagsNames(['foo3']) + ->withExistingAttributeNames(['foo3']) ) ), SpanAssertion::exists('internal', 'otel.trace2', null, (PHP_VERSION_ID < 80100) ? 'datadog/dd-trace-tests' : 'unknown_service:php') @@ -607,7 +602,7 @@ public function testMixingMultipleTraces() SpanAssertion::exists('dd.child2', 'dd.child2', null, (PHP_VERSION_ID < 80100) ? 'datadog/dd-trace-tests' : 'unknown_service:php') ), SpanAssertion::exists('dd.trace1', 'dd.trace1', null, (PHP_VERSION_ID < 80100) ? 'datadog/dd-trace-tests' : 'unknown_service:php') - ->withExistingTagsNames(['foo1']) + ->withExistingAttributeNames(['foo1']) ->withChildren( SpanAssertion::exists('dd.child1', 'dd.child1', null, (PHP_VERSION_ID < 80100) ? 'datadog/dd-trace-tests' : 'unknown_service:php') ), @@ -729,11 +724,8 @@ public function testW3CInteroperability() $this->assertSame("dd=p:$DDChildSpanId;t.dm:-0", $carrier[TraceContextPropagator::TRACESTATE]); // ff00000000000517 is the high 64-bit part of the 128-bit trace id }); - $this->assertSame('10511401530282737729', $traces[0][0]['trace_id']); - $this->assertSame('18374692078461386817', $traces[0][0]['parent_id']); - - $otelRootSpan = $traces[0][0]; - $this->assertSame('ff00000000000517', $otelRootSpan['trace_id_high']); + $this->assertSame('ff0000000000051791e0000000000041', $traces[0]['trace_id']); + $this->assertSame('18374692078461386817', $traces[0]['spans'][0]['parent_id']); $this->assertFlameGraph($traces, [ SpanAssertion::exists('internal', 'otel.root.span', false, 'phpunit') @@ -781,11 +773,8 @@ public function testB3SingleInteroperability() $this->assertSame("ff0000000000051791e0000000000041-$DDChildSpanId-1", $carrier['b3']); }); - $this->assertSame('10511401530282737729', $traces[0][0]['trace_id']); - $this->assertSame('18374692078461386817', $traces[0][0]['parent_id']); - - $otelRootSpan = $traces[0][0]; - $this->assertSame('ff00000000000517', $otelRootSpan['trace_id_high']); + $this->assertSame('ff0000000000051791e0000000000041', $traces[0]['trace_id']); + $this->assertSame('18374692078461386817', $traces[0]['spans'][0]['parent_id']); $this->assertFlameGraph($traces, [ SpanAssertion::exists('internal', 'otel.root.span', false, 'phpunit') @@ -837,11 +826,8 @@ public function testB3MultiInteroperability() $this->assertSame('1', $carrier['X-B3-Sampled']); }); - $this->assertSame('10511401530282737729', $traces[0][0]['trace_id']); - $this->assertSame('18374692078461386817', $traces[0][0]['parent_id']); - - $otelRootSpan = $traces[0][0]; - $this->assertSame('ff00000000000517', $otelRootSpan['trace_id_high']); + $this->assertSame('ff0000000000051791e0000000000041', $traces[0]['trace_id']); + $this->assertSame('18374692078461386817', $traces[0]['spans'][0]['parent_id']); $this->assertFlameGraph($traces, [ SpanAssertion::exists('internal', 'otel.root.span', false, 'phpunit') @@ -881,7 +867,7 @@ public function testBaggageInteroperability() $parentSpan->end(); }); - list($parent, $child) = $traces[0]; + list($parent, $child) = $traces[0]['spans']; $this->assertSame(2, $parent['span_kind']); // span_kind enum: Server=2 $this->assertSame('GET', $parent['attributes']['http.method']); $this->assertSame('/parent', $parent['attributes']['http.uri']); @@ -908,19 +894,17 @@ public function testSpecialAttributes() 'operation.name' => 'Overriden.name', 'service.name' => 'new.service.name', 'span.type' => 'new.span.type', - 'analytics.event' => 'true', ]); $span->end(); }); - $this->assertCount(1, $traces[0]); - $span = $traces[0][0]; + $this->assertCount(1, $traces[0]['spans']); + $span = $traces[0]['spans'][0]; $this->assertSame('overriden.name', $span['name']); $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['attributes']['_dd1.sr.eausr']); } public function testHasEnded() @@ -974,9 +958,9 @@ public function testAttributesInteroperability() $this->assertEquals(2, $attributes['m2']); }); - $this->assertCount(1, $traces[0]); + $this->assertCount(1, $traces[0]['spans']); - $meta = $traces[0][0]['attributes']; + $meta = $traces[0]['spans'][0]['attributes']; $this->assertArrayNotHasKey('arg1', $meta); $this->assertSame('value2', $meta['arg2']); $this->assertSame('value3', $meta['arg3']); @@ -986,8 +970,8 @@ public function testAttributesInteroperability() $this->assertSame('value', $meta['key']); $this->assertArrayNotHasKey('post', $meta); - $this->assertEquals(1, $traces[0][0]['attributes']['m1']); - $this->assertEquals(2, $traces[0][0]['attributes']['m2']); + $this->assertEquals(1, $traces[0]['spans'][0]['attributes']['m1']); + $this->assertEquals(2, $traces[0]['spans'][0]['attributes']['m2']); } public function testSpanLinksInteroperabilityFromDatadogSpan() @@ -1023,15 +1007,13 @@ public function testSpanLinksInteroperabilityFromDatadogSpan() close_span(); }); - $this->assertCount(1, $traces[0]); + $this->assertCount(1, $traces[0]['spans']); $this->assertSame([[ - 'trace_id' => '10511401530282737729', - 'trace_id_high' => 'ff00000000000517', - 'span_id' => '18374686479671624983', - 'trace_state' => 'dd=t.dm:-0', - 'flags' => 0, + 'trace_id' => 'ff0000000000051791e0000000000041', + 'span_id' => 'ff00000000000517', + 'tracestate' => 'dd=t.dm:-0', 'attributes' => ['arg1' => 'value1', 'arg2' => 'value2'], - ]], $traces[0][0]['span_links']); + ]], $traces[0]['spans'][0]['span_links']); } public function testBasicSpanLinksFromDatadog() @@ -1056,13 +1038,11 @@ public function testBasicSpanLinksFromDatadog() close_span(); }); - $this->assertCount(1, $traces[0]); + $this->assertCount(1, $traces[0]['spans']); $this->assertSame([[ - 'trace_id' => '10511401530282737729', - 'trace_id_high' => 'ff00000000000517', - 'span_id' => '18374686479671624983', - 'flags' => 0, - ]], $traces[0][0]['span_links']); + 'trace_id' => 'ff0000000000051791e0000000000041', + 'span_id' => 'ff00000000000517', + ]], $traces[0]['spans'][0]['span_links']); } public function testSpanLinksInteroperabilityFromOpenTelemetrySpan() @@ -1090,16 +1070,14 @@ public function testSpanLinksInteroperabilityFromOpenTelemetrySpan() $otelSpan->end(); }); - $this->assertCount(1, $traces[0]); + $this->assertCount(1, $traces[0]['spans']); // dropped_attributes_count is not surfaced in the V1 structured span_links (no PHP-side source). $this->assertSame([[ - 'trace_id' => '1311768467139281697', - 'trace_id_high' => '1234567887654321', - 'span_id' => '9756277977086449272', - 'trace_state' => 'dd=t.dm:-0', - 'flags' => 0, + 'trace_id' => '12345678876543211234567887654321', + 'span_id' => '8765432112345678', + 'tracestate' => 'dd=t.dm:-0', 'attributes' => ['arg1' => 'value1'], - ]], $traces[0][0]['span_links']); + ]], $traces[0]['spans'][0]['span_links']); } public function testSpanLinksInteroperabilityBothTypes() @@ -1153,23 +1131,19 @@ public function testSpanLinksInteroperabilityBothTypes() $otelSpan->end(); }); - $this->assertCount(1, $traces[0]); + $this->assertCount(1, $traces[0]['spans']); $this->assertSame([ [ - 'trace_id' => '1311768467139281697', - 'trace_id_high' => '1234567887654321', - 'span_id' => '9756277977086449272', - 'trace_state' => 'dd=t.dm:-0', - 'flags' => 0, + 'trace_id' => '12345678876543211234567887654321', + 'span_id' => '8765432112345678', + 'tracestate' => 'dd=t.dm:-0', 'attributes' => ['arg1' => 'value1'], ], [ - 'trace_id' => '10511401530282737729', - 'trace_id_high' => 'ff00000000000517', - 'span_id' => '18374686479671624983', - 'flags' => 0, + 'trace_id' => 'ff0000000000051791e0000000000041', + 'span_id' => 'ff00000000000517', ], - ], $traces[0][0]['span_links']); + ], $traces[0]['spans'][0]['span_links']); } public function testSpanLinksInteroperabilityRemoval() @@ -1213,7 +1187,7 @@ public function testSpanLinksInteroperabilityRemoval() $otelSpan->end(); }); - $this->assertCount(1, $traces[0]); + $this->assertCount(1, $traces[0]['spans']); } public function testSpanLinksInteroperabilityRemovalDuplicates() @@ -1328,7 +1302,7 @@ public function testSpanEventsInteroperabilityFromDatadogSpan() close_span(); }); - $this->assertCount(1, $traces[0]); + $this->assertCount(1, $traces[0]['spans']); $this->assertSame([[ 'name' => 'event-name', 'time_unix_nano' => 1720037568765201300, @@ -1337,7 +1311,7 @@ public function testSpanEventsInteroperabilityFromDatadogSpan() 'int_array' => [3, 4], 'string_array' => ['5', '6'], ], - ]], $traces[0][0]['span_events']); + ]], $traces[0]['spans'][0]['span_events']); } public function testSpanEventsInteroperabilityFromOpenTelemetrySpan() @@ -1368,7 +1342,7 @@ public function testSpanEventsInteroperabilityFromOpenTelemetrySpan() $otelSpan->end(); }); - $this->assertCount(1, $traces[0]); + $this->assertCount(1, $traces[0]['spans']); $this->assertSame([[ 'name' => 'event-name', 'time_unix_nano' => 1720037568765201300, @@ -1377,7 +1351,7 @@ public function testSpanEventsInteroperabilityFromOpenTelemetrySpan() 'int_array' => [3, 4], 'string_array' => ['5', '6'], ], - ]], $traces[0][0]['span_events']); + ]], $traces[0]['spans'][0]['span_events']); } public function testOtelRecordExceptionAttributesSerialization() @@ -1398,7 +1372,7 @@ public function testOtelRecordExceptionAttributesSerialization() $otelSpan->end(); }); - $events = $traces[0][0]['span_events']; + $events = $traces[0]['spans'][0]['span_events']; $this->assertCount(3, $events); $event1 = $events[0]; @@ -1412,11 +1386,11 @@ public function testOtelRecordExceptionAttributesSerialization() $event3 = $events[2]; $this->assertSame('message override', $event3['attributes']['exception.message']); - $this->assertSame(\DDTrace\get_sanitized_exception_trace($lastException), $traces[0][0]['attributes']['error.stack']); + $this->assertSame(\DDTrace\get_sanitized_exception_trace($lastException), $traces[0]['spans'][0]['attributes']['error.stack']); - $this->assertArrayNotHasKey('error.message', $traces[0][0]['attributes']); - $this->assertArrayNotHasKey('error.type', $traces[0][0]['attributes']); - $this->assertArrayNotHasKey('error', $traces[0][0]); + $this->assertArrayNotHasKey('error.message', $traces[0]['spans'][0]['attributes']); + $this->assertArrayNotHasKey('error.type', $traces[0]['spans'][0]['attributes']); + $this->assertArrayNotHasKey('error', $traces[0]['spans'][0]); } public function testExceptionSpanEvents() @@ -1449,7 +1423,7 @@ public function testExceptionSpanEvents() close_span(); }); - $event = $traces[0][0]['span_events'][0]; + $event = $traces[0]['spans'][0]['span_events'][0]; $this->assertSame('Test exception message', $event['attributes']['exception.message']); $this->assertSame('Exception', $event['attributes']['exception.type']); diff --git a/tests/OpenTelemetry/Integration/SDK/SpanBuilderTest.php b/tests/OpenTelemetry/Integration/SDK/SpanBuilderTest.php index 5d8a7406b71..cbcfbe647b1 100644 --- a/tests/OpenTelemetry/Integration/SDK/SpanBuilderTest.php +++ b/tests/OpenTelemetry/Integration/SDK/SpanBuilderTest.php @@ -276,6 +276,45 @@ public function test_set_attribute(): void $this->assertNull($attributes->get('nil')); } + public static function propertyAttributes(): array + { + return [ + 'resource.name' => ['resource.name', 'my-resource'], + 'operation.name' => ['operation.name', 'my.operation'], + 'span.type' => ['span.type', 'web'], + 'component' => ['component', 'my-component'], + 'span.kind' => ['span.kind', 'producer'], + ]; + } + + /** + * @dataProvider propertyAttributes + */ + public function test_property_attribute_is_readable(string $key, string $value): void + { + /** @var Span $span */ + $span = $this->tracer->spanBuilder(self::SPAN_NAME)->startSpan(); + $span->setAttribute($key, $value); + + $this->assertSame($value, $span->getAttribute($key)); + $this->assertSame($value, $span->toSpanData()->getAttributes()->get($key)); + + $span->end(); + } + + public function test_property_attributes_are_not_exposed_unless_set(): void + { + /** @var Span $span */ + $span = $this->tracer->spanBuilder(self::SPAN_NAME)->startSpan(); + $span->end(); + + $attributes = $span->toSpanData()->getAttributes(); + $this->assertFalse($attributes->has('operation.name')); + $this->assertFalse($attributes->has('resource.name')); + $this->assertFalse($attributes->has('span.type')); + $this->assertNull($span->getAttribute('operation.name')); + } + /** * @group trace-compliance */ diff --git a/tests/OpenTelemetry/Integration/SDK/SpanProcessorTest.php b/tests/OpenTelemetry/Integration/SDK/SpanProcessorTest.php index a4ffb9becc1..b92117b3157 100644 --- a/tests/OpenTelemetry/Integration/SDK/SpanProcessorTest.php +++ b/tests/OpenTelemetry/Integration/SDK/SpanProcessorTest.php @@ -103,7 +103,7 @@ public function forceFlush(?CancellationInterface $cancellation = null): bool $span->end(); }); - $span = $traces[0][0]; + $span = $traces[0]['spans'][0]; $this->assertSame('overwritten', $span['resource']); } diff --git a/tests/OpenTelemetry/Integration/SpanProvenanceTest.php b/tests/OpenTelemetry/Integration/SpanProvenanceTest.php index 7ed3e6ff13c..abde01cc53c 100644 --- a/tests/OpenTelemetry/Integration/SpanProvenanceTest.php +++ b/tests/OpenTelemetry/Integration/SpanProvenanceTest.php @@ -26,8 +26,8 @@ function testOtelSpanMarked() $scope->detach(); }); - $this->assertEquals($traces[0][0]["resource"], "file_get_contents"); - $this->assertEquals($traces[0][0]["name"], "internal"); - $this->assertEquals($traces[0][0]["component"], "otel.io"); + $this->assertEquals($traces[0]['spans'][0]["resource"], "file_get_contents"); + $this->assertEquals($traces[0]['spans'][0]["name"], "internal"); + $this->assertEquals($traces[0]['spans'][0]["component"], "otel.io"); } } diff --git a/tests/Unit/ConfigurationTest.php b/tests/Unit/ConfigurationTest.php index 884d209b3a3..a7083878193 100644 --- a/tests/Unit/ConfigurationTest.php +++ b/tests/Unit/ConfigurationTest.php @@ -34,7 +34,6 @@ private function cleanUpEnvs() self::putenv('DD_SERVICE_MAPPING'); self::putenv('DD_SERVICE'); self::putenv('DD_TAGS'); - self::putenv('DD_TRACE_ANALYTICS_ENABLED'); self::putenv('DD_TRACE_DEBUG'); self::putenv('DD_TRACE_ENABLED'); self::putenv('DD_TRACE_PDO_ENABLED'); @@ -48,13 +47,13 @@ private function cleanUpEnvs() public function testTracerEnabledByDefault() { - $this->assertTrue(\ddtrace_config_trace_enabled()); + $this->assertTrue(\dd_trace_env_config('DD_TRACE_ENABLED')); } public function testTracerDisabled() { $this->putEnvAndReloadConfig(['DD_TRACE_ENABLED=false']); - $this->assertFalse(\ddtrace_config_trace_enabled()); + $this->assertFalse(\dd_trace_env_config('DD_TRACE_ENABLED')); } public function testDebugModeDisabledByDefault() @@ -70,13 +69,13 @@ public function testDebugModeCanBeEnabled() public function testDistributedTracingEnabledByDefault() { - $this->assertTrue(\ddtrace_config_distributed_tracing_enabled()); + $this->assertTrue(\dd_trace_env_config('DD_DISTRIBUTED_TRACING')); } public function testDistributedTracingDisabled() { $this->putEnvAndReloadConfig(['DD_DISTRIBUTED_TRACING=false']); - $this->assertFalse(\ddtrace_config_distributed_tracing_enabled()); + $this->assertFalse(\dd_trace_env_config('DD_DISTRIBUTED_TRACING')); } public function testAllIntegrationsEnabledByDefault() @@ -128,10 +127,10 @@ private static function getIntegrationsUpper() public function testServiceName() { ini_set("datadog.service", ""); - $this->assertSame('__default__', \ddtrace_config_app_name('__default__')); + $this->assertSame('__default__', (\dd_trace_env_config('DD_SERVICE') ?: '__default__')); $this->putEnvAndReloadConfig(['DD_SERVICE=my_app']); - $this->assertSame('my_app', \ddtrace_config_app_name('__default__')); + $this->assertSame('my_app', (\dd_trace_env_config('DD_SERVICE') ?: '__default__')); } /** diff --git a/tests/Unit/Integrations/HttpClientIntegrationHelperTest.php b/tests/Unit/Integrations/HttpClientIntegrationHelperTest.php index b1edd12b2a4..be86d847573 100644 --- a/tests/Unit/Integrations/HttpClientIntegrationHelperTest.php +++ b/tests/Unit/Integrations/HttpClientIntegrationHelperTest.php @@ -18,7 +18,7 @@ protected function envsToCleanUpAtTearDown() private static function newSpan() { $span = new \stdClass(); - $span->meta = []; + $span->attributes = []; return $span; } @@ -64,16 +64,16 @@ public function testSetClientError() $span = self::newSpan(); $this->assertTrue(HttpClientIntegrationHelper::setClientError($span, 403)); - $this->assertSame('http_error', $span->meta[Tag::ERROR_TYPE]); - $this->assertSame('HTTP 403 Error', $span->meta[Tag::ERROR_MSG]); + $this->assertSame('http_error', $span->attributes[Tag::ERROR_TYPE]); + $this->assertSame('HTTP 403 Error', $span->attributes[Tag::ERROR_MSG]); $span = self::newSpan(); $this->assertTrue(HttpClientIntegrationHelper::setClientError($span, 412, 'Precondition Failed')); - $this->assertSame('HTTP 412: Precondition Failed', $span->meta[Tag::ERROR_MSG]); + $this->assertSame('HTTP 412: Precondition Failed', $span->attributes[Tag::ERROR_MSG]); $span = self::newSpan(); $this->assertFalse(HttpClientIntegrationHelper::setClientError($span, 200)); - $this->assertSame([], $span->meta); + $this->assertSame([], $span->attributes); } public function testSetClientErrorKeepsExistingError() @@ -81,9 +81,9 @@ public function testSetClientErrorKeepsExistingError() self::putEnvAndReloadConfig(['DD_TRACE_HTTP_CLIENT_ERROR_STATUSES=403']); $span = self::newSpan(); - $span->meta[Tag::ERROR] = 1; + $span->attributes[Tag::ERROR] = 1; $this->assertFalse(HttpClientIntegrationHelper::setClientError($span, 403)); - $this->assertArrayNotHasKey(Tag::ERROR_TYPE, $span->meta); + $this->assertArrayNotHasKey(Tag::ERROR_TYPE, $span->attributes); } public function testSetClientErrorKeepsTransportError() @@ -95,13 +95,13 @@ public function testSetClientErrorKeepsTransportError() Tag::ERROR_MSG => 'Operation timed out after 100 milliseconds with 1 out of 100 bytes received', ]; // Either field can flag an existing error; preserve both when present. - foreach ([$error, [Tag::ERROR_TYPE => $error[Tag::ERROR_TYPE]], [Tag::ERROR_MSG => $error[Tag::ERROR_MSG]]] as $meta) { + foreach ([$error, [Tag::ERROR_TYPE => $error[Tag::ERROR_TYPE]], [Tag::ERROR_MSG => $error[Tag::ERROR_MSG]]] as $attributes) { $span = self::newSpan(); - $span->meta = $meta + [Tag::HTTP_STATUS_CODE => '404']; - $expected = $span->meta; + $span->attributes = $attributes + [Tag::HTTP_STATUS_CODE => '404']; + $expected = $span->attributes; $this->assertFalse(HttpClientIntegrationHelper::setClientError($span, 404)); - $this->assertSame($expected, $span->meta); + $this->assertSame($expected, $span->attributes); } } @@ -111,6 +111,6 @@ public function testSetClientErrorWithEmptyConfiguration() $span = self::newSpan(); $this->assertFalse(HttpClientIntegrationHelper::setClientError($span, 404)); - $this->assertSame([], $span->meta); + $this->assertSame([], $span->attributes); } } diff --git a/tests/Unit/SpanTest.php b/tests/Unit/SpanTest.php index d874b5c0491..64c5145e765 100644 --- a/tests/Unit/SpanTest.php +++ b/tests/Unit/SpanTest.php @@ -265,6 +265,30 @@ public function testHasTag() $this->assertFalse($span->hasTag('other')); } + public function testNullTagRemovesIt() + { + $span = $this->createSpan(); + $span->setTag(self::TAG_KEY, self::TAG_VALUE); + $span->setTag(Tag::HTTP_URL, 'https://example.com/'); + $span->setTag(self::TAG_KEY, null); + $span->setTag(Tag::HTTP_URL, null); + $span->setTag('never_set', null); + + $this->assertFalse($span->hasTag(self::TAG_KEY)); + $this->assertFalse($span->hasTag(Tag::HTTP_URL)); + $this->assertFalse($span->hasTag('never_set')); + } + + public function testBoolTagIsSentAsString() + { + $span = $this->createSpan(); + $span->setTag('yes', true); + $span->setTag('no', false); + + $this->assertSame('true', $span->getTag('yes')); + $this->assertSame('false', $span->getTag('no')); + } + public function testMetricsSetGet() { $span = $this->createSpan(); @@ -273,6 +297,15 @@ public function testMetricsSetGet() $this->assertSame(1.0, $span->getMetrics()['exists']); } + public function testNullMetricRemovesIt() + { + $span = $this->createSpan(); + $span->setMetric('exists', 1.0); + $span->setMetric('exists', null); + + $this->assertArrayNotHasKey('exists', $span->getMetrics()); + } + public function testTraceAnalyticsByTagIsDeprecatedNoOp() { $span = $this->createSpan(); diff --git a/tests/Unit/TracerTest.php b/tests/Unit/TracerTest.php index 2fa1d32d9f7..83ecaa1ffd0 100644 --- a/tests/Unit/TracerTest.php +++ b/tests/Unit/TracerTest.php @@ -182,13 +182,13 @@ public function testTracingContextInheritedFromDistributedTracingContext() $span = $tracer->startRootSpan(self::OPERATION_NAME, [ 'child_of' => $distributedTracingContext, ])->getSpan(); - $context = \DDTrace\current_context(); + $rootSpan = \DDTrace\root_span(); $this->assertSame("1234", $span->getTraceId()); $this->assertSame("4321", $span->getParentId()); $this->assertSame("datadog", $span->getContext()->origin); - $this->assertSame("1234", $context["trace_id"]); - $this->assertSame("4321", $context["distributed_tracing_parent_id"]); - $this->assertSame("datadog", $context["distributed_tracing_origin"]); + $this->assertSame(str_pad(dechex(1234), 32, "0", STR_PAD_LEFT), $rootSpan->traceId); + $this->assertSame("4321", $rootSpan->parentId); + $this->assertSame("datadog", $rootSpan->origin); self::putenv('DD_TRACE_GENERATE_ROOT_SPAN'); } @@ -204,14 +204,16 @@ public function testSpanStartedAtRootCanBeAccessedLater() self::putenv('DD_TRACE_GENERATE_ROOT_SPAN'); } - public function testFlushAddsHostnameToRootSpanWhenEnabled() + public function testFlushAddsHostnameToThePayloadWhenEnabled() { self::putenv('DD_TRACE_REPORT_HOSTNAME=true'); \dd_trace_serialize_closed_spans(); $tracer = new Tracer(new NoopTransport()); - $scope = $tracer->startRootSpan(self::OPERATION_NAME); - $this->assertEquals(gethostname(), $tracer->getRootScope()->getSpan()->getTag(Tag::HOSTNAME)); + $tracer->startRootSpan(self::OPERATION_NAME)->close(); + $payload = \dd_trace_serialize_closed_spans(); + $this->assertEquals(gethostname(), $payload['hostname']); + $this->assertArrayNotHasKey(Tag::HOSTNAME, $payload['chunks'][0]['spans'][0]['attributes']); } public function testIfNoRootScopeExistsItWillBeNull() diff --git a/tests/WebServer.php b/tests/WebServer.php index 0919d608a26..6bac5e863cd 100644 --- a/tests/WebServer.php +++ b/tests/WebServer.php @@ -120,12 +120,6 @@ public function __construct($indexFile, $host = '0.0.0.0', $port = 80, $ddprofSe $this->ddprofServiceName = $ddprofServiceName; } - // SAPI name of the default web server, which the tracer reports as the root span's default component. - public static function defaultSapiName() - { - return \getenv('DD_TRACE_TEST_SAPI') ?: 'cli-server'; - } - public function setRoadrunner($version) { $this->roadrunnerVersion = $version; diff --git a/tests/ext/active_span.phpt b/tests/ext/active_span.phpt index dea587bfc5c..992234de086 100644 --- a/tests/ext/active_span.phpt +++ b/tests/ext/active_span.phpt @@ -28,7 +28,7 @@ var_dump(DDTrace\active_span() == DDTrace\active_span()); Hello, Datadog. greet tracer. bool(true) -object(DDTrace\RootSpanData)#%d (30) { +object(DDTrace\RootSpanData)#%d (28) { ["name"]=> string(15) "active_span.php" ["resource"]=> @@ -41,14 +41,20 @@ object(DDTrace\RootSpanData)#%d (30) { ["type"]=> string(3) "cli" ["meta"]=> - array(1) { + array(4) { ["runtime-id"]=> string(36) "%s" + ["service.name"]=> + string(15) "active_span.php" + ["operation.name"]=> + string(15) "active_span.php" + ["span.type"]=> + string(3) "cli" } ["metrics"]=> array(1) { ["process_id"]=> - float(%f) + int(%d) } ["exception"]=> NULL @@ -66,9 +72,9 @@ object(DDTrace\RootSpanData)#%d (30) { ["parent"]=> NULL ["stack"]=> - object(DDTrace\SpanStack)#%d (4) { + object(DDTrace\SpanStack)#%d (3) { ["parent"]=> - object(DDTrace\SpanStack)#%d (4) { + object(DDTrace\SpanStack)#%d (3) { ["parent"]=> NULL ["active"]=> @@ -76,18 +82,12 @@ object(DDTrace\RootSpanData)#%d (30) { ["spanCreationObservers"]=> array(0) { } - ["attributes"]=> - array(0) { - } } ["active"]=> *RECURSION* ["spanCreationObservers"]=> array(0) { } - ["attributes"]=> - array(0) { - } } ["onClose"]=> array(0) { @@ -108,7 +108,7 @@ object(DDTrace\RootSpanData)#%d (30) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) } ["ignoreError"]=> bool(false)%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r @@ -116,9 +116,7 @@ object(DDTrace\RootSpanData)#%d (30) { array(0) { } ["samplingPriority"]=> - int(1073741824) - ["samplingMechanism"]=> - int(0)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r + int(1073741824)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r ["tracestateTags"]=> array(0) { }%r(\s*\["parentId"\]=>\s+uninitialized\(string\))?%r @@ -128,7 +126,5 @@ object(DDTrace\RootSpanData)#%d (30) { NULL ["inferredSpan"]=> NULL - ["hostname"]=> - string(0) "" } bool(true) 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 d62abff2683..58996d70d45 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,11 +30,7 @@ var_dump(dd_clean_spans()); HOOK METHOD arg array(2) { [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -60,9 +56,7 @@ array(2) { } } [1]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> diff --git a/tests/ext/analytics_event.phpt b/tests/ext/analytics_event.phpt deleted file mode 100644 index 07ddd7720ee..00000000000 --- a/tests/ext/analytics_event.phpt +++ /dev/null @@ -1,43 +0,0 @@ ---TEST-- -analytics.event maps to the _dd1.sr.eausr metric, set via $meta or $attributes ---ENV-- -DD_TRACE_GENERATE_ROOT_SPAN=0 -DD_TRACE_AUTO_FLUSH_ENABLED=0 -DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 ---FILE-- - function ($s) { $s->meta['analytics.event'] = 'true'; }, - 'meta string F' => function ($s) { $s->meta['analytics.event'] = 'F'; }, - 'meta bool true' => function ($s) { $s->meta['analytics.event'] = true; }, - 'attributes bool false' => function ($s) { $s->attributes['analytics.event'] = false; }, - 'attributes float' => function ($s) { $s->attributes['analytics.event'] = 0.5; }, - 'attributes string 1' => function ($s) { $s->attributes['analytics.event'] = '1'; }, - 'invalid string' => function ($s) { $s->meta['analytics.event'] = 'yes'; }, - 'invalid string keeps metric' => function ($s) { $s->meta['analytics.event'] = 'yes'; $s->metrics['_dd1.sr.eausr'] = 0.25; }, - 'valid value wins over metric' => function ($s) { $s->meta['analytics.event'] = 'true'; $s->metrics['_dd1.sr.eausr'] = 0; }, - 'metric only' => function ($s) { $s->metrics['_dd1.sr.eausr'] = 0.75; }, -]; -foreach ($cases as $name => $set) { - $s = \DDTrace\start_span(); - $s->name = $name; - $set($s); - \DDTrace\close_span(); -} -foreach (dd_trace_serialize_closed_spans() as $span) { - $attrs = $span['attributes']; - echo $span['name'], ': eausr=', var_export(isset($attrs['_dd1.sr.eausr']) ? $attrs['_dd1.sr.eausr'] : null, true), - ' analytics.event=', isset($attrs['analytics.event']) ? 'kept' : 'removed', "\n"; -} -?> ---EXPECT-- -metric only: eausr=0.75 analytics.event=removed -valid value wins over metric: eausr=1.0 analytics.event=removed -invalid string keeps metric: eausr=0.25 analytics.event=removed -invalid string: eausr=NULL analytics.event=removed -attributes string 1: eausr=1.0 analytics.event=removed -attributes float: eausr=0.5 analytics.event=removed -attributes bool false: eausr=0.0 analytics.event=removed -meta bool true: eausr=1.0 analytics.event=removed -meta string F: eausr=0.0 analytics.event=removed -meta string true: eausr=1.0 analytics.event=removed diff --git a/tests/ext/background-sender/agent_sampling-standalone-asm_01.phpt b/tests/ext/background-sender/agent_sampling-standalone-asm_01.phpt index 955a76782c5..9aab3c5bf3a 100644 --- a/tests/ext/background-sender/agent_sampling-standalone-asm_01.phpt +++ b/tests/ext/background-sender/agent_sampling-standalone-asm_01.phpt @@ -46,12 +46,11 @@ for ($i = 0; $i < $maxIterations; $i++) if (!is_array($root)) { continue; } - $spans = $root["chunks"][0]["spans"] ?? ($root[0] ?? null); - $spanRecords[] = $spans; - if (!is_array($spans) || !isset($spans[0]["metrics"]["_sampling_priority_v1"])) { + $sampling = RequestReplayer::chunkPriority($root); + $spanRecords[] = $root; + if ($sampling === null) { continue; } - $sampling = $spans[0]["metrics"]["_sampling_priority_v1"]; if ($sampling == 1) { // First pick this minute (or minute rollover) $picked = 1; diff --git a/tests/ext/background-sender/agent_sampling-standalone-asm_02.phpt b/tests/ext/background-sender/agent_sampling-standalone-asm_02.phpt index f949ebb02b5..a838487c492 100644 --- a/tests/ext/background-sender/agent_sampling-standalone-asm_02.phpt +++ b/tests/ext/background-sender/agent_sampling-standalone-asm_02.phpt @@ -23,8 +23,7 @@ $rr = new RequestReplayer(); $get_sampling = function() use ($rr) { $root = json_decode($rr->waitForDataAndReplay()["body"], true); - $spans = $root["chunks"][0]["spans"] ?? $root[0]; - return $spans[0]["metrics"]["_sampling_priority_v1"]; + return RequestReplayer::chunkPriority($root); }; \DDTrace\start_span(); diff --git a/tests/ext/background-sender/agent_sampling-standalone-asm_03.phpt b/tests/ext/background-sender/agent_sampling-standalone-asm_03.phpt index 0c61a131d33..a6f8b647e89 100644 --- a/tests/ext/background-sender/agent_sampling-standalone-asm_03.phpt +++ b/tests/ext/background-sender/agent_sampling-standalone-asm_03.phpt @@ -28,8 +28,7 @@ $rr = new RequestReplayer(); $get_sampling = function() use ($rr) { $root = json_decode($rr->waitForDataAndReplay()["body"], true); - $spans = $root["chunks"][0]["spans"] ?? $root[0]; - return $spans[0]["metrics"]["_sampling_priority_v1"]; + return RequestReplayer::chunkPriority($root); }; \DDTrace\start_span(); diff --git a/tests/ext/background-sender/agent_sampling.phpt b/tests/ext/background-sender/agent_sampling.phpt index d6f9194f757..31f142139a4 100644 --- a/tests/ext/background-sender/agent_sampling.phpt +++ b/tests/ext/background-sender/agent_sampling.phpt @@ -25,11 +25,10 @@ $rr = new RequestReplayer(); $get_sampling = function() use ($rr) { $root = json_decode($rr->waitForDataAndReplay()["body"], true); - $spans = $root["chunks"][0]["spans"] ?? $root[0]; // Ensure the BGS has finished processing the HTTP response (writing agent rates to SHM) // before the caller changes the mock response. dd_trace_internal_fn("synchronous_flush"); - return $spans[0]["metrics"]["_sampling_priority_v1"]; + return RequestReplayer::chunkPriority($root); }; $rr->setResponse(["rate_by_service" => ["service:,env:" => 0]]); diff --git a/tests/ext/background-sender/agent_sampling_sidecar.phpt b/tests/ext/background-sender/agent_sampling_sidecar.phpt index fcd206c84c0..e16bfbb7d2c 100644 --- a/tests/ext/background-sender/agent_sampling_sidecar.phpt +++ b/tests/ext/background-sender/agent_sampling_sidecar.phpt @@ -63,8 +63,7 @@ $rr->replayRequest(); // cleanup possible leftover $errors = []; $get_sampling = function($label, $expected) use ($rr, &$errors) { $root = json_decode($rr->waitForDataAndReplay()["body"], true); - $spans = $root["chunks"][0]["spans"] ?? $root[0]; - $priority = $spans[0]["metrics"]["_sampling_priority_v1"]; + $priority = RequestReplayer::chunkPriority($root); if ($priority != $expected) { $errors[] = "{$label} sampling priority: expected {$expected}, got {$priority}"; } diff --git a/tests/ext/base_service.phpt b/tests/ext/base_service.phpt index 146041e8b8b..15acb6f53cc 100644 --- a/tests/ext/base_service.phpt +++ b/tests/ext/base_service.phpt @@ -18,11 +18,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> diff --git a/tests/ext/call_user_func/namespaced-array.phpt b/tests/ext/call_user_func/namespaced-array.phpt index 401650fdc0b..4389dc6834d 100644 --- a/tests/ext/call_user_func/namespaced-array.phpt +++ b/tests/ext/call_user_func/namespaced-array.phpt @@ -4,11 +4,11 @@ Test that call_user_func_array can trace inside a namespace name = "root"; $root->service = "my-service"; \DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; foreach ($spans as $span) { $has_top_level = isset($span["metrics"]["_dd.top_level"]); diff --git a/tests/ext/client_side_stats_top_level.phpt b/tests/ext/client_side_stats_top_level.phpt index 3f00ce01ed3..402a84cb318 100644 --- a/tests/ext/client_side_stats_top_level.phpt +++ b/tests/ext/client_side_stats_top_level.phpt @@ -30,7 +30,7 @@ $child_diff->service = "other-service"; \DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; foreach ($spans as $span) { $has_top_level = isset($span["attributes"]["_dd.top_level"]); diff --git a/tests/ext/dd_trace_current_context.phpt b/tests/ext/dd_trace_current_context.phpt index 51d382f7fb2..89a2c652cf0 100644 --- a/tests/ext/dd_trace_current_context.phpt +++ b/tests/ext/dd_trace_current_context.phpt @@ -3,6 +3,8 @@ Test the output of \DDTrace\current_context --ENV-- DD_VERSION=1.2.3 DD_ENV=dd-trace-test +--INI-- +error_reporting=E_ALL --FILE-- --EXPECTF-- +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d array(5) { ["trace_id"]=> string(%d) "%d" @@ -39,3 +42,5 @@ array(5) { array(0) { } } + +Deprecated: Function DDTrace\trace_id() is deprecated in %s on line %d diff --git a/tests/ext/dd_trace_current_context_noenv.phpt b/tests/ext/dd_trace_current_context_noenv.phpt index 4d277b47b51..d3f55de65b3 100644 --- a/tests/ext/dd_trace_current_context_noenv.phpt +++ b/tests/ext/dd_trace_current_context_noenv.phpt @@ -1,5 +1,7 @@ --TEST-- Test the output of \DDTrace\current_context without env variables. +--INI-- +error_reporting=E_ALL --FILE-- --EXPECTF-- +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d array(5) { ["trace_id"]=> string(%d) "%d" @@ -28,3 +31,5 @@ array(5) { array(0) { } } + +Deprecated: Function DDTrace\trace_id() is deprecated in %s on line %d diff --git a/tests/ext/dd_trace_serialize_header_to_meta.phpt b/tests/ext/dd_trace_serialize_header_to_meta.phpt index 2a83dc5dbb9..e31253916f3 100644 --- a/tests/ext/dd_trace_serialize_header_to_meta.phpt +++ b/tests/ext/dd_trace_serialize_header_to_meta.phpt @@ -13,7 +13,7 @@ application_key=123 --EXPECTF-- -array(11) { - ["trace_id"]=> - string(20) "13930160852258120406" - ["trace_id_high"]=> - string(16) "%s" +array(9) { ["span_id"]=> string(19) "2513787319205155662" ["parent_id"]=> @@ -76,54 +72,38 @@ array(11) { ["span_links"]=> array(2) { [0]=> - array(4) { + array(2) { ["trace_id"]=> - string(20) "13930160852258120406" - ["trace_id_high"]=> - string(16) "%s" + string(%d) "%s" ["span_id"]=> - string(20) "11788048577503494824" - ["flags"]=> - int(0) + string(16) "%s" } [1]=> - array(4) { + array(2) { ["trace_id"]=> - string(20) "13930160852258120406" - ["trace_id_high"]=> - string(16) "%s" + string(%d) "%s" ["span_id"]=> - string(20) "13874630024467741450" - ["flags"]=> - int(0) + string(16) "%s" } } } string(3) "bar" array(1) { [0]=> - array(4) { + array(2) { ["trace_id"]=> - string(20) "13930160852258120406" - ["trace_id_high"]=> - string(16) "%s" + string(%d) "%s" ["span_id"]=> - string(20) "13874630024467741450" - ["flags"]=> - int(0) + string(16) "%s" } } string(3) "foo" array(1) { [0]=> - array(4) { + array(2) { ["trace_id"]=> - string(20) "13930160852258120406" - ["trace_id_high"]=> - string(16) "%s" + string(%d) "%s" ["span_id"]=> - string(20) "11788048577503494824" - ["flags"]=> - int(0) + string(16) "%s" } } diff --git a/tests/ext/distributed_tracing/baggage/baggage_span_tags.phpt b/tests/ext/distributed_tracing/baggage/baggage_span_tags.phpt index 5dcc0481f40..e35bc266a8f 100644 --- a/tests/ext/distributed_tracing/baggage/baggage_span_tags.phpt +++ b/tests/ext/distributed_tracing/baggage/baggage_span_tags.phpt @@ -15,11 +15,17 @@ var_dump(DDTrace\start_span()->meta); ?> --EXPECTF-- -array(3) { +array(6) { ["baggage.user.id"]=> string(3) "123" ["baggage.session.id"]=> string(3) "abc" ["runtime-id"]=> string(36) "%s" + ["service.name"]=> + string(21) "baggage_span_tags.php" + ["operation.name"]=> + string(21) "baggage_span_tags.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/distributed_tracing/baggage/baggage_span_tags_empty.phpt b/tests/ext/distributed_tracing/baggage/baggage_span_tags_empty.phpt index bacadd12491..73e0c5bf33a 100644 --- a/tests/ext/distributed_tracing/baggage/baggage_span_tags_empty.phpt +++ b/tests/ext/distributed_tracing/baggage/baggage_span_tags_empty.phpt @@ -16,7 +16,13 @@ var_dump(DDTrace\start_span()->meta); ?> --EXPECTF-- -array(1) { +array(4) { ["runtime-id"]=> string(36) "%s" + ["service.name"]=> + string(27) "baggage_span_tags_empty.php" + ["operation.name"]=> + string(27) "baggage_span_tags_empty.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/distributed_tracing/baggage/baggage_span_tags_keys.phpt b/tests/ext/distributed_tracing/baggage/baggage_span_tags_keys.phpt index 79dac85f819..ecc79ee58db 100644 --- a/tests/ext/distributed_tracing/baggage/baggage_span_tags_keys.phpt +++ b/tests/ext/distributed_tracing/baggage/baggage_span_tags_keys.phpt @@ -16,9 +16,15 @@ var_dump(DDTrace\start_span()->meta); ?> --EXPECTF-- -array(2) { +array(5) { ["baggage.region"]=> string(8) "us-east1" ["runtime-id"]=> string(36) "%s" + ["service.name"]=> + string(26) "baggage_span_tags_keys.php" + ["operation.name"]=> + string(26) "baggage_span_tags_keys.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/distributed_tracing/baggage/baggage_span_tags_wildcard.phpt b/tests/ext/distributed_tracing/baggage/baggage_span_tags_wildcard.phpt index 6f2b69eae6b..cd12d139b30 100644 --- a/tests/ext/distributed_tracing/baggage/baggage_span_tags_wildcard.phpt +++ b/tests/ext/distributed_tracing/baggage/baggage_span_tags_wildcard.phpt @@ -16,7 +16,7 @@ var_dump(DDTrace\start_span()->meta); ?> --EXPECTF-- -array(5) { +array(8) { ["baggage.user.id"]=> string(3) "123" ["baggage.session.id"]=> @@ -27,4 +27,10 @@ array(5) { string(3) "php" ["runtime-id"]=> string(36) "%s" + ["service.name"]=> + string(30) "baggage_span_tags_wildcard.php" + ["operation.name"]=> + string(30) "baggage_span_tags_wildcard.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file 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 7a55657c358..018bc7f203f 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_01.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_01.phpt @@ -12,7 +12,6 @@ DD_APM_TRACING_ENABLED=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 --FILE-- name = 'outer'; @@ -22,83 +21,97 @@ $inner->name = 'inner'; DDTrace\close_span(); DDTrace\close_span(); -var_dump(dd_clean_spans()); +var_dump(dd_trace_serialize_closed_spans()); ?> --EXPECTF-- array(2) { - [0]=> - array(13) { - ["trace_id"]=> - string(2) "42" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(2) "10" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(5) "outer" - ["resource"]=> - string(5) "outer" - ["service"]=> - string(39) "distributed_trace_asm_standalone_01.php" - ["type"]=> - string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) - ["origin"]=> - string(7) "datadog" - ["attributes"]=> - array(9) { - ["_dd.p.custom_tag"]=> - string(9) "inherited" - ["_dd.propagation_error"]=> - string(14) "decoding_error" - ["_dd.p.other_tag"]=> - string(4) "also" - ["runtime-id"]=> - string(36) "%s" - ["process_id"]=> - float(%f) - ["_dd.apm.enabled"]=> - float(0) - ["php.compilation.total_time_ms"]=> - float(%f) - ["php.memory.peak_usage_bytes"]=> - float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) - } + ["attributes"]=> + array(2) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> + string(%d) "%s" } - [1]=> - array(10) { - ["trace_id"]=> - string(2) "42" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(5) "inner" - ["resource"]=> - string(5) "inner" - ["service"]=> - string(39) "distributed_trace_asm_standalone_01.php" - ["type"]=> - string(3) "cli" - ["attributes"]=> - array(1) { - ["_dd.apm.enabled"]=> - float(0) + ["chunks"]=> + array(1) { + [0]=> + array(5) { + ["trace_id"]=> + string(%d) "%s" + ["priority"]=> + int(1) + ["origin"]=> + string(7) "datadog" + ["sampling_mechanism"]=> + int(0) + ["spans"]=> + array(2) { + [0]=> + array(9) { + ["span_id"]=> + string(%d) "%d" + ["parent_id"]=> + string(2) "10" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(5) "outer" + ["resource"]=> + string(5) "outer" + ["service"]=> + string(39) "distributed_trace_asm_standalone_01.php" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(9) { + ["_dd.p.custom_tag"]=> + string(9) "inherited" + ["_dd.propagation_error"]=> + string(14) "decoding_error" + ["_dd.p.other_tag"]=> + string(4) "also" + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + int(%d) + ["_dd.apm.enabled"]=> + float(0) + ["php.compilation.total_time_ms"]=> + float(%f) + ["php.memory.peak_usage_bytes"]=> + float(%f) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) + } + } + [1]=> + array(9) { + ["span_id"]=> + string(%d) "%d" + ["parent_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(5) "inner" + ["resource"]=> + string(5) "inner" + ["service"]=> + string(39) "distributed_trace_asm_standalone_01.php" + ["type"]=> + string(3) "cli" + ["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 4fbf2826724..04899322155 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_02.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_02.phpt @@ -12,7 +12,6 @@ DD_APM_TRACING_ENABLED=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 --FILE-- name = 'outer'; @@ -22,79 +21,93 @@ $inner->name = 'inner'; DDTrace\close_span(); DDTrace\close_span(); -var_dump(dd_clean_spans()); +var_dump(dd_trace_serialize_closed_spans()); ?> --EXPECTF-- array(2) { - [0]=> - array(13) { - ["trace_id"]=> - string(2) "42" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(2) "10" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(5) "outer" - ["resource"]=> - string(5) "outer" - ["service"]=> - string(39) "distributed_trace_asm_standalone_02.php" - ["type"]=> - string(3) "cli" - ["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" - ["process_id"]=> - float(%f) - ["_dd.apm.enabled"]=> - float(0) - ["php.compilation.total_time_ms"]=> - float(%f) - ["php.memory.peak_usage_bytes"]=> - float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) - } + ["attributes"]=> + array(2) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> + string(%d) "%s" } - [1]=> - array(10) { - ["trace_id"]=> - string(2) "42" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(5) "inner" - ["resource"]=> - string(5) "inner" - ["service"]=> - string(39) "distributed_trace_asm_standalone_02.php" - ["type"]=> - string(3) "cli" - ["attributes"]=> - array(1) { - ["_dd.apm.enabled"]=> - float(0) + ["chunks"]=> + array(1) { + [0]=> + array(5) { + ["trace_id"]=> + string(%d) "%s" + ["priority"]=> + int(3) + ["origin"]=> + string(7) "datadog" + ["sampling_mechanism"]=> + int(0) + ["spans"]=> + array(2) { + [0]=> + array(9) { + ["span_id"]=> + string(%d) "%d" + ["parent_id"]=> + string(2) "10" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(5) "outer" + ["resource"]=> + string(5) "outer" + ["service"]=> + string(39) "distributed_trace_asm_standalone_02.php" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(7) { + ["_dd.p.ts"]=> + string(2) "02" + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + int(%d) + ["_dd.apm.enabled"]=> + float(0) + ["php.compilation.total_time_ms"]=> + float(%f) + ["php.memory.peak_usage_bytes"]=> + float(%f) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) + } + } + [1]=> + array(9) { + ["span_id"]=> + string(%d) "%d" + ["parent_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(5) "inner" + ["resource"]=> + string(5) "inner" + ["service"]=> + string(39) "distributed_trace_asm_standalone_02.php" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(1) { + ["_dd.apm.enabled"]=> + float(0) + } + } + } } } } 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 df4a71554c1..5dd5174e270 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_03.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_03.phpt @@ -16,9 +16,9 @@ $outer = DDTrace\start_span(); DDTrace\Testing\emit_asm_event(); DDTrace\close_span(); -$traces = dd_trace_serialize_closed_spans(); +$chunks = dd_trace_serialize_closed_spans()['chunks']; -var_dump($traces[0]['attributes']['_dd.p.ts']); +var_dump($chunks[0]['spans'][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 86700f64ac8..f97a6960f7b 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_04.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_04.phpt @@ -16,9 +16,9 @@ $outer = DDTrace\start_span(); DDTrace\Testing\emit_asm_event(); DDTrace\close_span(); -$traces = dd_trace_serialize_closed_spans(); +$chunks = dd_trace_serialize_closed_spans()['chunks']; -var_dump($traces[0]['attributes']['_dd.p.ts']); +var_dump($chunks[0]['spans'][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 eb5f2c44dea..0d7622804c4 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_05.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_05.phpt @@ -16,9 +16,9 @@ $outer = DDTrace\start_span(); DDTrace\Testing\emit_asm_event(); DDTrace\close_span(); -$traces = dd_trace_serialize_closed_spans(); +$chunks = dd_trace_serialize_closed_spans()['chunks']; -var_dump($traces[0]['attributes']['_dd.p.ts']); +var_dump($chunks[0]['spans'][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 cb92e2e7921..37c6c3299dd 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_06.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_06.phpt @@ -23,14 +23,14 @@ $root3= DDTrace\start_trace_span(); $root3->name = 'root3'; DDTrace\close_span(); -$traces = dd_trace_serialize_closed_spans(); +$chunks = dd_trace_serialize_closed_spans()['chunks']; -var_dump($traces[0]['name']); -var_dump(isset($traces[0]['attributes']['_dd.p.ts'])); -var_dump($traces[1]['name']); -var_dump($traces[1]['attributes']['_dd.p.ts']); -var_dump($traces[2]['name']); -var_dump($traces[2]['attributes']['_dd.p.ts']); +var_dump($chunks[0]['spans'][0]['name']); +var_dump(isset($chunks[0]['spans'][0]['attributes']['_dd.p.ts'])); +var_dump($chunks[1]['spans'][0]['name']); +var_dump($chunks[1]['spans'][0]['attributes']['_dd.p.ts']); +var_dump($chunks[2]['spans'][0]['name']); +var_dump($chunks[2]['spans'][0]['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 25a2bd7a14e..c8e34672f07 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_07.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_07.phpt @@ -19,12 +19,12 @@ $root2 = DDTrace\start_trace_span(); $root2->name = 'root2'; DDTrace\close_span(); -$traces = dd_trace_serialize_closed_spans(); +$chunks = dd_trace_serialize_closed_spans()['chunks']; -var_dump($traces[0]['name']); -var_dump($traces[0]['attributes']['_dd.p.ts']); -var_dump($traces[1]['name']); -var_dump($traces[1]['attributes']['_dd.p.ts']); +var_dump($chunks[0]['spans'][0]['name']); +var_dump($chunks[0]['spans'][0]['attributes']['_dd.p.ts']); +var_dump($chunks[1]['spans'][0]['name']); +var_dump($chunks[1]['spans'][0]['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 96e9fb8ad4d..622b9ff7fb1 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_08.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_08.phpt @@ -16,9 +16,9 @@ $outer = DDTrace\start_span(); DDTrace\Testing\emit_asm_event(); DDTrace\close_span(); -$traces = dd_trace_serialize_closed_spans(); +$chunks = dd_trace_serialize_closed_spans()['chunks']; -var_dump($traces[0]['attributes']['_dd.p.ts']); +var_dump($chunks[0]['spans'][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 9dec29edb76..bba04ad962f 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_09.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_09.phpt @@ -15,9 +15,9 @@ DD_APM_TRACING_ENABLED=0 $outer = DDTrace\start_span(); DDTrace\close_span(); -$traces = dd_trace_serialize_closed_spans(); +$chunks = dd_trace_serialize_closed_spans()['chunks']; -var_dump($traces[0]['attributes']['_dd.p.ts']); +var_dump($chunks[0]['spans'][0]['attributes']['_dd.p.ts']); ?> --EXPECTF-- diff --git a/tests/ext/distributed_tracing/distributed_trace_bogus_ids.phpt b/tests/ext/distributed_tracing/distributed_trace_bogus_ids.phpt index b8070bee42a..3baad6020b2 100644 --- a/tests/ext/distributed_tracing/distributed_trace_bogus_ids.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_bogus_ids.phpt @@ -9,57 +9,70 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 --FILE-- name = 'span'; DDTrace\close_span(); -var_dump(dd_clean_spans()); +var_dump(dd_trace_serialize_closed_spans()); ?> --EXPECTF-- -array(1) { - [0]=> - array(13) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" - ["span_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(4) "span" - ["resource"]=> - string(4) "span" - ["service"]=> - string(31) "distributed_trace_bogus_ids.php" - ["type"]=> - string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) - ["origin"]=> - string(7) "datadog" - ["attributes"]=> - array(6) { - ["runtime-id"]=> - string(36) "%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(2) { + ["attributes"]=> + array(2) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> + string(%d) "%s" + } + ["chunks"]=> + array(1) { + [0]=> + array(5) { + ["trace_id"]=> + string(%d) "%s" + ["priority"]=> + int(1) + ["origin"]=> + string(7) "datadog" + ["sampling_mechanism"]=> + int(0) + ["spans"]=> + array(1) { + [0]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(4) "span" + ["resource"]=> + string(4) "span" + ["service"]=> + string(31) "distributed_trace_bogus_ids.php" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(6) { + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + int(%d) + ["_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) + } + } + } } } } \ No newline at end of file diff --git a/tests/ext/distributed_tracing/distributed_trace_inherit.phpt b/tests/ext/distributed_tracing/distributed_trace_inherit.phpt index dba77a081c7..27e38d68e51 100644 --- a/tests/ext/distributed_tracing/distributed_trace_inherit.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_inherit.phpt @@ -11,7 +11,6 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 --FILE-- name = 'outer'; @@ -21,76 +20,90 @@ $inner->name = 'inner'; DDTrace\close_span(); DDTrace\close_span(); -var_dump(dd_clean_spans()); +var_dump(dd_trace_serialize_closed_spans()); ?> --EXPECTF-- array(2) { - [0]=> - array(13) { - ["trace_id"]=> - string(2) "42" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(2) "10" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(5) "outer" - ["resource"]=> - string(5) "outer" - ["service"]=> - string(29) "distributed_trace_inherit.php" - ["type"]=> - string(3) "cli" - ["sampling_priority"]=> - int(3) - ["sampling_mechanism"]=> - int(0) - ["origin"]=> - string(7) "datadog" - ["attributes"]=> - array(8) { - ["_dd.p.custom_tag"]=> - string(9) "inherited" - ["_dd.propagation_error"]=> - string(14) "decoding_error" - ["_dd.p.other_tag"]=> - string(4) "also" - ["runtime-id"]=> - string(36) "%s" - ["process_id"]=> - float(%f) - ["php.compilation.total_time_ms"]=> - float(%f) - ["php.memory.peak_usage_bytes"]=> - float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) - } + ["attributes"]=> + array(2) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> + string(%d) "%s" } - [1]=> - array(9) { - ["trace_id"]=> - string(2) "42" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(5) "inner" - ["resource"]=> - string(5) "inner" - ["service"]=> - string(29) "distributed_trace_inherit.php" - ["type"]=> - string(3) "cli" + ["chunks"]=> + array(1) { + [0]=> + array(5) { + ["trace_id"]=> + string(%d) "%s" + ["priority"]=> + int(3) + ["origin"]=> + string(7) "datadog" + ["sampling_mechanism"]=> + int(0) + ["spans"]=> + array(2) { + [0]=> + array(9) { + ["span_id"]=> + string(%d) "%d" + ["parent_id"]=> + string(2) "10" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(5) "outer" + ["resource"]=> + string(5) "outer" + ["service"]=> + string(29) "distributed_trace_inherit.php" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(8) { + ["_dd.p.custom_tag"]=> + string(9) "inherited" + ["_dd.propagation_error"]=> + string(14) "decoding_error" + ["_dd.p.other_tag"]=> + string(4) "also" + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + int(%d) + ["php.compilation.total_time_ms"]=> + float(%f) + ["php.memory.peak_usage_bytes"]=> + float(%f) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) + } + } + [1]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["parent_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(5) "inner" + ["resource"]=> + string(5) "inner" + ["service"]=> + string(29) "distributed_trace_inherit.php" + ["type"]=> + string(3) "cli" + } + } + } } } diff --git a/tests/ext/distributed_tracing/distributed_trace_inherit_b3-single-span.phpt b/tests/ext/distributed_tracing/distributed_trace_inherit_b3-single-span.phpt index 9b6786830a8..0cc55c16e8e 100644 --- a/tests/ext/distributed_tracing/distributed_trace_inherit_b3-single-span.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_inherit_b3-single-span.phpt @@ -3,6 +3,8 @@ Transmit distributed header information to spans via single B3 header --ENV-- HTTP_B3=42-10-d DD_TRACE_PROPAGATION_STYLE_EXTRACT=B3 single header +--INI-- +error_reporting=E_ALL --FILE-- ---EXPECT-- +--EXPECTF-- +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d string(2) "16" string(2) "66" int(2) diff --git a/tests/ext/distributed_tracing/distributed_trace_inherit_b3-single-span_no_sampling.phpt b/tests/ext/distributed_tracing/distributed_trace_inherit_b3-single-span_no_sampling.phpt index 9fe3e5de592..4269d5304f0 100644 --- a/tests/ext/distributed_tracing/distributed_trace_inherit_b3-single-span_no_sampling.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_inherit_b3-single-span_no_sampling.phpt @@ -4,6 +4,8 @@ Transmit distributed header information to spans via single B3 header without sa HTTP_B3=12345678901234567890-12345678901234567890123456789012 DD_TRACE_PROPAGATION_STYLE_EXTRACT=B3 single header DD_TRACE_GENERATE_ROOT_SPAN=0 +--INI-- +error_reporting=E_ALL --FILE-- propagatedSamplingPriority == DD_TRACE_PRIORITY_SAMPLING_UNKNOWN DDTrace\close_span(); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d string(19) "8687463697196027922" string(23) "85968058271978839505040" bool(true) diff --git a/tests/ext/distributed_tracing/distributed_trace_inherit_b3.phpt b/tests/ext/distributed_tracing/distributed_trace_inherit_b3.phpt index df127ba72b5..c40ad3ec7f1 100644 --- a/tests/ext/distributed_tracing/distributed_trace_inherit_b3.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_inherit_b3.phpt @@ -6,6 +6,8 @@ HTTP_X_B3_SPANID=10 HTTP_X_B3_SAMPLED=1 DD_TRACE_GENERATE_ROOT_SPAN=0 DD_TRACE_PROPAGATION_STYLE_EXTRACT=B3 +--INI-- +error_reporting=E_ALL --FILE-- --EXPECTF-- +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d string(2) "16" string(2) "66" int(1) diff --git a/tests/ext/distributed_tracing/distributed_trace_overwrite.phpt b/tests/ext/distributed_tracing/distributed_trace_overwrite.phpt index da4488a66b1..b3829865e0b 100644 --- a/tests/ext/distributed_tracing/distributed_trace_overwrite.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_overwrite.phpt @@ -6,6 +6,8 @@ HTTP_X_DATADOG_PARENT_ID=10 HTTP_X_DATADOG_ORIGIN=datadog HTTP_X_DATADOG_TAGS=_dd.p.custom_tag=inherited,_dd.p.second_tag=bar DD_TRACE_GENERATE_ROOT_SPAN=0 +--INI-- +error_reporting=E_ALL --FILE-- "c"]); dump_context(); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d trace_id: 42 distributed_tracing_origin: datadog distributed_tracing_parent_id: 10 distributed_tracing_propagated_tags: {"_dd.p.custom_tag":"inherited","_dd.p.second_tag":"bar"} + +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d trace_id: 123 distributed_tracing_origin: foo distributed_tracing_parent_id: 321 distributed_tracing_propagated_tags: {"a":"b"} + +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d trace_id: 0 distributed_tracing_origin: distributed_tracing_parent_id: 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 61b4a9eb80d..94a9a3073bd 100644 --- a/tests/ext/distributed_tracing/distributed_trace_overwrite_active_span.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_overwrite_active_span.phpt @@ -6,6 +6,8 @@ HTTP_X_DATADOG_TAGS=custom_tag=inherited HTTP_X_DATADOG_ORIGIN=datadog DD_TRACE_GENERATE_ROOT_SPAN=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--INI-- +error_reporting=E_ALL --FILE-- id; DDTrace\close_span(); DDTrace\close_span(); -$span = dump_spans(); -echo "all spans trace_id updated: "; var_dump($span["trace_id"] == $id); +$traceId = dump_spans(); +echo "all spans trace_id updated: "; var_dump($traceId == $id); ?> --EXPECTF-- bool(true) + +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d array(7) { ["trace_id"]=> string(3) "123" @@ -111,10 +107,16 @@ array(7) { string(1) "b" } } + +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d + +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d bool(true) -parent: 321, trace: 123, meta: {"_dd.origin":"foo","a":"b"} -parent: %d, trace: 123, meta: [] +parent: 321, trace: 123, origin: foo, meta: {"a":"b"} +parent: %d, trace: 123, origin: foo, meta: [] bool(true) + +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d array(5) { ["trace_id"]=> string(%d) "%d" @@ -128,8 +130,10 @@ array(5) { array(0) { } } + +Deprecated: Function DDTrace\trace_id() is deprecated in %s on line %d bool(true) bool(true) -parent: 0, trace: %d, meta: {"_dd.p.tid":"%s"} -parent: %d, trace: %d, meta: [] +parent: 0, trace: %d, origin: , meta: [] +parent: %d, trace: %d, origin: , meta: [] all spans trace_id updated: bool(true) diff --git a/tests/ext/distributed_tracing/distributed_trace_reset_context_on_init.phpt b/tests/ext/distributed_tracing/distributed_trace_reset_context_on_init.phpt index 08f33183915..3205efbaa42 100644 --- a/tests/ext/distributed_tracing/distributed_trace_reset_context_on_init.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_reset_context_on_init.phpt @@ -2,6 +2,8 @@ Reset distributed tracing context on request init --ENV-- DD_TRACE_GENERATE_ROOT_SPAN=0 +--INI-- +error_reporting=E_ALL --FILE-- ---EXPECT-- +--EXPECTF-- +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d array(5) { ["trace_id"]=> string(1) "0" @@ -33,6 +36,8 @@ array(5) { array(0) { } } + +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d array(6) { ["trace_id"]=> string(3) "123" @@ -48,6 +53,8 @@ array(6) { array(0) { } } + +Deprecated: Function DDTrace\current_context() is deprecated in %s on line %d array(5) { ["trace_id"]=> string(1) "0" diff --git a/tests/ext/dropped_spans_have_negative_duration.phpt b/tests/ext/dropped_spans_have_negative_duration.phpt index 598be4c6c14..3d4d23e05bb 100644 --- a/tests/ext/dropped_spans_have_negative_duration.phpt +++ b/tests/ext/dropped_spans_have_negative_duration.phpt @@ -10,7 +10,7 @@ $outerSpan = DDTrace\start_span(); DDTrace\start_span(); DDTrace\close_span(); -var_dump(count(dd_trace_serialize_closed_spans())); +var_dump(count(dd_trace_serialize_closed_spans()['chunks'][0]['spans'])); var_dump($outerSpan->getDuration()); diff --git a/tests/ext/env_meta_fallback_promoted.phpt b/tests/ext/env_meta_fallback_promoted.phpt index 61067b267ee..6a9102a937f 100644 --- a/tests/ext/env_meta_fallback_promoted.phpt +++ b/tests/ext/env_meta_fallback_promoted.phpt @@ -19,7 +19,7 @@ $s->name = "http.request"; $s->service = "web"; \DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; $root = $spans[0]; // env/version promoted from the DD_TAGS-sourced meta fallback; deleted from the unified // attributes map once promoted to the dedicated top-level fields. diff --git a/tests/ext/extract_ip_private_01.phpt b/tests/ext/extract_ip_private_01.phpt index 435145953da..0e8b618afc9 100644 --- a/tests/ext/extract_ip_private_01.phpt +++ b/tests/ext/extract_ip_private_01.phpt @@ -10,7 +10,7 @@ DD_TRACE_CLIENT_IP_ENABLED=true --EXPECTF-- diff --git a/tests/ext/extract_server_values.phpt b/tests/ext/extract_server_values.phpt index f503b5beb53..bcf6f9bf581 100644 --- a/tests/ext/extract_server_values.phpt +++ b/tests/ext/extract_server_values.phpt @@ -27,7 +27,7 @@ if (!isset($_SERVER[0])) { DDTrace\start_span(); DDTrace\close_span(); -var_dump(dd_trace_serialize_closed_spans()[0]["attributes"]["http.request.headers.0"]); +var_dump(dd_trace_serialize_closed_spans()['chunks'][0]['spans'][0]["attributes"]["http.request.headers.0"]); ?> --EXPECT-- diff --git a/tests/ext/generate_128_bit_trace_id.phpt b/tests/ext/generate_128_bit_trace_id.phpt index f0246e5adfa..a4084036f34 100644 --- a/tests/ext/generate_128_bit_trace_id.phpt +++ b/tests/ext/generate_128_bit_trace_id.phpt @@ -8,26 +8,26 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 ini_set("datadog.trace.128_bit_traceid_generation_enabled", "1"); DDTrace\start_span(); -var_dump(\DDTrace\trace_id() > 2 ** 64); +var_dump(substr(\DDTrace\root_span()->traceId, 0, 16) != "0000000000000000"); ini_set("datadog.trace.128_bit_traceid_generation_enabled", "0"); DDTrace\set_distributed_tracing_context(0, 0); -var_dump(\DDTrace\trace_id() < 2 ** 64); +var_dump(substr(\DDTrace\root_span()->traceId, 0, 16) == "0000000000000000"); ini_set("datadog.trace.128_bit_traceid_generation_enabled", "1"); DDTrace\set_distributed_tracing_context(0, 0); -var_dump(\DDTrace\trace_id() > 2 ** 64); -$first_trace_id = \DDTrace\trace_id(); +var_dump(substr(\DDTrace\root_span()->traceId, 0, 16) != "0000000000000000"); +$first_trace_id = \DDTrace\root_span()->traceId; DDTrace\close_span(); ini_set("datadog.trace.128_bit_traceid_generation_enabled", "0"); DDTrace\start_span(); -var_dump(\DDTrace\trace_id() < 2 ** 64); +var_dump(substr(\DDTrace\root_span()->traceId, 0, 16) == "0000000000000000"); DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); -var_dump(!isset($spans[0]["trace_id_high"])); -var_dump(hexdec($spans[1]["trace_id_high"]) == floor($spans[1]["start"] / 1000000000) * (1 << 32)); +$chunks = dd_trace_serialize_closed_spans()['chunks']; +var_dump(substr($chunks[0]["trace_id"], 0, 16) == "0000000000000000"); +var_dump(hexdec(substr($chunks[1]["trace_id"], 0, 16)) == floor($chunks[1]["spans"][0]["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 b4e38dc14f9..3956275b0fb 100644 --- a/tests/ext/http_endpoint_resource_renaming_always_simplified.phpt +++ b/tests/ext/http_endpoint_resource_renaming_always_simplified.phpt @@ -22,7 +22,7 @@ function test_endpoint_with_route($path, $route) { DDTrace\close_span(); - $spans = dd_trace_serialize_closed_spans(); + $spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; if (count($spans) > 0) { $span_data = $spans[0]; if ($route !== null) { diff --git a/tests/ext/http_endpoint_resource_renaming_basic.phpt b/tests/ext/http_endpoint_resource_renaming_basic.phpt index 90632a5089e..5bac096efd2 100644 --- a/tests/ext/http_endpoint_resource_renaming_basic.phpt +++ b/tests/ext/http_endpoint_resource_renaming_basic.phpt @@ -19,7 +19,7 @@ function test_endpoint($path) { DDTrace\close_span(); - $spans = dd_trace_serialize_closed_spans(); + $spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; if (count($spans) > 0) { $span_data = $spans[0]; echo "Path: $path\n"; @@ -90,7 +90,7 @@ function test_endpoint_with_route($path, $route) { DDTrace\close_span(); - $spans = dd_trace_serialize_closed_spans(); + $spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; if (count($spans) > 0) { $span_data = $spans[0]; echo "Path: $path, Route: $route\n"; diff --git a/tests/ext/includes/fake_tracer.inc b/tests/ext/includes/fake_tracer.inc index a3f080ee955..17ddbd54d9b 100644 --- a/tests/ext/includes/fake_tracer.inc +++ b/tests/ext/includes/fake_tracer.inc @@ -33,7 +33,7 @@ class Tracer if (strlen($valuesString) > 0) { $valuesStrings[] = $valuesString; } - }, dd_trace_serialize_closed_spans()); + }, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); // Reporting $output = '[ddtrace] [info] Flushing tracer...' . PHP_EOL; diff --git a/tests/ext/includes/request_replayer.inc b/tests/ext/includes/request_replayer.inc index a4567e3ef69..ddd7a2ae1df 100644 --- a/tests/ext/includes/request_replayer.inc +++ b/tests/ext/includes/request_replayer.inc @@ -91,6 +91,12 @@ class RequestReplayer } while (true); } + /** The sampling priority of the first chunk, from the replayer's v1 JSON view or a v0.4 payload. */ + public static function chunkPriority($payload) + { + return $payload["chunks"][0]["priority"] ?? $payload[0][0]["metrics"]["_sampling_priority_v1"] ?? null; + } + public function waitForDataAndReplay($ignoreTelemetry = true) { $i = 0; diff --git a/tests/ext/inferred_proxy/alter_service.phpt b/tests/ext/inferred_proxy/alter_service.phpt index 710e509a4cd..acfcb050f88 100644 --- a/tests/ext/inferred_proxy/alter_service.phpt +++ b/tests/ext/inferred_proxy/alter_service.phpt @@ -42,7 +42,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); --EXPECTF-- [ { - "trace_id": "13930160852258120406", "span_id": "13930160852258120406", "parent_id": "11788048577503494824", "start": 120000000, @@ -53,7 +52,7 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "type": "web", "env": "local-prod", "version": "1.0", - "component": "cgi-fcgi", + "component": "web", "span_kind": 2, "attributes": { "runtime-id": "%s", @@ -67,8 +66,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); } }, { - "trace_id": "13930160852258120406", - "trace_id_high": "%s", "span_id": "11788048577503494824", "start": 100000000, "duration": %d, @@ -79,8 +76,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "env": "local-prod", "version": "1.0", "component": "aws-apigateway", - "sampling_priority": 1, - "sampling_mechanism": 0, "attributes": { "http.method": "GET", "http.url": "example.com\/test", @@ -91,7 +86,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); } }, { - "trace_id": "13930160852258120406", "span_id": "13874630024467741450", "parent_id": "13930160852258120406", "start": 130000000, diff --git a/tests/ext/inferred_proxy/basic_test.phpt b/tests/ext/inferred_proxy/basic_test.phpt index 331851110d6..8fff83c6a9b 100644 --- a/tests/ext/inferred_proxy/basic_test.phpt +++ b/tests/ext/inferred_proxy/basic_test.phpt @@ -59,7 +59,6 @@ if ($percentageDifference > 0.01) { // 0.01% difference for the sake of the test --EXPECTF-- [ { - "trace_id": "13930160852258120406", "span_id": "13930160852258120406", "parent_id": "11788048577503494824", "start": %d, @@ -70,7 +69,7 @@ if ($percentageDifference > 0.01) { // 0.01% difference for the sake of the test "type": "web", "env": "local-prod", "version": "1.0", - "component": "cgi-fcgi", + "component": "web", "span_kind": 2, "attributes": { "runtime-id": "%s", @@ -85,8 +84,6 @@ if ($percentageDifference > 0.01) { // 0.01% difference for the sake of the test } }, { - "trace_id": "13930160852258120406", - "trace_id_high": "%s", "span_id": "11788048577503494824", "start": 1742285908783000000, "duration": %d, @@ -97,8 +94,6 @@ if ($percentageDifference > 0.01) { // 0.01% difference for the sake of the test "env": "local-prod", "version": "1.0", "component": "aws-apigateway", - "sampling_priority": 1, - "sampling_mechanism": 0, "attributes": { "http.method": "GET", "http.url": "example.com\/test", @@ -109,7 +104,6 @@ if ($percentageDifference > 0.01) { // 0.01% difference for the sake of the test } }, { - "trace_id": "13930160852258120406", "span_id": "13874630024467741450", "parent_id": "13930160852258120406", "start": %d, diff --git a/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt b/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt index f6da750f554..5e02b2a6937 100644 --- a/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt +++ b/tests/ext/inferred_proxy/consume_distributed_tracing_headers.phpt @@ -20,7 +20,6 @@ REQUEST_URI=/foo DD_TRACE_DEBUG_PRNG_SEED=42 --FILE-- name = "child"; \DDTrace\close_span(); \DDTrace\close_span(); // Should close the API Gateway span -echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); +echo json_encode(dd_trace_serialize_closed_spans(), JSON_PRETTY_PRINT); ?> --EXPECTF-- -[ - { - "trace_id": "13930160852258120406", - "span_id": "13930160852258120406", - "parent_id": "11788048577503494824", - "start": 120000000, - "duration": %d, - "name": "consume_distributed_tracing_headers.php", - "resource": "consume_distributed_tracing_headers.php", - "service": "aws-server", - "type": "cli", - "env": "local-prod", - "version": "1.0", - "attributes": { - "runtime-id": "%s", - "http.url": "http:\/\/localhost:8888\/foo", - "process_id": %d, - "php.compilation.total_time_ms": %f, - "php.memory.peak_usage_bytes": %d, - "php.memory.peak_real_usage_bytes": %d - } +{ + "env": "local-prod", + "app_version": "1.0", + "attributes": { + "_dd.sdk.otlp_export": "false", + "_dd.tags.process": "%s" }, - { - "trace_id": "13930160852258120406", - "trace_id_high": "%s", - "span_id": "11788048577503494824", - "start": %d, - "duration": %d, - "name": "aws.apigateway", - "resource": "GET \/test", - "service": "example.com", - "type": "web", - "env": "local-prod", - "version": "1.0", - "component": "aws-apigateway", - "sampling_priority": 1, - "sampling_mechanism": 0, - "attributes": { - "http.method": "GET", - "http.url": "example.com\/test", - "stage": "aws-prod", - "_dd.inferred_span": 1, - "_dd.agent_psr": 1 + "chunks": [ + { + "trace_id": "%s", + "priority": 1, + "sampling_mechanism": 0, + "spans": [ + { + "span_id": "13930160852258120406", + "parent_id": "11788048577503494824", + "start": 120000000, + "duration": %d, + "name": "consume_distributed_tracing_headers.php", + "resource": "consume_distributed_tracing_headers.php", + "service": "aws-server", + "type": "cli", + "env": "local-prod", + "version": "1.0", + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", + "process_id": %d, + "php.compilation.total_time_ms": %f, + "php.memory.peak_usage_bytes": %d, + "php.memory.peak_real_usage_bytes": %d + } + }, + { + "span_id": "11788048577503494824", + "start": %d, + "duration": %d, + "name": "aws.apigateway", + "resource": "GET \/test", + "service": "example.com", + "type": "web", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "attributes": { + "http.method": "GET", + "http.url": "example.com\/test", + "stage": "aws-prod", + "_dd.inferred_span": 1, + "_dd.agent_psr": 1 + } + }, + { + "span_id": "13874630024467741450", + "parent_id": "13930160852258120406", + "start": 130000000, + "duration": %d, + "name": "child", + "resource": "child", + "service": "aws-server", + "type": "cli", + "env": "local-prod", + "version": "1.0" + } + ] } - }, - { - "trace_id": "13930160852258120406", - "span_id": "13874630024467741450", - "parent_id": "13930160852258120406", - "start": 130000000, - "duration": %d, - "name": "child", - "resource": "child", - "service": "aws-server", - "type": "cli", - "env": "local-prod", - "version": "1.0" - } -] + ] +} diff --git a/tests/ext/inferred_proxy/distributed_tracing.phpt b/tests/ext/inferred_proxy/distributed_tracing.phpt index eb29334b900..355f944f682 100644 --- a/tests/ext/inferred_proxy/distributed_tracing.phpt +++ b/tests/ext/inferred_proxy/distributed_tracing.phpt @@ -33,7 +33,6 @@ DD_TRACE_DEBUG_PRNG_SEED=42 foo=bar --FILE-- name = "child"; \DDTrace\close_span(); \DDTrace\close_span(); -echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); +echo json_encode(dd_trace_serialize_closed_spans(), JSON_PRETTY_PRINT); ?> --EXPECTF-- -[ - { - "trace_id": "1", - "span_id": "13930160852258120406", - "parent_id": "11788048577503494824", - "start": 120000000, - "duration": %d, - "name": "web.request", - "resource": "GET \/foo", - "service": "aws-server", - "type": "web", - "env": "local-prod", - "version": "1.0", - "component": "cgi-fcgi", - "span_kind": 2, - "attributes": { - "runtime-id": "%s", - "http.url": "http:\/\/localhost:8888\/foo", - "http.method": "GET", - "process_id": %d, - "foo": "bar", - "http.status_code": "200", - "php.compilation.total_time_ms": %f, - "php.memory.peak_usage_bytes": %d, - "php.memory.peak_real_usage_bytes": %d - } +{ + "env": "local-prod", + "app_version": "1.0", + "attributes": { + "_dd.sdk.otlp_export": "false", + "_dd.tags.process": "%s" }, - { - "trace_id": "1", - "span_id": "11788048577503494824", - "parent_id": "2", - "start": 100000000, - "duration": %d, - "name": "aws.apigateway", - "resource": "GET \/test", - "service": "example.com", - "type": "web", - "env": "local-prod", - "version": "1.0", - "component": "aws-apigateway", - "sampling_priority": 2, - "sampling_mechanism": 0, - "origin": "rum", - "attributes": { - "http.method": "GET", - "http.url": "example.com\/test", - "stage": "aws-prod", - "_dd.inferred_span": 1, - "http.status_code": "200" + "chunks": [ + { + "trace_id": "%s", + "priority": 2, + "origin": "rum", + "sampling_mechanism": 0, + "spans": [ + { + "span_id": "13930160852258120406", + "parent_id": "11788048577503494824", + "start": 120000000, + "duration": %d, + "name": "web.request", + "resource": "GET \/foo", + "service": "aws-server", + "type": "web", + "env": "local-prod", + "version": "1.0", + "component": "web", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", + "http.method": "GET", + "process_id": %d, + "foo": "bar", + "http.status_code": "200", + "php.compilation.total_time_ms": %f, + "php.memory.peak_usage_bytes": %d, + "php.memory.peak_real_usage_bytes": %d + } + }, + { + "span_id": "11788048577503494824", + "parent_id": "2", + "start": 100000000, + "duration": %d, + "name": "aws.apigateway", + "resource": "GET \/test", + "service": "example.com", + "type": "web", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "attributes": { + "http.method": "GET", + "http.url": "example.com\/test", + "stage": "aws-prod", + "_dd.inferred_span": 1, + "http.status_code": "200" + } + }, + { + "span_id": "13874630024467741450", + "parent_id": "13930160852258120406", + "start": 130000000, + "duration": %d, + "name": "child", + "resource": "child", + "service": "aws-server", + "type": "web", + "env": "local-prod", + "version": "1.0" + } + ] } - }, - { - "trace_id": "1", - "span_id": "13874630024467741450", - "parent_id": "13930160852258120406", - "start": 130000000, - "duration": %d, - "name": "child", - "resource": "child", - "service": "aws-server", - "type": "web", - "env": "local-prod", - "version": "1.0" - } -] + ] +} diff --git a/tests/ext/inferred_proxy/error_propagated.phpt b/tests/ext/inferred_proxy/error_propagated.phpt index 59c066fbad1..e5084938218 100644 --- a/tests/ext/inferred_proxy/error_propagated.phpt +++ b/tests/ext/inferred_proxy/error_propagated.phpt @@ -51,7 +51,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); --EXPECTF-- [ { - "trace_id": "13930160852258120406", "span_id": "13930160852258120406", "parent_id": "11788048577503494824", "start": %d, @@ -60,10 +59,10 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/foo", "service": "aws-server", "type": "web", - "error": 1, + "error": true, "env": "local-prod", "version": "1.0", - "component": "cgi-fcgi", + "component": "web", "span_kind": 2, "attributes": { "runtime-id": "%s", @@ -80,8 +79,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); } }, { - "trace_id": "13930160852258120406", - "trace_id_high": "%s", "span_id": "11788048577503494824", "start": 100000000, "duration": %d, @@ -89,12 +86,10 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "resource": "GET \/test", "service": "example.com", "type": "web", - "error": 1, + "error": true, "env": "local-prod", "version": "1.0", "component": "aws-apigateway", - "sampling_priority": 1, - "sampling_mechanism": 0, "attributes": { "http.method": "GET", "http.url": "example.com\/test", diff --git a/tests/ext/inferred_proxy/fallback_service_name.phpt b/tests/ext/inferred_proxy/fallback_service_name.phpt index 970b47ce63e..0e91292b813 100644 --- a/tests/ext/inferred_proxy/fallback_service_name.phpt +++ b/tests/ext/inferred_proxy/fallback_service_name.phpt @@ -43,7 +43,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); --EXPECTF-- [ { - "trace_id": "13930160852258120406", "span_id": "13930160852258120406", "parent_id": "11788048577503494824", "start": 120000000, @@ -54,7 +53,7 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "type": "web", "env": "local-prod", "version": "1.0", - "component": "cgi-fcgi", + "component": "web", "span_kind": 2, "attributes": { "runtime-id": "%s", @@ -69,8 +68,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); } }, { - "trace_id": "13930160852258120406", - "trace_id_high": "%s", "span_id": "11788048577503494824", "start": 100000000, "duration": %d, @@ -81,8 +78,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "env": "local-prod", "version": "1.0", "component": "aws-apigateway", - "sampling_priority": 1, - "sampling_mechanism": 0, "attributes": { "http.method": "GET", "stage": "aws-prod", @@ -92,7 +87,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); } }, { - "trace_id": "13930160852258120406", "span_id": "13874630024467741450", "parent_id": "13930160852258120406", "start": 130000000, diff --git a/tests/ext/inferred_proxy/incomplete_headers.phpt b/tests/ext/inferred_proxy/incomplete_headers.phpt index 900be82425e..13491993f1c 100644 --- a/tests/ext/inferred_proxy/incomplete_headers.phpt +++ b/tests/ext/inferred_proxy/incomplete_headers.phpt @@ -36,8 +36,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); --EXPECTF-- [ { - "trace_id": "13930160852258120406", - "trace_id_high": "%s", "span_id": "13930160852258120406", "start": 120000000, "duration": %d, @@ -47,10 +45,8 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "type": "web", "env": "local-prod", "version": "1.0", - "component": "cgi-fcgi", + "component": "web", "span_kind": 2, - "sampling_priority": 1, - "sampling_mechanism": 0, "attributes": { "runtime-id": "%s", "http.url": "http:\/\/localhost:8888\/foo", @@ -58,7 +54,7 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); "process_id": %d, "_dd.code_origin.type": "entry", "_dd.code_origin.frames.0.file": "%sincomplete_headers.php", - "_dd.code_origin.frames.0.line": "1", + "_dd.code_origin.frames.0.line": 1, "_dd.agent_psr": 1, "http.status_code": "200", "php.compilation.total_time_ms": %f, @@ -67,7 +63,6 @@ echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); } }, { - "trace_id": "13930160852258120406", "span_id": "11788048577503494824", "parent_id": "13930160852258120406", "start": 130000000, diff --git a/tests/ext/inferred_proxy/multiple_traces.phpt b/tests/ext/inferred_proxy/multiple_traces.phpt index 85f9bb78285..2f8203375dd 100644 --- a/tests/ext/inferred_proxy/multiple_traces.phpt +++ b/tests/ext/inferred_proxy/multiple_traces.phpt @@ -29,7 +29,6 @@ DD_TRACE_DEBUG_PRNG_SEED=42 foo=bar --FILE-- name = "child"; $root = \DDTrace\start_trace_span(); \DDTrace\close_span(); -echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); +echo json_encode(dd_trace_serialize_closed_spans(), JSON_PRETTY_PRINT); ?> --EXPECTF-- -[ - { - "trace_id": "2513787319205155662", - "trace_id_high": "%s", - "span_id": "2513787319205155662", - "start": %d, - "duration": %d, - "name": "web.request", - "resource": "GET \/foo", - "service": "aws-server", - "type": "web", - "env": "local-prod", - "version": "1.0", - "component": "cgi-fcgi", - "span_kind": 2, - "sampling_priority": 1, - "sampling_mechanism": 0, - "attributes": { - "runtime-id": "%s", - "http.url": "http:\/\/localhost:8888\/foo", - "http.method": "GET", - "process_id": %d, - "_dd.agent_psr": 1, - "http.status_code": "200", - "php.compilation.total_time_ms": %f, - "php.memory.peak_usage_bytes": %d, - "php.memory.peak_real_usage_bytes": %d - } - }, - { - "trace_id": "13930160852258120406", - "span_id": "13930160852258120406", - "parent_id": "11788048577503494824", - "start": 120000000, - "duration": %d, - "name": "web.request", - "resource": "GET \/foo", - "service": "aws-server", - "type": "web", - "env": "local-prod", - "version": "1.0", - "component": "cgi-fcgi", - "span_kind": 2, - "attributes": { - "runtime-id": "%s", - "http.url": "http:\/\/localhost:8888\/foo", - "http.method": "GET", - "process_id": %d, - "http.status_code": "200", - "php.compilation.total_time_ms": %f, - "php.memory.peak_usage_bytes": %d, - "php.memory.peak_real_usage_bytes": %d - } +{ + "env": "local-prod", + "app_version": "1.0", + "attributes": { + "_dd.sdk.otlp_export": "false", + "_dd.tags.process": "%s" }, - { - "trace_id": "13930160852258120406", - "trace_id_high": "%s", - "span_id": "11788048577503494824", - "start": 100000000, - "duration": %d, - "name": "aws.apigateway", - "resource": "GET \/test", - "service": "example.com", - "type": "web", - "env": "local-prod", - "version": "1.0", - "component": "aws-apigateway", - "sampling_priority": 1, - "sampling_mechanism": 0, - "attributes": { - "http.method": "GET", - "http.url": "example.com\/test", - "stage": "aws-prod", - "_dd.inferred_span": 1, - "http.status_code": "200", - "_dd.agent_psr": 1 + "chunks": [ + { + "trace_id": "%s", + "priority": 1, + "sampling_mechanism": 0, + "spans": [ + { + "span_id": "2513787319205155662", + "start": %d, + "duration": %d, + "name": "web.request", + "resource": "GET \/foo", + "service": "aws-server", + "type": "web", + "env": "local-prod", + "version": "1.0", + "component": "web", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", + "http.method": "GET", + "process_id": %d, + "_dd.agent_psr": 1, + "http.status_code": "200", + "php.compilation.total_time_ms": %f, + "php.memory.peak_usage_bytes": %d, + "php.memory.peak_real_usage_bytes": %d + } + } + ] + }, + { + "trace_id": "%s", + "priority": 1, + "sampling_mechanism": 0, + "spans": [ + { + "span_id": "13930160852258120406", + "parent_id": "11788048577503494824", + "start": 120000000, + "duration": %d, + "name": "web.request", + "resource": "GET \/foo", + "service": "aws-server", + "type": "web", + "env": "local-prod", + "version": "1.0", + "component": "web", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", + "http.method": "GET", + "process_id": %d, + "http.status_code": "200", + "php.compilation.total_time_ms": %f, + "php.memory.peak_usage_bytes": %d, + "php.memory.peak_real_usage_bytes": %d + } + }, + { + "span_id": "11788048577503494824", + "start": 100000000, + "duration": %d, + "name": "aws.apigateway", + "resource": "GET \/test", + "service": "example.com", + "type": "web", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "attributes": { + "http.method": "GET", + "http.url": "example.com\/test", + "stage": "aws-prod", + "_dd.inferred_span": 1, + "http.status_code": "200", + "_dd.agent_psr": 1 + } + }, + { + "span_id": "13874630024467741450", + "parent_id": "13930160852258120406", + "start": 130000000, + "duration": %d, + "name": "child", + "resource": "child", + "service": "aws-server", + "type": "web", + "env": "local-prod", + "version": "1.0" + } + ] } - }, - { - "trace_id": "13930160852258120406", - "span_id": "13874630024467741450", - "parent_id": "13930160852258120406", - "start": 130000000, - "duration": %d, - "name": "child", - "resource": "child", - "service": "aws-server", - "type": "web", - "env": "local-prod", - "version": "1.0" - } -] + ] +} 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 c9ddbba259f..4e716a01da2 100644 --- a/tests/ext/inferred_proxy/propagated_tags_after_span_start.phpt +++ b/tests/ext/inferred_proxy/propagated_tags_after_span_start.phpt @@ -30,7 +30,6 @@ DD_TRACE_DEBUG_PRNG_SEED=42 foo=bar --FILE-- --EXPECTF-- -[ - { - "trace_id": "42", - "span_id": "13930160852258120406", - "parent_id": "11788048577503494824", - "start": 120000000, - "duration": %d, - "name": "web.request", - "resource": "GET \/foo", - "service": "aws-server", - "type": "web", - "env": "local-prod", - "version": "1.0", - "component": "cgi-fcgi", - "span_kind": 2, - "attributes": { - "runtime-id": "%s", - "http.url": "http:\/\/localhost:8888\/foo", - "http.method": "GET", - "process_id": %d, - "_dd.parent_id": "00000000000000bb", - "_dd.p.usr.id": "12345", - "http.status_code": "200", - "php.compilation.total_time_ms": %f, - "php.memory.peak_usage_bytes": %d, - "php.memory.peak_real_usage_bytes": %d - } +{ + "env": "local-prod", + "app_version": "1.0", + "attributes": { + "_dd.sdk.otlp_export": "false", + "_dd.tags.process": "%s" }, - { - "trace_id": "42", - "span_id": "11788048577503494824", - "parent_id": "1", - "start": 100000000, - "duration": %d, - "name": "aws.apigateway", - "resource": "GET \/test", - "service": "example.com", - "type": "web", - "env": "local-prod", - "version": "1.0", - "component": "aws-apigateway", - "sampling_priority": 1, - "sampling_mechanism": 4, - "origin": "rum", - "attributes": { - "http.method": "GET", - "http.url": "example.com\/test", - "stage": "aws-prod", - "_dd.inferred_span": 1, - "_dd.parent_id": "00000000000000bb", - "_dd.p.usr.id": "12345", - "http.status_code": "200" + "chunks": [ + { + "trace_id": "%s", + "priority": 1, + "origin": "rum", + "sampling_mechanism": 4, + "spans": [ + { + "span_id": "13930160852258120406", + "parent_id": "11788048577503494824", + "start": 120000000, + "duration": %d, + "name": "web.request", + "resource": "GET \/foo", + "service": "aws-server", + "type": "web", + "env": "local-prod", + "version": "1.0", + "component": "web", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", + "http.method": "GET", + "process_id": %d, + "_dd.parent_id": "00000000000000bb", + "_dd.p.usr.id": "12345", + "http.status_code": "200", + "php.compilation.total_time_ms": %f, + "php.memory.peak_usage_bytes": %d, + "php.memory.peak_real_usage_bytes": %d + } + }, + { + "span_id": "11788048577503494824", + "parent_id": "1", + "start": 100000000, + "duration": %d, + "name": "aws.apigateway", + "resource": "GET \/test", + "service": "example.com", + "type": "web", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "attributes": { + "http.method": "GET", + "http.url": "example.com\/test", + "stage": "aws-prod", + "_dd.inferred_span": 1, + "_dd.parent_id": "00000000000000bb", + "_dd.p.usr.id": "12345", + "http.status_code": "200" + } + } + ] } - } -] + ] +} 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 598989147f9..b5bf39fbaf5 100644 --- a/tests/ext/inferred_proxy/propagated_tags_before_span_start.phpt +++ b/tests/ext/inferred_proxy/propagated_tags_before_span_start.phpt @@ -30,7 +30,6 @@ DD_TRACE_DEBUG_PRNG_SEED=42 foo=bar --FILE-- "00-0000000000000000000000000000002a-0000000000000001-01", @@ -40,61 +39,72 @@ DDTrace\consume_distributed_tracing_headers([ $parent = \DDTrace\start_span(0.120); \DDTrace\close_span(); -echo json_encode(dd_clean_spans(), JSON_PRETTY_PRINT); +echo json_encode(dd_trace_serialize_closed_spans(), JSON_PRETTY_PRINT); ?> --EXPECTF-- -[ - { - "trace_id": "42", - "span_id": "13930160852258120406", - "parent_id": "11788048577503494824", - "start": 120000000, - "duration": %d, - "name": "web.request", - "resource": "GET \/foo", - "service": "aws-server", - "type": "web", - "env": "local-prod", - "version": "1.0", - "component": "cgi-fcgi", - "span_kind": 2, - "attributes": { - "_dd.parent_id": "00000000000000bb", - "_dd.p.usr.id": "12345", - "runtime-id": "%s", - "http.url": "http:\/\/localhost:8888\/foo", - "http.method": "GET", - "process_id": %d, - "http.status_code": "200", - "php.compilation.total_time_ms": %f, - "php.memory.peak_usage_bytes": %d, - "php.memory.peak_real_usage_bytes": %d - } +{ + "env": "local-prod", + "app_version": "1.0", + "attributes": { + "_dd.sdk.otlp_export": "false", + "_dd.tags.process": "%s" }, - { - "trace_id": "42", - "span_id": "11788048577503494824", - "parent_id": "1", - "start": 100000000, - "duration": %d, - "name": "aws.apigateway", - "resource": "GET \/test", - "service": "example.com", - "type": "web", - "env": "local-prod", - "version": "1.0", - "component": "aws-apigateway", - "sampling_priority": 1, - "sampling_mechanism": 4, - "origin": "rum", - "attributes": { - "_dd.parent_id": "00000000000000bb", - "_dd.p.usr.id": "12345", - "http.method": "GET", - "http.url": "example.com\/test", - "stage": "aws-prod", - "_dd.inferred_span": 1, - "http.status_code": "200" + "chunks": [ + { + "trace_id": "%s", + "priority": 1, + "origin": "rum", + "sampling_mechanism": 4, + "spans": [ + { + "span_id": "13930160852258120406", + "parent_id": "11788048577503494824", + "start": 120000000, + "duration": %d, + "name": "web.request", + "resource": "GET \/foo", + "service": "aws-server", + "type": "web", + "env": "local-prod", + "version": "1.0", + "component": "web", + "span_kind": 2, + "attributes": { + "_dd.parent_id": "00000000000000bb", + "_dd.p.usr.id": "12345", + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", + "http.method": "GET", + "process_id": %d, + "http.status_code": "200", + "php.compilation.total_time_ms": %f, + "php.memory.peak_usage_bytes": %d, + "php.memory.peak_real_usage_bytes": %d + } + }, + { + "span_id": "11788048577503494824", + "parent_id": "1", + "start": 100000000, + "duration": %d, + "name": "aws.apigateway", + "resource": "GET \/test", + "service": "example.com", + "type": "web", + "env": "local-prod", + "version": "1.0", + "component": "aws-apigateway", + "attributes": { + "_dd.parent_id": "00000000000000bb", + "_dd.p.usr.id": "12345", + "http.method": "GET", + "http.url": "example.com\/test", + "stage": "aws-prod", + "_dd.inferred_span": 1, + "http.status_code": "200" + } + } + ] } - } -] + ] +} diff --git a/tests/ext/inferred_proxy/sampling_rules.phpt b/tests/ext/inferred_proxy/sampling_rules.phpt index 90be2db7999..3f483f53b6e 100644 --- a/tests/ext/inferred_proxy/sampling_rules.phpt +++ b/tests/ext/inferred_proxy/sampling_rules.phpt @@ -29,60 +29,67 @@ pcre.jit=0 foo=bar --FILE-- --EXPECTF-- -[ - { - "trace_id": "13930160852258120406", - "span_id": "13930160852258120406", - "parent_id": "11788048577503494824", - "start": 120000000, - "duration": %d, - "name": "web.request", - "resource": "GET \/foo", - "service": "foo", - "type": "web", - "component": "cgi-fcgi", - "span_kind": 2, - "attributes": { - "runtime-id": "%s", - "http.url": "http:\/\/localhost:8888\/foo", - "http.method": "GET", - "process_id": %d, - "_dd.p.ksr": "0.3", - "http.status_code": "200", - "php.compilation.total_time_ms": %f, - "php.memory.peak_usage_bytes": %d, - "php.memory.peak_real_usage_bytes": %d - } +{ + "attributes": { + "_dd.sdk.otlp_export": "false", + "_dd.tags.process": "%s" }, - { - "trace_id": "13930160852258120406", - "trace_id_high": "%s", - "span_id": "11788048577503494824", - "start": 100000000, - "duration": %d, - "name": "aws.apigateway", - "resource": "GET \/test", - "service": "example.com", - "type": "web", - "component": "aws-apigateway", - "sampling_priority": 2, - "sampling_mechanism": 3, - "attributes": { - "http.method": "GET", - "http.url": "example.com\/test", - "stage": "aws-prod", - "_dd.inferred_span": 1, - "http.status_code": "200", - "_dd.rule_psr": 0.3, - "_dd.p.ksr": "0.3" + "chunks": [ + { + "trace_id": "%s", + "priority": 2, + "sampling_mechanism": 3, + "spans": [ + { + "span_id": "13930160852258120406", + "parent_id": "11788048577503494824", + "start": 120000000, + "duration": %d, + "name": "web.request", + "resource": "GET \/foo", + "service": "foo", + "type": "web", + "component": "web", + "span_kind": 2, + "attributes": { + "runtime-id": "%s", + "http.url": "http:\/\/localhost:8888\/foo", + "http.method": "GET", + "process_id": %d, + "_dd.p.ksr": "0.3", + "http.status_code": "200", + "php.compilation.total_time_ms": %f, + "php.memory.peak_usage_bytes": %d, + "php.memory.peak_real_usage_bytes": %d + } + }, + { + "span_id": "11788048577503494824", + "start": 100000000, + "duration": %d, + "name": "aws.apigateway", + "resource": "GET \/test", + "service": "example.com", + "type": "web", + "component": "aws-apigateway", + "attributes": { + "http.method": "GET", + "http.url": "example.com\/test", + "stage": "aws-prod", + "_dd.inferred_span": 1, + "http.status_code": "200", + "_dd.rule_psr": 0.3, + "_dd.p.ksr": "0.3" + } + } + ] } - } -] + ] +} diff --git a/tests/ext/inferred_proxy/security_headers_forwarded.phpt b/tests/ext/inferred_proxy/security_headers_forwarded.phpt index e901d01e4c4..2929f1f7858 100644 --- a/tests/ext/inferred_proxy/security_headers_forwarded.phpt +++ b/tests/ext/inferred_proxy/security_headers_forwarded.phpt @@ -22,7 +22,7 @@ DD_TRACE_DEBUG_PRNG_SEED=42 name = 'keep.root'; $root->attributes['http.status_code'] = new ChangeSamplingDuringSerialization(); DDTrace\close_span(); -foreach (dd_trace_serialize_closed_spans() as $span) { +$chunk = dd_trace_serialize_closed_spans()['chunks'][0]; +foreach ($chunk['spans'] as $span) { echo $span['name'], "\n"; if (isset($span['attributes']['_dd.span_sampling.mechanism'])) { echo 'single span: ', $span['attributes']['_dd.span_sampling.mechanism'], "\n"; } - if (isset($span['sampling_priority'])) { - echo 'trace priority: ', $span['sampling_priority'], "\n"; - } } +echo 'trace priority: ', $chunk['priority'], "\n"; ?> --EXPECT-- diff --git a/tests/ext/inherit_meta_from_parent.phpt b/tests/ext/inherit_meta_from_parent.phpt index d49fd52fe98..e4a5cb9c102 100644 --- a/tests/ext/inherit_meta_from_parent.phpt +++ b/tests/ext/inherit_meta_from_parent.phpt @@ -18,7 +18,7 @@ $span->meta["env"] = "goodenv"; \DDTrace\close_span(); -$span = dd_trace_serialize_closed_spans()[1]; +$span = dd_trace_serialize_closed_spans()['chunks'][0]['spans'][1]; var_dump([ "env" => $span["env"], "version" => $span["version"], diff --git a/tests/ext/integrations/curl/curl_multi_exec_span_limit.phpt b/tests/ext/integrations/curl/curl_multi_exec_span_limit.phpt index c6412fffec3..3d3927c6f7c 100644 --- a/tests/ext/integrations/curl/curl_multi_exec_span_limit.phpt +++ b/tests/ext/integrations/curl/curl_multi_exec_span_limit.phpt @@ -10,6 +10,7 @@ DD_TRACE_SPANS_LIMIT=20 DD_TRACE_LOG_LEVEL=error --FILE-- ', "\n"; } - dd_drupal_render_report($spans, ['Drupal\Core\Template\TwigThemeEngine::renderTemplate']); + dd_drupal_render_report($payload, ['Drupal\Core\Template\TwigThemeEngine::renderTemplate']); } ?> --EXPECT-- diff --git a/tests/ext/integrations/drupal/theme_render_dropped_nested_span.phpt b/tests/ext/integrations/drupal/theme_render_dropped_nested_span.phpt index 8676b380170..a4ddb4f1fec 100644 --- a/tests/ext/integrations/drupal/theme_render_dropped_nested_span.phpt +++ b/tests/ext/integrations/drupal/theme_render_dropped_nested_span.phpt @@ -80,7 +80,8 @@ namespace DDTrace\close_span(); - $spans = dd_trace_serialize_closed_spans(); + $payload = dd_trace_serialize_closed_spans(); + $spans = $payload['chunks'][0]['spans']; foreach ($spans as $span) { if ($span['name'] !== 'drupal.theme.render') { continue; @@ -89,7 +90,7 @@ namespace isset($span['attributes']['drupal.template.file']) ? $span['attributes']['drupal.template.file'] : '', "\n"; } - dd_drupal_render_report($spans, ['twig_render_template']); + dd_drupal_render_report($payload, ['twig_render_template']); } ?> --EXPECT-- diff --git a/tests/ext/integrations/drupal/theme_render_dropped_span.phpt b/tests/ext/integrations/drupal/theme_render_dropped_span.phpt index a2c4a53587b..37fd414a73f 100644 --- a/tests/ext/integrations/drupal/theme_render_dropped_span.phpt +++ b/tests/ext/integrations/drupal/theme_render_dropped_span.phpt @@ -79,7 +79,8 @@ namespace DDTrace\close_span(); - $spans = dd_trace_serialize_closed_spans(); + $payload = dd_trace_serialize_closed_spans(); + $spans = $payload['chunks'][0]['spans']; $names = []; foreach ($spans as $span) { $names[$span['name']] = (isset($names[$span['name']]) ? $names[$span['name']] : 0) + 1; @@ -89,7 +90,7 @@ namespace echo "span[$name] = $count\n"; } - dd_drupal_render_report($spans, ['twig_render_template']); + dd_drupal_render_report($payload, ['twig_render_template']); } ?> --EXPECT-- diff --git a/tests/ext/integrations/http_streams/distributed_tracing_http_streams.phpt b/tests/ext/integrations/http_streams/distributed_tracing_http_streams.phpt index c8267cd2e96..3b9b79143a7 100644 --- a/tests/ext/integrations/http_streams/distributed_tracing_http_streams.phpt +++ b/tests/ext/integrations/http_streams/distributed_tracing_http_streams.phpt @@ -42,7 +42,7 @@ dt_dump_headers_from_httpbin($headers, [ ]); echo "\n=== Span ===\n"; -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; $span = $spans[1]; echo "name: " . $span['name'] . "\n"; diff --git a/tests/ext/integrations/http_streams/distributed_tracing_http_streams_disabled.phpt b/tests/ext/integrations/http_streams/distributed_tracing_http_streams_disabled.phpt index 0a0259b7803..e71f7a23d43 100644 --- a/tests/ext/integrations/http_streams/distributed_tracing_http_streams_disabled.phpt +++ b/tests/ext/integrations/http_streams/distributed_tracing_http_streams_disabled.phpt @@ -35,7 +35,7 @@ dt_dump_headers_from_httpbin($headers, [ 'tracestate', ]); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; var_dump(count($spans) === 1); echo 'Done.' . PHP_EOL; 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 01943f8d28c..8734d071e8e 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 @@ -25,20 +25,17 @@ function makeRequest() { \DDTrace\close_span(); \DDTrace\close_span(); - $closedSpans = dd_trace_serialize_closed_spans(); - - $rootMeta = $closedSpans[0]['attributes']; - echo $rootMeta['_dd.git.repository_url'] . PHP_EOL; - echo $rootMeta['_dd.git.commit.sha'] . PHP_EOL; + $payloadAttributes = dd_trace_serialize_closed_spans()['attributes']; + echo $payloadAttributes['_dd.git.repository_url'] . PHP_EOL; + echo $payloadAttributes['_dd.git.commit.sha'] . PHP_EOL; \DDTrace\start_span(); \DDTrace\close_span(); - $closedRoot = dd_trace_serialize_closed_spans(); - $rootMeta2 = $closedRoot[0]['attributes']; + $payloadAttributes2 = dd_trace_serialize_closed_spans()['attributes']; - echo $rootMeta2['_dd.git.repository_url'] . PHP_EOL; - echo $rootMeta2['_dd.git.commit.sha'] . PHP_EOL; + echo $payloadAttributes2['_dd.git.repository_url'] . PHP_EOL; + echo $payloadAttributes2['_dd.git.commit.sha'] . PHP_EOL; } makeRequest(); 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 3a41aa29f6b..fb1785e933f 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 @@ -11,8 +11,6 @@ if (getenv('PHP_PEAR_RUNTESTS') === '1') die("skip: The pecl run-tests path is n ?> --FILE-- --EXPECTF-- -array(7) { - ["runtime-id"]=> +array(3) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> string(%d) "%s" - ["process_id"]=> - float(%f) - ["_dd.agent_psr"]=> - float(1) ["_dd.git.repository_url"]=> string(32) "https://github.com/user/repo_new" - ["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"]=> +array(3) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> string(%d) "%s" - ["process_id"]=> - float(%f) - ["_dd.agent_psr"]=> - float(1) ["_dd.git.repository_url"]=> string(32) "https://github.com/user/repo_new" - ["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"]=> +array(3) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> string(%d) "%s" - ["process_id"]=> - float(%f) - ["_dd.agent_psr"]=> - float(1) ["_dd.git.repository_url"]=> string(32) "https://github.com/user/repo_new" - ["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"]=> +array(3) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> string(%d) "%s" - ["process_id"]=> - float(%f) - ["_dd.agent_psr"]=> - float(1) ["_dd.git.repository_url"]=> string(32) "https://github.com/user/repo_new" - ["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 5b8534a25c3..4578d12a318 100644 --- a/tests/ext/integrations/source_code/commit_sha_env_var.phpt +++ b/tests/ext/integrations/source_code/commit_sha_env_var.phpt @@ -7,7 +7,6 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 --FILE-- --EXPECTF-- array(2) { - [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" - ["span_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(22) "commit_sha_env_var.php" - ["resource"]=> - string(22) "commit_sha_env_var.php" - ["service"]=> - string(22) "commit_sha_env_var.php" - ["type"]=> - string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) - ["attributes"]=> - array(7) { - ["runtime-id"]=> + ["attributes"]=> + array(3) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> + string(%d) "%s" + ["_dd.git.commit.sha"]=> + string(6) "123456" + } + ["chunks"]=> + array(1) { + [0]=> + array(4) { + ["trace_id"]=> string(%d) "%s" - ["process_id"]=> - float(%f) - ["_dd.agent_psr"]=> - float(1) - ["_dd.git.commit.sha"]=> - string(6) "123456" - ["php.compilation.total_time_ms"]=> - float(%f) - ["php.memory.peak_usage_bytes"]=> - float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) + ["priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["spans"]=> + array(2) { + [0]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(22) "commit_sha_env_var.php" + ["resource"]=> + string(22) "commit_sha_env_var.php" + ["service"]=> + string(22) "commit_sha_env_var.php" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(6) { + ["runtime-id"]=> + string(%d) "%s" + ["process_id"]=> + int(%d) + ["_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) + } + } + [1]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["parent_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(0) "" + ["resource"]=> + string(0) "" + ["service"]=> + string(22) "commit_sha_env_var.php" + ["type"]=> + string(3) "cli" + } + } } } - [1]=> - array(9) { - ["trace_id"]=> - string(%d) "%d" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(0) "" - ["resource"]=> - string(0) "" - ["service"]=> - string(22) "commit_sha_env_var.php" - ["type"]=> - string(3) "cli" - } } 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 ea9e02e4c07..20f8c1015a9 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 @@ -8,7 +8,6 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 --FILE-- --EXPECTF-- array(2) { - [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" - ["span_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(35) "git_metadata_injection_from_env.php" - ["resource"]=> - string(35) "git_metadata_injection_from_env.php" - ["service"]=> - string(35) "git_metadata_injection_from_env.php" - ["type"]=> - string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) - ["attributes"]=> - array(8) { - ["runtime-id"]=> + ["attributes"]=> + array(4) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> + string(%d) "%s" + ["_dd.git.commit.sha"]=> + string(6) "123456" + ["_dd.git.repository_url"]=> + string(24) "github.com/user/env_repo" + } + ["chunks"]=> + array(1) { + [0]=> + array(4) { + ["trace_id"]=> string(%d) "%s" - ["process_id"]=> - float(%f) - ["_dd.agent_psr"]=> - float(1) - ["_dd.git.commit.sha"]=> - string(6) "123456" - ["_dd.git.repository_url"]=> - string(24) "github.com/user/env_repo" - ["php.compilation.total_time_ms"]=> - float(%f) - ["php.memory.peak_usage_bytes"]=> - float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) + ["priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["spans"]=> + array(2) { + [0]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(35) "git_metadata_injection_from_env.php" + ["resource"]=> + string(35) "git_metadata_injection_from_env.php" + ["service"]=> + string(35) "git_metadata_injection_from_env.php" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(6) { + ["runtime-id"]=> + string(%d) "%s" + ["process_id"]=> + int(%d) + ["_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) + } + } + [1]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["parent_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(0) "" + ["resource"]=> + string(0) "" + ["service"]=> + string(35) "git_metadata_injection_from_env.php" + ["type"]=> + string(3) "cli" + } + } } } - [1]=> - array(9) { - ["trace_id"]=> - string(%d) "%d" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(0) "" - ["resource"]=> - string(0) "" - ["service"]=> - string(35) "git_metadata_injection_from_env.php" - ["type"]=> - string(3) "cli" - } } 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 d5057ea5445..6803a5fa68f 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 @@ -7,7 +7,6 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 --FILE-- --EXPECTF-- array(2) { - [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" - ["span_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(43) "git_metadata_injection_from_global_tags.php" - ["resource"]=> - string(43) "git_metadata_injection_from_global_tags.php" - ["service"]=> - string(43) "git_metadata_injection_from_global_tags.php" - ["type"]=> - string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) - ["attributes"]=> - array(10) { - ["runtime-id"]=> - string(%d) "%s" - ["process_id"]=> - float(%f) - ["git.commit.sha"]=> - string(6) "123456" - ["git.repository_url"]=> - string(24) "github.com/user/env_repo" - ["_dd.agent_psr"]=> - float(1) - ["_dd.git.commit.sha"]=> - string(6) "123456" - ["_dd.git.repository_url"]=> - string(24) "github.com/user/env_repo" - ["php.compilation.total_time_ms"]=> - float(%f) - ["php.memory.peak_usage_bytes"]=> - float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) - } + ["attributes"]=> + array(4) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> + string(%d) "%s" + ["_dd.git.commit.sha"]=> + string(6) "123456" + ["_dd.git.repository_url"]=> + string(24) "github.com/user/env_repo" } - [1]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(0) "" - ["resource"]=> - string(0) "" - ["service"]=> - string(43) "git_metadata_injection_from_global_tags.php" - ["type"]=> - string(3) "cli" - ["attributes"]=> - array(2) { - ["git.commit.sha"]=> - string(6) "123456" - ["git.repository_url"]=> - string(24) "github.com/user/env_repo" + ["chunks"]=> + array(1) { + [0]=> + array(4) { + ["trace_id"]=> + string(%d) "%s" + ["priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["spans"]=> + array(2) { + [0]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(43) "git_metadata_injection_from_global_tags.php" + ["resource"]=> + string(43) "git_metadata_injection_from_global_tags.php" + ["service"]=> + string(43) "git_metadata_injection_from_global_tags.php" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(8) { + ["runtime-id"]=> + string(%d) "%s" + ["process_id"]=> + int(%d) + ["git.commit.sha"]=> + string(6) "123456" + ["git.repository_url"]=> + string(24) "github.com/user/env_repo" + ["_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) + } + } + [1]=> + array(9) { + ["span_id"]=> + string(%d) "%d" + ["parent_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(0) "" + ["resource"]=> + string(0) "" + ["service"]=> + string(43) "git_metadata_injection_from_global_tags.php" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(2) { + ["git.commit.sha"]=> + string(6) "123456" + ["git.repository_url"]=> + string(24) "github.com/user/env_repo" + } + } + } } } } 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 7357f811ffb..6ea329a0ff3 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 @@ -8,7 +8,6 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 --FILE-- --EXPECTF-- array(2) { - [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" - ["span_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(54) "git_metadata_injection_remove_credentials_from_env.php" - ["resource"]=> - string(54) "git_metadata_injection_remove_credentials_from_env.php" - ["service"]=> - string(54) "git_metadata_injection_remove_credentials_from_env.php" - ["type"]=> - string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) - ["attributes"]=> - array(8) { - ["runtime-id"]=> + ["attributes"]=> + array(4) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> + string(%d) "%s" + ["_dd.git.commit.sha"]=> + string(6) "123456" + ["_dd.git.repository_url"]=> + string(32) "https://github.com/user/repo_new" + } + ["chunks"]=> + array(1) { + [0]=> + array(4) { + ["trace_id"]=> string(%d) "%s" - ["process_id"]=> - float(%f) - ["_dd.agent_psr"]=> - float(1) - ["_dd.git.commit.sha"]=> - string(6) "123456" - ["_dd.git.repository_url"]=> - string(32) "https://github.com/user/repo_new" - ["php.compilation.total_time_ms"]=> - float(%f) - ["php.memory.peak_usage_bytes"]=> - float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) + ["priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["spans"]=> + array(2) { + [0]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(54) "git_metadata_injection_remove_credentials_from_env.php" + ["resource"]=> + string(54) "git_metadata_injection_remove_credentials_from_env.php" + ["service"]=> + string(54) "git_metadata_injection_remove_credentials_from_env.php" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(6) { + ["runtime-id"]=> + string(%d) "%s" + ["process_id"]=> + int(%d) + ["_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) + } + } + [1]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["parent_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(0) "" + ["resource"]=> + string(0) "" + ["service"]=> + string(54) "git_metadata_injection_remove_credentials_from_env.php" + ["type"]=> + string(3) "cli" + } + } } } - [1]=> - array(9) { - ["trace_id"]=> - string(%d) "%d" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(0) "" - ["resource"]=> - string(0) "" - ["service"]=> - string(54) "git_metadata_injection_remove_credentials_from_env.php" - ["type"]=> - string(3) "cli" - } } 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 638bcf947aa..67252fde3d2 100644 --- a/tests/ext/integrations/source_code/repository_url_env_var.phpt +++ b/tests/ext/integrations/source_code/repository_url_env_var.phpt @@ -7,7 +7,6 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 --FILE-- --EXPECTF-- array(2) { - [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" - ["span_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(26) "repository_url_env_var.php" - ["resource"]=> - string(26) "repository_url_env_var.php" - ["service"]=> - string(26) "repository_url_env_var.php" - ["type"]=> - string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) - ["attributes"]=> - array(7) { - ["runtime-id"]=> + ["attributes"]=> + array(3) { + ["_dd.sdk.otlp_export"]=> + string(5) "false" + ["_dd.tags.process"]=> + string(%d) "%s" + ["_dd.git.repository_url"]=> + string(24) "github.com/user/env_repo" + } + ["chunks"]=> + array(1) { + [0]=> + array(4) { + ["trace_id"]=> string(%d) "%s" - ["process_id"]=> - float(%f) - ["_dd.agent_psr"]=> - float(1) - ["_dd.git.repository_url"]=> - string(24) "github.com/user/env_repo" - ["php.compilation.total_time_ms"]=> - float(%f) - ["php.memory.peak_usage_bytes"]=> - float(%f) - ["php.memory.peak_real_usage_bytes"]=> - float(%f) + ["priority"]=> + int(1) + ["sampling_mechanism"]=> + int(0) + ["spans"]=> + array(2) { + [0]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(26) "repository_url_env_var.php" + ["resource"]=> + string(26) "repository_url_env_var.php" + ["service"]=> + string(26) "repository_url_env_var.php" + ["type"]=> + string(3) "cli" + ["attributes"]=> + array(6) { + ["runtime-id"]=> + string(%d) "%s" + ["process_id"]=> + int(%d) + ["_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) + } + } + [1]=> + array(8) { + ["span_id"]=> + string(%d) "%d" + ["parent_id"]=> + string(%d) "%d" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(0) "" + ["resource"]=> + string(0) "" + ["service"]=> + string(26) "repository_url_env_var.php" + ["type"]=> + string(3) "cli" + } + } } } - [1]=> - array(9) { - ["trace_id"]=> - string(%d) "%d" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(0) "" - ["resource"]=> - string(0) "" - ["service"]=> - string(26) "repository_url_env_var.php" - ["type"]=> - string(3) "cli" - } } diff --git a/tests/ext/ip_collection_01.phpt b/tests/ext/ip_collection_01.phpt index 80efa5465c4..9442fbe6ae3 100644 --- a/tests/ext/ip_collection_01.phpt +++ b/tests/ext/ip_collection_01.phpt @@ -7,7 +7,7 @@ REMOTE_ADDR=127.0.0.1 --EXPECTF-- diff --git a/tests/ext/ip_collection_02.phpt b/tests/ext/ip_collection_02.phpt index 0ad7dea2256..6fcf0806f06 100644 --- a/tests/ext/ip_collection_02.phpt +++ b/tests/ext/ip_collection_02.phpt @@ -7,7 +7,7 @@ REMOTE_ADDR=127.0.0.1 --EXPECTF-- diff --git a/tests/ext/ip_collection_03.phpt b/tests/ext/ip_collection_03.phpt index 22462f9fd41..1b0563a3c38 100644 --- a/tests/ext/ip_collection_03.phpt +++ b/tests/ext/ip_collection_03.phpt @@ -9,7 +9,7 @@ DD_TRACE_CLIENT_IP_ENABLED=true --EXPECTF-- diff --git a/tests/ext/ip_collection_04.phpt b/tests/ext/ip_collection_04.phpt index 699d0bd462f..c9115b9f8a4 100644 --- a/tests/ext/ip_collection_04.phpt +++ b/tests/ext/ip_collection_04.phpt @@ -9,7 +9,7 @@ datadog.trace.client_ip_header_disabled=true --EXPECTF-- diff --git a/tests/ext/ip_collection_05.phpt b/tests/ext/ip_collection_05.phpt index 699d0bd462f..c9115b9f8a4 100644 --- a/tests/ext/ip_collection_05.phpt +++ b/tests/ext/ip_collection_05.phpt @@ -9,7 +9,7 @@ datadog.trace.client_ip_header_disabled=true --EXPECTF-- diff --git a/tests/ext/legacy_tracer_distributed_context.phpt b/tests/ext/legacy_tracer_distributed_context.phpt new file mode 100644 index 00000000000..6a57a67ffbc --- /dev/null +++ b/tests/ext/legacy_tracer_distributed_context.phpt @@ -0,0 +1,73 @@ +--TEST-- +DDTrace\Tracer reads the distributed context with and without an active span (DD_TRACE_GENERATE_ROOT_SPAN=0) +--SKIPIF-- + +--ENV-- +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--INI-- +datadog.trace.sources_path={PWD}/../../../../src +datadog.autoload_no_compile=1 +--FILE-- +setAccessible(true); + } + return $prop->getValue($tracer); +} + +function check(\DDTrace\Tracer $tracer) +{ + $expected = @\DDTrace\current_context(); + $context = root_context($tracer); + var_dump($context->getTraceId() === $expected["trace_id"]); + var_dump($context->getSpanId() === $expected["distributed_tracing_parent_id"]); + var_dump($context->origin === $expected["distributed_tracing_origin"]); + echo $context->getTraceId(), " ", $context->getSpanId(), " ", $context->origin, "\n"; +} + +// 128-bit trace id (2^64 + 1), no active span: only the distributed context globals are set +DDTrace\set_distributed_tracing_context("18446744073709551617", "42", "synthetics"); +var_dump(DDTrace\active_span()); +$tracer = new \DDTrace\Tracer(); +check($tracer); +var_dump(DDTrace\active_span()); + +// The first userland span continues the distributed trace +$scope = $tracer->startActiveSpan("op"); +$span = $scope->getSpan(); +var_dump($span->getTraceId() === @\DDTrace\trace_id()); +echo $span->getTraceId(), " ", DDTrace\root_span()->parentId, " ", DDTrace\root_span()->origin, "\n"; + +// With an active span, the context is read from the root span +$tracer = new \DDTrace\Tracer(); +check($tracer); + +// The scope manager maps internal spans onto userland scopes with the decimal trace id +$internal = DDTrace\start_span(); +$active = $tracer->getScopeManager()->getActive(); +var_dump($active->getSpan()->getSpanId() === $internal->id); +var_dump($active->getSpan()->getTraceId() === @\DDTrace\trace_id()); +DDTrace\close_span(); +$scope->close(); +?> +--EXPECT-- +NULL +bool(true) +bool(true) +bool(true) +18446744073709551617 42 synthetics +NULL +bool(true) +18446744073709551617 42 synthetics +bool(true) +bool(true) +bool(true) +18446744073709551617 42 synthetics +bool(true) +bool(true) diff --git a/tests/ext/limiter/002-limiter-reached.phpt b/tests/ext/limiter/002-limiter-reached.phpt index aa95978352f..49621a408f6 100644 --- a/tests/ext/limiter/002-limiter-reached.phpt +++ b/tests/ext/limiter/002-limiter-reached.phpt @@ -9,7 +9,7 @@ DD_TRACE_RATE_LIMIT=10 DD_TRACE_SAMPLE_RATE=1 --FILE-- --EXPECT-- int(21) diff --git a/tests/ext/meta_struct.phpt b/tests/ext/meta_struct.phpt index fc541516e6d..cc274d28dbf 100644 --- a/tests/ext/meta_struct.phpt +++ b/tests/ext/meta_struct.phpt @@ -18,7 +18,7 @@ $span->meta_struct["foo"] = "bar"; $span->meta_struct["john"] = ["Doe"]; DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; foreach ($spans as $span) { diff --git a/tests/ext/nested_exceptions.phpt b/tests/ext/nested_exceptions.phpt index e8d11dcddac..e4b1715717d 100644 --- a/tests/ext/nested_exceptions.phpt +++ b/tests/ext/nested_exceptions.phpt @@ -18,11 +18,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(10) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -40,7 +36,7 @@ array(1) { ["type"]=> string(3) "cli" ["error"]=> - int(1) + bool(true) ["attributes"]=> array(3) { ["error.message"]=> diff --git a/tests/ext/otel_http_response_status_code_remapping.phpt b/tests/ext/otel_http_response_status_code_remapping.phpt deleted file mode 100644 index f571b7c9905..00000000000 --- a/tests/ext/otel_http_response_status_code_remapping.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---TEST-- -Remap http.response.status_code to http.status_code - OTel HTTP Semantic Convention >= 1.21.0 ---FILE-- -metrics['http.response.status_code'] = "300"; -\DDTrace\close_span(); - -var_dump(dd_clean_spans()); - -?> ---EXPECTF-- -array(1) { - [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(0) "" - ["resource"]=> - string(0) "" - ["service"]=> - string(44) "otel_http_response_status_code_remapping.php" - ["type"]=> - string(3) "cli" - ["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 deleted file mode 100644 index b8f5f8f3e21..00000000000 --- a/tests/ext/otel_http_response_status_code_remapping_precedence.phpt +++ /dev/null @@ -1,45 +0,0 @@ ---TEST-- -http.response.status_code takes precedence over http.status_code ---FILE-- -metrics['http.response.status_code'] = 300; -$span->meta['http.status_code'] = 302; -\DDTrace\close_span(); - -var_dump(dd_clean_spans()); - -?> ---EXPECTF-- -array(1) { - [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(0) "" - ["resource"]=> - string(0) "" - ["service"]=> - string(55) "otel_http_response_status_code_remapping_precedence.php" - ["type"]=> - string(3) "cli" - ["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 deleted file mode 100644 index b6646d4695a..00000000000 --- a/tests/ext/otel_http_status_code_remapping.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---TEST-- -Remap http.status_code metric to http.status_code meta - OTel HTTP Semantic Convention < 1.21.0 ---FILE-- -metrics['http.status_code'] = "200"; -\DDTrace\close_span(); - -var_dump(dd_clean_spans()); - -?> ---EXPECTF-- -array(1) { - [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" - ["span_id"]=> - string(%d) "%d" - ["parent_id"]=> - string(%d) "%d" - ["start"]=> - int(%d) - ["duration"]=> - int(%d) - ["name"]=> - string(0) "" - ["resource"]=> - string(0) "" - ["service"]=> - string(35) "otel_http_status_code_remapping.php" - ["type"]=> - string(3) "cli" - ["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 2650487d0bc..da796b4cc37 100644 --- a/tests/ext/pcntl/pcntl_fork_long_running_autoflush.phpt +++ b/tests/ext/pcntl/pcntl_fork_long_running_autoflush.phpt @@ -33,7 +33,7 @@ function long_running_entry_point() // Main } else if ($forkPid === 0) { // Child - if (ddtrace_config_trace_enabled()) { + if (\dd_trace_env_config('DD_TRACE_ENABLED')) { echo "child is enabled\n"; } call_httpbin(); @@ -44,7 +44,7 @@ function long_running_entry_point() } call_httpbin(); pcntl_waitpid($forkPid, $status); - if (ddtrace_config_trace_enabled()) { + if (\dd_trace_env_config('DD_TRACE_ENABLED')) { echo "parent is enabled\n"; } } diff --git a/tests/ext/peer_service_disabled_default.phpt b/tests/ext/peer_service_disabled_default.phpt index 8bab4d83118..565bd50fff9 100644 --- a/tests/ext/peer_service_disabled_default.phpt +++ b/tests/ext/peer_service_disabled_default.phpt @@ -23,11 +23,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> diff --git a/tests/ext/peer_service_honor_user_value.phpt b/tests/ext/peer_service_honor_user_value.phpt index f1ef0d76015..a221b913d6b 100644 --- a/tests/ext/peer_service_honor_user_value.phpt +++ b/tests/ext/peer_service_honor_user_value.phpt @@ -29,11 +29,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -61,9 +57,7 @@ array(2) { } } [1]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> diff --git a/tests/ext/peer_service_remapping.phpt b/tests/ext/peer_service_remapping.phpt index 9d7483846ca..b0beda75cd7 100644 --- a/tests/ext/peer_service_remapping.phpt +++ b/tests/ext/peer_service_remapping.phpt @@ -34,11 +34,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -72,9 +68,7 @@ array(2) { } } [1]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> 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 08fb6c0837d..3784b657c6c 100644 --- a/tests/ext/peer_service_sources_not_serialized_when_set.phpt +++ b/tests/ext/peer_service_sources_not_serialized_when_set.phpt @@ -24,11 +24,7 @@ var_dump(dd_clean_spans()); HOOK METHOD arg array(1) { [0]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> 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 4024a2bc699..ba1d558a150 100644 --- a/tests/ext/peer_service_sources_not_serialized_when_unset.phpt +++ b/tests/ext/peer_service_sources_not_serialized_when_unset.phpt @@ -23,11 +23,7 @@ var_dump(dd_clean_spans()); HOOK METHOD arg array(1) { [0]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> diff --git a/tests/ext/peer_service_use_first_available_tag.phpt b/tests/ext/peer_service_use_first_available_tag.phpt index def02e5d2e3..652d2960080 100644 --- a/tests/ext/peer_service_use_first_available_tag.phpt +++ b/tests/ext/peer_service_use_first_available_tag.phpt @@ -36,11 +36,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(3) { [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -68,9 +64,7 @@ array(3) { } } [1]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -100,9 +94,7 @@ array(3) { } } [2]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> diff --git a/tests/ext/peer_service_wrong_values.phpt b/tests/ext/peer_service_wrong_values.phpt index 840373fd8e5..64aa8f42af1 100644 --- a/tests/ext/peer_service_wrong_values.phpt +++ b/tests/ext/peer_service_wrong_values.phpt @@ -29,11 +29,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(2) { [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -61,9 +57,7 @@ array(2) { } } [1]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> diff --git a/tests/ext/priority_sampling/serialization-chunk.phpt b/tests/ext/priority_sampling/serialization-chunk.phpt index 6778267391f..7a956c32d1c 100644 --- a/tests/ext/priority_sampling/serialization-chunk.phpt +++ b/tests/ext/priority_sampling/serialization-chunk.phpt @@ -8,6 +8,7 @@ DD_SPAN_SAMPLING_RULES=[{"name":"keep*","sample_rate":1}] DD_TRACE_STATS_COMPUTATION_ENABLED=0 --FILE-- name = 'root'; -// Serialization converts this attribute to a string tag and releases the old value. -$root->attributes['http.status_code'] = new ChangeSamplingDuringSerialization(); +// With a propagated priority the sampling decision keeps _dd.p.dm: serialization drops it from the root span, +// releasing this object mid-chunk. +DDTrace\consume_distributed_tracing_headers(['x-datadog-trace-id' => '1', 'x-datadog-parent-id' => '2', 'x-datadog-sampling-priority' => '0']); +$root->attributes['_dd.p.dm'] = new ChangeSamplingDuringSerialization(); DDTrace\start_span()->name = 'keep.child'; DDTrace\close_span(); @@ -30,17 +33,18 @@ DDTrace\start_span()->name = 'unmatched'; DDTrace\close_span(); DDTrace\close_span(); -foreach (dd_trace_serialize_closed_spans() as $span) { +foreach (dd_clean_spans() as $span) { echo $span['name'], ': ', isset($span['attributes']['_dd.span_sampling.mechanism']) ? 'single span' : 'trace', "\n"; } // Subsequent chunks must observe the new configuration. DDTrace\start_span()->name = 'keep.next'; DDTrace\close_span(); -$span = dd_trace_serialize_closed_spans()[0]; +$chunk = dd_trace_serialize_closed_spans()['chunks'][0]; +$span = $chunk['spans'][0]; echo $span['name'], ': ', isset($span['attributes']['_dd.span_sampling.mechanism']) ? 'single span' : 'trace', "\n"; -var_dump($span['sampling_priority']); -var_dump(dd_trace_serialize_closed_spans()); +var_dump($chunk['priority']); +var_dump(dd_trace_serialize_closed_spans()['chunks']); ?> --EXPECT-- diff --git a/tests/ext/process_tags.phpt b/tests/ext/process_tags.phpt index 23be23085a5..534d8d11268 100644 --- a/tests/ext/process_tags.phpt +++ b/tests/ext/process_tags.phpt @@ -1,5 +1,5 @@ --TEST-- -Process tags are added to root span when enabled +Process tags are added to the payload when enabled --ENV-- DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED=1 DD_TRACE_GENERATE_ROOT_SPAN=0 @@ -17,12 +17,12 @@ $child_span->service = 'test_service'; \DDTrace\close_span(); \DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); +$payload = dd_trace_serialize_closed_spans(); // Check if process tags are present -if (isset($spans[0]['attributes']['_dd.tags.process'])) { - $processTags = $spans[0]['attributes']['_dd.tags.process']; - echo "Process tags present in root span: YES\n"; +if (isset($payload['attributes']['_dd.tags.process'])) { + $processTags = $payload['attributes']['_dd.tags.process']; + echo "Process tags present in payload: YES\n"; echo "Process tags: $processTags\n"; // Verify format: comma-separated key:value pairs @@ -36,17 +36,16 @@ if (isset($spans[0]['attributes']['_dd.tags.process'])) { sort($sortedKeys); echo "Keys sorted: " . ($keys === $sortedKeys ? 'YES' : 'NO') . "\n"; } else { - echo "Process tags present in root span: NO\n"; + echo "Process tags present in payload: NO\n"; } -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"; +foreach ($payload['chunks'][0]['spans'] as $span) { + echo "Process tags present in span: ", isset($span['attributes']['_dd.tags.process']) ? 'YES' : 'NO', "\n"; } ?> --EXPECTF-- -Process tags present in root span: YES +Process tags present in payload: YES Process tags: entrypoint.basedir:ext,entrypoint.name:process_tags,entrypoint.type:script,entrypoint.workdir:%s,runtime.sapi:cli Keys sorted: YES -Process tags present in child span: NO +Process tags present in span: NO +Process tags present in span: NO diff --git a/tests/ext/referrer_extraction_01.phpt b/tests/ext/referrer_extraction_01.phpt index ab6c26a1c5f..ee8bf42d3ca 100644 --- a/tests/ext/referrer_extraction_01.phpt +++ b/tests/ext/referrer_extraction_01.phpt @@ -14,7 +14,7 @@ foo=bar --EXPECT-- diff --git a/tests/ext/referrer_extraction_02.phpt b/tests/ext/referrer_extraction_02.phpt index eb70044f44b..e7b31ac4db1 100644 --- a/tests/ext/referrer_extraction_02.phpt +++ b/tests/ext/referrer_extraction_02.phpt @@ -14,7 +14,7 @@ foo=bar --EXPECT-- diff --git a/tests/ext/referrer_extraction_03.phpt b/tests/ext/referrer_extraction_03.phpt index a7cbf5c5c18..dde5d47b0c2 100644 --- a/tests/ext/referrer_extraction_03.phpt +++ b/tests/ext/referrer_extraction_03.phpt @@ -14,7 +14,7 @@ foo=bar --EXPECT-- diff --git a/tests/ext/referrer_extraction_04.phpt b/tests/ext/referrer_extraction_04.phpt index f14c33a5003..70ce6b157f8 100644 --- a/tests/ext/referrer_extraction_04.phpt +++ b/tests/ext/referrer_extraction_04.phpt @@ -14,7 +14,7 @@ foo=bar --EXPECT-- diff --git a/tests/ext/referrer_extraction_05.phpt b/tests/ext/referrer_extraction_05.phpt index e2569f33b5f..76f77ea657e 100644 --- a/tests/ext/referrer_extraction_05.phpt +++ b/tests/ext/referrer_extraction_05.phpt @@ -14,7 +14,7 @@ foo=bar --EXPECT-- diff --git a/tests/ext/report_hostname_on_payload.phpt b/tests/ext/report_hostname_on_payload.phpt new file mode 100644 index 00000000000..4fa1dae5929 --- /dev/null +++ b/tests/ext/report_hostname_on_payload.phpt @@ -0,0 +1,24 @@ +--TEST-- +DD_TRACE_REPORT_HOSTNAME reports the hostname on the payload, not on spans +--ENV-- +DD_TRACE_REPORT_HOSTNAME=1 +DD_HOSTNAME=my-host +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +--FILE-- + +--EXPECT-- +string(7) "my-host" +bool(false) +bool(true) diff --git a/tests/ext/request-replayer/analytics_event_v04.phpt b/tests/ext/request-replayer/analytics_event_v04.phpt deleted file mode 100644 index 9196d71fdb1..00000000000 --- a/tests/ext/request-replayer/analytics_event_v04.phpt +++ /dev/null @@ -1,57 +0,0 @@ ---TEST-- -analytics.event maps to the _dd1.sr.eausr metric on the v0.4 wire ---SKIPIF-- - [ - 'method' => 'PUT', - 'header' => ["Content-Type: application/json", "X-Datadog-Test-Session-Token: analytics_event_v04"], - 'content' => json_encode(["endpoints" => ["/v0.4/traces", "/v0.6/stats", "/v0.7/config"], "client_drop_p0s" => false, "version" => "7.66.0"]), -]]); -if (@file_get_contents("http://request-replayer/set-agent-info", false, $ctx) === false) { - die("skip: request-replayer not reachable"); -} -?> ---ENV-- -DD_TRACE_LOG_LEVEL=error,startup=off -DD_AGENT_HOST=request-replayer -DD_TRACE_AGENT_PORT=80 -DD_TRACE_AGENT_FLUSH_INTERVAL=333 -DD_TRACE_GENERATE_ROOT_SPAN=0 -DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 -DD_TRACE_SIDECAR_TRACE_SENDER=0 ---INI-- -datadog.trace.agent_test_session_token=analytics_event_v04 ---FILE-- -clearDumpedData(); - -dd_trace_internal_fn('await_agent_info'); - -$s = \DDTrace\start_span(); -$s->name = "root"; -$s->meta["analytics.event"] = "true"; -$c = \DDTrace\start_span(); -$c->name = "child"; -$c->attributes["analytics.event"] = 0; -\DDTrace\close_span(); -\DDTrace\close_span(); -dd_trace_internal_fn("synchronous_flush"); - -$req = $rr->waitForRequest(function ($r) { return strpos($r["uri"], "traces") !== false; }); -echo "uri=" . $req["uri"] . "\n"; -$spans = json_decode($req["body"], true)[0]; -usort($spans, function ($a, $b) { return strcmp($a["name"], $b["name"]); }); -foreach ($spans as $span) { - echo $span["name"], ": eausr=", var_export($span["metrics"]["_dd1.sr.eausr"] ?? null, true), - " analytics.event=", isset($span["meta"]["analytics.event"]) || isset($span["metrics"]["analytics.event"]) ? "kept" : "removed", "\n"; -} -?> ---EXPECT-- -uri=/v0.4/traces -child: eausr=0 analytics.event=removed -root: eausr=1 analytics.event=removed 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 a4d0c5e2dca..b5c2f94e96d 100644 --- a/tests/ext/request-replayer/dd_trace_exception_span_event.phpt +++ b/tests/ext/request-replayer/dd_trace_exception_span_event.phpt @@ -1,7 +1,10 @@ --TEST-- DDTrace\ExceptionSpanEvent serialization with overridden attributes --SKIPIF-- - + --ENV-- DD_AGENT_HOST=request-replayer DD_TRACE_AGENT_PORT=80 @@ -47,36 +50,17 @@ try { $replay = $rr->waitForDataAndReplay(); $root = json_decode($replay["body"], true); -$spans = $root["chunks"][0]["spans"] ?? $root[0]; -$span = $spans[0]; +$span = $root[0][0]; -// This test pins the in-process sender (v0.4-only): events are legacy `events` meta JSON, no -// `span_events` field. Handle both shapes anyway; ddAnyValueToPhp() unwraps the v1 AnyValue form. -function ddAnyValueToPhp($v) { - if (!is_array($v) || !array_key_exists('type', $v)) { - return $v; // already a plain value (legacy `events` meta JSON) - } - switch ($v['type']) { - case 0: return $v['string_value']; - case 1: return $v['bool_value']; - case 2: return $v['int_value']; - case 3: return $v['double_value']; - case 4: return array_map('ddAnyValueToPhp', $v['array_value']['values']); - default: return $v; - } -} -if (isset($span['span_events'])) { - $event = $span['span_events'][0]; -} else { - $event = json_decode($span['meta']['events'], true)[0]; -} +// The in-process sender (v0.4-only) writes span events as legacy `events` meta JSON. +$event = json_decode($span['meta']['events'], true)[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(ddAnyValueToPhp($attrs['exception.message'])); -var_dump(ddAnyValueToPhp($attrs['exception.type'])); -var_dump(ddAnyValueToPhp($attrs['custom.attribute'])); -var_dump(ddAnyValueToPhp($attrs['exception.stacktrace'])); +var_dump($attrs['exception.message']); +var_dump($attrs['exception.type']); +var_dump($attrs['custom.attribute']); +var_dump($attrs['exception.stacktrace']); ?> --EXPECTF-- Caught exception: Exception in method diff --git a/tests/ext/request-replayer/dd_trace_span_event.phpt b/tests/ext/request-replayer/dd_trace_span_event.phpt index 0e9c1a62243..77cd1f9efbd 100644 --- a/tests/ext/request-replayer/dd_trace_span_event.phpt +++ b/tests/ext/request-replayer/dd_trace_span_event.phpt @@ -1,7 +1,10 @@ --TEST-- DDTrace\SpanEvent serialization with attributes --SKIPIF-- - + --ENV-- DD_AGENT_HOST=request-replayer DD_TRACE_AGENT_PORT=80 @@ -40,33 +43,14 @@ $test = new TestClass(); $test->testMethod(); $replay = $rr->waitForDataAndReplay(); $root = json_decode($replay["body"], true); -$spans = $root["chunks"][0]["spans"] ?? $root[0]; -$span = $spans[0]; -// This test pins the in-process sender (v0.4-only): events are legacy `events` meta JSON. Handle -// the v1 AnyValue shape too; ddAnyValueToPhp() unwraps it to the same plain PHP value. -function ddAnyValueToPhp($v) { - if (!is_array($v) || !array_key_exists('type', $v)) { - return $v; // already a plain value (legacy `events` meta JSON) - } - switch ($v['type']) { - case 0: return $v['string_value']; - case 1: return $v['bool_value']; - case 2: return $v['int_value']; - case 3: return $v['double_value']; - case 4: return array_map('ddAnyValueToPhp', $v['array_value']['values']); - default: return $v; - } -} -if (isset($span['span_events'])) { - $event = $span['span_events'][0]; -} else { - $event = json_decode($span['meta']['events'], true)[0]; -} +$span = $root[0][0]; +// The in-process sender (v0.4-only) writes span events as legacy `events` meta JSON. +$event = json_decode($span['meta']['events'], true)[0]; $attrs = $event['attributes']; var_dump($event['name'], $event['time_unix_nano']); -var_dump(ddAnyValueToPhp($attrs['arg1'])); -var_dump(ddAnyValueToPhp($attrs['int_array'])); -var_dump(ddAnyValueToPhp($attrs['string_array'])); +var_dump($attrs['arg1']); +var_dump($attrs['int_array']); +var_dump($attrs['string_array']); ?> --EXPECT-- In testMethod diff --git a/tests/ext/request-replayer/dd_trace_span_link_with_exception.phpt b/tests/ext/request-replayer/dd_trace_span_link_with_exception.phpt index 9795c149b99..542578ee7c4 100644 --- a/tests/ext/request-replayer/dd_trace_span_link_with_exception.phpt +++ b/tests/ext/request-replayer/dd_trace_span_link_with_exception.phpt @@ -48,8 +48,7 @@ try { echo 'Caught exception: ' . $e->getMessage() . PHP_EOL; } -// Find the request carrying our Foo.bar span (the wire may be v0.4 or v1 depending on which -// protocol the sidecar has negotiated). +// Find the request carrying our Foo.bar span (v0.4 or v1, whichever the sidecar negotiated). $replay = $rr->waitForRequest(function ($r) { if (strpos($r["uri"], "traces") === false) return false; $b = json_decode($r["body"], true); @@ -59,18 +58,16 @@ $replay = $rr->waitForRequest(function ($r) { $root = json_decode($replay["body"], true); $spans = $root["chunks"][0]["spans"] ?? $root[0]; $span = $spans[0]; -var_dump($span['meta']['error.message']); -var_dump($span['meta']['error.type']); -var_dump($span['meta']['error.stack']); -// Span links are carried natively (numeric ids) on the v0.4 downgrade wire and as the -// _dd.span_links meta JSON (zero-padded hex ids) on the v1 wire. Both encode the same 128-bit -// trace id (hex 0x42) and span id (0x6); normalise to ":". -if (isset($span['span_links'])) { - $link = $span['span_links'][0]; - printf("link=%x:%x\n", $link['trace_id'], $link['span_id']); +// v1 spans carry typed attributes and hex link ids; v0.4 spans meta and decimal link ids. +$attributes = $span['attributes'] ?? $span['meta']; +var_dump($attributes['error.message']); +var_dump($attributes['error.type']); +var_dump($attributes['error.stack']); +$link = $span['span_links'][0]; +if (isset($span['attributes'])) { + printf("link=%x:%x\n", hexdec(substr($link['trace_id'], 16)), hexdec($link['span_id'])); } else { - $link = json_decode($span['meta']['_dd.span_links'], true)[0]; - printf("link=%x:%x\n", hexdec($link['trace_id']), hexdec($link['span_id'])); + printf("link=%x:%x\n", $link['trace_id'], $link['span_id']); } ?> --EXPECTF-- diff --git a/tests/ext/request-replayer/traced_attribute_tags_v04_wire.phpt b/tests/ext/request-replayer/inprocess_sender_traced_attribute_tags.phpt similarity index 87% rename from tests/ext/request-replayer/traced_attribute_tags_v04_wire.phpt rename to tests/ext/request-replayer/inprocess_sender_traced_attribute_tags.phpt index b3f02644863..67b07b7a5f3 100644 --- a/tests/ext/request-replayer/traced_attribute_tags_v04_wire.phpt +++ b/tests/ext/request-replayer/inprocess_sender_traced_attribute_tags.phpt @@ -1,5 +1,5 @@ --TEST-- -#[DDTrace\Trace] tags keep their meta strings on the v0.4 wire (array leaves included) +The in-process sender writes deprecated #[DDTrace\Trace] tags as v0.4 meta strings (array leaves included) --SKIPIF-- [ 'method' => 'PUT', - 'header' => ["Content-Type: application/json", "X-Datadog-Test-Session-Token: traced_attribute_tags_v04"], + 'header' => ["Content-Type: application/json", "X-Datadog-Test-Session-Token: inprocess_sender_traced_attribute_tags"], 'content' => json_encode(["endpoints" => ["/v0.4/traces", "/v0.6/stats", "/v0.7/config"], "client_drop_p0s" => false, "version" => "7.66.0"]), ]]); if (@file_get_contents("http://request-replayer/set-agent-info", false, $ctx) === false) { @@ -26,7 +26,8 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 DD_TRACE_SIDECAR_TRACE_SENDER=0 --INI-- -datadog.trace.agent_test_session_token=traced_attribute_tags_v04 +error_reporting=E_ALL +datadog.trace.agent_test_session_token=inprocess_sender_traced_attribute_tags --FILE-- --EXPECTF-- +Deprecated: DDTrace\Trace: $tags is deprecated, use $attributes instead in %s on line %d [ddtrace] [info] [%d] Flushing %d v0.4 trace(s) to send-queue for http://request-replayer:80 meta.arr.0='1' meta.arr.1='true' diff --git a/tests/ext/request-replayer/serializer_wire_inprocess_v04.phpt b/tests/ext/request-replayer/serializer_wire_inprocess_v04.phpt index b49a8d67009..79c0797527a 100644 --- a/tests/ext/request-replayer/serializer_wire_inprocess_v04.phpt +++ b/tests/ext/request-replayer/serializer_wire_inprocess_v04.phpt @@ -44,7 +44,7 @@ dd_trace_internal_fn("synchronous_flush"); $req = $rr->waitForRequest(function ($r) { return strpos($r["uri"], "traces") !== false; }); $root = json_decode($req["body"], true); -$spans = $root["chunks"][0]["spans"] ?? $root[0]; +$spans = $root[0]; echo "uri=" . $req["uri"] . "\n"; echo "has_chunks=" . (isset($root['chunks']) ? "yes" : "no") . "\n"; echo "span_name=" . $spans[0]["name"] . "\n"; diff --git a/tests/ext/request-replayer/serializer_wire_inprocess_v1.phpt b/tests/ext/request-replayer/serializer_wire_inprocess_v1.phpt index 09653ef7ec4..6e3453e0ea2 100644 --- a/tests/ext/request-replayer/serializer_wire_inprocess_v1.phpt +++ b/tests/ext/request-replayer/serializer_wire_inprocess_v1.phpt @@ -2,7 +2,7 @@ In-process sender ignores a v1-capable agent and still serializes the v0.4 wire (/v0.4/traces) --DESCRIPTION-- Locks the in-process sender -> v0.4 wire mapping even when the agent advertises /v1.0/traces. The -in-process (<=8.2 / DD_TRACE_SIDECAR_TRACE_SENDER=0) sender ALWAYS downgrades the native V1 builder +in-process (DD_TRACE_SIDECAR_TRACE_SENDER=0) sender ALWAYS downgrades the native V1 builder to v0.4 and posts each trace to /v0.4/traces; a native V1 payload is a single msgpack MAP that the background sender's array-of-1 framing (comms_php.c mpack_expect_array_match) cannot parse, so the in-process path never uses /v1.0/traces regardless of agent capability. @@ -40,7 +40,7 @@ dd_trace_internal_fn("synchronous_flush"); $req = $rr->waitForRequest(function ($r) { return strpos($r["uri"], "traces") !== false; }); $root = json_decode($req["body"], true); -$spans = $root["chunks"][0]["spans"] ?? $root[0]; +$spans = $root[0]; echo "uri=" . $req["uri"] . "\n"; echo "has_chunks=" . (isset($root['chunks']) ? "yes" : "no") . "\n"; echo "span_name=" . $spans[0]["name"] . "\n"; diff --git a/tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt b/tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt index 2150b976dc0..249336ee7e0 100644 --- a/tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt +++ b/tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt @@ -1,5 +1,5 @@ --TEST-- -v0.4 native span_links and legacy events JSON print floats like json_encode and objects as property maps +v0.4 native span_links and legacy events JSON carry typed floats and objects as property maps --SKIPIF-- waitForRequest(function ($r) { return strpos($r["uri"], "traces") !== false; }); $span = json_decode($req["body"], true)[0][0]; $meta = $span["meta"]; -$expected = json_encode($floats); -echo $expected, "\n"; -// Native links carry nested values as a JSON string, events as raw JSON: both must print json_encode's floats. -var_dump(!isset($meta["_dd.span_links"]) && $span["span_links"][0]["attributes"]["floats"] === $expected); -var_dump(strpos($meta["events"], '"floats":' . $expected) !== false); -var_dump(strpos($meta["events"], '"f":1.0e+20') !== false); +// Native links carry nested values as a JSON string, events as raw JSON: both decode to the floats. +var_dump(!isset($meta["_dd.span_links"]) && json_decode($span["span_links"][0]["attributes"]["floats"], true) == $floats); $attrs = json_decode($meta["events"], true)[0]["attributes"]; +var_dump($attrs["floats"] == $floats, $attrs["f"] == 1e20); var_dump($attrs["obj"], $attrs["nested"]); ?> --EXPECT-- -[1.0e+20,1.0e-5,0.1,1.5,1.0e+17,1.2345678901234568e+17,-0,3] bool(true) bool(true) bool(true) diff --git a/tests/ext/request-replayer/top_level_marked_by_sidecar_sender.phpt b/tests/ext/request-replayer/top_level_marked_by_sidecar_sender.phpt new file mode 100644 index 00000000000..b32dfe87a86 --- /dev/null +++ b/tests/ext/request-replayer/top_level_marked_by_sidecar_sender.phpt @@ -0,0 +1,65 @@ +--TEST-- +The sidecar sender marks _dd.top_level (local root and service changes) without stats computation +--SKIPIF-- + +--ENV-- +DD_TRACE_LOG_LEVEL=error,startup=off +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=1 +DD_TRACE_STATS_COMPUTATION_ENABLED=0 +--INI-- +datadog.trace.agent_test_session_token=top_level_marked_by_sidecar_sender +--FILE-- +clearDumpedData(); + +$root = \DDTrace\start_span(); +$root->name = "root"; +$root->service = "svc"; +$same = \DDTrace\start_span(); +$same->name = "child_same_service"; +$same->service = "svc"; +\DDTrace\close_span(); +$diff = \DDTrace\start_span(); +$diff->name = "child_other_service"; +$diff->service = "other"; +\DDTrace\close_span(); +\DDTrace\close_span(); +dd_trace_internal_fn("synchronous_flush"); + +$found = null; +$rr->waitForRequest(function ($r) use (&$found) { + if (strpos($r["uri"], "/traces") === false) { + return false; + } + $body = json_decode($r["body"], true); + // v1: chunks of spans with attributes; v0.4: traces of spans with metrics. + foreach (isset($body["chunks"]) ? array_column($body["chunks"], "spans") : $body as $spans) { + if (in_array("child_other_service", array_column($spans, "name"), true)) { + $found = $spans; + } + } + return $found !== null; +}); +$marks = []; +foreach ($found as $span) { + $marks[$span["name"]] = isset($span["attributes"]["_dd.top_level"]) || isset($span["metrics"]["_dd.top_level"]) ? "1" : "not set"; +} +ksort($marks); +foreach ($marks as $name => $mark) { + echo "$name: _dd.top_level=$mark\n"; +} +?> +--EXPECT-- +child_other_service: _dd.top_level=1 +child_same_service: _dd.top_level=not set +root: _dd.top_level=1 diff --git a/tests/ext/request-replayer/top_level_marked_on_v1_wire.phpt b/tests/ext/request-replayer/top_level_marked_on_v1_wire.phpt deleted file mode 100644 index e98e70adf9a..00000000000 --- a/tests/ext/request-replayer/top_level_marked_on_v1_wire.phpt +++ /dev/null @@ -1,64 +0,0 @@ ---TEST-- -The sidecar sender marks _dd.top_level on the V1 wire (local root and service changes) without stats computation ---SKIPIF-- - ---ENV-- -DD_TRACE_LOG_LEVEL=error,startup=off -DD_AGENT_HOST=request-replayer -DD_TRACE_AGENT_PORT=80 -DD_TRACE_AGENT_FLUSH_INTERVAL=333 -DD_TRACE_GENERATE_ROOT_SPAN=0 -DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 -DD_TRACE_SIDECAR_TRACE_SENDER=1 -DD_TRACE_STATS_COMPUTATION_ENABLED=0 ---INI-- -datadog.trace.agent_test_session_token=top_level_marked_on_v1_wire ---FILE-- -clearDumpedData(); - -// The sidecar sends v0.4 until its /info fetch advertises /v1.0/traces: resend until a v1 request carries the trace. -$found = null; -for ($i = 0; $i < 100 && $found === null; $i++) { - $root = \DDTrace\start_span(); - $root->name = "root"; - $root->service = "svc"; - $same = \DDTrace\start_span(); - $same->name = "child_same_service"; - $same->service = "svc"; - \DDTrace\close_span(); - $diff = \DDTrace\start_span(); - $diff->name = "child_other_service"; - $diff->service = "other"; - \DDTrace\close_span(); - \DDTrace\close_span(); - dd_trace_internal_fn("synchronous_flush"); - usleep(100000); - foreach (($rr->replayAllRequests() ?: []) as $r) { - if (strpos($r["uri"], "/v1.0/traces") === false) continue; - foreach ((json_decode($r["body"], true)["chunks"] ?? []) as $chunk) { - $names = array_column($chunk["spans"] ?? [], "name"); - if (in_array("child_other_service", $names, true)) { - $found = $chunk["spans"]; - } - } - } -} -$marks = []; -foreach ($found ?: [] as $span) { - $marks[$span["name"]] = isset($span["metrics"]["_dd.top_level"]) ? "1" : "not set"; -} -ksort($marks); -foreach ($marks as $name => $mark) { - echo "$name: _dd.top_level=$mark\n"; -} -?> ---EXPECT-- -child_other_service: _dd.top_level=1 -child_same_service: _dd.top_level=not set -root: _dd.top_level=1 diff --git a/tests/ext/root_span_default_component.phpt b/tests/ext/root_span_default_component.phpt index 1efb1ce9543..8dcf7770ae4 100644 --- a/tests/ext/root_span_default_component.phpt +++ b/tests/ext/root_span_default_component.phpt @@ -1,5 +1,5 @@ --TEST-- -Web entrypoint root spans default component to the SAPI name +Web entrypoint root spans default component to "web" --ENV-- DD_TRACE_AUTO_FLUSH_ENABLED=0 DD_TRACE_GENERATE_ROOT_SPAN=0 @@ -9,9 +9,8 @@ foo=bar --EXPECT-- -string(8) "cgi-fcgi" -string(8) "cgi-fcgi" +string(3) "web" diff --git a/tests/ext/root_span_default_component_cli.phpt b/tests/ext/root_span_default_component_cli.phpt index 3fa007b0219..7152960f126 100644 --- a/tests/ext/root_span_default_component_cli.phpt +++ b/tests/ext/root_span_default_component_cli.phpt @@ -7,8 +7,8 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 --EXPECT-- bool(false) diff --git a/tests/ext/root_span_default_component_framework_wins.phpt b/tests/ext/root_span_default_component_framework_wins.phpt index c1e92530f01..a18f1dfe0f6 100644 --- a/tests/ext/root_span_default_component_framework_wins.phpt +++ b/tests/ext/root_span_default_component_framework_wins.phpt @@ -8,9 +8,9 @@ foo=bar --FILE-- meta["component"] = "laravel"; +$span->component = "laravel"; DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; var_dump($spans[0]["component"]); ?> --EXPECT-- diff --git a/tests/ext/root_span_http_client_ip.phpt b/tests/ext/root_span_http_client_ip.phpt index e9bd1cd3ac6..d93d3bc3934 100644 --- a/tests/ext/root_span_http_client_ip.phpt +++ b/tests/ext/root_span_http_client_ip.phpt @@ -9,7 +9,7 @@ DD_TRACE_CLIENT_IP_ENABLED=true --EXPECTF-- 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 1c3aee84f20..ea08ccfbd5f 100644 --- a/tests/ext/root_span_http_client_ip_custom_header.phpt +++ b/tests/ext/root_span_http_client_ip_custom_header.phpt @@ -10,7 +10,7 @@ DD_TRACE_CLIENT_IP_ENABLED=true --EXPECTF-- 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 c2ba58361d1..48b4c984027 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 @@ -16,7 +16,7 @@ DD_TRACE_CLIENT_IP_ENABLED=true --EXPECTF-- diff --git a/tests/ext/root_span_http_useragent.phpt b/tests/ext/root_span_http_useragent.phpt index 73fc5bcc1e6..09a27a9b5dd 100644 --- a/tests/ext/root_span_http_useragent.phpt +++ b/tests/ext/root_span_http_useragent.phpt @@ -8,7 +8,7 @@ HTTP_USER_AGENT=dd_trace_user_agent --EXPECTF-- diff --git a/tests/ext/root_span_security_testing_headers.phpt b/tests/ext/root_span_security_testing_headers.phpt index 911e8834d78..c1f9d885f89 100644 --- a/tests/ext/root_span_security_testing_headers.phpt +++ b/tests/ext/root_span_security_testing_headers.phpt @@ -10,7 +10,7 @@ HTTP_X_DATADOG_SECURITY_TEST=security-test-uuid diff --git a/tests/ext/root_span_security_testing_headers_absent.phpt b/tests/ext/root_span_security_testing_headers_absent.phpt index 160a09909b2..4b7727b26fc 100644 --- a/tests/ext/root_span_security_testing_headers_absent.phpt +++ b/tests/ext/root_span_security_testing_headers_absent.phpt @@ -7,7 +7,7 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 diff --git a/tests/ext/root_span_url_as_resource_names.phpt b/tests/ext/root_span_url_as_resource_names.phpt index 4224d657dfb..fe4b06a90d6 100644 --- a/tests/ext/root_span_url_as_resource_names.phpt +++ b/tests/ext/root_span_url_as_resource_names.phpt @@ -16,7 +16,7 @@ foo=bar 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 b50f7f317cc..b1016278ef2 100644 --- a/tests/ext/root_span_url_with_post_no_param.phpt +++ b/tests/ext/root_span_url_with_post_no_param.phpt @@ -14,7 +14,7 @@ METHOD=POST 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 7f66e030a9e..5fca2ccfe46 100644 --- a/tests/ext/root_span_url_with_query_params_obfuscation.phpt +++ b/tests/ext/root_span_url_with_query_params_obfuscation.phpt @@ -15,7 +15,7 @@ key1=val1&token=a0b21ce2-006f-4cc6-95d5-d7b550698482&key2=val2&password=somethin --EXPECT-- 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 7075915fe88..6722d79359a 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 @@ -16,7 +16,7 @@ application_key=123 --EXPECT-- 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 edcc9425b0b..7e7ea163ac5 100644 --- a/tests/ext/root_span_url_with_query_params_whitelist.phpt +++ b/tests/ext/root_span_url_with_query_params_whitelist.phpt @@ -15,7 +15,7 @@ password=value&some=query¶m&eters --EXPECT-- diff --git a/tests/ext/root_span_url_without_query_params.phpt b/tests/ext/root_span_url_without_query_params.phpt index 087a9326c58..6b98640ebbb 100644 --- a/tests/ext/root_span_url_without_query_params.phpt +++ b/tests/ext/root_span_url_without_query_params.phpt @@ -15,7 +15,7 @@ some=query¶m&eters --EXPECT-- diff --git a/tests/ext/sampling_mechanism_from_decision_maker.phpt b/tests/ext/sampling_mechanism_from_decision_maker.phpt index 4dc9ad334f6..5b2e6fd7c88 100644 --- a/tests/ext/sampling_mechanism_from_decision_maker.phpt +++ b/tests/ext/sampling_mechanism_from_decision_maker.phpt @@ -15,8 +15,8 @@ foreach (['-4', '934086a686-4', '-12', '-abc', '4-', '-'] as $dm) { 'x-datadog-tags' => "_dd.p.dm=$dm", ]); DDTrace\close_span(); - $span = dd_trace_serialize_closed_spans()[0]; - echo json_encode($dm), " => ", $span['sampling_mechanism'] ?? 'unset', "\n"; + $chunk = dd_trace_serialize_closed_spans()['chunks'][0]; + echo json_encode($dm), " => ", $chunk['sampling_mechanism'] ?? 'unset', "\n"; } ?> diff --git a/tests/ext/sandbox-prehook/close_on_exit.phpt b/tests/ext/sandbox-prehook/close_on_exit.phpt index 0599a704634..65f867784af 100644 --- a/tests/ext/sandbox-prehook/close_on_exit.phpt +++ b/tests/ext/sandbox-prehook/close_on_exit.phpt @@ -5,7 +5,7 @@ use DDTrace\SpanData; register_shutdown_function(function () { - $spans = dd_trace_serialize_closed_spans(); + $spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; array_map( function($span) { echo $span['name'], PHP_EOL; diff --git a/tests/ext/sandbox-prehook/dd_trace_function_internal.phpt b/tests/ext/sandbox-prehook/dd_trace_function_internal.phpt index f8dab1e51de..9fb9213b0cd 100644 --- a/tests/ext/sandbox-prehook/dd_trace_function_internal.phpt +++ b/tests/ext/sandbox-prehook/dd_trace_function_internal.phpt @@ -14,7 +14,7 @@ var_dump(array_sum([1, 3, 5])); array_map(function($span) { echo $span['name'], PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECT-- bool(true) diff --git a/tests/ext/sandbox-prehook/dd_trace_function_userland.phpt b/tests/ext/sandbox-prehook/dd_trace_function_userland.phpt index 39c0ac12fc1..18df530a427 100644 --- a/tests/ext/sandbox-prehook/dd_trace_function_userland.phpt +++ b/tests/ext/sandbox-prehook/dd_trace_function_userland.phpt @@ -28,7 +28,7 @@ echo PHP_EOL; array_map(function($span) { echo $span['name'], PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECT-- bool(true) diff --git a/tests/ext/sandbox-prehook/dd_trace_method.phpt b/tests/ext/sandbox-prehook/dd_trace_method.phpt index 5668afcb1a0..dc562cf6a07 100644 --- a/tests/ext/sandbox-prehook/dd_trace_method.phpt +++ b/tests/ext/sandbox-prehook/dd_trace_method.phpt @@ -95,11 +95,7 @@ array(3) { --- array(3) { [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -114,10 +110,6 @@ array(3) { string(10) "FooService" ["type"]=> string(7) "FooType" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(10) { ["runtime-id"]=> @@ -143,9 +135,7 @@ array(3) { } } [1]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -169,11 +159,7 @@ array(3) { } } [2]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -188,16 +174,12 @@ array(3) { string(19) "dd_trace_method.php" ["type"]=> string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(6) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> diff --git a/tests/ext/sandbox-prehook/drop_spans.phpt b/tests/ext/sandbox-prehook/drop_spans.phpt index 057e8c8499d..8b85043e4fc 100644 --- a/tests/ext/sandbox-prehook/drop_spans.phpt +++ b/tests/ext/sandbox-prehook/drop_spans.phpt @@ -31,7 +31,7 @@ new DateTime('2019-09-10'); // Should drop array_map(function($span) { echo $span['name'] . PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECT-- Traced array_sum diff --git a/tests/ext/sandbox-prehook/exception_handling.phpt b/tests/ext/sandbox-prehook/exception_handling.phpt index 07750c9d578..c34b0e719cb 100644 --- a/tests/ext/sandbox-prehook/exception_handling.phpt +++ b/tests/ext/sandbox-prehook/exception_handling.phpt @@ -19,7 +19,7 @@ DDTrace\trace_function("inner", ['prehook' => function() {}]); try { outer(); } catch (Exception $e) { - $stack = dd_trace_serialize_closed_spans(); + $stack = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; echo "Stack size: ", count($stack), "\n"; $span = $stack[0]; diff --git a/tests/ext/sandbox-prehook/exceptions_and_errors_are_ignored_in_tracing_closure.phpt b/tests/ext/sandbox-prehook/exceptions_and_errors_are_ignored_in_tracing_closure.phpt index 089acda1360..ed9c0a05d5f 100644 --- a/tests/ext/sandbox-prehook/exceptions_and_errors_are_ignored_in_tracing_closure.phpt +++ b/tests/ext/sandbox-prehook/exceptions_and_errors_are_ignored_in_tracing_closure.phpt @@ -42,7 +42,7 @@ $test->testFoo(); array_map(function($span) { echo $span['name'] . PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); var_dump(error_get_last()); ?> --EXPECTF-- diff --git a/tests/ext/sandbox-prehook/keep_spans_in_limited_tracing_userland_functions.phpt b/tests/ext/sandbox-prehook/keep_spans_in_limited_tracing_userland_functions.phpt index b1c568ee80e..8283edfbbbc 100644 --- a/tests/ext/sandbox-prehook/keep_spans_in_limited_tracing_userland_functions.phpt +++ b/tests/ext/sandbox-prehook/keep_spans_in_limited_tracing_userland_functions.phpt @@ -6,6 +6,7 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DD_TRACE_SPANS_LIMIT=5 --FILE-- --EXPECT-- bool(false) diff --git a/tests/ext/sandbox-prehook/new_static.phpt b/tests/ext/sandbox-prehook/new_static.phpt index ea2d952c27c..ec0c4dc217f 100644 --- a/tests/ext/sandbox-prehook/new_static.phpt +++ b/tests/ext/sandbox-prehook/new_static.phpt @@ -23,7 +23,7 @@ var_dump($bar instanceof Bar); array_map(function($span) { echo $span['name'] . PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECT-- bool(true) diff --git a/tests/ext/sandbox/close-on-exit-retval.phpt b/tests/ext/sandbox/close-on-exit-retval.phpt index 1dbbfcd3ee1..94c481610c6 100644 --- a/tests/ext/sandbox/close-on-exit-retval.phpt +++ b/tests/ext/sandbox/close-on-exit-retval.phpt @@ -5,7 +5,7 @@ Ensure tracing closure's $retval arg is null if invoked due to exit() use DDTrace\SpanData; register_shutdown_function(function () { - $spans = dd_trace_serialize_closed_spans(); + $spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; array_map( function($span) { echo @$span['name'], PHP_EOL; diff --git a/tests/ext/sandbox/close-on-exit.phpt b/tests/ext/sandbox/close-on-exit.phpt index 6affe2ac416..dd9c029383a 100644 --- a/tests/ext/sandbox/close-on-exit.phpt +++ b/tests/ext/sandbox/close-on-exit.phpt @@ -5,7 +5,7 @@ Run sandbox closures for open spans on exit use DDTrace\SpanData; register_shutdown_function(function () { - $spans = dd_trace_serialize_closed_spans(); + $spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; array_map( function($span) { echo @$span['name'], PHP_EOL; diff --git a/tests/ext/sandbox/dd_dumper.inc b/tests/ext/sandbox/dd_dumper.inc index e9789bece26..d2ad74ab5e9 100644 --- a/tests/ext/sandbox/dd_dumper.inc +++ b/tests/ext/sandbox/dd_dumper.inc @@ -2,9 +2,8 @@ function dd_dump_spans($skipMeta = false) { - $spans = dd_trace_serialize_closed_spans(); $roots = $children = []; - foreach ($spans as $span) { + foreach (dd_clean_spans() as $span) { if (isset($span["parent_id"])) { $children[$span["parent_id"]][] = $span; } else { @@ -42,14 +41,11 @@ function dd_dump_spans($skipMeta = false) unset($span["attributes"]["runtime-id"]); unset($span["attributes"]["_dd.tags.process"]); unset($span["attributes"]["_dd.sdk.otlp_export"]); - // 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 (['process_id', '_dd.agent_psr', 'php.compilation.total_time_ms', 'php.memory.peak_usage_bytes', 'php.memory.peak_real_usage_bytes'] as $volatile) { + unset($span['attributes'][$volatile]); + } foreach ($span['attributes'] as $k => $v) { - if (!is_string($v)) { - continue; - } - echo str_repeat(' ', $indent) . ' ' . $k . ' => ' . $v . PHP_EOL; + echo str_repeat(' ', $indent) . ' ' . $k . ' => ' . (is_string($v) ? $v : json_encode($v)) . PHP_EOL; } } else { echo PHP_EOL; @@ -84,16 +80,7 @@ function dd_dump_spans($skipMeta = false) echo '}' . PHP_EOL; } +// The spans of all chunks, in order. function dd_clean_spans() { - $spans = dd_trace_serialize_closed_spans(); - foreach ($spans as &$span) { - if (isset($span['attributes'])) { - unset($span['attributes']['_dd.tags.process']); - unset($span['attributes']['_dd.sdk.otlp_export']); - if (empty($span['attributes'])) { - unset($span['attributes']); - } - } - } - return $spans; + return array_merge([], ...array_column(dd_trace_serialize_closed_spans()['chunks'], 'spans')); } diff --git a/tests/ext/sandbox/dd_trace_function_alias.phpt b/tests/ext/sandbox/dd_trace_function_alias.phpt index 3e93ca1402c..7f227d57a1f 100644 --- a/tests/ext/sandbox/dd_trace_function_alias.phpt +++ b/tests/ext/sandbox/dd_trace_function_alias.phpt @@ -1,9 +1,11 @@ --TEST-- -dd_trace_function() is aliased to DDTrace\trace_function() +dd_trace_function() is a deprecated alias of DDTrace\trace_function() --ENV-- DD_TRACE_AUTO_FLUSH_ENABLED=0 DD_TRACE_GENERATE_ROOT_SPAN=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--INI-- +error_reporting=E_ALL --FILE-- --EXPECTF-- +Deprecated: Function dd_trace_function() is deprecated in %s on line %d bar(hello) spans(\DDTrace\SpanData) (1) { bar (alias, bar, cli) diff --git a/tests/ext/sandbox/dd_trace_function_complex.phpt b/tests/ext/sandbox/dd_trace_function_complex.phpt index d83c7229fc0..33e430b723d 100644 --- a/tests/ext/sandbox/dd_trace_function_complex.phpt +++ b/tests/ext/sandbox/dd_trace_function_complex.phpt @@ -96,11 +96,7 @@ array(3) { --- array(5) { [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -115,10 +111,6 @@ array(5) { string(10) "BarService" ["type"]=> string(7) "BarType" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(13) { ["runtime-id"]=> @@ -150,9 +142,7 @@ array(5) { } } [1]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -176,9 +166,7 @@ array(5) { } } [2]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -202,11 +190,7 @@ array(5) { } } [3]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -221,16 +205,12 @@ array(5) { string(29) "dd_trace_function_complex.php" ["type"]=> string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(6) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> @@ -242,11 +222,7 @@ array(5) { } } [4]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -261,16 +237,12 @@ array(5) { string(29) "dd_trace_function_complex.php" ["type"]=> string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(6) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> diff --git a/tests/ext/sandbox/dd_trace_function_internal.phpt b/tests/ext/sandbox/dd_trace_function_internal.phpt index cd207cca443..e1427d2d91a 100644 --- a/tests/ext/sandbox/dd_trace_function_internal.phpt +++ b/tests/ext/sandbox/dd_trace_function_internal.phpt @@ -27,11 +27,7 @@ int(9) --- array(1) { [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -46,16 +42,12 @@ array(1) { string(30) "dd_trace_function_internal.php" ["type"]=> string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(6) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> diff --git a/tests/ext/sandbox/dd_trace_function_userland.phpt b/tests/ext/sandbox/dd_trace_function_userland.phpt index 8cb397114cb..134bf509042 100644 --- a/tests/ext/sandbox/dd_trace_function_userland.phpt +++ b/tests/ext/sandbox/dd_trace_function_userland.phpt @@ -39,11 +39,7 @@ array ( --- array(1) { [0]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> diff --git a/tests/ext/sandbox/dd_trace_method.phpt b/tests/ext/sandbox/dd_trace_method.phpt index 388e2a789de..b6353b5a1b1 100644 --- a/tests/ext/sandbox/dd_trace_method.phpt +++ b/tests/ext/sandbox/dd_trace_method.phpt @@ -104,11 +104,7 @@ array(3) { --- array(3) { [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -123,10 +119,6 @@ array(3) { string(10) "FooService" ["type"]=> string(7) "FooType" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(13) { ["runtime-id"]=> @@ -158,9 +150,7 @@ array(3) { } } [1]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -188,11 +178,7 @@ array(3) { } } [2]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -207,16 +193,12 @@ array(3) { string(19) "dd_trace_method.php" ["type"]=> string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(6) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> diff --git a/tests/ext/sandbox/dd_trace_method_alias.phpt b/tests/ext/sandbox/dd_trace_method_alias.phpt index 66a074eed7b..3f05a501990 100644 --- a/tests/ext/sandbox/dd_trace_method_alias.phpt +++ b/tests/ext/sandbox/dd_trace_method_alias.phpt @@ -1,9 +1,11 @@ --TEST-- -dd_trace_method() is aliased to DDTrace\trace_method() +dd_trace_method() is a deprecated alias of DDTrace\trace_method() --ENV-- DD_TRACE_AUTO_FLUSH_ENABLED=0 DD_TRACE_GENERATE_ROOT_SPAN=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--INI-- +error_reporting=E_ALL --FILE-- --EXPECTF-- +Deprecated: Function dd_trace_method() is deprecated in %s on line %d Foo::bar(hello) spans(\DDTrace\SpanData) (1) { Foo.bar (alias, Foo.bar, cli) diff --git a/tests/ext/sandbox/deferred_load_using_function.phpt b/tests/ext/sandbox/deferred_load_using_function.phpt index cbd473fd0f7..b9367ab270a 100644 --- a/tests/ext/sandbox/deferred_load_using_function.phpt +++ b/tests/ext/sandbox/deferred_load_using_function.phpt @@ -11,7 +11,7 @@ namespace DDTrace\Test { static function init(): int { - dd_trace_method("Test", "public_static_method", [ + \DDTrace\trace_method("Test", "public_static_method", [ 'prehook' => function() { echo "test_access hook" . PHP_EOL; } diff --git a/tests/ext/sandbox/drop_spans.phpt b/tests/ext/sandbox/drop_spans.phpt index 276c8180d77..5cc39338dbf 100644 --- a/tests/ext/sandbox/drop_spans.phpt +++ b/tests/ext/sandbox/drop_spans.phpt @@ -31,7 +31,7 @@ new DateTime('2019-09-10'); // Should drop array_map(function($span) { echo $span['name'] . PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECT-- Traced array_sum diff --git a/tests/ext/sandbox/errors_are_flagged_from_userland.phpt b/tests/ext/sandbox/errors_are_flagged_from_userland.phpt index 6abce1e1aa9..7e3e538ccad 100644 --- a/tests/ext/sandbox/errors_are_flagged_from_userland.phpt +++ b/tests/ext/sandbox/errors_are_flagged_from_userland.phpt @@ -27,11 +27,7 @@ var_dump(dd_clean_spans()); testErrorFromUserland() array(1) { [0]=> - array(13) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(9) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -47,17 +43,13 @@ array(1) { ["type"]=> string(3) "cli" ["error"]=> - int(1) - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) + bool(true) ["attributes"]=> array(7) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["error.message"]=> string(9) "Foo error" ["_dd.agent_psr"]=> diff --git a/tests/ext/sandbox/exception_does_not_close_span_that_catches.phpt b/tests/ext/sandbox/exception_does_not_close_span_that_catches.phpt index 16077b26fec..c94c81310aa 100644 --- a/tests/ext/sandbox/exception_does_not_close_span_that_catches.phpt +++ b/tests/ext/sandbox/exception_does_not_close_span_that_catches.phpt @@ -47,7 +47,7 @@ DDTrace\trace_function('handleException', function(SpanData $s, $a, $retval) { echo main() . PHP_EOL; -list($mainSpan, $handleSpan, $handleExceptionSpan) = dd_trace_serialize_closed_spans(); +list($mainSpan, $handleSpan, $handleExceptionSpan) = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; echo $mainSpan['name'] . $mainSpan['resource'] . PHP_EOL; var_dump(isset($mainSpan['parent_id'])); // root span 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 e132c514600..34487991982 100644 --- a/tests/ext/sandbox/exception_from_user_error_handler_internal.phpt +++ b/tests/ext/sandbox/exception_from_user_error_handler_internal.phpt @@ -17,7 +17,7 @@ DDTrace\trace_function('chmod', function() {}); try { var_dump(chmod('php://foo', 0644)); } catch (Exception $e) { - $spans = dd_trace_serialize_closed_spans(); + $spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; echo 'Spans count: ' . count($spans) . PHP_EOL; $span = $spans[0]; 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 41d88ebc614..ce8eb1687b4 100644 --- a/tests/ext/sandbox/exception_handled_for_correct_catch_block.phpt +++ b/tests/ext/sandbox/exception_handled_for_correct_catch_block.phpt @@ -65,7 +65,7 @@ array_map(function($span) { echo isset($span['resource']) ? ', ' . $span['resource'] : ''; echo isset($span['attributes']['error.message']) ? ', ' . $span['attributes']['error.message'] : ''; echo PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECTF-- BarException caught 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 d1ff9421f33..01d20cfc49e 100644 --- a/tests/ext/sandbox/exception_handled_in_correct_catch_frame.phpt +++ b/tests/ext/sandbox/exception_handled_in_correct_catch_frame.phpt @@ -71,7 +71,7 @@ array_map(function($span) { echo ' (' . $span['attributes']['error.message'] . ')'; } echo PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECTF-- Exception was handled by level1(): Oops! diff --git a/tests/ext/sandbox/exception_handled_in_multicatch.phpt b/tests/ext/sandbox/exception_handled_in_multicatch.phpt index 30c1e5b09bc..c3e96de631a 100644 --- a/tests/ext/sandbox/exception_handled_in_multicatch.phpt +++ b/tests/ext/sandbox/exception_handled_in_multicatch.phpt @@ -40,7 +40,7 @@ array_map(function($span) { echo isset($span['resource']) ? ', ' . $span['resource'] : ''; echo isset($span['attributes']['error.message']) ? ', ' . $span['attributes']['error.message'] : ''; echo PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECTF-- FooException caught diff --git a/tests/ext/sandbox/exception_handled_with_finally.phpt b/tests/ext/sandbox/exception_handled_with_finally.phpt index ba7f5ee028b..b20da2d3689 100644 --- a/tests/ext/sandbox/exception_handled_with_finally.phpt +++ b/tests/ext/sandbox/exception_handled_with_finally.phpt @@ -39,7 +39,7 @@ array_map(function($span) { echo isset($span['resource']) ? ', ' . $span['resource'] : ''; echo isset($span['attributes']['error.message']) ? ', ' . $span['attributes']['error.message'] : ''; echo PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECTF-- Finally retval diff --git a/tests/ext/sandbox/exception_handling.phpt b/tests/ext/sandbox/exception_handling.phpt index 1be3557dc21..6f2b878e2c8 100644 --- a/tests/ext/sandbox/exception_handling.phpt +++ b/tests/ext/sandbox/exception_handling.phpt @@ -25,7 +25,7 @@ DDTrace\trace_function("inner", function ($span) { try { outer(); } catch (Exception $e) { - $stack = dd_trace_serialize_closed_spans(); + $stack = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; echo "Stack size: ", count($stack), "\n"; $span = $stack[0]; diff --git a/tests/ext/sandbox/exceptions_and_errors_are_ignored_in_tracing_closure.phpt b/tests/ext/sandbox/exceptions_and_errors_are_ignored_in_tracing_closure.phpt index 6739e2ea8a1..330147bf019 100644 --- a/tests/ext/sandbox/exceptions_and_errors_are_ignored_in_tracing_closure.phpt +++ b/tests/ext/sandbox/exceptions_and_errors_are_ignored_in_tracing_closure.phpt @@ -42,7 +42,7 @@ $test->testFoo(); array_map(function($span) { echo $span['name'] . PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); var_dump(error_get_last()); ?> --EXPECTF-- 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 c8280926148..7ed267f38ef 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 @@ -38,7 +38,7 @@ array_map(function($span) { echo ' with exception: ' . $span['attributes']['error.message']; } echo PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECTF-- testExceptionIsNull() 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 885df67cca9..0fe7d7e066a 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 @@ -25,7 +25,7 @@ array_map(function($span) { $span['name'], $span['attributes']['error.message'] ); -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECTF-- a() diff --git a/tests/ext/sandbox/fatal_errors_are_tracked_001.phpt b/tests/ext/sandbox/fatal_errors_are_tracked_001.phpt index 2555674c1e9..9c8c52225f6 100644 --- a/tests/ext/sandbox/fatal_errors_are_tracked_001.phpt +++ b/tests/ext/sandbox/fatal_errors_are_tracked_001.phpt @@ -6,11 +6,12 @@ DD_TRACE_TRACED_INTERNAL_FUNCTIONS=array_sum fatal_error_backtraces=0 --FILE-- --EXPECTF-- diff --git a/tests/ext/sandbox/generator.phpt b/tests/ext/sandbox/generator.phpt index 303ca4c7f3e..d2bb64f0368 100644 --- a/tests/ext/sandbox/generator.phpt +++ b/tests/ext/sandbox/generator.phpt @@ -35,7 +35,7 @@ array_map(function($span) { echo $span['name']; echo isset($span['resource']) ? ', ' . $span['resource'] : ''; echo PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECT-- 10 diff --git a/tests/ext/sandbox/generator_with_exception.phpt b/tests/ext/sandbox/generator_with_exception.phpt index 5a42c8b606b..9d309752345 100644 --- a/tests/ext/sandbox/generator_with_exception.phpt +++ b/tests/ext/sandbox/generator_with_exception.phpt @@ -44,7 +44,7 @@ array_map(function($span) { echo isset($span['resource']) ? ', ' . $span['resource'] : ''; echo isset($span['attributes']['error.message']) ? ', ' . $span['attributes']['error.message'] : ''; echo PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECTF-- 0 diff --git a/tests/ext/sandbox/generator_with_return.phpt b/tests/ext/sandbox/generator_with_return.phpt index e7455291985..924ddffdfa7 100644 --- a/tests/ext/sandbox/generator_with_return.phpt +++ b/tests/ext/sandbox/generator_with_return.phpt @@ -37,7 +37,7 @@ array_map(function($span) { echo $span['name']; echo isset($span['resource']) ? ', ' . $span['resource'] : ''; echo PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECT-- 20 diff --git a/tests/ext/sandbox/generator_yield_from.phpt b/tests/ext/sandbox/generator_yield_from.phpt index 63f286c005b..c22acab7ba8 100644 --- a/tests/ext/sandbox/generator_yield_from.phpt +++ b/tests/ext/sandbox/generator_yield_from.phpt @@ -34,7 +34,7 @@ array_map(function($span) { echo $span['name']; echo isset($span['resource']) ? ', ' . $span['resource'] : ''; echo PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECT-- 1337 diff --git a/tests/ext/sandbox/hook_function/dropping_trace_hook.phpt b/tests/ext/sandbox/hook_function/dropping_trace_hook.phpt index 9c60253dfde..b8c4d94baa2 100644 --- a/tests/ext/sandbox/hook_function/dropping_trace_hook.phpt +++ b/tests/ext/sandbox/hook_function/dropping_trace_hook.phpt @@ -13,7 +13,7 @@ DDTrace\trace_function("a", function() { }); // first function, creates span DDTrace\trace_function("a", function() { return false; }); a(); -var_dump(count(dd_trace_serialize_closed_spans())); +var_dump(count(dd_trace_serialize_closed_spans()['chunks'][0]['spans'] ?? [])); DDTrace\start_span(); dd_untrace("a"); @@ -21,7 +21,7 @@ DDTrace\trace_function("a", function() { }); // first function, creates span DDTrace\trace_function("a", ["prehook" => function() { return false; }]); a(); -var_dump(count(dd_trace_serialize_closed_spans())); +var_dump(count(dd_trace_serialize_closed_spans()['chunks'][0]['spans'] ?? [])); DDTrace\start_span(); dd_untrace("a"); @@ -29,7 +29,7 @@ DDTrace\trace_function("a", function() { return false; }); // first function, cr DDTrace\trace_function("a", function() { }); a(); -var_dump(count(dd_trace_serialize_closed_spans())); +var_dump(count(dd_trace_serialize_closed_spans()['chunks'][0]['spans'] ?? [])); DDTrace\start_span(); // Note that in this case we have a prehook as first function. A prehook returning false will drop an existing span, but not affect future spans. @@ -38,7 +38,7 @@ DDTrace\trace_function("a", ["prehook" => function() { return false; }]); // fir DDTrace\trace_function("a", function() { }); a(); -var_dump(count(dd_trace_serialize_closed_spans())); +var_dump(count(dd_trace_serialize_closed_spans()['chunks'][0]['spans'] ?? [])); ?> --EXPECT-- diff --git a/tests/ext/sandbox/hook_method/posthook_span_ids_02.phpt b/tests/ext/sandbox/hook_method/posthook_span_ids_02.phpt index fd6e55a8466..dd81b13599f 100644 --- a/tests/ext/sandbox/hook_method/posthook_span_ids_02.phpt +++ b/tests/ext/sandbox/hook_method/posthook_span_ids_02.phpt @@ -55,7 +55,7 @@ function main() main(); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; assert(count($spans) == 2); foreach ($spans as $span) { diff --git a/tests/ext/sandbox/hook_method/prehook_span_ids_02.phpt b/tests/ext/sandbox/hook_method/prehook_span_ids_02.phpt index f680dbc3b4a..d101c7ce739 100644 --- a/tests/ext/sandbox/hook_method/prehook_span_ids_02.phpt +++ b/tests/ext/sandbox/hook_method/prehook_span_ids_02.phpt @@ -54,7 +54,7 @@ function main() main(); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; assert(count($spans) == 2); foreach ($spans as $span) { diff --git a/tests/ext/sandbox/keep_spans_in_limited_tracing_internal_functions.phpt b/tests/ext/sandbox/keep_spans_in_limited_tracing_internal_functions.phpt index a5afa15814c..8fb52ddcb23 100644 --- a/tests/ext/sandbox/keep_spans_in_limited_tracing_internal_functions.phpt +++ b/tests/ext/sandbox/keep_spans_in_limited_tracing_internal_functions.phpt @@ -7,6 +7,7 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DD_TRACE_TRACED_INTERNAL_FUNCTIONS=array_sum,mt_rand --FILE-- name = 'array_sum'; }); @@ -28,7 +29,7 @@ mt_rand(); array_map(function($span) { echo $span['name'] . PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_clean_spans()); ?> --EXPECT-- bool(false) diff --git a/tests/ext/sandbox/keep_spans_in_limited_tracing_internal_methods.phpt b/tests/ext/sandbox/keep_spans_in_limited_tracing_internal_methods.phpt index 2e3bcadaab9..a2dfcaae365 100644 --- a/tests/ext/sandbox/keep_spans_in_limited_tracing_internal_methods.phpt +++ b/tests/ext/sandbox/keep_spans_in_limited_tracing_internal_methods.phpt @@ -7,6 +7,7 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 DD_TRACE_TRACED_INTERNAL_FUNCTIONS=DateTime::format,DateTime::setTime --FILE-- setTime(8, 12); array_map(function($span) { echo $span['name'] . PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_clean_spans()); ?> --EXPECT-- bool(false) diff --git a/tests/ext/sandbox/keep_spans_in_limited_tracing_userland_functions.phpt b/tests/ext/sandbox/keep_spans_in_limited_tracing_userland_functions.phpt index 57d1ffabe02..54a19c4809f 100644 --- a/tests/ext/sandbox/keep_spans_in_limited_tracing_userland_functions.phpt +++ b/tests/ext/sandbox/keep_spans_in_limited_tracing_userland_functions.phpt @@ -6,6 +6,7 @@ DD_TRACE_SPANS_LIMIT=5 DD_TRACE_GENERATE_ROOT_SPAN=0 --FILE-- --EXPECT-- bool(false) diff --git a/tests/ext/sandbox/keep_spans_in_limited_tracing_userland_methods.phpt b/tests/ext/sandbox/keep_spans_in_limited_tracing_userland_methods.phpt index 127af1f30a9..81a20e4b0e9 100644 --- a/tests/ext/sandbox/keep_spans_in_limited_tracing_userland_methods.phpt +++ b/tests/ext/sandbox/keep_spans_in_limited_tracing_userland_methods.phpt @@ -6,6 +6,7 @@ DD_TRACE_SPANS_LIMIT=5 DD_TRACE_GENERATE_ROOT_SPAN=0 --FILE-- myMethod2(true); array_map(function($span) { echo $span['name'] . PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_clean_spans()); ?> --EXPECT-- bool(false) diff --git a/tests/ext/sandbox/new_static.phpt b/tests/ext/sandbox/new_static.phpt index 7b6e916c827..e98dbd773f8 100644 --- a/tests/ext/sandbox/new_static.phpt +++ b/tests/ext/sandbox/new_static.phpt @@ -48,17 +48,17 @@ function dump_span_names($spans) { } } -dump_span_names(dd_trace_serialize_closed_spans()); +dump_span_names(dd_trace_serialize_closed_spans()['chunks'][0]['spans']); $bar = Bar::get2(); var_dump($bar instanceof Foo); -dump_span_names(dd_trace_serialize_closed_spans()); +dump_span_names(dd_trace_serialize_closed_spans()['chunks'][0]['spans']); $bar = Bar::get3(); var_dump($bar instanceof Bar); -dump_span_names(dd_trace_serialize_closed_spans()); +dump_span_names(dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECT-- diff --git a/tests/ext/sandbox/non-zero_duration.phpt b/tests/ext/sandbox/non-zero_duration.phpt index 5705946ed61..3ca4d86fb8e 100644 --- a/tests/ext/sandbox/non-zero_duration.phpt +++ b/tests/ext/sandbox/non-zero_duration.phpt @@ -17,7 +17,7 @@ function function1() { function1(); -$closedSpans = dd_trace_serialize_closed_spans(); +$closedSpans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; if (empty($closedSpans)) { die("No spans found; test is not set up as expected.\n"); } diff --git a/tests/ext/sandbox/return_by_ref.phpt b/tests/ext/sandbox/return_by_ref.phpt index 2f10afbc3e7..b55b35e84a6 100644 --- a/tests/ext/sandbox/return_by_ref.phpt +++ b/tests/ext/sandbox/return_by_ref.phpt @@ -22,7 +22,7 @@ var_dump($data); array_map(function($span) { echo $span['name'] . PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECT-- array(1) { diff --git a/tests/ext/sandbox/safe_to_string_metadata.phpt b/tests/ext/sandbox/safe_to_string_metadata.phpt index 97dab3a5469..35124b633cf 100644 --- a/tests/ext/sandbox/safe_to_string_metadata.phpt +++ b/tests/ext/sandbox/safe_to_string_metadata.phpt @@ -56,7 +56,7 @@ $allTheTypes[0][1] = &$allTheTypes[0]; call_user_func_array('meta_to_string', $allTheTypes); -list($span) = dd_trace_serialize_closed_spans(); +list($span) = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; unset($span['attributes']['process_id'], $span['attributes']['_dd.tags.process'], $span['attributes']['_dd.sdk.otlp_export']); $last = -1; foreach ($span['attributes'] as $key => $value) { @@ -85,7 +85,7 @@ arg.0: array(2) { [0]=> string(9) "recursive" [1]=> - string(0) "" + string(11) "*RECURSION*" } string(16) "already a string" diff --git a/tests/ext/sandbox/safe_to_string_metadata_ge_php_84.phpt b/tests/ext/sandbox/safe_to_string_metadata_ge_php_84.phpt index fd811fb96e7..af954f2124f 100644 --- a/tests/ext/sandbox/safe_to_string_metadata_ge_php_84.phpt +++ b/tests/ext/sandbox/safe_to_string_metadata_ge_php_84.phpt @@ -89,7 +89,7 @@ arg.0: array(2) { [0]=> string(9) "recursive" [1]=> - string(0) "" + string(11) "*RECURSION*" } string(16) "already a string" diff --git a/tests/ext/sandbox/safe_to_string_metrics.phpt b/tests/ext/sandbox/safe_to_string_metrics.phpt index 723ba500515..f187688225b 100644 --- a/tests/ext/sandbox/safe_to_string_metrics.phpt +++ b/tests/ext/sandbox/safe_to_string_metrics.phpt @@ -31,7 +31,7 @@ $allTheTypes[0][1] = &$allTheTypes[0]; call_user_func_array('metrics_to_string', $allTheTypes); -list($span) = dd_trace_serialize_closed_spans(); +list($span) = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; $last = -1; foreach ($span['attributes'] as $key => $value) { if (strpos($key, 'arg.') !== 0) { diff --git a/tests/ext/sandbox/safe_to_string_properties.phpt b/tests/ext/sandbox/safe_to_string_properties.phpt index a8592fa29f6..d3f4e4d3e3d 100644 --- a/tests/ext/sandbox/safe_to_string_properties.phpt +++ b/tests/ext/sandbox/safe_to_string_properties.phpt @@ -7,6 +7,7 @@ if (version_compare(PHP_VERSION, '7.4.0', '>=')) ?> --FILE-- --EXPECTF-- -object(DDTrace\RootSpanData)#%d (30) { +object(DDTrace\RootSpanData)#%d (28) { ["name"]=> string(3) "foo" ["resource"]=> @@ -40,14 +40,22 @@ object(DDTrace\RootSpanData)#%d (30) { ["type"]=> string(3) "cli" ["meta"]=> - array(1) { + array(5) { ["runtime-id"]=> string(36) "%s" + ["service.name"]=> + string(14) "span_clone.php" + ["resource.name"]=> + string(3) "abc" + ["operation.name"]=> + string(3) "foo" + ["span.type"]=> + string(3) "cli" } ["metrics"]=> array(1) { ["process_id"]=> - float(%f) + int(%d) } ["exception"]=> NULL @@ -65,9 +73,9 @@ object(DDTrace\RootSpanData)#%d (30) { ["parent"]=> NULL ["stack"]=> - object(DDTrace\SpanStack)#%d (4) { + object(DDTrace\SpanStack)#%d (3) { ["parent"]=> - object(DDTrace\SpanStack)#%d (4) { + object(DDTrace\SpanStack)#%d (3) { ["parent"]=> NULL ["active"]=> @@ -75,18 +83,12 @@ object(DDTrace\RootSpanData)#%d (30) { ["spanCreationObservers"]=> array(0) { } - ["attributes"]=> - array(0) { - } } ["active"]=> *RECURSION* ["spanCreationObservers"]=> array(0) { } - ["attributes"]=> - array(0) { - } } ["onClose"]=> array(0) { @@ -107,7 +109,7 @@ object(DDTrace\RootSpanData)#%d (30) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) } ["ignoreError"]=> bool(false)%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r @@ -115,9 +117,7 @@ object(DDTrace\RootSpanData)#%d (30) { array(0) { } ["samplingPriority"]=> - int(1073741824) - ["samplingMechanism"]=> - int(0)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r + int(1073741824)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r ["tracestateTags"]=> array(0) { }%r(\s*\["parentId"\]=>\s+uninitialized\(string\))?%r @@ -127,10 +127,8 @@ object(DDTrace\RootSpanData)#%d (30) { NULL ["inferredSpan"]=> NULL - ["hostname"]=> - string(0) "" } -object(DDTrace\RootSpanData)#%d (30) { +object(DDTrace\RootSpanData)#%d (28) { ["name"]=> string(5) "dummy" ["resource"]=> @@ -143,14 +141,22 @@ object(DDTrace\RootSpanData)#%d (30) { ["type"]=> string(3) "cli" ["meta"]=> - array(1) { + array(5) { ["runtime-id"]=> string(36) "%s" + ["service.name"]=> + string(14) "span_clone.php" + ["resource.name"]=> + string(3) "abc" + ["operation.name"]=> + string(5) "dummy" + ["span.type"]=> + string(3) "cli" } ["metrics"]=> array(1) { ["process_id"]=> - float(%f) + int(%d) } ["exception"]=> NULL @@ -168,9 +174,9 @@ object(DDTrace\RootSpanData)#%d (30) { ["parent"]=> NULL ["stack"]=> - object(DDTrace\SpanStack)#%d (4) { + object(DDTrace\SpanStack)#%d (3) { ["parent"]=> - object(DDTrace\SpanStack)#%d (4) { + object(DDTrace\SpanStack)#%d (3) { ["parent"]=> NULL ["active"]=> @@ -178,12 +184,9 @@ object(DDTrace\RootSpanData)#%d (30) { ["spanCreationObservers"]=> array(0) { } - ["attributes"]=> - array(0) { - } } ["active"]=> - object(DDTrace\RootSpanData)#%d (30) { + object(DDTrace\RootSpanData)#%d (28) { ["name"]=> string(3) "foo" ["resource"]=> @@ -196,14 +199,22 @@ object(DDTrace\RootSpanData)#%d (30) { ["type"]=> string(3) "cli" ["meta"]=> - array(1) { + array(5) { ["runtime-id"]=> string(36) "%s" + ["service.name"]=> + string(14) "span_clone.php" + ["resource.name"]=> + string(3) "abc" + ["operation.name"]=> + string(3) "foo" + ["span.type"]=> + string(3) "cli" } ["metrics"]=> array(1) { ["process_id"]=> - float(%d) + int(%d) } ["exception"]=> NULL @@ -241,7 +252,7 @@ object(DDTrace\RootSpanData)#%d (30) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) } ["ignoreError"]=> bool(false)%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r @@ -249,9 +260,7 @@ object(DDTrace\RootSpanData)#%d (30) { array(0) { } ["samplingPriority"]=> - int(1073741824) - ["samplingMechanism"]=> - int(0)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r + int(1073741824)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r ["tracestateTags"]=> array(0) { }%r(\s*\["parentId"\]=>\s+uninitialized\(string\))?%r @@ -261,15 +270,10 @@ object(DDTrace\RootSpanData)#%d (30) { NULL ["inferredSpan"]=> NULL - ["hostname"]=> - string(0) "" } ["spanCreationObservers"]=> array(0) { } - ["attributes"]=> - array(0) { - } } ["onClose"]=> array(0) { @@ -290,7 +294,7 @@ object(DDTrace\RootSpanData)#%d (30) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) } ["ignoreError"]=> bool(false)%r(\s*\["origin"\]=>\s+uninitialized\(string\))?%r @@ -298,9 +302,7 @@ object(DDTrace\RootSpanData)#%d (30) { array(0) { } ["samplingPriority"]=> - int(1073741824) - ["samplingMechanism"]=> - int(0)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r + int(1073741824)%r(\s*\["propagatedSamplingPriority"\]=>\s+uninitialized\(int\)\s*\["tracestate"\]=>\s+uninitialized\(string\))?%r ["tracestateTags"]=> array(0) { }%r(\s*\["parentId"\]=>\s+uninitialized\(string\))?%r @@ -310,16 +312,10 @@ object(DDTrace\RootSpanData)#%d (30) { NULL ["inferredSpan"]=> NULL - ["hostname"]=> - string(0) "" } array(1) { [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -334,16 +330,12 @@ array(1) { string(14) "span_clone.php" ["type"]=> string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(6) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> diff --git a/tests/ext/sandbox/span_resource_serialization.phpt b/tests/ext/sandbox/span_resource_serialization.phpt index a2ef4740f56..fbd47988931 100644 --- a/tests/ext/sandbox/span_resource_serialization.phpt +++ b/tests/ext/sandbox/span_resource_serialization.phpt @@ -34,7 +34,7 @@ with_false(); with_empty_string(); with_value(); -foreach (dd_trace_serialize_closed_spans() as $span) { +foreach (dd_trace_serialize_closed_spans()['chunks'][0]['spans'] as $span) { echo "name: {$span['name']}; resource: {$span['resource']}\n"; } diff --git a/tests/ext/sandbox/spans_out_of_sync_01.phpt b/tests/ext/sandbox/spans_out_of_sync_01.phpt index 70825cb7e88..623ddad9bc7 100644 --- a/tests/ext/sandbox/spans_out_of_sync_01.phpt +++ b/tests/ext/sandbox/spans_out_of_sync_01.phpt @@ -18,7 +18,10 @@ echo 'Done.' . PHP_EOL; ?> --EXPECTF-- [ddtrace] [error] [%d] Cannot run tracing closure for dd_trace_serialize_closed_spans(); spans out of sync; This message is only displayed once. Specify DD_TRACE_ONCE_LOGS=0 to show all messages. -array(0) { +array(1) { + ["chunks"]=> + array(0) { + } } Done. [ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/sandbox/spans_out_of_sync_02.phpt b/tests/ext/sandbox/spans_out_of_sync_02.phpt index b0f949b2d87..2f7d1ee39f8 100644 --- a/tests/ext/sandbox/spans_out_of_sync_02.phpt +++ b/tests/ext/sandbox/spans_out_of_sync_02.phpt @@ -17,7 +17,10 @@ echo 'Done.' . PHP_EOL; ?> --EXPECTF-- [ddtrace] [error] [%d] Cannot run tracing closure for dd_trace_serialize_closed_spans(); spans out of sync; This message is only displayed once. Specify DD_TRACE_ONCE_LOGS=0 to show all messages. -array(0) { +array(1) { + ["chunks"]=> + array(0) { + } } Done. [ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/sandbox/spans_out_of_sync_03.phpt b/tests/ext/sandbox/spans_out_of_sync_03.phpt index 59f8162b59e..cd1dc41da5b 100644 --- a/tests/ext/sandbox/spans_out_of_sync_03.phpt +++ b/tests/ext/sandbox/spans_out_of_sync_03.phpt @@ -20,7 +20,10 @@ shutdown_and_flush(); echo 'Done.' . PHP_EOL; ?> --EXPECTF-- -array(0) { +array(1) { + ["chunks"]=> + array(0) { + } } [ddtrace] [error] [%d] Cannot run tracing closure for shutdown_and_flush(); spans out of sync; This message is only displayed once. Specify DD_TRACE_ONCE_LOGS=0 to show all messages. Done. diff --git a/tests/ext/sandbox/spans_out_of_sync_04.phpt b/tests/ext/sandbox/spans_out_of_sync_04.phpt index ce7480231be..add2b853f71 100644 --- a/tests/ext/sandbox/spans_out_of_sync_04.phpt +++ b/tests/ext/sandbox/spans_out_of_sync_04.phpt @@ -19,7 +19,10 @@ shutdown_and_flush(); echo 'Done.' . PHP_EOL; ?> --EXPECTF-- -array(0) { +array(1) { + ["chunks"]=> + array(0) { + } } [ddtrace] [error] [%d] Cannot run tracing closure for shutdown_and_flush(); spans out of sync; This message is only displayed once. Specify DD_TRACE_ONCE_LOGS=0 to show all messages. Done. diff --git a/tests/ext/sandbox/vm_var_types_return.phpt b/tests/ext/sandbox/vm_var_types_return.phpt index fd2a575719c..760603fec0b 100644 --- a/tests/ext/sandbox/vm_var_types_return.phpt +++ b/tests/ext/sandbox/vm_var_types_return.phpt @@ -54,7 +54,7 @@ array_map(function($span) { echo $span['name']; echo isset($span['resource']) ? ', ' . $span['resource'] : ''; echo PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); ?> --EXPECT-- int(42) diff --git a/tests/ext/sdk_otlp_export_marker.phpt b/tests/ext/sdk_otlp_export_marker.phpt index 0a9fb54f4b3..7d252d97089 100644 --- a/tests/ext/sdk_otlp_export_marker.phpt +++ b/tests/ext/sdk_otlp_export_marker.phpt @@ -1,5 +1,5 @@ --TEST-- -_dd.sdk.otlp_export marker is set to "false" on the first span of each trace chunk only +_dd.sdk.otlp_export marker is set to "false" on the payload, not on spans --ENV-- DD_TRACE_GENERATE_ROOT_SPAN=0 DD_TRACE_AUTO_FLUSH_ENABLED=0 @@ -14,19 +14,21 @@ for ($i = 0; $i < 2; $i++) { \DDTrace\close_span(); } -$seen = []; -foreach (dd_trace_serialize_closed_spans() as $span) { - $first = !isset($seen[$span['trace_id']]); - $seen[$span['trace_id']] = true; - echo ($first ? "first" : "other"), ": ", var_export($span['attributes']['_dd.sdk.otlp_export'] ?? null, true), "\n"; +$payload = dd_trace_serialize_closed_spans(); +echo "payload: ", var_export($payload['attributes']['_dd.sdk.otlp_export'] ?? null, true), "\n"; +foreach ($payload['chunks'] as $chunk) { + foreach ($chunk['spans'] as $span) { + echo $span['name'], ": ", var_export($span['attributes']['_dd.sdk.otlp_export'] ?? null, true), "\n"; + } } -echo count($seen), " chunks\n"; +echo count($payload['chunks']), " chunks\n"; ?> --EXPECT-- -first: 'false' -other: NULL -other: NULL -first: 'false' -other: NULL -other: NULL +payload: 'false' +root_1: NULL +child_1: NULL +grandchild_1: NULL +root_0: NULL +child_0: NULL +grandchild_0: NULL 2 chunks diff --git a/tests/ext/set_user_no_metadata.phpt b/tests/ext/set_user_no_metadata.phpt index 85d4265a52c..09d6be2a33b 100644 --- a/tests/ext/set_user_no_metadata.phpt +++ b/tests/ext/set_user_no_metadata.phpt @@ -8,9 +8,15 @@ var_dump($root->meta); ?> --EXPECTF-- -array(2) { +array(5) { ["runtime-id"]=> string(36) "%s" ["usr.id"]=> string(5) "admin" + ["service.name"]=> + string(24) "set_user_no_metadata.php" + ["operation.name"]=> + string(24) "set_user_no_metadata.php" + ["span.type"]=> + string(3) "cli" } diff --git a/tests/ext/set_user_with_metadata.phpt b/tests/ext/set_user_with_metadata.phpt index cbac308ce3e..aa009f52e9a 100644 --- a/tests/ext/set_user_with_metadata.phpt +++ b/tests/ext/set_user_with_metadata.phpt @@ -8,7 +8,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(4) { +array(7) { ["runtime-id"]=> string(36) "%s" ["usr.id"]=> @@ -17,4 +17,10 @@ array(4) { string(4) "none" ["usr.permissions"]=> string(3) "777" + ["service.name"]=> + string(26) "set_user_with_metadata.php" + ["operation.name"]=> + string(26) "set_user_with_metadata.php" + ["span.type"]=> + string(3) "cli" } diff --git a/tests/ext/set_user_with_propagation_by_default.phpt b/tests/ext/set_user_with_propagation_by_default.phpt index a62c87c1db1..60bf90a3e90 100644 --- a/tests/ext/set_user_with_propagation_by_default.phpt +++ b/tests/ext/set_user_with_propagation_by_default.phpt @@ -10,7 +10,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(5) { +array(8) { ["runtime-id"]=> string(36) "%s" ["usr.id"]=> @@ -21,4 +21,10 @@ array(5) { string(4) "none" ["usr.permissions"]=> string(3) "777" + ["service.name"]=> + string(40) "set_user_with_propagation_by_default.php" + ["operation.name"]=> + string(40) "set_user_with_propagation_by_default.php" + ["span.type"]=> + string(3) "cli" } diff --git a/tests/ext/set_user_with_propagation_override_default.phpt b/tests/ext/set_user_with_propagation_override_default.phpt index 73229fdabf0..d6ee5421514 100644 --- a/tests/ext/set_user_with_propagation_override_default.phpt +++ b/tests/ext/set_user_with_propagation_override_default.phpt @@ -8,7 +8,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(5) { +array(8) { ["runtime-id"]=> string(36) "%s" ["usr.id"]=> @@ -19,4 +19,10 @@ array(5) { string(4) "none" ["usr.permissions"]=> string(3) "777" + ["service.name"]=> + string(46) "set_user_with_propagation_override_default.php" + ["operation.name"]=> + string(46) "set_user_with_propagation_override_default.php" + ["span.type"]=> + string(3) "cli" } diff --git a/tests/ext/set_user_without_propagation_override_default.phpt b/tests/ext/set_user_without_propagation_override_default.phpt index 332ac3c36ed..371e34358c9 100644 --- a/tests/ext/set_user_without_propagation_override_default.phpt +++ b/tests/ext/set_user_without_propagation_override_default.phpt @@ -10,7 +10,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(4) { +array(7) { ["runtime-id"]=> string(36) "%s" ["usr.id"]=> @@ -19,4 +19,10 @@ array(4) { string(4) "none" ["usr.permissions"]=> string(3) "777" + ["service.name"]=> + string(49) "set_user_without_propagation_override_default.php" + ["operation.name"]=> + string(49) "set_user_without_propagation_override_default.php" + ["span.type"]=> + string(3) "cli" } diff --git a/tests/ext/sidecar_enabled.phpt b/tests/ext/sidecar_enabled.phpt index a8b80601868..03df5ed2447 100644 --- a/tests/ext/sidecar_enabled.phpt +++ b/tests/ext/sidecar_enabled.phpt @@ -1,13 +1,11 @@ --TEST-- -Sidecar should be enabled by default on PHP 8.4 +The sidecar trace sender is enabled by default --SKIPIF-- - + --FILE-- '1', ]); diff --git a/tests/ext/single-span_sampling/accept-single-span.phpt b/tests/ext/single-span_sampling/accept-single-span.phpt index a101cf2f429..06a6fe3581b 100644 --- a/tests/ext/single-span_sampling/accept-single-span.phpt +++ b/tests/ext/single-span_sampling/accept-single-span.phpt @@ -9,7 +9,7 @@ DD_SPAN_SAMPLING_RULES=[{"sample_rate":1}] DDTrace\start_span(); DDTrace\close_span(); -$attributes = dd_trace_serialize_closed_spans()[0]["attributes"]; +$attributes = dd_trace_serialize_closed_spans()['chunks'][0]['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"], diff --git a/tests/ext/single-span_sampling/check-sample-rate.phpt b/tests/ext/single-span_sampling/check-sample-rate.phpt index 03104991a16..12598f33a8d 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]["attributes"]; +$last = dd_trace_serialize_closed_spans()['chunks'][0]['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]["attributes"]; + $last = dd_trace_serialize_closed_spans()['chunks'][0]['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]["attributes"]; + $last = dd_trace_serialize_closed_spans()['chunks'][0]['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]["attributes"]; +$last = dd_trace_serialize_closed_spans()['chunks'][0]['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 1efa9984856..834bd3b915a 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]["attributes"]; + $last = dd_trace_serialize_closed_spans()['chunks'][0]['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]["attributes"]; + $last = dd_trace_serialize_closed_spans()['chunks'][0]['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]["attributes"]; + $last = dd_trace_serialize_closed_spans()['chunks'][0]['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 1c2dacae456..f341b4660e6 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]["attributes"]; + $last = dd_trace_serialize_closed_spans()['chunks'][0]['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]["attributes"]; + $last = dd_trace_serialize_closed_spans()['chunks'][0]['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 0b93c97006e..d06c6883eb0 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]["attributes"]["_dd.span_sampling.mechanism"] ?? 0) == 8); + var_dump((dd_trace_serialize_closed_spans()['chunks'][0]['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]["attributes"]["_dd.span_sampling.mechanism"] ?? 0) == 8); + var_dump((dd_trace_serialize_closed_spans()['chunks'][0]['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 4c9d625460e..0e334175d2c 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]["attributes"]; +$last = dd_trace_serialize_closed_spans()['chunks'][0]['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]["attributes"]; +$last = dd_trace_serialize_closed_spans()['chunks'][0]['spans'][0]["attributes"]; echo "sampling present after span of service a: "; var_dump(isset($last["_dd.span_sampling.mechanism"])); diff --git a/tests/ext/span_attributes_empty_keys.phpt b/tests/ext/span_attributes_empty_keys.phpt index aa75f194f89..89298343aea 100644 --- a/tests/ext/span_attributes_empty_keys.phpt +++ b/tests/ext/span_attributes_empty_keys.phpt @@ -15,7 +15,7 @@ $s->attributes = [ ]; \DDTrace\close_span(); -$attrs = dd_trace_serialize_closed_spans()[0]['attributes']; +$attrs = dd_trace_serialize_closed_spans()['chunks'][0]['spans'][0]['attributes']; foreach (['', 'empty', 'nested', 'list'] as $key) { echo var_export($key, true), ' => ', json_encode(isset($attrs[$key]) ? $attrs[$key] : null), "\n"; } diff --git a/tests/ext/span_attributes_input.phpt b/tests/ext/span_attributes_input.phpt index 60b4f712f77..345ceeae32a 100644 --- a/tests/ext/span_attributes_input.phpt +++ b/tests/ext/span_attributes_input.phpt @@ -1,16 +1,30 @@ --TEST-- -SpanData::$attributes is the tag store: typed values, $meta/$metrics writes land in it (last write wins), special keys lifted +SpanData::$attributes is a raw typed store; only $meta/$metrics writes map special keys onto span properties --ENV-- DD_TRACE_GENERATE_ROOT_SPAN=0 DD_TRACE_AUTO_FLUSH_ENABLED=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 --FILE-- name = 'original.name'; -$s->attributes = [ +$special = [ + 'service.name' => 'special-service', + 'resource.name' => 'special-resource', + 'operation.name' => 'Special.Operation', + 'span.type' => 'special-type', + 'env' => 'special-env', + 'version' => 'special-version', + 'component' => 'special-component', + 'span.kind' => 'client', + 'error.ignored' => true, +]; + +// Attributes keep every key, typed, special keys included; no property is set from them +$raw = \DDTrace\start_span(); +$raw->name = 'raw.name'; +$raw->attributes = $special + [ 'int' => 42, 'float' => 1.5, 'bool' => true, @@ -19,69 +33,81 @@ $s->attributes = [ 'list' => [1, 'two', false], 'map' => ['k' => 'v', 'n' => [3]], 'object' => new Point, - // overwritten below through $meta / $metrics - 'both' => 'from attributes', - 'all' => 'from attributes', - // special keys - 'service.name' => 'attr-service', - 'resource.name' => 'attr-resource', - 'operation.name' => 'Attr.Operation', - 'span.type' => 'attr-type', - 'env' => 'attr-env', - 'version' => 'attr-version', - 'component' => 'attr-component', - 'span.kind' => 'client', - 'analytics.event' => true, 'http.status_code' => 404, '_sampling_priority_v1' => 2, '_dd1.sr.eausr' => 1, - 'error.ignored' => true, + // overwritten below through $meta / $metrics + 'both' => 'from attributes', + 'all' => 'from attributes', ]; -$s->meta['both'] = 'from meta'; -$s->meta['all'] = 'from meta'; -$s->meta['meta_only'] = 'from meta'; -$s->meta['meta_metric'] = 'from meta'; -$s->metrics['all'] = 3; -$s->metrics['meta_metric'] = 4; -$s->metrics['metric_only'] = 5; -$s->exception = new Exception('ignored via the attributes tag'); +$raw->meta['both'] = 'from meta'; +$raw->meta['all'] = 'from meta'; +$raw->meta['meta_only'] = 'from meta'; +$raw->meta['meta_metric'] = 'from meta'; +$raw->metrics['all'] = 3; +$raw->metrics['meta_metric'] = 4; +$raw->metrics['metric_only'] = 5; +$raw->exception = new Exception('not ignored by the error.ignored attribute'); \DDTrace\close_span(); -$span = dd_trace_serialize_closed_spans()[0]; -foreach (['name', 'resource', 'service', 'type', 'env', 'version', 'component', 'span_kind'] as $field) { - echo "$field: ", var_export(isset($span[$field]) ? $span[$field] : null, true), "\n"; +// $meta writes of special keys set the properties and read back through $meta +$viaMeta = \DDTrace\start_span(); +$viaMeta->name = 'meta.name'; +foreach ($special as $key => $value) { + $viaMeta->meta[$key] = $value; } -echo "error: ", isset($span['error']) ? $span['error'] : 0, "\n"; -$attrs = $span['attributes']; -foreach (['runtime-id', 'process_id', '_dd.p.tid', '_dd.p.dm', '_dd.tags.process', '_dd.sdk.otlp_export', '_dd.agent_psr', '_dd.svc_src', 'php.compilation.total_time_ms', 'php.memory.peak_real_usage_bytes', 'php.memory.peak_usage_bytes'] as $volatile) { - unset($attrs[$volatile]); +echo "meta read-back: component=", var_export($viaMeta->meta['component'], true), " span.kind=", var_export($viaMeta->meta['span.kind'], true), "\n"; +$viaMeta->exception = new Exception('ignored via $meta'); +\DDTrace\close_span(); + +$volatile = array_flip(['runtime-id', 'process_id', '_dd.p.tid', '_dd.p.dm', '_dd.tags.process', '_dd.sdk.otlp_export', '_dd.agent_psr', '_dd.svc_src', '_dd.base_service', 'php.compilation.total_time_ms', 'php.memory.peak_real_usage_bytes', 'php.memory.peak_usage_bytes', 'error.stack']); +foreach (array_reverse(dd_clean_spans()) as $span) { + echo "== {$span['name']}\n"; + foreach (['resource', 'service', 'type', 'env', 'version', 'component', 'span_kind'] as $field) { + echo "$field: ", var_export(isset($span[$field]) ? $span[$field] : null, true), "\n"; + } + echo "error: ", isset($span['error']) ? $span['error'] : 0, "\n"; + $attrs = array_diff_key($span['attributes'], $volatile); + ksort($attrs); + var_dump($attrs); } -ksort($attrs); -var_dump($attrs); ?> ---EXPECT-- -name: 'attr.operation' -resource: 'attr-resource' -service: 'attr-service' -type: 'attr-type' -env: 'attr-env' -version: 'attr-version' -component: 'attr-component' -span_kind: 3 -error: 0 -array(14) { +--EXPECTF-- +meta read-back: component='special-component' span.kind='client' +== raw.name +resource: 'raw.name' +service: 'span_attributes_input.php' +type: 'cli' +env: NULL +version: NULL +component: NULL +span_kind: NULL +error: 1 +array(26) { ["_dd1.sr.eausr"]=> - float(1) + int(1) + ["_sampling_priority_v1"]=> + int(2) ["all"]=> float(3) ["bool"]=> bool(true) ["both"]=> string(9) "from meta" + ["component"]=> + string(17) "special-component" + ["env"]=> + string(11) "special-env" + ["error.ignored"]=> + bool(true) + ["error.message"]=> + string(%d) "Uncaught Exception: not ignored by the error.ignored attribute in %s" + ["error.type"]=> + string(9) "Exception" ["float"]=> float(1.5) ["http.status_code"]=> - string(3) "404" + int(404) ["int"]=> int(42) ["list"]=> @@ -114,6 +140,29 @@ array(14) { ["x"]=> int(1) } + ["operation.name"]=> + string(17) "Special.Operation" + ["resource.name"]=> + string(16) "special-resource" + ["service.name"]=> + string(15) "special-service" + ["span.kind"]=> + string(6) "client" + ["span.type"]=> + string(12) "special-type" ["string"]=> string(3) "str" + ["version"]=> + string(15) "special-version" +} +== special.operation +resource: 'special-resource' +service: 'special-service' +type: 'special-type' +env: 'special-env' +version: 'special-version' +component: 'special-component' +span_kind: 3 +error: 0 +array(0) { } \ No newline at end of file diff --git a/tests/ext/span_data_attributes_init.phpt b/tests/ext/span_data_attributes_init.phpt index bacd6de58ac..b93030cd001 100644 --- a/tests/ext/span_data_attributes_init.phpt +++ b/tests/ext/span_data_attributes_init.phpt @@ -1,10 +1,10 @@ --TEST-- -Directly constructed span/stack objects expose an initialized attributes array +Directly constructed span objects expose an initialized attributes array --DESCRIPTION-- The declared `public array $attributes = []` must materialize to an empty array on -every PHP version. On PHP 7 the create_object callbacks (dd_init_span_data_object, -ddtrace_span_stack_create) must init property_attributes explicitly, since typed -array properties there default to NULL rather than their stub default. +every PHP version. On PHP 7 the create_object callback (dd_init_span_data_object) +must init property_attributes explicitly, since typed array properties there +default to NULL rather than their stub default. --FILE-- attributes); var_dump((new \DDTrace\RootSpanData())->attributes); var_dump((new \DDTrace\InferredSpanData())->attributes); -var_dump((new \DDTrace\SpanStack())->attributes); var_dump((new UserSpan())->attributes); $span = new UserSpan(); $span->attributes['k'] = 'v'; var_dump($span->attributes); -// Tracer-created spans and stacks go through the same create_object callbacks. +// Tracer-created spans go through the same create_object callback. $s = \DDTrace\start_span(); -var_dump($s->attributes, $s->stack->attributes); +var_dump($s->attributes); \DDTrace\close_span(); ?> --EXPECT-- @@ -35,13 +34,9 @@ array(0) { } array(0) { } -array(0) { -} array(1) { ["k"]=> string(1) "v" } array(0) { } -array(0) { -} diff --git a/tests/ext/span_data_meta_view.phpt b/tests/ext/span_data_meta_view.phpt index c86802fa5b1..ca0c13a342f 100644 --- a/tests/ext/span_data_meta_view.phpt +++ b/tests/ext/span_data_meta_view.phpt @@ -73,7 +73,7 @@ $s2->name = 's2'; $s2->meta['team'] = 'b'; \DDTrace\close_span(); \DDTrace\close_span(); -foreach (dd_trace_serialize_closed_spans() as $serialized) { +foreach (dd_trace_serialize_closed_spans()['chunks'][0]['spans'] as $serialized) { if (in_array($serialized['name'], ['s1', 's2'])) { echo $serialized['name'], ': team=', $serialized['attributes']['team'] ?? 'unset', ' region=', $serialized['attributes']['region'], "\n"; } @@ -116,17 +116,23 @@ array(3) { string(0) "" } -- whole-array assignment replaces the bucket -array(1) { +array(3) { ["only"]=> string(4) "this" + ["service.name"]=> + string(23) "span_data_meta_view.php" + ["span.type"]=> + string(3) "cli" } float(3) bool(false) -- iteration and the view object only=this k2=v2 +service.name=span_data_meta_view.php +span.type=cli string(20) "DDTrace\SpanTagsView" -int(2) +int(4) bool(true) bool(true) bool(true) diff --git a/tests/ext/span_ignore_error.phpt b/tests/ext/span_ignore_error.phpt index 513c8c6190a..b534143bc61 100644 --- a/tests/ext/span_ignore_error.phpt +++ b/tests/ext/span_ignore_error.phpt @@ -19,7 +19,7 @@ function run($label, $ignore) { $root->exception = $e; $ignore($root); \DDTrace\close_span(); - foreach (dd_trace_serialize_closed_spans() as $span) { + foreach (dd_trace_serialize_closed_spans()['chunks'][0]['spans'] as $span) { $attrs = isset($span['attributes']) ? $span['attributes'] : []; $errorTags = array_filter(array_keys($attrs), function ($k) { return strpos($k, 'error') === 0; }); sort($errorTags); @@ -35,7 +35,7 @@ run('property', function ($root) { $root->ignoreError = true; }); run('deprecated tag', function ($root) { $root->meta['error.ignored'] = 1; }); run('deprecated falsy tag cannot unset the property', function ($root) { $root->ignoreError = true; $root->meta['error.ignored'] = 0; }); run('deprecated falsy tag alone', function ($root) { $root->meta['error.ignored'] = 0; }); -run('falsy attributes tag does not mask a truthy meta tag', function ($root) { $root->attributes['error.ignored'] = 0; $root->meta['error.ignored'] = 1; }); +run('an error.ignored attribute is a plain attribute', function ($root) { $root->attributes['error.ignored'] = true; }); ?> --EXPECT-- bool(false) @@ -59,7 +59,7 @@ deprecated falsy tag alone root: error=1 error tags=[error.message,error.stack,error.type] track_error=- child: error=1 error tags=[error.message,error.stack,error.type] track_error=- root ignoreError after flush: false -falsy attributes tag does not mask a truthy meta tag - root: error=0 error tags=[] track_error=- - child: error=1 error tags=[error.message,error.stack,error.type] track_error=false - root ignoreError after flush: true +an error.ignored attribute is a plain attribute + root: error=1 error tags=[error.ignored,error.message,error.stack,error.type] track_error=- + child: error=1 error tags=[error.message,error.stack,error.type] track_error=- + root ignoreError after flush: false diff --git a/tests/ext/span_kind_meta_fallback_promoted.phpt b/tests/ext/span_kind_meta_fallback_promoted.phpt index b764dc426e5..b1e39379845 100644 --- a/tests/ext/span_kind_meta_fallback_promoted.phpt +++ b/tests/ext/span_kind_meta_fallback_promoted.phpt @@ -17,7 +17,7 @@ $s->service = "web"; $s->meta["span.kind"] = "server"; // meta only, no $s->kind property \DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; $root = $spans[0]; // server == OTEL SpanKind 2; promoted from meta fallback (dd_span_kind_meta_to_otel). The serializer // consumes meta["span.kind"] once promoted, so the introspection (pre-encode builder) view no longer diff --git a/tests/ext/span_link_event_recursive_attributes.phpt b/tests/ext/span_link_event_recursive_attributes.phpt index 9363a9061eb..137935fa7ea 100644 --- a/tests/ext/span_link_event_recursive_attributes.phpt +++ b/tests/ext/span_link_event_recursive_attributes.phpt @@ -1,5 +1,5 @@ --TEST-- -Self-referencing span link, event and meta attributes serialize with a bounded "" placeholder +Self-referencing span link, event and meta attributes serialize with a "*RECURSION*" placeholder --ENV-- DD_TRACE_DEBUG_PRNG_SEED=42 --FILE-- @@ -37,7 +37,7 @@ DDTrace\trace_function('foo', function (\DDTrace\SpanData $span) { foo(); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; foreach ([$spans[0]['span_links'][0]['attributes'], $spans[0]['span_events'][0]['attributes']] as $attrs) { $dt = $attrs['dt']; unset($attrs['dt']); @@ -48,10 +48,10 @@ var_dump($spans[0]['attributes']['dt']['self']); ?> --EXPECT-- -{"arr":["x",""],"obj":{"v":1,"self":""},"ao":{"d":2,"self":""},"empty":[]} -string(0) "" +{"arr":["x","*RECURSION*"],"obj":{"v":1,"self":"*RECURSION*"},"ao":{"d":2,"self":"*RECURSION*"},"empty":[]} +string(11) "*RECURSION*" string(3) "UTC" -{"arr":["x",""],"obj":{"v":1,"self":""},"ao":{"d":2,"self":""},"empty":[]} -string(0) "" +{"arr":["x","*RECURSION*"],"obj":{"v":1,"self":"*RECURSION*"},"ao":{"d":2,"self":"*RECURSION*"},"empty":[]} +string(11) "*RECURSION*" string(3) "UTC" -string(0) "" +string(11) "*RECURSION*" diff --git a/tests/ext/span_link_typed_scalar_attributes.phpt b/tests/ext/span_link_typed_scalar_attributes.phpt new file mode 100644 index 00000000000..aa36fc110cb --- /dev/null +++ b/tests/ext/span_link_typed_scalar_attributes.phpt @@ -0,0 +1,42 @@ +--TEST-- +Span link scalar attributes keep their PHP type when serialized +--ENV-- +DD_TRACE_DEBUG_PRNG_SEED=42 +--FILE-- +name = 'foo'; + + $link = new SpanLink(); + $link->traceId = "42"; + $link->spanId = "6"; + $link->attributes = ['t' => true, 'f' => false, 'i' => 42, 'd' => 1.5, 's' => 'str', 'n' => null]; + $span->links[] = $link; +}); + +foo(); + +$spans = dd_clean_spans(); +var_dump($spans[0]['span_links'][0]['attributes']); +?> +--EXPECT-- +array(6) { + ["t"]=> + bool(true) + ["f"]=> + bool(false) + ["i"]=> + int(42) + ["d"]=> + float(1.5) + ["s"]=> + string(3) "str" + ["n"]=> + string(4) "null" +} diff --git a/tests/ext/span_meta_alias_read.phpt b/tests/ext/span_meta_alias_read.phpt new file mode 100644 index 00000000000..007aee89d37 --- /dev/null +++ b/tests/ext/span_meta_alias_read.phpt @@ -0,0 +1,92 @@ +--TEST-- +$meta reads return the span properties that $meta writes of the legacy keys set +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--FILE-- + 'svc', + 'resource.name' => 'res', + 'operation.name' => 'Op.Name', + 'span.type' => 'web', + 'env' => 'e1', + 'version' => 'v1', + 'component' => 'c1', + 'span.kind' => 'client', + 'error.ignored' => true, +]; + +$span = \DDTrace\start_span(); +$view = &$span->meta; +foreach ($aliases as $key => $value) { + $span->meta[$key] = $value; + $meta = $span->meta; + echo "$key: isset=", var_export(isset($span->meta[$key]), true), + " read=", var_export($span->meta[$key], true), + " view=", var_export($view[$key], true), + " listed=", var_export($meta[$key] ?? null, true), "\n"; +} +echo "count matches: ", var_export(count($view) === count($span->meta), true), "\n"; +var_dump($span->attributes); + +echo "-- the property wins over a same-named attribute\n"; +$span->attributes['component'] = 'raw-component'; +$span->meta['component'] = 'c2'; +var_dump($span->meta['component'], $view['component'], $span->component, $span->attributes['component']); +echo "count matches: ", var_export(count($view) === count($span->meta), true), "\n"; + +echo "-- unset clears both\n"; +unset($span->meta['component']); +var_dump(isset($span->meta['component']), isset($view['component']), $span->component, isset($span->attributes['component'])); + +echo "-- an attribute shows while the property is unset\n"; +unset($view['env']); +$span->attributes['env'] = 'raw-env'; +var_dump($span->env, $span->meta['env'], $view['env']); + +echo "-- a bulk write leaves unchanged aliases alone\n"; +$span->name = 'Mixed.Case'; +$span->meta += ['added' => 'yes']; +var_dump($span->name, $span->env, $span->attributes['env'], $span->meta['added']); +unset($view); +\DDTrace\close_span(); +?> +--EXPECTF-- +service.name: isset=true read='svc' view='svc' listed='svc' +resource.name: isset=true read='res' view='res' listed='res' +operation.name: isset=true read='op.name' view='op.name' listed='op.name' +span.type: isset=true read='web' view='web' listed='web' +env: isset=true read='e1' view='e1' listed='e1' +version: isset=true read='v1' view='v1' listed='v1' +component: isset=true read='c1' view='c1' listed='c1' +span.kind: isset=true read='client' view='client' listed='client' +error.ignored: isset=true read='true' view='true' listed='true' +count matches: true +array(2) { + ["runtime-id"]=> + string(36) "%s" + ["process_id"]=> + int(%d) +} +-- the property wins over a same-named attribute +string(2) "c2" +string(2) "c2" +string(2) "c2" +string(13) "raw-component" +count matches: true +-- unset clears both +bool(false) +bool(false) +string(0) "" +bool(false) +-- an attribute shows while the property is unset +string(0) "" +string(7) "raw-env" +string(7) "raw-env" +-- a bulk write leaves unchanged aliases alone +string(10) "Mixed.Case" +string(0) "" +string(7) "raw-env" +string(3) "yes" diff --git a/tests/ext/span_stack/stack_dropped_parent.phpt b/tests/ext/span_stack/stack_dropped_parent.phpt index 7258df16cb3..4fcae0f828d 100644 --- a/tests/ext/span_stack/stack_dropped_parent.phpt +++ b/tests/ext/span_stack/stack_dropped_parent.phpt @@ -17,7 +17,7 @@ DDTrace\switch_stack($stack); DDTrace\start_span(); DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; var_dump(count($spans)); var_dump(isset($spans[0]["parent_id"])); diff --git a/tests/ext/span_stack/start_span_stack.phpt b/tests/ext/span_stack/start_span_stack.phpt index 77a08041bb2..c3136354ac8 100644 --- a/tests/ext/span_stack/start_span_stack.phpt +++ b/tests/ext/span_stack/start_span_stack.phpt @@ -24,7 +24,7 @@ print 'And updates DDTrace\active_stack(): '; var_dump($new_stack == DDTrace\act print 'Also updates the active span of the stack: '; var_dump($new_stack->active == $stack_span); print 'Which is also reflected in the globally active span: '; var_dump(DDTrace\active_span() == $stack_span); print 'That new span on the span stack has the same parent: '; var_dump($stack_span->parent == $primary_active); -print 'That new span stack does not touch trace id: '; var_dump($stack_span->id != DDTrace\trace_id()); +print 'That new span stack does not touch trace id: '; var_dump($stack_span->hexId() != substr(DDTrace\root_span()->traceId, 16)); DDTrace\close_span(); echo 'Verify the stack_span stays if spans on that stack are closed: '; var_dump($new_stack == DDTrace\active_stack()); diff --git a/tests/ext/span_with_removed_exception.phpt b/tests/ext/span_with_removed_exception.phpt index f09f177e2ca..384c21d1876 100644 --- a/tests/ext/span_with_removed_exception.phpt +++ b/tests/ext/span_with_removed_exception.phpt @@ -54,11 +54,7 @@ try { --EXPECTF-- array(1) { [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -73,16 +69,12 @@ array(1) { string(31) "span_with_removed_exception.php" ["type"]=> string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(6) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> @@ -96,11 +88,7 @@ array(1) { } array(1) { [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -115,16 +103,12 @@ array(1) { string(31) "span_with_removed_exception.php" ["type"]=> string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(6) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> @@ -138,11 +122,7 @@ array(1) { } array(1) { [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -157,16 +137,12 @@ array(1) { string(31) "span_with_removed_exception.php" ["type"]=> string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(6) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> diff --git a/tests/ext/start_span_with_all_properties.phpt b/tests/ext/start_span_with_all_properties.phpt index c264bafd55a..259d597b75c 100644 --- a/tests/ext/start_span_with_all_properties.phpt +++ b/tests/ext/start_span_with_all_properties.phpt @@ -58,11 +58,7 @@ bool(true) float(2000000000) array(2) { [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -77,16 +73,12 @@ array(2) { string(34) "start_span_with_all_properties.php" ["type"]=> string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(6) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> @@ -98,11 +90,7 @@ array(2) { } } [1]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -117,10 +105,6 @@ array(2) { string(4) "test" ["type"]=> string(6) "runner" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(9) { ["runtime-id"]=> diff --git a/tests/ext/start_span_without_closing.phpt b/tests/ext/start_span_without_closing.phpt index eca8c28fab7..fe91e3a20fb 100644 --- a/tests/ext/start_span_without_closing.phpt +++ b/tests/ext/start_span_without_closing.phpt @@ -30,11 +30,7 @@ var_dump(dd_clean_spans()); [ddtrace] [warning] [%d] Found unfinished span while automatically closing spans with name 'my precious span' array(1) { [0]=> - array(12) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["start"]=> @@ -49,16 +45,12 @@ array(1) { string(30) "start_span_without_closing.php" ["type"]=> string(3) "cli" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(6) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> diff --git a/tests/ext/start_span_without_closing_autofinish.phpt b/tests/ext/start_span_without_closing_autofinish.phpt index 338eefdb7dd..c055b4655c8 100644 --- a/tests/ext/start_span_without_closing_autofinish.phpt +++ b/tests/ext/start_span_without_closing_autofinish.phpt @@ -28,11 +28,7 @@ var_dump(dd_clean_spans()); [ddtrace] [warning] [%d] Found unfinished span while automatically closing spans with name 'my precious span' array(2) { [0]=> - array(10) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(8) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -51,9 +47,7 @@ array(2) { string(3) "cli" } [1]=> - array(9) { - ["trace_id"]=> - string(%d) "%d" + array(8) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> diff --git a/tests/ext/startup_logging.phpt b/tests/ext/startup_logging.phpt index d5eea598fdb..163d719140b 100644 --- a/tests/ext/startup_logging.phpt +++ b/tests/ext/startup_logging.phpt @@ -9,8 +9,6 @@ $logs = dd_get_startup_logs(['-ddatadog.trace.sources_path='], ['DD_TRACE_DEBUG' // Ignore any Agent connection errors for now unset($logs['agent_error']); -// Ignore sidecar config as it depends on specific versions of PHP for now -unset($logs['sidecar_trace_sender']); dd_dump_startup_logs($logs); ?> @@ -28,7 +26,6 @@ service: null enabled_cli: %s agent_url: "%s" debug: true -analytics_enabled: false sample_rate: -1 sampling_rules: [] tags: [] @@ -51,6 +48,7 @@ report_hostname_on_root_span: false traced_internal_functions: null enabled_from_env: true opcache.file_cache: null +sidecar_trace_sender: true dynamic_instrumentation_enabled: false exception_replay_enabled: false otlp_traces_export_enabled: false diff --git a/tests/ext/startup_logging_json.phpt b/tests/ext/startup_logging_json.phpt index 92c30bb4d06..1191b8f3c40 100644 --- a/tests/ext/startup_logging_json.phpt +++ b/tests/ext/startup_logging_json.phpt @@ -11,8 +11,6 @@ $logs = json_decode(\DDTrace\startup_logs(), true); // Ignore any Agent connection errors for now unset($logs['agent_error']); -// Ignore sidecar config as it depends on specific versions of PHP for now -unset($logs['sidecar_trace_sender']); dd_dump_startup_logs($logs); ?> @@ -29,7 +27,6 @@ service: null enabled_cli: %s agent_url: "%s" debug: false -analytics_enabled: false sample_rate: -1 sampling_rules: [] tags: [] @@ -52,6 +49,7 @@ report_hostname_on_root_span: false traced_internal_functions: null enabled_from_env: true opcache.file_cache: null +sidecar_trace_sender: true dynamic_instrumentation_enabled: false exception_replay_enabled: false otlp_traces_export_enabled: false diff --git a/tests/ext/startup_logging_skipif_unix_83.inc b/tests/ext/startup_logging_skipif_unix_83.inc deleted file mode 100644 index f38a7198601..00000000000 --- a/tests/ext/startup_logging_skipif_unix_83.inc +++ /dev/null @@ -1,6 +0,0 @@ -name = 'op'; \DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); -$processTags = $spans[0]['attributes']['_dd.tags.process']; +$processTags = dd_trace_serialize_closed_spans()['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 a5b19cf02ff..4eaf449e06e 100644 --- a/tests/ext/svc_auto_tag_otel.phpt +++ b/tests/ext/svc_auto_tag_otel.phpt @@ -11,8 +11,7 @@ $span = \DDTrace\start_span(); $span->name = 'op'; \DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); -$processTags = $spans[0]['attributes']['_dd.tags.process']; +$processTags = dd_trace_serialize_closed_spans()['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 244049d066f..f6721d96a13 100644 --- a/tests/ext/svc_runtime_change.phpt +++ b/tests/ext/svc_runtime_change.phpt @@ -7,8 +7,7 @@ DD_TRACE_AUTO_FLUSH_ENABLED=0 --FILE-- name = 'child'; \DDTrace\close_span(); $byName = []; -foreach (dd_trace_serialize_closed_spans() as $s) { $byName[$s['name']] = $s; } +foreach (dd_trace_serialize_closed_spans()['chunks'][0]['spans'] as $s) { $byName[$s['name']] = $s; } echo "root service: " . $byName['root']['service'] . "\n"; echo "child service: " . $byName['child']['service'] . "\n"; echo "root svc_src: " . ($byName['root']['attributes']['_dd.svc_src'] ?? '(unset)') . "\n"; diff --git a/tests/ext/svc_src_inheritance.phpt b/tests/ext/svc_src_inheritance.phpt index c330b7c7d4e..e1cf7d9512d 100644 --- a/tests/ext/svc_src_inheritance.phpt +++ b/tests/ext/svc_src_inheritance.phpt @@ -17,7 +17,7 @@ $child->name = 'child'; \DDTrace\close_span(); $byName = []; -foreach (dd_trace_serialize_closed_spans() as $s) { $byName[$s['name']] = $s; } +foreach (dd_trace_serialize_closed_spans()['chunks'][0]['spans'] as $s) { $byName[$s['name']] = $s; } echo "root svc_src: " . ($byName['root']['attributes']['_dd.svc_src'] ?? '(unset)') . "\n"; echo "child svc_src: " . ($byName['child']['attributes']['_dd.svc_src'] ?? '(unset)') . "\n"; ?> diff --git a/tests/ext/svc_src_manual_override.phpt b/tests/ext/svc_src_manual_override.phpt index f27a58c91ca..57f5cf4062e 100644 --- a/tests/ext/svc_src_manual_override.phpt +++ b/tests/ext/svc_src_manual_override.phpt @@ -17,7 +17,7 @@ $child->service = 'overridden'; \DDTrace\close_span(); $byName = []; -foreach (dd_trace_serialize_closed_spans() as $s) { $byName[$s['name']] = $s; } +foreach (dd_trace_serialize_closed_spans()['chunks'][0]['spans'] as $s) { $byName[$s['name']] = $s; } echo "root svc_src: " . ($byName['root']['attributes']['_dd.svc_src'] ?? '(unset)') . "\n"; echo "child svc_src: " . ($byName['child']['attributes']['_dd.svc_src'] ?? '(unset)') . "\n"; ?> diff --git a/tests/ext/svc_user_tag.phpt b/tests/ext/svc_user_tag.phpt index e5641d1101a..c8e6837d4f5 100644 --- a/tests/ext/svc_user_tag.phpt +++ b/tests/ext/svc_user_tag.phpt @@ -11,8 +11,7 @@ $span = \DDTrace\start_span(); $span->name = 'op'; \DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); -$processTags = $spans[0]['attributes']['_dd.tags.process']; +$processTags = dd_trace_serialize_closed_spans()['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/integration.phpt b/tests/ext/telemetry/integration.phpt index 984c0b060e1..959465bc328 100644 --- a/tests/ext/telemetry/integration.phpt +++ b/tests/ext/telemetry/integration.phpt @@ -24,7 +24,7 @@ namespace DDTrace\Test { static function init(): int { - dd_trace_method("Test", "public_static_method", function() { + \DDTrace\trace_method("Test", "public_static_method", function() { echo "test_access hook" . PHP_EOL; }); return self::LOADED; diff --git a/tests/ext/telemetry/metrics_spans_created.phpt b/tests/ext/telemetry/metrics_spans_created.phpt index b83f147f9aa..46d11dbe9a4 100644 --- a/tests/ext/telemetry/metrics_spans_created.phpt +++ b/tests/ext/telemetry/metrics_spans_created.phpt @@ -25,14 +25,14 @@ namespace DDTrace\Test { static function init(): int { - dd_trace_method("Test", "create_span_from_anomymous_source", function() { + \DDTrace\trace_method("Test", "create_span_from_anomymous_source", function() { }); - dd_trace_method("Test", "create_span_from_named_integration", function(\DDTrace\SpanData $span, array $args) { + \DDTrace\trace_method("Test", "create_span_from_named_integration", function(\DDTrace\SpanData $span, array $args) { $span->meta['component'] = $args[0]; }); - dd_trace_method("Test", "create_span_with_flag", function(\DDTrace\SpanData $span, array $args) { + \DDTrace\trace_method("Test", "create_span_with_flag", function(\DDTrace\SpanData $span, array $args) { \DDTrace\Internal\add_span_flag($span, $args[0]); }); diff --git a/tests/ext/test_special_attributes.phpt b/tests/ext/test_special_attributes.phpt index 2f010af5034..43d7485f14f 100644 --- a/tests/ext/test_special_attributes.phpt +++ b/tests/ext/test_special_attributes.phpt @@ -13,17 +13,16 @@ function greet($name) $span->meta['resource.name'] = 'new.resource'; $span->meta['span.type'] = 'new.type'; $span->meta['service.name'] = 'new.service'; - $span->meta['analytics.event'] = 'true'; return "Hello $name!"; } -\DDTrace\trace_function('greet', function (\DDTrace\SpanData $span) { +// The prehook sets the properties first, so the later $meta writes override them +\DDTrace\trace_function('greet', ['prehook' => function (\DDTrace\SpanData $span) { $span->name = 'old.name'; $span->resource = 'old.resource'; $span->type = 'old.type'; $span->service = 'old.service'; - $span->metrics['_dd1.sr.eausr'] = 0; -}); +}]); greet('World'); @@ -33,11 +32,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -55,9 +50,7 @@ array(1) { ["type"]=> string(8) "new.type" ["attributes"]=> - array(3) { - ["_dd1.sr.eausr"]=> - float(1) + array(2) { ["_dd.svc_src"]=> string(1) "m" ["_dd.base_service"]=> diff --git a/tests/ext/test_special_attributes_bis.phpt b/tests/ext/test_special_attributes_bis.phpt index d0486fc96a6..81d5c3f4df6 100644 --- a/tests/ext/test_special_attributes_bis.phpt +++ b/tests/ext/test_special_attributes_bis.phpt @@ -14,17 +14,16 @@ function greet($name) $span->meta['resource.name'] = 'new.resource'; $span->meta['span.type'] = 'new.type'; $span->meta['service.name'] = 'new.service'; - $span->meta['analytics.event'] = true; return "Hello $name!"; } -\DDTrace\trace_function('greet', function (\DDTrace\SpanData $span) { +// The prehook sets the properties first, so the later $meta writes override them +\DDTrace\trace_function('greet', ['prehook' => function (\DDTrace\SpanData $span) { $span->name = 'old.name'; $span->resource = 'old.resource'; $span->type = 'old.type'; $span->service = 'old.service'; - $span->metrics['_dd1.sr.eausr'] = 0; -}); +}]); greet('World'); @@ -34,11 +33,7 @@ var_dump(dd_clean_spans()); --EXPECTF-- array(1) { [0]=> - array(11) { - ["trace_id"]=> - string(%d) "%d" - ["trace_id_high"]=> - string(16) "%s" + array(9) { ["span_id"]=> string(%d) "%d" ["parent_id"]=> @@ -56,9 +51,7 @@ array(1) { ["type"]=> string(8) "new.type" ["attributes"]=> - array(3) { - ["_dd1.sr.eausr"]=> - float(1) + array(2) { ["_dd.svc_src"]=> string(1) "m" ["_dd.base_service"]=> diff --git a/tests/ext/traced_attribute.phpt b/tests/ext/traced_attribute.phpt index 99e6e1b45d6..d2ddccf6484 100644 --- a/tests/ext/traced_attribute.phpt +++ b/tests/ext/traced_attribute.phpt @@ -11,7 +11,7 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 include __DIR__ . '/sandbox/dd_dumper.inc'; class Foo { - #[DDTrace\Trace(name: "simplename", resource: "rsrc", type: "typeee", service: "test", tags: ["a" => "b", "data" => "dog", 1 => "ignored"])] + #[DDTrace\Trace(name: "simplename", resource: "rsrc", type: "typeee", service: "test", attributes: ["a" => "b", "data" => "dog", 1 => "ignored"])] static function simple($arg) {} /* #[DDTrace\Trace(saveArgs: ["foo"])] diff --git a/tests/ext/traced_attribute_attributes_recursive_and_empty.phpt b/tests/ext/traced_attribute_attributes_recursive_and_empty.phpt new file mode 100644 index 00000000000..1608ce943df --- /dev/null +++ b/tests/ext/traced_attribute_attributes_recursive_and_empty.phpt @@ -0,0 +1,33 @@ +--TEST-- +#[DDTrace\Trace] attributes: a self-referencing object attribute becomes "*RECURSION*" at the cycle, and empty attributes are accepted +--SKIPIF-- + +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--FILE-- +me = $this; } +} + +#[DDTrace\Trace(name: "recursive", attributes: ["s" => new SelfRef])] +function recursive() {} + +#[DDTrace\Trace(name: "empty", attributes: [])] +function emptyAttributes() {} + +recursive(); +emptyAttributes(); + +foreach (dd_clean_spans() as $span) { + echo $span['name'], ": ", json_encode(isset($span['attributes']['s']) ? $span['attributes']['s'] : null), "\n"; +} +?> +--EXPECT-- +empty: null +recursive: {"me":"*RECURSION*","v":1} diff --git a/tests/ext/traced_attribute_kind_component.phpt b/tests/ext/traced_attribute_kind_component.phpt new file mode 100644 index 00000000000..a8726a26ed4 --- /dev/null +++ b/tests/ext/traced_attribute_kind_component.phpt @@ -0,0 +1,35 @@ +--TEST-- +#[DDTrace\Trace] kind and component set the span properties; same-named $attributes stay raw +--SKIPIF-- + +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--FILE-- + "raw", "span.kind" => "server"])] +function withAttributes() {} + +#[DDTrace\Trace(name: "unset")] +function notSet() {} + +kindComponent(); +withAttributes(); +notSet(); + +foreach (array_reverse(dd_clean_spans()) as $span) { + $attributes = array_intersect_key($span['attributes'], array_flip(['component', 'span.kind'])); + ksort($attributes); + echo $span['name'], ": component=", json_encode($span['component'] ?? null), " span_kind=", json_encode($span['span_kind'] ?? null), + " attributes=", json_encode($attributes), "\n"; +} +?> +--EXPECT-- +kind_component: component="my-component" span_kind=3 attributes=[] +with_attributes: component="property" span_kind=4 attributes={"component":"raw","span.kind":"server"} +unset: component=null span_kind=null attributes=[] diff --git a/tests/ext/traced_attribute_tags_and_attributes.phpt b/tests/ext/traced_attribute_tags_and_attributes.phpt new file mode 100644 index 00000000000..a675025e6bf --- /dev/null +++ b/tests/ext/traced_attribute_tags_and_attributes.phpt @@ -0,0 +1,44 @@ +--TEST-- +#[DDTrace\Trace] $tags are written like $meta (special keys set properties), $attributes are merged as is and win +--SKIPIF-- + +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--INI-- +error_reporting=E_ALL +--FILE-- + "tag-component", "span.kind" => "client", "count" => 3])] +function tagsOnly() {} + +#[DDTrace\Trace(name: "attributes_only", attributes: ["component" => "attr-component", "count" => 3, "ok" => true])] +function attributesOnly() {} + +#[DDTrace\Trace(name: "both", tags: ["shared" => "from tags", "tag" => "t"], attributes: ["shared" => "from attributes", "attr" => 1])] +function both() {} + +echo "calls\n"; +tagsOnly(); +tagsOnly(); +attributesOnly(); +both(); + +foreach (array_reverse(dd_clean_spans()) as $span) { + $attributes = array_intersect_key($span['attributes'], array_flip(['component', 'count', 'ok', 'shared', 'tag', 'attr'])); + ksort($attributes); + echo $span['name'], ": component=", json_encode($span['component'] ?? null), " span_kind=", json_encode($span['span_kind'] ?? null), + " attributes=", json_encode($attributes), "\n"; +} +?> +--EXPECTF-- +Deprecated: DDTrace\Trace: $tags is deprecated, use $attributes instead in %s on line %d + +Deprecated: DDTrace\Trace: $tags is deprecated, use $attributes instead in %s on line %d +calls +tags_only: component="tag-component" span_kind=3 attributes={"count":"3"} +tags_only: component="tag-component" span_kind=3 attributes={"count":"3"} +attributes_only: component=null span_kind=null attributes={"component":"attr-component","count":3,"ok":true} +both: component=null span_kind=null attributes={"attr":1,"shared":"from attributes","tag":"t"} diff --git a/tests/ext/traced_attribute_tags_deprecation_count.phpt b/tests/ext/traced_attribute_tags_deprecation_count.phpt new file mode 100644 index 00000000000..f255a0d7c6c --- /dev/null +++ b/tests/ext/traced_attribute_tags_deprecation_count.phpt @@ -0,0 +1,53 @@ +--TEST-- +#[DDTrace\Trace] tags: the deprecation is raised once per hooked function (a trait method once per using class), not per call +--SKIPIF-- + +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--FILE-- + "b"])] + function traced() {} +} +class UsesT1 { use T; } +class UsesT2 { use T; } +'); +echo count($deprecations), "\n"; + +echo "-- inherited method\n"; +$deprecations = []; +eval(' +class Base { + #[DDTrace\Trace(tags: ["a" => "b"])] + function traced() {} +} +class Child extends Base {} +'); +echo count($deprecations), "\n"; + +echo "-- calls\n"; +$deprecations = []; +(new UsesT1)->traced(); +(new UsesT2)->traced(); +(new Child)->traced(); +(new Child)->traced(); +echo count($deprecations), "\n"; +?> +--EXPECT-- +-- trait used by two classes +3 +-- inherited method +1 +-- calls +0 diff --git a/tests/ext/traced_attribute_tags_recursive_and_empty.phpt b/tests/ext/traced_attribute_tags_recursive_and_empty.phpt index 276de719d5d..647f247bd81 100644 --- a/tests/ext/traced_attribute_tags_recursive_and_empty.phpt +++ b/tests/ext/traced_attribute_tags_recursive_and_empty.phpt @@ -1,13 +1,16 @@ --TEST-- -#[DDTrace\Trace] tags: a self-referencing object tag becomes "" at the cycle, and empty tags are accepted +#[DDTrace\Trace] tags: an empty $tags is not deprecated, and a self-referencing object tag becomes "*RECURSION*" at the cycle --SKIPIF-- --ENV-- DD_TRACE_GENERATE_ROOT_SPAN=0 DD_TRACE_AUTO_FLUSH_ENABLED=0 DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--INI-- +error_reporting=E_ALL --FILE-- ---EXPECT-- +--EXPECTF-- +Deprecated: DDTrace\Trace: $tags is deprecated, use $attributes instead in %s on line %d +calls empty: null -recursive: {"me":"","v":"1"} +recursive: {"me":"*RECURSION*","v":"1"} diff --git a/tests/ext/track_user_login_failure_01.phpt b/tests/ext/track_user_login_failure_01.phpt index ac227ccbdeb..00a8dd04950 100644 --- a/tests/ext/track_user_login_failure_01.phpt +++ b/tests/ext/track_user_login_failure_01.phpt @@ -14,7 +14,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(7) { +array(10) { ["runtime-id"]=> string(%d) %s ["appsec.events.users.login.failure.usr.login"]=> @@ -29,4 +29,10 @@ array(7) { string(%d) "metavalue" ["appsec.events.users.login.failure.metakey2"]=> string(%d) "metavalue02" + ["service.name"]=> + string(31) "track_user_login_failure_01.php" + ["operation.name"]=> + string(31) "track_user_login_failure_01.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/track_user_login_failure_02.phpt b/tests/ext/track_user_login_failure_02.phpt index 83889443daa..56be33f5e9e 100644 --- a/tests/ext/track_user_login_failure_02.phpt +++ b/tests/ext/track_user_login_failure_02.phpt @@ -11,7 +11,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(5) { +array(8) { ["runtime-id"]=> string(%d) %s ["appsec.events.users.login.failure.usr.login"]=> @@ -22,4 +22,10 @@ array(5) { string(%d) "true" ["_dd.appsec.events.users.login.failure.sdk"]=> string(%d) "true" + ["service.name"]=> + string(31) "track_user_login_failure_02.php" + ["operation.name"]=> + string(31) "track_user_login_failure_02.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/track_user_login_failure_03.phpt b/tests/ext/track_user_login_failure_03.phpt index 5d5302c86a0..2b81cb1fa01 100644 --- a/tests/ext/track_user_login_failure_03.phpt +++ b/tests/ext/track_user_login_failure_03.phpt @@ -12,7 +12,13 @@ var_dump($root->meta); ?> --EXPECTF-- -array(1) { +array(4) { ["runtime-id"]=> string(%d) %s + ["service.name"]=> + string(31) "track_user_login_failure_03.php" + ["operation.name"]=> + string(31) "track_user_login_failure_03.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/track_user_login_success_01.phpt b/tests/ext/track_user_login_success_01.phpt index 8ebba45f4a6..18364c1055f 100644 --- a/tests/ext/track_user_login_success_01.phpt +++ b/tests/ext/track_user_login_success_01.phpt @@ -14,7 +14,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(11) { +array(14) { ["runtime-id"]=> string(%d) %s ["appsec.events.users.login.success.usr.login"]=> @@ -37,4 +37,10 @@ array(11) { string(%d) "metavalue" ["usr.metakey2"]=> string(%d) "metavalue02" + ["service.name"]=> + string(31) "track_user_login_success_01.php" + ["operation.name"]=> + string(31) "track_user_login_success_01.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/track_user_login_success_02.phpt b/tests/ext/track_user_login_success_02.phpt index 6bca6d604dc..6c23e867f65 100644 --- a/tests/ext/track_user_login_success_02.phpt +++ b/tests/ext/track_user_login_success_02.phpt @@ -18,7 +18,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(13) { +array(16) { ["runtime-id"]=> string(%s) %s ["appsec.events.users.login.success.usr.id"]=> @@ -45,4 +45,10 @@ array(13) { string(%s) "metavalue" ["usr.metakey2"]=> string(%s) "metavalue02" + ["service.name"]=> + string(31) "track_user_login_success_02.php" + ["operation.name"]=> + string(31) "track_user_login_success_02.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/track_user_login_success_03.phpt b/tests/ext/track_user_login_success_03.phpt index 2f8c8ae9f4f..e76e3e050e1 100644 --- a/tests/ext/track_user_login_success_03.phpt +++ b/tests/ext/track_user_login_success_03.phpt @@ -17,7 +17,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(11) { +array(14) { ["runtime-id"]=> string(%s) %s ["appsec.events.users.login.success.usr.id"]=> @@ -40,4 +40,10 @@ array(11) { string(%s) "metavalue" ["usr.metakey2"]=> string(%s) "metavalue02" + ["service.name"]=> + string(31) "track_user_login_success_03.php" + ["operation.name"]=> + string(31) "track_user_login_success_03.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/track_user_login_success_04.phpt b/tests/ext/track_user_login_success_04.phpt index 1deab06aff4..f88c45e1999 100644 --- a/tests/ext/track_user_login_success_04.phpt +++ b/tests/ext/track_user_login_success_04.phpt @@ -16,7 +16,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(7) { +array(10) { ["runtime-id"]=> string(%s) %s ["appsec.events.users.login.success.usr.some_key"]=> @@ -31,4 +31,10 @@ array(7) { string(9) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(11) "metavalue02" + ["service.name"]=> + string(31) "track_user_login_success_04.php" + ["operation.name"]=> + string(31) "track_user_login_success_04.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/track_user_login_success_05.phpt b/tests/ext/track_user_login_success_05.phpt index c4e2d2dfb04..2a3904efcae 100644 --- a/tests/ext/track_user_login_success_05.phpt +++ b/tests/ext/track_user_login_success_05.phpt @@ -16,7 +16,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(6) { +array(9) { ["runtime-id"]=> string(%s) %s ["appsec.events.users.login.success.usr.login"]=> @@ -29,4 +29,10 @@ array(6) { string(9) "metavalue" ["appsec.events.users.login.success.metakey2"]=> string(11) "metavalue02" + ["service.name"]=> + string(31) "track_user_login_success_05.php" + ["operation.name"]=> + string(31) "track_user_login_success_05.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/track_user_login_success_06.phpt b/tests/ext/track_user_login_success_06.phpt index 64500a09930..b6085283b4a 100644 --- a/tests/ext/track_user_login_success_06.phpt +++ b/tests/ext/track_user_login_success_06.phpt @@ -10,7 +10,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(5) { +array(8) { ["runtime-id"]=> string(%d) %s ["appsec.events.users.login.success.usr.login"]=> @@ -21,4 +21,10 @@ array(5) { string(%d) "true" ["appsec.events.users.login.success.metakey1"]=> string(%d) "meta value" + ["service.name"]=> + string(31) "track_user_login_success_06.php" + ["operation.name"]=> + string(31) "track_user_login_success_06.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/track_user_login_success_07.phpt b/tests/ext/track_user_login_success_07.phpt index 8052da14a45..25992754616 100644 --- a/tests/ext/track_user_login_success_07.phpt +++ b/tests/ext/track_user_login_success_07.phpt @@ -8,7 +8,7 @@ var_dump($root->meta); ?> --EXPECTF-- -array(4) { +array(7) { ["runtime-id"]=> string(%d) %s ["appsec.events.users.login.success.usr.login"]=> @@ -17,4 +17,10 @@ array(4) { string(%d) "true" ["_dd.appsec.events.users.login.success.sdk"]=> string(%d) "true" + ["service.name"]=> + string(31) "track_user_login_success_07.php" + ["operation.name"]=> + string(31) "track_user_login_success_07.php" + ["span.type"]=> + string(3) "cli" } \ No newline at end of file diff --git a/tests/ext/try_drop_span.phpt b/tests/ext/try_drop_span.phpt index 952ccf7a84e..36562b6f27d 100644 --- a/tests/ext/try_drop_span.phpt +++ b/tests/ext/try_drop_span.phpt @@ -58,7 +58,7 @@ $span->getLink(); DDTrace\close_span(); var_dump(DDTrace\try_drop_span($span)); -foreach (dd_trace_serialize_closed_spans() as $span) { +foreach (dd_trace_serialize_closed_spans()['chunks'][0]['spans'] as $span) { echo $span["name"], "\n"; } diff --git a/tests/ext/try_drop_span_root.phpt b/tests/ext/try_drop_span_root.phpt index 2c921461a6a..6fd094b2520 100644 --- a/tests/ext/try_drop_span_root.phpt +++ b/tests/ext/try_drop_span_root.phpt @@ -12,7 +12,7 @@ $span->onClose[] = function($span) { }; DDTrace\close_span(); -foreach (dd_trace_serialize_closed_spans() as $span) { +foreach (dd_trace_serialize_closed_spans()['chunks'][0]['spans'] ?? [] as $span) { echo $span["service"], "\n"; } diff --git a/tests/ext/ust.phpt b/tests/ext/ust.phpt index 7f36e2485bb..506166f0f5d 100644 --- a/tests/ext/ust.phpt +++ b/tests/ext/ust.phpt @@ -28,10 +28,6 @@ var_dump(dd_clean_spans()); array(2) { [0]=> array(%d) { - ["trace_id"]=> - string(%d) "%s" - ["trace_id_high"]=> - string(16) "%s" ["span_id"]=> string(%d) "%s" ["start"]=> @@ -50,16 +46,12 @@ array(2) { string(8) "env_test" ["version"]=> string(5) "5.2.0" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(%d) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.agent_psr"]=> float(1) ["php.compilation.total_time_ms"]=> @@ -72,10 +64,6 @@ array(2) { } [1]=> array(%d) { - ["trace_id"]=> - string(%d) "%s" - ["trace_id_high"]=> - string(16) "%s" ["span_id"]=> string(%d) "%s" ["start"]=> @@ -92,16 +80,12 @@ array(2) { string(3) "cli" ["env"]=> string(8) "env_test" - ["sampling_priority"]=> - int(1) - ["sampling_mechanism"]=> - int(0) ["attributes"]=> array(%d) { ["runtime-id"]=> string(36) "%s" ["process_id"]=> - float(%f) + int(%d) ["_dd.svc_src"]=> string(1) "m" ["_dd.agent_psr"]=> diff --git a/tests/ext/ust_precedence_over_ddtags.phpt b/tests/ext/ust_precedence_over_ddtags.phpt index f456a6060ed..fbae8501e4e 100644 --- a/tests/ext/ust_precedence_over_ddtags.phpt +++ b/tests/ext/ust_precedence_over_ddtags.phpt @@ -21,7 +21,7 @@ DDTrace\close_span(); DDTrace\close_span(); // Get the spans and verify both -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; if (count($spans) >= 2) { var_dump([ 'span1' => [ diff --git a/tests/ext/ust_via_ddtags.phpt b/tests/ext/ust_via_ddtags.phpt index 4436c1efffc..6eb5d6add36 100644 --- a/tests/ext/ust_via_ddtags.phpt +++ b/tests/ext/ust_via_ddtags.phpt @@ -21,7 +21,7 @@ DDTrace\close_span(); DDTrace\close_span(); // Get the spans and verify both -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; if (count($spans) >= 2) { var_dump([ 'span1' => [ diff --git a/tests/ext/wrong-parameter-errors/DDTrace_trace_id.phpt b/tests/ext/wrong-parameter-errors/DDTrace_trace_id.phpt index aa968fead0b..5d509ae0151 100644 --- a/tests/ext/wrong-parameter-errors/DDTrace_trace_id.phpt +++ b/tests/ext/wrong-parameter-errors/DDTrace_trace_id.phpt @@ -1,5 +1,7 @@ --TEST-- DDTrace_trace_id is passed wrong parameters +--INI-- +error_reporting=E_ALL --FILE-- ---EXPECT-- +--EXPECTF-- +Deprecated: Function DDTrace\trace_id() is deprecated in %s on line %d OK diff --git a/tests/opcache/span_attributes_immutable_arrays.phpt b/tests/opcache/span_attributes_immutable_arrays.phpt index 28143ffff0c..5cde88a63c2 100644 --- a/tests/opcache/span_attributes_immutable_arrays.phpt +++ b/tests/opcache/span_attributes_immutable_arrays.phpt @@ -29,7 +29,7 @@ $span->links[] = $link; $span->events[] = new SpanEvent('evt', ['list' => ['x', 'y'], 'map' => ['n' => [3]]], 1); \DDTrace\close_span(); -$spans = dd_trace_serialize_closed_spans(); +$spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; echo json_encode([ $spans[0]['attributes']['flat'], $spans[0]['attributes']['nested'], diff --git a/tests/randomized/app/public/long_running_script.php b/tests/randomized/app/public/long_running_script.php index a407dc51d27..723a0c380cb 100644 --- a/tests/randomized/app/public/long_running_script.php +++ b/tests/randomized/app/public/long_running_script.php @@ -15,16 +15,16 @@ // Access method arguments and change resource name $span->resource = 'message:' . $args[0]->id; $span->meta['message.content'] = $args[0]->content; - $span->service = \ddtrace_config_app_name(); + $span->service = \dd_trace_env_config('DD_SERVICE'); }); \DDTrace\trace_method('ProcessingStage1', 'process', function (SpanData $span, $args) { - $span->service = \ddtrace_config_app_name(); + $span->service = \dd_trace_env_config('DD_SERVICE'); // Resource name defaults to the fully qualified method name. }); \DDTrace\trace_method('ProcessingStage2', 'process', function (SpanData $span, $args) { - $span->service = \ddtrace_config_app_name(); + $span->service = \dd_trace_env_config('DD_SERVICE'); $span->resource = 'message:' . $args[0]->id; }); // End of Datadog manual tracing diff --git a/tests/randomized/app/src/RandomizedTests/RandomExecutionPath.php b/tests/randomized/app/src/RandomizedTests/RandomExecutionPath.php index e82e5856554..550017fdc21 100644 --- a/tests/randomized/app/src/RandomizedTests/RandomExecutionPath.php +++ b/tests/randomized/app/src/RandomizedTests/RandomExecutionPath.php @@ -37,12 +37,12 @@ public function __construct(RandomExecutionPathConfiguration $config) if (getenv('DD_TRACE_ENABLED') !== 'false' && extension_loaded('ddtrace')) { // Tracing manual functions $callback = function (\DDTrace\SpanData $span) { - $span->service = \ddtrace_config_app_name(); + $span->service = \dd_trace_env_config('DD_SERVICE'); }; - \dd_trace_method('RandomizedTests\RandomExecutionPath', 'doSomethingTraced', $callback); - \dd_trace_method('RandomizedTests\RandomExecutionPath', 'doSomethingTraced1', $callback); - \dd_trace_method('RandomizedTests\RandomExecutionPath', 'doSomethingTraced2', $callback); - \dd_trace_method('RandomizedTests\GeneratorSnippets', 'generator', $callback); + \DDTrace\trace_method('RandomizedTests\RandomExecutionPath', 'doSomethingTraced', $callback); + \DDTrace\trace_method('RandomizedTests\RandomExecutionPath', 'doSomethingTraced1', $callback); + \DDTrace\trace_method('RandomizedTests\RandomExecutionPath', 'doSomethingTraced2', $callback); + \DDTrace\trace_method('RandomizedTests\GeneratorSnippets', 'generator', $callback); } } diff --git a/tests/snapshots/tests.integrations.cli.symfony.latest.common_scenarios_test.test_silenced_spans_are_dropped.json b/tests/snapshots/tests.integrations.cli.symfony.latest.common_scenarios_test.test_silenced_spans_are_dropped.json index 41edfa5f224..8be8fb46bfa 100644 --- a/tests/snapshots/tests.integrations.cli.symfony.latest.common_scenarios_test.test_silenced_spans_are_dropped.json +++ b/tests/snapshots/tests.integrations.cli.symfony.latest.common_scenarios_test.test_silenced_spans_are_dropped.json @@ -28,11 +28,13 @@ "type": "system", "meta": { "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Latest/bin/console", - "_dd.code_origin.frames.9.line": "11", "_dd.code_origin.type": "exit", "cmd.exec": "[\"stty\",\"-a\"]", - "cmd.exit_code": "0", "component": "subprocess" + }, + "metrics": { + "_dd.code_origin.frames.9.line": 11, + "cmd.exit_code": 0 } }, { @@ -46,11 +48,11 @@ "meta": { "_dd.base_service": "console", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Latest/bin/console", - "_dd.code_origin.frames.6.line": "11", "_dd.code_origin.type": "exit", "component": "symfony" }, "metrics": { + "_dd.code_origin.frames.6.line": 11, "_dd.top_level": 1 } }, diff --git a/tests/snapshots/tests.integrations.cli.symfony.v4_4.common_scenarios_test.test_silenced_spans_are_dropped.json b/tests/snapshots/tests.integrations.cli.symfony.v4_4.common_scenarios_test.test_silenced_spans_are_dropped.json index 5158782ea4a..0a286f4fb88 100644 --- a/tests/snapshots/tests.integrations.cli.symfony.v4_4.common_scenarios_test.test_silenced_spans_are_dropped.json +++ b/tests/snapshots/tests.integrations.cli.symfony.v4_4.common_scenarios_test.test_silenced_spans_are_dropped.json @@ -28,11 +28,13 @@ "type": "system", "meta": { "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_4_4/bin/console", - "_dd.code_origin.frames.7.line": "42", "_dd.code_origin.type": "exit", - "cmd.exit_code": "0", "cmd.shell": "stty -a | grep columns", "component": "subprocess" + }, + "metrics": { + "_dd.code_origin.frames.7.line": 42, + "cmd.exit_code": 0 } }, { @@ -46,11 +48,11 @@ "meta": { "_dd.base_service": "console", "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Version_4_4/bin/console", - "_dd.code_origin.frames.4.line": "42", "_dd.code_origin.type": "exit", "component": "symfony" }, "metrics": { + "_dd.code_origin.frames.4.line": 42, "_dd.top_level": 1 } }, diff --git a/tests/snapshots/tests.integrations.cli.symfony.v5_2.common_scenarios_test.test_silenced_spans_are_dropped.json b/tests/snapshots/tests.integrations.cli.symfony.v5_2.common_scenarios_test.test_silenced_spans_are_dropped.json index 41d50574433..c2706f16422 100644 --- a/tests/snapshots/tests.integrations.cli.symfony.v5_2.common_scenarios_test.test_silenced_spans_are_dropped.json +++ b/tests/snapshots/tests.integrations.cli.symfony.v5_2.common_scenarios_test.test_silenced_spans_are_dropped.json @@ -28,11 +28,13 @@ "type": "system", "meta": { "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_5_2/bin/console", - "_dd.code_origin.frames.7.line": "43", "_dd.code_origin.type": "exit", - "cmd.exit_code": "0", "cmd.shell": "stty -a | grep columns", "component": "subprocess" + }, + "metrics": { + "_dd.code_origin.frames.7.line": 43, + "cmd.exit_code": 0 } }, { @@ -46,11 +48,11 @@ "meta": { "_dd.base_service": "console", "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Version_5_2/bin/console", - "_dd.code_origin.frames.4.line": "43", "_dd.code_origin.type": "exit", "component": "symfony" }, "metrics": { + "_dd.code_origin.frames.4.line": 43, "_dd.top_level": 1 } }, diff --git a/tests/snapshots/tests.integrations.cli.symfony.v6_2.common_scenarios_test.test_silenced_spans_are_dropped.json b/tests/snapshots/tests.integrations.cli.symfony.v6_2.common_scenarios_test.test_silenced_spans_are_dropped.json index 09042e94eee..7d438415d4a 100644 --- a/tests/snapshots/tests.integrations.cli.symfony.v6_2.common_scenarios_test.test_silenced_spans_are_dropped.json +++ b/tests/snapshots/tests.integrations.cli.symfony.v6_2.common_scenarios_test.test_silenced_spans_are_dropped.json @@ -28,11 +28,13 @@ "type": "system", "meta": { "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_6_2/bin/console", - "_dd.code_origin.frames.7.line": "43", "_dd.code_origin.type": "exit", "cmd.exec": "[\"stty\",\"-a\"]", - "cmd.exit_code": "0", "component": "subprocess" + }, + "metrics": { + "_dd.code_origin.frames.7.line": 43, + "cmd.exit_code": 0 } }, { @@ -46,11 +48,11 @@ "meta": { "_dd.base_service": "console", "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Version_6_2/bin/console", - "_dd.code_origin.frames.4.line": "43", "_dd.code_origin.type": "exit", "component": "symfony" }, "metrics": { + "_dd.code_origin.frames.4.line": 43, "_dd.top_level": 1 } }, @@ -64,10 +66,12 @@ "type": "system", "meta": { "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Version_6_2/bin/console", - "_dd.code_origin.frames.6.line": "43", "_dd.code_origin.type": "exit", "cmd.shell": "stty -g", "component": "subprocess" + }, + "metrics": { + "_dd.code_origin.frames.6.line": 43 } }, { diff --git a/tests/snapshots/tests.integrations.cli.symfony.v7_3.common_scenarios_test.test_silenced_spans_are_dropped.json b/tests/snapshots/tests.integrations.cli.symfony.v7_3.common_scenarios_test.test_silenced_spans_are_dropped.json index e218355e4aa..829d337c7a0 100644 --- a/tests/snapshots/tests.integrations.cli.symfony.v7_3.common_scenarios_test.test_silenced_spans_are_dropped.json +++ b/tests/snapshots/tests.integrations.cli.symfony.v7_3.common_scenarios_test.test_silenced_spans_are_dropped.json @@ -28,11 +28,13 @@ "type": "system", "meta": { "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.9.line": "11", "_dd.code_origin.type": "exit", "cmd.exec": "[\"stty\",\"-a\"]", - "cmd.exit_code": "0", "component": "subprocess" + }, + "metrics": { + "_dd.code_origin.frames.9.line": 11, + "cmd.exit_code": 0 } }, { @@ -46,11 +48,11 @@ "meta": { "_dd.base_service": "console", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.6.line": "11", "_dd.code_origin.type": "exit", "component": "symfony" }, "metrics": { + "_dd.code_origin.frames.6.line": 11, "_dd.top_level": 1 } }, @@ -64,10 +66,12 @@ "type": "system", "meta": { "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.8.line": "11", "_dd.code_origin.type": "exit", "cmd.shell": "stty -g", "component": "subprocess" + }, + "metrics": { + "_dd.code_origin.frames.8.line": 11 } }, { diff --git a/tests/snapshots/tests.integrations.guzzle.latest.guzzle_integration_test.test_multi_exec.json b/tests/snapshots/tests.integrations.guzzle.latest.guzzle_integration_test.test_multi_exec.json index 169e47adc29..fca7227493c 100644 --- a/tests/snapshots/tests.integrations.guzzle.latest.guzzle_integration_test.test_multi_exec.json +++ b/tests/snapshots/tests.integrations.guzzle.latest.guzzle_integration_test.test_multi_exec.json @@ -202,47 +202,47 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "0", - "curl.connect_time_us": "0", - "curl.download_content_length": "-1", - "curl.filetime": "-1", - "curl.header_size": "0", - "curl.http_version": "0", - "curl.namelookup_time": "0", - "curl.namelookup_time_us": "0", - "curl.pretransfer_time": "0", - "curl.pretransfer_time_us": "0", - "curl.protocol": "0", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "0", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "0", - "curl.starttransfer_time_us": "0", - "curl.total_time": "1834000", - "curl.total_time_us": "1834", - "curl.upload_content_length": "-1", "error.message": "Couldn't resolve host name", "error.stack": "#0 {path}/tests/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(233): curl_multi_info_read()\n#1 {path}/tests/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(174): GuzzleHttp\\Handler\\CurlMultiHandler->processMessages()\n#2 {path}/tests/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(189): GuzzleHttp\\Handler\\CurlMultiHandler->tick()\n#3 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Handler\\CurlMultiHandler->execute()\n#4 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()\n#5 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()\n#6 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()\n#7 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()\n#8 {path}/tests/vendor/guzzlehttp/promises/src/Utils.php(121): GuzzleHttp\\Promise\\Promise->wait()\n#9 {path}/tests/Integrations/Guzzle/V7/GuzzleIntegrationTest.php(77): GuzzleHttp\\Promise\\Utils::unwrap()\n#10 {path}/tests/Common/SnapshotTestTrait.php(171): DDTrace\\Tests\\Integrations\\Guzzle\\V7\\GuzzleIntegrationTest->DDTrace\\Tests\\Integrations\\Guzzle\\V7\\{closure}()\n#11 {path}/tests/Integrations/Guzzle/V7/GuzzleIntegrationTest.php(86): DDTrace\\Tests\\Integrations\\Guzzle\\V6\\GuzzleIntegrationTest->isolateTracerSnapshot()\n#12 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(1612): DDTrace\\Tests\\Integrations\\Guzzle\\V7\\GuzzleIntegrationTest->testMultiExec()\n#13 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(1218): PHPUnit\\Framework\\TestCase->runTest()\n#14 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestResult.php(728): PHPUnit\\Framework\\TestCase->runBare()\n#15 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(968): PHPUnit\\Framework\\TestResult->run()\n#16 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestSuite.php(684): PHPUnit\\Framework\\TestCase->run()\n#17 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestSuite.php(684): PHPUnit\\Framework\\TestSuite->run()\n#18 {path}/tests/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(651): PHPUnit\\Framework\\TestSuite->run()\n#19 {path}/tests/vendor/phpunit/phpunit/src/TextUI/Command.php(144): PHPUnit\\TextUI\\TestRunner->run()\n#20 {path}/tests/vendor/phpunit/phpunit/src/TextUI/Command.php(97): PHPUnit\\TextUI\\Command->run()\n#21 phpvfscomposer:{path}/tests/vendor/phpunit/phpunit/phpunit(106): PHPUnit\\TextUI\\Command::main()\n#22 {path}/tests/vendor/bin/phpunit(118): include()\n#23 {main}", "error.type": "curl error", "http.status_code": "0", "http.url": "https://google.wrong/", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "", - "network.client.port": "0", "network.destination.ip": "", "network.destination.name": "google.wrong", - "network.destination.port": "0", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 0, + "curl.connect_time_us": 0, + "curl.download_content_length": -1, + "curl.filetime": -1, + "curl.header_size": 0, + "curl.http_version": 0, + "curl.namelookup_time": 0, + "curl.namelookup_time_us": 0, + "curl.pretransfer_time": 0, + "curl.pretransfer_time_us": 0, + "curl.protocol": 0, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 0, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 0, + "curl.starttransfer_time_us": 0, + "curl.total_time": 1834000, + "curl.total_time_us": 1834, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 0, + "network.destination.port": 0 } }, { @@ -256,47 +256,47 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "1028000", - "curl.connect_time_us": "1028", "curl.content_type": "text/html; charset=utf-8", - "curl.download_content_length": "0", - "curl.filetime": "-1", - "curl.header_size": "288", - "curl.http_version": "2", - "curl.namelookup_time": "977000", - "curl.namelookup_time_us": "977", - "curl.pretransfer_time": "1045000", - "curl.pretransfer_time_us": "1045", - "curl.protocol": "1", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", "curl.redirect_url": "http://{httpbin}/status/200", - "curl.request_size": "389", "curl.scheme": "HTTP", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "5027084000", - "curl.starttransfer_time_us": "5027084", - "curl.total_time": "5027223000", - "curl.total_time_us": "5027223", - "curl.upload_content_length": "-1", "http.status_code": "302", "http.url": "http://{httpbin}/redirect-to?url=http://{httpbin}/status/200", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "47880", "network.destination.ip": "172.20.0.2", "network.destination.name": "httpbin-integration", - "network.destination.port": "80", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 1028000, + "curl.connect_time_us": 1028, + "curl.download_content_length": 0, + "curl.filetime": -1, + "curl.header_size": 288, + "curl.http_version": 2, + "curl.namelookup_time": 977000, + "curl.namelookup_time_us": 977, + "curl.pretransfer_time": 1045000, + "curl.pretransfer_time_us": 1045, + "curl.protocol": 1, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 389, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 5027084000, + "curl.starttransfer_time_us": 5027084, + "curl.total_time": 5027223000, + "curl.total_time_us": 5027223, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 47880, + "network.destination.port": 80 } }, { @@ -310,46 +310,46 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "1059000", - "curl.connect_time_us": "1059", "curl.content_type": "text/html; charset=utf-8", - "curl.download_content_length": "0", - "curl.filetime": "-1", - "curl.header_size": "236", - "curl.http_version": "2", - "curl.namelookup_time": "1014000", - "curl.namelookup_time_us": "1014", - "curl.pretransfer_time": "1074000", - "curl.pretransfer_time_us": "1074", - "curl.protocol": "1", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "344", "curl.scheme": "HTTP", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "5027269000", - "curl.starttransfer_time_us": "5027269", - "curl.total_time": "5027360000", - "curl.total_time_us": "5027360", - "curl.upload_content_length": "-1", "http.status_code": "200", "http.url": "http://{httpbin}/status/200", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "47894", "network.destination.ip": "172.20.0.2", "network.destination.name": "httpbin-integration", - "network.destination.port": "80", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 1059000, + "curl.connect_time_us": 1059, + "curl.download_content_length": 0, + "curl.filetime": -1, + "curl.header_size": 236, + "curl.http_version": 2, + "curl.namelookup_time": 1014000, + "curl.namelookup_time_us": 1014, + "curl.pretransfer_time": 1074000, + "curl.pretransfer_time_us": 1074, + "curl.protocol": 1, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 344, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 5027269000, + "curl.starttransfer_time_us": 5027269, + "curl.total_time": 5027360000, + "curl.total_time_us": 5027360, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 47894, + "network.destination.port": 80 } }, { @@ -363,46 +363,46 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "707000", - "curl.connect_time_us": "707", "curl.content_type": "text/html; charset=utf-8", - "curl.download_content_length": "0", - "curl.filetime": "-1", - "curl.header_size": "241", - "curl.http_version": "2", - "curl.namelookup_time": "535000", - "curl.namelookup_time_us": "535", - "curl.pretransfer_time": "741000", - "curl.pretransfer_time_us": "741", - "curl.protocol": "1", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "346", "curl.scheme": "HTTP", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "1662000", - "curl.starttransfer_time_us": "1662", - "curl.total_time": "2151000", - "curl.total_time_us": "2151", - "curl.upload_content_length": "-1", "http.status_code": "201", "http.url": "http://{httpbin}/status/201", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "47864", "network.destination.ip": "172.20.0.2", "network.destination.name": "httpbin-integration", - "network.destination.port": "80", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 707000, + "curl.connect_time_us": 707, + "curl.download_content_length": 0, + "curl.filetime": -1, + "curl.header_size": 241, + "curl.http_version": 2, + "curl.namelookup_time": 535000, + "curl.namelookup_time_us": 535, + "curl.pretransfer_time": 741000, + "curl.pretransfer_time_us": 741, + "curl.protocol": 1, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 346, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 1662000, + "curl.starttransfer_time_us": 1662, + "curl.total_time": 2151000, + "curl.total_time_us": 2151, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 47864, + "network.destination.port": 80 } }, { @@ -416,46 +416,46 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "788000", - "curl.connect_time_us": "788", "curl.content_type": "text/html; charset=utf-8", - "curl.download_content_length": "0", - "curl.filetime": "-1", - "curl.header_size": "242", - "curl.http_version": "2", - "curl.namelookup_time": "720000", - "curl.namelookup_time_us": "720", - "curl.pretransfer_time": "812000", - "curl.pretransfer_time_us": "812", - "curl.protocol": "1", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "347", "curl.scheme": "HTTP", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "2131000", - "curl.starttransfer_time_us": "2131", - "curl.total_time": "5009544000", - "curl.total_time_us": "5009544", - "curl.upload_content_length": "-1", "http.status_code": "202", "http.url": "http://{httpbin}/status/202", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "47870", "network.destination.ip": "172.20.0.2", "network.destination.name": "httpbin-integration", - "network.destination.port": "80", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 788000, + "curl.connect_time_us": 788, + "curl.download_content_length": 0, + "curl.filetime": -1, + "curl.header_size": 242, + "curl.http_version": 2, + "curl.namelookup_time": 720000, + "curl.namelookup_time_us": 720, + "curl.pretransfer_time": 812000, + "curl.pretransfer_time_us": 812, + "curl.protocol": 1, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 347, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 2131000, + "curl.starttransfer_time_us": 2131, + "curl.total_time": 5009544000, + "curl.total_time_us": 5009544, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 47870, + "network.destination.port": 80 } }, { @@ -470,47 +470,47 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "0", - "curl.connect_time_us": "0", - "curl.download_content_length": "-1", - "curl.filetime": "-1", - "curl.header_size": "0", - "curl.http_version": "0", - "curl.namelookup_time": "0", - "curl.namelookup_time_us": "0", - "curl.pretransfer_time": "0", - "curl.pretransfer_time_us": "0", - "curl.protocol": "0", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "0", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "0", - "curl.starttransfer_time_us": "0", - "curl.total_time": "1572000", - "curl.total_time_us": "1572", - "curl.upload_content_length": "-1", "error.message": "Couldn't resolve host name", "error.stack": "#0 {path}/tests/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(233): curl_multi_info_read()\n#1 {path}/tests/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(174): GuzzleHttp\\Handler\\CurlMultiHandler->processMessages()\n#2 {path}/tests/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(189): GuzzleHttp\\Handler\\CurlMultiHandler->tick()\n#3 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Handler\\CurlMultiHandler->execute()\n#4 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()\n#5 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()\n#6 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()\n#7 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()\n#8 {path}/tests/vendor/guzzlehttp/promises/src/Utils.php(121): GuzzleHttp\\Promise\\Promise->wait()\n#9 {path}/tests/Integrations/Guzzle/V7/GuzzleIntegrationTest.php(77): GuzzleHttp\\Promise\\Utils::unwrap()\n#10 {path}/tests/Common/SnapshotTestTrait.php(171): DDTrace\\Tests\\Integrations\\Guzzle\\V7\\GuzzleIntegrationTest->DDTrace\\Tests\\Integrations\\Guzzle\\V7\\{closure}()\n#11 {path}/tests/Integrations/Guzzle/V7/GuzzleIntegrationTest.php(86): DDTrace\\Tests\\Integrations\\Guzzle\\V6\\GuzzleIntegrationTest->isolateTracerSnapshot()\n#12 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(1612): DDTrace\\Tests\\Integrations\\Guzzle\\V7\\GuzzleIntegrationTest->testMultiExec()\n#13 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(1218): PHPUnit\\Framework\\TestCase->runTest()\n#14 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestResult.php(728): PHPUnit\\Framework\\TestCase->runBare()\n#15 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(968): PHPUnit\\Framework\\TestResult->run()\n#16 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestSuite.php(684): PHPUnit\\Framework\\TestCase->run()\n#17 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestSuite.php(684): PHPUnit\\Framework\\TestSuite->run()\n#18 {path}/tests/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(651): PHPUnit\\Framework\\TestSuite->run()\n#19 {path}/tests/vendor/phpunit/phpunit/src/TextUI/Command.php(144): PHPUnit\\TextUI\\TestRunner->run()\n#20 {path}/tests/vendor/phpunit/phpunit/src/TextUI/Command.php(97): PHPUnit\\TextUI\\Command->run()\n#21 phpvfscomposer:{path}/tests/vendor/phpunit/phpunit/phpunit(106): PHPUnit\\TextUI\\Command::main()\n#22 {path}/tests/vendor/bin/phpunit(118): include()\n#23 {main}", "error.type": "curl error", "http.status_code": "0", "http.url": "https://google.still.wrong/", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "", - "network.client.port": "0", "network.destination.ip": "", "network.destination.name": "google.still.wrong", - "network.destination.port": "0", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 0, + "curl.connect_time_us": 0, + "curl.download_content_length": -1, + "curl.filetime": -1, + "curl.header_size": 0, + "curl.http_version": 0, + "curl.namelookup_time": 0, + "curl.namelookup_time_us": 0, + "curl.pretransfer_time": 0, + "curl.pretransfer_time_us": 0, + "curl.protocol": 0, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 0, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 0, + "curl.starttransfer_time_us": 0, + "curl.total_time": 1572000, + "curl.total_time_us": 1572, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 0, + "network.destination.port": 0 } }, { @@ -524,46 +524,46 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "5047012", - "curl.connect_time": "5034226000", - "curl.connect_time_us": "5034226", "curl.content_type": "text/html; charset=ISO-8859-1", - "curl.download_content_length": "-1", - "curl.filetime": "-1", - "curl.header_size": "1372", - "curl.http_version": "2", - "curl.namelookup_time": "5027239000", - "curl.namelookup_time_us": "5027239", - "curl.pretransfer_time": "5047044000", - "curl.pretransfer_time_us": "5047044", - "curl.protocol": "2", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "331", "curl.scheme": "HTTPS", - "curl.speed_download": "3815", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "5098443000", - "curl.starttransfer_time_us": "5098443", - "curl.total_time": "5102544000", - "curl.total_time_us": "5102544", - "curl.upload_content_length": "-1", "http.status_code": "200", "http.url": "https://www.google.com/", - "network.bytes_read": "19469", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "44268", "network.destination.ip": "172.217.20.196", "network.destination.name": "www.google.com", - "network.destination.port": "443", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 5047012, + "curl.connect_time": 5034226000, + "curl.connect_time_us": 5034226, + "curl.download_content_length": -1, + "curl.filetime": -1, + "curl.header_size": 1372, + "curl.http_version": 2, + "curl.namelookup_time": 5027239000, + "curl.namelookup_time_us": 5027239, + "curl.pretransfer_time": 5047044000, + "curl.pretransfer_time_us": 5047044, + "curl.protocol": 2, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 331, + "curl.speed_download": 3815, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 5098443000, + "curl.starttransfer_time_us": 5098443, + "curl.total_time": 5102544000, + "curl.total_time_us": 5102544, + "curl.upload_content_length": -1, + "network.bytes_read": 19469, + "network.bytes_written": 0, + "network.client.port": 44268, + "network.destination.port": 443 } }, { @@ -577,46 +577,46 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "5041652", - "curl.connect_time": "5029748000", - "curl.connect_time_us": "5029748", "curl.content_type": "text/html; charset=ISO-8859-1", - "curl.download_content_length": "-1", - "curl.filetime": "-1", - "curl.header_size": "1372", - "curl.http_version": "2", - "curl.namelookup_time": "5009822000", - "curl.namelookup_time_us": "5009822", - "curl.pretransfer_time": "5041685000", - "curl.pretransfer_time_us": "5041685", - "curl.protocol": "2", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "331", "curl.scheme": "HTTPS", - "curl.speed_download": "3823", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "5112020000", - "curl.starttransfer_time_us": "5112020", - "curl.total_time": "5119631000", - "curl.total_time_us": "5119631", - "curl.upload_content_length": "-1", "http.status_code": "200", "http.url": "https://www.google.com/", - "network.bytes_read": "19572", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "44254", "network.destination.ip": "172.217.20.196", "network.destination.name": "www.google.com", - "network.destination.port": "443", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 5041652, + "curl.connect_time": 5029748000, + "curl.connect_time_us": 5029748, + "curl.download_content_length": -1, + "curl.filetime": -1, + "curl.header_size": 1372, + "curl.http_version": 2, + "curl.namelookup_time": 5009822000, + "curl.namelookup_time_us": 5009822, + "curl.pretransfer_time": 5041685000, + "curl.pretransfer_time_us": 5041685, + "curl.protocol": 2, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 331, + "curl.speed_download": 3823, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 5112020000, + "curl.starttransfer_time_us": 5112020, + "curl.total_time": 5119631000, + "curl.total_time_us": 5119631, + "curl.upload_content_length": -1, + "network.bytes_read": 19572, + "network.bytes_written": 0, + "network.client.port": 44254, + "network.destination.port": 443 } }, { @@ -630,45 +630,45 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "5042192", - "curl.connect_time": "5027246000", - "curl.connect_time_us": "5027246", "curl.content_type": "text/html; charset=ISO-8859-1", - "curl.download_content_length": "-1", - "curl.filetime": "-1", - "curl.header_size": "1372", - "curl.http_version": "2", - "curl.namelookup_time": "5010251000", - "curl.namelookup_time_us": "5010251", - "curl.pretransfer_time": "5042225000", - "curl.pretransfer_time_us": "5042225", - "curl.protocol": "2", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "331", "curl.scheme": "HTTPS", - "curl.speed_download": "3823", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "5099234000", - "curl.starttransfer_time_us": "5099234", - "curl.total_time": "5102712000", - "curl.total_time_us": "5102712", - "curl.upload_content_length": "-1", "http.status_code": "200", "http.url": "https://www.google.com/", - "network.bytes_read": "19506", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "44260", "network.destination.ip": "172.217.20.196", "network.destination.name": "www.google.com", - "network.destination.port": "443", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 5042192, + "curl.connect_time": 5027246000, + "curl.connect_time_us": 5027246, + "curl.download_content_length": -1, + "curl.filetime": -1, + "curl.header_size": 1372, + "curl.http_version": 2, + "curl.namelookup_time": 5010251000, + "curl.namelookup_time_us": 5010251, + "curl.pretransfer_time": 5042225000, + "curl.pretransfer_time_us": 5042225, + "curl.protocol": 2, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 331, + "curl.speed_download": 3823, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 5099234000, + "curl.starttransfer_time_us": 5099234, + "curl.total_time": 5102712000, + "curl.total_time_us": 5102712, + "curl.upload_content_length": -1, + "network.bytes_read": 19506, + "network.bytes_written": 0, + "network.client.port": 44260, + "network.destination.port": 443 } }]] diff --git a/tests/snapshots/tests.integrations.guzzle.v6.guzzle_integration_test.test_multi_exec.json b/tests/snapshots/tests.integrations.guzzle.v6.guzzle_integration_test.test_multi_exec.json index c1158d09b8b..d6b35bac6ca 100644 --- a/tests/snapshots/tests.integrations.guzzle.v6.guzzle_integration_test.test_multi_exec.json +++ b/tests/snapshots/tests.integrations.guzzle.v6.guzzle_integration_test.test_multi_exec.json @@ -201,47 +201,47 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "0", - "curl.connect_time_us": "0", - "curl.download_content_length": "-1", - "curl.filetime": "-1", - "curl.header_size": "0", - "curl.http_version": "0", - "curl.namelookup_time": "0", - "curl.namelookup_time_us": "0", - "curl.pretransfer_time": "0", - "curl.pretransfer_time_us": "0", - "curl.protocol": "0", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "0", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "0", - "curl.starttransfer_time_us": "0", - "curl.total_time": "5026255000", - "curl.total_time_us": "5026255", - "curl.upload_content_length": "-1", "error.message": "Couldn't resolve host name", "error.stack": "#0 {path}/tests/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(128): curl_multi_exec()\n#1 {path}/tests/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(145): GuzzleHttp\\Handler\\CurlMultiHandler->tick()\n#2 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(248): GuzzleHttp\\Handler\\CurlMultiHandler->execute()\n#3 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(224): GuzzleHttp\\Promise\\Promise->invokeWaitFn()\n#4 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(269): GuzzleHttp\\Promise\\Promise->waitIfPending()\n#5 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(226): GuzzleHttp\\Promise\\Promise->invokeWaitList()\n#6 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(62): GuzzleHttp\\Promise\\Promise->waitIfPending()\n#7 {path}/tests/vendor/guzzlehttp/promises/src/Utils.php(134): GuzzleHttp\\Promise\\Promise->wait()\n#8 {path}/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php(521): GuzzleHttp\\Promise\\Utils::unwrap()\n#9 {path}/tests/Common/SnapshotTestTrait.php(171): DDTrace\\Tests\\Integrations\\Guzzle\\V6\\GuzzleIntegrationTest->DDTrace\\Tests\\Integrations\\Guzzle\\V6\\{closure}()\n#10 {path}/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php(502): DDTrace\\Tests\\Integrations\\Guzzle\\V6\\GuzzleIntegrationTest->isolateTracerSnapshot()\n#11 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(1612): DDTrace\\Tests\\Integrations\\Guzzle\\V6\\GuzzleIntegrationTest->testMultiExec()\n#12 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(1218): PHPUnit\\Framework\\TestCase->runTest()\n#13 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestResult.php(728): PHPUnit\\Framework\\TestCase->runBare()\n#14 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(968): PHPUnit\\Framework\\TestResult->run()\n#15 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestSuite.php(684): PHPUnit\\Framework\\TestCase->run()\n#16 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestSuite.php(684): PHPUnit\\Framework\\TestSuite->run()\n#17 {path}/tests/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(651): PHPUnit\\Framework\\TestSuite->run()\n#18 {path}/tests/vendor/phpunit/phpunit/src/TextUI/Command.php(144): PHPUnit\\TextUI\\TestRunner->run()\n#19 {path}/tests/vendor/phpunit/phpunit/src/TextUI/Command.php(97): PHPUnit\\TextUI\\Command->run()\n#20 {path}/tests/vendor/phpunit/phpunit/phpunit(107): PHPUnit\\TextUI\\Command::main()\n#21 {path}/tests/vendor/bin/phpunit(122): include()\n#22 {main}", "error.type": "curl error", "http.status_code": "0", "http.url": "https://google.wrong/", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "", - "network.client.port": "0", "network.destination.ip": "", "network.destination.name": "google.wrong", - "network.destination.port": "0", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 0, + "curl.connect_time_us": 0, + "curl.download_content_length": -1, + "curl.filetime": -1, + "curl.header_size": 0, + "curl.http_version": 0, + "curl.namelookup_time": 0, + "curl.namelookup_time_us": 0, + "curl.pretransfer_time": 0, + "curl.pretransfer_time_us": 0, + "curl.protocol": 0, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 0, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 0, + "curl.starttransfer_time_us": 0, + "curl.total_time": 5026255000, + "curl.total_time_us": 5026255, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 0, + "network.destination.port": 0 } }, { @@ -255,47 +255,47 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "1810000", - "curl.connect_time_us": "1810", "curl.content_type": "text/html; charset=utf-8", - "curl.download_content_length": "0", - "curl.filetime": "-1", - "curl.header_size": "288", - "curl.http_version": "2", - "curl.namelookup_time": "893000", - "curl.namelookup_time_us": "893", - "curl.pretransfer_time": "1866000", - "curl.pretransfer_time_us": "1866", - "curl.protocol": "1", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", "curl.redirect_url": "http://{httpbin}/status/200", - "curl.request_size": "414", "curl.scheme": "HTTP", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "6049000", - "curl.starttransfer_time_us": "6049", - "curl.total_time": "6629000", - "curl.total_time_us": "6629", - "curl.upload_content_length": "-1", "http.status_code": "302", "http.url": "http://{httpbin}/redirect-to?url=http://{httpbin}/status/200", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "50982", "network.destination.ip": "172.20.0.2", "network.destination.name": "httpbin-integration", - "network.destination.port": "80", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 1810000, + "curl.connect_time_us": 1810, + "curl.download_content_length": 0, + "curl.filetime": -1, + "curl.header_size": 288, + "curl.http_version": 2, + "curl.namelookup_time": 893000, + "curl.namelookup_time_us": 893, + "curl.pretransfer_time": 1866000, + "curl.pretransfer_time_us": 1866, + "curl.protocol": 1, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 414, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 6049000, + "curl.starttransfer_time_us": 6049, + "curl.total_time": 6629000, + "curl.total_time_us": 6629, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 50982, + "network.destination.port": 80 } }, { @@ -309,46 +309,46 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "1968000", - "curl.connect_time_us": "1968", "curl.content_type": "text/html; charset=utf-8", - "curl.download_content_length": "0", - "curl.filetime": "-1", - "curl.header_size": "236", - "curl.http_version": "2", - "curl.namelookup_time": "1842000", - "curl.namelookup_time_us": "1842", - "curl.pretransfer_time": "2000000", - "curl.pretransfer_time_us": "2000", - "curl.protocol": "1", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "370", "curl.scheme": "HTTP", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "8083000", - "curl.starttransfer_time_us": "8083", - "curl.total_time": "8144000", - "curl.total_time_us": "8144", - "curl.upload_content_length": "-1", "http.status_code": "200", "http.url": "http://{httpbin}/status/200", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "50998", "network.destination.ip": "172.20.0.2", "network.destination.name": "httpbin-integration", - "network.destination.port": "80", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 1968000, + "curl.connect_time_us": 1968, + "curl.download_content_length": 0, + "curl.filetime": -1, + "curl.header_size": 236, + "curl.http_version": 2, + "curl.namelookup_time": 1842000, + "curl.namelookup_time_us": 1842, + "curl.pretransfer_time": 2000000, + "curl.pretransfer_time_us": 2000, + "curl.protocol": 1, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 370, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 8083000, + "curl.starttransfer_time_us": 8083, + "curl.total_time": 8144000, + "curl.total_time_us": 8144, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 50998, + "network.destination.port": 80 } }, { @@ -362,46 +362,46 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "1969000", - "curl.connect_time_us": "1969", "curl.content_type": "text/html; charset=utf-8", - "curl.download_content_length": "0", - "curl.filetime": "-1", - "curl.header_size": "241", - "curl.http_version": "2", - "curl.namelookup_time": "1880000", - "curl.namelookup_time_us": "1880", - "curl.pretransfer_time": "1993000", - "curl.pretransfer_time_us": "1993", - "curl.protocol": "1", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "371", "curl.scheme": "HTTP", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "8064000", - "curl.starttransfer_time_us": "8064", - "curl.total_time": "8124000", - "curl.total_time_us": "8124", - "curl.upload_content_length": "-1", "http.status_code": "201", "http.url": "http://{httpbin}/status/201", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "51004", "network.destination.ip": "172.20.0.2", "network.destination.name": "httpbin-integration", - "network.destination.port": "80", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 1969000, + "curl.connect_time_us": 1969, + "curl.download_content_length": 0, + "curl.filetime": -1, + "curl.header_size": 241, + "curl.http_version": 2, + "curl.namelookup_time": 1880000, + "curl.namelookup_time_us": 1880, + "curl.pretransfer_time": 1993000, + "curl.pretransfer_time_us": 1993, + "curl.protocol": 1, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 371, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 8064000, + "curl.starttransfer_time_us": 8064, + "curl.total_time": 8124000, + "curl.total_time_us": 8124, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 51004, + "network.destination.port": 80 } }, { @@ -415,46 +415,46 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "1960000", - "curl.connect_time_us": "1960", "curl.content_type": "text/html; charset=utf-8", - "curl.download_content_length": "0", - "curl.filetime": "-1", - "curl.header_size": "242", - "curl.http_version": "2", - "curl.namelookup_time": "1871000", - "curl.namelookup_time_us": "1871", - "curl.pretransfer_time": "1980000", - "curl.pretransfer_time_us": "1980", - "curl.protocol": "1", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "369", "curl.scheme": "HTTP", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "8021000", - "curl.starttransfer_time_us": "8021", - "curl.total_time": "8070000", - "curl.total_time_us": "8070", - "curl.upload_content_length": "-1", "http.status_code": "202", "http.url": "http://{httpbin}/status/202", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "51014", "network.destination.ip": "172.20.0.2", "network.destination.name": "httpbin-integration", - "network.destination.port": "80", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 1960000, + "curl.connect_time_us": 1960, + "curl.download_content_length": 0, + "curl.filetime": -1, + "curl.header_size": 242, + "curl.http_version": 2, + "curl.namelookup_time": 1871000, + "curl.namelookup_time_us": 1871, + "curl.pretransfer_time": 1980000, + "curl.pretransfer_time_us": 1980, + "curl.protocol": 1, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 369, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 8021000, + "curl.starttransfer_time_us": 8021, + "curl.total_time": 8070000, + "curl.total_time_us": 8070, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 51014, + "network.destination.port": 80 } }, { @@ -469,47 +469,47 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "0", - "curl.connect_time": "0", - "curl.connect_time_us": "0", - "curl.download_content_length": "-1", - "curl.filetime": "-1", - "curl.header_size": "0", - "curl.http_version": "0", - "curl.namelookup_time": "0", - "curl.namelookup_time_us": "0", - "curl.pretransfer_time": "0", - "curl.pretransfer_time_us": "0", - "curl.protocol": "0", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "0", - "curl.speed_download": "0", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "0", - "curl.starttransfer_time_us": "0", - "curl.total_time": "5025663000", - "curl.total_time_us": "5025663", - "curl.upload_content_length": "-1", "error.message": "Couldn't resolve host name", "error.stack": "#0 {path}/tests/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(128): curl_multi_exec()\n#1 {path}/tests/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(145): GuzzleHttp\\Handler\\CurlMultiHandler->tick()\n#2 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(248): GuzzleHttp\\Handler\\CurlMultiHandler->execute()\n#3 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(224): GuzzleHttp\\Promise\\Promise->invokeWaitFn()\n#4 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(269): GuzzleHttp\\Promise\\Promise->waitIfPending()\n#5 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(226): GuzzleHttp\\Promise\\Promise->invokeWaitList()\n#6 {path}/tests/vendor/guzzlehttp/promises/src/Promise.php(62): GuzzleHttp\\Promise\\Promise->waitIfPending()\n#7 {path}/tests/vendor/guzzlehttp/promises/src/Utils.php(134): GuzzleHttp\\Promise\\Promise->wait()\n#8 {path}/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php(521): GuzzleHttp\\Promise\\Utils::unwrap()\n#9 {path}/tests/Common/SnapshotTestTrait.php(171): DDTrace\\Tests\\Integrations\\Guzzle\\V6\\GuzzleIntegrationTest->DDTrace\\Tests\\Integrations\\Guzzle\\V6\\{closure}()\n#10 {path}/tests/Integrations/Guzzle/V6/GuzzleIntegrationTest.php(502): DDTrace\\Tests\\Integrations\\Guzzle\\V6\\GuzzleIntegrationTest->isolateTracerSnapshot()\n#11 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(1612): DDTrace\\Tests\\Integrations\\Guzzle\\V6\\GuzzleIntegrationTest->testMultiExec()\n#12 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(1218): PHPUnit\\Framework\\TestCase->runTest()\n#13 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestResult.php(728): PHPUnit\\Framework\\TestCase->runBare()\n#14 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestCase.php(968): PHPUnit\\Framework\\TestResult->run()\n#15 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestSuite.php(684): PHPUnit\\Framework\\TestCase->run()\n#16 {path}/tests/vendor/phpunit/phpunit/src/Framework/TestSuite.php(684): PHPUnit\\Framework\\TestSuite->run()\n#17 {path}/tests/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(651): PHPUnit\\Framework\\TestSuite->run()\n#18 {path}/tests/vendor/phpunit/phpunit/src/TextUI/Command.php(144): PHPUnit\\TextUI\\TestRunner->run()\n#19 {path}/tests/vendor/phpunit/phpunit/src/TextUI/Command.php(97): PHPUnit\\TextUI\\Command->run()\n#20 {path}/tests/vendor/phpunit/phpunit/phpunit(107): PHPUnit\\TextUI\\Command::main()\n#21 {path}/tests/vendor/bin/phpunit(122): include()\n#22 {main}", "error.type": "curl error", "http.status_code": "0", "http.url": "https://google.still.wrong/", - "network.bytes_read": "0", - "network.bytes_written": "0", "network.client.ip": "", - "network.client.port": "0", "network.destination.ip": "", "network.destination.name": "google.still.wrong", - "network.destination.port": "0", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 0, + "curl.connect_time": 0, + "curl.connect_time_us": 0, + "curl.download_content_length": -1, + "curl.filetime": -1, + "curl.header_size": 0, + "curl.http_version": 0, + "curl.namelookup_time": 0, + "curl.namelookup_time_us": 0, + "curl.pretransfer_time": 0, + "curl.pretransfer_time_us": 0, + "curl.protocol": 0, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 0, + "curl.speed_download": 0, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 0, + "curl.starttransfer_time_us": 0, + "curl.total_time": 5025663000, + "curl.total_time_us": 5025663, + "curl.upload_content_length": -1, + "network.bytes_read": 0, + "network.bytes_written": 0, + "network.client.port": 0, + "network.destination.port": 0 } }, { @@ -523,46 +523,46 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "43779", - "curl.connect_time": "29467000", - "curl.connect_time_us": "29467", "curl.content_type": "text/html; charset=ISO-8859-1", - "curl.download_content_length": "-1", - "curl.filetime": "-1", - "curl.header_size": "1373", - "curl.http_version": "2", - "curl.namelookup_time": "21685000", - "curl.namelookup_time_us": "21685", - "curl.pretransfer_time": "43825000", - "curl.pretransfer_time_us": "43825", - "curl.protocol": "2", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "355", "curl.scheme": "HTTPS", - "curl.speed_download": "169766", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "101763000", - "curl.starttransfer_time_us": "101763", - "curl.total_time": "107525000", - "curl.total_time_us": "107525", - "curl.upload_content_length": "-1", "http.status_code": "200", "http.url": "https://www.google.com/", - "network.bytes_read": "18165", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "35392", "network.destination.ip": "216.58.215.36", "network.destination.name": "www.google.com", - "network.destination.port": "443", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 43779, + "curl.connect_time": 29467000, + "curl.connect_time_us": 29467, + "curl.download_content_length": -1, + "curl.filetime": -1, + "curl.header_size": 1373, + "curl.http_version": 2, + "curl.namelookup_time": 21685000, + "curl.namelookup_time_us": 21685, + "curl.pretransfer_time": 43825000, + "curl.pretransfer_time_us": 43825, + "curl.protocol": 2, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 355, + "curl.speed_download": 169766, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 101763000, + "curl.starttransfer_time_us": 101763, + "curl.total_time": 107525000, + "curl.total_time_us": 107525, + "curl.upload_content_length": -1, + "network.bytes_read": 18165, + "network.bytes_written": 0, + "network.client.port": 35392, + "network.destination.port": 443 } }, { @@ -576,46 +576,46 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "44113", - "curl.connect_time": "28231000", - "curl.connect_time_us": "28231", "curl.content_type": "text/html; charset=ISO-8859-1", - "curl.download_content_length": "-1", - "curl.filetime": "-1", - "curl.header_size": "1373", - "curl.http_version": "2", - "curl.namelookup_time": "21623000", - "curl.namelookup_time_us": "21623", - "curl.pretransfer_time": "44137000", - "curl.pretransfer_time_us": "44137", - "curl.protocol": "2", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "355", "curl.scheme": "HTTPS", - "curl.speed_download": "173161", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "100594000", - "curl.starttransfer_time_us": "100594", - "curl.total_time": "105348000", - "curl.total_time_us": "105348", - "curl.upload_content_length": "-1", "http.status_code": "200", "http.url": "https://www.google.com/", - "network.bytes_read": "18182", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "35400", "network.destination.ip": "216.58.215.36", "network.destination.name": "www.google.com", - "network.destination.port": "443", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 44113, + "curl.connect_time": 28231000, + "curl.connect_time_us": 28231, + "curl.download_content_length": -1, + "curl.filetime": -1, + "curl.header_size": 1373, + "curl.http_version": 2, + "curl.namelookup_time": 21623000, + "curl.namelookup_time_us": 21623, + "curl.pretransfer_time": 44137000, + "curl.pretransfer_time_us": 44137, + "curl.protocol": 2, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 355, + "curl.speed_download": 173161, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 100594000, + "curl.starttransfer_time_us": 100594, + "curl.total_time": 105348000, + "curl.total_time_us": 105348, + "curl.upload_content_length": -1, + "network.bytes_read": 18182, + "network.bytes_written": 0, + "network.client.port": 35400, + "network.destination.port": 443 } }, { @@ -629,45 +629,45 @@ "meta": { "_dd.base_service": "cli", "component": "curl", - "curl.appconnect_time_us": "44492", - "curl.connect_time": "29002000", - "curl.connect_time_us": "29002", "curl.content_type": "text/html; charset=ISO-8859-1", - "curl.download_content_length": "-1", - "curl.filetime": "-1", - "curl.header_size": "1373", - "curl.http_version": "2", - "curl.namelookup_time": "21608000", - "curl.namelookup_time_us": "21608", - "curl.pretransfer_time": "44527000", - "curl.pretransfer_time_us": "44527", - "curl.protocol": "2", - "curl.redirect_count": "0", - "curl.redirect_time": "0", - "curl.redirect_time_us": "0", - "curl.request_size": "356", "curl.scheme": "HTTPS", - "curl.speed_download": "179673", - "curl.speed_upload": "0", - "curl.ssl_verify_result": "0", - "curl.ssl_verifyresult": "0", - "curl.starttransfer_time": "93764000", - "curl.starttransfer_time_us": "93764", - "curl.total_time": "101863000", - "curl.total_time_us": "101863", - "curl.upload_content_length": "-1", "http.status_code": "200", "http.url": "https://www.google.com/", - "network.bytes_read": "18147", - "network.bytes_written": "0", "network.client.ip": "172.20.0.15", - "network.client.port": "35404", "network.destination.ip": "216.58.215.36", "network.destination.name": "www.google.com", - "network.destination.port": "443", "span.kind": "client" }, "metrics": { - "_dd.measured": 1 + "_dd.measured": 1, + "curl.appconnect_time_us": 44492, + "curl.connect_time": 29002000, + "curl.connect_time_us": 29002, + "curl.download_content_length": -1, + "curl.filetime": -1, + "curl.header_size": 1373, + "curl.http_version": 2, + "curl.namelookup_time": 21608000, + "curl.namelookup_time_us": 21608, + "curl.pretransfer_time": 44527000, + "curl.pretransfer_time_us": 44527, + "curl.protocol": 2, + "curl.redirect_count": 0, + "curl.redirect_time": 0, + "curl.redirect_time_us": 0, + "curl.request_size": 356, + "curl.speed_download": 179673, + "curl.speed_upload": 0, + "curl.ssl_verify_result": 0, + "curl.ssl_verifyresult": 0, + "curl.starttransfer_time": 93764000, + "curl.starttransfer_time_us": 93764, + "curl.total_time": 101863000, + "curl.total_time_us": 101863, + "curl.upload_content_length": -1, + "network.bytes_read": 18147, + "network.bytes_written": 0, + "network.client.port": 35404, + "network.destination.port": 443 } }]] diff --git a/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_consumer.json b/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_consumer.json index 643301750a4..6bceac88611 100644 --- a/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_consumer.json +++ b/tests/snapshots/tests.integrations.kafka_test.test_span_links_high_level_consumer.json @@ -8,8 +8,8 @@ "parent_id": 0, "type": "queue", "meta": { - "_dd.p.dm": "0", - "_dd.span_links": "[{\"trace_id\":\"0000000000000000c151df7d6ee5e2d6\",\"span_id\":\"c151df7d6ee5e2d6\",\"trace_state\":\"dd=t.dm:-0,ot=rv:ea5f0f7db45435;th:0\",\"attributes\":{\"_dd.p.dm\":\"-0\"}}]", + "_dd.p.dm": "-0", + "_dd.sdk.otlp_export": "false", "component": "kafka", "messaging.destination": "test-highlevel", "messaging.destination_kind": "queue", @@ -18,17 +18,28 @@ "messaging.kafka.group_id": "consumer-highlevel", "messaging.operation": "receive", "messaging.system": "kafka", - "runtime-id": "bff4ee81-2002-4ffb-9ec3-13308f9f7dde", + "runtime-id": "377e631e-f448-4a3b-bc75-db1d762eedaa", "span.kind": "consumer" }, "metrics": { - "_dd.agent_psr": 1, - "_dd.top_level": 1, - "_sampling_priority_v1": 1, - "messaging.kafka.message_offset": 18, - "messaging.kafka.partition": 0, - "messaging.message_payload_size_bytes": 11 - } + "_dd.agent_psr": 1.0, + "_dd.top_level": 1.0, + "_sampling_priority_v1": 1.0, + "messaging.kafka.message_offset": 6.0, + "messaging.kafka.partition": 0.0, + "messaging.message_payload_size_bytes": 11.0 + }, + "span_links": [ + { + "trace_id": 0, + "trace_id_high": 0, + "span_id": 1, + "attributes": { + "_dd.p.dm": "-0" + }, + "tracestate": "dd=t.dm:-0,ot=rv:ea5f0f7db45435;th:0" + } + ] }], [ { @@ -40,7 +51,8 @@ "parent_id": 0, "type": "queue", "meta": { - "_dd.p.dm": "0", + "_dd.p.dm": "-0", + "_dd.sdk.otlp_export": "false", "component": "kafka", "messaging.destination": "test-highlevel", "messaging.destination_kind": "queue", @@ -50,15 +62,15 @@ "messaging.kafka.tombstone": "true", "messaging.operation": "receive", "messaging.system": "kafka", - "runtime-id": "bff4ee81-2002-4ffb-9ec3-13308f9f7dde", + "runtime-id": "377e631e-f448-4a3b-bc75-db1d762eedaa", "span.kind": "consumer" }, "metrics": { - "_dd.agent_psr": 1, - "_dd.top_level": 1, - "_sampling_priority_v1": 1, - "messaging.kafka.message_offset": 19, - "messaging.kafka.partition": 0, - "messaging.message_payload_size_bytes": 76 + "_dd.agent_psr": 1.0, + "_dd.top_level": 1.0, + "_sampling_priority_v1": 1.0, + "messaging.kafka.message_offset": 7.0, + "messaging.kafka.partition": 0.0, + "messaging.message_payload_size_bytes": 76.0 } }]] diff --git a/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_consumer.json b/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_consumer.json index 55529a131c9..bd0b284d9c4 100644 --- a/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_consumer.json +++ b/tests/snapshots/tests.integrations.kafka_test.test_span_links_low_level_consumer.json @@ -8,8 +8,8 @@ "parent_id": 0, "type": "queue", "meta": { - "_dd.p.dm": "0", - "_dd.span_links": "[{\"trace_id\":\"0000000000000000c151df7d6ee5e2d6\",\"span_id\":\"c151df7d6ee5e2d6\",\"trace_state\":\"dd=t.dm:-0,ot=rv:ea5f0f7db45435;th:0\",\"attributes\":{\"_dd.p.dm\":\"-0\"}}]", + "_dd.p.dm": "-0", + "_dd.sdk.otlp_export": "false", "component": "kafka", "messaging.destination": "test-lowlevel", "messaging.destination_kind": "queue", @@ -18,17 +18,28 @@ "messaging.kafka.group_id": "consumer-lowlevel", "messaging.operation": "receive", "messaging.system": "kafka", - "runtime-id": "cb546b0e-9a6f-450b-8bf2-359f968d021f", + "runtime-id": "f311028f-7a98-47ca-9436-bec6441ffc16", "span.kind": "consumer" }, "metrics": { - "_dd.agent_psr": 1, - "_dd.top_level": 1, - "_sampling_priority_v1": 1, - "messaging.kafka.message_offset": 10, - "messaging.kafka.partition": 0, - "messaging.message_payload_size_bytes": 11 - } + "_dd.agent_psr": 1.0, + "_dd.top_level": 1.0, + "_sampling_priority_v1": 1.0, + "messaging.kafka.message_offset": 4.0, + "messaging.kafka.partition": 0.0, + "messaging.message_payload_size_bytes": 11.0 + }, + "span_links": [ + { + "trace_id": 0, + "trace_id_high": 0, + "span_id": 1, + "attributes": { + "_dd.p.dm": "-0" + }, + "tracestate": "dd=t.dm:-0,ot=rv:ea5f0f7db45435;th:0" + } + ] }], [ { @@ -40,7 +51,8 @@ "parent_id": 0, "type": "queue", "meta": { - "_dd.p.dm": "0", + "_dd.p.dm": "-0", + "_dd.sdk.otlp_export": "false", "component": "kafka", "messaging.destination": "test-lowlevel", "messaging.destination_kind": "queue", @@ -50,16 +62,16 @@ "messaging.kafka.tombstone": "true", "messaging.operation": "receive", "messaging.system": "kafka", - "runtime-id": "cb546b0e-9a6f-450b-8bf2-359f968d021f", + "runtime-id": "f311028f-7a98-47ca-9436-bec6441ffc16", "span.kind": "consumer" }, "metrics": { - "_dd.agent_psr": 1, - "_dd.top_level": 1, - "_sampling_priority_v1": 1, - "messaging.kafka.message_offset": 11, - "messaging.kafka.partition": 0, - "messaging.message_payload_size_bytes": 76 + "_dd.agent_psr": 1.0, + "_dd.top_level": 1.0, + "_sampling_priority_v1": 1.0, + "messaging.kafka.message_offset": 5.0, + "messaging.kafka.partition": 0.0, + "messaging.message_payload_size_bytes": 76.0 } }], [ @@ -72,7 +84,8 @@ "parent_id": 0, "type": "queue", "meta": { - "_dd.p.dm": "0", + "_dd.p.dm": "-0", + "_dd.sdk.otlp_export": "false", "component": "kafka", "messaging.kafka.bootstrap.servers": "kafka-integration:9092", "messaging.kafka.client_id": "rdkafka", @@ -80,12 +93,12 @@ "messaging.kafka.tombstone": "true", "messaging.operation": "receive", "messaging.system": "kafka", - "runtime-id": "cb546b0e-9a6f-450b-8bf2-359f968d021f", + "runtime-id": "f311028f-7a98-47ca-9436-bec6441ffc16", "span.kind": "consumer" }, "metrics": { - "_dd.agent_psr": 1, - "_dd.top_level": 1, - "_sampling_priority_v1": 1 + "_dd.agent_psr": 1.0, + "_dd.top_level": 1.0, + "_sampling_priority_v1": 1.0 } }]] diff --git a/tests/snapshots/tests.integrations.laravel.v8_x.queue_test.test_broadcast.json b/tests/snapshots/tests.integrations.laravel.v8_x.queue_test.test_broadcast.json index 971f75b6c50..4d7c47034c9 100644 --- a/tests/snapshots/tests.integrations.laravel.v8_x.queue_test.test_broadcast.json +++ b/tests/snapshots/tests.integrations.laravel.v8_x.queue_test.test_broadcast.json @@ -260,12 +260,14 @@ "component": "laravelqueue", "messaging.destination": "sync", "messaging.destination_kind": "queue", - "messaging.laravel.attempts": "1", "messaging.laravel.connection": "sync", "messaging.laravel.name": "App\\Events\\NoopEvent", "messaging.operation": "process", "messaging.system": "laravel", "span.kind": "client" + }, + "metrics": { + "messaging.laravel.attempts": 1 } }, { @@ -280,12 +282,14 @@ "component": "laravelqueue", "messaging.destination": "sync", "messaging.destination_kind": "queue", - "messaging.laravel.attempts": "1", "messaging.laravel.connection": "sync", "messaging.laravel.name": "App\\Events\\NoopEvent", "messaging.operation": "process", "messaging.system": "laravel", "span.kind": "client" + }, + "metrics": { + "messaging.laravel.attempts": 1 } }, { diff --git a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_return_string.json index 7e8e4c01c9c..a8f787708d7 100644 --- a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_return_string.json @@ -14,7 +14,6 @@ "http.status_code": "200", "http.url": "http://localhost/datadog/simple/index?key=value&", "magento.area": "frontend", - "magento.cached": "false", "magento.frontname": "datadog", "magento.pathinfo": "datadog/simple/index", "magento.route": "datadog", @@ -23,7 +22,8 @@ }, "metrics": { "_dd.top_level": 1.0, - "_sampling_priority_v1": 1.0 + "_sampling_priority_v1": 1.0, + "magento.cached": 0 } }, { diff --git a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json index 62985721749..364041b5eec 100644 --- a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -14,7 +14,6 @@ "http.status_code": "404", "http.url": "http://localhost/does_not_exist?key=value&", "magento.area": "frontend", - "magento.cached": "false", "magento.frontname": "does_not_exist", "magento.pathinfo": "cms/noroute/index", "magento.route": "cms", @@ -23,7 +22,8 @@ }, "metrics": { "_dd.top_level": 1.0, - "_sampling_priority_v1": 1.0 + "_sampling_priority_v1": 1.0, + "magento.cached": 0 } }, { @@ -1767,11 +1767,13 @@ "meta": { "component": "magento", "magento.block.area": "frontend", - "magento.block.cache_lifetime": "3600", "magento.block.class": "Magento\\Theme\\Block\\Html\\Footer", "magento.block.module": "Magento_Theme", "magento.block.name": "absolute_footer", "magento.block.template": "Magento_Theme::html/absolute_footer.phtml" + }, + "metrics": { + "magento.block.cache_lifetime": 3600 } }, { @@ -1785,11 +1787,13 @@ "meta": { "component": "magento", "magento.block.area": "frontend", - "magento.block.cache_lifetime": "3600", "magento.block.class": "Magento\\Theme\\Block\\Html\\Footer", "magento.block.module": "Magento_Theme", "magento.block.name": "copyright", "magento.block.template": "Magento_Theme::html/copyright.phtml" + }, + "metrics": { + "magento.block.cache_lifetime": 3600 } }, { diff --git a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_exception.json index ef08bad4c65..0fc70ccea60 100644 --- a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_exception.json @@ -18,7 +18,6 @@ "http.status_code": "500", "http.url": "http://localhost/datadog/error/index?key=value&", "magento.area": "frontend", - "magento.cached": "false", "magento.frontname": "datadog", "magento.pathinfo": "datadog/error/index", "magento.route": "datadog", @@ -27,7 +26,8 @@ }, "metrics": { "_dd.top_level": 1.0, - "_sampling_priority_v1": 1.0 + "_sampling_priority_v1": 1.0, + "magento.cached": 0 } }, { diff --git a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_view.json index 9f749be8df6..198762707ef 100644 --- a/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.magento.v2_3.common_scenarios_test.test_scenario_get_with_view.json @@ -14,7 +14,6 @@ "http.status_code": "200", "http.url": "http://localhost/datadog/simpleview/index?key=value&", "magento.area": "frontend", - "magento.cached": "false", "magento.frontname": "datadog", "magento.pathinfo": "datadog/simpleview/index", "magento.route": "datadog", @@ -23,7 +22,8 @@ }, "metrics": { "_dd.top_level": 1.0, - "_sampling_priority_v1": 1.0 + "_sampling_priority_v1": 1.0, + "magento.cached": 0 } }, { @@ -1687,11 +1687,13 @@ "meta": { "component": "magento", "magento.block.area": "frontend", - "magento.block.cache_lifetime": "3600", "magento.block.class": "Magento\\Theme\\Block\\Html\\Footer", "magento.block.module": "Magento_Theme", "magento.block.name": "absolute_footer", "magento.block.template": "Magento_Theme::html/absolute_footer.phtml" + }, + "metrics": { + "magento.block.cache_lifetime": 3600 } }, { @@ -1720,11 +1722,13 @@ "meta": { "component": "magento", "magento.block.area": "frontend", - "magento.block.cache_lifetime": "3600", "magento.block.class": "Magento\\Theme\\Block\\Html\\Footer", "magento.block.module": "Magento_Theme", "magento.block.name": "copyright", "magento.block.template": "Magento_Theme::html/copyright.phtml" + }, + "metrics": { + "magento.block.cache_lifetime": 3600 } }, { diff --git a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_return_string.json b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_return_string.json index 68dc912b0b6..c8df8c40302 100644 --- a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_return_string.json +++ b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_return_string.json @@ -14,7 +14,6 @@ "http.status_code": "200", "http.url": "http://localhost/datadog/simple/index?key=value&", "magento.area": "frontend", - "magento.cached": "false", "magento.frontname": "datadog", "magento.pathinfo": "datadog/simple/index", "magento.route": "datadog", @@ -23,7 +22,8 @@ }, "metrics": { "_dd.top_level": 1.0, - "_sampling_priority_v1": 1.0 + "_sampling_priority_v1": 1.0, + "magento.cached": 0 } }, { diff --git a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_to_missing_route.json b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_to_missing_route.json index 9ea121f0eac..c71e8a0fe98 100644 --- a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_to_missing_route.json +++ b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_to_missing_route.json @@ -14,7 +14,6 @@ "http.status_code": "404", "http.url": "http://localhost/does_not_exist?key=value&", "magento.area": "frontend", - "magento.cached": "false", "magento.frontname": "does_not_exist", "magento.pathinfo": "cms/noroute/index", "magento.route": "cms", @@ -23,7 +22,8 @@ }, "metrics": { "_dd.top_level": 1.0, - "_sampling_priority_v1": 1.0 + "_sampling_priority_v1": 1.0, + "magento.cached": 0 } }, { @@ -1962,11 +1962,13 @@ "meta": { "component": "magento", "magento.block.area": "frontend", - "magento.block.cache_lifetime": "3600", "magento.block.class": "Magento\\Theme\\Block\\Html\\Footer", "magento.block.module": "Magento_Theme", "magento.block.name": "absolute_footer", "magento.block.template": "Magento_Theme::html/absolute_footer.phtml" + }, + "metrics": { + "magento.block.cache_lifetime": 3600 } }, { @@ -1980,11 +1982,13 @@ "meta": { "component": "magento", "magento.block.area": "frontend", - "magento.block.cache_lifetime": "3600", "magento.block.class": "Magento\\Theme\\Block\\Html\\Footer", "magento.block.module": "Magento_Theme", "magento.block.name": "copyright", "magento.block.template": "Magento_Theme::html/copyright.phtml" + }, + "metrics": { + "magento.block.cache_lifetime": 3600 } }, { diff --git a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_exception.json b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_exception.json index fe0454314f7..9862871ecf7 100644 --- a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_exception.json +++ b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_exception.json @@ -18,7 +18,6 @@ "http.status_code": "500", "http.url": "http://localhost/datadog/error/index?key=value&", "magento.area": "frontend", - "magento.cached": "false", "magento.frontname": "datadog", "magento.pathinfo": "datadog/error/index", "magento.route": "datadog", @@ -27,7 +26,8 @@ }, "metrics": { "_dd.top_level": 1.0, - "_sampling_priority_v1": 1.0 + "_sampling_priority_v1": 1.0, + "magento.cached": 0 } }, { diff --git a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_view.json index dae272177b5..c4d8ab9c391 100644 --- a/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.magento.v2_4.common_scenarios_test.test_scenario_get_with_view.json @@ -14,7 +14,6 @@ "http.status_code": "200", "http.url": "http://localhost/datadog/simpleview/index?key=value&", "magento.area": "frontend", - "magento.cached": "false", "magento.frontname": "datadog", "magento.pathinfo": "datadog/simpleview/index", "magento.route": "datadog", @@ -23,7 +22,8 @@ }, "metrics": { "_dd.top_level": 1.0, - "_sampling_priority_v1": 1.0 + "_sampling_priority_v1": 1.0, + "magento.cached": 0 } }, { @@ -1765,11 +1765,13 @@ "meta": { "component": "magento", "magento.block.area": "frontend", - "magento.block.cache_lifetime": "3600", "magento.block.class": "Magento\\Theme\\Block\\Html\\Footer", "magento.block.module": "Magento_Theme", "magento.block.name": "absolute_footer", "magento.block.template": "Magento_Theme::html/absolute_footer.phtml" + }, + "metrics": { + "magento.block.cache_lifetime": 3600 } }, { @@ -1798,11 +1800,13 @@ "meta": { "component": "magento", "magento.block.area": "frontend", - "magento.block.cache_lifetime": "3600", "magento.block.class": "Magento\\Theme\\Block\\Html\\Footer", "magento.block.module": "Magento_Theme", "magento.block.name": "copyright", "magento.block.template": "Magento_Theme::html/copyright.phtml" + }, + "metrics": { + "magento.block.cache_lifetime": 3600 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json index 4975bfd0f8e..5a5a3a59bb8 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json @@ -18,6 +18,7 @@ "openai.request.fine_tune_id": "ftjob-AF1WoRqd3aJAHsqc9NY7iL8F", "openai.request.method": "POST", "openai.response.fine_tuned_model": "curie => ft-acmeco-2021-03-03-21-44-20", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "fine-tune", "openai.response.status": "cancelled", @@ -36,7 +37,6 @@ "openai.response.hyperparams.learning_rate_multiplier": 0.1, "openai.response.hyperparams.n_epochs": 4, "openai.response.hyperparams.prompt_loss_weight": 0.1, - "openai.response.id": 42, "openai.response.result_files_count": 2, "openai.response.training_files_count": 2, "openai.response.updated_at": 1614807865, diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json index 999fbe903c2..18adbfce5e7 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json @@ -21,6 +21,7 @@ "openai.response.choices.0.finish_reason": "stop", "openai.response.choices.0.message.content": "\\n\\nHello there, how may I assist you today?", "openai.response.choices.0.message.role": "assistant", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "chat.completion", "openai.user.api_key": "sk-...9d5d", @@ -34,7 +35,6 @@ "_sampling_priority_v1": 1, "openai.response.choices_count": 1, "openai.response.created": 1677652288, - "openai.response.id": 42, "openai.response.usage.completion_tokens": 12, "openai.response.usage.prompt_tokens": 9, "openai.response.usage.total_tokens": 21 diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json index 8eb6da8514b..f44af6c9b7c 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json @@ -18,6 +18,7 @@ "openai.request.message.0.role": "user", "openai.request.method": "POST", "openai.request.model": "gpt-3.5-turbo", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.user.api_key": "sk-...9d5d", "runtime-id": "87cccdb5-2d7c-453e-bc51-70997f55724c", @@ -30,7 +31,6 @@ "_sampling_priority_v1": 1, "openai.request.prompt_tokens_estimated": 1, "openai.response.completion_tokens_estimated": 1, - "openai.response.id": 42, "openai.response.usage.completion_tokens": 6, "openai.response.usage.prompt_tokens": 1, "openai.response.usage.total_tokens": 7 diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json index 537b7d67df6..ebf92d055eb 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json @@ -20,6 +20,7 @@ "openai.request.model": "gpt-4-turbo", "openai.response.choices.0.finish_reason": "tool_calls", "openai.response.choices.0.message.role": "assistant", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "chat.completion", "openai.user.api_key": "sk-...9d5d", @@ -33,7 +34,6 @@ "_sampling_priority_v1": 1, "openai.response.choices_count": 1, "openai.response.created": 1699896916, - "openai.response.id": 42, "openai.response.usage.completion_tokens": 17, "openai.response.usage.prompt_tokens": 82, "openai.response.usage.total_tokens": 99 diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json index 6c4a22e08e2..a5cebe31d9d 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json @@ -14,7 +14,6 @@ "openai.api_base": "https://api.openai.com/v1/", "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/chat/completions", - "openai.request.max_tokens": "300", "openai.request.message.0.content": "[{\"type\":\"text\",\"text\":\"What's in this image?\"},{\"type\":\"image_url\",\"image_url\":{\"url\":\"https:\\/\\/example.com\\/image.jpg\"}}]", "openai.request.message.0.role": "user", "openai.request.method": "POST", @@ -22,6 +21,7 @@ "openai.response.choices.0.finish_reason": "stop", "openai.response.choices.0.message.content": "\\n\\nThis image shows a wooden boardwalk extending through a lush green marshland.", "openai.response.choices.0.message.role": "assistant", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "chat.completion", "openai.user.api_key": "sk-...9d5d", @@ -33,9 +33,9 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, + "openai.request.max_tokens": 300, "openai.response.choices_count": 1, "openai.response.created": 1677652288, - "openai.response.id": 42, "openai.response.usage.completion_tokens": 12, "openai.response.usage.prompt_tokens": 9, "openai.response.usage.total_tokens": 21 diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json index ec8e4fbf2cc..68ea7f948f7 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json @@ -23,6 +23,7 @@ "openai.response.choices.0.finish_reason": "stop", "openai.response.choices.0.message.content": "\\n\\nHello there, how may I assist you today?", "openai.response.choices.0.message.role": "assistant", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "chat.completion", "openai.user.api_key": "sk-...9d5d", @@ -36,7 +37,6 @@ "_sampling_priority_v1": 1, "openai.response.choices_count": 1, "openai.response.created": 1677652288, - "openai.response.id": 42, "openai.response.usage.completion_tokens": 12, "openai.response.usage.prompt_tokens": 9, "openai.response.usage.total_tokens": 21 diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json index 627cd2cdc20..a18eb706555 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json @@ -14,13 +14,13 @@ "openai.api_base": "https://api.openai.com/v1/", "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/completions", - "openai.request.logit_bias.50256": "-100", "openai.request.method": "POST", "openai.request.model": "da-vince", "openai.request.prompt": "hi", "openai.request.user": "dd-trace", "openai.response.choices.0.finish_reason": "length", "openai.response.choices.0.text": "el, she elaborates more on the Corruptor's role, suggesting K", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "text_completion", "openai.user.api_key": "sk-...9d5d", @@ -32,9 +32,9 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, + "openai.request.logit_bias.50256": -100, "openai.response.choices_count": 1, "openai.response.created": 1664136088, - "openai.response.id": 42, "openai.response.usage.completion_tokens": 16, "openai.response.usage.prompt_tokens": 1, "openai.response.usage.total_tokens": 17 diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json index a95f67fab32..51db37e24a6 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json @@ -17,6 +17,7 @@ "openai.request.method": "POST", "openai.request.model": "gpt-3.5-turbo-instruct", "openai.request.prompt": "hi", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.user.api_key": "sk-...9d5d", "runtime-id": "87cccdb5-2d7c-453e-bc51-70997f55724c", @@ -30,7 +31,6 @@ "openai.request.prompt_tokens_estimated": 1, "openai.request.streamed": 1, "openai.response.completion_tokens_estimated": 1, - "openai.response.id": 42, "openai.response.usage.completion_tokens": 7, "openai.response.usage.prompt_tokens": 0, "openai.response.usage.total_tokens": 7 diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json index 51356a08fcb..81ed454fe97 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json @@ -17,6 +17,7 @@ "openai.request.input": "The food was delicious and the waiter...", "openai.request.method": "POST", "openai.request.model": "text-similarity-babbage-001", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "list", "openai.user.api_key": "sk-...9d5d", @@ -31,7 +32,6 @@ "openai.response.embeddings.0.embedding_length": 3, "openai.response.embeddings.1.embedding_length": 3, "openai.response.embeddings_count": 2, - "openai.response.id": 42, "openai.response.usage.prompt_tokens": 8, "openai.response.usage.total_tokens": 8 } diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json index 0a1f9b3434e..eca2ef62da7 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json @@ -18,6 +18,7 @@ "openai.request.input.1": "The food was terrible and the waiter...", "openai.request.method": "POST", "openai.request.model": "text-similarity-babbage-001", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "list", "openai.user.api_key": "sk-...9d5d", @@ -32,7 +33,6 @@ "openai.response.embeddings.0.embedding_length": 3, "openai.response.embeddings.1.embedding_length": 3, "openai.response.embeddings_count": 2, - "openai.response.id": 42, "openai.response.usage.prompt_tokens": 8, "openai.response.usage.total_tokens": 8 } diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json index 58b124bb591..5d28427f4ae 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json @@ -18,6 +18,7 @@ "openai.request.method": "POST", "openai.request.purpose": "fine-tune", "openai.response.filename": "mydata.jsonl", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "file", "openai.response.purpose": "fine-tune", @@ -32,8 +33,7 @@ "_dd.measured": 1, "_sampling_priority_v1": 1, "openai.response.bytes": 140, - "openai.response.created_at": 1613779121, - "openai.response.id": 42 + "openai.response.created_at": 1613779121 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json index 8731592998f..4b348744200 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json @@ -15,10 +15,10 @@ "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/images/generations", "openai.request.method": "POST", - "openai.request.n": "1", "openai.request.prompt": "A cute baby sea otter", "openai.request.response_format": "url", "openai.request.size": "256x256", + "openai.response.id": "42", "openai.response.images.0.url": "https://openai.com/image.png", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.user.api_key": "sk-...9d5d", @@ -30,8 +30,8 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, + "openai.request.n": 1, "openai.response.created": 1664136088, - "openai.response.id": 42, "openai.response.images_count": 1 } }, diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json index db236b7668f..d7f4358c27c 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json @@ -16,10 +16,10 @@ "openai.request.endpoint": "/v1/images/edits", "openai.request.mask": "MyFile.jsonl", "openai.request.method": "POST", - "openai.request.n": "1", "openai.request.prompt": "A sunlit indoor lounge area with a pool containing a flamingo", "openai.request.response_format": "url", "openai.request.size": "256x256", + "openai.response.id": "42", "openai.response.images.0.url": "https://openai.com/image.png", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.user.api_key": "sk-...9d5d", @@ -31,8 +31,8 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, + "openai.request.n": 1, "openai.response.created": 1664136088, - "openai.response.id": 42, "openai.response.images_count": 1 } }, diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json index af3374ec4eb..871c147fc5b 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json @@ -15,9 +15,9 @@ "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/images/variations", "openai.request.method": "POST", - "openai.request.n": "1", "openai.request.response_format": "url", "openai.request.size": "256x256", + "openai.response.id": "42", "openai.response.images.0.url": "https://openai.com/image.png", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.user.api_key": "sk-...9d5d", @@ -29,8 +29,8 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, + "openai.request.n": 1, "openai.response.created": 1664136088, - "openai.response.id": 42, "openai.response.images_count": 1 } }, diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json index f62bf9b8fb8..a0b45d02b1e 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json @@ -28,6 +28,7 @@ "openai.response.categories.sexual/minors": "false", "openai.response.categories.violence": "true", "openai.response.categories.violence/graphic": "false", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.user.api_key": "sk-...9d5d", "runtime-id": "87cccdb5-2d7c-453e-bc51-70997f55724c", @@ -49,8 +50,7 @@ "openai.response.category_scores.sexual/minors": 0.0038522258400917053, "openai.response.category_scores.violence": 0.9223177433013916, "openai.response.category_scores.violence/graphic": 0.036865197122097015, - "openai.response.flagged": 1, - "openai.response.id": 42 + "openai.response.flagged": 1 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json index 9db1590381d..f7cd4072a18 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json @@ -18,6 +18,7 @@ "openai.request.method": "POST", "openai.request.model": "whisper-1", "openai.request.response_format": "json", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.text": "Hello, how are you?", "openai.user.api_key": "sk-...9d5d", @@ -29,7 +30,6 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, - "openai.response.id": 42, "openai.response.segments_count": 0 } }, diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json index ef3379ab5c0..cfeec32afd4 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json @@ -19,7 +19,7 @@ "openai.request.model": "whisper-1", "openai.request.prompt": "Transcribe the following audio", "openai.request.response_format": "text", - "openai.request.temperature": "0.7", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.text": "Hello, how are you?", "openai.user.api_key": "sk-...9d5d", @@ -31,7 +31,7 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, - "openai.response.id": 42, + "openai.request.temperature": 0.7, "openai.response.segments_count": 0 } }, diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json index 313a8b2dfe6..ce634989b30 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json @@ -18,6 +18,7 @@ "openai.request.method": "POST", "openai.request.model": "whisper-1", "openai.request.response_format": "verbose_json", + "openai.response.id": "42", "openai.response.language": "english", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.text": "Hello, how are you?", @@ -31,7 +32,6 @@ "_dd.measured": 1, "_sampling_priority_v1": 1, "openai.response.duration": 2.95, - "openai.response.id": 42, "openai.response.segments_count": 1 } }, diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json index f449ee2fa0c..234174d144c 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json @@ -18,6 +18,7 @@ "openai.request.method": "POST", "openai.request.model": "whisper-1", "openai.request.response_format": "json", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.text": "Hello, how are you?", "openai.user.api_key": "sk-...9d5d", @@ -29,7 +30,6 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, - "openai.response.id": 42, "openai.response.segments_count": 0 } }, diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json index 29fa2b93272..19476735058 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json @@ -19,7 +19,7 @@ "openai.request.model": "whisper-1", "openai.request.prompt": "Translate the following audio", "openai.request.response_format": "text", - "openai.request.temperature": "0.7", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.text": "Hello, how are you?", "openai.user.api_key": "sk-...9d5d", @@ -31,7 +31,7 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, - "openai.response.id": 42, + "openai.request.temperature": 0.7, "openai.response.segments_count": 0 } }, diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json index d4a9ea4022c..d932c5d19dc 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json @@ -18,6 +18,7 @@ "openai.request.method": "POST", "openai.request.model": "whisper-1", "openai.request.response_format": "verbose_json", + "openai.response.id": "42", "openai.response.language": "english", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.text": "Hello, how are you?", @@ -31,7 +32,6 @@ "_dd.measured": 1, "_sampling_priority_v1": 1, "openai.response.duration": 2.95, - "openai.response.id": 42, "openai.response.segments_count": 1 } }, diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json index 99a4bdd3efb..0c1e585fff6 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json @@ -17,6 +17,7 @@ "openai.request.file_id": "file-XjGxS3KTG0uNmNOK362iJua3", "openai.request.method": "DELETE", "openai.response.deleted": "true", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "file", "openai.user.api_key": "sk-...9d5d", @@ -27,8 +28,7 @@ "metrics": { "_dd.agent_psr": 1, "_dd.measured": 1, - "_sampling_priority_v1": 1, - "openai.response.id": 42 + "_sampling_priority_v1": 1 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json index 0d2514c24d9..d2a8e244ced 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json @@ -17,6 +17,7 @@ "openai.request.fine_tune_id": "curie:ft-acmeco-2021-03-03-21-44-20", "openai.request.method": "DELETE", "openai.response.deleted": "true", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "model", "openai.user.api_key": "sk-...9d5d", @@ -27,8 +28,7 @@ "metrics": { "_dd.agent_psr": 1, "_dd.measured": 1, - "_sampling_priority_v1": 1, - "openai.response.id": 42 + "_sampling_priority_v1": 1 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json index 97ea693cde2..170f40b23f5 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json @@ -15,6 +15,7 @@ "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/files", "openai.request.method": "GET", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "list", "openai.user.api_key": "sk-...9d5d", @@ -26,8 +27,7 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, - "openai.response.count": 2, - "openai.response.id": 42 + "openai.response.count": 2 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json index 0007ab3b8f0..45a2965fd47 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json @@ -16,6 +16,7 @@ "openai.request.endpoint": "/v1/fine-tunes/*/events", "openai.request.fine_tune_id": "ftjob-AF1WoRqd3aJAHsqc9NY7iL8F", "openai.request.method": "GET", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "list", "openai.user.api_key": "sk-...9d5d", @@ -27,8 +28,7 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, - "openai.response.count": 2, - "openai.response.id": 42 + "openai.response.count": 2 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json index 80ffb656efa..a3d231ee4e7 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json @@ -16,6 +16,7 @@ "openai.request.endpoint": "/v1/fine-tunes/*/events", "openai.request.fine_tune_id": "ft-MaoEAULREoazpupm8uB7qoIl", "openai.request.method": "GET", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.user.api_key": "sk-...9d5d", "runtime-id": "87cccdb5-2d7c-453e-bc51-70997f55724c", @@ -25,8 +26,7 @@ "metrics": { "_dd.agent_psr": 1, "_dd.measured": 1, - "_sampling_priority_v1": 1, - "openai.response.id": 42 + "_sampling_priority_v1": 1 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json index 9e72afe70bf..2e0072a9534 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json @@ -15,6 +15,7 @@ "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/models", "openai.request.method": "GET", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "list", "openai.user.api_key": "sk-...9d5d", @@ -26,8 +27,7 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, - "openai.response.count": 2, - "openai.response.id": 42 + "openai.response.count": 2 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json index b9b654dce80..bfb64d5a4d6 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json @@ -14,13 +14,13 @@ "openai.api_base": "https://api.openai.com/v1/", "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/completions", - "openai.request.logit_bias.50256": "-100", "openai.request.method": "POST", "openai.request.model": "da-vince", "openai.request.prompt": "Tell me a joke", "openai.request.user": "dd-trace", "openai.response.choices.0.finish_reason": "length", "openai.response.choices.0.text": "el, she elaborates more on the Corruptor's role, suggesting K", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "text_completion", "openai.user.api_key": "sk-...9d5d", @@ -32,9 +32,9 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, + "openai.request.logit_bias.50256": -100, "openai.response.choices_count": 1, "openai.response.created": 1664136088, - "openai.response.id": 42, "openai.response.usage.completion_tokens": 16, "openai.response.usage.prompt_tokens": 1, "openai.response.usage.total_tokens": 17 diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json index 33b608434f8..dca9c71a4c1 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json @@ -15,6 +15,7 @@ "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/models", "openai.request.method": "GET", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "list", "openai.user.api_key": "sk-...9d5d", @@ -26,8 +27,7 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, - "openai.response.count": 2, - "openai.response.id": 42 + "openai.response.count": 2 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json index 158ae73a91c..35bc02f5507 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json @@ -15,6 +15,7 @@ "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/models", "openai.request.method": "GET", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "list", "openai.user.api_key": "sk-...9d5d", @@ -26,8 +27,7 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, - "openai.response.count": 2, - "openai.response.id": 42 + "openai.response.count": 2 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json index 21013bf0579..793b2fcf795 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json @@ -15,18 +15,19 @@ "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/models", "openai.request.method": "GET", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "list", "openai.user.api_key": "sk-...9d5d", "runtime-id": "87cccdb5-2d7c-453e-bc51-70997f55724c", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" }, "metrics": { "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, - "openai.response.count": 2, - "openai.response.id": 42 + "openai.response.count": 2 } }, { @@ -44,6 +45,7 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json index 967a3817aa1..9a820541ef2 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json @@ -17,6 +17,7 @@ "openai.request.file_id": "file-XjGxS3KTG0uNmNOK362iJua3", "openai.request.method": "GET", "openai.response.filename": "mydata.jsonl", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "file", "openai.response.purpose": "fine-tune", @@ -31,8 +32,7 @@ "_dd.measured": 1, "_sampling_priority_v1": 1, "openai.response.bytes": 140, - "openai.response.created_at": 1613779121, - "openai.response.id": 42 + "openai.response.created_at": 1613779121 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json index c7f8942acd4..8d0654939e9 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json @@ -18,6 +18,7 @@ "openai.request.fine_tune_id": "ftjob-AF1WoRqd3aJAHsqc9NY7iL8F", "openai.request.method": "GET", "openai.response.fine_tuned_model": "ft:gpt-3.5-turbo-0613:jwe-dev::7qnxQ0sQ", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "fine_tuning.job", "openai.response.status": "succeeded", @@ -31,7 +32,6 @@ "_dd.measured": 1, "_sampling_priority_v1": 1, "openai.response.created_at": 1614807352, - "openai.response.id": 42, "openai.response.result_files_count": 1 } }, diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json index 076e7a562e0..3e71d852ed0 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json @@ -16,6 +16,7 @@ "openai.request.endpoint": "/v1/models/*", "openai.request.method": "GET", "openai.request.model": "da-vince", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "model", "openai.response.owned_by": "openai", @@ -28,8 +29,7 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, - "openai.response.created": 1642018370, - "openai.response.id": 42 + "openai.response.created": 1642018370 } }, { diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json index 25ce2126def..65558cef1d8 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json @@ -14,13 +14,13 @@ "openai.api_base": "https://api.openai.com/v1/", "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/completions", - "openai.request.logit_bias.50256": "-100", "openai.request.method": "POST", "openai.request.model": "da-vince", "openai.request.prompt": "Tel...", "openai.request.user": "dd-trace", "openai.response.choices.0.finish_reason": "length", "openai.response.choices.0.text": "el,...", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "text_completion", "openai.user.api_key": "sk-...9d5d", @@ -32,9 +32,9 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, + "openai.request.logit_bias.50256": -100, "openai.response.choices_count": 1, "openai.response.created": 1664136088, - "openai.response.id": 42, "openai.response.usage.completion_tokens": 16, "openai.response.usage.prompt_tokens": 1, "openai.response.usage.total_tokens": 17 diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json index f6b5f4fc38c..f57358f8d45 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json @@ -14,11 +14,11 @@ "openai.api_base": "https://api.openai.com/v1/", "openai.organization.name": "org-1234", "openai.request.endpoint": "/v1/completions", - "openai.request.logit_bias.50256": "-100", "openai.request.method": "POST", "openai.request.model": "da-vince", "openai.request.user": "dd-trace", "openai.response.choices.0.finish_reason": "length", + "openai.response.id": "42", "openai.response.model": "gpt-3.5-turbo-instruct", "openai.response.object": "text_completion", "openai.user.api_key": "sk-...9d5d", @@ -30,9 +30,9 @@ "_dd.agent_psr": 1, "_dd.measured": 1, "_sampling_priority_v1": 1, + "openai.request.logit_bias.50256": -100, "openai.response.choices_count": 1, "openai.response.created": 1664136088, - "openai.response.id": 42, "openai.response.usage.completion_tokens": 16, "openai.response.usage.prompt_tokens": 1, "openai.response.usage.total_tokens": 17 diff --git a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_failure.json b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_failure.json index f57a6772946..3192488b712 100644 --- a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_failure.json +++ b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_failure.json @@ -119,11 +119,9 @@ "type": "queue", "meta": { "_dd.code_origin.frames.1.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.1.line": "25", "_dd.code_origin.frames.1.method": "fail", "_dd.code_origin.frames.1.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.7.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination": "async", @@ -135,6 +133,8 @@ "messaging.system": "symfony" }, "metrics": { + "_dd.code_origin.frames.1.line": 25, + "_dd.code_origin.frames.7.line": 5, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -151,16 +151,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.2.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.2.line": "25", "_dd.code_origin.frames.2.method": "fail", "_dd.code_origin.frames.2.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.8.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.2.line": 25, + "_dd.code_origin.frames.8.line": 5 } }, { @@ -173,16 +175,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.3.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.3.line": "25", "_dd.code_origin.frames.3.method": "fail", "_dd.code_origin.frames.3.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.9.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.3.line": 25, + "_dd.code_origin.frames.9.line": 5 } }, { @@ -195,9 +199,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.10.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.10.line": "5", "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.4.line": "25", "_dd.code_origin.frames.4.method": "fail", "_dd.code_origin.frames.4.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -205,6 +207,10 @@ "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.10.line": 5, + "_dd.code_origin.frames.4.line": 25 } }, { @@ -217,9 +223,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.11.line": "5", "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.5.line": "25", "_dd.code_origin.frames.5.method": "fail", "_dd.code_origin.frames.5.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -228,6 +232,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.11.line": 5, + "_dd.code_origin.frames.5.line": 25 } }, { @@ -240,9 +248,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.12.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.12.line": "5", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.6.line": "25", "_dd.code_origin.frames.6.method": "fail", "_dd.code_origin.frames.6.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -251,6 +257,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.12.line": 5, + "_dd.code_origin.frames.6.line": 25 } }, { @@ -263,9 +273,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.13.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.13.line": "5", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.7.line": "25", "_dd.code_origin.frames.7.method": "fail", "_dd.code_origin.frames.7.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -274,6 +282,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.13.line": 5, + "_dd.code_origin.frames.7.line": 25 } }, { @@ -286,9 +298,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.14.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.14.line": "5", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.8.line": "25", "_dd.code_origin.frames.8.method": "fail", "_dd.code_origin.frames.8.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -297,6 +307,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.14.line": 5, + "_dd.code_origin.frames.8.line": 25 } }, { @@ -321,9 +335,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.15.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.15.line": "5", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.9.line": "25", "_dd.code_origin.frames.9.method": "fail", "_dd.code_origin.frames.9.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "entry", @@ -339,6 +351,8 @@ "span.kind": "producer" }, "metrics": { + "_dd.code_origin.frames.15.line": 5, + "_dd.code_origin.frames.9.line": 25, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -356,11 +370,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.23.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.23.line": "25", "_dd.code_origin.frames.23.method": "fail", "_dd.code_origin.frames.23.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.29.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.29.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -370,8 +382,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.23.line": 25, + "_dd.code_origin.frames.29.line": 5, + "out.port": 3306 } }, { @@ -385,11 +401,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "25", "_dd.code_origin.frames.19.method": "fail", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -399,8 +413,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.19.line": 25, + "_dd.code_origin.frames.25.line": 5, + "out.port": 3306 } }, { @@ -414,11 +432,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "25", "_dd.code_origin.frames.19.method": "fail", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -428,11 +444,13 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "_dd.code_origin.frames.19.line": 25, + "_dd.code_origin.frames.25.line": 5, + "db.row_count": 1.0, + "out.port": 3306 } }, { @@ -446,11 +464,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "25", "_dd.code_origin.frames.19.method": "fail", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -460,8 +476,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.19.line": 25, + "_dd.code_origin.frames.25.line": 5, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_failure_consumer.json b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_failure_consumer.json index a0be6567647..e40913e8f85 100644 --- a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_failure_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_failure_consumer.json @@ -10,7 +10,6 @@ "error": 1, "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Latest/bin/console", - "_dd.code_origin.frames.11.line": "11", "_dd.code_origin.type": "exit", "_dd.p.dm": "0", "_dd.p.tid": "69e7d8e800000000", @@ -29,6 +28,7 @@ "span.kind": "consumer" }, "metrics": { + "_dd.code_origin.frames.11.line": 11, "_sampling_priority_v1": 1 } }, @@ -340,7 +340,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.28.file": "{path}/tests/Frameworks/Symfony/Latest/bin/console", - "_dd.code_origin.frames.28.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -350,8 +349,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.28.line": 11, + "out.port": 3306 } }, { @@ -365,7 +367,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.28.file": "{path}/tests/Frameworks/Symfony/Latest/bin/console", - "_dd.code_origin.frames.28.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -375,11 +376,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1 + "_dd.code_origin.frames.28.line": 11, + "db.row_count": 1, + "out.port": 3306 } }, { @@ -393,7 +395,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.28.file": "{path}/tests/Frameworks/Symfony/Latest/bin/console", - "_dd.code_origin.frames.28.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -403,8 +404,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.28.line": 11, + "out.port": 3306 } }, { @@ -418,7 +422,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/bin/console", - "_dd.code_origin.frames.25.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -428,8 +431,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.25.line": 11, + "out.port": 3306 } }, { @@ -443,7 +449,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/bin/console", - "_dd.code_origin.frames.25.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -453,10 +458,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1 + "_dd.code_origin.frames.25.line": 11, + "db.row_count": 1, + "out.port": 3306 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success.json b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success.json index 380f76930f4..b22b894a2b9 100644 --- a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success.json +++ b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success.json @@ -119,11 +119,9 @@ "type": "queue", "meta": { "_dd.code_origin.frames.1.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.1.line": "17", "_dd.code_origin.frames.1.method": "number", "_dd.code_origin.frames.1.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.7.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination": "async", @@ -135,6 +133,8 @@ "messaging.system": "symfony" }, "metrics": { + "_dd.code_origin.frames.1.line": 17, + "_dd.code_origin.frames.7.line": 5, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -151,16 +151,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.2.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.2.line": "17", "_dd.code_origin.frames.2.method": "number", "_dd.code_origin.frames.2.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.8.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.2.line": 17, + "_dd.code_origin.frames.8.line": 5 } }, { @@ -173,16 +175,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.3.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.3.line": "17", "_dd.code_origin.frames.3.method": "number", "_dd.code_origin.frames.3.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.9.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.3.line": 17, + "_dd.code_origin.frames.9.line": 5 } }, { @@ -195,9 +199,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.10.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.10.line": "5", "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.4.line": "17", "_dd.code_origin.frames.4.method": "number", "_dd.code_origin.frames.4.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -205,6 +207,10 @@ "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.10.line": 5, + "_dd.code_origin.frames.4.line": 17 } }, { @@ -217,9 +223,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.11.line": "5", "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.5.line": "17", "_dd.code_origin.frames.5.method": "number", "_dd.code_origin.frames.5.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -228,6 +232,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.11.line": 5, + "_dd.code_origin.frames.5.line": 17 } }, { @@ -240,9 +248,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.12.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.12.line": "5", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.6.line": "17", "_dd.code_origin.frames.6.method": "number", "_dd.code_origin.frames.6.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -251,6 +257,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.12.line": 5, + "_dd.code_origin.frames.6.line": 17 } }, { @@ -263,9 +273,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.13.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.13.line": "5", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.7.line": "17", "_dd.code_origin.frames.7.method": "number", "_dd.code_origin.frames.7.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -274,6 +282,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.13.line": 5, + "_dd.code_origin.frames.7.line": 17 } }, { @@ -286,9 +298,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.14.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.14.line": "5", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.8.line": "17", "_dd.code_origin.frames.8.method": "number", "_dd.code_origin.frames.8.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -297,6 +307,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.14.line": 5, + "_dd.code_origin.frames.8.line": 17 } }, { @@ -321,9 +335,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.15.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.15.line": "5", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.9.line": "17", "_dd.code_origin.frames.9.method": "number", "_dd.code_origin.frames.9.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "entry", @@ -339,6 +351,8 @@ "span.kind": "producer" }, "metrics": { + "_dd.code_origin.frames.15.line": 5, + "_dd.code_origin.frames.9.line": 17, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -356,11 +370,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.23.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.23.line": "17", "_dd.code_origin.frames.23.method": "number", "_dd.code_origin.frames.23.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.29.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.29.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -370,8 +382,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.23.line": 17, + "_dd.code_origin.frames.29.line": 5, + "out.port": 3306 } }, { @@ -385,11 +401,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "17", "_dd.code_origin.frames.19.method": "number", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -399,8 +413,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.19.line": 17, + "_dd.code_origin.frames.25.line": 5, + "out.port": 3306 } }, { @@ -414,11 +432,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "17", "_dd.code_origin.frames.19.method": "number", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -428,11 +444,13 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "_dd.code_origin.frames.19.line": 17, + "_dd.code_origin.frames.25.line": 5, + "db.row_count": 1.0, + "out.port": 3306 } }, { @@ -446,11 +464,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "17", "_dd.code_origin.frames.19.method": "number", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -460,8 +476,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.19.line": 17, + "_dd.code_origin.frames.25.line": 5, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success_consumer.json b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success_consumer.json index 4272fd7d6b8..01580a21533 100644 --- a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_success_consumer.json @@ -9,7 +9,6 @@ "type": "queue", "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Latest/bin/console", - "_dd.code_origin.frames.11.line": "11", "_dd.code_origin.type": "exit", "_dd.p.dm": "0", "_dd.p.tid": "69e7c70e00000000", @@ -25,6 +24,7 @@ "span.kind": "consumer" }, "metrics": { + "_dd.code_origin.frames.11.line": 11, "_dd.top_level": 1, "_sampling_priority_v1": 1 } @@ -283,7 +283,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/bin/console", - "_dd.code_origin.frames.25.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -293,11 +292,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "_dd.top_level": 1 + "_dd.code_origin.frames.25.line": 11, + "_dd.top_level": 1, + "out.port": 3306 } }, { @@ -311,7 +311,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/bin/console", - "_dd.code_origin.frames.25.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -321,11 +320,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { + "_dd.code_origin.frames.25.line": 11, "_dd.top_level": 1, - "db.row_count": 1 + "db.row_count": 1, + "out.port": 3306 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_with_tracer_disabled_on_consume.json b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_with_tracer_disabled_on_consume.json index 197943a03ac..0800d4faee6 100644 --- a/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_with_tracer_disabled_on_consume.json +++ b/tests/snapshots/tests.integrations.symfony.latest.messenger_test.test_async_with_tracer_disabled_on_consume.json @@ -119,11 +119,9 @@ "type": "queue", "meta": { "_dd.code_origin.frames.1.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.1.line": "17", "_dd.code_origin.frames.1.method": "number", "_dd.code_origin.frames.1.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.7.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination": "async", @@ -135,6 +133,8 @@ "messaging.system": "symfony" }, "metrics": { + "_dd.code_origin.frames.1.line": 17, + "_dd.code_origin.frames.7.line": 5, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -151,16 +151,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.2.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.2.line": "17", "_dd.code_origin.frames.2.method": "number", "_dd.code_origin.frames.2.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.8.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.2.line": 17, + "_dd.code_origin.frames.8.line": 5 } }, { @@ -173,16 +175,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.3.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.3.line": "17", "_dd.code_origin.frames.3.method": "number", "_dd.code_origin.frames.3.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.9.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.3.line": 17, + "_dd.code_origin.frames.9.line": 5 } }, { @@ -195,9 +199,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.10.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.10.line": "5", "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.4.line": "17", "_dd.code_origin.frames.4.method": "number", "_dd.code_origin.frames.4.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -205,6 +207,10 @@ "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.10.line": 5, + "_dd.code_origin.frames.4.line": 17 } }, { @@ -217,9 +223,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.11.line": "5", "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.5.line": "17", "_dd.code_origin.frames.5.method": "number", "_dd.code_origin.frames.5.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -228,6 +232,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.11.line": 5, + "_dd.code_origin.frames.5.line": 17 } }, { @@ -240,9 +248,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.12.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.12.line": "5", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.6.line": "17", "_dd.code_origin.frames.6.method": "number", "_dd.code_origin.frames.6.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -251,6 +257,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.12.line": 5, + "_dd.code_origin.frames.6.line": 17 } }, { @@ -263,9 +273,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.13.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.13.line": "5", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.7.line": "17", "_dd.code_origin.frames.7.method": "number", "_dd.code_origin.frames.7.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -274,6 +282,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.13.line": 5, + "_dd.code_origin.frames.7.line": 17 } }, { @@ -286,9 +298,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.14.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.14.line": "5", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.8.line": "17", "_dd.code_origin.frames.8.method": "number", "_dd.code_origin.frames.8.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -297,6 +307,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.14.line": 5, + "_dd.code_origin.frames.8.line": 17 } }, { @@ -321,9 +335,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.15.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.15.line": "5", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.9.line": "17", "_dd.code_origin.frames.9.method": "number", "_dd.code_origin.frames.9.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "entry", @@ -339,6 +351,8 @@ "span.kind": "producer" }, "metrics": { + "_dd.code_origin.frames.15.line": 5, + "_dd.code_origin.frames.9.line": 17, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -356,11 +370,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.23.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.23.line": "17", "_dd.code_origin.frames.23.method": "number", "_dd.code_origin.frames.23.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.29.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.29.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -370,8 +382,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.23.line": 17, + "_dd.code_origin.frames.29.line": 5, + "out.port": 3306 } }, { @@ -385,11 +401,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "17", "_dd.code_origin.frames.19.method": "number", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -399,8 +413,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.19.line": 17, + "_dd.code_origin.frames.25.line": 5, + "out.port": 3306 } }, { @@ -414,11 +432,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "17", "_dd.code_origin.frames.19.method": "number", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -428,11 +444,13 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "_dd.code_origin.frames.19.line": 17, + "_dd.code_origin.frames.25.line": 5, + "db.row_count": 1.0, + "out.port": 3306 } }, { @@ -446,11 +464,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Latest/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "17", "_dd.code_origin.frames.19.method": "number", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Latest/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -460,8 +476,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.19.line": 17, + "_dd.code_origin.frames.25.line": 5, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_failure.json b/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_failure.json index d5149dfdc8d..22c87fd7eaf 100644 --- a/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_failure.json +++ b/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_failure.json @@ -285,8 +285,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -307,8 +309,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -329,11 +333,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "db.row_count": 1.0, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_failure_consumer.json b/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_failure_consumer.json index 8d286c588fd..d26f4be7108 100644 --- a/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_failure_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_failure_consumer.json @@ -283,8 +283,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -305,10 +307,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1 + "db.row_count": 1, + "out.port": 3306 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_success.json b/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_success.json index 022b59c7af8..57cce9866de 100644 --- a/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_success.json +++ b/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_success.json @@ -285,8 +285,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -307,8 +309,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -329,11 +333,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "db.row_count": 1.0, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_success_consumer.json b/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_success_consumer.json index 3395a724db3..5573547151d 100644 --- a/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_success_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_success_consumer.json @@ -265,8 +265,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -287,10 +289,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1 + "db.row_count": 1, + "out.port": 3306 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_with_tracer_disabled_on_consume.json b/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_with_tracer_disabled_on_consume.json index d4041b31693..9fdc3a9dc87 100644 --- a/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_with_tracer_disabled_on_consume.json +++ b/tests/snapshots/tests.integrations.symfony.v4_4.messenger_test.test_async_with_tracer_disabled_on_consume.json @@ -285,8 +285,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -307,8 +309,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -329,11 +333,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "db.row_count": 1.0, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_failure.json b/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_failure.json index b855eb677e8..85cd5eaf9a1 100644 --- a/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_failure.json +++ b/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_failure.json @@ -285,8 +285,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -307,8 +309,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -329,11 +333,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "db.row_count": 1.0, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_failure_consumer.json b/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_failure_consumer.json index 2a19adbfa9d..b64a856697d 100644 --- a/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_failure_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_failure_consumer.json @@ -316,8 +316,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -338,11 +340,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1 + "db.row_count": 1, + "out.port": 3306 } }, { @@ -363,8 +365,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -385,10 +389,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1 + "db.row_count": 1, + "out.port": 3306 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_success.json b/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_success.json index 98689bf55ac..1d3fede790f 100644 --- a/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_success.json +++ b/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_success.json @@ -285,8 +285,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -307,8 +309,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -329,11 +333,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "db.row_count": 1.0, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_success_consumer.json b/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_success_consumer.json index 14f5c414f1a..061f0b279b6 100644 --- a/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_success_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_success_consumer.json @@ -265,8 +265,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -287,10 +289,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1 + "db.row_count": 1, + "out.port": 3306 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_with_tracer_disabled_on_consume.json b/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_with_tracer_disabled_on_consume.json index 63c6603940c..069f7ce4d76 100644 --- a/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_with_tracer_disabled_on_consume.json +++ b/tests/snapshots/tests.integrations.symfony.v5_2.messenger_test.test_async_with_tracer_disabled_on_consume.json @@ -285,8 +285,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -307,8 +309,10 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "out.port": 3306 } }, { @@ -329,11 +333,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "db.row_count": 1.0, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_failure.json b/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_failure.json index 2f7394d7f4b..bd6866e9832 100644 --- a/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_failure.json +++ b/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_failure.json @@ -119,11 +119,9 @@ "type": "queue", "meta": { "_dd.code_origin.frames.1.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.1.line": "25", "_dd.code_origin.frames.1.method": "fail", "_dd.code_origin.frames.1.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.5.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination": "async", @@ -135,6 +133,8 @@ "messaging.system": "symfony" }, "metrics": { + "_dd.code_origin.frames.1.line": 25, + "_dd.code_origin.frames.5.line": 20, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -151,16 +151,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.2.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.2.line": "25", "_dd.code_origin.frames.2.method": "fail", "_dd.code_origin.frames.2.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.6.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.2.line": 25, + "_dd.code_origin.frames.6.line": 20 } }, { @@ -173,16 +175,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.3.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.3.line": "25", "_dd.code_origin.frames.3.method": "fail", "_dd.code_origin.frames.3.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.7.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.3.line": 25, + "_dd.code_origin.frames.7.line": 20 } }, { @@ -195,17 +199,19 @@ "type": "queue", "meta": { "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.4.line": "25", "_dd.code_origin.frames.4.method": "fail", "_dd.code_origin.frames.4.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.8.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.4.line": 25, + "_dd.code_origin.frames.8.line": 20 } }, { @@ -218,17 +224,19 @@ "type": "queue", "meta": { "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.5.line": "25", "_dd.code_origin.frames.5.method": "fail", "_dd.code_origin.frames.5.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.9.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.5.line": 25, + "_dd.code_origin.frames.9.line": 20 } }, { @@ -241,9 +249,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.10.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.10.line": "20", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.6.line": "25", "_dd.code_origin.frames.6.method": "fail", "_dd.code_origin.frames.6.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -252,6 +258,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.10.line": 20, + "_dd.code_origin.frames.6.line": 25 } }, { @@ -264,9 +274,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.11.line": "20", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.7.line": "25", "_dd.code_origin.frames.7.method": "fail", "_dd.code_origin.frames.7.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -275,6 +283,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.11.line": 20, + "_dd.code_origin.frames.7.line": 25 } }, { @@ -299,9 +311,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.12.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.12.line": "20", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.8.line": "25", "_dd.code_origin.frames.8.method": "fail", "_dd.code_origin.frames.8.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "entry", @@ -317,6 +327,8 @@ "span.kind": "producer" }, "metrics": { + "_dd.code_origin.frames.12.line": 20, + "_dd.code_origin.frames.8.line": 25, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -334,11 +346,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.20.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.20.line": "25", "_dd.code_origin.frames.20.method": "fail", "_dd.code_origin.frames.20.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.24.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.24.line": "20", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -348,8 +358,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.20.line": 25, + "_dd.code_origin.frames.24.line": 20, + "out.port": 3306 } }, { @@ -363,11 +377,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "25", "_dd.code_origin.frames.18.method": "fail", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.22.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.22.line": "20", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -377,8 +389,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.18.line": 25, + "_dd.code_origin.frames.22.line": 20, + "out.port": 3306 } }, { @@ -392,11 +408,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "25", "_dd.code_origin.frames.18.method": "fail", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.22.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.22.line": "20", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -406,11 +420,13 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "_dd.code_origin.frames.18.line": 25, + "_dd.code_origin.frames.22.line": 20, + "db.row_count": 1.0, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_failure_consumer.json b/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_failure_consumer.json index 7de32e3f8f0..47638900568 100644 --- a/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_failure_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_failure_consumer.json @@ -10,7 +10,6 @@ "error": 1, "meta": { "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Version_6_2/bin/console", - "_dd.code_origin.frames.9.line": "43", "_dd.code_origin.type": "exit", "_dd.p.dm": "0", "_dd.p.tid": "686e4ae600000000", @@ -29,6 +28,7 @@ "span.kind": "consumer" }, "metrics": { + "_dd.code_origin.frames.9.line": 43, "_sampling_priority_v1": 1 } }, @@ -279,9 +279,8 @@ "type": "sql", "meta": { "_dd.base_service": "symfony_messenger_test", - "_dd.code_origin.frames.21.file": "{path}/tests/Frameworks/Symfony/Version_6_2/bin/console", - "_dd.code_origin.frames.21.line": "43", - "_dd.code_origin.type": "exit", + "_dd.code_origin.frames.21.file": "{path}/tests/Frameworks/Symfony/Version_6_2/bin/console", + "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", "db.engine": "mysql", @@ -290,8 +289,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.21.line": 43, + "out.port": 3306 } }, { @@ -304,9 +306,8 @@ "type": "sql", "meta": { "_dd.base_service": "symfony_messenger_test", - "_dd.code_origin.frames.21.file": "{path}/tests/Frameworks/Symfony/Version_6_2/bin/console", - "_dd.code_origin.frames.21.line": "43", - "_dd.code_origin.type": "exit", + "_dd.code_origin.frames.21.file": "{path}/tests/Frameworks/Symfony/Version_6_2/bin/console", + "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", "db.engine": "mysql", @@ -315,10 +316,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1 + "_dd.code_origin.frames.21.line": 43, + "db.row_count": 1, + "out.port": 3306 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_success.json b/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_success.json index 1ae71e1e127..af8f6f34006 100644 --- a/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_success.json +++ b/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_success.json @@ -119,11 +119,9 @@ "type": "queue", "meta": { "_dd.code_origin.frames.1.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.1.line": "17", "_dd.code_origin.frames.1.method": "number", "_dd.code_origin.frames.1.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.5.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination": "async", @@ -135,6 +133,8 @@ "messaging.system": "symfony" }, "metrics": { + "_dd.code_origin.frames.1.line": 17, + "_dd.code_origin.frames.5.line": 20, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -151,16 +151,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.2.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.2.line": "17", "_dd.code_origin.frames.2.method": "number", "_dd.code_origin.frames.2.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.6.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.2.line": 17, + "_dd.code_origin.frames.6.line": 20 } }, { @@ -173,16 +175,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.3.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.3.line": "17", "_dd.code_origin.frames.3.method": "number", "_dd.code_origin.frames.3.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.7.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.3.line": 17, + "_dd.code_origin.frames.7.line": 20 } }, { @@ -195,17 +199,19 @@ "type": "queue", "meta": { "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.4.line": "17", "_dd.code_origin.frames.4.method": "number", "_dd.code_origin.frames.4.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.8.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.4.line": 17, + "_dd.code_origin.frames.8.line": 20 } }, { @@ -218,17 +224,19 @@ "type": "queue", "meta": { "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.5.line": "17", "_dd.code_origin.frames.5.method": "number", "_dd.code_origin.frames.5.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.9.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.5.line": 17, + "_dd.code_origin.frames.9.line": 20 } }, { @@ -241,9 +249,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.10.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.10.line": "20", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.6.line": "17", "_dd.code_origin.frames.6.method": "number", "_dd.code_origin.frames.6.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -252,6 +258,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.10.line": 20, + "_dd.code_origin.frames.6.line": 17 } }, { @@ -264,9 +274,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.11.line": "20", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.7.line": "17", "_dd.code_origin.frames.7.method": "number", "_dd.code_origin.frames.7.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -275,6 +283,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.11.line": 20, + "_dd.code_origin.frames.7.line": 17 } }, { @@ -299,9 +311,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.12.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.12.line": "20", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.8.line": "17", "_dd.code_origin.frames.8.method": "number", "_dd.code_origin.frames.8.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "entry", @@ -317,6 +327,8 @@ "span.kind": "producer" }, "metrics": { + "_dd.code_origin.frames.12.line": 20, + "_dd.code_origin.frames.8.line": 17, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -334,11 +346,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.20.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.20.line": "17", "_dd.code_origin.frames.20.method": "number", "_dd.code_origin.frames.20.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.24.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.24.line": "20", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -348,8 +358,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.20.line": 17, + "_dd.code_origin.frames.24.line": 20, + "out.port": 3306 } }, { @@ -363,11 +377,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "17", "_dd.code_origin.frames.18.method": "number", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.22.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.22.line": "20", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -377,8 +389,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.18.line": 17, + "_dd.code_origin.frames.22.line": 20, + "out.port": 3306 } }, { @@ -392,11 +408,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "17", "_dd.code_origin.frames.18.method": "number", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.22.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.22.line": "20", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -406,11 +420,13 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "_dd.code_origin.frames.18.line": 17, + "_dd.code_origin.frames.22.line": 20, + "db.row_count": 1.0, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_success_consumer.json b/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_success_consumer.json index 5efd3a1a176..ea2faf8e46c 100644 --- a/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_success_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_success_consumer.json @@ -9,7 +9,6 @@ "type": "queue", "meta": { "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Version_6_2/bin/console", - "_dd.code_origin.frames.9.line": "43", "_dd.code_origin.type": "exit", "_dd.p.dm": "0", "_dd.p.tid": "686e4ae500000000", @@ -25,6 +24,7 @@ "span.kind": "consumer" }, "metrics": { + "_dd.code_origin.frames.9.line": 43, "_sampling_priority_v1": 1 } }, @@ -262,7 +262,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.21.file": "{path}/tests/Frameworks/Symfony/Version_6_2/bin/console", - "_dd.code_origin.frames.21.line": "43", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -272,8 +271,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.21.line": 43, + "out.port": 3306 } }, { @@ -287,7 +289,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.21.file": "{path}/tests/Frameworks/Symfony/Version_6_2/bin/console", - "_dd.code_origin.frames.21.line": "43", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -297,10 +298,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1 + "_dd.code_origin.frames.21.line": 43, + "db.row_count": 1, + "out.port": 3306 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_with_tracer_disabled_on_consume.json b/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_with_tracer_disabled_on_consume.json index 96256186c7a..81b4b6e4e30 100644 --- a/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_with_tracer_disabled_on_consume.json +++ b/tests/snapshots/tests.integrations.symfony.v6_2.messenger_test.test_async_with_tracer_disabled_on_consume.json @@ -119,11 +119,9 @@ "type": "queue", "meta": { "_dd.code_origin.frames.1.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.1.line": "17", "_dd.code_origin.frames.1.method": "number", "_dd.code_origin.frames.1.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.5.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination": "async", @@ -135,6 +133,8 @@ "messaging.system": "symfony" }, "metrics": { + "_dd.code_origin.frames.1.line": 17, + "_dd.code_origin.frames.5.line": 20, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -151,16 +151,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.2.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.2.line": "17", "_dd.code_origin.frames.2.method": "number", "_dd.code_origin.frames.2.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.6.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.2.line": 17, + "_dd.code_origin.frames.6.line": 20 } }, { @@ -173,16 +175,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.3.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.3.line": "17", "_dd.code_origin.frames.3.method": "number", "_dd.code_origin.frames.3.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.7.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.3.line": 17, + "_dd.code_origin.frames.7.line": 20 } }, { @@ -195,17 +199,19 @@ "type": "queue", "meta": { "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.4.line": "17", "_dd.code_origin.frames.4.method": "number", "_dd.code_origin.frames.4.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.8.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.4.line": 17, + "_dd.code_origin.frames.8.line": 20 } }, { @@ -218,17 +224,19 @@ "type": "queue", "meta": { "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.5.line": "17", "_dd.code_origin.frames.5.method": "number", "_dd.code_origin.frames.5.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.9.line": "20", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.5.line": 17, + "_dd.code_origin.frames.9.line": 20 } }, { @@ -241,9 +249,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.10.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.10.line": "20", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.6.line": "17", "_dd.code_origin.frames.6.method": "number", "_dd.code_origin.frames.6.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -252,6 +258,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.10.line": 20, + "_dd.code_origin.frames.6.line": 17 } }, { @@ -264,9 +274,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.11.line": "20", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.7.line": "17", "_dd.code_origin.frames.7.method": "number", "_dd.code_origin.frames.7.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -275,6 +283,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.11.line": 20, + "_dd.code_origin.frames.7.line": 17 } }, { @@ -299,9 +311,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.12.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.12.line": "20", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.8.line": "17", "_dd.code_origin.frames.8.method": "number", "_dd.code_origin.frames.8.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "entry", @@ -317,6 +327,8 @@ "span.kind": "producer" }, "metrics": { + "_dd.code_origin.frames.12.line": 20, + "_dd.code_origin.frames.8.line": 17, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -334,11 +346,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.20.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.20.line": "17", "_dd.code_origin.frames.20.method": "number", "_dd.code_origin.frames.20.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.24.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.24.line": "20", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -348,8 +358,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.20.line": 17, + "_dd.code_origin.frames.24.line": 20, + "out.port": 3306 } }, { @@ -363,11 +377,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "17", "_dd.code_origin.frames.18.method": "number", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.22.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.22.line": "20", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -377,8 +389,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.18.line": 17, + "_dd.code_origin.frames.22.line": 20, + "out.port": 3306 } }, { @@ -392,11 +408,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_6_2/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "17", "_dd.code_origin.frames.18.method": "number", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.22.file": "{path}/tests/Frameworks/Symfony/Version_6_2/public/index.php", - "_dd.code_origin.frames.22.line": "20", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -406,11 +420,13 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "_dd.code_origin.frames.18.line": 17, + "_dd.code_origin.frames.22.line": 20, + "db.row_count": 1.0, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_failure.json b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_failure.json index ac008361f10..7a979506f5c 100644 --- a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_failure.json +++ b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_failure.json @@ -119,11 +119,9 @@ "type": "queue", "meta": { "_dd.code_origin.frames.1.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.1.line": "25", "_dd.code_origin.frames.1.method": "fail", "_dd.code_origin.frames.1.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.7.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination": "async", @@ -135,6 +133,8 @@ "messaging.system": "symfony" }, "metrics": { + "_dd.code_origin.frames.1.line": 25, + "_dd.code_origin.frames.7.line": 5, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -151,16 +151,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.2.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.2.line": "25", "_dd.code_origin.frames.2.method": "fail", "_dd.code_origin.frames.2.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.8.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.2.line": 25, + "_dd.code_origin.frames.8.line": 5 } }, { @@ -173,16 +175,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.3.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.3.line": "25", "_dd.code_origin.frames.3.method": "fail", "_dd.code_origin.frames.3.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.9.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.3.line": 25, + "_dd.code_origin.frames.9.line": 5 } }, { @@ -195,9 +199,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.10.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.10.line": "5", "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.4.line": "25", "_dd.code_origin.frames.4.method": "fail", "_dd.code_origin.frames.4.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -206,6 +208,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.10.line": 5, + "_dd.code_origin.frames.4.line": 25 } }, { @@ -218,9 +224,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.11.line": "5", "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.5.line": "25", "_dd.code_origin.frames.5.method": "fail", "_dd.code_origin.frames.5.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -229,6 +233,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.11.line": 5, + "_dd.code_origin.frames.5.line": 25 } }, { @@ -241,9 +249,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.12.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.12.line": "5", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.6.line": "25", "_dd.code_origin.frames.6.method": "fail", "_dd.code_origin.frames.6.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -252,6 +258,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.12.line": 5, + "_dd.code_origin.frames.6.line": 25 } }, { @@ -264,9 +274,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.13.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.13.line": "5", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.7.line": "25", "_dd.code_origin.frames.7.method": "fail", "_dd.code_origin.frames.7.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -275,6 +283,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.13.line": 5, + "_dd.code_origin.frames.7.line": 25 } }, { @@ -299,9 +311,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.14.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.14.line": "5", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.8.line": "25", "_dd.code_origin.frames.8.method": "fail", "_dd.code_origin.frames.8.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "entry", @@ -317,6 +327,8 @@ "span.kind": "producer" }, "metrics": { + "_dd.code_origin.frames.14.line": 5, + "_dd.code_origin.frames.8.line": 25, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -334,11 +346,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.22.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.22.line": "25", "_dd.code_origin.frames.22.method": "fail", "_dd.code_origin.frames.22.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.28.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.28.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -348,8 +358,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.22.line": 25, + "_dd.code_origin.frames.28.line": 5, + "out.port": 3306 } }, { @@ -363,11 +377,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "25", "_dd.code_origin.frames.18.method": "fail", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.24.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.24.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -377,8 +389,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.18.line": 25, + "_dd.code_origin.frames.24.line": 5, + "out.port": 3306 } }, { @@ -392,11 +408,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "25", "_dd.code_origin.frames.18.method": "fail", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.24.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.24.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -406,11 +420,13 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "_dd.code_origin.frames.18.line": 25, + "_dd.code_origin.frames.24.line": 5, + "db.row_count": 1.0, + "out.port": 3306 } }, { @@ -424,11 +440,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "25", "_dd.code_origin.frames.19.method": "fail", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -438,8 +452,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.19.line": 25, + "_dd.code_origin.frames.25.line": 5, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_failure_consumer.json b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_failure_consumer.json index 20cacbd4950..83060a221aa 100644 --- a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_failure_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_failure_consumer.json @@ -10,7 +10,6 @@ "error": 1, "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.11.line": "11", "_dd.code_origin.type": "exit", "_dd.p.dm": "0", "_dd.p.tid": "68bedce700000000", @@ -29,6 +28,7 @@ "span.kind": "consumer" }, "metrics": { + "_dd.code_origin.frames.11.line": 11, "_sampling_priority_v1": 1 } }, @@ -317,7 +317,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.28.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.28.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -327,8 +326,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.28.line": 11, + "out.port": 3306 } }, { @@ -342,7 +344,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.28.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.28.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -352,11 +353,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1 + "_dd.code_origin.frames.28.line": 11, + "db.row_count": 1, + "out.port": 3306 } }, { @@ -370,7 +372,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.29.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.29.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -380,8 +381,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.29.line": 11, + "out.port": 3306 } }, { @@ -395,7 +399,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.25.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -405,8 +408,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.25.line": 11, + "out.port": 3306 } }, { @@ -420,7 +426,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.25.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -430,10 +435,11 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1 + "_dd.code_origin.frames.25.line": 11, + "db.row_count": 1, + "out.port": 3306 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success.json b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success.json index b4ea6c64938..6bf0b58e6ec 100644 --- a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success.json +++ b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success.json @@ -119,11 +119,9 @@ "type": "queue", "meta": { "_dd.code_origin.frames.1.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.1.line": "17", "_dd.code_origin.frames.1.method": "number", "_dd.code_origin.frames.1.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.7.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination": "async", @@ -135,6 +133,8 @@ "messaging.system": "symfony" }, "metrics": { + "_dd.code_origin.frames.1.line": 17, + "_dd.code_origin.frames.7.line": 5, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -151,16 +151,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.2.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.2.line": "17", "_dd.code_origin.frames.2.method": "number", "_dd.code_origin.frames.2.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.8.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.2.line": 17, + "_dd.code_origin.frames.8.line": 5 } }, { @@ -173,16 +175,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.3.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.3.line": "17", "_dd.code_origin.frames.3.method": "number", "_dd.code_origin.frames.3.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.9.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.3.line": 17, + "_dd.code_origin.frames.9.line": 5 } }, { @@ -195,9 +199,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.10.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.10.line": "5", "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.4.line": "17", "_dd.code_origin.frames.4.method": "number", "_dd.code_origin.frames.4.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -206,6 +208,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.10.line": 5, + "_dd.code_origin.frames.4.line": 17 } }, { @@ -218,9 +224,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.11.line": "5", "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.5.line": "17", "_dd.code_origin.frames.5.method": "number", "_dd.code_origin.frames.5.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -229,6 +233,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.11.line": 5, + "_dd.code_origin.frames.5.line": 17 } }, { @@ -241,9 +249,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.12.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.12.line": "5", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.6.line": "17", "_dd.code_origin.frames.6.method": "number", "_dd.code_origin.frames.6.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -252,6 +258,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.12.line": 5, + "_dd.code_origin.frames.6.line": 17 } }, { @@ -264,9 +274,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.13.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.13.line": "5", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.7.line": "17", "_dd.code_origin.frames.7.method": "number", "_dd.code_origin.frames.7.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -275,6 +283,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.13.line": 5, + "_dd.code_origin.frames.7.line": 17 } }, { @@ -299,9 +311,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.14.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.14.line": "5", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.8.line": "17", "_dd.code_origin.frames.8.method": "number", "_dd.code_origin.frames.8.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "entry", @@ -317,6 +327,8 @@ "span.kind": "producer" }, "metrics": { + "_dd.code_origin.frames.14.line": 5, + "_dd.code_origin.frames.8.line": 17, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -334,11 +346,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.22.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.22.line": "17", "_dd.code_origin.frames.22.method": "number", "_dd.code_origin.frames.22.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.28.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.28.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -348,8 +358,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.22.line": 17, + "_dd.code_origin.frames.28.line": 5, + "out.port": 3306 } }, { @@ -363,11 +377,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "17", "_dd.code_origin.frames.18.method": "number", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.24.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.24.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -377,8 +389,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.18.line": 17, + "_dd.code_origin.frames.24.line": 5, + "out.port": 3306 } }, { @@ -392,11 +408,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "17", "_dd.code_origin.frames.18.method": "number", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.24.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.24.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -406,11 +420,13 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "_dd.code_origin.frames.18.line": 17, + "_dd.code_origin.frames.24.line": 5, + "db.row_count": 1.0, + "out.port": 3306 } }, { @@ -424,11 +440,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "17", "_dd.code_origin.frames.19.method": "number", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -438,8 +452,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.19.line": 17, + "_dd.code_origin.frames.25.line": 5, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success_consumer.json b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success_consumer.json index 48dd4481412..ad0d829b3c8 100644 --- a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success_consumer.json +++ b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_success_consumer.json @@ -9,7 +9,6 @@ "type": "queue", "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.11.line": "11", "_dd.code_origin.type": "exit", "_dd.p.dm": "0", "_dd.p.tid": "68bedce500000000", @@ -25,6 +24,7 @@ "span.kind": "consumer" }, "metrics": { + "_dd.code_origin.frames.11.line": 11, "_dd.top_level": 1, "_sampling_priority_v1": 1 } @@ -264,7 +264,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.25.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -274,11 +273,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "_dd.top_level": 1 + "_dd.code_origin.frames.25.line": 11, + "_dd.top_level": 1, + "out.port": 3306 } }, { @@ -292,7 +292,6 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Version_7_3/bin/console", - "_dd.code_origin.frames.25.line": "11", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -302,11 +301,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { + "_dd.code_origin.frames.25.line": 11, "_dd.top_level": 1, - "db.row_count": 1 + "db.row_count": 1, + "out.port": 3306 } }]] diff --git a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_with_tracer_disabled_on_consume.json b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_with_tracer_disabled_on_consume.json index 0327d98741e..9df47a0e4da 100644 --- a/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_with_tracer_disabled_on_consume.json +++ b/tests/snapshots/tests.integrations.symfony.v7_3.messenger_test.test_async_with_tracer_disabled_on_consume.json @@ -119,11 +119,9 @@ "type": "queue", "meta": { "_dd.code_origin.frames.1.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.1.line": "17", "_dd.code_origin.frames.1.method": "number", "_dd.code_origin.frames.1.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.7.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination": "async", @@ -135,6 +133,8 @@ "messaging.system": "symfony" }, "metrics": { + "_dd.code_origin.frames.1.line": 17, + "_dd.code_origin.frames.7.line": 5, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -151,16 +151,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.2.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.2.line": "17", "_dd.code_origin.frames.2.method": "number", "_dd.code_origin.frames.2.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.8.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.2.line": 17, + "_dd.code_origin.frames.8.line": 5 } }, { @@ -173,16 +175,18 @@ "type": "queue", "meta": { "_dd.code_origin.frames.3.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.3.line": "17", "_dd.code_origin.frames.3.method": "number", "_dd.code_origin.frames.3.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.9.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.9.line": "5", "_dd.code_origin.type": "exit", "component": "symfonymessenger", "messaging.destination_kind": "queue", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.3.line": 17, + "_dd.code_origin.frames.9.line": 5 } }, { @@ -195,9 +199,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.10.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.10.line": "5", "_dd.code_origin.frames.4.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.4.line": "17", "_dd.code_origin.frames.4.method": "number", "_dd.code_origin.frames.4.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -206,6 +208,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.10.line": 5, + "_dd.code_origin.frames.4.line": 17 } }, { @@ -218,9 +224,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.11.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.11.line": "5", "_dd.code_origin.frames.5.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.5.line": "17", "_dd.code_origin.frames.5.method": "number", "_dd.code_origin.frames.5.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -229,6 +233,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.11.line": 5, + "_dd.code_origin.frames.5.line": 17 } }, { @@ -241,9 +249,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.12.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.12.line": "5", "_dd.code_origin.frames.6.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.6.line": "17", "_dd.code_origin.frames.6.method": "number", "_dd.code_origin.frames.6.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -252,6 +258,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.12.line": 5, + "_dd.code_origin.frames.6.line": 17 } }, { @@ -264,9 +274,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.13.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.13.line": "5", "_dd.code_origin.frames.7.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.7.line": "17", "_dd.code_origin.frames.7.method": "number", "_dd.code_origin.frames.7.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "exit", @@ -275,6 +283,10 @@ "messaging.symfony.bus": "messenger.bus.default", "messaging.symfony.message": "App\\Message\\LuckyNumberNotification", "messaging.system": "symfony" + }, + "metrics": { + "_dd.code_origin.frames.13.line": 5, + "_dd.code_origin.frames.7.line": 17 } }, { @@ -299,9 +311,7 @@ "type": "queue", "meta": { "_dd.code_origin.frames.14.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.14.line": "5", "_dd.code_origin.frames.8.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.8.line": "17", "_dd.code_origin.frames.8.method": "number", "_dd.code_origin.frames.8.type": "App\\Controller\\LuckyController", "_dd.code_origin.type": "entry", @@ -317,6 +327,8 @@ "span.kind": "producer" }, "metrics": { + "_dd.code_origin.frames.14.line": 5, + "_dd.code_origin.frames.8.line": 17, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SentStamp": 1.0, "messaging.symfony.stamps.Symfony\\Component\\Messenger\\Stamp\\SerializerStamp": 2.0, @@ -334,11 +346,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.22.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.22.line": "17", "_dd.code_origin.frames.22.method": "number", "_dd.code_origin.frames.22.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.28.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.28.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -348,8 +358,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.22.line": 17, + "_dd.code_origin.frames.28.line": 5, + "out.port": 3306 } }, { @@ -363,11 +377,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "17", "_dd.code_origin.frames.18.method": "number", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.24.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.24.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -377,8 +389,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.18.line": 17, + "_dd.code_origin.frames.24.line": 5, + "out.port": 3306 } }, { @@ -392,11 +408,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.18.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.18.line": "17", "_dd.code_origin.frames.18.method": "number", "_dd.code_origin.frames.18.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.24.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.24.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -406,11 +420,13 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" }, "metrics": { - "db.row_count": 1.0 + "_dd.code_origin.frames.18.line": 17, + "_dd.code_origin.frames.24.line": 5, + "db.row_count": 1.0, + "out.port": 3306 } }, { @@ -424,11 +440,9 @@ "meta": { "_dd.base_service": "symfony_messenger_test", "_dd.code_origin.frames.19.file": "{path}/tests/Frameworks/Symfony/Version_7_3/src/Controller/LuckyController.php", - "_dd.code_origin.frames.19.line": "17", "_dd.code_origin.frames.19.method": "number", "_dd.code_origin.frames.19.type": "App\\Controller\\LuckyController", "_dd.code_origin.frames.25.file": "{path}/tests/Frameworks/Symfony/Version_7_3/public/index.php", - "_dd.code_origin.frames.25.line": "5", "_dd.code_origin.type": "exit", "component": "pdo", "db.charset": "utf8mb4", @@ -438,8 +452,12 @@ "db.type": "mysql", "db.user": "test", "out.host": "mysql-integration", - "out.port": "3306", "span.kind": "client" + }, + "metrics": { + "_dd.code_origin.frames.19.line": 17, + "_dd.code_origin.frames.25.line": 5, + "out.port": 3306 } }, { diff --git a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_view.json index 10973e8ec51..5a00a20ed7f 100644 --- a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_callbacks_test.test_scenario_get_with_view.json @@ -1096,8 +1096,10 @@ "parent_id": 42, "type": "web", "meta": { - "component": "wordpress", - "wordpress.post.id": "2" + "component": "wordpress" + }, + "metrics": { + "wordpress.post.id": 2 } }, { diff --git a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_view.json index 2e742dc1a32..177ca1c7783 100644 --- a/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v4_8.common_scenarios_test.test_scenario_get_with_view.json @@ -480,8 +480,10 @@ "parent_id": 32, "type": "web", "meta": { - "component": "wordpress", - "wordpress.post.id": "2" + "component": "wordpress" + }, + "metrics": { + "wordpress.post.id": 2 } }, { diff --git a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_view.json index e88095a347d..90207a3c714 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_callbacks_test.test_scenario_get_with_view.json @@ -1377,8 +1377,10 @@ "parent_id": 63, "type": "web", "meta": { - "component": "wordpress", - "wordpress.post.id": "5" + "component": "wordpress" + }, + "metrics": { + "wordpress.post.id": 5 } }, { diff --git a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_view.json index f306df4b012..d5d249a48bc 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v5_5.common_scenarios_test.test_scenario_get_with_view.json @@ -481,8 +481,10 @@ "parent_id": 33, "type": "web", "meta": { - "component": "wordpress", - "wordpress.post.id": "5" + "component": "wordpress" + }, + "metrics": { + "wordpress.post.id": 5 } }, { diff --git a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_view.json index 4cebcc1c975..3ee2a1d5c1c 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_callbacks_test.test_scenario_get_with_view.json @@ -1937,8 +1937,10 @@ "parent_id": 102, "type": "web", "meta": { - "component": "wordpress", - "wordpress.post.id": "5" + "component": "wordpress" + }, + "metrics": { + "wordpress.post.id": 5 } }, { diff --git a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_view.json b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_view.json index 646e2faeb8d..b73bf53f1f4 100644 --- a/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_view.json +++ b/tests/snapshots/tests.integrations.word_press.v5_9.common_scenarios_test.test_scenario_get_with_view.json @@ -481,8 +481,10 @@ "parent_id": 33, "type": "web", "meta": { - "component": "wordpress", - "wordpress.post.id": "5" + "component": "wordpress" + }, + "metrics": { + "wordpress.post.id": 5 } }, { diff --git a/tests/xdebug/2.9.5/autoload_php.phpt b/tests/xdebug/2.9.5/autoload_php.phpt index 3a457014385..7f5fd047b76 100644 --- a/tests/xdebug/2.9.5/autoload_php.phpt +++ b/tests/xdebug/2.9.5/autoload_php.phpt @@ -18,7 +18,7 @@ var_dump(array_sum([1, 2, 3])); array_map(function($span) { echo $span['name'] . PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); echo 'Done.' . PHP_EOL; ?> diff --git a/tests/xdebug/3.0.0/autoload_php.phpt b/tests/xdebug/3.0.0/autoload_php.phpt index 4ce79221bcf..ff3a8ac1749 100644 --- a/tests/xdebug/3.0.0/autoload_php.phpt +++ b/tests/xdebug/3.0.0/autoload_php.phpt @@ -18,7 +18,7 @@ var_dump(array_sum([1, 2, 3])); array_map(function($span) { echo $span['name'] . PHP_EOL; -}, dd_trace_serialize_closed_spans()); +}, dd_trace_serialize_closed_spans()['chunks'][0]['spans']); echo 'Done.' . PHP_EOL; ?> diff --git a/tracer/auto_flush.c b/tracer/auto_flush.c index b728892b1ed..2fbff727ab4 100644 --- a/tracer/auto_flush.c +++ b/tracer/auto_flush.c @@ -26,7 +26,7 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles bool success = true; // Serialization fills the native V1 builder directly (no v0.4 intermediate). The sidecar - // negotiates V1-vs-v0.4; the in-process (<=8.2) sender downgrades to v0.4 at flush time. + // negotiates V1-vs-v0.4; the in-process sender (DD_TRACE_SIDECAR_TRACE_SENDER=0) downgrades to v0.4 at flush time. ddtrace_serialize_ctx serialize_ctx = { .builder = ddog_v1_new_builder(), .chunk = DD_CHUNK_NONE, @@ -48,7 +48,7 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles return SUCCESS; } - // Spans are built into the builder, not the (empty) V0.4 traces, so gate on the chunk count. + // Gate on the builder's chunk count. size_t payload_count = ddog_v1_get_chunk_count(ctx->builder); if (!payload_count) { ddog_v1_free_builder(ctx->builder); @@ -95,8 +95,8 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles } } else { #ifndef _WIN32 - // Removable v0.4 bolt-on: the in-process (<=8.2) background sender's array-of-1 framing can't - // parse a native V1 payload (one msgpack MAP), so it downgrades to v0.4 traces. Delete to revert. + // In-process sender (DD_TRACE_SIDECAR_TRACE_SENDER=0): its array-of-1 framing can't + // parse a native V1 payload (one msgpack MAP), so it downgrades to v0.4 traces. // Consumes ctx->builder; returns a v0.4 collection to free below. ddog_TracesBytes *v04_traces = ddog_downgrade_v1_builder_to_v04_traces(ctx->builder); size_t trace_count = ddog_get_traces_size(v04_traces); diff --git a/tracer/code_origins.c b/tracer/code_origins.c index 0b91c93e700..01e1b3c1be4 100644 --- a/tracer/code_origins.c +++ b/tracer/code_origins.c @@ -12,7 +12,7 @@ static inline bool dd_is_dir_sep(const char c) { } void ddtrace_add_code_origin_information(ddtrace_span_data *span, int skip_frames) { - zend_array *meta = ddtrace_property_array(&span->property_attributes); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); zend_long max_frames = get_DD_CODE_ORIGIN_MAX_USER_FRAMES(); int current_frame = 0, collected_frames = 0; @@ -42,12 +42,10 @@ void ddtrace_add_code_origin_information(ddtrace_span_data *span, int skip_frame } if (collected_frames == 0) { - zval type, *kind = ddtrace_span_find_tag(span, ZEND_STRL("span.kind")); - if (kind) { - ZVAL_DEREF(kind); - } - ZVAL_STRING(&type, (kind && Z_TYPE_P(kind) == IS_STRING ? zend_string_equals_literal(Z_STR_P(kind), "server") || zend_string_equals_literal(Z_STR_P(kind), "producer") : &span->root->span == span) ? "entry" : "exit"); - if (!zend_hash_str_add(meta, ZEND_STRL("_dd.code_origin.type"), &type)) { + zval type; + zend_long kind = zval_get_long(&span->property_span_kind); + ZVAL_STRING(&type, (kind ? kind == DDTRACE_SPAN_KIND_SERVER || kind == DDTRACE_SPAN_KIND_PRODUCER : &span->root->span == span) ? "entry" : "exit"); + if (!zend_hash_str_add(attributes, ZEND_STRL("_dd.code_origin.type"), &type)) { zend_string_release(Z_STR(type)); return; // skip if already present } @@ -58,26 +56,25 @@ void ddtrace_add_code_origin_information(ddtrace_span_data *span, int skip_frame key = zend_strpprintf(0, "_dd.code_origin.frames.%d.file", current_frame); ZVAL_STR_COPY(&zv, EX(func)->op_array.filename); - zend_hash_update(meta, key, &zv); + zend_hash_update(attributes, key, &zv); zend_string_release(key); key = zend_strpprintf(0, "_dd.code_origin.frames.%d.line", current_frame); - // A string, as the tag was when it lived in meta. - ZVAL_STR(&zv, zend_long_to_str(current_frame == 0 ? EX(func)->op_array.line_start : EX(opline)->lineno)); - zend_hash_update(meta, key, &zv); + ZVAL_LONG(&zv, current_frame == 0 ? EX(func)->op_array.line_start : EX(opline)->lineno); + zend_hash_update(attributes, key, &zv); zend_string_release(key); if (EX(func)->op_array.function_name) { key = zend_strpprintf(0, "_dd.code_origin.frames.%d.method", current_frame); ZVAL_STR_COPY(&zv, EX(func)->op_array.function_name); - zend_hash_update(meta, key, &zv); + zend_hash_update(attributes, key, &zv); zend_string_release(key); } if (EX(func)->op_array.scope) { key = zend_strpprintf(0, "_dd.code_origin.frames.%d.type", current_frame); ZVAL_STR_COPY(&zv, EX(func)->op_array.scope->name); - zend_hash_update(meta, key, &zv); + zend_hash_update(attributes, key, &zv); zend_string_release(key); } @@ -93,14 +90,10 @@ void ddtrace_maybe_add_code_origin_information(ddtrace_span_data *span, int skip if (Z_TYPE_P(type) == IS_STRING && Z_STRLEN_P(type) != 0) { // If it's identical, we don't add it to the child so that only the parent span will be added the code origin information if (span->parent && zend_is_identical(type, &span->parent->property_type)) { - zval *kind = ddtrace_span_find_tag(span, ZEND_STRL("span.kind")); - if (kind) { - zval *parent_kind = ddtrace_span_find_tag(SPANDATA(span->parent), ZEND_STRL("span.kind")); - // span.kind must match, otherwise websocket has false positives for example, where both entry and exit span have type websocket - if (!parent_kind || zend_is_identical(kind, parent_kind)) { - return; - } - } else { + zend_long kind = zval_get_long(&span->property_span_kind); + zend_long parent_kind = zval_get_long(&span->parent->property_span_kind); + // span.kind must match, otherwise websocket has false positives for example, where both entry and exit span have type websocket + if (!kind || !parent_kind || kind == parent_kind) { return; } } diff --git a/tracer/coms.c b/tracer/coms.c index be5ff796ea6..ddfb421a225 100644 --- a/tracer/coms.c +++ b/tracer/coms.c @@ -916,7 +916,6 @@ static void ddtrace_curl_set_hostname_generic(CURL *curl, const char *path) { } void ddtrace_curl_set_hostname(CURL *curl) { - // The in-process (<=8.2) background sender is v0.4-only. ddtrace_curl_set_hostname_generic(curl, TRACE_PATH_STR); } diff --git a/tracer/configuration.h b/tracer/configuration.h index 23d5f217642..d754f717a63 100644 --- a/tracer/configuration.h +++ b/tracer/configuration.h @@ -8,9 +8,6 @@ /* This should be at least an order of magnitude higher than the userland HTTP Transport default. */ #define DD_TRACE_BGS_TIMEOUT_VAL 5000 -#define DD_INTEGRATION_ANALYTICS_ENABLED_DEFAULT false -#define DD_INTEGRATION_ANALYTICS_SAMPLE_RATE_DEFAULT 1.0 - // Sidecar is the default trace sender on all PHP versions (in-process coms.c sender is the // DD_TRACE_SIDECAR_TRACE_SENDER=0 opt-in). Thread mode isn't pcntl_fork()-safe; auto falls back. #define DD_SIDECAR_TRACE_SENDER_DEFAULT true @@ -34,12 +31,7 @@ #else #define INTEGRATION_CONFIG_ACTIVE(id, ...) GET_INTEGRATION_CONFIG_MACRO(__VA_ARGS__, INTEGRATION_ALIAS, INTEGRATION_ALIAS, INTEGRATION_WITH_DEFAULT, INTEGRATION_NORMAL)(DD_TRACE_##id##_ENABLED, __VA_ARGS__) #endif -#define INTEGRATION(id, ...) \ - INTEGRATION_CONFIG_ACTIVE(id, __VA_ARGS__) \ - CALIAS(BOOL, DD_TRACE_##id##_ANALYTICS_ENABLED, DD_CFG_EXPSTR(DD_INTEGRATION_ANALYTICS_ENABLED_DEFAULT), \ - CALIASES(DD_CFG_STR(DD_##id##_ANALYTICS_ENABLED), DD_CFG_STR(DD_TRACE_##id##_ANALYTICS_ENABLED))) \ - CALIAS(DOUBLE, DD_TRACE_##id##_ANALYTICS_SAMPLE_RATE, DD_CFG_EXPSTR(DD_INTEGRATION_ANALYTICS_SAMPLE_RATE_DEFAULT), \ - CALIASES(DD_CFG_STR(DD_##id##_ANALYTICS_SAMPLE_RATE), DD_CFG_STR(DD_TRACE_##id##_ANALYTICS_SAMPLE_RATE))) +#define INTEGRATION(id, ...) INTEGRATION_CONFIG_ACTIVE(id, __VA_ARGS__) #define DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP_DEFAULT \ "(?i)(?:(?:\"|%22)?)(?:(?:old[-_]?|new[-_]?)?p(?:ass)?w(?:or)?d(?:1|2)?|pass(?:[-_]?phrase)?|secret|(?:api[-_]?|private[-_]?|public[-_]?|access[-_]?|secret[-_]?|app(?:lication)?[-_]?)key(?:[-_]?id)?|token|consumer[-_]?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:(?:\\s|%20)*(?:=|%3D)[^&]+|(?:\"|%22)(?:\\s|%20)*(?::|%3A)(?:\\s|%20)*(?:\"|%22)(?:%2[^2]|%[^2]|[^\"%])+(?:\"|%22))|(?:bearer(?:\\s|%20)+[a-z0-9._\\-]+|token(?::|%3A)[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|(^|[^\\w%-]|%[0-9a-f]{2})ey[I-L][\\w-]+(?:=|%3D)*\\.ey[I-L][\\w-]+(?:=|%3D)*(?:\\.(?:[\\w.+/=-]|%3D|%2F|%2B)+)?|-{5}BEGIN(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY-{5}[^\\-]+-{5}END(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY(?:-{5})?(?:\\n|%0A)?|(?:ssh-(?:rsa|dss)|ecdsa-[a-z0-9]+-[a-z0-9]+)(?:\\s|%20|%09)+(?:[a-z0-9/.+]|%2F|%5C|%2B){100,}(?:=|%3D)*(?:(?:\\s|%20|%09)+[a-z0-9._-]+)?)" @@ -51,7 +43,6 @@ CONFIG(BOOL, DD_AUTOFINISH_SPANS, "false") \ CONFIG(BOOL, DD_TRACE_URL_AS_RESOURCE_NAMES_ENABLED, "true") \ CONFIG(BOOL, DD_HTTP_SERVER_ROUTE_BASED_NAMING, "true") \ - CONFIG(BOOL, DD_TRACE_ANALYTICS_ENABLED, "false") \ CONFIG(BOOL, DD_TRACE_APPEND_TRACE_IDS_TO_LOGS, "false") \ CONFIG(BOOL, DD_TRACE_AUTO_FLUSH_ENABLED, "false") /* true in CLI */ \ CONFIG(BOOL, DD_TRACE_MEASURE_COMPILE_TIME, "true") \ diff --git a/tracer/ddtrace.c b/tracer/ddtrace.c index dd53280969c..bb902af2701 100644 --- a/tracer/ddtrace.c +++ b/tracer/ddtrace.c @@ -313,11 +313,6 @@ void ddtrace_pre_config_minit() { datadog_config_entries[DATADOG_CONFIG_DD_TRACE_FORCE_FLUSH_ON_SIGTERM].default_encoded_value = (zai_str) ZAI_STR_FROM_CSTR("true"); datadog_config_entries[DATADOG_CONFIG_DD_TRACE_FORCE_FLUSH_ON_SIGINT].default_encoded_value = (zai_str) ZAI_STR_FROM_CSTR("true"); } - - // Background sender does not send a Content-Length header, but sidecar does. Force-enable it thus, as the background sender does not work at all. - if (getenv("AWS_LAMBDA_FUNCTION_NAME")) { - datadog_config_entries[DATADOG_CONFIG_DD_TRACE_SIDECAR_TRACE_SENDER].default_encoded_value = (zai_str) ZAI_STR_FROM_CSTR("true"); - } #endif // Make sure it's available for appsec, before any early returns diff --git a/tracer/ddtrace.stub.php b/tracer/ddtrace.stub.php index f644767f286..a1e0219cd88 100644 --- a/tracer/ddtrace.stub.php +++ b/tracer/ddtrace.stub.php @@ -90,7 +90,7 @@ public function __construct(string $name, array $attributes = [], ?int $timestam public string $name; /** - * @var string[] $attributes + * @var array $attributes Event attributes, keeping their type: bool, int, float, string, or nested arrays. */ public array $attributes; @@ -134,7 +134,7 @@ class SpanLink { public string $traceState; /** - * @var string[] $attributes + * @var array $attributes Link attributes, keeping their type: bool, int, float, string, or nested arrays. */ public array $attributes; @@ -165,18 +165,36 @@ 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; + /** + * @var int + * @cvalue DDTRACE_SPAN_KIND_UNSPECIFIED + */ + const UNSPECIFIED = UNKNOWN; + /** + * @var int + * @cvalue DDTRACE_SPAN_KIND_INTERNAL + */ + const INTERNAL = UNKNOWN; + /** + * @var int + * @cvalue DDTRACE_SPAN_KIND_SERVER + */ + const SERVER = UNKNOWN; + /** + * @var int + * @cvalue DDTRACE_SPAN_KIND_CLIENT + */ + const CLIENT = UNKNOWN; + /** + * @var int + * @cvalue DDTRACE_SPAN_KIND_PRODUCER + */ + const PRODUCER = UNKNOWN; + /** + * @var int + * @cvalue DDTRACE_SPAN_KIND_CONSUMER + */ + const CONSUMER = UNKNOWN; } class SpanData { @@ -211,6 +229,8 @@ class SpanData { /** * @var string[] $meta A view onto the non-numeric entries of $attributes; values are stored as strings. + * Writing service.name, resource.name, operation.name, span.type, env, version, component, span.kind or + * error.ignored sets the matching property instead, and reading them returns that property. * @deprecated Use $attributes. Setting meta['error.ignored'] is deprecated too: use $ignoreError. */ public $meta = []; @@ -305,8 +325,14 @@ public function hexId(): string {} */ public string $version = ""; + /** + * @var string The integration that created the span + */ public string $component = ""; + /** + * @var int The span kind, a \DDTrace\SpanKind constant + */ public int $spanKind = 0; /** @@ -340,8 +366,6 @@ 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. */ @@ -379,8 +403,6 @@ class RootSpanData extends SpanData { public GitMetadata|null $gitMetadata = null; public InferredSpanData|null $inferredSpan = null; - - public string $hostname = ""; } /** @@ -414,8 +436,6 @@ class SpanStack { * removal. */ public array $spanCreationObservers = []; - - public array $attributes = []; } interface Integration { @@ -567,7 +587,7 @@ function hook_method( // phpcs:enable Generic.Files.LineLength.TooLong /** - * Add a tag to be automatically applied to every spanStack that is created, if tracing is enabled. + * Add a tag to be automatically applied to every span that is created, if tracing is enabled. * * @param string $key Tag key * @param string $value Tag Value @@ -784,7 +804,7 @@ function startup_logs(): string {} /** * Return the id of the current trace * - * @deprecated This function is deprecated and should not be used. + * @deprecated Use \DDTrace\root_span()->traceId (hexadecimal) or \DDTrace\logs_correlation_trace_id() instead. * @return string The id of the current trace */ function trace_id(): string {} @@ -804,7 +824,7 @@ function logs_correlation_trace_id(): string {} /** * Get information on the current context * - * @deprecated This function is deprecated and should not be used. + * @deprecated Use the \DDTrace\root_span() properties or \DDTrace\generate_distributed_tracing_headers() instead. * @return array{trace_id: string, span_id: string, version: string, env: string} */ function current_context(): array {} @@ -815,7 +835,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 hex unsigned) ID of the trace containing this span + * @param string $traceId The unique integer (128-bit 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 @@ -1056,6 +1076,15 @@ function emit_asm_event(): void {} * @return string The normalized tag value */ function normalize_tag_value(string $value): string {} + + /** + * Like dd_trace_serialize_closed_spans(), and also runs the in-process sender's v0.4 downgrade. + * + * @return array [the dd_trace_serialize_closed_spans() payload, list of v0.4 msgpack payloads (one per trace)] + * + * @internal Used by tests only. + */ + function serialize_closed_spans_v04(): array {} } namespace DDTrace\Internal { @@ -1210,7 +1239,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. + * @deprecated Use dd_trace_env_config('DD_SERVICE') instead. * @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. @@ -1220,7 +1249,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. + * @deprecated Use dd_trace_env_config('DD_DISTRIBUTED_TRACING') instead. * @return bool 'true' if distributed tracing is enabled, else 'false' */ function ddtrace_config_distributed_tracing_enabled(): bool {} @@ -1228,7 +1257,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. + * @deprecated Use dd_trace_env_config('DD_TRACE_ENABLED') instead. * @return bool 'true' is tracing is enabled, else 'false' */ function ddtrace_config_trace_enabled(): bool {} @@ -1246,7 +1275,7 @@ function ddtrace_config_integration_enabled(string $integrationName): bool {} * * Internal functions are: init_and_start_writer, ddtrace_coms_next_group_id, ddtrace_coms_buffer_span, * ddtrace_coms_buffer_data, shutdown_writer, set_writer_send_on_flush, test_consumer, test_writers, - * test_msgpack_consumer, synchronous_flush, and root_span_add_tag + * test_msgpack_consumer, and synchronous_flush * * @internal * @param string $functionName Internal function name @@ -1258,7 +1287,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. + * @deprecated Use \DDTrace\set_distributed_tracing_context() instead. * @param string|null $traceId New trace id * @return bool 'true' if the change was properly applied, else 'false' */ @@ -1281,7 +1310,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. + * @deprecated There is no replacement. * @return int Compile time */ function dd_trace_compile_time_microseconds(): int {} @@ -1290,7 +1319,8 @@ function dd_trace_compile_time_microseconds(): int {} * Get serialized information about closed spans as arrays. Note that calling this function will result in * automatically closing unfinished spans (destroys the open span stack). * - * @return array Closed spans data + * @return array The V1 trace payload: payload fields, and 'chunks', each with its own fields + * (trace_id, priority, origin, sampling_mechanism) and 'spans' */ function dd_trace_serialize_closed_spans(): array {} @@ -1309,13 +1339,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. + * @deprecated Use \DDTrace\trace_function() instead. * @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. + * @deprecated Use \DDTrace\trace_method() instead. * @alias DDTrace_trace_method */ function dd_trace_method( diff --git a/tracer/ddtrace_arginfo.h b/tracer/ddtrace_arginfo.h index ddfe7a6dd71..ef4c6ac4a66 100644 --- a/tracer/ddtrace_arginfo.h +++ b/tracer/ddtrace_arginfo.h @@ -1,5 +1,7 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: f24f35fb55682e040fd9c2e3e6ec535f0e365194 */ +/* This is a generated file, edit ddtrace.stub.php instead. + * Stub hash: d5f6d646e096319037aa857122a4c995d97ed471 */ + +#include "zend_constants.h" 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) @@ -231,6 +233,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_Testing_normalize_tag_va ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0) ZEND_END_ARG_INFO() +#define arginfo_DDTrace_Testing_serialize_closed_spans_v04 arginfo_DDTrace_current_context + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_Internal_add_span_flag, 0, 2, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, span, DDTrace\\SpanData, 0) ZEND_ARG_TYPE_INFO(0, flag, IS_LONG, 0) @@ -248,6 +252,19 @@ 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_DDTrace_Internal_record_ffe_flag_evaluation, 0, 9, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, flagKey, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, variant, IS_STRING, 1) + ZEND_ARG_TYPE_INFO(0, allocationKey, IS_STRING, 1) + ZEND_ARG_TYPE_INFO(0, targetingKey, IS_STRING, 1) + ZEND_ARG_TYPE_INFO(0, attributes, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, errorType, IS_STRING, 1) + ZEND_ARG_TYPE_INFO(0, runtimeDefaultUsed, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, observeFullEvaluationData, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, evaluationTimestampMs, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, targetingKeyInvalid, _IS_BOOL, 0, "false") +ZEND_END_ARG_INFO() + 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) ZEND_ARG_TYPE_MASK(0, user, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_NULL, "null") @@ -403,10 +420,12 @@ 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); +ZEND_FUNCTION(DDTrace_Testing_serialize_closed_spans_v04); ZEND_FUNCTION(DDTrace_Internal_add_span_flag); ZEND_FUNCTION(DDTrace_Internal_handle_fork); ZEND_FUNCTION(DDTrace_Internal_record_ffe_evaluation_metric); ZEND_FUNCTION(DDTrace_Internal_flush_ffe_evaluation_metrics); +ZEND_FUNCTION(DDTrace_Internal_record_ffe_flag_evaluation); ZEND_FUNCTION(datadog_appsec_v2_track_user_login_success); ZEND_FUNCTION(datadog_appsec_v2_track_user_login_failure); ZEND_FUNCTION(dd_trace_env_config); @@ -465,9 +484,9 @@ static const zend_function_entry ext_functions[] = { ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "find_active_exception"), zif_DDTrace_find_active_exception, arginfo_DDTrace_find_active_exception, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "extract_ip_from_headers"), zif_DDTrace_extract_ip_from_headers, arginfo_DDTrace_extract_ip_from_headers, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "startup_logs"), zif_DDTrace_startup_logs, arginfo_DDTrace_startup_logs, 0, NULL, NULL) - ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "trace_id"), zif_DDTrace_trace_id, arginfo_DDTrace_trace_id, 0, NULL, NULL) + ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "trace_id"), zif_DDTrace_trace_id, arginfo_DDTrace_trace_id, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "logs_correlation_trace_id"), zif_DDTrace_logs_correlation_trace_id, arginfo_DDTrace_logs_correlation_trace_id, 0, NULL, NULL) - ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "current_context"), zif_DDTrace_current_context, arginfo_DDTrace_current_context, 0, NULL, NULL) + ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "current_context"), zif_DDTrace_current_context, arginfo_DDTrace_current_context, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "set_distributed_tracing_context"), zif_DDTrace_set_distributed_tracing_context, arginfo_DDTrace_set_distributed_tracing_context, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "flush"), zif_DDTrace_flush, arginfo_DDTrace_flush, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "curl_multi_exec_get_request_spans"), zif_DDTrace_curl_multi_exec_get_request_spans, arginfo_DDTrace_curl_multi_exec_get_request_spans, 0, NULL, NULL) @@ -495,30 +514,32 @@ static const zend_function_entry ext_functions[] = { ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Testing", "trigger_error"), zif_DDTrace_Testing_trigger_error, arginfo_DDTrace_Testing_trigger_error, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Testing", "emit_asm_event"), zif_DDTrace_Testing_emit_asm_event, arginfo_DDTrace_Testing_emit_asm_event, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Testing", "normalize_tag_value"), zif_DDTrace_Testing_normalize_tag_value, arginfo_DDTrace_Testing_normalize_tag_value, 0, NULL, NULL) + ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Testing", "serialize_closed_spans_v04"), zif_DDTrace_Testing_serialize_closed_spans_v04, arginfo_DDTrace_Testing_serialize_closed_spans_v04, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Internal", "add_span_flag"), zif_DDTrace_Internal_add_span_flag, arginfo_DDTrace_Internal_add_span_flag, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Internal", "handle_fork"), zif_DDTrace_Internal_handle_fork, arginfo_DDTrace_Internal_handle_fork, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Internal", "record_ffe_evaluation_metric"), zif_DDTrace_Internal_record_ffe_evaluation_metric, arginfo_DDTrace_Internal_record_ffe_evaluation_metric, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Internal", "flush_ffe_evaluation_metrics"), zif_DDTrace_Internal_flush_ffe_evaluation_metrics, arginfo_DDTrace_Internal_flush_ffe_evaluation_metrics, 0, NULL, NULL) + ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Internal", "record_ffe_flag_evaluation"), zif_DDTrace_Internal_record_ffe_flag_evaluation, arginfo_DDTrace_Internal_record_ffe_flag_evaluation, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("datadog\\appsec\\v2", "track_user_login_success"), zif_datadog_appsec_v2_track_user_login_success, arginfo_datadog_appsec_v2_track_user_login_success, 0, NULL, NULL) 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_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_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_RAW_FENTRY("ddtrace_config_app_name", zif_ddtrace_config_app_name, arginfo_ddtrace_config_app_name, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("ddtrace_config_distributed_tracing_enabled", zif_ddtrace_config_distributed_tracing_enabled, arginfo_ddtrace_config_distributed_tracing_enabled, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("ddtrace_config_trace_enabled", zif_ddtrace_config_trace_enabled, arginfo_ddtrace_config_trace_enabled, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(ddtrace_config_integration_enabled, arginfo_ddtrace_config_integration_enabled) ZEND_FE(dd_trace_internal_fn, arginfo_dd_trace_internal_fn) - ZEND_RAW_FENTRY("dd_trace_set_trace_id", zif_dd_trace_set_trace_id, arginfo_dd_trace_set_trace_id, 0, NULL, NULL) + ZEND_RAW_FENTRY("dd_trace_set_trace_id", zif_dd_trace_set_trace_id, arginfo_dd_trace_set_trace_id, ZEND_ACC_DEPRECATED, 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_RAW_FENTRY("dd_trace_compile_time_microseconds", zif_dd_trace_compile_time_microseconds, arginfo_dd_trace_compile_time_microseconds, 0, NULL, NULL) + ZEND_RAW_FENTRY("dd_trace_compile_time_microseconds", zif_dd_trace_compile_time_microseconds, arginfo_dd_trace_compile_time_microseconds, ZEND_ACC_DEPRECATED, 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) - ZEND_RAW_FENTRY("dd_trace_function", zif_DDTrace_trace_function, arginfo_dd_trace_function, 0, NULL, NULL) - ZEND_RAW_FENTRY("dd_trace_method", zif_DDTrace_trace_method, arginfo_dd_trace_method, 0, NULL, NULL) + ZEND_RAW_FENTRY("dd_trace_function", zif_DDTrace_trace_function, arginfo_dd_trace_function, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("dd_trace_method", zif_DDTrace_trace_method, arginfo_dd_trace_method, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(dd_untrace, arginfo_dd_untrace) ZEND_FE(dd_trace_synchronous_flush, arginfo_dd_trace_synchronous_flush) ZEND_FE_END @@ -583,39 +604,45 @@ 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, 1); + zend_string *property_valueJson_name = zend_string_init("valueJson", sizeof("valueJson") - 1, true); 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(property_valueJson_name); + zend_string_release_ex(property_valueJson_name, true); zval property_variant_default_value; ZVAL_NULL(&property_variant_default_value); - zend_string *property_variant_name = zend_string_init("variant", sizeof("variant") - 1, 1); + zend_string *property_variant_name = zend_string_init("variant", sizeof("variant") - 1, true); 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(property_variant_name); + zend_string_release_ex(property_variant_name, true); zval property_allocationKey_default_value; ZVAL_NULL(&property_allocationKey_default_value); - zend_string *property_allocationKey_name = zend_string_init("allocationKey", sizeof("allocationKey") - 1, 1); + zend_string *property_allocationKey_name = zend_string_init("allocationKey", sizeof("allocationKey") - 1, true); 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(property_allocationKey_name); + zend_string_release_ex(property_allocationKey_name, true); zval property_reason_default_value; ZVAL_LONG(&property_reason_default_value, 0); - zend_string *property_reason_name = zend_string_init("reason", sizeof("reason") - 1, 1); + zend_string *property_reason_name = zend_string_init("reason", sizeof("reason") - 1, true); 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(property_reason_name); + zend_string_release_ex(property_reason_name, true); zval property_errorCode_default_value; ZVAL_LONG(&property_errorCode_default_value, 0); - zend_string *property_errorCode_name = zend_string_init("errorCode", sizeof("errorCode") - 1, 1); + zend_string *property_errorCode_name = zend_string_init("errorCode", sizeof("errorCode") - 1, true); 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(property_errorCode_name); + zend_string_release_ex(property_errorCode_name, true); zval property_doLog_default_value; ZVAL_FALSE(&property_doLog_default_value); - zend_string *property_doLog_name = zend_string_init("doLog", sizeof("doLog") - 1, 1); + zend_string *property_doLog_name = zend_string_init("doLog", sizeof("doLog") - 1, true); 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(property_doLog_name); + zend_string_release_ex(property_doLog_name, true); + + zval property_observeFullEvaluationData_default_value; + ZVAL_FALSE(&property_observeFullEvaluationData_default_value); + zend_string *property_observeFullEvaluationData_name = zend_string_init("observeFullEvaluationData", sizeof("observeFullEvaluationData") - 1, true); + zend_declare_typed_property(class_entry, property_observeFullEvaluationData_name, &property_observeFullEvaluationData_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_string_release_ex(property_observeFullEvaluationData_name, true); zval property_serialId_default_value; ZVAL_NULL(&property_serialId_default_value); @@ -625,27 +652,27 @@ 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, 1); + zend_string *property_providerState_name = zend_string_init("providerState", sizeof("providerState") - 1, true); 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(property_providerState_name); + zend_string_release_ex(property_providerState_name, true); zval property_errorMessage_default_value; ZVAL_NULL(&property_errorMessage_default_value); - zend_string *property_errorMessage_name = zend_string_init("errorMessage", sizeof("errorMessage") - 1, 1); + zend_string *property_errorMessage_name = zend_string_init("errorMessage", sizeof("errorMessage") - 1, true); 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(property_errorMessage_name); + zend_string_release_ex(property_errorMessage_name, true); zval property_hasConfig_default_value; ZVAL_NULL(&property_hasConfig_default_value); - zend_string *property_hasConfig_name = zend_string_init("hasConfig", sizeof("hasConfig") - 1, 1); + zend_string *property_hasConfig_name = zend_string_init("hasConfig", sizeof("hasConfig") - 1, true); 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(property_hasConfig_name); + zend_string_release_ex(property_hasConfig_name, true); zval property_configVersion_default_value; ZVAL_NULL(&property_configVersion_default_value); - zend_string *property_configVersion_name = zend_string_init("configVersion", sizeof("configVersion") - 1, 1); + zend_string *property_configVersion_name = zend_string_init("configVersion", sizeof("configVersion") - 1, true); 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(property_configVersion_name); + zend_string_release_ex(property_configVersion_name, true); return class_entry; } @@ -659,21 +686,19 @@ static zend_class_entry *register_class_DDTrace_SpanEvent(void) zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); - 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); + 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)); zval property_attributes_default_value; ZVAL_UNDEF(&property_attributes_default_value); - zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); + zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, true); 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); + zend_string_release_ex(property_attributes_name, true); zval property_timestamp_default_value; ZVAL_UNDEF(&property_timestamp_default_value); - zend_string *property_timestamp_name = zend_string_init("timestamp", sizeof("timestamp") - 1, 1); + zend_string *property_timestamp_name = zend_string_init("timestamp", sizeof("timestamp") - 1, true); 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(property_timestamp_name); + zend_string_release_ex(property_timestamp_name, true); return class_entry; } @@ -687,10 +712,10 @@ 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, 1); + zend_string *property_exception_name = zend_string_init("exception", sizeof("exception") - 1, true); 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(property_exception_name); + zend_string_release_ex(property_exception_name, true); return class_entry; } @@ -704,33 +729,33 @@ static zend_class_entry *register_class_DDTrace_SpanLink(void) zval property_traceId_default_value; ZVAL_UNDEF(&property_traceId_default_value); - zend_string *property_traceId_name = zend_string_init("traceId", sizeof("traceId") - 1, 1); + zend_string *property_traceId_name = zend_string_init("traceId", sizeof("traceId") - 1, true); 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(property_traceId_name); + zend_string_release_ex(property_traceId_name, true); zval property_spanId_default_value; ZVAL_UNDEF(&property_spanId_default_value); - zend_string *property_spanId_name = zend_string_init("spanId", sizeof("spanId") - 1, 1); + zend_string *property_spanId_name = zend_string_init("spanId", sizeof("spanId") - 1, true); 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(property_spanId_name); + zend_string_release_ex(property_spanId_name, true); zval property_traceState_default_value; ZVAL_UNDEF(&property_traceState_default_value); - zend_string *property_traceState_name = zend_string_init("traceState", sizeof("traceState") - 1, 1); + zend_string *property_traceState_name = zend_string_init("traceState", sizeof("traceState") - 1, true); 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(property_traceState_name); + zend_string_release_ex(property_traceState_name, true); zval property_attributes_default_value; ZVAL_UNDEF(&property_attributes_default_value); - zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); + zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, true); 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); + zend_string_release_ex(property_attributes_name, true); zval property_droppedAttributesCount_default_value; ZVAL_UNDEF(&property_droppedAttributesCount_default_value); - zend_string *property_droppedAttributesCount_name = zend_string_init("droppedAttributesCount", sizeof("droppedAttributesCount") - 1, 1); + zend_string *property_droppedAttributesCount_name = zend_string_init("droppedAttributesCount", sizeof("droppedAttributesCount") - 1, true); 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(property_droppedAttributesCount_name); + zend_string_release_ex(property_droppedAttributesCount_name, true); return class_entry; } @@ -744,15 +769,15 @@ 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, 1); + zend_string *property_commitSha_name = zend_string_init("commitSha", sizeof("commitSha") - 1, true); 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(property_commitSha_name); + zend_string_release_ex(property_commitSha_name, true); zval property_repositoryUrl_default_value; ZVAL_EMPTY_STRING(&property_repositoryUrl_default_value); - zend_string *property_repositoryUrl_name = zend_string_init("repositoryUrl", sizeof("repositoryUrl") - 1, 1); + zend_string *property_repositoryUrl_name = zend_string_init("repositoryUrl", sizeof("repositoryUrl") - 1, true); 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(property_repositoryUrl_name); + zend_string_release_ex(property_repositoryUrl_name, true); return class_entry; } @@ -765,40 +790,40 @@ static zend_class_entry *register_class_DDTrace_SpanKind(void) 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); + ZVAL_LONG(&const_UNSPECIFIED_value, DDTRACE_SPAN_KIND_UNSPECIFIED); + zend_string *const_UNSPECIFIED_name = zend_string_init_interned("UNSPECIFIED", sizeof("UNSPECIFIED") - 1, true); zend_declare_class_constant_ex(class_entry, const_UNSPECIFIED_name, &const_UNSPECIFIED_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release(const_UNSPECIFIED_name); + zend_string_release_ex(const_UNSPECIFIED_name, true); zval const_INTERNAL_value; - ZVAL_LONG(&const_INTERNAL_value, 1); - zend_string *const_INTERNAL_name = zend_string_init_interned("INTERNAL", sizeof("INTERNAL") - 1, 1); + ZVAL_LONG(&const_INTERNAL_value, DDTRACE_SPAN_KIND_INTERNAL); + zend_string *const_INTERNAL_name = zend_string_init_interned("INTERNAL", sizeof("INTERNAL") - 1, true); zend_declare_class_constant_ex(class_entry, const_INTERNAL_name, &const_INTERNAL_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release(const_INTERNAL_name); + zend_string_release_ex(const_INTERNAL_name, true); zval const_SERVER_value; - ZVAL_LONG(&const_SERVER_value, 2); - zend_string *const_SERVER_name = zend_string_init_interned("SERVER", sizeof("SERVER") - 1, 1); + ZVAL_LONG(&const_SERVER_value, DDTRACE_SPAN_KIND_SERVER); + zend_string *const_SERVER_name = zend_string_init_interned("SERVER", sizeof("SERVER") - 1, true); zend_declare_class_constant_ex(class_entry, const_SERVER_name, &const_SERVER_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release(const_SERVER_name); + zend_string_release_ex(const_SERVER_name, true); zval const_CLIENT_value; - ZVAL_LONG(&const_CLIENT_value, 3); - zend_string *const_CLIENT_name = zend_string_init_interned("CLIENT", sizeof("CLIENT") - 1, 1); + ZVAL_LONG(&const_CLIENT_value, DDTRACE_SPAN_KIND_CLIENT); + zend_string *const_CLIENT_name = zend_string_init_interned("CLIENT", sizeof("CLIENT") - 1, true); zend_declare_class_constant_ex(class_entry, const_CLIENT_name, &const_CLIENT_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release(const_CLIENT_name); + zend_string_release_ex(const_CLIENT_name, true); zval const_PRODUCER_value; - ZVAL_LONG(&const_PRODUCER_value, 4); - zend_string *const_PRODUCER_name = zend_string_init_interned("PRODUCER", sizeof("PRODUCER") - 1, 1); + ZVAL_LONG(&const_PRODUCER_value, DDTRACE_SPAN_KIND_PRODUCER); + zend_string *const_PRODUCER_name = zend_string_init_interned("PRODUCER", sizeof("PRODUCER") - 1, true); zend_declare_class_constant_ex(class_entry, const_PRODUCER_name, &const_PRODUCER_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release(const_PRODUCER_name); + zend_string_release_ex(const_PRODUCER_name, true); zval const_CONSUMER_value; - ZVAL_LONG(&const_CONSUMER_value, 5); - zend_string *const_CONSUMER_name = zend_string_init_interned("CONSUMER", sizeof("CONSUMER") - 1, 1); + ZVAL_LONG(&const_CONSUMER_value, DDTRACE_SPAN_KIND_CONSUMER); + zend_string *const_CONSUMER_name = zend_string_init_interned("CONSUMER", sizeof("CONSUMER") - 1, true); zend_declare_class_constant_ex(class_entry, const_CONSUMER_name, &const_CONSUMER_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release(const_CONSUMER_name); + zend_string_release_ex(const_CONSUMER_name, true); return class_entry; } @@ -812,138 +837,130 @@ static zend_class_entry *register_class_DDTrace_SpanData(void) zval property_name_default_value; ZVAL_EMPTY_STRING(&property_name_default_value); - 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); + 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)); zval property_resource_default_value; ZVAL_EMPTY_STRING(&property_resource_default_value); - 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); + 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)); zval property_service_default_value; ZVAL_EMPTY_STRING(&property_service_default_value); - zend_string *property_service_name = zend_string_init("service", sizeof("service") - 1, 1); + zend_string *property_service_name = zend_string_init("service", sizeof("service") - 1, true); 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(property_service_name); + zend_string_release_ex(property_service_name, true); 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, 1); + zend_string *property_meta_struct_name = zend_string_init("meta_struct", sizeof("meta_struct") - 1, true); 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(property_meta_struct_name); + zend_string_release_ex(property_meta_struct_name, true); zval property_type_default_value; ZVAL_EMPTY_STRING(&property_type_default_value); - 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); + 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)); zval property_meta_default_value; ZVAL_EMPTY_ARRAY(&property_meta_default_value); - zend_string *property_meta_name = zend_string_init("meta", sizeof("meta") - 1, 1); + zend_string *property_meta_name = zend_string_init("meta", sizeof("meta") - 1, true); zend_declare_typed_property(class_entry, property_meta_name, &property_meta_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_NONE(0)); - zend_string_release(property_meta_name); + zend_string_release_ex(property_meta_name, true); zval property_metrics_default_value; ZVAL_EMPTY_ARRAY(&property_metrics_default_value); - zend_string *property_metrics_name = zend_string_init("metrics", sizeof("metrics") - 1, 1); + zend_string *property_metrics_name = zend_string_init("metrics", sizeof("metrics") - 1, true); zend_declare_typed_property(class_entry, property_metrics_name, &property_metrics_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_NONE(0)); - zend_string_release(property_metrics_name); + zend_string_release_ex(property_metrics_name, true); zval property_exception_default_value; ZVAL_NULL(&property_exception_default_value); - zend_string *property_exception_name = zend_string_init("exception", sizeof("exception") - 1, 1); + zend_string *property_exception_name = zend_string_init("exception", sizeof("exception") - 1, true); 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(property_exception_name); + zend_string_release_ex(property_exception_name, true); zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); - zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); + zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, true); 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(property_id_name); + zend_string_release_ex(property_id_name, true); zval property_links_default_value; ZVAL_EMPTY_ARRAY(&property_links_default_value); - zend_string *property_links_name = zend_string_init("links", sizeof("links") - 1, 1); + zend_string *property_links_name = zend_string_init("links", sizeof("links") - 1, true); 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(property_links_name); + zend_string_release_ex(property_links_name, true); zval property_events_default_value; ZVAL_EMPTY_ARRAY(&property_events_default_value); - zend_string *property_events_name = zend_string_init("events", sizeof("events") - 1, 1); + zend_string *property_events_name = zend_string_init("events", sizeof("events") - 1, true); 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(property_events_name); + zend_string_release_ex(property_events_name, true); zval property_peerServiceSources_default_value; ZVAL_EMPTY_ARRAY(&property_peerServiceSources_default_value); - zend_string *property_peerServiceSources_name = zend_string_init("peerServiceSources", sizeof("peerServiceSources") - 1, 1); + zend_string *property_peerServiceSources_name = zend_string_init("peerServiceSources", sizeof("peerServiceSources") - 1, true); 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(property_peerServiceSources_name); + zend_string_release_ex(property_peerServiceSources_name, true); 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, 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); + 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)); zval property_stack_default_value; ZVAL_UNDEF(&property_stack_default_value); - zend_string *property_stack_name = zend_string_init("stack", sizeof("stack") - 1, 1); + zend_string *property_stack_name = zend_string_init("stack", sizeof("stack") - 1, true); 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(property_stack_name); + zend_string_release_ex(property_stack_name, true); zval property_onClose_default_value; ZVAL_EMPTY_ARRAY(&property_onClose_default_value); - zend_string *property_onClose_name = zend_string_init("onClose", sizeof("onClose") - 1, 1); + zend_string *property_onClose_name = zend_string_init("onClose", sizeof("onClose") - 1, true); 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(property_onClose_name); + zend_string_release_ex(property_onClose_name, true); zval property_baggage_default_value; ZVAL_EMPTY_ARRAY(&property_baggage_default_value); - zend_string *property_baggage_name = zend_string_init("baggage", sizeof("baggage") - 1, 1); + zend_string *property_baggage_name = zend_string_init("baggage", sizeof("baggage") - 1, true); 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(property_baggage_name); + zend_string_release_ex(property_baggage_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, 1); + 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(property_env_name); + 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, 1); + 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(property_version_name); + zend_string_release_ex(property_version_name, true); 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_string *property_component_name = zend_string_init("component", sizeof("component") - 1, true); 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); + zend_string_release_ex(property_component_name, true); 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_string *property_spanKind_name = zend_string_init("spanKind", sizeof("spanKind") - 1, true); 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); + zend_string_release_ex(property_spanKind_name, true); 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_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, true); 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); + zend_string_release_ex(property_attributes_name, true); zval property_ignoreError_default_value; ZVAL_FALSE(&property_ignoreError_default_value); - zend_string *property_ignoreError_name = zend_string_init("ignoreError", sizeof("ignoreError") - 1, 1); + zend_string *property_ignoreError_name = zend_string_init("ignoreError", sizeof("ignoreError") - 1, true); zend_declare_typed_property(class_entry, property_ignoreError_name, &property_ignoreError_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release(property_ignoreError_name); + zend_string_release_ex(property_ignoreError_name, true); return class_entry; } @@ -967,77 +984,65 @@ 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, 1); + zend_string *property_origin_name = zend_string_init("origin", sizeof("origin") - 1, true); 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(property_origin_name); + zend_string_release_ex(property_origin_name, true); zval property_propagatedTags_default_value; ZVAL_EMPTY_ARRAY(&property_propagatedTags_default_value); - zend_string *property_propagatedTags_name = zend_string_init("propagatedTags", sizeof("propagatedTags") - 1, 1); + zend_string *property_propagatedTags_name = zend_string_init("propagatedTags", sizeof("propagatedTags") - 1, true); 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(property_propagatedTags_name); + zend_string_release_ex(property_propagatedTags_name, true); 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, 1); + zend_string *property_samplingPriority_name = zend_string_init("samplingPriority", sizeof("samplingPriority") - 1, true); 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(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); + zend_string_release_ex(property_samplingPriority_name, true); zval property_propagatedSamplingPriority_default_value; ZVAL_UNDEF(&property_propagatedSamplingPriority_default_value); - zend_string *property_propagatedSamplingPriority_name = zend_string_init("propagatedSamplingPriority", sizeof("propagatedSamplingPriority") - 1, 1); + zend_string *property_propagatedSamplingPriority_name = zend_string_init("propagatedSamplingPriority", sizeof("propagatedSamplingPriority") - 1, true); 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(property_propagatedSamplingPriority_name); + zend_string_release_ex(property_propagatedSamplingPriority_name, true); zval property_tracestate_default_value; ZVAL_UNDEF(&property_tracestate_default_value); - zend_string *property_tracestate_name = zend_string_init("tracestate", sizeof("tracestate") - 1, 1); + zend_string *property_tracestate_name = zend_string_init("tracestate", sizeof("tracestate") - 1, true); 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(property_tracestate_name); + zend_string_release_ex(property_tracestate_name, true); zval property_tracestateTags_default_value; ZVAL_EMPTY_ARRAY(&property_tracestateTags_default_value); - zend_string *property_tracestateTags_name = zend_string_init("tracestateTags", sizeof("tracestateTags") - 1, 1); + zend_string *property_tracestateTags_name = zend_string_init("tracestateTags", sizeof("tracestateTags") - 1, true); 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(property_tracestateTags_name); + zend_string_release_ex(property_tracestateTags_name, true); zval property_parentId_default_value; ZVAL_UNDEF(&property_parentId_default_value); - zend_string *property_parentId_name = zend_string_init("parentId", sizeof("parentId") - 1, 1); + zend_string *property_parentId_name = zend_string_init("parentId", sizeof("parentId") - 1, true); 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(property_parentId_name); + zend_string_release_ex(property_parentId_name, true); zval property_traceId_default_value; ZVAL_EMPTY_STRING(&property_traceId_default_value); - zend_string *property_traceId_name = zend_string_init("traceId", sizeof("traceId") - 1, 1); + zend_string *property_traceId_name = zend_string_init("traceId", sizeof("traceId") - 1, true); 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(property_traceId_name); + zend_string_release_ex(property_traceId_name, true); zval property_gitMetadata_default_value; ZVAL_NULL(&property_gitMetadata_default_value); - zend_string *property_gitMetadata_name = zend_string_init("gitMetadata", sizeof("gitMetadata") - 1, 1); + zend_string *property_gitMetadata_name = zend_string_init("gitMetadata", sizeof("gitMetadata") - 1, true); 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(property_gitMetadata_name); + zend_string_release_ex(property_gitMetadata_name, true); zval property_inferredSpan_default_value; ZVAL_NULL(&property_inferredSpan_default_value); - zend_string *property_inferredSpan_name = zend_string_init("inferredSpan", sizeof("inferredSpan") - 1, 1); + zend_string *property_inferredSpan_name = zend_string_init("inferredSpan", sizeof("inferredSpan") - 1, true); 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(property_inferredSpan_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); + zend_string_release_ex(property_inferredSpan_name, true); return class_entry; } @@ -1051,29 +1056,21 @@ 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, 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); + 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)); zval property_active_default_value; ZVAL_NULL(&property_active_default_value); - zend_string *property_active_name = zend_string_init("active", sizeof("active") - 1, 1); + zend_string *property_active_name = zend_string_init("active", sizeof("active") - 1, true); 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(property_active_name); + zend_string_release_ex(property_active_name, true); zval property_spanCreationObservers_default_value; ZVAL_EMPTY_ARRAY(&property_spanCreationObservers_default_value); - zend_string *property_spanCreationObservers_name = zend_string_init("spanCreationObservers", sizeof("spanCreationObservers") - 1, 1); + zend_string *property_spanCreationObservers_name = zend_string_init("spanCreationObservers", sizeof("spanCreationObservers") - 1, true); 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(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); + zend_string_release_ex(property_spanCreationObservers_name, true); return class_entry; } @@ -1087,21 +1084,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, 1); + zend_string *const_NOT_LOADED_name = zend_string_init_interned("NOT_LOADED", sizeof("NOT_LOADED") - 1, true); zend_declare_class_constant_ex(class_entry, const_NOT_LOADED_name, &const_NOT_LOADED_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release(const_NOT_LOADED_name); + zend_string_release_ex(const_NOT_LOADED_name, true); 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, 1); + zend_string *const_LOADED_name = zend_string_init_interned("LOADED", sizeof("LOADED") - 1, true); zend_declare_class_constant_ex(class_entry, const_LOADED_name, &const_LOADED_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release(const_LOADED_name); + zend_string_release_ex(const_LOADED_name, true); 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, 1); + zend_string *const_NOT_AVAILABLE_name = zend_string_init_interned("NOT_AVAILABLE", sizeof("NOT_AVAILABLE") - 1, true); zend_declare_class_constant_ex(class_entry, const_NOT_AVAILABLE_name, &const_NOT_AVAILABLE_value, ZEND_ACC_PUBLIC, NULL); - zend_string_release(const_NOT_AVAILABLE_name); + zend_string_release_ex(const_NOT_AVAILABLE_name, true); return class_entry; } diff --git a/tracer/distributed_tracing_headers.c b/tracer/distributed_tracing_headers.c index 40940d53adf..e5da3c05093 100644 --- a/tracer/distributed_tracing_headers.c +++ b/tracer/distributed_tracing_headers.c @@ -26,13 +26,13 @@ static ddtrace_distributed_tracing_result dd_init_empty_result(void) { result.priority_sampling = DDTRACE_PRIORITY_SAMPLING_UNKNOWN; zend_hash_init(&result.tracestate_unknown_dd_keys, 8, unused, ZVAL_PTR_DTOR, 0); zend_hash_init(&result.propagated_tags, 8, unused, ZVAL_PTR_DTOR, 0); - zend_hash_init(&result.meta_tags, 8, unused, ZVAL_PTR_DTOR, 0); + zend_hash_init(&result.attributes, 8, unused, ZVAL_PTR_DTOR, 0); zend_hash_init(&result.baggage, 8, unused, ZVAL_PTR_DTOR, 0); return result; } static void dd_check_tid(ddtrace_distributed_tracing_result *result) { - zval *tidzv = zend_hash_str_find(&result->meta_tags, ZEND_STRL("_dd.p.tid")); + zval *tidzv = zend_hash_str_find(&result->attributes, ZEND_STRL("_dd.p.tid")); if (tidzv && result->trace_id.low) { uint64_t tid = ddtrace_parse_hex_span_id(tidzv); uint64_t cur_high = result->trace_id.high; @@ -42,14 +42,14 @@ static void dd_check_tid(ddtrace_distributed_tracing_result *result) { } else { zval error; ZVAL_STR(&error, zend_strpprintf(0, "inconsistent_tid %s", Z_STRVAL_P(tidzv))); - zend_hash_str_update(&result->meta_tags, ZEND_STRL("_dd.propagation_error"), &error); + zend_hash_str_update(&result->attributes, ZEND_STRL("_dd.propagation_error"), &error); } } else if (Z_TYPE_P(tidzv) == IS_STRING && strcmp(Z_STRVAL_P(tidzv), "0") != 0) { zval error; ZVAL_STR(&error, zend_strpprintf(0, "malformed_tid %s", Z_STRVAL_P(tidzv))); - zend_hash_str_update(&result->meta_tags, ZEND_STRL("_dd.propagation_error"), &error); + zend_hash_str_update(&result->attributes, ZEND_STRL("_dd.propagation_error"), &error); } - zend_hash_str_del(&result->meta_tags, ZEND_STRL("_dd.p.tid")); + zend_hash_str_del(&result->attributes, ZEND_STRL("_dd.p.tid")); zend_hash_str_del(&result->propagated_tags, ZEND_STRL("_dd.p.tid")); } } @@ -91,7 +91,7 @@ static void ddtrace_parse_datadog_tracestate_member(ddtrace_distributed_tracing_ if (*span_parent_key) { zval zv; ZVAL_STRINGL(&zv, valuestart, valuelen); - zend_hash_update(&result->meta_tags, *span_parent_key, &zv); + zend_hash_update(&result->attributes, *span_parent_key, &zv); zend_string_release(*span_parent_key); *span_parent_key = NULL; } @@ -123,13 +123,13 @@ static void ddtrace_parse_datadog_tracestate_member(ddtrace_distributed_tracing_ *valptr = '='; } } - zend_hash_update(&result->meta_tags, tag_name, &zv); + zend_hash_update(&result->attributes, tag_name, &zv); zend_hash_add_empty_element(&result->propagated_tags, tag_name); zend_string_release(tag_name); } else { zval error_zv; ZVAL_STRING(&error_zv, "extract_max_size"); - zend_hash_str_update(&result->meta_tags, ZEND_STRL("_dd.propagation_error"), &error_zv); + zend_hash_str_update(&result->attributes, ZEND_STRL("_dd.propagation_error"), &error_zv); } } else if (zend_hash_num_elements(&result->tracestate_unknown_dd_keys) < 100) { zval zv; @@ -295,7 +295,7 @@ static ddtrace_distributed_tracing_result ddtrace_read_distributed_tracing_ids_d } if (read_header((zai_str)ZAI_STRL("X_DATADOG_TAGS"), "x-datadog-tags", &propagated_tags, data)) { - ddtrace_add_tracer_tags_from_header(propagated_tags, &result.meta_tags, &result.propagated_tags); + ddtrace_add_tracer_tags_from_header(propagated_tags, &result.attributes, &result.propagated_tags); zend_string_release(propagated_tags); dd_check_tid(&result); @@ -511,7 +511,7 @@ static ddtrace_distributed_tracing_result ddtrace_read_distributed_tracing_ids_t if (span_parent_key) { zval zv; ZVAL_STRING(&zv, "0000000000000000"); - zend_hash_update(&result.meta_tags, span_parent_key, &zv); + zend_hash_update(&result.attributes, span_parent_key, &zv); zend_string_release(span_parent_key); } @@ -549,8 +549,8 @@ ddtrace_distributed_tracing_result ddtrace_read_distributed_tracing_ids(ddtrace_ if (!has_trace) { zend_string *existing_origin = result.origin; - if (result.meta_tags.arData) { - zend_hash_destroy(&result.meta_tags); + if (result.attributes.arData) { + zend_hash_destroy(&result.attributes); } if (result.propagated_tags.arData) { zend_hash_destroy(&result.propagated_tags); @@ -592,15 +592,15 @@ ddtrace_distributed_tracing_result ddtrace_read_distributed_tracing_ids(ddtrace_ } if (result.parent_id != new_result.parent_id) { // set last datadog span_id tag - zval *lp_id = zend_hash_str_find(&new_result.meta_tags, ZEND_STRL("_dd.parent_id")); + zval *lp_id = zend_hash_str_find(&new_result.attributes, ZEND_STRL("_dd.parent_id")); if (lp_id && !zend_string_equals_literal(Z_STR_P(lp_id), "0000000000000000")) { Z_TRY_ADDREF_P(lp_id); - zend_hash_str_update(&result.meta_tags, ZEND_STRL("_dd.parent_id"), lp_id); + zend_hash_str_update(&result.attributes, ZEND_STRL("_dd.parent_id"), lp_id); } else if (result.parent_id != 0) { zval parent_id_zval; ZVAL_STR(&parent_id_zval, zend_string_alloc(16, 0)); sprintf(Z_STRVAL_P(&parent_id_zval), "%016" PRIx64, result.parent_id); - zend_hash_str_update(&result.meta_tags, ZEND_STRL("_dd.parent_id"), &parent_id_zval); + zend_hash_str_update(&result.attributes, ZEND_STRL("_dd.parent_id"), &parent_id_zval); } result.parent_id = new_result.parent_id; } @@ -613,7 +613,7 @@ ddtrace_distributed_tracing_result ddtrace_read_distributed_tracing_ids(ddtrace_ zend_string_release(new_result.origin); } - zend_hash_destroy(&new_result.meta_tags); + zend_hash_destroy(&new_result.attributes); zend_hash_destroy(&new_result.propagated_tags); zend_hash_destroy(&new_result.tracestate_unknown_dd_keys); ddtrace_otel_sampling_clear(&new_result.otel_sampling); @@ -644,7 +644,7 @@ ddtrace_distributed_tracing_result ddtrace_read_distributed_tracing_ids(ddtrace_ return result; } -void apply_baggage_span_tags(zend_string *key, zval *val, zend_array *meta) { +void apply_baggage_span_tags(zend_string *key, zval *val, zend_array *attributes) { if (!zend_hash_exists(get_DD_TRACE_BAGGAGE_TAG_KEYS(), key)) { if (zend_hash_num_elements(get_DD_TRACE_BAGGAGE_TAG_KEYS()) != 1) { return; @@ -657,7 +657,7 @@ void apply_baggage_span_tags(zend_string *key, zval *val, zend_array *meta) { } key = zend_strpprintf(0, "baggage.%s", ZSTR_VAL(key)); - zend_hash_update(meta, key, val); + zend_hash_update(attributes, key, val); zend_string_release(key); Z_TRY_ADDREF_P(val); } @@ -669,7 +669,7 @@ void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result // behavior=ignore: drop all extracted context including baggage case DD_TRACE_PROPAGATION_BEHAVIOR_EXTRACT_IGNORE: zend_hash_destroy(&result->propagated_tags); - zend_hash_destroy(&result->meta_tags); + zend_hash_destroy(&result->attributes); zend_hash_destroy(&result->tracestate_unknown_dd_keys); zend_hash_destroy(&result->baggage); if (result->origin) { zend_string_release(result->origin); } @@ -709,7 +709,7 @@ void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result ZVAL_COPY_VALUE(&DDTRACE_G(pending_upstream_span_link), &link_zv); } - zend_hash_clean(&result->meta_tags); + zend_hash_clean(&result->attributes); zend_hash_clean(&result->propagated_tags); zend_hash_clean(&result->tracestate_unknown_dd_keys); if (result->origin) { @@ -731,19 +731,19 @@ void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result break; } - zend_array *root_meta = span ? ddtrace_property_array(&span->property_attributes) : &DDTRACE_G(root_span_tags_preset); + zend_array *root_attributes = span ? ddtrace_property_array(&span->property_attributes) : &DDTRACE_G(root_span_tags_preset); if (span) { - ddtrace_drop_propagated_tags(root_meta, ddtrace_property_array(&span->property_propagated_tags)); + ddtrace_drop_propagated_tags(root_attributes, ddtrace_property_array(&span->property_propagated_tags)); ZVAL_ARR(&zv, emalloc(sizeof(HashTable))); *Z_ARR(zv) = result->propagated_tags; datadog_assign_variable(&span->property_propagated_tags, &zv); - zend_hash_copy(root_meta, &result->meta_tags, NULL); + zend_hash_copy(root_attributes, &result->attributes, NULL); ddtrace_span_data *inferred_span = ddtrace_get_inferred_span(span); if (inferred_span) { - zend_array *inferred_meta = ddtrace_property_array(&inferred_span->property_attributes); - zend_hash_copy(inferred_meta, &result->meta_tags, (copy_ctor_func_t)zval_add_ref); + zend_array *inferred_attributes = ddtrace_property_array(&inferred_span->property_attributes); + zend_hash_copy(inferred_attributes, &result->attributes, (copy_ctor_func_t)zval_add_ref); } if (result->origin) { @@ -768,7 +768,7 @@ void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result ZEND_HASH_FOREACH_KEY_VAL(&result->baggage, key_i, key, val) { if (key) { zend_hash_update(existing_baggage, key, val); - apply_baggage_span_tags(key, val, root_meta); + apply_baggage_span_tags(key, val, root_attributes); } else { zend_hash_index_update(existing_baggage, key_i, val); } @@ -790,7 +790,7 @@ void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result DDTRACE_G(propagated_root_span_tags) = result->propagated_tags; zend_hash_destroy(&DDTRACE_G(tracestate_unknown_dd_keys)); DDTRACE_G(tracestate_unknown_dd_keys) = result->tracestate_unknown_dd_keys; - zend_hash_copy(&DDTRACE_G(root_span_tags_preset), &result->meta_tags, NULL); + zend_hash_copy(&DDTRACE_G(root_span_tags_preset), &result->attributes, NULL); if (DDTRACE_G(dd_origin)) { zend_string_release(DDTRACE_G(dd_origin)); } @@ -818,8 +818,8 @@ void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result } ddtrace_otel_sampling_clear(&result->otel_sampling); - result->meta_tags.pDestructor = NULL; // we moved values directly - zend_hash_destroy(&result->meta_tags); + result->attributes.pDestructor = NULL; // we moved values directly + zend_hash_destroy(&result->attributes); if (result->trace_id.low || result->trace_id.high || result->priority_sampling != DDTRACE_PRIORITY_SAMPLING_UNKNOWN) { if (span) { @@ -831,14 +831,14 @@ void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result } if (result->priority_sampling != DDTRACE_PRIORITY_SAMPLING_UNKNOWN) { - bool reset_decision_maker = result->conflicting_sampling_priority || !zend_hash_str_exists(root_meta, ZEND_STRL("_dd.p.dm")); + bool reset_decision_maker = result->conflicting_sampling_priority || !zend_hash_str_exists(root_attributes, ZEND_STRL("_dd.p.dm")); if (reset_decision_maker) { if (result->priority_sampling > 0) { ZVAL_STRINGL(&zv, "-0", 2); - zend_hash_str_update(root_meta, ZEND_STRL("_dd.p.dm"), &zv); + zend_hash_str_update(root_attributes, ZEND_STRL("_dd.p.dm"), &zv); zend_hash_str_add_empty_element(span ? ddtrace_property_array(&span->property_propagated_tags) : &DDTRACE_G(propagated_root_span_tags), ZEND_STRL("_dd.p.dm")); } else { - zend_hash_str_del(root_meta, ZEND_STRL("_dd.p.dm")); + zend_hash_str_del(root_attributes, ZEND_STRL("_dd.p.dm")); } } if (!span) { diff --git a/tracer/distributed_tracing_headers.h b/tracer/distributed_tracing_headers.h index 2ab38e712c4..4d7844eb52c 100644 --- a/tracer/distributed_tracing_headers.h +++ b/tracer/distributed_tracing_headers.h @@ -15,7 +15,7 @@ typedef struct { HashTable baggage; HashTable tracestate_unknown_dd_keys; HashTable propagated_tags; - HashTable meta_tags; + HashTable attributes; int priority_sampling; uint8_t trace_flags; enum dd_sampling_mechanism sampling_mechanism; diff --git a/tracer/endpoint_guessing.c b/tracer/endpoint_guessing.c index 2a82a7a44fb..65c975732c2 100644 --- a/tracer/endpoint_guessing.c +++ b/tracer/endpoint_guessing.c @@ -200,7 +200,7 @@ void ddtrace_maybe_add_guessed_endpoint_tag(ddtrace_root_span_data *span) zend_array* attributes = ddtrace_property_array(&span->property_attributes); if (!get_DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT()) { - zval* route = ddtrace_span_find_tag(&span->span, ZEND_STRL("http.route")); + zval* route = zend_hash_str_find(attributes, ZEND_STRL("http.route")); // unless we have always_simplified_endpoiont set, // we skip the calculation if http.route is set if (route && Z_TYPE_P(route) == IS_STRING) { @@ -210,10 +210,7 @@ void ddtrace_maybe_add_guessed_endpoint_tag(ddtrace_root_span_data *span) zval* endpoint; if ((endpoint = zend_hash_str_add(attributes, ZEND_STRL("http.endpoint"), &(zval){0}))) { - zval* url = ddtrace_span_find_tag(&span->span, ZEND_STRL("http.url")); - if (url) { - ZVAL_DEREF(url); - } + zval* url = zend_hash_str_find_deref(attributes, ZEND_STRL("http.url")); if (!url || Z_TYPE_P(url) != IS_STRING) { // "In case the url is not available, a default value of / should be used for the endpoint tag." ZVAL_STRING(endpoint, "/"); diff --git a/tracer/exception_serialize.c b/tracer/exception_serialize.c index 37e3987fc79..29abe944c35 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_SpanNode *span, enum dd_exception exception_state) { +static void dd_exception_to_error_msg(zend_object *exception, ddog_SpanBytes *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))); @@ -49,7 +49,7 @@ static void dd_exception_to_error_msg(zend_object *exception, ddog_SpanNode *spa free(status_line); } -static void dd_exception_to_error_type(zend_object *exception, ddog_SpanNode *span) { +static void dd_exception_to_error_type(zend_object *exception, ddog_SpanBytes *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}"; @@ -82,7 +82,7 @@ static void dd_exception_to_error_type(zend_object *exception, ddog_SpanNode *sp } } -static void dd_exception_trace_to_error_stack(zend_string *trace, ddog_SpanNode *span) { +static void dd_exception_trace_to_error_stack(zend_string *trace, ddog_SpanBytes *span) { dd_span_attr_zstr(span, "error.stack", trace); zend_string_release(trace); } @@ -314,7 +314,7 @@ 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_SpanNode *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, ddog_SpanBytes *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); @@ -393,7 +393,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_SpanNode *span) { +static void ddtrace_collect_exception_debug_data(zend_object *exception, zend_object *throwable, zend_string *service_name, uint64_t time, ddog_SpanBytes *span) { if (!ddtrace_exception_debugging_is_active()) { return; } @@ -541,7 +541,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_SpanNode *span, enum dd_exception exception_state) { +void ddtrace_exception_to_attributes(zend_object *exception, zend_string *service_name, uint64_t time, ddog_SpanBytes *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 345106e5613..ffa10d0a325 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_SpanNode *span, enum dd_exception exception_state); +void ddtrace_exception_to_attributes(zend_object *exception, zend_string *service_name, uint64_t time, ddog_SpanBytes *span, 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 82a5cfbff61..2734e9a6d6e 100644 --- a/tracer/functions.c +++ b/tracer/functions.c @@ -165,9 +165,9 @@ void ddtrace_build_span_link_from_result(ddtrace_distributed_tracing_result *res ZVAL_STR(&link->property_span_id, ddtrace_span_id_as_hex_string(result->parent_id)); array_init(&link->property_attributes); - zend_hash_copy(Z_ARR(link->property_attributes), &result->meta_tags, (copy_ctor_func_t)zval_add_ref); + zend_hash_copy(Z_ARR(link->property_attributes), &result->attributes, (copy_ctor_func_t)zval_add_ref); - zend_string *propagated_tags = ddtrace_format_propagated_tags(&result->propagated_tags, &result->meta_tags); + zend_string *propagated_tags = ddtrace_format_propagated_tags(&result->propagated_tags, &result->attributes); zend_string *full_tracestate = ddtrace_format_tracestate(result->tracestate, 0, result->origin, result->priority_sampling, propagated_tags, &result->tracestate_unknown_dd_keys, &result->otel_sampling); full_tracestate = ddtrace_otel_sampling_limit_tracestate(full_tracestate); if (propagated_tags) { @@ -195,8 +195,8 @@ ZEND_METHOD(DDTrace_SpanLink, fromHeaders) { ddtrace_build_span_link_from_result(&result, link); // The span link took its own references (zval_add_ref) on the copied values, so destroy - // meta_tags normally to release the references it still owns. - zend_hash_destroy(&result.meta_tags); + // attributes normally to release the references it still owns. + zend_hash_destroy(&result.attributes); zend_hash_destroy(&result.propagated_tags); zend_hash_destroy(&result.tracestate_unknown_dd_keys); zend_hash_destroy(&result.baggage); @@ -291,7 +291,6 @@ static zend_object *ddtrace_span_stack_create(zend_class_entry *class_type) { #if PHP_VERSION_ID < 80000 // Not handled in arginfo on these old versions array_init(&stack->property_span_creation_observers); - array_init(&stack->property_attributes); #endif return &stack->std; } @@ -458,10 +457,10 @@ static zval *ddtrace_span_data_readonly(zend_object *object, zend_string *member } } if (Z_TYPE_P(value) == IS_STRING && !zend_is_identical(&span->property_service, value)) { - zend_array *meta = ddtrace_property_array(&span->property_attributes); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); zval val; ZVAL_NEW_STR(&val, zend_string_init("m", 1, 0)); - zend_hash_str_update(meta, ZEND_STRL("_dd.svc_src"), &val); + zend_hash_str_update(attributes, ZEND_STRL("_dd.svc_src"), &val); } } @@ -1130,7 +1129,10 @@ PHP_FUNCTION(dd_trace_serialize_closed_spans) { } if (!get_DD_TRACE_ENABLED()) { + zval chunks; + array_init(&chunks); array_init(return_value); + add_assoc_zval(return_value, "chunks", &chunks); return; } @@ -1143,24 +1145,9 @@ PHP_FUNCTION(dd_trace_serialize_closed_spans) { ddtrace_serialize_closed_spans_with_cycle(ctx, false); - zval traces_zv = dd_serialize_rust_to_zval(ctx->builder); + zval payload_zv = dd_serialize_rust_to_zval(ctx->builder); ddog_v1_free_builder(ctx->builder); - - if (zend_hash_num_elements(Z_ARR(traces_zv)) == 1) { - ZVAL_COPY(return_value, zend_hash_get_current_data(Z_ARR(traces_zv))); - } else { - array_init(return_value); - zval *spans; - ZEND_HASH_FOREACH_VAL(Z_ARR(traces_zv), spans) { - zval *span; - ZEND_HASH_FOREACH_VAL(Z_ARR_P(spans), span) { - Z_ADDREF_P(span); - zend_hash_next_index_insert_new(Z_ARR_P(return_value), span); - } ZEND_HASH_FOREACH_END(); - } ZEND_HASH_FOREACH_END(); - } - - zval_ptr_dtor(&traces_zv); + ZVAL_COPY_VALUE(return_value, &payload_zv); ddtrace_free_span_stacks(false); ddtrace_init_span_stacks(); @@ -1331,6 +1318,48 @@ PHP_FUNCTION(DDTrace_Testing_normalize_tag_value) { } } +PHP_FUNCTION(DDTrace_Testing_serialize_closed_spans_v04) { + ZEND_PARSE_PARAMETERS_NONE(); + + zval view, payloads; + array_init(&payloads); + array_init(return_value); + + if (!get_DD_TRACE_ENABLED()) { + zval chunks; + array_init(&chunks); + array_init(&view); + add_assoc_zval(&view, "chunks", &chunks); + add_next_index_zval(return_value, &view); + add_next_index_zval(return_value, &payloads); + return; + } + + ddtrace_mark_all_span_stacks_flushable(); + + ddtrace_serialize_ctx serialize_ctx = {.builder = ddog_v1_new_builder(), .chunk = DD_CHUNK_NONE}; + ddtrace_serialize_closed_spans_with_cycle(&serialize_ctx, false); + + view = dd_serialize_rust_to_zval(serialize_ctx.builder); + add_next_index_zval(return_value, &view); + + // The in-process sender's downgrade and per-trace framing (auto_flush.c); consumes the builder. + ddog_TracesBytes *v04_traces = ddog_downgrade_v1_builder_to_v04_traces(serialize_ctx.builder); + size_t trace_count = ddog_get_traces_size(v04_traces); + for (size_t i = 0; i < trace_count; i++) { + ddog_CharSlice payload = ddog_serialize_trace_into_charslice(ddog_get_trace(v04_traces, i)); + if (payload.len > 0) { + add_next_index_stringl(&payloads, payload.ptr, payload.len); + } + ddog_free_charslice(payload); + } + ddog_free_traces(v04_traces); + add_next_index_zval(return_value, &payloads); + + ddtrace_free_span_stacks(false); + ddtrace_init_span_stacks(); +} + PHP_FUNCTION(DDTrace_Internal_add_span_flag) { zend_object *span; zend_long flag; @@ -2589,17 +2618,17 @@ PHP_FUNCTION(DDTrace_set_distributed_tracing_context) { } if (tags) { - zend_array *root_meta = &DDTRACE_G(root_span_tags_preset); + zend_array *root_attributes = &DDTRACE_G(root_span_tags_preset); zend_array *propagated_tags = &DDTRACE_G(propagated_root_span_tags); if (root_span) { - root_meta = ddtrace_property_array(&root_span->property_attributes); + root_attributes = ddtrace_property_array(&root_span->property_attributes); propagated_tags = ddtrace_property_array(&root_span->property_propagated_tags); } if (Z_TYPE_P(tags) == IS_STRING) { - ddtrace_add_tracer_tags_from_header(Z_STR_P(tags), root_meta, propagated_tags); + ddtrace_add_tracer_tags_from_header(Z_STR_P(tags), root_attributes, propagated_tags); } else if (Z_TYPE_P(tags) == IS_ARRAY) { - ddtrace_add_tracer_tags_from_array(Z_ARR_P(tags), root_meta, propagated_tags); + ddtrace_add_tracer_tags_from_array(Z_ARR_P(tags), root_attributes, propagated_tags); } } diff --git a/tracer/handlers_http.h b/tracer/handlers_http.h index f5a78b6ee79..067febfaf1a 100644 --- a/tracer/handlers_http.h +++ b/tracer/handlers_http.h @@ -323,8 +323,8 @@ static inline void ddtrace_inject_distributed_headers_config(zend_array *array, } ddtrace_root_span_data *root_span = DDTRACE_G(active_stack) ? DDTRACE_G(active_stack)->root_span : NULL; - zend_array *meta = root_span ? ddtrace_property_array(&root_span->property_attributes) : &DDTRACE_G(root_span_tags_preset); - if (!get_DD_APM_TRACING_ENABLED() && !ddtrace_asm_event_emitted() && !ddtrace_trace_source_is_meta_asm_sourced(meta)) { + zend_array *attributes = root_span ? ddtrace_property_array(&root_span->property_attributes) : &DDTRACE_G(root_span_tags_preset); + if (!get_DD_APM_TRACING_ENABLED() && !ddtrace_asm_event_emitted() && !ddtrace_trace_source_is_asm_sourced(attributes)) { return; } diff --git a/tracer/handlers_httpstreams.c b/tracer/handlers_httpstreams.c index 6e8a7f7e078..40fccf19b94 100644 --- a/tracer/handlers_httpstreams.c +++ b/tracer/handlers_httpstreams.c @@ -69,16 +69,15 @@ static php_stream *dd_stream_opener( if (span) { ddtrace_set_global_span_properties(span); - zend_array *meta = ddtrace_property_array(&span->property_attributes); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); zval zv; - // 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 */); + ZVAL_LONG(&span->property_span_kind, DDTRACE_SPAN_KIND_CLIENT); ZVAL_STRING(&zv, filename); - zend_hash_str_update(meta, ZEND_STRL("http.url"), &zv); + zend_hash_str_update(attributes, ZEND_STRL("http.url"), &zv); // Stream context options store HTTP wrapper options under the "http" subarray, e.g. // stream_context_create(['http' => ['method' => 'GET', ...]]). @@ -93,7 +92,7 @@ static php_stream *dd_stream_opener( // to avoid leaving span attributes with a dangling zend_string once the options array is destroyed. zval method_copy; ZVAL_COPY(&method_copy, method_zv); - zend_hash_str_update(meta, ZEND_STRL("http.method"), &method_copy); + zend_hash_str_update(attributes, ZEND_STRL("http.method"), &method_copy); } } @@ -103,7 +102,7 @@ static php_stream *dd_stream_opener( const char *host_end = strchr(host_start, '/'); size_t host_len = host_end ? (size_t)(host_end - host_start) : strlen(host_start); ZVAL_STRINGL(&zv, host_start, host_len); - zend_hash_str_update(meta, ZEND_STRL("network.destination.name"), &zv); + zend_hash_str_update(attributes, ZEND_STRL("network.destination.name"), &zv); } } } diff --git a/tracer/hook/uhook_arginfo.h b/tracer/hook/uhook_arginfo.h index 01ae1ff9ef9..490318f24eb 100644 --- a/tracer/hook/uhook_arginfo.h +++ b/tracer/hook/uhook_arginfo.h @@ -1,6 +1,8 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit uhook.stub.php instead. * Stub hash: 27176438d997b2f7e883e8e6a265b82eae65139f */ +#include "zend_constants.h" + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_install_hook, 0, 1, IS_LONG, 0) ZEND_ARG_OBJ_TYPE_MASK(0, target, Closure|Generator, MAY_BE_STRING|MAY_BE_CALLABLE, NULL) ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, begin, Closure, 1, "null") diff --git a/tracer/hook/uhook_attributes.c b/tracer/hook/uhook_attributes.c index 4bb4d0e7532..454e2fca453 100644 --- a/tracer/hook/uhook_attributes.c +++ b/tracer/hook/uhook_attributes.c @@ -4,7 +4,7 @@ #include "../ddtrace.h" #include "../configuration.h" #include "../span.h" -#include +#include "../span_tags_view.h" #include "uhook_attributes_arginfo.h" #include "uhook.h" @@ -18,7 +18,11 @@ typedef struct { zend_string *resource; zend_string *service; zend_string *type; + zend_string *component; + zend_long kind; + bool has_kind; zend_array *tags; + zend_array *attributes; bool args; zend_array *arg_whitelist; bool retval; @@ -103,46 +107,6 @@ static zval dd_uhook_save_value(zval *value) { return ret; } -// A tag value as it serialized from meta: string leaves (null -> "null"), "" for an empty or -// recursive (reference cycle) array/object, so the v0.4 wire is unchanged now that it lives in the -// attributes. -static void dd_uhook_tag_as_meta(zval *dst, zval *src) { - ZVAL_DEREF(src); - if (Z_TYPE_P(src) != IS_ARRAY && Z_TYPE_P(src) != IS_OBJECT) { - datadog_convert_to_string(dst, src); - return; - } - HashTable *ht = Z_TYPE_P(src) == IS_ARRAY ? Z_ARR_P(src) : Z_OBJPROP_P(src); - if (!zend_hash_num_elements(ht) || Z_IS_RECURSIVE_P(src)) { - ZVAL_EMPTY_STRING(dst); - return; - } - // Immutable arrays cannot form a cycle and must never be written to. - bool guard = Z_TYPE_P(src) != IS_ARRAY || !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE); - if (guard) { - Z_PROTECT_RECURSION_P(src); - } - array_init_size(dst, zend_hash_num_elements(ht)); - zend_string *key; - zend_ulong idx; - zval *val; - ZEND_HASH_FOREACH_KEY_VAL_IND(ht, idx, key, val) { - if (key && ZSTR_LEN(key) && ZSTR_VAL(key)[0] == '\0') { - continue; // protected and private members - } - zval leaf; - dd_uhook_tag_as_meta(&leaf, val); - if (key) { - zend_hash_update(Z_ARR_P(dst), key, &leaf); - } else { - zend_hash_index_update(Z_ARR_P(dst), idx, &leaf); - } - } ZEND_HASH_FOREACH_END(); - if (guard) { - Z_UNPROTECT_RECURSION_P(src); - } -} - static void dd_fill_span_data(dd_uhook_def *def, ddtrace_span_data *span) { if (def->name) { zval *name = &span->property_name; @@ -160,10 +124,10 @@ static void dd_fill_span_data(dd_uhook_def *def, ddtrace_span_data *span) { zval_ptr_dtor(service); ZVAL_STR_COPY(service, def->service); if (service_changed) { - zend_array *meta = ddtrace_property_array(&span->property_attributes); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); zval val; ZVAL_NEW_STR(&val, zend_string_init("m", 1, 0)); - zend_hash_str_update(meta, ZEND_STRL("_dd.svc_src"), &val); + zend_hash_str_update(attributes, ZEND_STRL("_dd.svc_src"), &val); } } if (def->type) { @@ -171,21 +135,37 @@ static void dd_fill_span_data(dd_uhook_def *def, ddtrace_span_data *span) { zval_ptr_dtor(type); ZVAL_STR_COPY(type, def->type); } + if (def->component) { + zval *component = &span->property_component; + zval_ptr_dtor(component); + ZVAL_STR_COPY(component, def->component); + } + if (def->has_kind) { + zval *kind = &span->property_span_kind; + zval_ptr_dtor(kind); + ZVAL_LONG(kind, def->kind); + } + zend_string *key; + zval *value; if (def->tags) { - zend_array *meta = ddtrace_property_array(&span->property_attributes); - zend_string *key; - zval *value; ZEND_HASH_FOREACH_STR_KEY_VAL(def->tags, key, value) { if (key) { - zval tag; - dd_uhook_tag_as_meta(&tag, value); - zend_hash_update(meta, key, &tag); + ddtrace_span_write_meta(span, key, value, false); + } + } ZEND_HASH_FOREACH_END(); + } + if (def->attributes) { + zend_array *attributes = ddtrace_property_array(&span->property_attributes); + ZEND_HASH_FOREACH_STR_KEY_VAL(def->attributes, key, value) { + if (key) { + Z_TRY_ADDREF_P(value); + zend_hash_update(attributes, key, value); } } ZEND_HASH_FOREACH_END(); } } -void dd_uhook_fill_args_in_meta(dd_uhook_def *def, HashTable *meta, zend_execute_data *execute_data) { +void dd_uhook_fill_args_in_attributes(dd_uhook_def *def, HashTable *attributes, zend_execute_data *execute_data) { uint32_t num_args = EX_NUM_ARGS(); if (!num_args || !def->args) { @@ -204,7 +184,7 @@ void dd_uhook_fill_args_in_meta(dd_uhook_def *def, HashTable *meta, zend_execute if (!def->arg_whitelist || zend_hash_exists(def->arg_whitelist, arg_name)) { zend_string *arg = zend_strpprintf(0, "arg.%.*s", (int) ZSTR_LEN(arg_name), ZSTR_VAL(arg_name)); zval zv = dd_uhook_save_value(p); - zend_hash_update(meta, arg, &zv); + zend_hash_update(attributes, arg, &zv); zend_string_release(arg); } } @@ -217,7 +197,7 @@ void dd_uhook_fill_args_in_meta(dd_uhook_def *def, HashTable *meta, zend_execute if (!def->arg_whitelist || zend_hash_exists(def->arg_whitelist, arg_name)) { zend_string *arg = zend_strpprintf(0, "arg.%.*s", (int) ZSTR_LEN(arg_name), ZSTR_VAL(arg_name)); zval zv = dd_uhook_save_value(p); - zend_hash_update(meta, arg, &zv); + zend_hash_update(attributes, arg, &zv); zend_string_release(arg); } } @@ -230,7 +210,7 @@ void dd_uhook_fill_args_in_meta(dd_uhook_def *def, HashTable *meta, zend_execute for (zval *end = p + num_args; p < end; ++p) { zend_string *arg = zend_strpprintf(0, "arg.%d", varnum++); zval zv = dd_uhook_save_value(p); - zend_hash_update(meta, arg, &zv); + zend_hash_update(attributes, arg, &zv); zend_string_release(arg); } } @@ -253,7 +233,7 @@ static bool dd_uhook_begin(zend_ulong invocation, zend_execute_data *execute_dat bool new_span; dyn->span = ddtrace_alloc_execute_data_span_ex(invocation, execute_data, &new_span); dd_fill_span_data(def, dyn->span); - dd_uhook_fill_args_in_meta(def, ddtrace_property_array(&dyn->span->property_attributes), execute_data); + dd_uhook_fill_args_in_attributes(def, ddtrace_property_array(&dyn->span->property_attributes), execute_data); if (new_span) { ddtrace_observe_opened_span(dyn->span); } @@ -282,9 +262,9 @@ static void dd_uhook_generator_resumption(zend_ulong invocation, zend_execute_da dyn->span = ddtrace_alloc_execute_data_span_ex(invocation, execute_data, &new_span); dd_fill_span_data(def, dyn->span); if (def->retval) { - zend_array *meta = ddtrace_property_array(&dyn->span->property_attributes); + zend_array *attributes = ddtrace_property_array(&dyn->span->property_attributes); zval val = dd_uhook_save_value(value); - zend_hash_str_update(meta, ZEND_STRL("send_value"), &val); + zend_hash_str_update(attributes, ZEND_STRL("send_value"), &val); } if (new_span) { ddtrace_observe_opened_span(dyn->span); @@ -313,11 +293,11 @@ static void dd_uhook_generator_yield(zend_ulong invocation, zend_execute_data *e dd_trace_stop_span_time(dyn->span); if (def->retval) { - zend_array *meta = ddtrace_property_array(&dyn->span->property_attributes); + zend_array *attributes = ddtrace_property_array(&dyn->span->property_attributes); zval keyzv = dd_uhook_save_value(key); - zend_hash_str_update(meta, ZEND_STRL("yield_key"), &keyzv); + zend_hash_str_update(attributes, ZEND_STRL("yield_key"), &keyzv); zval val = dd_uhook_save_value(value); - zend_hash_str_update(meta, ZEND_STRL("yield_value"), &val); + zend_hash_str_update(attributes, ZEND_STRL("yield_value"), &val); } } @@ -345,9 +325,9 @@ static void dd_uhook_end(zend_ulong invocation, zend_execute_data *execute_data, dd_trace_stop_span_time(dyn->span); if (def->retval) { - zend_array *meta = ddtrace_property_array(&dyn->span->property_attributes); + zend_array *attributes = ddtrace_property_array(&dyn->span->property_attributes); zval val = dd_uhook_save_value(retval); - zend_hash_str_update(meta, ZEND_STRL("return_value"), &val); + zend_hash_str_update(attributes, ZEND_STRL("return_value"), &val); } } @@ -381,12 +361,18 @@ static void dd_uhook_dtor(void *data) { if (def->type) { zend_string_release(def->type); } + if (def->component) { + zend_string_release(def->component); + } if (def->arg_whitelist) { zend_array_release(def->arg_whitelist); } if (def->tags) { zend_array_release(def->tags); } + if (def->attributes) { + zend_array_release(def->attributes); + } efree(def); } @@ -434,6 +420,15 @@ void dd_uhook_on_function_resolve(zend_function *func) { if (!def->type) { def->type = zend_string_copy(Z_STR(value)); } + } else if (zend_string_equals_literal(name, "component") && Z_TYPE(value) == IS_STRING) { + if (!def->component) { + def->component = zend_string_copy(Z_STR(value)); + } + } else if (zend_string_equals_literal(name, "kind") && Z_TYPE(value) == IS_LONG) { + if (!def->has_kind) { + def->has_kind = true; + def->kind = Z_LVAL(value); + } } else if (zend_string_equals_literal(name, "saveArgs")) { if (!def->arg_whitelist) { if (Z_TYPE(value) == IS_ARRAY) { @@ -460,6 +455,14 @@ void dd_uhook_on_function_resolve(zend_function *func) { def->tags = Z_ARR(value); // tags may be an immutable array in opcache's shared memory, e.g. a preloaded class constant GC_TRY_ADDREF(def->tags); + if (zend_hash_num_elements(def->tags)) { + zend_error(E_DEPRECATED, "DDTrace\\Trace: $tags is deprecated, use $attributes instead"); + } + } + } else if (zend_string_equals_literal(name, "attributes") && Z_TYPE(value) == IS_ARRAY) { + if (!def->attributes) { + def->attributes = Z_ARR(value); + GC_TRY_ADDREF(def->attributes); } } diff --git a/tracer/hook/uhook_attributes.stub.php b/tracer/hook/uhook_attributes.stub.php index e8e699acbf5..f03bc7a1e8a 100644 --- a/tracer/hook/uhook_attributes.stub.php +++ b/tracer/hook/uhook_attributes.stub.php @@ -18,12 +18,18 @@ final class Trace { * @param string $resource The resource to be assigned to the span. * @param string $type The type to be assigned to the span. * @param string $service The service to be assigned to the span. Defaults to default or inherited service name. - * @param array $tags The tags to be assigned to the span. - * @param bool|array $saveArgs Whether arguments shall be saved as tags on the span. True to save them all. + * @param array $tags Deprecated, use $attributes. The tags to be assigned to the span, as if written to + * SpanData::$meta. + * @param bool|array $saveArgs Whether arguments shall be saved as attributes on the span. True to save them all. * False to save none. An array with parameter names to save only select ones. * @param bool $saveReturn Whether to save return values (including yielded values on generators) on the span. * @param bool $recurse Whether recursive calls shall be traced. * @param bool $run_if_limited Whether the function shall be traced in limited mode. (E.g. when span limit exceeded) + * @param array $attributes The attributes to be merged into SpanData::$attributes as is. They are raw: keys + * like "component" or "span.kind" do not set the dedicated span fields, use the + * other parameters for these. + * @param int|null $kind The span kind, a DDTrace\SpanKind constant. + * @param string|null $component The component to be assigned to the span. */ public function __construct( string $name = "", @@ -36,7 +42,10 @@ public function __construct( bool $saveReturn = false, */ bool $recurse = true, - bool $run_if_limited = false + bool $run_if_limited = false, + array $attributes = [], + ?int $kind = null, + ?string $component = null ) {} } } diff --git a/tracer/hook/uhook_attributes_arginfo.h b/tracer/hook/uhook_attributes_arginfo.h index fb6596cb009..6e608e5a2e1 100644 --- a/tracer/hook/uhook_attributes_arginfo.h +++ b/tracer/hook/uhook_attributes_arginfo.h @@ -1,5 +1,7 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 39cf4bf2cf4b4ec1c18f3ff8643b3ba7b4ad69a1 */ +/* This is a generated file, edit uhook_attributes.stub.php instead. + * Stub hash: 9f833ba566426979c9ee7ec5c22dcd2f7053cc1d */ + +#include "zend_attributes.h" ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DDTrace_Trace___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, name, IS_STRING, 0, "\"\"") @@ -9,6 +11,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DDTrace_Trace___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tags, IS_ARRAY, 0, "[]") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, recurse, _IS_BOOL, 0, "true") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, run_if_limited, _IS_BOOL, 0, "false") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, attributes, IS_ARRAY, 0, "[]") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, kind, IS_LONG, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, component, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_METHOD(DDTrace_Trace, __construct); @@ -25,12 +30,10 @@ static zend_class_entry *register_class_DDTrace_Trace(void) INIT_NS_CLASS_ENTRY(ce, "DDTrace", "Trace", class_DDTrace_Trace_methods); class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); - zend_string *attribute_name_Attribute_class_DDTrace_Trace_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); + zend_string *attribute_name_Attribute_class_DDTrace_Trace_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, true); zend_attribute *attribute_Attribute_class_DDTrace_Trace_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_DDTrace_Trace_0, 1); - zend_string_release(attribute_name_Attribute_class_DDTrace_Trace_0); - zval attribute_Attribute_class_DDTrace_Trace_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_DDTrace_Trace_0_arg0, ZEND_ATTRIBUTE_TARGET_FUNCTION | ZEND_ATTRIBUTE_TARGET_METHOD); - ZVAL_COPY_VALUE(&attribute_Attribute_class_DDTrace_Trace_0->args[0].value, &attribute_Attribute_class_DDTrace_Trace_0_arg0); + zend_string_release_ex(attribute_name_Attribute_class_DDTrace_Trace_0, true); + ZVAL_LONG(&attribute_Attribute_class_DDTrace_Trace_0->args[0].value, ZEND_ATTRIBUTE_TARGET_FUNCTION | ZEND_ATTRIBUTE_TARGET_METHOD); return class_entry; } diff --git a/tracer/integrations/exec_integration.c b/tracer/integrations/exec_integration.c index 92e26a3bab5..ef017f8713d 100644 --- a/tracer/integrations/exec_integration.c +++ b/tracer/integrations/exec_integration.c @@ -94,16 +94,15 @@ static int dd_php_stdiop_close_wrapper(php_stream *stream, int close_handle) { ddtrace_span_data *span_data = OBJ_SPANDATA(Z_OBJ_P(span_data_zv)); - zend_array *meta = ddtrace_property_array(&span_data->property_attributes); + zend_array *attributes = ddtrace_property_array(&span_data->property_attributes); if (ret == -1) { zval zv; ZVAL_INTERNED_STR(&zv, pclose_minus_one_zstr); - zend_hash_update(meta, error_message_zstr, &zv); + zend_hash_update(attributes, error_message_zstr, &zv); } else { - // A string, as the tag was when it lived in meta. zval zexit; - ZVAL_STR(&zexit, zend_long_to_str(ret)); - zend_hash_update(meta, cmd_exit_code_zstr, &zexit); + ZVAL_LONG(&zexit, ret); + zend_hash_update(attributes, cmd_exit_code_zstr, &zexit); } dd_trace_stop_span_time(span_data); @@ -138,7 +137,7 @@ static void dd_waitpid(ddtrace_span_data *span_data, dd_proc_span *proc) { // already closed return; } - zend_array *meta = ddtrace_property_array(&span_data->property_attributes); + zend_array *attributes = ddtrace_property_array(&span_data->property_attributes); int wstatus; bool exited = false; @@ -177,17 +176,17 @@ static void dd_waitpid(ddtrace_span_data *span_data, dd_proc_span *proc) { // that's how PHP does it in the return value of proc_open zval has_signalled_zv; ZVAL_INTERNED_STR(&has_signalled_zv, has_signalled_zstr); - zend_hash_update(meta, error_message_zstr, &has_signalled_zv); + zend_hash_update(attributes, error_message_zstr, &has_signalled_zv); exited = true; } // else !FG(pclose_wait) and it hasn't finished #endif if (exited) { zval zexit; - ZVAL_STR(&zexit, zend_long_to_str(wstatus)); + ZVAL_LONG(&zexit, wstatus); // set tag 'cmd.exit_code' - zend_hash_update(meta, cmd_exit_code_zstr, &zexit); + zend_hash_update(attributes, cmd_exit_code_zstr, &zexit); } } diff --git a/tracer/integrations/integrations.c b/tracer/integrations/integrations.c index c955e91b67f..099ff778320 100644 --- a/tracer/integrations/integrations.c +++ b/tracer/integrations/integrations.c @@ -37,8 +37,6 @@ static bool is_filesystem_enabled() { return get_DD_TRACE_FILESYSTEM_ENABLED() & .name_lcase = (lcname), \ .name_len = sizeof(lcname) - 1, \ .is_enabled = is_enabled_func, \ - .is_analytics_enabled = get_DD_TRACE_##id##_ANALYTICS_ENABLED, \ - .get_sample_rate = get_DD_TRACE_##id##_ANALYTICS_SAMPLE_RATE, \ .aux = {0}, \ }, ddtrace_integration ddtrace_integrations[] = {DD_INTEGRATIONS}; diff --git a/tracer/integrations/integrations.h b/tracer/integrations/integrations.h index 835cce9ab9b..60d8e570379 100644 --- a/tracer/integrations/integrations.h +++ b/tracer/integrations/integrations.h @@ -66,8 +66,6 @@ struct ddtrace_integration { char *name_lcase; size_t name_len; bool (*is_enabled)(void); - bool (*is_analytics_enabled)(void); - double (*get_sample_rate)(void); void *aux[10]; // Needs to be the max number of deferred loading hooks for any integration plus one NULL sentinel }; typedef struct ddtrace_integration ddtrace_integration; diff --git a/tracer/ip_extraction.c b/tracer/ip_extraction.c index 858a8e1cb57..683a03f351f 100644 --- a/tracer/ip_extraction.c +++ b/tracer/ip_extraction.c @@ -213,7 +213,7 @@ static zend_string *dd_fetch_arr_str(const zval *server, zend_string *key) { return Z_STR_P(value); } -void ddtrace_extract_ip_from_headers(zval *server, zend_array *meta) +void ddtrace_extract_ip_from_headers(zval *server, zend_array *attributes) { zend_string *val = ddtrace_ip_extraction_find(server); if (!val) { @@ -221,7 +221,7 @@ void ddtrace_extract_ip_from_headers(zval *server, zend_array *meta) } zval http_client_ip; ZVAL_STR(&http_client_ip, val); - zend_hash_str_update(meta, ZEND_STRL("http.client_ip"), &http_client_ip); + zend_hash_str_update(attributes, ZEND_STRL("http.client_ip"), &http_client_ip); } static zend_string *dd_ipaddr_to_zstr(const ipaddr *ipaddr) { diff --git a/tracer/ip_extraction.h b/tracer/ip_extraction.h index a542e0c2abc..c9c7b2e5583 100644 --- a/tracer/ip_extraction.h +++ b/tracer/ip_extraction.h @@ -8,6 +8,6 @@ void ddtrace_ip_extraction_startup(void); bool ddtrace_parse_client_ip_header_config(zai_str value, zval *decoded_value, bool persistent); zend_string *ddtrace_ip_extraction_find(zval *server); -void ddtrace_extract_ip_from_headers(zval *server, zend_array *meta); +void ddtrace_extract_ip_from_headers(zval *server, zend_array *attributes); #endif diff --git a/tracer/live_debugger.c b/tracer/live_debugger.c index 253cb6cb643..add5f525b5d 100644 --- a/tracer/live_debugger.c +++ b/tracer/live_debugger.c @@ -500,7 +500,7 @@ static void dd_span_decoration_end(zend_ulong invocation, zend_execute_data *exe if (def->probe.probe.span_decoration.target == DDOG_SPAN_PROBE_TARGET_ROOT) { span = &span->stack->root_span->span; } - zend_array *meta = ddtrace_property_array(&span->property_attributes); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); bool condition_result = true; const ddog_ProbeCondition *const *condition = def->probe.probe.span_decoration.conditions; @@ -523,11 +523,11 @@ static void dd_span_decoration_end(zend_ulong invocation, zend_execute_data *exe ddog_Vec_SnapshotEvaluationError *error; ddog_CaptureConfiguration config_defaults = ddog_capture_defaults(); ZVAL_STR(&zv, dd_eval_string(spanTag->tag.value, &config_defaults, retval, &error)); - zend_hash_str_update(meta, spanTag->tag.name.ptr, spanTag->tag.name.len, &zv); + zend_hash_str_update(attributes, spanTag->tag.name.ptr, spanTag->tag.name.len, &zv); zend_string *tag = zend_strpprintf(0, "_dd.di.%.*s.probe_id", (int)spanTag->tag.name.len, spanTag->tag.name.ptr); ZVAL_STR_COPY(&zv, def->probe_id); - zend_hash_update(meta, tag, &zv); + zend_hash_update(attributes, tag, &zv); zend_string_release(tag); if (error) { @@ -535,7 +535,7 @@ static void dd_span_decoration_end(zend_ulong invocation, zend_execute_data *exe tag = zend_strpprintf(0, "_dd.di.%.*s.evaluation_error", (int)spanTag->tag.name.len, spanTag->tag.name.ptr); ZVAL_STR(&zv, dd_CharSlice_to_zend_string(msg)); - zend_hash_update(meta, tag, &zv); + zend_hash_update(attributes, tag, &zv); zend_string_release(tag); ddog_evaluation_error_drop(error); diff --git a/tracer/priority_sampling/priority_sampling.c b/tracer/priority_sampling/priority_sampling.c index 97c8557d5fd..54c6f0e04ec 100644 --- a/tracer/priority_sampling/priority_sampling.c +++ b/tracer/priority_sampling/priority_sampling.c @@ -45,14 +45,8 @@ void ddtrace_try_read_agent_rate(void) { } } -static void dd_del_root_tag(ddtrace_root_span_data *root_span, const char *key, size_t len) { - zend_hash_str_del(ddtrace_property_array(&root_span->property_attributes), key, len); -} - -static void dd_update_decision_maker_tag(ddtrace_root_span_data *root_span, +static void dd_update_decision_maker_attribute(ddtrace_root_span_data *root_span, zend_array *attributes, enum dd_sampling_mechanism mechanism) { - zend_array *attributes = ddtrace_property_array(&root_span->property_attributes); - zend_long sampling_priority = zval_get_long(&root_span->property_sampling_priority); if (Z_TYPE(root_span->property_propagated_sampling_priority) != IS_UNDEF && zval_get_long(&root_span->property_propagated_sampling_priority) == sampling_priority) { @@ -65,13 +59,11 @@ static void dd_update_decision_maker_tag(ddtrace_root_span_data *root_span, zend_hash_str_update(attributes, ZEND_STRL("_dd.p.dm"), &dm); zend_hash_str_add_empty_element(ddtrace_property_array(&root_span->property_propagated_tags), ZEND_STRL("_dd.p.dm")); } else { - dd_del_root_tag(root_span, ZEND_STRL("_dd.p.dm")); + zend_hash_str_del(attributes, ZEND_STRL("_dd.p.dm")); } } -static void dd_update_knuth_sampling_rate_tag(ddtrace_root_span_data *root_span, double sample_rate) { - zend_array *attributes = ddtrace_property_array(&root_span->property_attributes); - +static void dd_update_knuth_sampling_rate_attribute(ddtrace_root_span_data *root_span, zend_array *attributes, double sample_rate) { char buf[32]; #if PHP_VERSION_ID < 80100 int is_negative; @@ -162,7 +154,7 @@ static ddtrace_rule_result dd_match_rules(ddtrace_span_data *span, bool eval_roo return (ddtrace_rule_result){ .sampling_rate = 0, .rule = INT32_MAX, .mechanism = DD_MECHANISM_RULE }; } - if (ddtrace_span_find_tag(span, ZEND_STRL("manual.keep"))) { + if (zend_hash_str_find(ddtrace_property_array(&span->property_attributes), ZEND_STRL("manual.keep"))) { // manual.keep and manual.drop count as manual return (ddtrace_rule_result){ .sampling_rate = 1, .rule = -2, .mechanism = DD_MECHANISM_MANUAL }; } @@ -170,7 +162,7 @@ static ddtrace_rule_result dd_match_rules(ddtrace_span_data *span, bool eval_roo if (++index >= skip_at) { return (ddtrace_rule_result){ .sampling_rate = 0, .rule = INT32_MAX, .mechanism = DD_MECHANISM_RULE }; } - if (ddtrace_span_find_tag(span, ZEND_STRL("manual.drop"))) { + if (zend_hash_str_find(ddtrace_property_array(&span->property_attributes), ZEND_STRL("manual.drop"))) { return (ddtrace_rule_result){ .sampling_rate = 0, .rule = -1, .mechanism = DD_MECHANISM_MANUAL }; } @@ -267,6 +259,7 @@ static void dd_decide_on_sampling(ddtrace_root_span_data *span) { int priority; bool is_trace_root = !span->parent_id; enum dd_sampling_mechanism mechanism; + zend_array *attributes = ddtrace_property_array(&span->property_attributes); ddtrace_rule_result result = dd_decide_on_open_span_sampling(span); double sample_rate = 0; @@ -286,10 +279,7 @@ static void dd_decide_on_sampling(ddtrace_root_span_data *span) { } else { explicit_rule = false; - zval *env = ddtrace_span_find_tag(&span->span, ZEND_STRL("env")); - if (!env) { - env = &span->property_env; - } + zval *env = &span->property_env; ddtrace_try_read_agent_rate(); // if we have an empty env... we can default to the cluster env. @@ -334,7 +324,7 @@ static void dd_decide_on_sampling(ddtrace_root_span_data *span) { ddtrace_otel_update_trace_flags(span); #endif } - dd_del_root_tag(span, ZEND_STRL("_dd.p.ksr")); + zend_hash_str_del(attributes, ZEND_STRL("_dd.p.ksr")); return; } else { sample_rate = result.sampling_rate; @@ -359,20 +349,19 @@ static void dd_decide_on_sampling(ddtrace_root_span_data *span) { zval sample_rate_zv; ZVAL_DOUBLE(&sample_rate_zv, sample_rate); - zend_array *attributes = ddtrace_property_array(&span->property_attributes); if (explicit_rule) { mechanism = result.mechanism; priority = sampling && !limited ? PRIORITY_SAMPLING_USER_KEEP : PRIORITY_SAMPLING_USER_REJECT; if (mechanism == DD_MECHANISM_MANUAL) { - dd_del_root_tag(span, ZEND_STRL("_dd.rule_psr")); - dd_del_root_tag(span, ZEND_STRL("_dd.p.ksr")); + zend_hash_str_del(attributes, ZEND_STRL("_dd.rule_psr")); + zend_hash_str_del(attributes, ZEND_STRL("_dd.p.ksr")); } else { zend_hash_str_update(attributes, ZEND_STRL("_dd.rule_psr"), &sample_rate_zv); - dd_update_knuth_sampling_rate_tag(span, sample_rate); + dd_update_knuth_sampling_rate_attribute(span, attributes, sample_rate); } - dd_del_root_tag(span, ZEND_STRL("_dd.agent_psr")); + zend_hash_str_del(attributes, ZEND_STRL("_dd.agent_psr")); } else { // manual if it's not just inherited, otherwise this value is irrelevant (as sampling priority will be default) mechanism = DDTRACE_G(agent_rate_by_service) ? DD_MECHANISM_AGENT_RATE : DD_MECHANISM_DEFAULT; @@ -380,9 +369,9 @@ static void dd_decide_on_sampling(ddtrace_root_span_data *span) { zend_hash_str_update(attributes, ZEND_STRL("_dd.agent_psr"), &sample_rate_zv); if (mechanism == DD_MECHANISM_AGENT_RATE) { - dd_update_knuth_sampling_rate_tag(span, sample_rate); + dd_update_knuth_sampling_rate_attribute(span, attributes, sample_rate); } else { - dd_del_root_tag(span, ZEND_STRL("_dd.p.ksr")); + zend_hash_str_del(attributes, ZEND_STRL("_dd.p.ksr")); } } @@ -404,7 +393,7 @@ static void dd_decide_on_sampling(ddtrace_root_span_data *span) { #ifdef __linux__ ddtrace_otel_update_trace_flags(span); #endif - dd_update_decision_maker_tag(span, mechanism); + dd_update_decision_maker_attribute(span, attributes, mechanism); } zend_long ddtrace_fetch_priority_sampling_from_root(void) { @@ -457,7 +446,7 @@ void ddtrace_set_priority_sampling_on_span(ddtrace_root_span_data *root_span, ze #endif if (priority != DDTRACE_PRIORITY_SAMPLING_UNKNOWN) { - dd_update_decision_maker_tag(root_span, mechanism); + dd_update_decision_maker_attribute(root_span, ddtrace_property_array(&root_span->property_attributes), mechanism); // Default is never explicit - e.g. distributed tracing. root_span->explicit_sampling_priority = mechanism != DD_MECHANISM_DEFAULT; if (mechanism != DD_MECHANISM_DEFAULT) { diff --git a/tracer/serializer.c b/tracer/serializer.c index e4c41ea2546..a51ee6fbeb0 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -296,26 +296,26 @@ static zend_string *dd_fatal_error_stack(void) { return error_stack; } -static int dd_fatal_error_to_meta(zend_array *meta, dd_error_info error) { +static int dd_fatal_error_to_attributes(zend_array *attributes, dd_error_info error) { if (error.type) { zval tmp = ddtrace_zval_zstr(zend_string_copy(error.type)); - zend_symtable_str_update(meta, ZEND_STRL("error.type"), &tmp); + zend_symtable_str_update(attributes, ZEND_STRL("error.type"), &tmp); } if (error.msg) { zval tmp = ddtrace_zval_zstr(zend_string_copy(error.msg)); - zend_symtable_str_update(meta, ZEND_STRL("error.message"), &tmp); + zend_symtable_str_update(attributes, ZEND_STRL("error.message"), &tmp); } if (error.stack) { zval tmp = ddtrace_zval_zstr(zend_string_copy(error.stack)); - zend_symtable_str_update(meta, ZEND_STRL("error.stack"), &tmp); + zend_symtable_str_update(attributes, ZEND_STRL("error.stack"), &tmp); } return error.type && error.msg ? SUCCESS : FAILURE; } -static void dd_add_header_to_meta(zend_array *meta, const char *type, zend_string *lowerheader, +static void dd_add_header_to_attributes(zend_array *attributes, 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) { @@ -333,19 +333,19 @@ static void dd_add_header_to_meta(zend_array *meta, const char *type, zend_strin } zval headerzv; ZVAL_STR_COPY(&headerzv, headerval); - zend_hash_update(meta, headertag, &headerzv); + zend_hash_update(attributes, headertag, &headerzv); zend_string_release(headertag); } } -void dd_span_attr_str(ddog_SpanNode *span, const char *key, const char *val) { +void dd_span_attr_str(ddog_SpanBytes *span, const char *key, const char *val) { ddog_attributes_add_lit(ddog_span_get_attributes(span), key, (ddog_CharSlice){ .ptr = val, .len = strlen(val) }); } -void dd_span_attr_zstr(ddog_SpanNode *span, const char *key, zend_string *val) { +void dd_span_attr_zstr(ddog_SpanBytes *span, const char *key, zend_string *val) { ddog_attributes_add_lit(ddog_span_get_attributes(span), key, dd_zend_string_to_CharSlice(val)); } -static void dd_add_header_to_rust_span(ddog_SpanNode *span, const char *type, zend_string *lowerheader, +static void dd_add_header_to_rust_span(ddog_SpanBytes *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) { @@ -379,15 +379,15 @@ static void normalize_with_underscores(zend_string *str) { } } -static void dd_add_post_fields_to_meta(zend_array *meta, const char *type, zend_string *postkey, zend_string *postval) { +static void dd_add_post_fields_to_attributes(zend_array *attributes, const char *type, zend_string *postkey, zend_string *postval) { zend_string *posttag = zend_strpprintf(0, "http.%s.post.%s", type, ZSTR_VAL(postkey)); zval postzv; ZVAL_STR_COPY(&postzv, postval); - zend_hash_update(meta, posttag, &postzv); + zend_hash_update(attributes, posttag, &postzv); zend_string_release(posttag); } -static void dd_add_post_fields_to_meta_recursive(zend_array *meta, const char *type, zend_string *postkey, +static void dd_add_post_fields_to_attributes_recursive(zend_array *attributes, const char *type, zend_string *postkey, zval *postval, zend_array* post_whitelist, bool is_prefixed) { if (Z_TYPE_P(postval) == IS_ARRAY) { @@ -400,12 +400,12 @@ static void dd_add_post_fields_to_meta_recursive(zend_array *meta, const char *t zend_string *copy_key = zend_string_dup(key, 0); normalize_with_underscores(copy_key); if (ZSTR_LEN(postkey) == 0) { - dd_add_post_fields_to_meta_recursive(meta, type, copy_key, val, post_whitelist, + dd_add_post_fields_to_attributes_recursive(attributes, type, copy_key, val, post_whitelist, is_prefixed || zend_hash_exists(post_whitelist, copy_key)); } else { // If the current postkey is not the empty string, we want to add a '.' to the beginning of the key zend_string *newkey = zend_strpprintf(0, "%s.%s", ZSTR_VAL(postkey), ZSTR_VAL(copy_key)); - dd_add_post_fields_to_meta_recursive(meta, type, newkey, val, post_whitelist, + dd_add_post_fields_to_attributes_recursive(attributes, type, newkey, val, post_whitelist, is_prefixed || zend_hash_exists(post_whitelist, newkey)); zend_string_release(newkey); } @@ -413,7 +413,7 @@ static void dd_add_post_fields_to_meta_recursive(zend_array *meta, const char *t } else { // Use numeric index if there isn't a string key zend_string *newkey = zend_strpprintf(0, "%s." ZEND_LONG_FMT, ZSTR_VAL(postkey), index); - dd_add_post_fields_to_meta_recursive(meta, type, newkey, val, post_whitelist, + dd_add_post_fields_to_attributes_recursive(attributes, type, newkey, val, post_whitelist, is_prefixed || zend_hash_exists(post_whitelist, newkey)); zend_string_release(newkey); } @@ -421,9 +421,9 @@ static void dd_add_post_fields_to_meta_recursive(zend_array *meta, const char *t ZEND_HASH_FOREACH_END(); } else { if (is_prefixed) { // The postkey is in the whitelist or is prefixed by a key in the whitelist - // we want to add it to the meta as is + // we want to add it to the attributes as is zend_string *ztr_postval = zval_get_string(postval); - dd_add_post_fields_to_meta(meta, type, postkey, ztr_postval); + dd_add_post_fields_to_attributes(attributes, type, postkey, ztr_postval); zend_string_release(ztr_postval); } else if (post_whitelist) { zend_string *str; @@ -438,42 +438,40 @@ static void dd_add_post_fields_to_meta_recursive(zend_array *meta, const char *t // Match it with the regex to redact if needed if (zai_match_regex(get_DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP(), postvalconcat)) { zend_string *replacement = zend_string_init(ZEND_STRL(""), 0); - dd_add_post_fields_to_meta(meta, type, postkey, replacement); + dd_add_post_fields_to_attributes(attributes, type, postkey, replacement); zend_string_release(replacement); } else { - dd_add_post_fields_to_meta(meta, type, postkey, postvalstr); + dd_add_post_fields_to_attributes(attributes, type, postkey, postvalstr); } zend_string_release(postvalconcat); } else { // No wildcard and the postkey isn't in the whitelist // Always use "" as the value zend_string *replacement = zend_string_init(ZEND_STRL(""), 0); - dd_add_post_fields_to_meta(meta, type, postkey, replacement); + dd_add_post_fields_to_attributes(attributes, type, postkey, replacement); zend_string_release(replacement); } } else { // No whitelist, so we always use "" as the value zend_string *replacement = zend_string_init(ZEND_STRL(""), 0); - dd_add_post_fields_to_meta(meta, type, postkey, replacement); + dd_add_post_fields_to_attributes(attributes, type, postkey, replacement); zend_string_release(replacement); } } } void ddtrace_set_global_span_properties(ddtrace_span_data *span) { - zend_array *meta = ddtrace_property_array(&span->property_attributes); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); zend_array *global_tags = get_DD_TAGS(); zend_string *global_key; zval *global_val; - zval *prop_env = &span->property_env; - zval *prop_version = &span->property_version; + // DD_TAGS env/version are the root's property fallback (ddtrace_set_root_span_properties). ZEND_HASH_FOREACH_STR_KEY_VAL(global_tags, global_key, global_val) { - if ((zend_string_equals_literal(global_key, "env") && Z_TYPE_P(prop_env) == IS_STRING && Z_STRLEN_P(prop_env) > 0) || - (zend_string_equals_literal(global_key, "version") && Z_TYPE_P(prop_version) == IS_STRING && Z_STRLEN_P(prop_version) > 0) || + if (zend_string_equals_literal(global_key, "env") || zend_string_equals_literal(global_key, "version") || zend_string_equals_literal(global_key, "service")) { continue; } - if (zend_hash_add(meta, global_key, global_val)) { + if (zend_hash_add(attributes, global_key, global_val)) { Z_TRY_ADDREF_P(global_val); } } @@ -482,7 +480,7 @@ void ddtrace_set_global_span_properties(ddtrace_span_data *span) { zend_string *tag_key; zval *tag_value; ZEND_HASH_FOREACH_STR_KEY_VAL(DDTRACE_G(additional_global_tags), tag_key, tag_value) { - if (zend_hash_add(meta, tag_key, tag_value)) { + if (zend_hash_add(attributes, tag_key, tag_value)) { Z_TRY_ADDREF_P(tag_value); } } @@ -593,7 +591,7 @@ static zend_string *dd_get_referrer_host(zend_array *_server) { return ZSTR_EMPTY_ALLOC(); } -static bool dd_set_mapped_peer_service(ddog_SpanNode *span, zend_string *peer_service) { +static bool dd_set_mapped_peer_service(ddog_SpanBytes *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; @@ -659,20 +657,15 @@ static void dd_set_entrypoint_root_span_props(struct superglob_equiv *data, ddtr zend_hash_str_add_new(attributes, ZEND_STRL("http.method"), &http_method); // Mark HTTP server entry spans with span.kind=server for client-side stats aggregation. - // Written as a tag 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(attributes, ZEND_STRL("span.kind"), &span_kind_server)) { - zval_ptr_dtor(&span_kind_server); - } - - // Default component to the SAPI (the server integration layer), add-if-absent so frameworks override it. - if (strcmp(sapi_module.name, "cli") != 0) { - zval component; - ZVAL_STRING(&component, sapi_module.name); - if (!zend_hash_str_add(attributes, ZEND_STRL("component"), &component)) { - zval_ptr_dtor(&component); - } + if (zval_get_long(&span->property_span_kind) == DDTRACE_SPAN_KIND_UNSPECIFIED) { + ZVAL_LONG(&span->property_span_kind, DDTRACE_SPAN_KIND_SERVER); + } + + // Default component of web root spans; frameworks override it. + zval *component = &span->property_component; + if (strcmp(sapi_module.name, "cli") != 0 && Z_TYPE_P(component) == IS_STRING && !Z_STRLEN_P(component)) { + zval_ptr_dtor(component); + ZVAL_STRING(component, "web"); } if (get_DD_TRACE_URL_AS_RESOURCE_NAMES_ENABLED()) { @@ -736,7 +729,7 @@ static void dd_set_entrypoint_root_span_props(struct superglob_equiv *data, ddtr } } - dd_add_header_to_meta(attributes, "request", lowerheader, Z_STR_P(headerval)); + dd_add_header_to_attributes(attributes, "request", lowerheader, Z_STR_P(headerval)); zend_string_release(lowerheader); } } @@ -747,7 +740,7 @@ static void dd_set_entrypoint_root_span_props(struct superglob_equiv *data, ddtr zval post_zv; ZVAL_ARR(&post_zv, data->post); zend_string *empty = ZSTR_EMPTY_ALLOC(); - dd_add_post_fields_to_meta_recursive(attributes, "request", empty, &post_zv, get_DD_TRACE_HTTP_POST_DATA_PARAM_ALLOWED(), false); + dd_add_post_fields_to_attributes_recursive(attributes, "request", empty, &post_zv, get_DD_TRACE_HTTP_POST_DATA_PARAM_ALLOWED(), false); zend_string_release(empty); } } @@ -764,36 +757,20 @@ void ddtrace_inherit_span_properties(ddtrace_span_data *span, ddtrace_span_data zval_ptr_dtor(prop_baggage); ZVAL_COPY_DEREF(prop_baggage, prop_parent_baggage); - zval *parent_svc_src = ddtrace_span_find_tag(parent, ZEND_STRL("_dd.svc_src")); + zval *parent_svc_src = zend_hash_str_find(ddtrace_property_array(&parent->property_attributes), ZEND_STRL("_dd.svc_src")); if (parent_svc_src) { - zend_array *child_meta = ddtrace_property_array(&span->property_attributes); + zend_array *child_attributes = ddtrace_property_array(&span->property_attributes); Z_TRY_ADDREF_P(parent_svc_src); - zend_hash_str_update(child_meta, ZEND_STRL("_dd.svc_src"), parent_svc_src); + zend_hash_str_update(child_attributes, ZEND_STRL("_dd.svc_src"), parent_svc_src); } zval *prop_version = &span->property_version; zval_ptr_dtor(prop_version); - zval *version; - if ((version = ddtrace_span_find_tag(parent, ZEND_STRL("version")))) { - zval old = *version; - datadog_convert_to_string(version, version); - zval_ptr_dtor(&old); - } else { - version = &parent->property_version; - } - ZVAL_COPY_DEREF(prop_version, version); + ZVAL_COPY_DEREF(prop_version, &parent->property_version); zval *prop_env = &span->property_env; zval_ptr_dtor(prop_env); - zval *env; - if ((env = ddtrace_span_find_tag(parent, ZEND_STRL("env")))) { - zval old = *env; - datadog_convert_to_string(env, env); - zval_ptr_dtor(&old); - } else { - env = &parent->property_env; - } - ZVAL_COPY_DEREF(prop_env, env); + ZVAL_COPY_DEREF(prop_env, &parent->property_env); } zend_string *ddtrace_active_service_name(void) { @@ -846,29 +823,6 @@ void ddtrace_set_root_span_properties(ddtrace_root_span_data *span) { dd_set_entrypoint_root_span_props(&data, span); } - if (get_DD_TRACE_REPORT_HOSTNAME()) { - if (ZSTR_LEN(get_DD_HOSTNAME())) { - zval hostname_zv; - ZVAL_STR_COPY(&hostname_zv, get_DD_HOSTNAME()); - zend_hash_str_update(attributes, ZEND_STRL("_dd.hostname"), &hostname_zv); - } else { - -#ifndef HOST_NAME_MAX -#define HOST_NAME_MAX 255 -#endif - - zend_string *hostname = zend_string_alloc(HOST_NAME_MAX, 0); - if (gethostname(ZSTR_VAL(hostname), HOST_NAME_MAX + 1)) { - zend_string_release(hostname); - } else { - hostname = zend_string_truncate(hostname, strlen(ZSTR_VAL(hostname)), 0); - zval hostname_zv; - ZVAL_STR(&hostname_zv, hostname); - zend_hash_str_update(attributes, ZEND_STRL("_dd.hostname"), &hostname_zv); - } - } - } - ddtrace_root_span_data *parent_root = span->stack->parent_stack->root_span; if (parent_root) { ddtrace_inherit_span_properties(&span->span, &parent_root->span); @@ -894,16 +848,25 @@ void ddtrace_set_root_span_properties(ddtrace_root_span_data *span) { ZVAL_STR_COPY(prop_service, ZSTR_LEN(get_DD_SERVICE()) ? get_DD_SERVICE() : Z_STR_P(prop_name)); + // DD_VERSION/DD_ENV, else the DD_TAGS version/env. zend_string *version = get_DD_VERSION(); + zval *version_tag = zend_hash_str_find(get_DD_TAGS(), ZEND_STRL("version")); if (ZSTR_LEN(version) > 0) { // non-empty zval_ptr_dtor(prop_version); ZVAL_STR_COPY(prop_version, version); + } else if (version_tag && Z_TYPE_P(version_tag) == IS_STRING) { + zval_ptr_dtor(prop_version); + ZVAL_COPY(prop_version, version_tag); } zend_string *env = get_DD_ENV(); + zval *env_tag = zend_hash_str_find(get_DD_TAGS(), ZEND_STRL("env")); if (ZSTR_LEN(env) > 0) { // non-empty zval_ptr_dtor(prop_env); ZVAL_STR_COPY(prop_env, env); + } else if (env_tag && Z_TYPE_P(env_tag) == IS_STRING) { + zval_ptr_dtor(prop_env); + ZVAL_COPY(prop_env, env_tag); } if (DDTRACE_G(dd_origin)) { @@ -942,7 +905,7 @@ void ddtrace_set_root_span_properties(ddtrace_root_span_data *span) { } zval pid; - ZVAL_DOUBLE(&pid, (double)getpid()); + ZVAL_LONG(&pid, (zend_long)getpid()); zend_hash_str_update(attributes, ZEND_STRL("process_id"), &pid); } @@ -1014,15 +977,14 @@ static inline bool dd_native_is_hidden_member(zend_string *str_key) { // // One emitter fills every attribute map (span, link, event, nested map): scalars keep their PHP type, // arrays/objects nest as a List/KeyValue (objects as a map of their public properties), and a -// reference cycle becomes the "" leaf. The top-level flags keep each node's v0.4-parity differences. +// reference cycle becomes the "*RECURSION*" leaf, as in var_dump. The top-level flags set each node's form. #define DD_ATTR_TOP (1 << 0) // top-level entry: empty keys are skipped #define DD_ATTR_NULL_AS_STRING (1 << 1) // null is the "null" string (links, events), not skipped -#define DD_ATTR_EMPTY_ARRAY_AS_STRING (1 << 2) // an empty array is the "" tag (spans: no v0.4 form) -#define DD_ATTR_SCALARS_AS_STRINGS (1 << 3) // scalars are strings (links) +#define DD_ATTR_EMPTY_ARRAY_AS_STRING (1 << 2) // an empty array is the "" tag (spans) #define DD_ATTR_SPAN (DD_ATTR_TOP | DD_ATTR_EMPTY_ARRAY_AS_STRING) #define DD_ATTR_EVENT (DD_ATTR_TOP | DD_ATTR_NULL_AS_STRING) -#define DD_ATTR_LINK (DD_ATTR_TOP | DD_ATTR_NULL_AS_STRING | DD_ATTR_SCALARS_AS_STRINGS) +#define DD_ATTR_LINK (DD_ATTR_TOP | DD_ATTR_NULL_AS_STRING) static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string *zkey, zval *value, int flags); static void dd_attr_emit_list(ddog_AttrList *dest, zval *value); @@ -1061,11 +1023,6 @@ static ddog_AttrMap *dd_attr_build_map(zval *value) { return map; } -// String form of a scalar leaf (null -> "null"). -static zend_string *dd_native_typed_str(zval *value) { - return datadog_convert_to_str(value); -} - // Emits one list element, preserving the PHP scalar type (nested nulls are skipped). static void dd_attr_emit_list(ddog_AttrList *dest, zval *value) { ZVAL_DEREF(value); @@ -1073,7 +1030,7 @@ static void dd_attr_emit_list(ddog_AttrList *dest, zval *value) { case IS_ARRAY: case IS_OBJECT: if (Z_IS_RECURSIVE_P(value)) { - ddog_attr_list_push_str(dest, DDOG_CHARSLICE_C("")); + ddog_attr_list_push_str(dest, DDOG_CHARSLICE_C("*RECURSION*")); } else if (dd_native_is_list(value)) { ddog_attr_list_push_list(dest, dd_attr_build_list(value)); } else { @@ -1087,7 +1044,7 @@ static void dd_attr_emit_list(ddog_AttrList *dest, zval *value) { case IS_LONG: ddog_attr_list_push_int(dest, Z_LVAL_P(value)); break; case IS_DOUBLE: ddog_attr_list_push_double(dest, Z_DVAL_P(value)); break; default: { - zend_string *str = dd_native_typed_str(value); + zend_string *str = datadog_convert_to_str(value); ddog_attr_list_push_str(dest, dd_zend_string_to_CharSlice(str)); zend_string_release(str); break; @@ -1095,58 +1052,18 @@ static void dd_attr_emit_list(ddog_AttrList *dest, zval *value) { } } -// 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; -} - // Emits `value` under `key` into `dest`; `zkey`, when given, is `key` as a zend_string (zero-copy). static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string *zkey, zval *value, int flags) { if ((flags & DD_ATTR_TOP) && !key.len) { return; } - bool as_string = flags & DD_ATTR_SCALARS_AS_STRINGS; ZVAL_DEREF(value); switch (Z_TYPE_P(value)) { case IS_ARRAY: case IS_OBJECT: - if (Z_IS_RECURSIVE_P(value) - || ((flags & DD_ATTR_EMPTY_ARRAY_AS_STRING) && Z_TYPE_P(value) == IS_ARRAY && !zend_hash_num_elements(Z_ARR_P(value)))) { + if (Z_IS_RECURSIVE_P(value)) { + ddog_attributes_add_str(dest, key, DDOG_CHARSLICE_C("*RECURSION*")); + } else if ((flags & DD_ATTR_EMPTY_ARRAY_AS_STRING) && Z_TYPE_P(value) == IS_ARRAY && !zend_hash_num_elements(Z_ARR_P(value))) { ddog_attributes_add_str(dest, key, DDOG_CHARSLICE_C("")); } else if (dd_native_is_list(value)) { ddog_attributes_add_list(dest, key, dd_attr_build_list(value)); @@ -1161,29 +1078,20 @@ static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string break; case IS_TRUE: case IS_FALSE: - if (!as_string) { - ddog_attributes_add_bool(dest, key, Z_TYPE_P(value) == IS_TRUE); - return; - } - break; + ddog_attributes_add_bool(dest, key, Z_TYPE_P(value) == IS_TRUE); + return; case IS_LONG: - if (!as_string) { - ddog_attributes_add_int(dest, key, Z_LVAL_P(value)); - return; - } - break; + ddog_attributes_add_int(dest, key, Z_LVAL_P(value)); + return; case IS_DOUBLE: - if (!as_string) { - if (zkey) { - ddog_attributes_add_double_zstr(dest, zkey, Z_DVAL_P(value)); - } else { - ddog_attributes_add_double(dest, key, Z_DVAL_P(value)); - } - return; + if (zkey) { + ddog_attributes_add_double_zstr(dest, zkey, Z_DVAL_P(value)); + } else { + ddog_attributes_add_double(dest, key, Z_DVAL_P(value)); } - break; + return; } - zend_string *str = dd_native_typed_str(value); + zend_string *str = datadog_convert_to_str(value); if (zkey) { ddog_attributes_add_zstr(dest, zkey, str); } else { @@ -1192,9 +1100,8 @@ static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string zend_string_release(str); } -// Emit each SpanLink into the V1 builder span, reading from the PHP link objects (scalar attributes -// are strings; dropped_attributes_count has no PHP-side source). -static void dd_span_links_to_rust(zend_array *links, ddog_SpanNode *span) { +// Emit each SpanLink into the V1 builder span. V1 links carry no dropped_attributes_count. +static void dd_span_links_to_rust(zend_array *links, ddog_SpanBytes *span) { zval *val; ZEND_HASH_FOREACH_VAL(links, val) { ZVAL_DEREF(val); @@ -1233,7 +1140,7 @@ static void dd_span_links_to_rust(zend_array *links, ddog_SpanNode *span) { // Emit each SpanEvent into the V1 builder span, dispatching attributes by type. ExceptionSpanEvent // flattens exception.message/type/stacktrace as string attributes. -static void dd_span_events_to_rust(zend_array *events, ddog_SpanNode *span) { +static void dd_span_events_to_rust(zend_array *events, ddog_SpanBytes *span) { zval *val; ZEND_HASH_FOREACH_VAL(events, val) { ZVAL_DEREF(val); @@ -1287,7 +1194,7 @@ static void dd_span_events_to_rust(zend_array *events, ddog_SpanNode *span) { } // Value stored through the $meta/$metrics views: meta leaves become strings, metric leaves doubles, -// and empty or recursive arrays/objects the ""/0.0 placeholder, so the v0.4 wire keeps the old form. +// empty arrays/objects the ""/0.0 placeholder and reference cycles "*RECURSION*"/0.0. void ddtrace_normalize_tag_value(zval *dst, zval *value, bool metric) { ZVAL_DEREF(value); if (Z_TYPE_P(value) == IS_ARRAY || Z_TYPE_P(value) == IS_OBJECT) { @@ -1318,9 +1225,12 @@ void ddtrace_normalize_tag_value(zval *dst, zval *value, bool metric) { dd_native_release_props(arr, release); return; } + bool recursive = Z_IS_RECURSIVE_P(value); dd_native_release_props(arr, release); if (metric) { ZVAL_DOUBLE(dst, 0.0); + } else if (recursive) { + ZVAL_STRINGL(dst, "*RECURSION*", sizeof("*RECURSION*") - 1); } else { ZVAL_EMPTY_STRING(dst); } @@ -1331,7 +1241,7 @@ void ddtrace_normalize_tag_value(zval *dst, zval *value, bool metric) { } } -static void dd_serialize_array_meta_struct_recursively(ddog_SpanNode *target, zend_string *str, zval *value) { +static void dd_serialize_array_meta_struct_recursively(ddog_SpanBytes *target, zend_string *str, zval *value) { char *data; size_t size; @@ -1515,35 +1425,34 @@ static bool dd_is_http_error(int status) { return false; } -static void dd_set_http_error(ddtrace_span_data *span, int status, bool ignore_error) { +static void dd_set_http_error(zend_array *attributes, int status, bool ignore_error) { if (status) { - zend_array *attributes = ddtrace_property_array(&span->property_attributes); zend_string *status_str = zend_long_to_str((long)status); zval status_zv; ZVAL_STR(&status_zv, status_str); zend_hash_str_update(attributes, ZEND_STRL("http.status_code"), &status_zv); // Only check status codes if not ignoring errors - if (!ignore_error && dd_is_http_error(status) && !ddtrace_span_find_tag(span, ZEND_STRL("error.type"))) { - zval zv; - ZVAL_STR(&zv, zend_string_init(ZEND_STRL("HttpError"), 0)); - zend_hash_str_add_new(attributes, ZEND_STRL("error.type"), &zv); + if (!ignore_error && dd_is_http_error(status)) { + zval zv = {0}, *value; + if ((value = zend_hash_str_add(attributes, ZEND_STRL("error.type"), &zv))) { + ZVAL_STR(value, zend_string_init(ZEND_STRL("HttpError"), 0)); + } } } } -static void dd_set_entrypoint_root_span_props_end(ddtrace_span_data *span, int status, struct iter *headers, bool ignore_error) { - dd_set_http_error(span, status, ignore_error); +static void dd_set_entrypoint_root_span_props_end(zend_array *attributes, int status, struct iter *headers, bool ignore_error) { + dd_set_http_error(attributes, status, ignore_error); - zend_array *attributes = ddtrace_property_array(&span->property_attributes); for (zend_string *lowerheader, *headerval; headers->next(headers, &lowerheader, &headerval);) { - dd_add_header_to_meta(attributes, "response", lowerheader, headerval); + dd_add_header_to_attributes(attributes, "response", lowerheader, headerval); zend_string_release(lowerheader); zend_string_release(headerval); } } -static void dd_set_entrypoint_root_rust_span_props_end(ddog_SpanNode *span, struct iter *headers) { +static void dd_set_entrypoint_root_rust_span_props_end(ddog_SpanBytes *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); @@ -1551,16 +1460,6 @@ static void dd_set_entrypoint_root_rust_span_props_end(ddog_SpanNode *span, stru } } -// $ignoreError, or the deprecated "error.ignored" tag of a span not yet serialized (serialized spans -// have it folded into the property, see ddtrace_precompute_span). -static bool dd_span_ignores_error(ddtrace_span_data *span) { - if (zend_is_true(&span->property_ignore_error)) { - return true; - } - zval *attr = ddtrace_span_find_tag(span, ZEND_STRL("error.ignored")); - return attr && zend_is_true(attr); -} - static bool should_track_error(zend_object *exception, ddtrace_span_data *span) { if (Z_TYPE(span->property_exception) != IS_OBJECT || Z_OBJ(span->property_exception) != exception) { return true; @@ -1569,10 +1468,10 @@ static bool should_track_error(zend_object *exception, ddtrace_span_data *span) zval *zv; // Check if error should be ignored or tracking is disabled - if (dd_span_ignores_error(span)) { + if (zend_is_true(&span->property_ignore_error)) { return false; } - if ((zv = ddtrace_span_find_tag(span, ZEND_STRL("track_error"))) && !zend_is_true(zv)) { + if ((zv = zend_hash_str_find(ddtrace_property_array(&span->property_attributes), ZEND_STRL("track_error"))) && !zend_is_true(zv)) { return false; } return true; @@ -1617,14 +1516,23 @@ void ddtrace_shutdown_span_sampling_limiter(void) { zend_hash_destroy(&dd_span_sampling_limiters); } -// DD_ENV/DD_VERSION win, else the root's env/version (DD_TAGS fallback); the hostname is _dd.hostname's. -static void dd_set_payload_fields(ddog_TracerPayloadV1Builder *builder, ddtrace_span_precomputed *pre, zend_array *attributes, zval *git_metadata) { +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 255 +#endif + +// DD_ENV/DD_VERSION win, else the root's env/version. +static void dd_set_payload_fields(ddog_TracerPayloadBytes *builder, ddtrace_span_precomputed *pre, zval *git_metadata) { zend_string *env = ZSTR_LEN(get_DD_ENV()) ? get_DD_ENV() : pre->env; zend_string *version = ZSTR_LEN(get_DD_VERSION()) ? get_DD_VERSION() : pre->version; ddog_CharSlice hostname = DDOG_CHARSLICE_C(""); - zval *hostname_zv = zend_hash_str_find(attributes, ZEND_STRL("_dd.hostname")); - if (get_DD_TRACE_REPORT_HOSTNAME() && hostname_zv && Z_TYPE_P(hostname_zv) == IS_STRING) { - hostname = dd_zend_string_to_CharSlice(Z_STR_P(hostname_zv)); + char hostname_buf[HOST_NAME_MAX + 1]; + if (get_DD_TRACE_REPORT_HOSTNAME()) { + if (ZSTR_LEN(get_DD_HOSTNAME())) { + hostname = dd_zend_string_to_CharSlice(get_DD_HOSTNAME()); + } else if (!gethostname(hostname_buf, sizeof(hostname_buf))) { + hostname_buf[HOST_NAME_MAX] = '\0'; + hostname = (ddog_CharSlice){ .ptr = hostname_buf, .len = strlen(hostname_buf) }; + } } ddog_set_payload_metadata(builder, env ? dd_zend_string_to_CharSlice(env) : DDOG_CHARSLICE_C(""), @@ -1644,24 +1552,9 @@ static void dd_set_payload_fields(ddog_TracerPayloadV1Builder *builder, ddtrace_ } } -ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtrace_serialize_ctx *ctx, bool p0_trace) { +ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtrace_serialize_ctx *ctx, bool p0_trace) { zend_array *attributes = ddtrace_property_array(&span->property_attributes); - // http.status_code is a string tag on the wire; a numeric one (e.g. OTel's metric) is converted. - zval *attr_status_code = zend_hash_str_find(attributes, ZEND_STRL("http.status_code")); - if (attr_status_code && Z_TYPE_P(attr_status_code) != IS_STRING) { - zval status_code_as_string; - datadog_convert_to_string(&status_code_as_string, attr_status_code); - zend_hash_str_update(attributes, ZEND_STRL("http.status_code"), &status_code_as_string); - } - zval *attr_response_status_code = zend_hash_str_find(attributes, ZEND_STRL("http.response.status_code")); - if (attr_response_status_code && Z_TYPE_P(attr_response_status_code) != IS_STRING) { - zval status_code_as_string; - datadog_convert_to_string(&status_code_as_string, attr_response_status_code); - zend_hash_str_update(attributes, ZEND_STRL("http.status_code"), &status_code_as_string); - zend_hash_str_del(attributes, ZEND_STRL("http.response.status_code")); - } - ddtrace_span_precomputed pre; ddtrace_precompute_span(span, &pre); @@ -1685,7 +1578,7 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr if (datadog_active_sapi == DATADOG_PHP_SAPI_FRANKENPHP && !status) { status = pre.has_exception ? 500 : 200; } - dd_set_http_error(span, status, pre.ignore_error); + dd_set_http_error(attributes, status, pre.ignore_error); } ddtrace_span_data *inferred_span = NULL; @@ -1859,16 +1752,15 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr // dropped_trace is reserved for the agent; the chunk priority carries the sampling decision. ctx->chunk = ddog_new_chunk(ctx->builder, span->root->trace_id.high, span->root->trace_id.low); } - bool is_first_span = ddog_chunk_span_count(ctx->chunk) == 0; - ddog_SpanNode *rspan = ddog_new_span(ctx->chunk); + uintptr_t rspan_index = ddog_chunk_span_count(ctx->chunk); + bool is_first_span = rspan_index == 0; + ddog_SpanBytes *rspan = ddog_new_span(ctx->chunk); ddog_Attributes *rattrs = ddog_span_get_attributes(rspan); ddog_span_set_id(rspan, span->span_id); - uint64_t parent_id_set = 0; - bool has_parent_id = false; if (inferred_span) { - parent_id_set = inferred_span->span_id; has_parent_id = true; + ddog_span_set_parent_id(rspan, inferred_span->span_id); } 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 @@ -1876,15 +1768,12 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr parent = SPANDATA(parent->parent); } if (parent) { - parent_id_set = parent->span_id; has_parent_id = true; + ddog_span_set_parent_id(rspan, parent->span_id); } } else if (is_root_span) { - parent_id_set = ROOTSPANDATA(&span->std)->parent_id; has_parent_id = true; + ddog_span_set_parent_id(rspan, ROOTSPANDATA(&span->std)->parent_id); } else if (is_inferred_span) { - parent_id_set = span->root->parent_id; has_parent_id = true; - } - if (has_parent_id) { - ddog_span_set_parent_id(rspan, parent_id_set); + ddog_span_set_parent_id(rspan, span->root->parent_id); } ddog_span_set_start(rspan, span->start); @@ -1894,7 +1783,6 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr if (is_first_span && !ctx->process_tags_set) { ctx->process_tags_set = true; ddog_Attributes *payload_attrs = ddog_payload_get_attributes(ctx->builder); - // v0.4 downgrade puts this on each chunk's first span, as the pre-V1 serializer did. ddog_attributes_add_lit(payload_attrs, "_dd.sdk.otlp_export", DDOG_CHARSLICE_C("false")); zend_string *process_tags = datadog_process_tags_get_serialized(); if (ZSTR_LEN(process_tags)) { @@ -1905,7 +1793,7 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr if (dd_service && ZSTR_LEN(dd_service)) { svc_tag_appendix = ",svc.user:true"; } else { - if (!ddtrace_span_find_tag(&span->root->span, ZEND_STRL("_dd.svc_src"))) { + if (!zend_hash_str_find(ddtrace_property_array(&span->root->property_attributes), ZEND_STRL("_dd.svc_src"))) { zend_string *root_svc = datadog_convert_to_str(&span->root->property_service); if (ZSTR_LEN(root_svc)) { normalized_default = ddog_normalize_process_tag_value(dd_zend_string_to_CharSlice(root_svc)); @@ -1940,47 +1828,21 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr if (pre.name) { ddog_set_span_name_zstr(rspan, pre.name); } - if (pre.name_from_meta) { - zend_hash_str_del(attributes, ZEND_STRL("operation.name")); - } // SpanData::$resource defaults to SpanData::$name if (pre.resource) { ddog_set_span_resource_zstr(rspan, pre.resource); } - if (pre.resource_from_meta) { - zend_hash_str_del(attributes, ZEND_STRL("resource.name")); - } // TODO: SpanData::$service defaults to parent SpanData::$service or DD_SERVICE if root span if (pre.service) { ddog_set_span_service_zstr(rspan, pre.service); } - if (pre.service_from_meta) { - zend_hash_str_del(attributes, ZEND_STRL("service.name")); - } // SpanData::$type is optional and defaults to 'custom' at the Agent level if (pre.type) { ddog_set_span_type_zstr(rspan, pre.type); } - if (pre.type_from_meta) { - zend_hash_str_del(attributes, ZEND_STRL("span.type")); - } - - // analytics.event maps to _dd1.sr.eausr (a valid value wins over a set _dd1.sr.eausr). - zval *analytics_event = zend_hash_str_find(attributes, ZEND_STRL("analytics.event")); - if (analytics_event) { - ZVAL_DEREF(analytics_event); - double parsed_analytics_event = Z_TYPE_P(analytics_event) == IS_STRING - ? strconv_parse_bool(Z_STR_P(analytics_event)) - : zval_get_double(analytics_event); - if (Z_TYPE_P(analytics_event) != IS_STRING || parsed_analytics_event >= 0) { - zend_hash_str_del(attributes, ZEND_STRL("_dd1.sr.eausr")); - ddog_attributes_add_double_lit(rattrs, "_dd1.sr.eausr", parsed_analytics_event); - } - zend_hash_str_del(attributes, ZEND_STRL("analytics.event")); - } if (span_sampling_applied) { ddog_attributes_add_double_lit(rattrs, "_dd.span_sampling.mechanism", 8.0); @@ -1990,9 +1852,6 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr } } - // Promote span/chunk fields up front (their tags are deleted below). env/version are property-first - // with a tag fallback: DD_TAGS "env"/"version" are plain tags when DD_ENV/DD_VERSION are unset. - // pre.env/pre.version already carry that fallback. if (pre.env) { ddog_set_span_env(rspan, dd_zend_string_to_CharSlice(pre.env)); } @@ -2004,25 +1863,10 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr ZVAL_DEREF(component_prop); if (Z_TYPE_P(component_prop) == IS_STRING && Z_STRLEN_P(component_prop) > 0) { ddog_set_span_component(rspan, dd_zend_string_to_CharSlice(Z_STR_P(component_prop))); - } else { - zval *component_meta = zend_hash_str_find(attributes, ZEND_STRL("component")); - if (component_meta && Z_TYPE_P(component_meta) == IS_STRING) { - ddog_set_span_component(rspan, dd_zend_string_to_CharSlice(Z_STR_P(component_meta))); - } } - zval *span_kind_prop = &span->property_span_kind; - ZVAL_DEREF(span_kind_prop); - // Non-canonical span.kind strings (e.g. "process") leave the kind unspecified; - // keep them as a plain attribute instead of deleting below. - bool span_kind_is_canonical = true; - if (Z_TYPE_P(span_kind_prop) == IS_LONG && Z_LVAL_P(span_kind_prop) >= 1 && Z_LVAL_P(span_kind_prop) <= 5) { - ddog_set_span_kind(rspan, (uint32_t)Z_LVAL_P(span_kind_prop)); - } else { - zval *span_kind_meta = zend_hash_str_find(attributes, ZEND_STRL("span.kind")); - if (span_kind_meta && Z_TYPE_P(span_kind_meta) == IS_STRING) { - span_kind_is_canonical = ddog_set_span_kind_str(rspan, dd_zend_string_to_CharSlice(Z_STR_P(span_kind_meta))); - } + if (ddtrace_span_kind_str(pre.span_kind)) { + ddog_set_span_kind(rspan, (uint32_t)pre.span_kind); } // _dd.origin is property-sourced; the chunk carries it (never a span attribute). @@ -2031,14 +1875,14 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr ddog_set_chunk_origin(ctx->chunk, dd_zend_string_to_CharSlice(Z_STR_P(origin))); } - { + if (is_root_span || is_inferred_span) { // _dd.p.dm is "-N" (legacy "-N"): the mechanism is the digits after the last '-'. // Unparseable values leave the chunk field unset rather than claiming mechanism 0. - zval *dm_meta = zend_hash_str_find(attributes, ZEND_STRL("_dd.p.dm")); - if (dm_meta && Z_TYPE_P(dm_meta) == IS_STRING) { - const char *dash = zend_memrchr(Z_STRVAL_P(dm_meta), '-', Z_STRLEN_P(dm_meta)); - const char *p = dash ? dash + 1 : Z_STRVAL_P(dm_meta); - const char *end = Z_STRVAL_P(dm_meta) + Z_STRLEN_P(dm_meta); + zval *dm = zend_hash_str_find(attributes, ZEND_STRL("_dd.p.dm")); + if (dm && Z_TYPE_P(dm) == IS_STRING) { + const char *dash = zend_memrchr(Z_STRVAL_P(dm), '-', Z_STRLEN_P(dm)); + const char *p = dash ? dash + 1 : Z_STRVAL_P(dm); + const char *end = Z_STRVAL_P(dm) + Z_STRLEN_P(dm); uint64_t mech = 0; bool valid = p < end; for (; valid && p < end; p++) { @@ -2048,20 +1892,10 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr ddog_set_chunk_sampling_mechanism(ctx->chunk, (uint32_t)mech); } } - // Delete promoted keys so the copy loop only carries plain attributes. - zend_hash_str_del(attributes, ZEND_STRL("env")); - zend_hash_str_del(attributes, ZEND_STRL("version")); - zend_hash_str_del(attributes, ZEND_STRL("component")); - if (span_kind_is_canonical) { - zend_hash_str_del(attributes, ZEND_STRL("span.kind")); - } - zend_hash_str_del(attributes, ZEND_STRL("_dd.origin")); zend_hash_str_del(attributes, ZEND_STRL("_dd.p.dm")); - // _sampling_priority_v1 becomes the chunk sampling priority below. - zend_hash_str_del(attributes, ZEND_STRL("_sampling_priority_v1")); } - // $attributes is the single tag store ($meta/$metrics are views onto it). + // $meta/$metrics are views onto $attributes, so this emits them too. zend_string *attr_str_key; zval *attr_val; ZEND_HASH_FOREACH_STR_KEY_VAL_IND(attributes, attr_str_key, attr_val) { @@ -2076,11 +1910,10 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr 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, rspan, exception_type); + ddtrace_exception_to_attributes(Z_OBJ_P(exception_zv), pre.service ? pre.service : ZSTR_EMPTY_ALLOC(), span->start, rspan, exception_type); } - // Links/events are emitted natively from the PHP span (the _dd.span_links/events meta keys are - // never produced on the V1 path). + // Links/events are emitted natively from the PHP span. zend_array *span_links = ddtrace_property_array(&span->property_links); if (zend_hash_num_elements(span_links) > 0) { dd_span_links_to_rust(span_links, rspan); @@ -2091,33 +1924,17 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr dd_span_events_to_rust(span_events, rspan); } - zval *git_metadata = &span->root->property_git_metadata; - // Payload env/app_version/hostname/git come from the payload's first root span, as the v0.4 agent read them. + // Payload env/app_version/git come from the payload's first root span. if (is_root_span && !ctx->payload_fields_set) { ctx->payload_fields_set = true; - dd_set_payload_fields(ctx->builder, &pre, attributes, git_metadata); - } - if (git_metadata && Z_TYPE_P(git_metadata) == IS_OBJECT) { - datadog_git_metadata *metadata = (datadog_git_metadata *)Z_OBJ_P(git_metadata); - if (is_root_span) { - if (Z_TYPE(metadata->property_commit) == IS_STRING) { - zend_string *commit_sha = datadog_convert_to_str(&metadata->property_commit); - dd_span_attr_zstr(rspan, "_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); - dd_span_attr_zstr(rspan, "_dd.git.repository_url", repository_url); - zend_string_release(repository_url); - } - } + dd_set_payload_fields(ctx->builder, &pre, &span->root->property_git_metadata); } if (get_DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED()) { zend_array *peer_service_sources = ddtrace_property_array(&span->property_peer_service_sources); zval *peer_service_tag = zend_hash_str_find(attributes, ZEND_STRL("peer.service")); if (peer_service_tag && Z_TYPE_P(peer_service_tag) == IS_STRING) { - dd_span_attr_str(rspan, "_dd.peer.service.source", "peer.service"); + ddog_attributes_add_lit(rattrs, "_dd.peer.service.source", DDOG_CHARSLICE_C("peer.service")); dd_set_mapped_peer_service(rspan, Z_STR_P(peer_service_tag)); } else if (zend_hash_num_elements(peer_service_sources) > 0) { zval *tag; @@ -2125,10 +1942,10 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr if (Z_TYPE_P(tag) == IS_STRING) { zval *found_peer_service = zend_hash_find(attributes, Z_STR_P(tag)); if (found_peer_service && Z_TYPE_P(found_peer_service) == IS_STRING) { - dd_span_attr_zstr(rspan, "_dd.peer.service.source", Z_STR_P(tag)); + ddog_attributes_add_lit(rattrs, "_dd.peer.service.source", dd_zend_string_to_CharSlice(Z_STR_P(tag))); zend_string *peer = zval_get_string(found_peer_service); if (!dd_set_mapped_peer_service(rspan, peer)) { - dd_span_attr_zstr(rspan, "peer.service", peer); + ddog_attributes_add_lit(rattrs, "peer.service", dd_zend_string_to_CharSlice(peer)); } zend_string_release(peer); break; @@ -2154,7 +1971,7 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr do { should_track = should_track_error(exception, current); if (!should_track) { - dd_span_attr_str(rspan, "track_error", "false"); + ddog_attributes_add_lit(rattrs, "track_error", DDOG_CHARSLICE_C("false")); break; } current = current->parent ? SPANDATA(current->parent) : NULL; @@ -2173,7 +1990,7 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr 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))) { - dd_span_attr_zstr(rspan, "_dd.base_service", Z_STR_P(&prop_root_service_as_string)); + ddog_attributes_add_lit(rattrs, "_dd.base_service", dd_zend_string_to_CharSlice(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)); @@ -2187,7 +2004,7 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr if ((is_root_span && !inferred_span) || is_inferred_span) { if (Z_TYPE_P(&span->root->property_sampling_priority) != IS_UNDEF) { long sampling_priority = zval_get_long(&span->root->property_sampling_priority); - if (!get_global_DD_APM_TRACING_ENABLED() && !ddtrace_trace_source_is_meta_asm_sourced(attributes)) { + if (!get_global_DD_APM_TRACING_ENABLED() && !ddtrace_trace_source_is_asm_sourced(attributes)) { sampling_priority = MIN(PRIORITY_SAMPLING_AUTO_KEEP, sampling_priority); } ddog_set_chunk_sampling_priority(ctx->chunk, (int32_t)sampling_priority); @@ -2227,9 +2044,10 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr } } - ddog_SpanNode *inferred = inferred_span ? ddtrace_serialize_span_to_rust_span(inferred_span, ctx, p0_trace) : NULL; - // A dropped inferred span returns NULL; skip the transfers then. Node pointers stay valid across - // sibling pushes, so rspan is still usable after the inferred span was added to the chunk. + ddog_SpanBytes *inferred = inferred_span ? ddtrace_serialize_span_to_rust_span(inferred_span, ctx, p0_trace) : NULL; + // The inferred span was pushed into the same chunk, which may have moved rspan (rattrs is stale too). + rspan = ddog_v1_get_span(ctx->chunk, rspan_index); + // A dropped inferred span returns NULL; skip the transfers then. if (inferred) { ddog_transfer_span_attr(rspan, inferred, "_dd.agent_psr", true); ddog_transfer_span_attr(rspan, inferred, "_dd.rule_psr", true); @@ -2239,7 +2057,6 @@ ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtr ddog_transfer_span_attr(rspan, inferred, "error.type", false); ddog_transfer_span_attr(rspan, inferred, "error.stack", false); ddog_transfer_span_attr(rspan, inferred, "track_error", false); - ddog_transfer_span_attr(rspan, inferred, "_dd.p.dm", true); ddog_transfer_span_attr(rspan, inferred, "_dd.p.ksr", false); ddog_transfer_span_attr(rspan, inferred, "_dd.svc_src", false); ddog_transfer_span_attr(rspan, inferred, DD_TAG_HTTP_REQH_ENDPOINT_SCAN, false); @@ -2336,155 +2153,137 @@ static void dd_add_assoc_nonempty(zval *parent, const char *key, zval *arr) { } } -// Introspection reader for the native V1 builder: promoted and chunk-level fields are surfaced -// directly, the unified typed attribute map under "attributes", and links/events natively. -zval dd_serialize_rust_to_zval(ddog_TracerPayloadV1Builder *b) { - // The payload's process tags and OTLP export marker show on each chunk's first span, as on the v0.4 wire. - const ddog_AttrValue *process_tags_value = ddog_v1_attributes_get(ddog_payload_get_attributes(b), DDOG_CHARSLICE_C("_dd.tags.process")); - ddog_CharSlice process_tags = process_tags_value ? ddog_v1_value_str(process_tags_value) : (ddog_CharSlice){0}; - const ddog_AttrValue *otlp_export_value = ddog_v1_attributes_get(ddog_payload_get_attributes(b), DDOG_CHARSLICE_C("_dd.sdk.otlp_export")); - ddog_CharSlice otlp_export = otlp_export_value ? ddog_v1_value_str(otlp_export_value) : (ddog_CharSlice){0}; - zval traces_zv; - array_init(&traces_zv); - - size_t chunk_count; - ddog_ChunkNode *const *chunks = ddog_v1_get_chunks(b, &chunk_count); +// Adds a non-empty string field under `key`. +static void dd_add_assoc_charslice(zval *parent, const char *key, ddog_CharSlice value) { + if (value.len) { + add_assoc_str(parent, key, dd_CharSlice_to_zend_string(value)); + } +} + +static void dd_span_to_zval(ddog_SpanBytes *span, zval *span_zv) { + array_init(span_zv); + add_assoc_str(span_zv, KEY_SPAN_ID, ddtrace_span_id_as_string(ddog_v1_get_span_id(span))); + uint64_t parent_id = ddog_v1_get_span_parent_id(span); + 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(span)); + add_assoc_long(span_zv, "duration", ddog_v1_get_span_duration(span)); + add_assoc_str(span_zv, "name", dd_CharSlice_to_zend_string(ddog_v1_get_span_name(span))); + add_assoc_str(span_zv, "resource", dd_CharSlice_to_zend_string(ddog_v1_get_span_resource(span))); + add_assoc_str(span_zv, "service", dd_CharSlice_to_zend_string(ddog_v1_get_span_service(span))); + add_assoc_str(span_zv, "type", dd_CharSlice_to_zend_string(ddog_v1_get_span_type(span))); + if (ddog_v1_get_span_error(span)) { + add_assoc_bool(span_zv, "error", true); + } + dd_add_assoc_charslice(span_zv, "env", ddog_v1_get_span_env(span)); + dd_add_assoc_charslice(span_zv, "version", ddog_v1_get_span_version(span)); + dd_add_assoc_charslice(span_zv, "component", ddog_v1_get_span_component(span)); + uint32_t span_kind = ddog_v1_get_span_kind(span); + if (span_kind) { + add_assoc_long(span_zv, "span_kind", span_kind); + } + + // Bytes-typed attributes go under "meta_struct" (as on SpanData), not in the attribute map. + zval attrs_zv, meta_struct_zv; + array_init(&attrs_zv); + array_init(&meta_struct_zv); + dd_attributes_to_zval(ddog_span_get_attributes(span), &attrs_zv, &meta_struct_zv); + dd_add_assoc_nonempty(span_zv, "attributes", &attrs_zv); + dd_add_assoc_nonempty(span_zv, "meta_struct", &meta_struct_zv); + + size_t link_count = ddog_v1_get_link_count(span); + if (link_count > 0) { + zval links_zv; + array_init(&links_zv); + for (size_t l = 0; l < link_count; l++) { + ddog_SpanLinkBytes *link = ddog_v1_get_link(span, l); + zval link_zv; + array_init(&link_zv); + datadog_trace_id link_tid = {.low = ddog_v1_get_link_trace_id_low(link), .high = ddog_v1_get_link_trace_id_high(link)}; + add_assoc_str(&link_zv, KEY_TRACE_ID, datadog_trace_id_as_hex_string(link_tid)); + add_assoc_str(&link_zv, KEY_SPAN_ID, ddtrace_span_id_as_hex_string(ddog_v1_get_link_span_id(link))); + dd_add_assoc_charslice(&link_zv, "tracestate", ddog_v1_get_link_tracestate(link)); + zval lattrs_zv; + array_init(&lattrs_zv); + dd_attributes_to_zval(ddog_link_get_attributes(link), &lattrs_zv, NULL); + dd_add_assoc_nonempty(&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(span); + if (event_count > 0) { + zval events_zv; + array_init(&events_zv); + for (size_t e = 0; e < event_count; e++) { + ddog_SpanEventBytes *event = ddog_v1_get_event(span, e); + zval event_zv; + array_init(&event_zv); + add_assoc_str(&event_zv, "name", dd_CharSlice_to_zend_string(ddog_v1_get_event_name(event))); + add_assoc_long(&event_zv, "time_unix_nano", ddog_v1_get_event_time(event)); + zval eattrs_zv; + array_init(&eattrs_zv); + dd_attributes_to_zval(ddog_event_get_attributes(event), &eattrs_zv, NULL); + dd_add_assoc_nonempty(&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); + } +} + +// Introspection view of the V1 payload: payload fields, then its chunks with their own fields and +// spans, named as on the V1 wire (the request-replayer's JSON view has the same shape). +zval dd_serialize_rust_to_zval(ddog_TracerPayloadBytes *b) { + zval payload_zv; + array_init(&payload_zv); + dd_add_assoc_charslice(&payload_zv, "env", ddog_v1_get_payload_env(b)); + dd_add_assoc_charslice(&payload_zv, "hostname", ddog_v1_get_payload_hostname(b)); + dd_add_assoc_charslice(&payload_zv, "app_version", ddog_v1_get_payload_app_version(b)); + zval payload_attrs_zv; + array_init(&payload_attrs_zv); + dd_attributes_to_zval(ddog_payload_get_attributes(b), &payload_attrs_zv, NULL); + dd_add_assoc_nonempty(&payload_zv, "attributes", &payload_attrs_zv); + + zval chunks_zv; + array_init(&chunks_zv); + size_t chunk_count = ddog_v1_get_chunk_count(b); for (size_t c = 0; c < chunk_count; c++) { - const ddog_ChunkNode *chunk = chunks[c]; - zval trace_zv; - array_init(&trace_zv); - - uint64_t tid_high = ddog_v1_get_chunk_trace_id_high(chunk); - uint64_t tid_low = ddog_v1_get_chunk_trace_id_low(chunk); - // Chunk-level fields go on the chunk's local root only, the same span the v0.4 wire picks. - const ddog_SpanNode *root = ddog_v1_get_chunk_root_span(chunk); - int32_t chunk_priority; - bool has_priority = ddog_v1_get_chunk_sampling_priority(chunk, &chunk_priority); - uint32_t chunk_mechanism; - bool has_mechanism = ddog_v1_get_chunk_sampling_mechanism(chunk, &chunk_mechanism); - ddog_CharSlice chunk_origin = ddog_v1_get_chunk_origin(chunk); - - size_t span_count; - ddog_SpanNode *const *spans = ddog_v1_get_spans(chunk, &span_count); + ddog_TraceChunkBytes *chunk = ddog_v1_get_chunk(b, c); + zval chunk_zv; + array_init(&chunk_zv); + + datadog_trace_id tid = {.low = ddog_v1_get_chunk_trace_id_low(chunk), .high = ddog_v1_get_chunk_trace_id_high(chunk)}; + add_assoc_str(&chunk_zv, KEY_TRACE_ID, datadog_trace_id_as_hex_string(tid)); + int32_t priority; + if (ddog_v1_get_chunk_sampling_priority(chunk, &priority)) { + add_assoc_long(&chunk_zv, "priority", priority); + } + dd_add_assoc_charslice(&chunk_zv, "origin", ddog_v1_get_chunk_origin(chunk)); + uint32_t mechanism; + if (ddog_v1_get_chunk_sampling_mechanism(chunk, &mechanism)) { + add_assoc_long(&chunk_zv, "sampling_mechanism", mechanism); + } + zval chunk_attrs_zv; + array_init(&chunk_attrs_zv); + dd_attributes_to_zval(ddog_chunk_get_attributes(chunk), &chunk_attrs_zv, NULL); + dd_add_assoc_nonempty(&chunk_zv, "attributes", &chunk_attrs_zv); + + zval spans_zv; + array_init(&spans_zv); + size_t span_count = ddog_chunk_span_count(chunk); for (size_t j = 0; j < span_count; j++) { - ddog_SpanNode *span = spans[j]; - bool is_root = span == root; 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 && is_root) { - 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(span))); - uint64_t parent_id = ddog_v1_get_span_parent_id(span); - 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(span)); - add_assoc_long(&span_zv, "duration", ddog_v1_get_span_duration(span)); - add_assoc_str(&span_zv, "name", dd_CharSlice_to_zend_string(ddog_v1_get_span_name(span))); - add_assoc_str(&span_zv, "resource", dd_CharSlice_to_zend_string(ddog_v1_get_span_resource(span))); - add_assoc_str(&span_zv, "service", dd_CharSlice_to_zend_string(ddog_v1_get_span_service(span))); - add_assoc_str(&span_zv, "type", dd_CharSlice_to_zend_string(ddog_v1_get_span_type(span))); - if (ddog_v1_get_span_error(span)) { - add_assoc_long(&span_zv, "error", 1); - } - -#define DD_ZVAL_PROMOTED(field, getter) \ - do { \ - ddog_CharSlice _v = getter(span); \ - if (_v.len) add_assoc_str(&span_zv, field, dd_CharSlice_to_zend_string(_v)); \ - } while (0) - DD_ZVAL_PROMOTED("env", ddog_v1_get_span_env); - DD_ZVAL_PROMOTED("version", ddog_v1_get_span_version); - DD_ZVAL_PROMOTED("component", ddog_v1_get_span_component); -#undef DD_ZVAL_PROMOTED - uint32_t span_kind = ddog_v1_get_span_kind(span); - if (span_kind) { - add_assoc_long(&span_zv, "span_kind", span_kind); - } - if (has_priority && is_root) { - add_assoc_long(&span_zv, "sampling_priority", chunk_priority); - } - if (has_mechanism && is_root) { - add_assoc_long(&span_zv, "sampling_mechanism", chunk_mechanism); - } - if (chunk_origin.len && is_root) { - add_assoc_str(&span_zv, "origin", dd_CharSlice_to_zend_string(chunk_origin)); - } - - // Bytes-typed attributes are v0.4 meta_struct entries; surface them under - // "meta_struct" (as the v0.4 reader did), not mixed into the attribute map. - zval attrs_zv, meta_struct_zv; - array_init(&attrs_zv); - array_init(&meta_struct_zv); - if (j == 0 && process_tags.len) { - add_assoc_str(&attrs_zv, "_dd.tags.process", dd_CharSlice_to_zend_string(process_tags)); - } - if (j == 0 && otlp_export.len) { - add_assoc_str(&attrs_zv, "_dd.sdk.otlp_export", dd_CharSlice_to_zend_string(otlp_export)); - } - dd_attributes_to_zval(ddog_span_get_attributes(span), &attrs_zv, &meta_struct_zv); - dd_add_assoc_nonempty(&span_zv, "attributes", &attrs_zv); - dd_add_assoc_nonempty(&span_zv, "meta_struct", &meta_struct_zv); - - size_t link_count; - ddog_SpanLinkBytes *const *links = ddog_v1_get_links(span, &link_count); - if (link_count > 0) { - zval links_zv; - array_init(&links_zv); - for (size_t l = 0; l < link_count; l++) { - ddog_SpanLinkBytes *link = links[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(link))); - uint64_t link_tid_high = ddog_v1_get_link_trace_id_high(link); - if (link_tid_high) { - add_assoc_str(&link_zv, "trace_id_high", ddtrace_span_id_as_hex_string(link_tid_high)); - } - add_assoc_str(&link_zv, KEY_SPAN_ID, ddtrace_span_id_as_string(ddog_v1_get_link_span_id(link))); - ddog_CharSlice tracestate = ddog_v1_get_link_tracestate(link); - 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(link)); - zval lattrs_zv; - array_init(&lattrs_zv); - dd_attributes_to_zval(ddog_link_get_attributes(link), &lattrs_zv, NULL); - dd_add_assoc_nonempty(&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_SpanEventBytes *const *events = ddog_v1_get_events(span, &event_count); - if (event_count > 0) { - zval events_zv; - array_init(&events_zv); - for (size_t e = 0; e < event_count; e++) { - ddog_SpanEventBytes *event = events[e]; - zval event_zv; - array_init(&event_zv); - add_assoc_str(&event_zv, "name", dd_CharSlice_to_zend_string(ddog_v1_get_event_name(event))); - add_assoc_long(&event_zv, "time_unix_nano", ddog_v1_get_event_time(event)); - zval eattrs_zv; - array_init(&eattrs_zv); - dd_attributes_to_zval(ddog_event_get_attributes(event), &eattrs_zv, NULL); - dd_add_assoc_nonempty(&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); + dd_span_to_zval(ddog_v1_get_span(chunk, j), &span_zv); + zend_hash_next_index_insert_new(Z_ARR(spans_zv), &span_zv); } - - zend_hash_next_index_insert_new(Z_ARR_P(&traces_zv), &trace_zv); + add_assoc_zval(&chunk_zv, "spans", &spans_zv); + zend_hash_next_index_insert_new(Z_ARR(chunks_zv), &chunk_zv); } + add_assoc_zval(&payload_zv, "chunks", &chunks_zv); - return traces_zv; + return payload_zv; } static zend_string *dd_truncate_uncaught_exception(zend_string *msg) { @@ -2517,7 +2316,7 @@ void ddtrace_save_active_error_to_metadata(void) { continue; } - dd_fatal_error_to_meta(ddtrace_property_array(&pspan->property_attributes), error); + dd_fatal_error_to_attributes(ddtrace_property_array(&pspan->property_attributes), error); } zend_string_release(error.type); zend_string_release(error.msg); @@ -2613,7 +2412,7 @@ void ddtrace_error_cb(DDTRACE_ERROR_CB_PARAMETERS) { continue; } - dd_fatal_error_to_meta(ddtrace_property_array(&pspan->property_attributes), error); + dd_fatal_error_to_attributes(ddtrace_property_array(&pspan->property_attributes), error); } zend_string_release(error.type); zend_string_release(error.msg); @@ -2652,8 +2451,9 @@ static zend_array *dd_ser_response_committed(ddtrace_user_req_listeners *self, z UNUSED(self, entity); ddtrace_root_span_data *root_span_data = ROOTSPANDATA(span); + zend_array *attributes = ddtrace_property_array(&root_span_data->property_attributes); struct iter *iter = dd_iterate_arr_arr_headers(headers); - dd_set_entrypoint_root_span_props_end(&root_span_data->span, status, iter, false); + dd_set_entrypoint_root_span_props_end(attributes, status, iter, false); efree(iter); return NULL; } diff --git a/tracer/serializer.h b/tracer/serializer.h index 1bfcdf3c7e1..9cadc3d2a38 100644 --- a/tracer/serializer.h +++ b/tracer/serializer.h @@ -7,12 +7,12 @@ 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); // Returns the span's V1 builder node, or NULL when the span was dropped. -ddog_SpanNode *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtrace_serialize_ctx *ctx, bool p0_trace); -zval dd_serialize_rust_to_zval(struct ddog_TracerPayloadV1Builder *builder); +ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddtrace_serialize_ctx *ctx, bool p0_trace); +zval dd_serialize_rust_to_zval(struct ddog_TracerPayloadBytes *builder); // String span attribute setters shared with exception_serialize.c. -void dd_span_attr_str(ddog_SpanNode *span, const char *key, const char *val); -void dd_span_attr_zstr(ddog_SpanNode *span, const char *key, zend_string *val); +void dd_span_attr_str(ddog_SpanBytes *span, const char *key, const char *val); +void dd_span_attr_zstr(ddog_SpanBytes *span, const char *key, zend_string *val); // Normalizes a value written through SpanData::$meta (strings) or $metrics (doubles) into `dst`. void ddtrace_normalize_tag_value(zval *dst, zval *value, bool metric); diff --git a/tracer/span.c b/tracer/span.c index c15ac124ccf..74cd962cc4b 100644 --- a/tracer/span.c +++ b/tracer/span.c @@ -244,9 +244,8 @@ ddtrace_inferred_span_data *ddtrace_open_inferred_span(ddtrace_inferred_proxy_re zend_hash_str_update(attributes, ZEND_STRL("stage"), &zv); } - ZVAL_DOUBLE(&zv, 1); + ZVAL_LONG(&zv, 1); zend_hash_str_update(attributes, ZEND_STRL("_dd.inferred_span"), &zv); - // 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)); @@ -549,10 +548,10 @@ ddtrace_span_data *ddtrace_alloc_execute_data_span_ex(zend_ulong index, zend_exe zend_string_release(basename); } - zend_array *meta = ddtrace_property_array(&span->property_attributes); + zend_array *attributes = ddtrace_property_array(&span->property_attributes); zval location; ZVAL_STR(&location, zend_strpprintf(0, "%s:%d", ZSTR_VAL(EX(func)->op_array.filename), EX(func)->op_array.opcodes->lineno)); - zend_hash_str_add_new(meta, ZEND_STRL("closure.declaration"), &location); + zend_hash_str_add_new(attributes, ZEND_STRL("closure.declaration"), &location); } else if (EX(func) && EX(func)->common.function_name) { zval_ptr_dtor(prop_name); @@ -829,7 +828,7 @@ static void dd_mark_closed_spans_flushable(ddtrace_span_stack *stack) { // This might get updated later with SpanStacks, but at that point it will be orphan spans. That's intentional. if (!get_global_DD_APM_TRACING_ENABLED()) { // Increment limiter, then force sampling priority if not an asm event - if (!ddtrace_standalone_limiter_allow() && !root_span->asm_event_emitted && !ddtrace_trace_source_is_meta_asm_sourced(ddtrace_property_array(&stack->root_span->property_attributes))) { + if (!ddtrace_standalone_limiter_allow() && !root_span->asm_event_emitted && !ddtrace_trace_source_is_asm_sourced(ddtrace_property_array(&stack->root_span->property_attributes))) { zval priority; ZVAL_LONG(&priority, PRIORITY_SAMPLING_AUTO_REJECT); datadog_assign_variable(&root_span->property_sampling_priority, &priority); @@ -984,7 +983,7 @@ void ddtrace_close_top_span_without_stack_swap(ddtrace_span_data *span) { } // Telemetry: increment the spans_created counter - // Must be done at closing because we need to read the "component" span's meta which is not available at creation + // Must be done at closing because the component property is not set yet at creation ddtrace_telemetry_inc_spans_created(span); ddtrace_span_stack *stack = span->stack; @@ -1166,7 +1165,7 @@ void ddtrace_serialize_closed_spans(ddtrace_serialize_ctx *ctx, bool fast_shutdo next_stack = stack->next; } if (ctx) { - ctx->chunk = DD_CHUNK_NONE; // one V1 chunk per V0.4 trace + ctx->chunk = DD_CHUNK_NONE; // one chunk per trace } bool sampling_decided = false; bool p0_trace = false; @@ -1262,21 +1261,15 @@ void ddtrace_populate_span_data(ddtrace_span_data *span, zend_string **service, *service = zend_string_init(ZEND_STRL("unnamed-php-service"), 0); } - zval *prop_env = ddtrace_span_find_tag(span, ZEND_STRL("env")); - if (!prop_env) { - prop_env = &span->property_env; - } + zval *prop_env = &span->property_env; if (Z_TYPE_P(prop_env) == IS_STRING && Z_STRLEN_P(prop_env) > 0) { *env = zend_string_copy(Z_STR_P(prop_env)); } else { *env = NULL; } - zval *prop_version = ddtrace_span_find_tag(span, ZEND_STRL("version")); - if (!prop_version) { - prop_version = &span->property_version; - } - if (prop_version && Z_TYPE_P(prop_version) == IS_STRING && Z_STRLEN_P(prop_version) > 0) { + zval *prop_version = &span->property_version; + if (Z_TYPE_P(prop_version) == IS_STRING && Z_STRLEN_P(prop_version) > 0) { *version = zend_string_copy(Z_STR_P(prop_version)); } else { *version = NULL; diff --git a/tracer/span.h b/tracer/span.h index 6569dbcdd3f..cbc3ea56142 100644 --- a/tracer/span.h +++ b/tracer/span.h @@ -18,14 +18,14 @@ // V1 payload build context threaded through serialization. `chunk` is DD_CHUNK_NONE until the // first span of the current stack creates its chunk (ddtrace_serialize_closed_spans resets it per -// stack). Under the Box-per-node model `chunk` is the chunk node pointer, stable across sibling pushes. +// stack). It points into the builder and is only used until the next chunk is created. #define DD_CHUNK_NONE (NULL) typedef struct { - struct ddog_TracerPayloadV1Builder *builder; - struct ddog_ChunkNode *chunk; + struct ddog_TracerPayloadBytes *builder; + struct ddog_TraceChunkBytes *chunk; bool process_tags_set; // the payload's _dd.tags.process / _dd.sdk.otlp_export attributes were decided bool payload_fields_set; // the payload env/app_version/hostname/git were taken from a root span - bool mark_top_level; // mark `_dd.top_level` on every top-level span (the sidecar sender's V1 needs it) + bool mark_top_level; // mark `_dd.top_level` on every top-level span (the sidecar sender declares client-computed top-level) } ddtrace_serialize_ctx; #define DDTRACE_DROPPED_SPAN (-1ull) @@ -51,6 +51,22 @@ typedef struct { enum dd_sampling_mechanism mechanism; } ddtrace_rule_result; +// DDTrace\SpanKind constants (SpanData::$spanKind), as the V1 span kind field encodes them. +enum ddtrace_span_kind { + DDTRACE_SPAN_KIND_UNSPECIFIED = 0, + DDTRACE_SPAN_KIND_INTERNAL = 1, + DDTRACE_SPAN_KIND_SERVER = 2, + DDTRACE_SPAN_KIND_CLIENT = 3, + DDTRACE_SPAN_KIND_PRODUCER = 4, + DDTRACE_SPAN_KIND_CONSUMER = 5, +}; + +// The span.kind string of a DDTrace\SpanKind value; NULL when unspecified or unknown. +static inline const char *ddtrace_span_kind_str(zend_long kind) { + static const char *const names[] = {NULL, "internal", "server", "client", "producer", "consumer"}; + return kind > 0 && kind <= DDTRACE_SPAN_KIND_CONSUMER ? names[kind] : NULL; +} + enum ddtrace_trace_limited { DD_TRACE_LIMIT_UNCHECKED, DD_TRACE_LIMITED, @@ -167,7 +183,6 @@ 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; @@ -175,7 +190,6 @@ 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) { @@ -196,7 +210,6 @@ struct ddtrace_span_stack { ddtrace_span_properties *active; }; zval property_span_creation_observers; - zval property_attributes; }; }; struct ddtrace_root_span_data *root_span; @@ -314,11 +327,6 @@ static inline bool ddtrace_span_is_entrypoint_root(ddtrace_span_data *span) { return span->std.ce == ddtrace_ce_root_span_data && (!span->stack->parent_stack || !span->stack->parent_stack->parent_stack); } -// Tag lookup in SpanData::$attributes, the single tag store ($meta/$metrics are views onto it). -static inline zval *ddtrace_span_find_tag(ddtrace_span_data *span, const char *key, size_t len) { - return zend_hash_str_find(ddtrace_property_array(&span->property_attributes), key, len); -} - static inline ddtrace_span_data *ddtrace_get_inferred_span(ddtrace_root_span_data *root) { zval *inferred_span_zv = &root->property_inferred_span; if (Z_TYPE_P(inferred_span_zv) == IS_OBJECT && Z_OBJCE_P(inferred_span_zv) == ddtrace_ce_inferred_span_data) { diff --git a/tracer/span_stats.c b/tracer/span_stats.c index c90bedbf0a6..2d5736ba3f9 100644 --- a/tracer/span_stats.c +++ b/tracer/span_stats.c @@ -39,27 +39,15 @@ static const size_t GRPC_META_KEY_LENS[] = { // agent, which is larger and must be scanned in full. #define DDTRACE_MAX_PEER_TAGS 32 -static zval *dd_pre_find_tag(const ddtrace_span_precomputed *pre, const char *key, size_t len) { - return zend_hash_str_find(pre->attributes, key, len); -} - void ddtrace_precompute_span(ddtrace_span_data *span, ddtrace_span_precomputed *pre) { pre->attributes = ddtrace_property_array(&span->property_attributes); - // Service: "service.name" tag override then span property, then apply DD_SERVICE_MAPPING. - zval *service_name_meta = dd_pre_find_tag(pre, ZEND_STRL("service.name")); - pre->service_from_meta = (service_name_meta != NULL); + // Service: span property, then apply DD_SERVICE_MAPPING. pre->service = NULL; - if (service_name_meta) { - pre->service = datadog_convert_to_str(service_name_meta); - } else { - zval *prop_service = &span->property_service; - ZVAL_DEREF(prop_service); - if (Z_TYPE_P(prop_service) > IS_NULL) { - pre->service = datadog_convert_to_str(prop_service); - } - } - if (pre->service) { + zval *prop_service = &span->property_service; + ZVAL_DEREF(prop_service); + if (Z_TYPE_P(prop_service) > IS_NULL) { + pre->service = datadog_convert_to_str(prop_service); zval *mapped = zend_hash_find(get_DD_SERVICE_MAPPING(), pre->service); if (mapped) { zend_string_release(pre->service); @@ -67,123 +55,66 @@ void ddtrace_precompute_span(ddtrace_span_data *span, ddtrace_span_precomputed * } } - // Name: "operation.name" tag (lowercased!) or span property. - zval *operation_name = dd_pre_find_tag(pre, ZEND_STRL("operation.name")); pre->name = NULL; - if (operation_name && Z_TYPE_P(operation_name) == IS_STRING) { - pre->name = zend_string_tolower(Z_STR_P(operation_name)); - pre->name_from_meta = true; - } else { - zval *prop_name = &span->property_name; - ZVAL_DEREF(prop_name); - if (Z_TYPE_P(prop_name) > IS_NULL) { - pre->name = datadog_convert_to_str(prop_name); - } - pre->name_from_meta = false; + zval *prop_name = &span->property_name; + ZVAL_DEREF(prop_name); + if (Z_TYPE_P(prop_name) > IS_NULL) { + pre->name = datadog_convert_to_str(prop_name); } - // Resource: "resource.name" tag or span property, falling back to name. - zval *resource_name = dd_pre_find_tag(pre, ZEND_STRL("resource.name")); - pre->resource_from_meta = (resource_name != NULL); + // Resource: span property, falling back to name. pre->resource = NULL; - if (resource_name) { - pre->resource = datadog_convert_to_str(resource_name); - } else { - zval *prop_resource = &span->property_resource; - ZVAL_DEREF(prop_resource); - if (Z_TYPE_P(prop_resource) > IS_FALSE && - (Z_TYPE_P(prop_resource) != IS_STRING || Z_STRLEN_P(prop_resource) > 0)) { - pre->resource = datadog_convert_to_str(prop_resource); - } + zval *prop_resource = &span->property_resource; + ZVAL_DEREF(prop_resource); + if (Z_TYPE_P(prop_resource) > IS_FALSE && + (Z_TYPE_P(prop_resource) != IS_STRING || Z_STRLEN_P(prop_resource) > 0)) { + pre->resource = datadog_convert_to_str(prop_resource); } if (!pre->resource && pre->name) { pre->resource = zend_string_copy(pre->name); } - // Type: "span.type" tag or span property. - zval *span_type = dd_pre_find_tag(pre, ZEND_STRL("span.type")); - pre->type_from_meta = (span_type != NULL); pre->type = NULL; - zval *prop_type = span_type ? span_type : &span->property_type; + zval *prop_type = &span->property_type; ZVAL_DEREF(prop_type); if (Z_TYPE_P(prop_type) > IS_NULL) { pre->type = datadog_convert_to_str(prop_type); } - // Env: property first, then the "env" tag fallback (matching serializer.c promotion). Without the - // fallback, DD_TAGS "env" (DD_ENV unset) would bucket stats by empty env vs the trace's. pre->env = NULL; 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); - } - } - if (!pre->env) { - zval *env_meta = dd_pre_find_tag(pre, ZEND_STRL("env")); - if (env_meta && Z_TYPE_P(env_meta) == IS_STRING) { - pre->env = zend_string_copy(Z_STR_P(env_meta)); - } + if (Z_TYPE_P(prop_env) == IS_STRING && Z_STRLEN_P(prop_env) > 0) { + pre->env = zend_string_copy(Z_STR_P(prop_env)); } - // Version: span property first, then the "version" tag fallback (same rationale). pre->version = NULL; 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); - } - } - if (!pre->version) { - zval *version_meta = dd_pre_find_tag(pre, ZEND_STRL("version")); - if (version_meta && Z_TYPE_P(version_meta) == IS_STRING) { - pre->version = zend_string_copy(Z_STR_P(version_meta)); - } + if (Z_TYPE_P(prop_version) == IS_STRING && Z_STRLEN_P(prop_version) > 0) { + pre->version = zend_string_copy(Z_STR_P(prop_version)); } // has_exception: used by dd_compute_span_is_error() for exception-based error detection. zval *exception_zv = &span->property_exception; pre->has_exception = Z_TYPE_P(exception_zv) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception_zv), zend_ce_throwable); - - // $ignoreError, or the deprecated "error.ignored" tag, which can only turn it on. The tag is folded into - // the property and dropped, so it is never emitted and should_track_error's ancestor walk still sees it. - zval *error_ignored = zend_hash_str_find(pre->attributes, ZEND_STRL("error.ignored")); - if (error_ignored) { - if (zend_is_true(error_ignored)) { - zval *ignore_error = &span->property_ignore_error; - ZVAL_DEREF(ignore_error); - zval_ptr_dtor(ignore_error); - ZVAL_TRUE(ignore_error); - } - zend_hash_str_del(pre->attributes, ZEND_STRL("error.ignored")); - } pre->ignore_error = zend_is_true(&span->property_ignore_error); // Stats eligibility fields — fetched once here to avoid duplicate lookups in the two // call sites (ddtrace_span_concentrator_feed_cb and ddtrace_feed_span_to_concentrator). pre->has_top_level = ddtrace_span_is_entrypoint_root(span) || (span->std.ce == ddtrace_ce_root_span_data && ROOTSPANDATA(&span->std)->parent_id == 0) || (span->parent && !zend_is_identical(&span->property_service, &span->parent->property_service)); - zval *is_measured = dd_pre_find_tag(pre, ZEND_STRL("_dd.measured")); + zval *is_measured = zend_hash_str_find(pre->attributes, ZEND_STRL("_dd.measured")); pre->is_measured = is_measured && zval_get_double(is_measured) != 0.0; pre->is_partial_snapshot = false; - zval *span_kind_zv = dd_pre_find_tag(pre, ZEND_STRL("span.kind")); - // Owned copy: the serializer deletes the "span.kind" tag up front, so pre must not borrow it. - pre->span_kind = (span_kind_zv && Z_TYPE_P(span_kind_zv) == IS_STRING) ? zend_string_copy(Z_STR_P(span_kind_zv)) : NULL; + pre->span_kind = zval_get_long(&span->property_span_kind); } bool dd_compute_span_is_error(const ddtrace_span_precomputed *pre) { if (pre->ignore_error) { return false; } - if (dd_pre_find_tag(pre, ZEND_STRL("error.message")) || dd_pre_find_tag(pre, ZEND_STRL("error.type"))) { + if (zend_hash_str_find(pre->attributes, ZEND_STRL("error.message")) || zend_hash_str_find(pre->attributes, ZEND_STRL("error.type"))) { return true; } return pre->has_exception; @@ -208,9 +139,6 @@ void ddtrace_free_span_precomputed(ddtrace_span_precomputed *pre) { if (pre->version) { zend_string_release(pre->version); } - if (pre->span_kind) { - zend_string_release(pre->span_kind); - } } typedef struct { @@ -237,22 +165,22 @@ static ddog_PhpSpanStats ddtrace_build_span_stats_core( // HTTP and gRPC fields only appear on service entry spans, which are always stats-eligible. // They are fetched here (after the eligibility check) rather than in ddtrace_precompute_span. - zval *http_status_str_zv = dd_pre_find_tag(pre, ZEND_STRL("http.status_code")); + zval *http_status_str_zv = zend_hash_str_find(pre->attributes, ZEND_STRL("http.status_code")); ddog_CharSlice http_status_str_slice = http_status_str_zv && Z_TYPE_P(http_status_str_zv) == IS_STRING ? dd_zend_string_to_CharSlice(Z_STR_P(http_status_str_zv)) : DDOG_CHARSLICE_C(""); - zval *http_method_zv = dd_pre_find_tag(pre, ZEND_STRL("http.method")); + zval *http_method_zv = zend_hash_str_find(pre->attributes, ZEND_STRL("http.method")); ddog_CharSlice http_method_slice = http_method_zv && Z_TYPE_P(http_method_zv) == IS_STRING ? dd_zend_string_to_CharSlice(Z_STR_P(http_method_zv)) : DDOG_CHARSLICE_C(""); - zval *http_endpoint_zv = dd_pre_find_tag(pre, ZEND_STRL("http.endpoint")); + zval *http_endpoint_zv = zend_hash_str_find(pre->attributes, ZEND_STRL("http.endpoint")); ddog_CharSlice http_endpoint_slice = http_endpoint_zv && Z_TYPE_P(http_endpoint_zv) == IS_STRING ? dd_zend_string_to_CharSlice(Z_STR_P(http_endpoint_zv)) : DDOG_CHARSLICE_C(""); - zval *http_route_zv = dd_pre_find_tag(pre, ZEND_STRL("http.route")); + zval *http_route_zv = zend_hash_str_find(pre->attributes, ZEND_STRL("http.route")); ddog_CharSlice http_route_slice = http_route_zv && Z_TYPE_P(http_route_zv) == IS_STRING ? dd_zend_string_to_CharSlice(Z_STR_P(http_route_zv)) : DDOG_CHARSLICE_C(""); @@ -263,7 +191,7 @@ static ddog_PhpSpanStats ddtrace_build_span_stats_core( ? dd_zend_string_to_CharSlice(Z_STR_P(origin_zv)) : DDOG_CHARSLICE_C(""); - zval *service_source_zv = dd_pre_find_tag(pre, ZEND_STRL("_dd.svc_src")); + zval *service_source_zv = zend_hash_str_find(pre->attributes, ZEND_STRL("_dd.svc_src")); ddog_CharSlice service_source_slice = service_source_zv && Z_TYPE_P(service_source_zv) == IS_STRING ? dd_zend_string_to_CharSlice(Z_STR_P(service_source_zv)) : DDOG_CHARSLICE_C(""); @@ -319,7 +247,12 @@ static ddog_OwnedShmSpanInput *ddtrace_span_concentrator_feed_cb(const ddog_Span ddtrace_span_data *span = data->span; const ddtrace_span_precomputed *pre = data->pre; - ddog_CharSlice span_kind_slice = dd_zend_string_to_CharSlice(pre->span_kind); + // No ternary here: MSVC 2017 (PHP 7.x on Windows) dropped its NULL branch and ran strlen(NULL). + const char *span_kind = ddtrace_span_kind_str(pre->span_kind); + if (!span_kind) { + span_kind = ""; + } + ddog_CharSlice span_kind_slice = { .ptr = span_kind, .len = strlen(span_kind) }; if (!ddog_span_concentrator_is_eligible(c, pre->has_top_level, pre->is_measured, span_kind_slice, pre->is_partial_snapshot)) { return NULL; @@ -334,13 +267,13 @@ static ddog_OwnedShmSpanInput *ddtrace_span_concentrator_feed_cb(const ddog_Span ddog_PhpPeerTag peer_tags[DDTRACE_MAX_PEER_TAGS]; size_t actual_peer_tags = 0; - if (pre->span_kind && (zend_string_equals_literal(pre->span_kind, "client") || zend_string_equals_literal(pre->span_kind, "producer") || zend_string_equals_literal(pre->span_kind, "consumer"))) { + if (pre->span_kind == DDTRACE_SPAN_KIND_CLIENT || pre->span_kind == DDTRACE_SPAN_KIND_PRODUCER || pre->span_kind == DDTRACE_SPAN_KIND_CONSUMER) { size_t peer_tag_keys_count = 0; const ddog_CharSlice *peer_tag_keys = ddog_span_concentrator_peer_tag_keys(c, &peer_tag_keys_count); if (peer_tag_keys_count > 0 && peer_tag_keys) { for (size_t i = 0; i < peer_tag_keys_count && actual_peer_tags < DDTRACE_MAX_PEER_TAGS; i++) { const ddog_CharSlice *k = &peer_tag_keys[i]; - zval *val = dd_pre_find_tag(pre, k->ptr, k->len); + zval *val = zend_hash_str_find(pre->attributes, k->ptr, k->len); if (val && Z_TYPE_P(val) == IS_STRING) { peer_tags[actual_peer_tags].key = *k; peer_tags[actual_peer_tags].value = dd_zend_string_to_CharSlice(Z_STR_P(val)); @@ -348,10 +281,10 @@ static ddog_OwnedShmSpanInput *ddtrace_span_concentrator_feed_cb(const ddog_Span } } } - } else if (!pre->span_kind || !zend_string_equals_literal(pre->span_kind, "server")) { + } else if (pre->span_kind != DDTRACE_SPAN_KIND_SERVER) { // internal or no span.kind: use _dd.base_service only if it marks a service override static const ddog_CharSlice BASE_SERVICE_KEY = DDOG_CHARSLICE_C_BARE("_dd.base_service"); - zval *base_svc_zv = dd_pre_find_tag(pre, ZEND_STRL("_dd.base_service")); + zval *base_svc_zv = zend_hash_str_find(pre->attributes, ZEND_STRL("_dd.base_service")); if (base_svc_zv && Z_TYPE_P(base_svc_zv) == IS_STRING) { peer_tags[0].key = BASE_SERVICE_KEY; peer_tags[0].value = dd_zend_string_to_CharSlice(Z_STR_P(base_svc_zv)); @@ -375,11 +308,6 @@ void ddtrace_feed_span_to_concentrator(ddtrace_span_data *span, const ddtrace_sp version_zstr = Z_STR_P(root_version_zv); } else { version_zstr = get_DD_VERSION(); - // When DD_VERSION is unset, DD_TAGS "version" lives only in meta (deleted during promotion), - // so fall back to pre->version to keep stats bucketed by the trace's version. - if (ZSTR_LEN(version_zstr) == 0 && pre->version) { - version_zstr = pre->version; - } } ddog_CharSlice version_slice = dd_zend_string_to_CharSlice(version_zstr); // Use the process-level DD_SERVICE as the concentrator key so all spans from this PHP diff --git a/tracer/span_stats.h b/tracer/span_stats.h index f1fa07e17aa..eb955a1e5ac 100644 --- a/tracer/span_stats.h +++ b/tracer/span_stats.h @@ -8,43 +8,36 @@ * * The serializer computes service (with mapping), name, resource, and type once for its own * purposes. This struct carries those results so the concentrator callback can use them directly - * instead of re-fetching from meta/metrics. + * instead of re-fetching them. * * Owned strings (service, name, resource, type) are zend_string* that must be released with * ddtrace_free_span_precomputed() when no longer needed. NULL means the field is absent. * - * attributes is a borrowed pointer (no ownership transfer); all tag lookups read it. + * attributes is a borrowed pointer (no ownership transfer); all attribute lookups read it. */ typedef struct { zend_array *attributes; /* Owned strings — release with ddtrace_free_span_precomputed() */ zend_string *service; /* mapped service name */ - zend_string *name; /* resolved operation name, lowercased when from operation.name meta */ + zend_string *name; /* operation name */ zend_string *resource; /* resolved resource; falls back to name when property_resource is empty */ - zend_string *type; /* resolved span type */ + zend_string *type; /* span type */ zend_string *env; /* from span->property_env; NULL when empty */ - zend_string *version; /* from span->root->property_version; NULL when empty */ - zend_string *span_kind; /* owned copy of meta["span.kind"], NULL if absent or not a string */ - - /* True when the value came from a meta override (serializer must delete that meta key) */ - bool service_from_meta; /* from_meta: an attributes or meta override */ - bool name_from_meta; - bool resource_from_meta; - bool type_from_meta; + zend_string *version; /* from span->property_version; NULL when empty */ + zend_long span_kind; /* SpanData::$spanKind (DDTrace\SpanKind) */ bool has_exception; /* when span->property_exception holds a Throwable */ - bool ignore_error; /* SpanData::$ignoreError, or the deprecated meta["error.ignored"] */ + bool ignore_error; /* SpanData::$ignoreError */ /* Stats-specific fields — precomputed to avoid repeated lookups across two call sites. */ bool has_top_level; /* ddtrace_span_is_entrypoint_root() */ - bool is_measured; /* metrics["_dd.measured"] != 0 */ + bool is_measured; /* attributes["_dd.measured"] != 0 */ bool is_partial_snapshot; /* always false until partial-flush is implemented */ } ddtrace_span_precomputed; /** - * Fill *pre from span's properties and meta hash tables. - * Must be called before any meta modifications (OTel remapping, meta key deletion). + * Fill *pre from the span's properties and attributes. */ void ddtrace_precompute_span(ddtrace_span_data *span, ddtrace_span_precomputed *pre); @@ -54,7 +47,7 @@ void ddtrace_free_span_precomputed(ddtrace_span_precomputed *pre); /** * Compute whether a span should be marked as an error. * Checks the error.message/error.type tags, pre->has_exception, and pre->ignore_error. - * Accurate for both sampled and non-sampled spans (HTTP errors are in PHP meta via + * Accurate for both sampled and non-sampled spans (HTTP errors are in the attributes via * dd_ser_response_committed before the span is closed). */ bool dd_compute_span_is_error(const ddtrace_span_precomputed *pre); diff --git a/tracer/span_tags_view.c b/tracer/span_tags_view.c index 9596d74eba2..1594af87c25 100644 --- a/tracer/span_tags_view.c +++ b/tracer/span_tags_view.c @@ -10,6 +10,7 @@ #include "ddtrace.h" #include "serializer.h" +#include zend_class_entry *ddtrace_ce_span_tags_view; static zend_object_handlers dd_span_tags_view_handlers; @@ -65,8 +66,161 @@ static inline zend_array *dd_tags_attrs_read(ddtrace_span_data *span) { return Z_TYPE_P(attrs) == IS_ARRAY ? Z_ARR_P(attrs) : NULL; } -static void dd_tags_snapshot(zend_array *attrs, bool metrics, zval *rv) { +// Legacy $meta keys aliasing a span property. +enum dd_tags_special { + DD_TAGS_PLAIN, + DD_TAGS_SERVICE, + DD_TAGS_RESOURCE, + DD_TAGS_NAME, + DD_TAGS_TYPE, + DD_TAGS_ENV, + DD_TAGS_VERSION, + DD_TAGS_COMPONENT, + DD_TAGS_SPAN_KIND, + DD_TAGS_IGNORE_ERROR, +}; + +static enum dd_tags_special dd_tags_special_of(zend_string *key) { + switch (ZSTR_LEN(key)) { + case 3: return zend_string_equals_literal(key, "env") ? DD_TAGS_ENV : DD_TAGS_PLAIN; + case 7: return zend_string_equals_literal(key, "version") ? DD_TAGS_VERSION : DD_TAGS_PLAIN; + case 9: + if (zend_string_equals_literal(key, "component")) { + return DD_TAGS_COMPONENT; + } + if (zend_string_equals_literal(key, "span.type")) { + return DD_TAGS_TYPE; + } + return zend_string_equals_literal(key, "span.kind") ? DD_TAGS_SPAN_KIND : DD_TAGS_PLAIN; + case 12: return zend_string_equals_literal(key, "service.name") ? DD_TAGS_SERVICE : DD_TAGS_PLAIN; + case 13: + if (zend_string_equals_literal(key, "resource.name")) { + return DD_TAGS_RESOURCE; + } + return zend_string_equals_literal(key, "error.ignored") ? DD_TAGS_IGNORE_ERROR : DD_TAGS_PLAIN; + case 14: return zend_string_equals_literal(key, "operation.name") ? DD_TAGS_NAME : DD_TAGS_PLAIN; + default: return DD_TAGS_PLAIN; + } +} + +static zval *dd_tags_special_prop(ddtrace_span_data *span, enum dd_tags_special special) { + zval *prop; + switch (special) { + case DD_TAGS_SERVICE: prop = &span->property_service; break; + case DD_TAGS_RESOURCE: prop = &span->property_resource; break; + case DD_TAGS_NAME: prop = &span->property_name; break; + case DD_TAGS_TYPE: prop = &span->property_type; break; + case DD_TAGS_ENV: prop = &span->property_env; break; + case DD_TAGS_VERSION: prop = &span->property_version; break; + case DD_TAGS_COMPONENT: prop = &span->property_component; break; + case DD_TAGS_SPAN_KIND: prop = &span->property_span_kind; break; + default: prop = &span->property_ignore_error; break; + } + ZVAL_DEREF(prop); + return prop; +} + +static zend_long dd_tags_span_kind_of(zval *value) { + ZVAL_DEREF(value); + if (Z_TYPE_P(value) == IS_STRING) { + for (zend_long kind = DDTRACE_SPAN_KIND_INTERNAL; kind <= DDTRACE_SPAN_KIND_CONSUMER; ++kind) { + if (zend_string_equals_cstr(Z_STR_P(value), ddtrace_span_kind_str(kind), strlen(ddtrace_span_kind_str(kind)))) { + return kind; + } + } + } + return DDTRACE_SPAN_KIND_UNSPECIFIED; +} + +// Sets the property aliased by `special`; false for a non-canonical span.kind, which is stored as an attribute. +static bool dd_tags_special_write(ddtrace_span_data *span, enum dd_tags_special special, zval *value) { + zval *prop = dd_tags_special_prop(span, special); + if (special == DD_TAGS_SPAN_KIND) { + // The latest write wins: a canonical kind replaces a non-canonical span.kind attribute and vice versa. + zend_long kind = dd_tags_span_kind_of(value); + zval_ptr_dtor(prop); + ZVAL_LONG(prop, kind); + if (!kind) { + return false; + } + zend_hash_str_del(ddtrace_property_array(&span->property_attributes), ZEND_STRL("span.kind")); + } else if (special == DD_TAGS_IGNORE_ERROR) { + // Deprecated: can only turn $ignoreError on. + if (zend_is_true(value)) { + zval_ptr_dtor(prop); + ZVAL_TRUE(prop); + } + } else { + ZVAL_DEREF(value); + zend_string *str = special == DD_TAGS_NAME && Z_TYPE_P(value) == IS_STRING + ? zend_string_tolower(Z_STR_P(value)) : datadog_convert_to_str(value); + zval_ptr_dtor(prop); + ZVAL_STR(prop, str); + } + return true; +} + +// The $meta read of the property aliased by `special`; false while it holds its empty default. +static bool dd_tags_special_read(ddtrace_span_data *span, enum dd_tags_special special, zval *rv) { + zval *prop = dd_tags_special_prop(span, special); + if (special == DD_TAGS_SPAN_KIND) { + const char *kind = ddtrace_span_kind_str(zval_get_long(prop)); + if (kind) { + ZVAL_STRING(rv, kind); + } + return kind != NULL; + } + if (special == DD_TAGS_IGNORE_ERROR) { + if (zend_is_true(prop)) { + ZVAL_STRINGL(rv, "true", 4); + return true; + } + return false; + } + if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop)) { + ZVAL_COPY(rv, prop); + return true; + } + return false; +} + +static void dd_tags_special_reset(ddtrace_span_data *span, enum dd_tags_special special) { + zval *prop = dd_tags_special_prop(span, special); + zval_ptr_dtor(prop); + if (special == DD_TAGS_SPAN_KIND) { + ZVAL_LONG(prop, DDTRACE_SPAN_KIND_UNSPECIFIED); + } else if (special == DD_TAGS_IGNORE_ERROR) { + ZVAL_FALSE(prop); + } else { + ZVAL_EMPTY_STRING(prop); + } +} + +void ddtrace_span_write_meta(ddtrace_span_data *span, zend_string *key, zval *value, bool metric) { + enum dd_tags_special special = dd_tags_special_of(key); + if (special != DD_TAGS_PLAIN && dd_tags_special_write(span, special, value)) { + return; + } + zval normalized; + ddtrace_normalize_tag_value(&normalized, value, metric); + zend_symtable_update(ddtrace_property_array(&span->property_attributes), key, &normalized); +} + +static const char *const dd_tags_special_keys[] = { + [DD_TAGS_SERVICE] = "service.name", + [DD_TAGS_RESOURCE] = "resource.name", + [DD_TAGS_NAME] = "operation.name", + [DD_TAGS_TYPE] = "span.type", + [DD_TAGS_ENV] = "env", + [DD_TAGS_VERSION] = "version", + [DD_TAGS_COMPONENT] = "component", + [DD_TAGS_SPAN_KIND] = "span.kind", + [DD_TAGS_IGNORE_ERROR] = "error.ignored", +}; + +static void dd_tags_snapshot(ddtrace_span_data *span, bool metrics, zval *rv) { array_init(rv); + zend_array *attrs = dd_tags_attrs_read(span); if (!attrs) { return; } @@ -84,21 +238,63 @@ static void dd_tags_snapshot(zend_array *attrs, bool metrics, zval *rv) { } } } ZEND_HASH_FOREACH_END(); + if (!metrics) { + // $meta also lists the aliased properties, which win over same-named attributes. + for (enum dd_tags_special special = DD_TAGS_SERVICE; special <= DD_TAGS_IGNORE_ERROR; ++special) { + zval prop; + if (dd_tags_special_read(span, special, &prop)) { + zend_hash_str_update(Z_ARR_P(rv), dd_tags_special_keys[special], strlen(dd_tags_special_keys[special]), &prop); + } + } + } } -static zend_long dd_tags_count(zend_array *attrs, bool metrics) { +static zend_long dd_tags_count(ddtrace_span_data *span, bool metrics) { zend_long count = 0; - if (attrs) { - zval *val; - ZEND_HASH_FOREACH_VAL_IND(attrs, val) { - count += dd_tags_in_bucket(val, metrics); - } ZEND_HASH_FOREACH_END(); + zend_array *attrs = dd_tags_attrs_read(span); + if (!attrs) { + return 0; + } + zval *val; + ZEND_HASH_FOREACH_VAL_IND(attrs, val) { + count += dd_tags_in_bucket(val, metrics); + } ZEND_HASH_FOREACH_END(); + if (!metrics) { + for (enum dd_tags_special special = DD_TAGS_SERVICE; special <= DD_TAGS_IGNORE_ERROR; ++special) { + zval prop; + if (dd_tags_special_read(span, special, &prop)) { + zval *dup = zend_hash_str_find(attrs, dd_tags_special_keys[special], strlen(dd_tags_special_keys[special])); + count += !dup || !dd_tags_in_bucket(dup, false); + zval_ptr_dtor(&prop); + } + } } return count; } +// Whether `value` is what a $meta read of the legacy `key` returns: the property, else a same-named attribute. +static bool dd_tags_special_unchanged(ddtrace_span_data *span, enum dd_tags_special special, zend_string *key, zval *value) { + ZVAL_DEREF(value); + if (Z_TYPE_P(value) != IS_STRING) { + return false; + } + zval current; + if (dd_tags_special_read(span, special, ¤t)) { + bool unchanged = zend_string_equals(Z_STR(current), Z_STR_P(value)); + zval_ptr_dtor(¤t); + return unchanged; + } + zval *attr = zend_hash_find(ddtrace_property_array(&span->property_attributes), key); + if (!attr) { + return false; + } + ZVAL_DEREF(attr); + return Z_TYPE_P(attr) == IS_STRING && zend_string_equals(Z_STR_P(attr), Z_STR_P(value)); +} + // Replaces the bucket's entries of $attributes with `values` (normalized), or just clears it. -// Keys kept by `values` are updated in place so that they keep their position. +// Keys kept by `values` are updated in place so that they keep their position. Unchanged legacy keys are +// skipped, so that `$span->meta += [...]` neither rewrites (e.g. lowercases) nor promotes the aliased values. static void dd_tags_replace_bucket(ddtrace_span_data *span, bool metrics, zend_array *values) { zend_array *attrs = ddtrace_property_array(&span->property_attributes); zend_ulong h; @@ -117,11 +313,14 @@ static void dd_tags_replace_bucket(ddtrace_span_data *span, bool metrics, zend_a if (values) { ZEND_HASH_FOREACH_KEY_VAL_IND(values, h, key, val) { - zval normalized; - ddtrace_normalize_tag_value(&normalized, val, metrics); if (key) { - zend_hash_update(attrs, key, &normalized); + enum dd_tags_special special = metrics ? DD_TAGS_PLAIN : dd_tags_special_of(key); + if (special == DD_TAGS_PLAIN || !dd_tags_special_unchanged(span, special, key, val)) { + ddtrace_span_write_meta(span, key, val, metrics); + } } else { + zval normalized; + ddtrace_normalize_tag_value(&normalized, val, metrics); zend_hash_index_update(attrs, h, &normalized); } } ZEND_HASH_FOREACH_END(); @@ -144,6 +343,12 @@ static zval *dd_tags_find(dd_span_tags_view *view, zval *offset, zend_string **k return val; } +// Only $meta aliases span properties: their values are strings. +static bool dd_tags_view_special_read(dd_span_tags_view *view, zend_string *key, zval *rv) { + enum dd_tags_special special = dd_tags_special_of(key); + return view->span && !view->metrics && special != DD_TAGS_PLAIN && dd_tags_special_read(view->span, special, rv); +} + static zval *dd_tags_view_read(dd_span_tags_view *view, zval *offset, int type, zval *rv) { if (!offset) { zend_throw_error(NULL, "Cannot read an appended element of SpanData::$%s", view->metrics ? "metrics" : "meta"); @@ -151,7 +356,9 @@ static zval *dd_tags_view_read(dd_span_tags_view *view, zval *offset, int type, } zend_string *key; zval *val = dd_tags_find(view, offset, &key); - if (val) { + if (!EG(exception) && dd_tags_view_special_read(view, key, rv)) { + // a legacy key aliasing a span property + } else if (val) { ZVAL_COPY_DEREF(rv, val); } else { if (type == BP_VAR_R && !EG(exception)) { @@ -178,16 +385,21 @@ static void dd_tags_view_write(dd_span_tags_view *view, zval *offset, zval *valu ZVAL_DEREF(offset); zend_string *key = zval_get_string(offset); if (!EG(exception)) { - zval normalized; - ddtrace_normalize_tag_value(&normalized, value, view->metrics); - zend_symtable_update(ddtrace_property_array(&view->span->property_attributes), key, &normalized); + ddtrace_span_write_meta(view->span, key, value, view->metrics); } zend_string_release(key); } static bool dd_tags_view_has(dd_span_tags_view *view, zval *offset, int check_empty) { - zval *val = dd_tags_find(view, offset, NULL); - return val && (check_empty ? zend_is_true(val) : 1); + zend_string *key; + zval *val = dd_tags_find(view, offset, &key), special; + bool has = val && (check_empty ? zend_is_true(val) : 1); + if (!EG(exception) && dd_tags_view_special_read(view, key, &special)) { + has = check_empty ? zend_is_true(&special) : 1; + zval_ptr_dtor(&special); + } + zend_string_release(key); + return has; } static void dd_tags_view_unset(dd_span_tags_view *view, zval *offset) { @@ -195,6 +407,12 @@ static void dd_tags_view_unset(dd_span_tags_view *view, zval *offset) { if (dd_tags_find(view, offset, &key)) { zend_symtable_del(ddtrace_property_array(&view->span->property_attributes), key); } + if (view->span && !view->metrics && !EG(exception)) { + enum dd_tags_special special = dd_tags_special_of(key); + if (special != DD_TAGS_PLAIN) { + dd_tags_special_reset(view->span, special); + } + } zend_string_release(key); } @@ -255,14 +473,14 @@ static zend_result dd_tags_view_count_elements(DD_OBJ_ARG, zend_long *count) { static int dd_tags_view_count_elements(DD_OBJ_ARG, zend_long *count) { #endif dd_span_tags_view *view = dd_tags_view_from_obj(DD_OBJ); - *count = dd_tags_count(dd_tags_attrs_read(view->span), view->metrics); + *count = dd_tags_count(view->span, view->metrics); return SUCCESS; } static zend_array *dd_tags_view_snapshot_ht(zend_object *obj) { dd_span_tags_view *view = dd_tags_view_from_obj(obj); zval snapshot; - dd_tags_snapshot(dd_tags_attrs_read(view->span), view->metrics, &snapshot); + dd_tags_snapshot(view->span, view->metrics, &snapshot); return Z_ARR(snapshot); } @@ -319,7 +537,7 @@ PHP_METHOD(DDTrace_SpanTagsView, count) { return; } dd_span_tags_view *view = DD_THIS_VIEW; - RETURN_LONG(dd_tags_count(dd_tags_attrs_read(view->span), view->metrics)); + RETURN_LONG(dd_tags_count(view->span, view->metrics)); } PHP_METHOD(DDTrace_SpanTagsView, getIterator) { @@ -413,7 +631,7 @@ static zval *dd_span_read_property(DD_OBJ_ARG, DD_MEMBER_ARG, int type, void **c } ddtrace_span_data *span = OBJ_SPANDATA(DD_OBJ); if (type == BP_VAR_R || type == BP_VAR_IS) { - dd_tags_snapshot(dd_tags_attrs_read(span), bucket, rv); + dd_tags_snapshot(span, bucket, rv); } else { ZVAL_OBJ(rv, dd_span_tags_view_get(span, bucket)); } @@ -434,7 +652,7 @@ static int dd_span_has_property(DD_OBJ_ARG, DD_MEMBER_ARG, int has_set_exists, v return std_object_handlers.has_property(object, member, has_set_exists, cache_slot); } if (has_set_exists == 1) { // empty() - return dd_tags_count(dd_tags_attrs_read(OBJ_SPANDATA(DD_OBJ)), bucket) > 0; + return dd_tags_count(OBJ_SPANDATA(DD_OBJ), bucket) > 0; } return 1; } @@ -480,7 +698,7 @@ static zend_array *dd_span_properties_with_tags(zend_object *obj, zend_array *pr int bucket = key ? dd_tags_bucket_of(key) : -1; zval copy; if (bucket >= 0) { - dd_tags_snapshot(dd_tags_attrs_read(OBJ_SPANDATA(obj)), bucket, ©); + dd_tags_snapshot(OBJ_SPANDATA(obj), bucket, ©); } else { ZVAL_COPY(©, val); } diff --git a/tracer/span_tags_view.h b/tracer/span_tags_view.h index 1b4e9e0982f..5a60e0f0464 100644 --- a/tracer/span_tags_view.h +++ b/tracer/span_tags_view.h @@ -13,6 +13,10 @@ extern zend_class_entry *ddtrace_ce_span_tags_view; void ddtrace_register_span_tags_view(void); void ddtrace_span_tags_view_install(zend_object_handlers *handlers); void ddtrace_span_tags_views_release(ddtrace_span_data *span); +// One $meta (or $metrics) entry write: the legacy keys aliasing span properties (service.name, +// resource.name, operation.name, span.type, env, version, component, span.kind, error.ignored) set +// the property, any other key the normalized value in $attributes. +void ddtrace_span_write_meta(ddtrace_span_data *span, zend_string *key, zval *value, bool metric); // Handles assignments to $meta/$metrics; false for any other property. bool ddtrace_span_tags_view_write_property(zend_object *obj, zend_string *name, zval *value); diff --git a/tracer/trace_filter.c b/tracer/trace_filter.c index fc6178a825f..3dc8bd89abb 100644 --- a/tracer/trace_filter.c +++ b/tracer/trace_filter.c @@ -24,7 +24,7 @@ ZEND_EXTERN_MODULE_GLOBALS(datadog); static const char *ddtrace_root_tag_value(const void *ctx, const char *key, uintptr_t key_len, uintptr_t *out_len) { ddtrace_span_data *root = (ddtrace_span_data *)ctx; - // Check well-known span struct properties first (not in meta). + // Check well-known span struct properties first (not in attributes). #define CHECK_PROP(name_lit, prop) \ if (key_len == sizeof(name_lit) - 1 \ && memcmp(key, name_lit, sizeof(name_lit) - 1) == 0) { \ @@ -44,6 +44,23 @@ static const char *ddtrace_root_tag_value(const void *ctx, const char *key, uint CHECK_PROP("resource", property_resource) #undef CHECK_PROP + // The component and span.kind tags are properties too, when set. + if (key_len == sizeof("component") - 1 && memcmp(key, "component", sizeof("component") - 1) == 0) { + zval *component = &root->property_component; + ZVAL_DEREF(component); + if (Z_TYPE_P(component) == IS_STRING && Z_STRLEN_P(component)) { + *out_len = Z_STRLEN_P(component); + return Z_STRVAL_P(component); + } + } + if (key_len == sizeof("span.kind") - 1 && memcmp(key, "span.kind", sizeof("span.kind") - 1) == 0) { + const char *kind = ddtrace_span_kind_str(zval_get_long(&root->property_span_kind)); + if (kind) { + *out_len = strlen(kind); + return kind; + } + } + // Attributes: string tags as-is, numbers as stringified floats, bools as on the v0.4 wire. zval *attr = zend_hash_str_find(ddtrace_property_array(&root->property_attributes), key, key_len); if (attr) { @@ -68,7 +85,6 @@ static const char *ddtrace_root_tag_value(const void *ctx, const char *key, uint } } - // Meta struct: key-presence only (value is unrepresentable as a string). zend_array *meta_struct = ddtrace_property_array(&root->property_meta_struct); if (meta_struct && zend_hash_str_exists(meta_struct, key, key_len)) { diff --git a/tracer/trace_source.c b/tracer/trace_source.c index 994c1104909..2a705c59042 100644 --- a/tracer/trace_source.c +++ b/tracer/trace_source.c @@ -36,15 +36,15 @@ static void ddtrace_trace_source_add_propagated_tag(zend_string *encoded) { zend_string_release(encoded); } -static void ddtrace_add_trace_source_to_meta(zend_string *encoded, zend_array *meta) +static void ddtrace_add_trace_source_to_attributes(zend_string *encoded, zend_array *attributes) { - if (!meta || !encoded) { + if (!attributes || !encoded) { return; } zval trace_source_zv; ZVAL_STR(&trace_source_zv, zend_string_copy(encoded)); - zend_hash_str_update(meta, ZEND_STRL(DD_P_TS_KEY), &trace_source_zv); + zend_hash_str_update(attributes, ZEND_STRL(DD_P_TS_KEY), &trace_source_zv); } void ddtrace_trace_source_set_asm_source() { @@ -56,22 +56,22 @@ void ddtrace_trace_source_set_asm_source() { return; } - zend_array *meta = ddtrace_property_array(&root_span->property_attributes); - if (!meta) { + zend_array *attributes = ddtrace_property_array(&root_span->property_attributes); + if (!attributes) { return; } zend_string *encoded = ddtrace_trace_source_get_encoded(TRACE_SOURCE_ASM); - ddtrace_add_trace_source_to_meta(encoded, meta); + ddtrace_add_trace_source_to_attributes(encoded, attributes); ddtrace_trace_source_add_propagated_tag(encoded); } -bool ddtrace_trace_source_is_meta_asm_sourced(zend_array *meta) { - if (!meta) { +bool ddtrace_trace_source_is_asm_sourced(zend_array *attributes) { + if (!attributes) { return false; } - zval *trace_source_zv = zend_hash_str_find(meta, ZEND_STRL(DD_P_TS_KEY)); + zval *trace_source_zv = zend_hash_str_find(attributes, ZEND_STRL(DD_P_TS_KEY)); if (!trace_source_zv || Z_TYPE_P(trace_source_zv) != IS_STRING) { return false; } diff --git a/tracer/trace_source.h b/tracer/trace_source.h index 7b45d7230af..9208f30923c 100644 --- a/tracer/trace_source.h +++ b/tracer/trace_source.h @@ -7,9 +7,8 @@ void ddtrace_trace_source_minit(void); zend_string *ddtrace_trace_source_get_encoded(uint32_t source); -void ddtrace_trace_source_set_from_hexadecimal(zend_string *hexadecimal, zend_array *meta); void ddtrace_trace_source_set_asm_source(void); bool ddtrace_trace_source_is_trace_asm_sourced(zval *trace); -bool ddtrace_trace_source_is_meta_asm_sourced(zend_array *meta); +bool ddtrace_trace_source_is_asm_sourced(zend_array *attributes); #endif // DD_TRACE_SOURCE_H diff --git a/tracer/tracer_startup_logging.c b/tracer/tracer_startup_logging.c index 2e1e1a05f9e..0b760d17ddb 100644 --- a/tracer/tracer_startup_logging.c +++ b/tracer/tracer_startup_logging.c @@ -17,11 +17,9 @@ void ddtrace_populate_startup_config(HashTable *ht) { // Cross-language tracer values - dd_add_assoc_bool(ht, ZEND_STRL("analytics_enabled"), get_DD_TRACE_ANALYTICS_ENABLED()); dd_add_assoc_double(ht, ZEND_STRL("sample_rate"), get_DD_TRACE_SAMPLE_RATE()); dd_add_assoc_array(ht, ZEND_STRL("sampling_rules"), dd_array_copy(get_DD_TRACE_SAMPLING_RULES())); - // TODO Add integration-specific config: integration__analytics_enabled, - // integration__sample_rate, integrations_loaded + // TODO Add integration-specific config: integrations_loaded dd_add_assoc_array(ht, ZEND_STRL("tags"), dd_array_copy(get_DD_TAGS())); dd_add_assoc_array(ht, ZEND_STRL("service_mapping"), dd_array_copy(get_DD_SERVICE_MAPPING())); // "log_injection_enabled" N/A for PHP diff --git a/tracer/tracer_tag_propagation/tracer_tag_propagation.c b/tracer/tracer_tag_propagation/tracer_tag_propagation.c index a9897ace4ef..71f7d6981a8 100644 --- a/tracer/tracer_tag_propagation/tracer_tag_propagation.c +++ b/tracer/tracer_tag_propagation/tracer_tag_propagation.c @@ -11,27 +11,27 @@ ZEND_EXTERN_MODULE_GLOBALS(datadog); -void ddtrace_drop_propagated_tags(zend_array *tags, zend_array *propagated_tags) { +void ddtrace_drop_propagated_tags(zend_array *root_attributes, zend_array *propagated_tags) { zend_string *tagname; ZEND_HASH_FOREACH_STR_KEY(propagated_tags, tagname) { - zend_hash_del(tags, tagname); + zend_hash_del(root_attributes, tagname); } ZEND_HASH_FOREACH_END(); } -void ddtrace_clean_tracer_tags(zend_array *root_meta, zend_array *propagated_tags) { - ddtrace_drop_propagated_tags(root_meta, propagated_tags); +void ddtrace_clean_tracer_tags(zend_array *root_attributes, zend_array *propagated_tags) { + ddtrace_drop_propagated_tags(root_attributes, propagated_tags); zend_hash_clean(propagated_tags); } -void ddtrace_add_tracer_tags_from_header(zend_string *headerstr, zend_array *root_meta, zend_array *propagated_tags) { - ddtrace_clean_tracer_tags(root_meta, propagated_tags); +void ddtrace_add_tracer_tags_from_header(zend_string *headerstr, zend_array *root_attributes, zend_array *propagated_tags) { + ddtrace_clean_tracer_tags(root_attributes, propagated_tags); char *header = ZSTR_VAL(headerstr), *headerend = header + ZSTR_LEN(headerstr); if (ZSTR_LEN(headerstr) > 512) { zval error_zv; ZVAL_STRING(&error_zv, "extract_max_size"); - zend_hash_str_update(root_meta, ZEND_STRL("_dd.propagation_error"), &error_zv); + zend_hash_str_update(root_attributes, ZEND_STRL("_dd.propagation_error"), &error_zv); return; } @@ -50,7 +50,7 @@ void ddtrace_add_tracer_tags_from_header(zend_string *headerstr, zend_array *roo strncmp(ZSTR_VAL(tag_name), "_dd.p.", sizeof("_dd.p.") - 1) == 0) { zval zv; ZVAL_STRINGL(&zv, valuestart, header - valuestart); - zend_hash_update(root_meta, tag_name, &zv); + zend_hash_update(root_attributes, tag_name, &zv); zend_hash_add_empty_element(propagated_tags, tag_name); } zend_string_release(tag_name); @@ -63,13 +63,13 @@ void ddtrace_add_tracer_tags_from_header(zend_string *headerstr, zend_array *roo zval error_zv; ZVAL_STRING(&error_zv, "decoding_error"); - zend_hash_str_update(root_meta, ZEND_STRL("_dd.propagation_error"), &error_zv); + zend_hash_str_update(root_attributes, ZEND_STRL("_dd.propagation_error"), &error_zv); } } } -void ddtrace_add_tracer_tags_from_array(zend_array *array, zend_array *root_meta, zend_array *propagated_tags) { - ddtrace_clean_tracer_tags(root_meta, propagated_tags); +void ddtrace_add_tracer_tags_from_array(zend_array *array, zend_array *root_attributes, zend_array *propagated_tags) { + ddtrace_clean_tracer_tags(root_attributes, propagated_tags); zend_string *tagname; zval *tag; @@ -77,7 +77,7 @@ void ddtrace_add_tracer_tags_from_array(zend_array *array, zend_array *root_meta if (tagname) { zval tagstr; datadog_convert_to_string(&tagstr, tag); - zend_hash_update(root_meta, tagname, &tagstr); + zend_hash_update(root_attributes, tagname, &tagstr); zend_hash_add_empty_element(propagated_tags, tagname); } } @@ -95,40 +95,39 @@ static zend_array *ddtrace_get_propagated() { } // Propagated tag values live in the root span's $attributes (the preset before a root exists). -static zend_array *ddtrace_get_root_meta() { - zend_array *root_meta = &DDTRACE_G(root_span_tags_preset); +static zend_array *ddtrace_get_root_attributes() { + zend_array *root_attributes = &DDTRACE_G(root_span_tags_preset); ddtrace_root_span_data *root_span = DDTRACE_G(active_stack)->root_span; if (root_span) { - root_meta = ddtrace_property_array(&root_span->property_attributes); + root_attributes = ddtrace_property_array(&root_span->property_attributes); } - return root_meta; + return root_attributes; } - zval *ddtrace_propagated_tags_get_tag(const char *tag) { if (!tag) { return NULL; } zend_array *propagated = ddtrace_get_propagated(); - zend_array *root_meta = ddtrace_get_root_meta(); + zend_array *root_attributes = ddtrace_get_root_attributes(); size_t tag_len = strlen(tag); if (!zend_hash_str_find(propagated, tag, tag_len)) { return NULL; } - return zend_hash_str_find(root_meta, tag, tag_len); + return zend_hash_str_find(root_attributes, tag, tag_len); } void ddtrace_get_propagated_tags(zend_array *tags) { zend_array *propagated = ddtrace_get_propagated(); - zend_array *root_meta = ddtrace_get_root_meta(); + zend_array *root_attributes = ddtrace_get_root_attributes(); zend_string *tagname; ZEND_HASH_FOREACH_STR_KEY(propagated, tagname) { zval *tag; - if ((tag = zend_hash_find(root_meta, tagname))) { + if ((tag = zend_hash_find(root_attributes, tagname))) { Z_TRY_ADDREF_P(tag); zend_hash_update(tags, tagname, tag); } @@ -138,9 +137,9 @@ void ddtrace_get_propagated_tags(zend_array *tags) { zend_string *ddtrace_format_root_propagated_tags(void) { zend_array *propagated = ddtrace_get_propagated(); - zend_array *root_meta = ddtrace_get_root_meta(); + zend_array *root_attributes = ddtrace_get_root_attributes(); - return ddtrace_format_propagated_tags(propagated, root_meta); + return ddtrace_format_propagated_tags(propagated, root_attributes); } zend_string *ddtrace_format_propagated_tags(zend_array *propagated, zend_array *tags) { @@ -215,11 +214,11 @@ zend_string *ddtrace_format_propagated_tags(zend_array *propagated, zend_array * void ddtrace_add_propagated_tag(zend_string *key, zval *value) { zend_array *propagated = ddtrace_get_propagated(); - zend_array *root_meta = ddtrace_get_root_meta(); + zend_array *root_attributes = ddtrace_get_root_attributes(); zval tagstr; datadog_convert_to_string(&tagstr, value); - zend_hash_update(root_meta, key, &tagstr); + zend_hash_update(root_attributes, key, &tagstr); zend_hash_add_empty_element(propagated, key); } diff --git a/tracer/tracer_tag_propagation/tracer_tag_propagation.h b/tracer/tracer_tag_propagation/tracer_tag_propagation.h index e93ab976da2..f0a534ad513 100644 --- a/tracer/tracer_tag_propagation/tracer_tag_propagation.h +++ b/tracer/tracer_tag_propagation/tracer_tag_propagation.h @@ -5,11 +5,11 @@ #include -// Deletes the values of `propagated_tags` from `tags`, keeping the propagated list. -void ddtrace_drop_propagated_tags(zend_array *tags, zend_array *propagated_tags); -void ddtrace_clean_tracer_tags(zend_array *root_meta, zend_array *propagated_tags); -void ddtrace_add_tracer_tags_from_header(zend_string *headerstr, zend_array *root_meta, zend_array *propagated_tags); -void ddtrace_add_tracer_tags_from_array(zend_array *array, zend_array *root_meta, zend_array *propagated_tags); +// Deletes the values of `propagated_tags` from `root_attributes`, keeping the propagated list. +void ddtrace_drop_propagated_tags(zend_array *root_attributes, zend_array *propagated_tags); +void ddtrace_clean_tracer_tags(zend_array *root_attributes, zend_array *propagated_tags); +void ddtrace_add_tracer_tags_from_header(zend_string *headerstr, zend_array *root_attributes, zend_array *propagated_tags); +void ddtrace_add_tracer_tags_from_array(zend_array *array, zend_array *root_attributes, zend_array *propagated_tags); void ddtrace_add_propagated_tag_on_span_zobj(zend_string *key, zval *value); void ddtrace_add_propagated_tag(zend_string *key, zval *value); diff --git a/tracer/tracer_telemetry.c b/tracer/tracer_telemetry.c index 66848b21c4b..44c5b724c56 100644 --- a/tracer/tracer_telemetry.c +++ b/tracer/tracer_telemetry.c @@ -202,20 +202,12 @@ void ddtrace_telemetry_notify_integration_version(const char *name, size_t name_ } void ddtrace_telemetry_inc_spans_created(ddtrace_span_data *span) { - // Prefer the $span->component property; the tag mirror only happens later at serialization, - // so fall back to the "component" tag for spans (e.g. userland integrations) that set it directly. zval *component_prop = &span->property_component; ZVAL_DEREF(component_prop); - zval *component = NULL; - if (!(Z_TYPE_P(component_prop) == IS_STRING && Z_STRLEN_P(component_prop) > 0)) { - component = ddtrace_span_find_tag(span, ZEND_STRL("component")); - } zend_string *integration = NULL; 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); } else if (span->flags & DDTRACE_SPAN_FLAG_OPENTRACING) { From 82d491c4c8e2bc6531d71e5ab33c1eb4ee2b4ee6 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Mon, 26 Oct 2026 15:24:49 +0100 Subject: [PATCH 07/11] address review --- src/DDTrace/OpenTelemetry/Span.php | 1 - .../Integration/InteroperabilityTest.php | 3 - tests/ext/meta_struct.phpt | 8 +- .../serializer_wire_sidecar_forced_v04.phpt | 19 +++- .../serializer_wire_sidecar_v1.phpt | 15 ++- .../ext/sandbox/safe_to_string_metadata.phpt | 6 +- .../safe_to_string_metadata_ge_php_84.phpt | 6 +- ...safe_to_string_metadata_numeric_keys.phpt} | 14 +-- tests/ext/span_attributes_empty_keys.phpt | 4 +- tests/ext/span_data_meta_view.phpt | 9 +- ...span_data_meta_view_null_aliased_keys.phpt | 49 ++++++++++ .../span_data_meta_view_null_empty_array.phpt | 84 +++++++++++++++++ .../span_link_event_attributes_same_rule.phpt | 81 ++++++++++++++++ .../span_link_typed_scalar_attributes.phpt | 6 +- tests/ext/traced_attribute.phpt | 3 +- tests/ext/traced_attribute_numeric_keys.phpt | 33 +++++++ tracer/ddtrace.stub.php | 11 +-- tracer/ddtrace_arginfo.h | 8 +- tracer/hook/uhook_attributes.c | 15 +-- tracer/serializer.c | 94 +++++++------------ tracer/span.h | 1 - tracer/span_tags_view.c | 7 ++ tracer/span_tags_view.h | 2 +- 23 files changed, 361 insertions(+), 118 deletions(-) rename tests/ext/sandbox/{safe_to_string_metadata_drops_invalid_keys.phpt => safe_to_string_metadata_numeric_keys.phpt} (69%) create mode 100644 tests/ext/span_data_meta_view_null_aliased_keys.phpt create mode 100644 tests/ext/span_data_meta_view_null_empty_array.phpt create mode 100644 tests/ext/span_link_event_attributes_same_rule.phpt create mode 100644 tests/ext/traced_attribute_numeric_keys.phpt diff --git a/src/DDTrace/OpenTelemetry/Span.php b/src/DDTrace/OpenTelemetry/Span.php index feb8d3aa5cb..2de51838812 100644 --- a/src/DDTrace/OpenTelemetry/Span.php +++ b/src/DDTrace/OpenTelemetry/Span.php @@ -636,7 +636,6 @@ private function createAndSaveSpanLink(SpanContextInterface $context, iterable $ $spanLink->spanId = $context->getSpanId(); $spanLink->traceState = (string)$context->getTraceState(); // __toString() $spanLink->attributes = $attributes; - $spanLink->droppedAttributesCount = 0; // Attributes limit aren't supported/meaningful in DD // Save the link if (is_null($link)) { diff --git a/tests/OpenTelemetry/Integration/InteroperabilityTest.php b/tests/OpenTelemetry/Integration/InteroperabilityTest.php index 2998a18890c..209a0e1011f 100644 --- a/tests/OpenTelemetry/Integration/InteroperabilityTest.php +++ b/tests/OpenTelemetry/Integration/InteroperabilityTest.php @@ -1065,13 +1065,11 @@ public function testSpanLinksInteroperabilityFromOpenTelemetrySpan() $this->assertSame('8765432112345678', $spanLink->spanId); $this->assertSame('dd=t.dm:-0', $spanLink->traceState); $this->assertSame(['arg1' => 'value1'], $spanLink->attributes); - $this->assertEquals(0, $spanLink->droppedAttributesCount); $otelSpan->end(); }); $this->assertCount(1, $traces[0]['spans']); - // dropped_attributes_count is not surfaced in the V1 structured span_links (no PHP-side source). $this->assertSame([[ 'trace_id' => '12345678876543211234567887654321', 'span_id' => '8765432112345678', @@ -1109,7 +1107,6 @@ public function testSpanLinksInteroperabilityBothTypes() $this->assertSame('8765432112345678', $datadogSpanLinks[0]->spanId); $this->assertSame('dd=t.dm:-0', $datadogSpanLinks[0]->traceState); $this->assertSame(['arg1' => 'value1'], $datadogSpanLinks[0]->attributes); - $this->assertEquals(0, $datadogSpanLinks[0]->droppedAttributesCount); $this->assertSame('ff0000000000051791e0000000000041', $datadogSpanLinks[1]->traceId); $this->assertSame('ff00000000000517', $datadogSpanLinks[1]->spanId); diff --git a/tests/ext/meta_struct.phpt b/tests/ext/meta_struct.phpt index cc274d28dbf..7fe9bc94144 100644 --- a/tests/ext/meta_struct.phpt +++ b/tests/ext/meta_struct.phpt @@ -1,5 +1,5 @@ --TEST-- -Add meta struct string +Add meta struct string; empty and numeric keys are kept (numeric ones as decimal strings) --FILE-- meta_struct["foo"] = "bar"; $span->meta_struct["john"] = ["Doe"]; +$span->meta_struct[""] = "e"; +$span->meta_struct[7] = "n"; DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans()['chunks'][0]['spans']; @@ -31,3 +33,7 @@ string(3) "foo" string(11) "a3 62 61 72" string(4) "john" string(14) "91 a3 44 6f 65" +string(0) "" +string(5) "a1 65" +int(7) +string(5) "a1 6e" diff --git a/tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt b/tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt index 8d70aeabf4a..9c68ced7fad 100644 --- a/tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt +++ b/tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt @@ -23,21 +23,36 @@ $rr = new RequestReplayer(); $rr->clearDumpedData(); // Without the setting the sidecar switches to v1 once its /info fetch completes (well within 3s). -$v04 = $v1 = 0; +$v04 = $v1 = $roots = $empty = 0; for ($i = 0; $i < 30; $i++) { $s = \DDTrace\start_span(); $s->name = "root"; + $s->attributes['empty'] = []; \DDTrace\close_span(); dd_trace_internal_fn("synchronous_flush"); usleep(100000); foreach (($rr->replayAllRequests() ?: []) as $r) { if (strpos($r["uri"], "/v1.0/traces") !== false) $v1++; - if (strpos($r["uri"], "/v0.4/traces") !== false) $v04++; + if (strpos($r["uri"], "/v0.4/traces") === false) continue; + $v04++; + // v0.4 flattens an empty list to no leaf at all, so the attribute is absent. + foreach ((json_decode($r["body"], true) ?: []) as $trace) { + foreach ($trace as $span) { + if (($span["name"] ?? null) === "root") { + $roots++; + $empty += isset($span["meta"]["empty"]) || isset($span["metrics"]["empty"]); + } + } + } } } echo "v0.4 requests: ", $v04 > 0 ? "some" : "none", "\n"; echo "v1 requests: $v1\n"; +echo "root spans: ", $roots > 0 ? "some" : "none", "\n"; +echo "root spans with an 'empty' tag: $empty\n"; ?> --EXPECT-- v0.4 requests: some v1 requests: 0 +root spans: some +root spans with an 'empty' tag: 0 diff --git a/tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt b/tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt index 6e594290002..5b31f90ae72 100644 --- a/tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt +++ b/tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt @@ -29,14 +29,16 @@ for ($i = 0; $i < 100 && $req === null; $i++) { $s = \DDTrace\start_span(); $s->name = "root"; $s->service = "svc"; + $s->attributes['empty'] = []; \DDTrace\close_span(); dd_trace_internal_fn("synchronous_flush"); usleep(100000); foreach (($rr->replayAllRequests() ?: []) as $r) { if (strpos($r["uri"], "/v1.0/traces") === false) continue; - foreach ((json_decode($r["body"], true)["chunks"] ?? []) as $chunk) { - foreach (($chunk["spans"] ?? []) as $span) { - if (($span["name"] ?? null) === "root" && ($span["service"] ?? null) === "svc") { + // Decoded as objects so that an empty list ([]) and an empty map ({}) stay distinct. + foreach ((json_decode($r["body"])->chunks ?? []) as $chunk) { + foreach (($chunk->spans ?? []) as $span) { + if (($span->name ?? null) === "root" && ($span->service ?? null) === "svc") { $req = $r; $foundSpan = $span; } @@ -47,10 +49,13 @@ for ($i = 0; $i < 100 && $req === null; $i++) { echo "uri=" . ($req["uri"] ?? "none") . "\n"; // Derived from the matched span itself, not from $req's truthiness: proves the // v1 payload actually carries the span's own name/service, not just any chunk. -echo "span_name=" . ($foundSpan["name"] ?? "none") . "\n"; -echo "span_service=" . ($foundSpan["service"] ?? "none") . "\n"; +echo "span_name=" . ($foundSpan->name ?? "none") . "\n"; +echo "span_service=" . ($foundSpan->service ?? "none") . "\n"; +// An empty array attribute is an empty V1 list. +echo "empty_attribute=" . (isset($foundSpan->attributes->empty) ? json_encode($foundSpan->attributes->empty) : "absent") . "\n"; ?> --EXPECT-- uri=/v1.0/traces span_name=root span_service=svc +empty_attribute=[] diff --git a/tests/ext/sandbox/safe_to_string_metadata.phpt b/tests/ext/sandbox/safe_to_string_metadata.phpt index 35124b633cf..aa4e47aa403 100644 --- a/tests/ext/sandbox/safe_to_string_metadata.phpt +++ b/tests/ext/sandbox/safe_to_string_metadata.phpt @@ -103,12 +103,10 @@ arg.4: string(4) "true" bool(false) arg.5: string(5) "false" -NULL -arg.6: string(4) "null" - object(Closure)#%d (0) { } -arg.7: string(0) "" +arg.7: array(0) { +} object(DateTime)#%d (3) { ["date"]=> diff --git a/tests/ext/sandbox/safe_to_string_metadata_ge_php_84.phpt b/tests/ext/sandbox/safe_to_string_metadata_ge_php_84.phpt index af954f2124f..fcab8a4d9ab 100644 --- a/tests/ext/sandbox/safe_to_string_metadata_ge_php_84.phpt +++ b/tests/ext/sandbox/safe_to_string_metadata_ge_php_84.phpt @@ -107,9 +107,6 @@ arg.4: string(4) "true" bool(false) arg.5: string(5) "false" -NULL -arg.6: string(4) "null" - object(Closure)#%d (3) { ["name"]=> string(%d) "{closure%s}" @@ -118,7 +115,8 @@ object(Closure)#%d (3) { ["line"]=> int(%d) } -arg.7: string(0) "" +arg.7: array(0) { +} object(DateTime)#%d (3) { ["date"]=> diff --git a/tests/ext/sandbox/safe_to_string_metadata_drops_invalid_keys.phpt b/tests/ext/sandbox/safe_to_string_metadata_numeric_keys.phpt similarity index 69% rename from tests/ext/sandbox/safe_to_string_metadata_drops_invalid_keys.phpt rename to tests/ext/sandbox/safe_to_string_metadata_numeric_keys.phpt index 900eb8dc58f..ede7eea586d 100644 --- a/tests/ext/sandbox/safe_to_string_metadata_drops_invalid_keys.phpt +++ b/tests/ext/sandbox/safe_to_string_metadata_numeric_keys.phpt @@ -1,5 +1,5 @@ --TEST-- -Invalid (non-string) keys in span metadata are dropped +Numeric keys in span metadata are sent as decimal strings, and null values are skipped --FILE-- name = 'MetaToString'; $span->meta = [ 'answer_to_universe' => 42, - 5 => 'should be dropped', - 100 => 'should be dropped as well', + 5 => 'five', + 100 => 'one hundred', 'null_value' => null, ]; }); @@ -24,9 +24,11 @@ unset($span['attributes']['process_id']); var_dump($span['attributes']); ?> --EXPECT-- -array(2) { +array(3) { ["answer_to_universe"]=> string(2) "42" - ["null_value"]=> - string(4) "null" + [5]=> + string(4) "five" + [100]=> + string(11) "one hundred" } diff --git a/tests/ext/span_attributes_empty_keys.phpt b/tests/ext/span_attributes_empty_keys.phpt index 89298343aea..7e139373050 100644 --- a/tests/ext/span_attributes_empty_keys.phpt +++ b/tests/ext/span_attributes_empty_keys.phpt @@ -8,7 +8,7 @@ DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 attributes = [ - '' => 'empty key', // dropped: a top-level attribute needs a key + '' => 'empty key', 'empty' => '', 'nested' => ['a' => ['b' => ['' => 1, 'c' => '']]], 'list' => ['', ['' => '']], @@ -21,7 +21,7 @@ foreach (['', 'empty', 'nested', 'list'] as $key) { } ?> --EXPECT-- -'' => null +'' => "empty key" 'empty' => "" 'nested' => {"a":{"b":{"":1,"c":""}}} 'list' => ["",{"":""}] diff --git a/tests/ext/span_data_meta_view.phpt b/tests/ext/span_data_meta_view.phpt index ca0c13a342f..8121c541492 100644 --- a/tests/ext/span_data_meta_view.phpt +++ b/tests/ext/span_data_meta_view.phpt @@ -37,7 +37,7 @@ var_dump($merged['num'], $merged['x']); $span->meta += ['added' => 'yes']; var_dump($span->attributes['added']); -echo "-- nested values keep the old string leaves\n"; +echo "-- nested values keep the old string leaves, null and empty arrays as they are\n"; $span->meta['nested'] = ['a' => 1, 'b' => [true, null], 'c' => []]; var_dump($span->attributes['nested']); @@ -101,7 +101,7 @@ bool(false) string(2) "42" string(1) "y" string(3) "yes" --- nested values keep the old string leaves +-- nested values keep the old string leaves, null and empty arrays as they are array(3) { ["a"]=> string(1) "1" @@ -110,10 +110,11 @@ array(3) { [0]=> string(4) "true" [1]=> - string(4) "null" + NULL } ["c"]=> - string(0) "" + array(0) { + } } -- whole-array assignment replaces the bucket array(3) { diff --git a/tests/ext/span_data_meta_view_null_aliased_keys.phpt b/tests/ext/span_data_meta_view_null_aliased_keys.phpt new file mode 100644 index 00000000000..c23b1452b51 --- /dev/null +++ b/tests/ext/span_data_meta_view_null_aliased_keys.phpt @@ -0,0 +1,49 @@ +--TEST-- +Writing null to a $meta key aliasing a span property resets the property, as unsetting the key does +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--FILE-- +name = 'aliased'; +$span->meta['env'] = 'meta-env'; +$span->meta['version'] = 'meta-version'; +$span->meta['component'] = 'meta-component'; +$span->meta['span.kind'] = 'not-a-kind'; // not a canonical kind: stored as an attribute +$span->meta['error.ignored'] = true; +$span->attributes['env'] = 'attribute-env'; // a same-named attribute goes away too + +$span->meta['env'] = null; +$span->meta['component'] = null; +$span->meta['span.kind'] = null; +$span->meta['error.ignored'] = null; +$span->meta = ['version' => null] + $span->meta; + +var_dump($span->env, $span->version, $span->component, $span->spanKind, $span->ignoreError); +var_dump(array_intersect_key($span->meta, $keys), array_intersect_key($span->attributes, $keys)); +\DDTrace\close_span(); + +$serialized = dd_trace_serialize_closed_spans()['chunks'][0]['spans'][0]; +foreach (['env', 'version', 'component', 'span_kind'] as $field) { + echo $field, '=', json_encode($serialized[$field] ?? null), "\n"; +} +echo 'attributes=', json_encode(array_intersect_key($serialized['attributes'], $keys)), "\n"; +?> +--EXPECT-- +string(0) "" +string(0) "" +string(0) "" +int(0) +bool(false) +array(0) { +} +array(0) { +} +env=null +version=null +component=null +span_kind=null +attributes=[] diff --git a/tests/ext/span_data_meta_view_null_empty_array.phpt b/tests/ext/span_data_meta_view_null_empty_array.phpt new file mode 100644 index 00000000000..befc55dd957 --- /dev/null +++ b/tests/ext/span_data_meta_view_null_empty_array.phpt @@ -0,0 +1,84 @@ +--TEST-- +null and empty arrays written through SpanData::$meta and $metrics are stored as they are +--DESCRIPTION-- +The views store them unconverted (no "null"/"" or 0.0 placeholder), so the serializer applies its +usual rule: null is skipped and an empty array is an empty list. +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--FILE-- +meta['m_empty'] = []; +$span->meta['m_object'] = new stdClass; +$span->meta['m_null'] = null; +$span->meta['m_nested'] = ['l' => [1, null, []], 'n' => null]; +$span->metrics['x_empty'] = []; +$span->metrics['x_null'] = null; + +echo "-- stored attributes\n"; +var_dump(array_intersect_key($span->attributes, array_flip($keys))); + +echo "-- read-back (an array is a meta entry, null is in neither view)\n"; +$meta = $span->meta; +$metrics = $span->metrics; +foreach ($keys as $key) { + echo $key, ': meta=', array_key_exists($key, $meta) ? json_encode($meta[$key]) : 'absent', + ' metrics=', array_key_exists($key, $metrics) ? json_encode($metrics[$key]) : 'absent', "\n"; +} +\DDTrace\close_span(); + +echo "-- serialized\n"; +$attrs = dd_trace_serialize_closed_spans()['chunks'][0]['spans'][0]['attributes']; +foreach ($keys as $key) { + echo $key, ' => ', array_key_exists($key, $attrs) ? json_encode($attrs[$key]) : 'absent', "\n"; +} +?> +--EXPECT-- +-- stored attributes +array(6) { + ["m_empty"]=> + array(0) { + } + ["m_object"]=> + array(0) { + } + ["m_null"]=> + NULL + ["m_nested"]=> + array(2) { + ["l"]=> + array(3) { + [0]=> + string(1) "1" + [1]=> + NULL + [2]=> + array(0) { + } + } + ["n"]=> + NULL + } + ["x_empty"]=> + array(0) { + } + ["x_null"]=> + NULL +} +-- read-back (an array is a meta entry, null is in neither view) +m_empty: meta=[] metrics=absent +m_object: meta=[] metrics=absent +m_null: meta=absent metrics=absent +m_nested: meta={"l":["1",null,[]],"n":null} metrics=absent +x_empty: meta=[] metrics=absent +x_null: meta=absent metrics=absent +-- serialized +m_empty => [] +m_object => [] +m_null => absent +m_nested => {"l":["1",[]]} +x_empty => [] +x_null => absent diff --git a/tests/ext/span_link_event_attributes_same_rule.phpt b/tests/ext/span_link_event_attributes_same_rule.phpt new file mode 100644 index 00000000000..1f5f4a187f7 --- /dev/null +++ b/tests/ext/span_link_event_attributes_same_rule.phpt @@ -0,0 +1,81 @@ +--TEST-- +The same attributes serialize identically on a span, a span link and a span event +--DESCRIPTION-- +null is skipped (in lists the element is omitted), an empty array is an empty list (an empty object +an empty map), and empty or numeric keys are kept, at the top level and nested. +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--FILE-- + null, + 'empty' => [], + 'object' => new stdClass, + '' => 'empty key', + 7 => 'numeric key', + 'list' => ['a', null, [], ['n' => null, 'e' => []]], + 'map' => ['n' => null, 'e' => [], '' => 1, 3 => 'three', 'l' => [null]], +]; + +$s = \DDTrace\start_span(); +$s->attributes = $attrs; +$link = new \DDTrace\SpanLink(); +$link->traceId = "42"; +$link->spanId = "6"; +$link->attributes = $attrs; +$s->links[] = $link; +$s->events[] = new \DDTrace\SpanEvent('evt', $attrs, 1); +\DDTrace\close_span(); + +$span = dd_trace_serialize_closed_spans()['chunks'][0]['spans'][0]; +// The span also carries tracer attributes (process_id, ...): compare only the ones set here. +$spanAttrs = array_intersect_key($span['attributes'], $attrs); +$linkAttrs = $span['span_links'][0]['attributes']; +$eventAttrs = $span['span_events'][0]['attributes']; +var_dump($spanAttrs === $linkAttrs, $linkAttrs === $eventAttrs); +var_dump($spanAttrs); +?> +--EXPECT-- +bool(true) +bool(true) +array(6) { + ["empty"]=> + array(0) { + } + ["object"]=> + array(0) { + } + [""]=> + string(9) "empty key" + [7]=> + string(11) "numeric key" + ["list"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + array(0) { + } + [2]=> + array(1) { + ["e"]=> + array(0) { + } + } + } + ["map"]=> + array(4) { + ["e"]=> + array(0) { + } + [""]=> + int(1) + [3]=> + string(5) "three" + ["l"]=> + array(0) { + } + } +} diff --git a/tests/ext/span_link_typed_scalar_attributes.phpt b/tests/ext/span_link_typed_scalar_attributes.phpt index aa36fc110cb..c21bda27016 100644 --- a/tests/ext/span_link_typed_scalar_attributes.phpt +++ b/tests/ext/span_link_typed_scalar_attributes.phpt @@ -1,5 +1,5 @@ --TEST-- -Span link scalar attributes keep their PHP type when serialized +Span link scalar attributes keep their PHP type when serialized, and null is skipped --ENV-- DD_TRACE_DEBUG_PRNG_SEED=42 --FILE-- @@ -26,7 +26,7 @@ $spans = dd_clean_spans(); var_dump($spans[0]['span_links'][0]['attributes']); ?> --EXPECT-- -array(6) { +array(5) { ["t"]=> bool(true) ["f"]=> @@ -37,6 +37,4 @@ array(6) { float(1.5) ["s"]=> string(3) "str" - ["n"]=> - string(4) "null" } diff --git a/tests/ext/traced_attribute.phpt b/tests/ext/traced_attribute.phpt index d2ddccf6484..bb0ac55861c 100644 --- a/tests/ext/traced_attribute.phpt +++ b/tests/ext/traced_attribute.phpt @@ -11,7 +11,7 @@ DD_TRACE_GENERATE_ROOT_SPAN=0 include __DIR__ . '/sandbox/dd_dumper.inc'; class Foo { - #[DDTrace\Trace(name: "simplename", resource: "rsrc", type: "typeee", service: "test", attributes: ["a" => "b", "data" => "dog", 1 => "ignored"])] + #[DDTrace\Trace(name: "simplename", resource: "rsrc", type: "typeee", service: "test", attributes: ["a" => "b", "data" => "dog", 1 => "numeric key"])] static function simple($arg) {} /* #[DDTrace\Trace(saveArgs: ["foo"])] @@ -69,6 +69,7 @@ spans(\DDTrace\SpanData) (3) { _dd.svc_src => m a => b data => dog + 1 => numeric key _dd.code_origin.type => exit _dd.code_origin.frames.0.file => %s _dd.code_origin.frames.0.line => 7 diff --git a/tests/ext/traced_attribute_numeric_keys.phpt b/tests/ext/traced_attribute_numeric_keys.phpt new file mode 100644 index 00000000000..4271f0fd9d2 --- /dev/null +++ b/tests/ext/traced_attribute_numeric_keys.phpt @@ -0,0 +1,33 @@ +--TEST-- +#[DDTrace\Trace] numeric $tags and $attributes keys are sent as decimal strings, like any other attribute key +--SKIPIF-- + +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_CODE_ORIGIN_FOR_SPANS_ENABLED=0 +--INI-- +error_reporting=E_ALL +--FILE-- + 'five', 'tag' => 't'], attributes: [7 => 'seven', 8 => 8])] +function numeric() {} + +numeric(); + +$span = dd_clean_spans()[0]; +var_dump(array_intersect_key($span['attributes'], [5 => 1, 'tag' => 1, 7 => 1, 8 => 1])); +?> +--EXPECTF-- +Deprecated: DDTrace\Trace: $tags is deprecated, use $attributes instead in %s on line %d +array(4) { + [5]=> + string(4) "five" + ["tag"]=> + string(1) "t" + [7]=> + string(5) "seven" + [8]=> + int(8) +} diff --git a/tracer/ddtrace.stub.php b/tracer/ddtrace.stub.php index a1e0219cd88..fc9faa4916e 100644 --- a/tracer/ddtrace.stub.php +++ b/tracer/ddtrace.stub.php @@ -90,7 +90,8 @@ public function __construct(string $name, array $attributes = [], ?int $timestam public string $name; /** - * @var array $attributes Event attributes, keeping their type: bool, int, float, string, or nested arrays. + * @var array $attributes Event attributes, keeping their type: bool, int, float, string, or nested arrays + * and objects. Null values are skipped. */ public array $attributes; @@ -134,15 +135,11 @@ class SpanLink { public string $traceState; /** - * @var array $attributes Link attributes, keeping their type: bool, int, float, string, or nested arrays. + * @var array $attributes Link attributes, keeping their type: bool, int, float, string, or nested arrays + * and objects. Null values are skipped. */ public array $attributes; - /** - * @var int $droppedAttributesCount - */ - public int $droppedAttributesCount; - /** * Consumes distributed tracing headers, from which a span link will be constructed. * diff --git a/tracer/ddtrace_arginfo.h b/tracer/ddtrace_arginfo.h index ef4c6ac4a66..4fd9d63ba5e 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: d5f6d646e096319037aa857122a4c995d97ed471 */ + * Stub hash: 79fa4c6dd80602a43ad7a3df0bc2d1fe035d5bff */ #include "zend_constants.h" @@ -751,12 +751,6 @@ static zend_class_entry *register_class_DDTrace_SpanLink(void) 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); - 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_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); - return class_entry; } diff --git a/tracer/hook/uhook_attributes.c b/tracer/hook/uhook_attributes.c index 454e2fca453..d8298a58fc6 100644 --- a/tracer/hook/uhook_attributes.c +++ b/tracer/hook/uhook_attributes.c @@ -146,20 +146,23 @@ static void dd_fill_span_data(dd_uhook_def *def, ddtrace_span_data *span) { ZVAL_LONG(kind, def->kind); } zend_string *key; + zend_ulong num_key; zval *value; if (def->tags) { - ZEND_HASH_FOREACH_STR_KEY_VAL(def->tags, key, value) { - if (key) { - ddtrace_span_write_meta(span, key, value, false); - } + ZEND_HASH_FOREACH_KEY_VAL(def->tags, num_key, key, value) { + zend_string *tag = key ? zend_string_copy(key) : zend_long_to_str((zend_long)num_key); + ddtrace_span_write_meta(span, tag, value, false); + zend_string_release(tag); } ZEND_HASH_FOREACH_END(); } if (def->attributes) { zend_array *attributes = ddtrace_property_array(&span->property_attributes); - ZEND_HASH_FOREACH_STR_KEY_VAL(def->attributes, key, value) { + ZEND_HASH_FOREACH_KEY_VAL(def->attributes, num_key, key, value) { + Z_TRY_ADDREF_P(value); if (key) { - Z_TRY_ADDREF_P(value); zend_hash_update(attributes, key, value); + } else { + zend_hash_index_update(attributes, num_key, value); } } ZEND_HASH_FOREACH_END(); } diff --git a/tracer/serializer.c b/tracer/serializer.c index a51ee6fbeb0..7d9ad6d9f06 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -186,23 +186,19 @@ static int msgpack_write_zval(mpack_writer_t *writer, zval *trace, int level) { static void serialize_meta_struct(mpack_writer_t *writer, zval *meta_struct) { zval *tmp; zend_string *string_key; + zend_ulong num_key; HashTable *ht = Z_ARRVAL_P(meta_struct); - // Integer keys are skipped, and must not be counted in the map's size - uint32_t size = 0; - ZEND_HASH_FOREACH_STR_KEY_VAL_IND(ht, string_key, tmp) { - size += string_key != NULL; - } - ZEND_HASH_FOREACH_END(); - - mpack_start_map(writer, size); + mpack_start_map(writer, zend_hash_num_elements(ht)); - ZEND_HASH_FOREACH_STR_KEY_VAL_IND(ht, string_key, tmp) { - if (!string_key) { - continue; + ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) { + if (string_key) { + mpack_write_cstr(writer, ZSTR_VAL(string_key)); + } else { + char num_str_buf[MAX_ID_BUFSIZ]; + mpack_write_str(writer, num_str_buf, sprintf(num_str_buf, ZEND_ULONG_FMT, num_key)); } - mpack_write_cstr(writer, ZSTR_VAL(string_key)); mpack_write_bin(writer, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); } ZEND_HASH_FOREACH_END(); @@ -975,18 +971,9 @@ static inline bool dd_native_is_hidden_member(zend_string *str_key) { // --- Native attributes -------------------------------------------------------------------------- // -// One emitter fills every attribute map (span, link, event, nested map): scalars keep their PHP type, -// arrays/objects nest as a List/KeyValue (objects as a map of their public properties), and a -// reference cycle becomes the "*RECURSION*" leaf, as in var_dump. The top-level flags set each node's form. -#define DD_ATTR_TOP (1 << 0) // top-level entry: empty keys are skipped -#define DD_ATTR_NULL_AS_STRING (1 << 1) // null is the "null" string (links, events), not skipped -#define DD_ATTR_EMPTY_ARRAY_AS_STRING (1 << 2) // an empty array is the "" tag (spans) - -#define DD_ATTR_SPAN (DD_ATTR_TOP | DD_ATTR_EMPTY_ARRAY_AS_STRING) -#define DD_ATTR_EVENT (DD_ATTR_TOP | DD_ATTR_NULL_AS_STRING) -#define DD_ATTR_LINK (DD_ATTR_TOP | DD_ATTR_NULL_AS_STRING) - -static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string *zkey, zval *value, int flags); +// One rule for every attribute map (span, link, event, nested): scalars keep their PHP type, arrays/objects nest +// as a List/KeyValue, null is skipped, keys go out as they are and a reference cycle is "*RECURSION*", as in var_dump. +static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string *zkey, zval *value); static void dd_attr_emit_list(ddog_AttrList *dest, zval *value); // Builds the list for packed array `value`. @@ -1015,7 +1002,7 @@ static ddog_AttrMap *dd_attr_build_map(zval *value) { ZEND_HASH_FOREACH_KEY_VAL_IND(arr, num_key, str_key, val) { if (!dd_native_is_hidden_member(str_key)) { char numbuf[24]; - dd_attr_emit(attrs, dd_native_member_key(str_key, num_key, numbuf), NULL, val, 0); + dd_attr_emit(attrs, dd_native_member_key(str_key, num_key, numbuf), NULL, val); } } ZEND_HASH_FOREACH_END(); dd_native_unprotect_recursion(value); @@ -1023,7 +1010,7 @@ static ddog_AttrMap *dd_attr_build_map(zval *value) { return map; } -// Emits one list element, preserving the PHP scalar type (nested nulls are skipped). +// Emits one list element, preserving the PHP scalar type. static void dd_attr_emit_list(ddog_AttrList *dest, zval *value) { ZVAL_DEREF(value); switch (Z_TYPE_P(value)) { @@ -1053,18 +1040,13 @@ static void dd_attr_emit_list(ddog_AttrList *dest, zval *value) { } // Emits `value` under `key` into `dest`; `zkey`, when given, is `key` as a zend_string (zero-copy). -static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string *zkey, zval *value, int flags) { - if ((flags & DD_ATTR_TOP) && !key.len) { - return; - } +static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string *zkey, zval *value) { ZVAL_DEREF(value); switch (Z_TYPE_P(value)) { case IS_ARRAY: case IS_OBJECT: if (Z_IS_RECURSIVE_P(value)) { ddog_attributes_add_str(dest, key, DDOG_CHARSLICE_C("*RECURSION*")); - } else if ((flags & DD_ATTR_EMPTY_ARRAY_AS_STRING) && Z_TYPE_P(value) == IS_ARRAY && !zend_hash_num_elements(Z_ARR_P(value))) { - ddog_attributes_add_str(dest, key, DDOG_CHARSLICE_C("")); } else if (dd_native_is_list(value)) { ddog_attributes_add_list(dest, key, dd_attr_build_list(value)); } else { @@ -1072,10 +1054,7 @@ static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string } return; case IS_NULL: - if (!(flags & DD_ATTR_NULL_AS_STRING)) { - return; - } - break; + return; // V1 has no null value case IS_TRUE: case IS_FALSE: ddog_attributes_add_bool(dest, key, Z_TYPE_P(value) == IS_TRUE); @@ -1100,7 +1079,7 @@ static void dd_attr_emit(ddog_Attributes *dest, ddog_CharSlice key, zend_string zend_string_release(str); } -// Emit each SpanLink into the V1 builder span. V1 links carry no dropped_attributes_count. +// Emit each SpanLink into the V1 builder span. static void dd_span_links_to_rust(zend_array *links, ddog_SpanBytes *span) { zval *val; ZEND_HASH_FOREACH_VAL(links, val) { @@ -1132,7 +1111,7 @@ static void dd_span_links_to_rust(zend_array *links, ddog_SpanBytes *span) { zval *aval; ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(attrs), idx, key, aval) { char numbuf[24]; - dd_attr_emit(link_attrs, dd_native_member_key(key, idx, numbuf), NULL, aval, DD_ATTR_LINK); + dd_attr_emit(link_attrs, dd_native_member_key(key, idx, numbuf), NULL, aval); } ZEND_HASH_FOREACH_END(); } } ZEND_HASH_FOREACH_END(); @@ -1187,20 +1166,20 @@ static void dd_span_events_to_rust(zend_array *events, ddog_SpanBytes *span) { zval *aval; ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(attrs), idx, key, aval) { char numbuf[24]; - dd_attr_emit(event_attrs, dd_native_member_key(key, idx, numbuf), NULL, aval, DD_ATTR_EVENT); + dd_attr_emit(event_attrs, dd_native_member_key(key, idx, numbuf), NULL, aval); } ZEND_HASH_FOREACH_END(); } } ZEND_HASH_FOREACH_END(); } -// Value stored through the $meta/$metrics views: meta leaves become strings, metric leaves doubles, -// empty arrays/objects the ""/0.0 placeholder and reference cycles "*RECURSION*"/0.0. +// Value stored through the $meta/$metrics views: meta leaves become strings, metric leaves doubles and +// reference cycles "*RECURSION*"/0.0; null and empty arrays are stored as they are. void ddtrace_normalize_tag_value(zval *dst, zval *value, bool metric) { ZVAL_DEREF(value); if (Z_TYPE_P(value) == IS_ARRAY || Z_TYPE_P(value) == IS_OBJECT) { bool release; zend_array *arr = dd_native_props(value, &release); - if (zend_hash_num_elements(arr) && !Z_IS_RECURSIVE_P(value)) { + if (!Z_IS_RECURSIVE_P(value)) { bool is_list = dd_native_is_list(value); array_init_size(dst, zend_hash_num_elements(arr)); dd_native_protect_recursion(value); @@ -1225,15 +1204,14 @@ void ddtrace_normalize_tag_value(zval *dst, zval *value, bool metric) { dd_native_release_props(arr, release); return; } - bool recursive = Z_IS_RECURSIVE_P(value); dd_native_release_props(arr, release); if (metric) { ZVAL_DOUBLE(dst, 0.0); - } else if (recursive) { - ZVAL_STRINGL(dst, "*RECURSION*", sizeof("*RECURSION*") - 1); } else { - ZVAL_EMPTY_STRING(dst); + ZVAL_STRINGL(dst, "*RECURSION*", sizeof("*RECURSION*") - 1); } + } else if (Z_TYPE_P(value) == IS_NULL) { + ZVAL_NULL(dst); } else if (metric) { ZVAL_DOUBLE(dst, zval_get_double(value)); } else { @@ -1241,7 +1219,7 @@ void ddtrace_normalize_tag_value(zval *dst, zval *value, bool metric) { } } -static void dd_serialize_array_meta_struct_recursively(ddog_SpanBytes *target, zend_string *str, zval *value) { +static void dd_serialize_array_meta_struct_recursively(ddog_SpanBytes *target, ddog_CharSlice key, zval *value) { char *data; size_t size; @@ -1257,9 +1235,7 @@ static void dd_serialize_array_meta_struct_recursively(ddog_SpanBytes *target, z return; } - if (ZSTR_LEN(str)) { - ddog_attributes_add_bytes(ddog_span_get_attributes(target), dd_zend_string_to_CharSlice(str), (ddog_CharSlice){.ptr = data, .len = size}); - } + ddog_attributes_add_bytes(ddog_span_get_attributes(target), key, (ddog_CharSlice){.ptr = data, .len = size}); efree(data); } @@ -1897,11 +1873,11 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddt // $meta/$metrics are views onto $attributes, so this emits them too. zend_string *attr_str_key; + zend_ulong attr_num_key; zval *attr_val; - ZEND_HASH_FOREACH_STR_KEY_VAL_IND(attributes, attr_str_key, attr_val) { - if (attr_str_key) { - dd_attr_emit(rattrs, dd_zend_string_to_CharSlice(attr_str_key), attr_str_key, attr_val, DD_ATTR_SPAN); - } + ZEND_HASH_FOREACH_KEY_VAL_IND(attributes, attr_num_key, attr_str_key, attr_val) { + char numbuf[24]; + dd_attr_emit(rattrs, dd_native_member_key(attr_str_key, attr_num_key, numbuf), attr_str_key, attr_val); } ZEND_HASH_FOREACH_END(); zval *exception_zv = &span->property_exception; @@ -2073,11 +2049,11 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddt zend_array *meta_struct = ddtrace_property_array(&span->property_meta_struct); zend_string *ms_str_key; + zend_ulong ms_num_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(rspan, ms_str_key, ms_val); - } + ZEND_HASH_FOREACH_KEY_VAL_IND(meta_struct, ms_num_key, ms_str_key, ms_val) { + char numbuf[24]; + dd_serialize_array_meta_struct_recursively(rspan, dd_native_member_key(ms_str_key, ms_num_key, numbuf), ms_val); } ZEND_HASH_FOREACH_END(); @@ -2140,7 +2116,7 @@ static void dd_attributes_to_zval(const ddog_Attributes *attrs, zval *out, zval zval v; dd_attr_value_to_zval(value, &v); zval *target = bytes_out && ddog_v1_value_type(value) == ddog_DDOG_V1_ATTR_BYTES ? bytes_out : out; - zend_hash_str_update(Z_ARR_P(target), dd_CharSlice_ptr(key), key.len, &v); + zend_symtable_str_update(Z_ARR_P(target), dd_CharSlice_ptr(key), key.len, &v); } } diff --git a/tracer/span.h b/tracer/span.h index cbc3ea56142..45906eb466f 100644 --- a/tracer/span.h +++ b/tracer/span.h @@ -238,7 +238,6 @@ struct ddtrace_span_link { zval property_span_id; zval property_trace_state; zval property_attributes; - zval property_dropped_attributes_count; }; }; }; diff --git a/tracer/span_tags_view.c b/tracer/span_tags_view.c index 1594af87c25..e9d780fa142 100644 --- a/tracer/span_tags_view.c +++ b/tracer/span_tags_view.c @@ -198,6 +198,13 @@ static void dd_tags_special_reset(ddtrace_span_data *span, enum dd_tags_special void ddtrace_span_write_meta(ddtrace_span_data *span, zend_string *key, zval *value, bool metric) { enum dd_tags_special special = dd_tags_special_of(key); + ZVAL_DEREF(value); + if (special != DD_TAGS_PLAIN && Z_TYPE_P(value) == IS_NULL) { + // null removes the key, as unset() does: the property resets and no same-named attribute is left. + dd_tags_special_reset(span, special); + zend_hash_del(ddtrace_property_array(&span->property_attributes), key); + return; + } if (special != DD_TAGS_PLAIN && dd_tags_special_write(span, special, value)) { return; } diff --git a/tracer/span_tags_view.h b/tracer/span_tags_view.h index 5a60e0f0464..42a2ae6af82 100644 --- a/tracer/span_tags_view.h +++ b/tracer/span_tags_view.h @@ -15,7 +15,7 @@ void ddtrace_span_tags_view_install(zend_object_handlers *handlers); void ddtrace_span_tags_views_release(ddtrace_span_data *span); // One $meta (or $metrics) entry write: the legacy keys aliasing span properties (service.name, // resource.name, operation.name, span.type, env, version, component, span.kind, error.ignored) set -// the property, any other key the normalized value in $attributes. +// the property (null resets it), any other key the normalized value in $attributes. void ddtrace_span_write_meta(ddtrace_span_data *span, zend_string *key, zval *value, bool metric); // Handles assignments to $meta/$metrics; false for any other property. bool ddtrace_span_tags_view_write_property(zend_object *obj, zend_string *name, zval *value); From fa5b46057c349d5889047a43bc0a8f326263028f Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Tue, 27 Oct 2026 11:46:16 +0100 Subject: [PATCH 08/11] test: follow the attribute rule in the remaining tests, bound sidecar wire loops by time --- tests/OpenTelemetry/Integration/API/TracerTest.php | 2 +- .../inprocess_sender_traced_attribute_tags.phpt | 2 -- .../serializer_wire_sidecar_forced_v04.phpt | 7 ++++++- tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt | 3 ++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/OpenTelemetry/Integration/API/TracerTest.php b/tests/OpenTelemetry/Integration/API/TracerTest.php index cf9ca5c7c4a..868fa97e449 100644 --- a/tests/OpenTelemetry/Integration/API/TracerTest.php +++ b/tests/OpenTelemetry/Integration/API/TracerTest.php @@ -292,7 +292,7 @@ public function testSpanAttributes() $this->assertEquals("1.1", $attributes['float-array'][0]); $this->assertEquals("2.2", $attributes['float-array'][1]); $this->assertEquals("3.3", $attributes['float-array'][2]); - $this->assertSame("", $attributes['empty-array']); + $this->assertSame([], $attributes['empty-array']); } /** diff --git a/tests/ext/request-replayer/inprocess_sender_traced_attribute_tags.phpt b/tests/ext/request-replayer/inprocess_sender_traced_attribute_tags.phpt index 67b07b7a5f3..7ae73237b9c 100644 --- a/tests/ext/request-replayer/inprocess_sender_traced_attribute_tags.phpt +++ b/tests/ext/request-replayer/inprocess_sender_traced_attribute_tags.phpt @@ -67,8 +67,6 @@ Deprecated: DDTrace\Trace: $tags is deprecated, use $attributes instead in %s on meta.arr.0='1' meta.arr.1='true' meta.arr.2='2.5' -meta.arr.3='null' meta.i='7' -meta.map.e='' meta.map.k='3' [ddtrace] [info] [%d] No finished traces to be sent to the agent diff --git a/tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt b/tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt index 9c68ced7fad..13bacb5fa5a 100644 --- a/tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt +++ b/tests/ext/request-replayer/serializer_wire_sidecar_forced_v04.phpt @@ -24,7 +24,12 @@ $rr->clearDumpedData(); // Without the setting the sidecar switches to v1 once its /info fetch completes (well within 3s). $v04 = $v1 = $roots = $empty = 0; -for ($i = 0; $i < 30; $i++) { +// Bounded by time, not count: a synchronous flush can take seconds on a loaded runner. +// Run until a v0.4 request was seen and the /info window (~3s) has passed, capped at 40s. +$start = microtime(true); +while (true) { + $elapsed = microtime(true) - $start; + if ($elapsed >= 40 || ($v04 > 0 && $elapsed >= 3)) break; $s = \DDTrace\start_span(); $s->name = "root"; $s->attributes['empty'] = []; diff --git a/tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt b/tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt index 5b31f90ae72..44a6d12250d 100644 --- a/tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt +++ b/tests/ext/request-replayer/serializer_wire_sidecar_v1.phpt @@ -25,7 +25,8 @@ $rr->clearDumpedData(); // several traces per payload: resend "root" until it shows up in any chunk of a v1 request. $req = null; $foundSpan = null; -for ($i = 0; $i < 100 && $req === null; $i++) { +$deadline = microtime(true) + 40; // wall-clock cap: a synchronous flush can take seconds under load +while ($req === null && microtime(true) < $deadline) { $s = \DDTrace\start_span(); $s->name = "root"; $s->service = "svc"; From d5175e479b2cd3e1acfbaa9cb8fa7f69099954f3 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Tue, 27 Oct 2026 12:20:08 +0100 Subject: [PATCH 09/11] address review --- Cargo.lock | 176 +++++++++++++----- Cargo.toml | 13 +- components-rs/common.h | 5 + components-rs/crashtracker.h | 28 --- components-rs/datadog.h | 6 + components-rs/sidecar.h | 11 +- components-rs/tracer_runtime/agent_info.rs | 23 ++- components-rs/tracer_runtime/sidecar.rs | 3 +- components-rs/tracer_runtime/stats.rs | 5 + libdatadog | 2 +- tests/Common/TracerTestTrait.php | 19 +- .../dd_trace_exception_span_event.phpt | 2 +- .../request-replayer/dd_trace_span_event.phpt | 2 +- .../span_link_event_attributes_v04_wire.phpt | 2 +- ...ent_attributes_v04_wire_native_events.phpt | 90 +++++++++ tracer/auto_flush.c | 2 +- tracer/functions.c | 2 +- tracer/serializer.c | 14 -- tracer/serializer.h | 1 - 19 files changed, 298 insertions(+), 108 deletions(-) create mode 100644 tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt diff --git a/Cargo.lock b/Cargo.lock index fea7f2da817..b8588e2fc51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -531,6 +531,7 @@ version = "0.0.1" dependencies = [ "cbindgen 0.29.0", "serde_json", + "winresource", ] [[package]] @@ -650,14 +651,6 @@ dependencies = [ "shlex 2.0.1", ] -[[package]] -name = "cc_utils" -version = "0.1.0" -dependencies = [ - "anyhow", - "cc", -] - [[package]] name = "cesu8" version = "1.1.0" @@ -1283,6 +1276,7 @@ dependencies = [ "console-subscriber", "crossbeam-utils", "datadog-sidecar-macros", + "flate2", "futures", "http 1.4.2", "httpmock", @@ -1310,6 +1304,8 @@ dependencies = [ "prctl", "priority-queue", "rand 0.8.8", + "rmp-serde", + "rmpv", "serde", "serde_json", "serde_with", @@ -2746,7 +2742,7 @@ dependencies = [ [[package]] name = "libdd-capabilities-impl" -version = "7.0.0" +version = "8.0.0" dependencies = [ "anyhow", "bytes", @@ -2760,16 +2756,13 @@ dependencies = [ [[package]] name = "libdd-common" -version = "8.0.0" +version = "9.0.0" dependencies = [ "anyhow", "arc-swap", "bytes", - "cc", "const_format", - "criterion", "futures", - "futures-util", "hex", "http 1.4.2", "http-body", @@ -2781,12 +2774,11 @@ dependencies = [ "indexmap 2.12.1", "libc", "maplit", - "mime", - "multer", "nix 0.29.0", "pin-project", "proptest", "rand 0.8.8", + "rcgen", "regex", "regex-lite", "reqwest 0.13.2", @@ -2798,7 +2790,11 @@ dependencies = [ "tempfile", "thiserror 2.0.18", "tokio", + "tokio-rustls", + "tools", "tower-service", + "webpki-root-certs", + "webpki-roots", "windows-sys 0.52.0", ] @@ -2878,7 +2874,7 @@ dependencies = [ [[package]] name = "libdd-data-pipeline" -version = "12.0.0" +version = "13.0.0" dependencies = [ "anyhow", "arc-swap", @@ -2925,12 +2921,12 @@ dependencies = [ "uuid", "web-time", "zrip", - "zstd", + "zstd 0.14.3", ] [[package]] name = "libdd-data-pipeline-core" -version = "3.0.0" +version = "4.0.0" dependencies = [ "anyhow", "bytes", @@ -2944,12 +2940,12 @@ dependencies = [ "libdd-trace-utils", "serde_json", "thiserror 2.0.18", - "zstd", + "zstd 0.14.3", ] [[package]] name = "libdd-ddsketch" -version = "1.1.3" +version = "1.1.4" dependencies = [ "criterion", "prost", @@ -2961,7 +2957,7 @@ dependencies = [ [[package]] name = "libdd-dogstatsd-client" -version = "8.0.0" +version = "9.0.0" dependencies = [ "anyhow", "async-trait", @@ -2978,12 +2974,19 @@ dependencies = [ name = "libdd-ffe" version = "2.0.0" dependencies = [ + "base64 0.22.1", "bincode", "chrono", "derive_more", + "fastrand", "faststr", + "flate2", + "futures-util", "http 1.4.2", + "http-body-util", + "httpdate", "httpmock", + "hyper", "libdd-capabilities", "libdd-capabilities-impl", "libdd-common", @@ -2992,6 +2995,7 @@ dependencies = [ "log", "lru", "md5", + "percent-encoding", "prost", "pyo3", "semver", @@ -3002,6 +3006,8 @@ dependencies = [ "strum_macros", "thiserror 2.0.18", "tokio", + "tokio-util", + "url", ] [[package]] @@ -3034,6 +3040,8 @@ dependencies = [ "page_size", "serde", "spawn_worker", + "strum", + "strum_macros", "tempfile", "tokio", "tracing", @@ -3053,7 +3061,7 @@ dependencies = [ [[package]] name = "libdd-library-config" -version = "4.2.0" +version = "5.0.0" dependencies = [ "anyhow", "libc", @@ -3077,7 +3085,6 @@ dependencies = [ "constcat", "function_name", "libc_alloc", - "libdd-common", "libdd-common-ffi", "libdd-library-config", ] @@ -3164,7 +3171,6 @@ dependencies = [ "indexmap 2.12.1", "libdd-alloc", "libdd-common", - "libdd-profiling", "libdd-profiling-protobuf", "opentelemetry-proto", "parking_lot", @@ -3174,7 +3180,6 @@ dependencies = [ "reqwest 0.13.2", "rustc-hash", "rustls", - "rustls-platform-verifier", "serde", "serde_json", "strum", @@ -3183,8 +3188,9 @@ dependencies = [ "thiserror 2.0.18", "tokio", "tokio-util", + "tools", "zrip", - "zstd", + "zstd 0.14.3", ] [[package]] @@ -3198,7 +3204,7 @@ dependencies = [ [[package]] name = "libdd-remote-config" -version = "7.0.0" +version = "8.0.0" dependencies = [ "anyhow", "base64 0.22.1", @@ -3227,7 +3233,6 @@ dependencies = [ "strum", "strum_macros", "thiserror 2.0.18", - "time", "tokio", "tokio-util", "tracing", @@ -3236,7 +3241,7 @@ dependencies = [ [[package]] name = "libdd-shared-runtime" -version = "6.0.0" +version = "7.0.0" dependencies = [ "async-trait", "futures", @@ -3252,7 +3257,7 @@ dependencies = [ [[package]] name = "libdd-telemetry" -version = "10.0.0" +version = "11.0.0" dependencies = [ "anyhow", "async-trait", @@ -3275,6 +3280,7 @@ dependencies = [ "sys-info", "tokio", "tokio-util", + "tools", "tracing", "tracing-subscriber", "uuid", @@ -3299,9 +3305,10 @@ dependencies = [ [[package]] name = "libdd-tinybytes" -version = "1.1.5" +version = "1.2.0" dependencies = [ "libdd-tinybytes", + "libdd-trace-model", "once_cell", "pretty_assertions", "proptest", @@ -3311,9 +3318,13 @@ dependencies = [ "test-case", ] +[[package]] +name = "libdd-trace-model" +version = "1.0.0" + [[package]] name = "libdd-trace-normalization" -version = "4.2.0" +version = "4.3.0" dependencies = [ "anyhow", "arbitrary", @@ -3325,7 +3336,7 @@ dependencies = [ [[package]] name = "libdd-trace-obfuscation" -version = "10.0.0" +version = "11.0.0" dependencies = [ "anyhow", "criterion", @@ -3333,6 +3344,7 @@ dependencies = [ "fluent-uri", "libdd-common", "libdd-tinybytes", + "libdd-trace-model", "libdd-trace-protobuf", "libdd-trace-utils", "log", @@ -3344,7 +3356,7 @@ dependencies = [ [[package]] name = "libdd-trace-protobuf" -version = "5.1.0" +version = "5.1.1" dependencies = [ "bolero", "prost", @@ -3358,7 +3370,7 @@ dependencies = [ [[package]] name = "libdd-trace-stats" -version = "11.0.0" +version = "12.0.0" dependencies = [ "anyhow", "arc-swap", @@ -3388,8 +3400,9 @@ dependencies = [ [[package]] name = "libdd-trace-utils" -version = "14.0.0" +version = "15.0.0" dependencies = [ + "allocator-api2", "anyhow", "base64 0.22.1", "bolero", @@ -3414,6 +3427,7 @@ dependencies = [ "libdd-capabilities-impl", "libdd-common", "libdd-tinybytes", + "libdd-trace-model", "libdd-trace-normalization", "libdd-trace-protobuf", "libdd-trace-utils", @@ -3430,10 +3444,11 @@ dependencies = [ "thin-vec", "thread_local", "tokio", + "tools", "tracing", "urlencoding", "zrip", - "zstd", + "zstd 0.14.3", ] [[package]] @@ -3492,7 +3507,7 @@ dependencies = [ "rustls", "tar", "yoke-derive 0.8.2", - "zstd", + "zstd 0.13.3", ] [[package]] @@ -4123,6 +4138,16 @@ dependencies = [ "smallvec", ] +[[package]] +name = "pem" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" +dependencies = [ + "base64 0.22.1", + "serde_core", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -4692,6 +4717,19 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rcgen" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" +dependencies = [ + "pem", + "ring", + "rustls-pki-types", + "time", + "yasna", +] + [[package]] name = "redox_syscall" version = "0.5.8" @@ -5539,7 +5577,7 @@ name = "spawn_worker" version = "0.0.1" dependencies = [ "anyhow", - "cc_utils", + "cc", "fastrand", "io-lifetimes", "libc", @@ -6123,13 +6161,23 @@ name = "tools" version = "0.0.1" dependencies = [ "anyhow", + "bytes", "cargo_metadata", "clap", "colored", + "criterion", + "futures", + "futures-util", + "httparse", "libdd-common", + "mime", + "multer", "quick-xml", + "rand 0.8.8", + "tokio", "toml", "wait-timeout", + "windows-sys 0.52.0", ] [[package]] @@ -6578,18 +6626,18 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +checksum = "58ec80e73fd8baf57bf0d9615554c75348bda990d6d5bbeab964dd068319fecb" dependencies = [ "rustls-pki-types", ] [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "1c1c8e20c8a38fc7d65abfe74eb7280e4aa667e8eec8bc84996d2874810748d9" dependencies = [ "rustls-pki-types", ] @@ -7059,6 +7107,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "winresource" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bc6d36480b829272a5bdabf08e6dca8004761c1da7e35efef800540c66221b" +dependencies = [ + "version_check", +] + [[package]] name = "winver" version = "1.0.0" @@ -7118,6 +7175,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + [[package]] name = "yoke" version = "0.7.5" @@ -7291,7 +7357,16 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ - "zstd-safe", + "zstd-safe 7.2.4", +] + +[[package]] +name = "zstd" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3ae9bf90af6e40197bef767eeefc46ad6397420fe873830bd85e5fbbfb3c70" +dependencies = [ + "zstd-safe 8.2.0", ] [[package]] @@ -7303,11 +7378,20 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "zstd-safe" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded520f16b29e1a9b771c722221b2b0a0398c2316d9bb3c42b458a5414d7434b" +dependencies = [ + "zstd-sys", +] + [[package]] name = "zstd-sys" -version = "2.0.15+zstd.1.5.7" +version = "2.1.2+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +checksum = "481ada9c543b2323cbb7bbdbb5249177fbf0188ed959ed2c15e4b22421c84ed3" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index de6edc48434..b154c83f779 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -258,6 +258,7 @@ hex = { version = "0.4", default-features = false } http = { version = "1.1", default-features = false } http-body = { version = "1", default-features = false } http-body-util = { version = "0.1", default-features = false } +httpdate = { version = "1.0", default-features = false } # allow(workspace-deps-features): httpmock 0.8.0-alpha.1 does not compile # without the `cookies` feature: its own `readers.rs` calls `req.cookies()` # unconditionally while that method is gated behind `cookies`. Keep it as a @@ -314,6 +315,10 @@ quick-xml = { version = "0.37", default-features = false } quote = { version = "1", default-features = false } rand = { version = "0.8", default-features = false } rand_chacha = { version = "0.3.1", default-features = false } +# Test-only: self-signed certificate generation for local TLS servers in integration tests. +# allow(workspace-deps-features): `pem` is required for certificate generation and `ring` selects +# the ring backend instead of rcgen's default aws-lc-rs, which the workspace avoids outside fips. +rcgen = { version = "0.13", default-features = false, features = ["pem", "ring"] } regex = { version = "1.5", default-features = false } regex-lite = { version = "0.1", default-features = false } reqwest = { version = "0.13", default-features = false } @@ -365,6 +370,9 @@ thiserror = { version = "2.0.3", default-features = false } thread_local = { version = "1.1", default-features = false } time = { version = "0.3", default-features = false } tokio = { version = "1.49", default-features = false } +# Test-only: TLS acceptor for local TLS servers in integration tests. +# allow(workspace-deps-features): `tls12` matches the TLS clients under test, which enable rustls/tls12. +tokio-rustls = { version = "0.26", default-features = false, features = ["tls12"] } tokio-util = { version = "0.7.11", default-features = false } toml = { version = "0.8.19", default-features = false } tonic = { version = "0.14", default-features = false } @@ -381,13 +389,16 @@ wait-timeout = { version = "0.2", default-features = false } walkdir = { version = "2.4", default-features = false } wasm-bindgen-futures = { version = "0.4", default-features = false } wasm-bindgen-test = { version = "=0.3.50", default-features = false } +webpki-roots = { version = "1.0.10", default-features = false } +webpki-root-certs = { version = "1.0.10", default-features = false } web-time = { version = "1", default-features = false } windows = { version = "0.59.0", default-features = false } windows-sys = { version = "0.52", default-features = false } +winresource = { version = "0.1", default-features = false } winver = { version = "1.0.0", default-features = false } zip = { version = "4.0.0", default-features = false } zrip = { version = "=0.6.0", default-features = false } -zstd = { version = "0.13", default-features = false } +zstd = { version = "0.14.3", default-features = false } zwohash = { version = "0.1.2", default-features = false } diff --git a/components-rs/common.h b/components-rs/common.h index 95c0402fa2b..470ea263b89 100644 --- a/components-rs/common.h +++ b/components-rs/common.h @@ -485,6 +485,11 @@ typedef enum ddog_RemoteConfigCapabilities { DDOG_REMOTE_CONFIG_CAPABILITIES_FFE_FLAG_CONFIGURATION_RULES = 46, DDOG_REMOTE_CONFIG_CAPABILITIES_DD_DATA_STREAMS_TRANSACTION_EXTRACTORS = 47, DDOG_REMOTE_CONFIG_CAPABILITIES_LLM_OBS_ACTIVATION = 48, + /** + * The consumer evaluates prerequisite conditions against a flag's selected variant key. + * Register only when the evaluator implements the dependent-flag variant-key contract. + */ + DDOG_REMOTE_CONFIG_CAPABILITIES_FFE_FLAG_DEPENDENT_FLAG_VARIANT_KEY_V1 = 50, } ddog_RemoteConfigCapabilities; typedef enum ddog_RemoteConfigProduct { diff --git a/components-rs/crashtracker.h b/components-rs/crashtracker.h index d7110398ea7..ddb891bb506 100644 --- a/components-rs/crashtracker.h +++ b/components-rs/crashtracker.h @@ -407,34 +407,6 @@ bool ddog_crasht_init_windows(ddog_CharSlice module, struct ddog_crasht_Metadata metadata); #endif -#if (defined(_CRASHTRACKING_COLLECTOR) && defined(_WIN32)) -HRESULT OutOfProcessExceptionEventSignatureCallback(const void *_context, - const WER_RUNTIME_EXCEPTION_INFORMATION *_exception_information, - int32_t _index, - uint16_t *_name, - uint32_t *_name_size, - uint16_t *_value, - uint32_t *_value_size); -#endif - -#if (defined(_CRASHTRACKING_COLLECTOR) && defined(_WIN32)) -HRESULT OutOfProcessExceptionEventDebuggerLaunchCallback(const void *_context, - const WER_RUNTIME_EXCEPTION_INFORMATION *_exception_information, - BOOL *_is_custom_debugger, - uint16_t *_debugger_launch, - uint32_t *_debugger_launch_size, - BOOL *_is_debugger_auto_launch); -#endif - -#if (defined(_CRASHTRACKING_COLLECTOR) && defined(_WIN32)) -HRESULT OutOfProcessExceptionEventCallback(const void *context, - const WER_RUNTIME_EXCEPTION_INFORMATION *exception_information, - BOOL *_ownership_claimed, - uint16_t *_event_name, - uint32_t *_size, - uint32_t *_signature_count); -#endif - /** * # Safety * The `crash_info` can be null, but if non-null it must point to a Builder made by this module, diff --git a/components-rs/datadog.h b/components-rs/datadog.h index cec183a5088..f93dc465397 100644 --- a/components-rs/datadog.h +++ b/components-rs/datadog.h @@ -145,6 +145,12 @@ void ddog_agent_info_json_free(char *ptr); */ void ddog_apply_agent_info_concentrator_config(struct ddog_AgentInfoReader *reader); +/** + * Whether the in-process sender's v0.4 downgrade can send native `span_events`: the agent's + * /info advertises them. Otherwise span events go to the legacy `events` meta JSON. + */ +bool ddog_agent_has_span_events(void); + void ddog_init_span_func(void (*free_func)(ddog_OwnedZendString), void (*addref_func)(struct _zend_string*), ddog_OwnedZendString (*init_func)(ddog_CharSlice)); diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 45944af1ff7..cf24f8433dc 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -512,9 +512,11 @@ void ddog_send_traces_to_sidecar_v1(ddog_TracerPayloadBytes *builder, * sender (DD_TRACE_SIDECAR_TRACE_SENDER=0). Consumes `builder`. Returns the collection (not one * whole-payload CharSlice) so `auto_flush` can frame each trace individually; a single CharSlice * would drop extra traces of a multi-trace payload. Empty collection on error; free with - * [`crate::span_v04::ddog_free_traces`]. + * [`crate::span_v04::ddog_free_traces`]. Pass `native_span_events` when the agent info + * advertises `span_events`; otherwise span events go to the legacy `events` meta JSON. */ -ddog_TracesBytes *ddog_downgrade_v1_builder_to_v04_traces(ddog_TracerPayloadBytes *builder); +ddog_TracesBytes *ddog_downgrade_v1_builder_to_v04_traces(ddog_TracerPayloadBytes *builder, + bool native_span_events); /** * Drops the agent info reader. @@ -703,7 +705,8 @@ ddog_TraceChunkBytes *ddog_new_chunk(ddog_TracerPayloadBytes *builder, uintptr_t ddog_chunk_span_count(const ddog_TraceChunkBytes *chunk); /** - * Appends an empty span to `chunk`. + * Appends an empty span to `chunk`. Its kind starts as `Unspecified`, so a span without + * `span.kind` goes out as 0 on V1, as Go and Java send it. */ ddog_SpanBytes *ddog_new_span(ddog_TraceChunkBytes *chunk); @@ -747,7 +750,7 @@ void ddog_set_span_version(ddog_SpanBytes *span, ddog_CharSlice value); void ddog_set_span_component(ddog_SpanBytes *span, ddog_CharSlice value); /** - * Sets the span kind from an OTEL wire value (unset/unknown → Unspecified). + * Sets the span kind from an OTEL wire value (0 → Unspecified, unknown → Internal). */ void ddog_set_span_kind(ddog_SpanBytes *span, uint32_t kind); diff --git a/components-rs/tracer_runtime/agent_info.rs b/components-rs/tracer_runtime/agent_info.rs index cf73f020497..11cf5042f41 100644 --- a/components-rs/tracer_runtime/agent_info.rs +++ b/components-rs/tracer_runtime/agent_info.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 //! FFI wrappers that read from the agent /info SHM (`AgentInfoReader`) and propagate -//! the results to the concentrator and trace-filter subsystems. +//! the results to the concentrator and trace-filter subsystems and the v0.4 downgrade. //! //! Both functions perform a single `reader.read()` call (advancing the internal SHM //! position once) and use the returned `changed` flag to decide whether to rebuild @@ -14,8 +14,14 @@ use libdd_common_ffi::slice::CharSlice; use libdd_data_pipeline::agent_info::schema::AgentInfoStruct; use std::ffi::c_char; use std::ffi::CString; +use std::sync::atomic::{AtomicBool, Ordering}; -fn info_to_concentrator_config(info: &AgentInfoStruct) { +/// Whether the agent's /info advertises native v0.4 `span_events`, as of the last change. +static AGENT_SPAN_EVENTS: AtomicBool = AtomicBool::new(false); + +/// Applies agent /info data that changed since the last read. +fn apply_changed_info(info: &AgentInfoStruct) { + AGENT_SPAN_EVENTS.store(info.span_events == Some(true), Ordering::Release); apply_concentrator_config( info.peer_tags.as_deref().unwrap_or(&[]).to_owned(), info.span_kinds_stats_computed @@ -73,7 +79,7 @@ pub unsafe extern "C" fn ddog_apply_agent_info( } else { *container_hash_out = CharSlice::empty(); } - info_to_concentrator_config(info); + apply_changed_info(info); } } } @@ -86,7 +92,7 @@ pub unsafe extern "C" fn ddog_agent_info_as_json(reader: &mut AgentInfoReader) - let (changed, info) = reader.read(); if let Some(info) = info { if changed { - info_to_concentrator_config(info); + apply_changed_info(info); } CString::new(serde_json::to_string(info).unwrap()) .unwrap() @@ -118,6 +124,13 @@ pub unsafe extern "C" fn ddog_apply_agent_info_concentrator_config(reader: &mut return; } if let Some(info) = info { - info_to_concentrator_config(info); + apply_changed_info(info); } } + +/// Whether the in-process sender's v0.4 downgrade can send native `span_events`: the agent's +/// /info advertises them. Otherwise span events go to the legacy `events` meta JSON. +#[no_mangle] +pub extern "C" fn ddog_agent_has_span_events() -> bool { + AGENT_SPAN_EVENTS.load(Ordering::Acquire) +} diff --git a/components-rs/tracer_runtime/sidecar.rs b/components-rs/tracer_runtime/sidecar.rs index 64c1ea9a9c5..6f2177b3f5d 100644 --- a/components-rs/tracer_runtime/sidecar.rs +++ b/components-rs/tracer_runtime/sidecar.rs @@ -7,11 +7,10 @@ use datadog_sidecar::service::exception_hash_rate_limiter::ExceptionHashRateLimi use datadog_sidecar::tracer::shm_limiter_path; use datadog_sidecar_ffi::AgentRemoteConfigReader; use lazy_static::lazy_static; -use libdd_common::rate_limiter::LocalLimiter; use libdd_common::Endpoint; use libdd_common_ffi::slice::AsBytes; use libdd_common_ffi::{self as ffi, CharSlice, MaybeError}; -use libdd_ipc::rate_limiter::{ShmLimiter, ShmLimiterMemory}; +use libdd_ipc::rate_limiter::{LocalLimiter, ShmLimiter, ShmLimiterMemory}; use libdd_telemetry_ffi::try_c; #[cfg(windows)] use spawn_worker::{get_trampoline_target_data, LibDependency}; diff --git a/components-rs/tracer_runtime/stats.rs b/components-rs/tracer_runtime/stats.rs index 79f98086686..9d6423839ae 100644 --- a/components-rs/tracer_runtime/stats.rs +++ b/components-rs/tracer_runtime/stats.rs @@ -185,6 +185,9 @@ fn php_span_to_shm_input<'a>( ShmSpanInput { fixed: build_fixed_key(span), peer_tags: &peer_tag_buf[..peer_tag_count], + // No additional metric tags (DD_TRACE_STATS_ADDITIONAL_TAGS is unsupported), so no limit. + additional_tags: &[], + additional_tags_cardinality_limit: 0, duration_ns: span.duration, is_error: span.is_error, is_top_level: span.has_top_level, @@ -470,6 +473,8 @@ unsafe fn php_span_to_owned_input(span: &PhpSpanStats<'_>) -> OwnedShmSpanInput service_source: fixed.service_source.to_owned(), }, peer_tags, + additional_tags: Vec::new(), + additional_tags_cardinality_limit: 0, duration_ns: span.duration, is_error: span.is_error, is_top_level: span.has_top_level, diff --git a/libdatadog b/libdatadog index 61066493583..86b9b3944b9 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 61066493583f173e67ef4461627b17a656860c3a +Subproject commit 86b9b3944b93bf5b39bd2622cbf8e71e2a84a620 diff --git a/tests/Common/TracerTestTrait.php b/tests/Common/TracerTestTrait.php index b43cab67fe9..6d62c5a5776 100644 --- a/tests/Common/TracerTestTrait.php +++ b/tests/Common/TracerTestTrait.php @@ -461,7 +461,15 @@ private function fromV04Span(array $span) } else { unset($span['error']); } - if (isset($attributes['events']) && is_array($events = json_decode($attributes['events'], true))) { + if (isset($span['span_events'])) { + // Native v0.4 events, for agents advertising span_events: typed attribute values. + foreach ($span['span_events'] as &$event) { + $eventAttributes = array_map([$this, 'fromV04EventValue'], $event['attributes'] ?? []); + $event = ['name' => $event['name'], 'time_unix_nano' => $event['time_unix_nano']] + + ($eventAttributes ? ['attributes' => $eventAttributes] : []); + } + unset($event); + } elseif (isset($attributes['events']) && is_array($events = json_decode($attributes['events'], true))) { $span['span_events'] = $events; unset($attributes['events']); } @@ -477,6 +485,15 @@ private function fromV04Span(array $span) return $span; } + /** A native v0.4 span event attribute value, {"type": <0-4>, "_value": ...}, as a plain value. */ + private function fromV04EventValue(array $value) + { + $field = ['string_value', 'bool_value', 'int_value', 'double_value', 'array_value'][$value['type']]; + return $field === 'array_value' + ? array_map([$this, 'fromV04EventValue'], $value[$field]['values']) + : $value[$field]; + } + private function parseRawDumpedSpans($rawSpans) { $spans = []; 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 b5c2f94e96d..dbeb8f825e9 100644 --- a/tests/ext/request-replayer/dd_trace_exception_span_event.phpt +++ b/tests/ext/request-replayer/dd_trace_exception_span_event.phpt @@ -52,7 +52,7 @@ $replay = $rr->waitForDataAndReplay(); $root = json_decode($replay["body"], true); $span = $root[0][0]; -// The in-process sender (v0.4-only) writes span events as legacy `events` meta JSON. +// The in-process sender (v0.4-only) writes span events as legacy `events` meta JSON: the default /info lacks span_events. $event = json_decode($span['meta']['events'], true)[0]; $attrs = $event['attributes']; var_dump($event['name']); diff --git a/tests/ext/request-replayer/dd_trace_span_event.phpt b/tests/ext/request-replayer/dd_trace_span_event.phpt index 77cd1f9efbd..3d410b44885 100644 --- a/tests/ext/request-replayer/dd_trace_span_event.phpt +++ b/tests/ext/request-replayer/dd_trace_span_event.phpt @@ -44,7 +44,7 @@ $test->testMethod(); $replay = $rr->waitForDataAndReplay(); $root = json_decode($replay["body"], true); $span = $root[0][0]; -// The in-process sender (v0.4-only) writes span events as legacy `events` meta JSON. +// The in-process sender (v0.4-only) writes span events as legacy `events` meta JSON: the default /info lacks span_events. $event = json_decode($span['meta']['events'], true)[0]; $attrs = $event['attributes']; var_dump($event['name'], $event['time_unix_nano']); diff --git a/tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt b/tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt index 249336ee7e0..f4a5e6f6a37 100644 --- a/tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt +++ b/tests/ext/request-replayer/span_link_event_attributes_v04_wire.phpt @@ -5,7 +5,7 @@ v0.4 native span_links and legacy events JSON carry typed floats and objects as if (strncasecmp(PHP_OS, "WIN", 3) == 0) die('skip: the in-process sender is not available on Windows'); if (PHP_VERSION_ID < 70100) die('skip: serialize_precision=-1 requires PHP 7.1'); include __DIR__ . '/../includes/skipif_no_dev_env.inc'; -// Pre-seed a non-v1 /info so the in-process sender negotiates the v0.4 downgrade. +// Pre-seed a non-v1 /info without span_events so the in-process sender downgrades to v0.4 with JSON events. $ctx = stream_context_create(['http' => [ 'method' => 'PUT', 'header' => ["Content-Type: application/json", "X-Datadog-Test-Session-Token: span_link_event_attributes_v04_wire"], diff --git a/tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt b/tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt new file mode 100644 index 00000000000..d016f29212f --- /dev/null +++ b/tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt @@ -0,0 +1,90 @@ +--TEST-- +v0.4 native span_events carry typed values, nested ones under dotted keys, when the agent advertises span_events +--SKIPIF-- + [ + 'method' => 'PUT', + 'header' => ["Content-Type: application/json", "X-Datadog-Test-Session-Token: span_link_event_attributes_v04_wire_native_events"], + 'content' => json_encode(["endpoints" => ["/v0.4/traces", "/v0.6/stats", "/v0.7/config"], "client_drop_p0s" => false, "version" => "7.66.0", "span_events" => true]), +]]); +if (@file_get_contents("http://request-replayer/set-agent-info", false, $ctx) === false) { + die("skip: request-replayer not reachable"); +} +?> +--ENV-- +DD_AGENT_HOST=request-replayer +DD_TRACE_AGENT_PORT=80 +DD_TRACE_AGENT_FLUSH_INTERVAL=333 +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_TRACE_SIDECAR_TRACE_SENDER=0 +--INI-- +datadog.trace.agent_test_session_token=span_link_event_attributes_v04_wire_native_events +serialize_precision=-1 +--FILE-- +clearDumpedData(); +dd_trace_internal_fn('await_agent_info'); + +class Pub { public $a = 1; protected $prot = 'p'; private $priv = 'x'; } + +$floats = [1e20, 1e-5, 0.1, 1.5, 1e17, 123456789012345678.0, -0.0, 3.0]; +$s = \DDTrace\start_span(); +$s->name = "root"; +$link = new \DDTrace\SpanLink(); +$link->traceId = str_repeat('0', 31) . '1'; +$link->spanId = str_repeat('0', 15) . '2'; +$link->attributes = ['floats' => $floats]; +$s->links[] = $link; +$s->events[] = new \DDTrace\SpanEvent('evt', ['f' => 1e20, 'floats' => $floats, 'obj' => new Pub, 'nested' => ['k' => [1e-5]]], 1); +\DDTrace\close_span(); +dd_trace_internal_fn("synchronous_flush"); + +$req = $rr->waitForRequest(function ($r) { return strpos($r["uri"], "traces") !== false; }); +$span = json_decode($req["body"], true)[0][0]; +// Native links carry nested values as a JSON string, as without span_events. +var_dump(!isset($span["meta"]["_dd.span_links"]) && json_decode($span["span_links"][0]["attributes"]["floats"], true) == $floats); +// Native events replace the legacy events meta. +var_dump(isset($span["meta"]["events"])); +$event = $span["span_events"][0]; +var_dump($event["name"], $event["time_unix_nano"]); +$attrs = $event["attributes"]; +ksort($attrs); +var_dump(array_keys($attrs)); +// Floats are typed doubles (type 3), arrays of scalars stay arrays (type 4), object members are dotted keys. +var_dump($attrs["f"]["type"], $attrs["f"]["double_value"] == 1e20); +var_dump($attrs["floats"]["type"], array_column($attrs["floats"]["array_value"]["values"], "type") === array_fill(0, count($floats), 3)); +var_dump(array_column($attrs["floats"]["array_value"]["values"], "double_value") == $floats); +var_dump($attrs["obj.a"] == ["type" => 2, "int_value" => 1]); +var_dump($attrs["nested.k"]["type"], $attrs["nested.k"]["array_value"]["values"][0]["type"], $attrs["nested.k"]["array_value"]["values"][0]["double_value"] == 1e-5); +?> +--EXPECT-- +bool(true) +bool(false) +string(3) "evt" +int(1) +array(4) { + [0]=> + string(1) "f" + [1]=> + string(6) "floats" + [2]=> + string(8) "nested.k" + [3]=> + string(5) "obj.a" +} +int(3) +bool(true) +int(4) +bool(true) +bool(true) +bool(true) +int(4) +int(3) +bool(true) diff --git a/tracer/auto_flush.c b/tracer/auto_flush.c index 2fbff727ab4..3b5f31b50e5 100644 --- a/tracer/auto_flush.c +++ b/tracer/auto_flush.c @@ -98,7 +98,7 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles // In-process sender (DD_TRACE_SIDECAR_TRACE_SENDER=0): its array-of-1 framing can't // parse a native V1 payload (one msgpack MAP), so it downgrades to v0.4 traces. // Consumes ctx->builder; returns a v0.4 collection to free below. - ddog_TracesBytes *v04_traces = ddog_downgrade_v1_builder_to_v04_traces(ctx->builder); + ddog_TracesBytes *v04_traces = ddog_downgrade_v1_builder_to_v04_traces(ctx->builder, ddog_agent_has_span_events()); size_t trace_count = ddog_get_traces_size(v04_traces); for (size_t i = 0; i < trace_count; i++) { // One msgpack array-of-1 per trace, matching the background sender's framing. diff --git a/tracer/functions.c b/tracer/functions.c index 2734e9a6d6e..1005ed35489 100644 --- a/tracer/functions.c +++ b/tracer/functions.c @@ -1344,7 +1344,7 @@ PHP_FUNCTION(DDTrace_Testing_serialize_closed_spans_v04) { add_next_index_zval(return_value, &view); // The in-process sender's downgrade and per-trace framing (auto_flush.c); consumes the builder. - ddog_TracesBytes *v04_traces = ddog_downgrade_v1_builder_to_v04_traces(serialize_ctx.builder); + ddog_TracesBytes *v04_traces = ddog_downgrade_v1_builder_to_v04_traces(serialize_ctx.builder, ddog_agent_has_span_events()); size_t trace_count = ddog_get_traces_size(v04_traces); for (size_t i = 0; i < trace_count; i++) { ddog_CharSlice payload = ddog_serialize_trace_into_charslice(ddog_get_trace(v04_traces, i)); diff --git a/tracer/serializer.c b/tracer/serializer.c index 7d9ad6d9f06..29ac8066c08 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -237,20 +237,6 @@ int ddtrace_serialize_simple_array_into_c_string(zval *trace, char **data_p, siz } } -int ddtrace_serialize_simple_array(zval *trace, zval *retval) { - // encode to memory buffer - char *data; - size_t size; - - if (ddtrace_serialize_simple_array_into_c_string(trace, &data, &size)) { - ZVAL_STRINGL(retval, data, size); - efree(data); - return 1; - } else { - return 0; - } -} - typedef struct dd_error_info { zend_string *type; zend_string *msg; diff --git a/tracer/serializer.h b/tracer/serializer.h index 9cadc3d2a38..02114bac9d1 100644 --- a/tracer/serializer.h +++ b/tracer/serializer.h @@ -3,7 +3,6 @@ #include "components-rs/common.h" #include "span.h" -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); // Returns the span's V1 builder node, or NULL when the span was dropped. From fcdf84a99d5c0b35d3c7c661d77d0a74d53ae905 Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Tue, 3 Nov 2026 15:29:48 +0100 Subject: [PATCH 10/11] test: let the native span_events wire test fetch agent info The test disabled telemetry and the sidecar trace sender, so nothing started the sidecar that fetches the agent /info, and span_events was never advertised. Drop the telemetry opt-out and assert await_agent_info succeeds. --- .../span_link_event_attributes_v04_wire_native_events.phpt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt b/tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt index d016f29212f..ed72a1a6400 100644 --- a/tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt +++ b/tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt @@ -20,7 +20,7 @@ DD_AGENT_HOST=request-replayer DD_TRACE_AGENT_PORT=80 DD_TRACE_AGENT_FLUSH_INTERVAL=333 DD_TRACE_GENERATE_ROOT_SPAN=0 -DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 +DD_INSTRUMENTATION_TELEMETRY_ENABLED=1 DD_TRACE_SIDECAR_TRACE_SENDER=0 --INI-- datadog.trace.agent_test_session_token=span_link_event_attributes_v04_wire_native_events @@ -30,7 +30,7 @@ serialize_precision=-1 include __DIR__ . '/../includes/request_replayer.inc'; $rr = new RequestReplayer(); $rr->clearDumpedData(); -dd_trace_internal_fn('await_agent_info'); +var_dump(dd_trace_internal_fn('await_agent_info')); class Pub { public $a = 1; protected $prot = 'p'; private $priv = 'x'; } @@ -66,6 +66,7 @@ var_dump($attrs["nested.k"]["type"], $attrs["nested.k"]["array_value"]["values"] ?> --EXPECT-- bool(true) +bool(true) bool(false) string(3) "evt" int(1) From 705778ab11070db74faa1f8b69c3dd19cdeb49fe Mon Sep 17 00:00:00 2001 From: Alexandre Rulleau Date: Tue, 3 Nov 2026 17:30:18 +0100 Subject: [PATCH 11/11] test: skip the native span_events wire test before PHP 7.4 like the peer-tags test --- .../span_link_event_attributes_v04_wire_native_events.phpt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt b/tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt index ed72a1a6400..ec3de9394f9 100644 --- a/tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt +++ b/tests/ext/request-replayer/span_link_event_attributes_v04_wire_native_events.phpt @@ -5,6 +5,10 @@ v0.4 native span_events carry typed values, nested ones under dotted keys, when if (strncasecmp(PHP_OS, "WIN", 3) == 0) die('skip: the in-process sender is not available on Windows'); if (PHP_VERSION_ID < 70100) die('skip: serialize_precision=-1 requires PHP 7.1'); include __DIR__ . '/../includes/skipif_no_dev_env.inc'; +if (PHP_VERSION_ID < 70400) die("skip: Before PHP 7.4, the skip-task would cause the sidecar to fetch the info already."); +if (PHP_VERSION_ID >= 80100) { + echo "nocache\n"; +} // Pre-seed a non-v1 /info with span_events so the in-process sender downgrades to v0.4 with native events. $ctx = stream_context_create(['http' => [ 'method' => 'PUT',