Skip to content

Commit dfe83ec

Browse files
PROFeNoMbwoebi
andauthored
feat: API Gateway Tracing (#3116)
* feat: InferredSpanData * fix: remove added refcount * Create inferred span from distributed headers consumption * cr: Check that the inferred_span property is an instance of ddtrace_ce_inferred_span_data * style: Refactor metrics/meta data transfer during serialization * (raw) Handle propagated tags & sampling rules * style: refactor inferred span retrieval * Change serialized data transfer location & update snapshots * Return serialized array * fix: return value of ddtrace_serialize_span_to_array * chore: update snapshots * tests: stop using request replayer * tests: update tests * tests: Windows compatibility * fix: SEGV when tracer is disabled * Remove useless inferred_span_created initialization Co-authored-by: Bob Weinand <[email protected]> * Replace transfered data from error.ignored to error Co-authored-by: Bob Weinand <[email protected]> * Change ddtrace_set_global_span_properties location * style: indentation * style: inferred_span consistency * tests: Update after merge * tests: Update after merge * fix: cast proxy_info->component to char * when passing it to add_assoc_string * style: Move _dd.inferred_span to metrics * Fallback to global config on missing domain name * fix: `"error": 1` not properly transferred * tests: Assert proper span duration * tests: Windows tests weird behavior * fix: correct track_error serialization in span metadata * Merge master * tests: Update active_span.phpt & span_clone.phpt * fix arginfo * Make dummy_span actually return a RootSpanData instance Signed-off-by: Bob Weinand <[email protected]> * Free the proxy_map Signed-off-by: Bob Weinand <[email protected]> * Avoid pcre JIT to prevent valgrind complaining Signed-off-by: Bob Weinand <[email protected]> --------- Signed-off-by: Bob Weinand <[email protected]> Co-authored-by: Bob Weinand <[email protected]>
1 parent c0e70bd commit dfe83ec

40 files changed

Lines changed: 3185 additions & 68 deletions

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,6 +1373,8 @@ test_integrations_sqlsrv: global_test_run_dependencies
13731373
$(eval TEST_EXTRA_INI=)
13741374
test_integrations_swoole_5: global_test_run_dependencies
13751375
$(call run_tests_debug,--testsuite=swoole-test)
1376+
test_web_apigw: global_test_run_dependencies tests/Frameworks/Laravel/Latest/composer.lock-php$(PHP_MAJOR_MINOR) tests/Frameworks/Laravel/Octane/Latest/composer.lock-php$(PHP_MAJOR_MINOR) tests/Frameworks/Roadrunner/Version_2/composer.lock-php$(PHP_MAJOR_MINOR)
1377+
$(call run_tests_debug,--testsuite=api-gateway-test)
13761378
test_web_cakephp_28: global_test_run_dependencies tests/Frameworks/CakePHP/Version_2_8/composer.lock-php$(PHP_MAJOR_MINOR)
13771379
$(call run_tests_debug,--testsuite=cakephp-28-test)
13781380
test_web_cakephp_310: global_test_run_dependencies tests/Frameworks/CakePHP/Version_3_10/composer.lock-php$(PHP_MAJOR_MINOR)

config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ if test "$PHP_DDTRACE" != "no"; then
188188
ext/handlers_kafka.c \
189189
ext/handlers_pcntl.c \
190190
ext/handlers_signal.c \
191+
ext/inferred_proxy_headers.c \
191192
ext/integrations/exec_integration.c \
192193
ext/integrations/integrations.c \
193194
ext/ip_extraction.c \

config.w32

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ if (PHP_DDTRACE != 'no') {
3939
DDTRACE_EXT_SOURCES += " handlers_internal.c";
4040
DDTRACE_EXT_SOURCES += " handlers_kafka.c";
4141
DDTRACE_EXT_SOURCES += " handlers_pcntl.c";
42+
DDTRACE_EXT_SOURCES += " inferred_proxy_headers.c";
4243
DDTRACE_EXT_SOURCES += " ip_extraction.c";
4344
DDTRACE_EXT_SOURCES += " standalone_limiter.c";
4445
DDTRACE_EXT_SOURCES += " live_debugger.c";

ext/configuration.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ enum ddtrace_sampling_rules_format {
245245
CONFIG(SET, DD_DYNAMIC_INSTRUMENTATION_REDACTED_TYPES, "", .ini_change = zai_config_system_ini_change) \
246246
CONFIG(INT, DD_TRACE_BAGGAGE_MAX_ITEMS, "64") \
247247
CONFIG(INT, DD_TRACE_BAGGAGE_MAX_BYTES, "8192") \
248+
CONFIG(BOOL, DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED, "false") \
248249
DD_INTEGRATIONS
249250

250251
#ifndef _WIN32

ext/ddtrace.c

Lines changed: 76 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
#endif
102102
#include "ddtrace_arginfo.h"
103103
#include "distributed_tracing_headers.h"
104+
#include "inferred_proxy_headers.h"
104105
#include "live_debugger.h"
105106
#include "agent_info.h"
106107

@@ -894,12 +895,14 @@ ZEND_METHOD(DDTrace_SpanLink, fromHeaders) {
894895

895896
/* DDTrace\SpanData */
896897
zend_class_entry *ddtrace_ce_span_data;
898+
zend_class_entry *ddtrace_ce_inferred_span_data;
897899
zend_class_entry *ddtrace_ce_root_span_data;
898900
#if PHP_VERSION_ID >= 80000 && PHP_VERSION_ID < 80100
899901
HashTable dd_root_span_data_duplicated_properties_table;
900902
#endif
901903
zend_class_entry *ddtrace_ce_span_stack;
902904
zend_object_handlers ddtrace_span_data_handlers;
905+
zend_object_handlers ddtrace_inferred_span_data_handlers;
903906
zend_object_handlers ddtrace_root_span_data_handlers;
904907
zend_object_handlers ddtrace_span_stack_handlers;
905908

@@ -934,6 +937,11 @@ static zend_object *ddtrace_span_data_create(zend_class_entry *class_type) {
934937
return &span->std;
935938
}
936939

940+
static zend_object *ddtrace_inferred_span_data_create(zend_class_entry *class_type) {
941+
ddtrace_inferred_span_data *span = ecalloc(1, sizeof(*span));
942+
return dd_init_span_data_object(class_type, &span->span, &ddtrace_inferred_span_data_handlers);
943+
}
944+
937945
static zend_object *ddtrace_root_span_data_create(zend_class_entry *class_type) {
938946
ddtrace_root_span_data *span = ecalloc(1, sizeof(*span));
939947
dd_init_span_data_object(class_type, &span->span, &ddtrace_root_span_data_handlers);
@@ -1044,6 +1052,18 @@ static zend_object *ddtrace_span_data_clone_obj(zend_object *old_obj) {
10441052
return new_obj;
10451053
}
10461054

1055+
#if PHP_VERSION_ID < 80000
1056+
static zend_object *ddtrace_inferred_span_data_clone_obj(zval *old_zv) {
1057+
zend_object *old_obj = Z_OBJ_P(old_zv);
1058+
#else
1059+
static zend_object *ddtrace_inferred_span_data_clone_obj(zend_object *old_obj) {
1060+
#endif
1061+
zend_object *new_obj = ddtrace_inferred_span_data_create(old_obj->ce);
1062+
zend_objects_clone_members(new_obj, old_obj);
1063+
return new_obj;
1064+
}
1065+
1066+
10471067
#if PHP_VERSION_ID < 80000
10481068
static zend_object *ddtrace_root_span_data_clone_obj(zval *old_zv) {
10491069
zend_object *old_obj = Z_OBJ_P(old_zv);
@@ -1242,6 +1262,14 @@ static void dd_register_span_data_ce(void) {
12421262
ddtrace_span_data_handlers.write_property = ddtrace_span_data_readonly;
12431263
ddtrace_span_data_handlers.get_constructor = ddtrace_span_data_get_constructor;
12441264

1265+
ddtrace_ce_inferred_span_data = register_class_DDTrace_InferredSpanData(ddtrace_ce_span_data);
1266+
ddtrace_ce_inferred_span_data->create_object = ddtrace_inferred_span_data_create;
1267+
1268+
memcpy(&ddtrace_inferred_span_data_handlers, &ddtrace_span_data_handlers, sizeof(zend_object_handlers));
1269+
ddtrace_inferred_span_data_handlers.offset = XtOffsetOf(ddtrace_inferred_span_data, std);
1270+
ddtrace_inferred_span_data_handlers.clone_obj = ddtrace_inferred_span_data_clone_obj;
1271+
1272+
12451273
ddtrace_ce_root_span_data = register_class_DDTrace_RootSpanData(ddtrace_ce_span_data);
12461274
ddtrace_ce_root_span_data->create_object = ddtrace_root_span_data_create;
12471275

@@ -1474,6 +1502,7 @@ static PHP_MINIT_FUNCTION(ddtrace) {
14741502
ddtrace_git_metadata_handlers.free_obj = ddtrace_free_obj_wrapper;
14751503

14761504
ddtrace_engine_hooks_minit();
1505+
ddtrace_init_proxy_info_map();
14771506

14781507
ddtrace_integrations_minit();
14791508
ddtrace_serializer_startup();
@@ -1522,6 +1551,7 @@ static PHP_MSHUTDOWN_FUNCTION(ddtrace) {
15221551
ddtrace_log_mshutdown();
15231552

15241553
ddtrace_engine_hooks_mshutdown();
1554+
ddtrace_shutdown_proxy_info_map();
15251555

15261556
ddtrace_shutdown_span_sampling_limiter();
15271557
ddtrace_limiter_destroy();
@@ -1575,6 +1605,7 @@ static void dd_initialize_request(void) {
15751605
DDTRACE_G(additional_global_tags) = zend_new_array(0);
15761606
DDTRACE_G(default_priority_sampling) = DDTRACE_PRIORITY_SAMPLING_UNKNOWN;
15771607
DDTRACE_G(propagated_priority_sampling) = DDTRACE_PRIORITY_SAMPLING_UNSET;
1608+
DDTRACE_G(inferred_span_created) = false;
15781609
zend_hash_init(&DDTRACE_G(root_span_tags_preset), 8, unused, ZVAL_PTR_DTOR, 0);
15791610
zend_hash_init(&DDTRACE_G(propagated_root_span_tags), 8, unused, ZVAL_PTR_DTOR, 0);
15801611
zend_hash_init(&DDTRACE_G(tracestate_unknown_dd_keys), 8, unused, ZVAL_PTR_DTOR, 0);
@@ -3100,36 +3131,22 @@ static bool dd_read_userspace_header(zai_str zai_header, const char *lowercase_h
31003131
return true;
31013132
}
31023133

3103-
static bool dd_read_array_header(zai_str zai_header, const char *lowercase_header, zend_string **header_value, void *data) {
3104-
UNUSED(zai_header);
3105-
zend_array *array = (zend_array *) data;
3106-
zval *value = zend_hash_str_find(array, lowercase_header, strlen(lowercase_header));
3107-
if (!value) {
3108-
return false;
3109-
}
3110-
3111-
*header_value = zval_get_string(value);
3112-
return true;
3113-
}
3114-
3115-
static ddtrace_distributed_tracing_result dd_parse_distributed_tracing_headers_function(INTERNAL_FUNCTION_PARAMETERS, bool *success) {
3134+
static bool parse_tracing_headers_common(INTERNAL_FUNCTION_PARAMETERS, dd_fci_fcc_pair *func, bool *use_server_headers, zend_array **array) {
31163135
UNUSED(return_value);
3117-
3118-
dd_fci_fcc_pair func;
3119-
bool use_server_headers = false;
3120-
zend_array *array = NULL;
3136+
*use_server_headers = false;
3137+
*array = NULL;
31213138

31223139
ZEND_PARSE_PARAMETERS_START(1, 1)
31233140
DD_PARAM_PROLOGUE(0, 0);
31243141
if (Z_TYPE_P(_arg) == IS_NULL) {
3125-
use_server_headers = true;
3126-
} else if (UNEXPECTED(!zend_parse_arg_func(_arg, &func.fci, &func.fcc, false, &_error, true))) {
3142+
*use_server_headers = true;
3143+
} else if (UNEXPECTED(!zend_parse_arg_func(_arg, &func->fci, &func->fcc, false, &_error, true))) {
31273144
if (!_error) {
31283145
zend_argument_type_error(1, "must be a valid callback or of type array, %s given", zend_zval_value_name(_arg));
31293146
_error_code = ZPP_ERROR_FAILURE;
31303147
break;
31313148
} else if (Z_TYPE_P(_arg) == IS_ARRAY) {
3132-
array = Z_ARR_P(_arg);
3149+
*array = Z_ARR_P(_arg);
31333150
efree(_error);
31343151
} else {
31353152
_error_code = ZPP_ERROR_WRONG_CALLBACK;
@@ -3144,26 +3161,61 @@ static ddtrace_distributed_tracing_result dd_parse_distributed_tracing_headers_f
31443161
#endif
31453162
#endif
31463163
}
3147-
ZEND_PARSE_PARAMETERS_END_EX(*success = false; return (ddtrace_distributed_tracing_result){0});
3164+
ZEND_PARSE_PARAMETERS_END_EX(return false);
31483165

3149-
*success = true;
3150-
if (!get_DD_TRACE_ENABLED()) {
3166+
return true;
3167+
}
3168+
3169+
static ddtrace_distributed_tracing_result dd_parse_distributed_tracing_headers_function(INTERNAL_FUNCTION_PARAMETERS, bool *success) {
3170+
dd_fci_fcc_pair func;
3171+
bool use_server_headers;
3172+
zend_array *array;
3173+
3174+
*success = parse_tracing_headers_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, &func, &use_server_headers, &array);
3175+
if (!*success || !get_DD_TRACE_ENABLED()) {
31513176
return (ddtrace_distributed_tracing_result){0};
31523177
}
31533178

31543179
func.fci.param_count = 1;
31553180

31563181
if (array) {
3157-
return ddtrace_read_distributed_tracing_ids(dd_read_array_header, array);
3182+
return ddtrace_read_distributed_tracing_ids(ddtrace_read_array_header, array);
31583183
} else if (use_server_headers) {
31593184
return ddtrace_read_distributed_tracing_ids(ddtrace_read_zai_header, &func);
31603185
} else {
31613186
return ddtrace_read_distributed_tracing_ids(dd_read_userspace_header, &func);
31623187
}
31633188
}
31643189

3190+
static ddtrace_inferred_proxy_result dd_parse_inferred_proxy_headers_function(INTERNAL_FUNCTION_PARAMETERS, bool *success) {
3191+
dd_fci_fcc_pair func;
3192+
bool use_server_headers;
3193+
zend_array *array;
3194+
3195+
*success = parse_tracing_headers_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, &func, &use_server_headers, &array);
3196+
if (!*success || !get_DD_TRACE_ENABLED() || !get_DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED()) {
3197+
return (ddtrace_inferred_proxy_result){0};
3198+
}
3199+
3200+
func.fci.param_count = 1;
3201+
3202+
if (array) {
3203+
return ddtrace_read_inferred_proxy_headers(ddtrace_read_array_header, array);
3204+
} else if (use_server_headers) {
3205+
return ddtrace_read_inferred_proxy_headers(ddtrace_read_zai_header, &func);
3206+
} else {
3207+
return ddtrace_read_inferred_proxy_headers(dd_read_userspace_header, &func);
3208+
}
3209+
}
3210+
31653211
PHP_FUNCTION(DDTrace_consume_distributed_tracing_headers) {
31663212
bool success;
3213+
3214+
ddtrace_inferred_proxy_result inferred_result = dd_parse_inferred_proxy_headers_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, &success);
3215+
if (success && get_DD_TRACE_ENABLED() && DDTRACE_G(active_stack)->root_span && Z_TYPE(DDTRACE_G(active_stack)->root_span->property_inferred_span) != IS_OBJECT) {
3216+
ddtrace_open_inferred_span(&inferred_result, DDTRACE_G(active_stack)->root_span);
3217+
}
3218+
31673219
ddtrace_distributed_tracing_result result = dd_parse_distributed_tracing_headers_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, &success);
31683220
if (success && get_DD_TRACE_ENABLED()) {
31693221
ddtrace_apply_distributed_tracing_result(&result, DDTRACE_G(active_stack)->root_span);

ext/ddtrace.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
extern zend_module_entry ddtrace_module_entry;
2121
extern zend_class_entry *ddtrace_ce_span_data;
22+
extern zend_class_entry *ddtrace_ce_inferred_span_data;
2223
extern zend_class_entry *ddtrace_ce_root_span_data;
2324
extern zend_class_entry *ddtrace_ce_span_stack;
2425
extern zend_class_entry *ddtrace_ce_fatal_error;
@@ -30,6 +31,7 @@ extern zend_class_entry *ddtrace_ce_git_metadata;
3031

3132
typedef struct ddtrace_span_ids_t ddtrace_span_ids_t;
3233
typedef struct ddtrace_span_data ddtrace_span_data;
34+
typedef struct ddtrace_inferred_span_data ddtrace_inferred_span_data;
3335
typedef struct ddtrace_root_span_data ddtrace_root_span_data;
3436
typedef struct ddtrace_span_stack ddtrace_span_stack;
3537
typedef struct ddtrace_span_link ddtrace_span_link;
@@ -161,6 +163,8 @@ ZEND_BEGIN_MODULE_GLOBALS(ddtrace)
161163

162164
HashTable git_metadata;
163165
zend_object *git_object;
166+
167+
bool inferred_span_created;
164168
ZEND_END_MODULE_GLOBALS(ddtrace)
165169
// clang-format on
166170

ext/ddtrace.stub.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ public function hexId(): string {}
248248
public array $baggage = [];
249249
}
250250

251+
class InferredSpanData extends SpanData {}
252+
251253
class RootSpanData extends SpanData {
252254
/**
253255
* @var string The origin site of the trace. Propagated through distributed tracing by default.
@@ -299,6 +301,8 @@ class RootSpanData extends SpanData {
299301
* @var GitMetadata|null The git metadata of the span
300302
*/
301303
public GitMetadata|null $gitMetadata = null;
304+
305+
public InferredSpanData|null $inferredSpan = null;
302306
}
303307

304308
/**

ext/ddtrace_arginfo.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: d903751b8aaecac2235c17bf8904563e4a8f1d63 */
2+
* Stub hash: f7e8f6a8052abd0404a3e01fa6b52d27024e6f1b */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_trace_method, 0, 3, _IS_BOOL, 0)
55
ZEND_ARG_TYPE_INFO(0, className, IS_STRING, 0)
@@ -61,7 +61,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_update_span_duration, 0,
6161
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, finishTime, IS_DOUBLE, 0, "0")
6262
ZEND_END_ARG_INFO()
6363

64-
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_DDTrace_start_trace_span, 0, 0, DDTrace\\SpanData, 0)
64+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_DDTrace_start_trace_span, 0, 0, DDTrace\\RootSpanData, 0)
6565
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, startTime, IS_DOUBLE, 0, "0")
6666
ZEND_END_ARG_INFO()
6767

@@ -740,6 +740,16 @@ static zend_class_entry *register_class_DDTrace_SpanData(void)
740740
return class_entry;
741741
}
742742

743+
static zend_class_entry *register_class_DDTrace_InferredSpanData(zend_class_entry *class_entry_DDTrace_SpanData)
744+
{
745+
zend_class_entry ce, *class_entry;
746+
747+
INIT_NS_CLASS_ENTRY(ce, "DDTrace", "InferredSpanData", NULL);
748+
class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DDTrace_SpanData, 0);
749+
750+
return class_entry;
751+
}
752+
743753
static zend_class_entry *register_class_DDTrace_RootSpanData(zend_class_entry *class_entry_DDTrace_SpanData)
744754
{
745755
zend_class_entry ce, *class_entry;
@@ -802,6 +812,13 @@ static zend_class_entry *register_class_DDTrace_RootSpanData(zend_class_entry *c
802812
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));
803813
zend_string_release(property_gitMetadata_name);
804814

815+
zval property_inferredSpan_default_value;
816+
ZVAL_NULL(&property_inferredSpan_default_value);
817+
zend_string *property_inferredSpan_name = zend_string_init("inferredSpan", sizeof("inferredSpan") - 1, 1);
818+
zend_string *property_inferredSpan_class_DDTrace_InferredSpanData = zend_string_init("DDTrace\\InferredSpanData", sizeof("DDTrace\\InferredSpanData")-1, 1);
819+
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));
820+
zend_string_release(property_inferredSpan_name);
821+
805822
return class_entry;
806823
}
807824

ext/distributed_tracing_headers.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,11 @@ void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result
581581
ddtrace_assign_variable(&span->property_propagated_tags, &zv);
582582

583583
zend_hash_copy(root_meta, &result->meta_tags, NULL);
584+
ddtrace_span_data *inferred_span = ddtrace_get_inferred_span(span);
585+
if (inferred_span) {
586+
zend_array *inferred_meta = ddtrace_property_array(&inferred_span->property_meta);
587+
zend_hash_copy(inferred_meta, &result->meta_tags, (copy_ctor_func_t)zval_add_ref);
588+
}
584589

585590
if (result->origin) {
586591
ZVAL_STR(&zv, result->origin);
@@ -671,3 +676,15 @@ bool ddtrace_read_zai_header(zai_str zai_header, const char *lowercase_header, z
671676
*header_value = zend_string_copy(*header_value);
672677
return true;
673678
}
679+
680+
bool ddtrace_read_array_header(zai_str zai_header, const char *lowercase_header, zend_string **header_value, void *data) {
681+
UNUSED(zai_header);
682+
zend_array *array = (zend_array *) data;
683+
zval *value = zend_hash_str_find(array, lowercase_header, strlen(lowercase_header));
684+
if (!value) {
685+
return false;
686+
}
687+
688+
*header_value = zval_get_string(value);
689+
return true;
690+
}

ext/distributed_tracing_headers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ typedef bool (ddtrace_read_header)(zai_str zai_header, const char *lowercase_hea
2323
ddtrace_distributed_tracing_result ddtrace_read_distributed_tracing_ids(ddtrace_read_header *read_header, void *data);
2424
void ddtrace_apply_distributed_tracing_result(ddtrace_distributed_tracing_result *result, ddtrace_root_span_data *span);
2525
bool ddtrace_read_zai_header(zai_str zai_header, const char *lowercase_header, zend_string **header_value, void *data);
26+
bool ddtrace_read_array_header(zai_str zai_header, const char *lowercase_header, zend_string **header_value, void *data);
2627

2728
#endif // DD_DISTRIBUTED_TRACING_HEADERS_H

0 commit comments

Comments
 (0)