diff --git a/ext/configuration.h b/ext/configuration.h index 970b97f212..1ab209a4e5 100644 --- a/ext/configuration.h +++ b/ext/configuration.h @@ -164,9 +164,9 @@ enum ddtrace_sampling_rules_format { CONFIG(BOOL, DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED, "false") \ CONFIG(BOOL, DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED, "false") \ CONFIG(BOOL, DD_TRACE_PROPAGATE_SERVICE, "false") \ - CONFIG(SET_LOWERCASE, DD_TRACE_PROPAGATION_STYLE_EXTRACT, "datadog,tracecontext,B3,B3 single header") \ - CONFIG(SET_LOWERCASE, DD_TRACE_PROPAGATION_STYLE_INJECT, "datadog,tracecontext") \ - CONFIG(SET_LOWERCASE, DD_TRACE_PROPAGATION_STYLE, "datadog,tracecontext", \ + CONFIG(SET_LOWERCASE, DD_TRACE_PROPAGATION_STYLE_EXTRACT, "datadog,tracecontext,B3,B3 single header,baggage") \ + CONFIG(SET_LOWERCASE, DD_TRACE_PROPAGATION_STYLE_INJECT, "datadog,tracecontext,baggage") \ + CONFIG(SET_LOWERCASE, DD_TRACE_PROPAGATION_STYLE, "datadog,tracecontext,baggage", \ .env_config_fallback = ddtrace_conf_otel_propagators) \ CONFIG(SET, DD_TRACE_TRACED_INTERNAL_FUNCTIONS, "") \ CONFIG(INT, DD_TRACE_AGENT_TIMEOUT, DD_CFG_EXPSTR(DD_TRACE_AGENT_TIMEOUT_VAL), \ diff --git a/ext/ddtrace.c b/ext/ddtrace.c index e256d1aeae..cce1f246be 100644 --- a/ext/ddtrace.c +++ b/ext/ddtrace.c @@ -881,6 +881,8 @@ ZEND_METHOD(DDTrace_SpanLink, fromHeaders) { zend_hash_destroy(&result.meta_tags); zend_hash_destroy(&result.propagated_tags); zend_hash_destroy(&result.tracestate_unknown_dd_keys); + zend_hash_destroy(&result.baggage); + if (result.origin) { zend_string_release(result.origin); } @@ -1646,6 +1648,7 @@ static void dd_clean_globals(void) { zend_hash_destroy(&DDTRACE_G(root_span_tags_preset)); zend_hash_destroy(&DDTRACE_G(tracestate_unknown_dd_keys)); zend_hash_destroy(&DDTRACE_G(propagated_root_span_tags)); + zend_hash_destroy(&DDTRACE_G(baggage)); if (DDTRACE_G(curl_multi_injecting_spans)) { if (GC_DELREF(DDTRACE_G(curl_multi_injecting_spans)) == 0) { diff --git a/ext/ddtrace.h b/ext/ddtrace.h index 899e90332b..cd627eeb5c 100644 --- a/ext/ddtrace.h +++ b/ext/ddtrace.h @@ -104,6 +104,7 @@ ZEND_BEGIN_MODULE_GLOBALS(ddtrace) zend_array tracestate_unknown_dd_keys; zend_bool backtrace_handler_already_run; ddtrace_error_data active_error; + HashTable baggage; #ifndef _WIN32 dogstatsd_client dogstatsd_client; #endif diff --git a/ext/ddtrace.stub.php b/ext/ddtrace.stub.php index 066b759dc5..6efb50d719 100644 --- a/ext/ddtrace.stub.php +++ b/ext/ddtrace.stub.php @@ -284,6 +284,12 @@ class RootSpanData extends SpanData { * @var GitMetadata|null The git metadata of the span */ public GitMetadata|null $gitMetadata = null; + + /** + * @var array In OpenTelemetry, Baggage is contextual information that resides next to context. + * 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 = []; } /** diff --git a/ext/ddtrace_arginfo.h b/ext/ddtrace_arginfo.h index d616d445e9..2331989100 100644 --- a/ext/ddtrace_arginfo.h +++ b/ext/ddtrace_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 5edec61a2b1ae22c8473ffbd3c509df6196abbae */ + * Stub hash: 3e5816ef45654bc111875f74d66de5e7d478437f */ 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) @@ -520,7 +520,9 @@ static zend_class_entry *register_class_DDTrace_SpanEvent(zend_class_entry *clas 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); @@ -626,11 +628,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); @@ -658,7 +664,9 @@ 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); @@ -782,6 +790,12 @@ static zend_class_entry *register_class_DDTrace_RootSpanData(zend_class_entry *c 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); + 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_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); + return class_entry; } diff --git a/ext/distributed_tracing_headers.c b/ext/distributed_tracing_headers.c index f54a4d06e4..bf0452255e 100644 --- a/ext/distributed_tracing_headers.c +++ b/ext/distributed_tracing_headers.c @@ -17,6 +17,7 @@ static ddtrace_distributed_tracing_result dd_init_empty_result(void) { 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.baggage, 8, unused, ZVAL_PTR_DTOR, 0); return result; } @@ -42,6 +43,54 @@ static void dd_check_tid(ddtrace_distributed_tracing_result *result) { } } +static void ddtrace_deserialize_baggage(char *baggage_ptr, char *baggage_end, HashTable *baggage) { + while (baggage_ptr < baggage_end) { + char *key_start = baggage_ptr; + while (baggage_ptr < baggage_end && *baggage_ptr != '=') { + ++baggage_ptr; + } + if (baggage_ptr >= baggage_end || *baggage_ptr != '=') break; + + size_t key_len = baggage_ptr - key_start; + ++baggage_ptr; // skip '=' + + char *value_start = baggage_ptr; + while (baggage_ptr < baggage_end && *baggage_ptr != ',') { + ++baggage_ptr; + } + + size_t value_len = baggage_ptr - value_start; + if (key_len > 0 && value_len > 0) { + zend_string *key = zend_string_init(key_start, key_len, 0); + zval value; + ZVAL_STRINGL(&value, value_start, value_len); + zend_hash_update(baggage, key, &value); + zend_string_release(key); + } + + if (baggage_ptr < baggage_end && *baggage_ptr == ',') { + ++baggage_ptr; // skip ',' + } + } +} + +static ddtrace_distributed_tracing_result ddtrace_read_distributed_baggage(ddtrace_read_header *read_header, void *data) { + zend_string *baggage_header; + ddtrace_distributed_tracing_result result = dd_init_empty_result(); + + if (!read_header((zai_str)ZAI_STRL("BAGGAGE"), "baggage", &baggage_header, data)) { + return result; + } + + char *baggage_ptr = ZSTR_VAL(baggage_header); + char *baggage_end = baggage_ptr + ZSTR_LEN(baggage_header); + + ddtrace_deserialize_baggage(baggage_ptr, baggage_end, &result.baggage); + + zend_string_release(baggage_header); + return result; +} + static ddtrace_distributed_tracing_result ddtrace_read_distributed_tracing_ids_datadog(ddtrace_read_header *read_header, void *data) { zend_string *trace_id_str, *parent_id_str, *priority_str, *propagated_tags; ddtrace_distributed_tracing_result result = dd_init_empty_result(); @@ -359,12 +408,16 @@ ddtrace_distributed_tracing_result ddtrace_read_distributed_tracing_ids(ddtrace_ func = ddtrace_read_distributed_tracing_ids_b3; } else if (!has_trace && zend_string_equals_literal(extraction_style, "b3 single header")) { func = ddtrace_read_distributed_tracing_ids_b3_single_header; + } else if (zend_string_equals_literal(extraction_style, "baggage")) { + func = ddtrace_read_distributed_baggage; } else { continue; } if (!has_trace) { zend_string *existing_origin = result.origin; + zend_array existing_baggage = result.baggage; + if (result.meta_tags.arData) { zend_hash_destroy(&result.meta_tags); } @@ -388,8 +441,24 @@ ddtrace_distributed_tracing_result ddtrace_read_distributed_tracing_ids(ddtrace_ result.origin = existing_origin; } } + + if (existing_baggage.arData) { + zend_string *key; + zval *value; + ZEND_HASH_FOREACH_STR_KEY_VAL(&existing_baggage, key, value) { + zend_string *new_key = zend_string_dup(key, 0); + zval new_value; + ZVAL_DUP(&new_value, value); + + zend_hash_update(&result.baggage, new_key, &new_value); + zend_string_release(new_key); + } ZEND_HASH_FOREACH_END(); + + zend_hash_destroy(&existing_baggage); + } } else { ddtrace_distributed_tracing_result new_result = func(read_header, data); + if (result.trace_id.low == new_result.trace_id.low && result.trace_id.high == new_result.trace_id.high) { if (!result.tracestate && new_result.tracestate) { result.tracestate = new_result.tracestate; @@ -415,12 +484,27 @@ ddtrace_distributed_tracing_result ddtrace_read_distributed_tracing_ids(ddtrace_ } } + if (new_result.baggage.arData) { + zend_string *key; + zval *value; + ZEND_HASH_FOREACH_STR_KEY_VAL(&new_result.baggage, key, value) { + zend_string *new_key = zend_string_dup(key, 0); + zval new_value; + ZVAL_DUP(&new_value, value); + + zend_hash_update(&result.baggage, new_key, &new_value); + zend_string_release(new_key); + } ZEND_HASH_FOREACH_END(); + } + if (new_result.tracestate) { zend_string_release(new_result.tracestate); } if (new_result.origin) { zend_string_release(new_result.origin); } + + zend_hash_destroy(&new_result.baggage); zend_hash_destroy(&new_result.meta_tags); zend_hash_destroy(&new_result.propagated_tags); zend_hash_destroy(&new_result.tracestate_unknown_dd_keys); @@ -448,6 +532,10 @@ void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result *Z_ARR(zv) = result->propagated_tags; ddtrace_assign_variable(&span->property_propagated_tags, &zv); + ZVAL_ARR(&zv, emalloc(sizeof(HashTable))); + *Z_ARR(zv) = result->baggage; + ddtrace_assign_variable(&span->property_baggage, &zv); + zend_hash_copy(root_meta, &result->meta_tags, NULL); if (result->origin) { @@ -474,6 +562,8 @@ 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_destroy(&DDTRACE_G(baggage)); + DDTRACE_G(baggage) = result->baggage; zend_hash_copy(&DDTRACE_G(root_span_tags_preset), &result->meta_tags, NULL); if (DDTRACE_G(dd_origin)) { zend_string_release(DDTRACE_G(dd_origin)); diff --git a/ext/distributed_tracing_headers.h b/ext/distributed_tracing_headers.h index b69120cdf2..beb0b6adb8 100644 --- a/ext/distributed_tracing_headers.h +++ b/ext/distributed_tracing_headers.h @@ -10,6 +10,7 @@ typedef struct { uint64_t parent_id; zend_string *origin; zend_string *tracestate; + HashTable baggage; HashTable tracestate_unknown_dd_keys; HashTable propagated_tags; HashTable meta_tags; diff --git a/ext/handlers_http.h b/ext/handlers_http.h index 2cdbec083e..9d2e453edc 100644 --- a/ext/handlers_http.h +++ b/ext/handlers_http.h @@ -101,11 +101,44 @@ static inline zend_string *ddtrace_format_tracestate(zend_string *tracestate, ui return NULL; } +static inline zend_string *ddtrace_serialize_baggage(HashTable *baggage) { + smart_str serialized_baggage = {0}; + zend_string *key; + zval *value; + bool first_entry = true; + + ZEND_HASH_FOREACH_STR_KEY_VAL(baggage, key, value) { + if (!key || Z_TYPE_P(value) != IS_STRING) { + continue; // Skip invalid entries + } + + if (!first_entry) { + smart_str_appendc(&serialized_baggage, ','); // Add comma separator + } else { + first_entry = false; + } + + // Append key=value + smart_str_appendl(&serialized_baggage, ZSTR_VAL(key), ZSTR_LEN(key)); + smart_str_appendc(&serialized_baggage, '='); + smart_str_appendl(&serialized_baggage, Z_STRVAL_P(value), Z_STRLEN_P(value)); + } ZEND_HASH_FOREACH_END(); + + if (!serialized_baggage.s) { + smart_str_free(&serialized_baggage); + } else { + smart_str_0(&serialized_baggage); // Null-terminate + } + + return serialized_baggage.s; +} + static inline void ddtrace_inject_distributed_headers_config(zend_array *array, bool key_value_pairs, zend_array *inject) { ddtrace_root_span_data *root = DDTRACE_G(active_stack) && DDTRACE_G(active_stack)->active ? SPANDATA(DDTRACE_G(active_stack)->active)->root : NULL; zend_string *origin = DDTRACE_G(dd_origin); zend_array *tracestate_unknown_dd_keys = &DDTRACE_G(tracestate_unknown_dd_keys); zend_string *tracestate = DDTRACE_G(tracestate); + zend_array *baggage = &DDTRACE_G(baggage); if (root) { if (Z_TYPE(root->property_origin) == IS_STRING && Z_STRLEN(root->property_origin)) { origin = Z_STR(root->property_origin); @@ -118,6 +151,7 @@ static inline void ddtrace_inject_distributed_headers_config(zend_array *array, tracestate = NULL; } tracestate_unknown_dd_keys = ddtrace_property_array(&root->property_tracestate_tags); + baggage = ddtrace_property_array(&root->property_baggage); } zval headers; @@ -134,6 +168,7 @@ static inline void ddtrace_inject_distributed_headers_config(zend_array *array, bool send_tracestate = zend_hash_str_exists(inject, ZEND_STRL("tracecontext")); bool send_b3 = zend_hash_str_exists(inject, ZEND_STRL("b3")) || zend_hash_str_exists(inject, ZEND_STRL("b3multi")); bool send_b3single = zend_hash_str_exists(inject, ZEND_STRL("b3 single header")); + bool send_baggage = zend_hash_str_exists(inject, ZEND_STRL("baggage")); zend_long sampling_priority = ddtrace_fetch_priority_sampling_from_root(); if (get_DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED() && DDTRACE_G(asm_event_emitted) == true) { @@ -239,6 +274,15 @@ static inline void ddtrace_inject_distributed_headers_config(zend_array *array, } } + if (send_baggage) { + zend_string *full_baggage = ddtrace_serialize_baggage(baggage); + + if (full_baggage) { + ADD_HEADER("baggage", "%.*s", (int)ZSTR_LEN(full_baggage), ZSTR_VAL(full_baggage)); + zend_string_release(full_baggage); + } + } + if (propagated_tags) { zend_string_release(propagated_tags); } diff --git a/ext/serializer.c b/ext/serializer.c index 463756ee99..5e088896a4 100644 --- a/ext/serializer.c +++ b/ext/serializer.c @@ -797,6 +797,7 @@ void ddtrace_set_root_span_properties(ddtrace_root_span_data *span) { if (parent_root) { ddtrace_inherit_span_properties(&span->span, &parent_root->span); ZVAL_COPY(&span->property_origin, &parent_root->property_origin); + ZVAL_COPY(&span->property_baggage, &parent_root->property_baggage); } else { zval *prop_type = &span->property_type; zval *prop_name = &span->property_name; @@ -840,6 +841,9 @@ void ddtrace_set_root_span_properties(ddtrace_root_span_data *span) { zend_hash_copy(Z_ARR(span->property_propagated_tags), &DDTRACE_G(propagated_root_span_tags), zval_add_ref); SEPARATE_ARRAY(&span->property_tracestate_tags); zend_hash_copy(Z_ARR(span->property_tracestate_tags), &DDTRACE_G(tracestate_unknown_dd_keys), zval_add_ref); + SEPARATE_ARRAY(&span->property_baggage); + zend_hash_copy(Z_ARR(span->property_baggage), &DDTRACE_G(baggage), zval_add_ref); + if (DDTRACE_G(propagated_priority_sampling) != DDTRACE_PRIORITY_SAMPLING_UNSET) { ZVAL_LONG(&span->property_propagated_sampling_priority, DDTRACE_G(propagated_priority_sampling)); } diff --git a/ext/span.h b/ext/span.h index c664ead825..75b148db53 100644 --- a/ext/span.h +++ b/ext/span.h @@ -122,6 +122,7 @@ struct ddtrace_root_span_data { zval property_parent_id; zval property_trace_id; zval property_git_metadata; + zval property_baggage; }; static inline ddtrace_root_span_data *ROOTSPANDATA(zend_object *obj) { diff --git a/tests/ext/distributed_tracing/baggage/distributed_trace_baggage_alone.phpt b/tests/ext/distributed_tracing/baggage/distributed_trace_baggage_alone.phpt new file mode 100644 index 0000000000..9569b1cdd1 --- /dev/null +++ b/tests/ext/distributed_tracing/baggage/distributed_trace_baggage_alone.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test baggage header behavior when configured by itself +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_PROPAGATION_STYLE=baggage +--FILE-- + 42, + "x-datadog-parent-id" => 10, + "x-datadog-origin" => "datadog", + "x-datadog-sampling-priority" => 3, + "baggage" => "user.id=123,session.id=abc" + ][$header] ?? null; +}); +var_dump(DDTrace\generate_distributed_tracing_headers()); + +?> +--EXPECT-- +array(1) { + ["baggage"]=> + string(26) "user.id=123,session.id=abc" +} diff --git a/tests/ext/distributed_tracing/baggage/distributed_trace_baggage_default.phpt b/tests/ext/distributed_tracing/baggage/distributed_trace_baggage_default.phpt new file mode 100644 index 0000000000..0fb18c67a2 --- /dev/null +++ b/tests/ext/distributed_tracing/baggage/distributed_trace_baggage_default.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test baggage header interaction with default configurations +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +--FILE-- + 42, + "x-datadog-parent-id" => 10, + "x-datadog-origin" => "datadog", + "x-datadog-sampling-priority" => 3, + "baggage" => "user.id=123,session.id=abc" + ][$header] ?? null; +}); +var_dump(DDTrace\generate_distributed_tracing_headers()); + +?> +--EXPECT-- +array(8) { + ["x-datadog-sampling-priority"]=> + string(1) "3" + ["x-datadog-tags"]=> + string(11) "_dd.p.dm=-0" + ["x-datadog-origin"]=> + string(7) "datadog" + ["x-datadog-trace-id"]=> + string(2) "42" + ["x-datadog-parent-id"]=> + string(2) "10" + ["traceparent"]=> + string(55) "00-0000000000000000000000000000002a-000000000000000a-01" + ["tracestate"]=> + string(24) "dd=o:datadog;s:3;t.dm:-0" + ["baggage"]=> + string(26) "user.id=123,session.id=abc" +} diff --git a/tests/ext/distributed_tracing/baggage/distributed_trace_baggage_first.phpt b/tests/ext/distributed_tracing/baggage/distributed_trace_baggage_first.phpt new file mode 100644 index 0000000000..b4d2c45313 --- /dev/null +++ b/tests/ext/distributed_tracing/baggage/distributed_trace_baggage_first.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test baggage header interaction when is configured as first +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_PROPAGATION_STYLE=baggage,tracecontext +--FILE-- + 42, + "x-datadog-parent-id" => 10, + "x-datadog-origin" => "datadog", + "x-datadog-sampling-priority" => 3, + "traceparent" => "00-0000000000000000000000000000002a-0000000000000001-01", + "tracestate" => "dd=p:00000000000000bb;p:00000000000000bb;s:1", + "baggage" => "user.id=123,session.id=abc" + ][$header] ?? null; +}); +var_dump(DDTrace\generate_distributed_tracing_headers()); + +?> +--EXPECT-- +array(3) { + ["traceparent"]=> + string(55) "00-0000000000000000000000000000002a-0000000000000001-01" + ["tracestate"]=> + string(29) "dd=p:00000000000000bb;t.dm:-0" + ["baggage"]=> + string(26) "user.id=123,session.id=abc" +} diff --git a/tests/ext/distributed_tracing/distributed_trace_consume_func.phpt b/tests/ext/distributed_tracing/distributed_trace_consume_func.phpt index 9c1db8d9eb..b54405d52d 100644 --- a/tests/ext/distributed_tracing/distributed_trace_consume_func.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_consume_func.phpt @@ -11,13 +11,14 @@ DDTrace\consume_distributed_tracing_headers(function ($header) { "x-datadog-parent-id" => 10, "x-datadog-origin" => "datadog", "x-datadog-sampling-priority" => 3, + "baggage" => "user.id=123,session.id=abc" ][$header] ?? null; }); var_dump(DDTrace\generate_distributed_tracing_headers()); ?> --EXPECT-- -array(7) { +array(8) { ["x-datadog-sampling-priority"]=> string(1) "3" ["x-datadog-tags"]=> @@ -32,4 +33,6 @@ array(7) { string(55) "00-0000000000000000000000000000002a-000000000000000a-01" ["tracestate"]=> string(24) "dd=o:datadog;s:3;t.dm:-0" + ["baggage"]=> + string(26) "user.id=123,session.id=abc" }