Skip to content

Commit

Permalink
Add a DDTrace\generate_distributed_tracing_headers() function
Browse files Browse the repository at this point in the history
It's a direct opposite function to consume_distributed_tracing_headers, thereby trivially enabling users to use it for custom propoagation and later consumption.

Also needed for easy testing of parametric tests.

And force phpunit < 10 to fix tests.
  • Loading branch information
bwoebi committed Feb 3, 2023
1 parent fed56e0 commit 8c8c475
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 28 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"ext-posix": "*",
"g1a/composer-test-scenarios": "~3.0",
"mockery/mockery": "*",
"phpunit/phpunit": "*",
"phpunit/phpunit": "<10",
"squizlabs/php_codesniffer": "^3.3.0",
"symfony/process": "<5"
},
Expand Down
12 changes: 12 additions & 0 deletions ext/ddtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "dogstatsd_client.h"
#include "engine_hooks.h"
#include "excluded_modules.h"
#include "handlers_http.h"
#include "handlers_internal.h"
#include "integrations/integrations.h"
#include "ip_extraction.h"
Expand Down Expand Up @@ -2005,6 +2006,16 @@ static PHP_FUNCTION(consume_distributed_tracing_headers) {
RETURN_NULL();
}

/* {{{ proto array generate_distributed_tracing_headers() */
static PHP_FUNCTION(generate_distributed_tracing_headers) {
UNUSED(execute_data);

array_init(return_value);
if (get_DD_TRACE_ENABLED()) {
ddtrace_inject_distributed_headers(Z_ARR_P(return_value), true);
}
}

/* {{{ proto string dd_trace_closed_spans_count() */
static PHP_FUNCTION(dd_trace_closed_spans_count) {
UNUSED(execute_data);
Expand Down Expand Up @@ -2126,6 +2137,7 @@ static const zend_function_entry ddtrace_functions[] = {
DDTRACE_NS_FE(current_context, arginfo_ddtrace_void),
DDTRACE_NS_FE(set_distributed_tracing_context, arginfo_dd_trace_set_distributed_tracing_context),
DDTRACE_NS_FE(consume_distributed_tracing_headers, arginfo_consume_distributed_tracing_headers),
DDTRACE_NS_FE(generate_distributed_tracing_headers, arginfo_ddtrace_void),
DDTRACE_FE(dd_trace_reset, arginfo_ddtrace_void),
DDTRACE_FE(dd_trace_send_traces_via_thread, arginfo_dd_trace_send_traces_via_thread),
DDTRACE_FE(dd_trace_serialize_closed_spans, arginfo_ddtrace_void),
Expand Down
2 changes: 1 addition & 1 deletion ext/handlers_curl.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ static void dd_inject_distributed_tracing_headers(zend_object *ch) {
array_init(&headers);
}

ddtrace_inject_distributed_headers(Z_ARR(headers));
ddtrace_inject_distributed_headers(Z_ARR(headers), false);

zend_function *setopt_fn = zend_hash_str_find_ptr(EG(function_table), ZEND_STRL("curl_setopt"));

Expand Down
2 changes: 1 addition & 1 deletion ext/handlers_curl_php7.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ static int dd_inject_distributed_tracing_headers(zval *ch) {
array_init(&headers);
}

ddtrace_inject_distributed_headers(Z_ARR(headers));
ddtrace_inject_distributed_headers(Z_ARR(headers), false);

zend_function *setopt_fn = zend_hash_str_find_ptr(EG(function_table), ZEND_STRL("curl_setopt"));

Expand Down
56 changes: 32 additions & 24 deletions ext/handlers_http.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@

ZEND_EXTERN_MODULE_GLOBALS(ddtrace);

static inline void ddtrace_inject_distributed_headers(zend_array *array) {
static inline void ddtrace_inject_distributed_headers(zend_array *array, bool key_value_pairs) {
zval headers;
ZVAL_ARR(&headers, array);

#define ADD_HEADER(header, ...) \
if (key_value_pairs) { \
add_assoc_str_ex(&headers, ZEND_STRL(header), zend_strpprintf(0, __VA_ARGS__)); \
} else { \
add_next_index_str(&headers, zend_strpprintf(0, header ": " __VA_ARGS__)); \
}

zend_array *inject = zai_config_is_modified(DDTRACE_CONFIG_DD_TRACE_PROPAGATION_STYLE)
&& !zai_config_is_modified(DDTRACE_CONFIG_DD_TRACE_PROPAGATION_STYLE_INJECT)
? get_DD_TRACE_PROPAGATION_STYLE() : get_DD_TRACE_PROPAGATION_STYLE_INJECT();
Expand All @@ -23,54 +30,53 @@ static inline void ddtrace_inject_distributed_headers(zend_array *array) {
zend_long sampling_priority = ddtrace_fetch_prioritySampling_from_root();
if (sampling_priority != DDTRACE_PRIORITY_SAMPLING_UNKNOWN) {
if (send_datadog) {
add_next_index_str(&headers,
zend_strpprintf(0, "x-datadog-sampling-priority: " ZEND_LONG_FMT, sampling_priority));
ADD_HEADER("x-datadog-sampling-priority", ZEND_LONG_FMT, sampling_priority);
}
if (send_b3) {
if (sampling_priority <= 0) {
add_next_index_string(&headers, "X-B3-Sampled: 0");
ADD_HEADER("x-b3-sampled", "0");
} else if (sampling_priority == PRIORITY_SAMPLING_USER_KEEP) {
add_next_index_string(&headers, "X-B3-Flags: 1");
ADD_HEADER("x-b3-flags", "1");
} else {
add_next_index_string(&headers, "X-B3-Sampled: 1");
ADD_HEADER("x-b3-sampled", "1");
}
}
}
zend_string *propagated_tags = ddtrace_format_propagated_tags();
if (send_datadog || send_b3 || send_b3single) {
if (propagated_tags) {
add_next_index_str(&headers, zend_strpprintf(0, "x-datadog-tags: %s", ZSTR_VAL(propagated_tags)));
ADD_HEADER("x-datadog-tags", "%s", ZSTR_VAL(propagated_tags));
}
if (DDTRACE_G(dd_origin)) {
add_next_index_str(&headers, zend_strpprintf(0, "x-datadog-origin: %s", ZSTR_VAL(DDTRACE_G(dd_origin))));
ADD_HEADER("x-datadog-origin", "%s", ZSTR_VAL(DDTRACE_G(dd_origin)));
}
}
ddtrace_trace_id trace_id = ddtrace_peek_trace_id();
uint64_t span_id = ddtrace_peek_span_id();
if (trace_id.low || trace_id.high) {
if (send_datadog) {
add_next_index_str(&headers, zend_strpprintf(0, "x-datadog-trace-id: %" PRIu64, trace_id.low));
ADD_HEADER("x-datadog-trace-id", "%" PRIu64, trace_id.low);
}
if (send_b3) {
if (trace_id.high) {
add_next_index_str(&headers, zend_strpprintf(0, "X-B3-TraceId: %016" PRIx64 "%016" PRIx64, trace_id.high, trace_id.low));
ADD_HEADER("X-B3-TraceId", "%016" PRIx64 "%016" PRIx64, trace_id.high, trace_id.low);
} else {
add_next_index_str(&headers, zend_strpprintf(0, "X-B3-TraceId: %016" PRIx64, trace_id.low));
ADD_HEADER("X-B3-TraceId", "%016" PRIx64, trace_id.low);
}
}
if (span_id) {
if (send_datadog) {
add_next_index_str(&headers, zend_strpprintf(0, "x-datadog-parent-id: %" PRIu64, span_id));
ADD_HEADER("x-datadog-parent-id", "%" PRIu64, span_id);
}
if (send_b3) {
add_next_index_str(&headers, zend_strpprintf(0, "X-B3-SpanId: %016" PRIx64, span_id));
ADD_HEADER("X-B3-SpanId", "%016" PRIx64, span_id);
}
if (send_tracestate) {
add_next_index_str(&headers, zend_strpprintf(0, "traceparent: 00-%016" PRIx64 "%016" PRIx64 "-%016" PRIx64 "-%02" PRIx8,
trace_id.high,
trace_id.low,
span_id,
sampling_priority > 0));
ADD_HEADER("traceparent", "00-%016" PRIx64 "%016" PRIx64 "-%016" PRIx64 "-%02" PRIx8,
trace_id.high,
trace_id.low,
span_id,
sampling_priority > 0);

smart_str str = {0};

Expand Down Expand Up @@ -138,7 +144,7 @@ static inline void ddtrace_inject_distributed_headers(zend_array *array) {
}

if (str.s) {
add_next_index_str(&headers, zend_strpprintf(0, "tracestate: %s%.*s", hasdd ? "dd=" : "", (int)ZSTR_LEN(str.s), ZSTR_VAL(str.s)));
ADD_HEADER("tracestate", "%s%.*s", hasdd ? "dd=" : "", (int)ZSTR_LEN(str.s), ZSTR_VAL(str.s));
smart_str_free(&str);
}
}
Expand All @@ -163,16 +169,18 @@ static inline void ddtrace_inject_distributed_headers(zend_array *array) {
} else {
sprintf(trace_id_buf, "%016" PRIx64, trace_id.low);
}
add_next_index_str(&headers, zend_strpprintf(0, "b3: %s-%016" PRIx64 "%s%s",
trace_id_buf,
span_id,
b3_sampling_decision ? "-" : "", b3_sampling_decision ? b3_sampling_decision : ""));
ADD_HEADER("b3", "%s-%016" PRIx64 "%s%s",
trace_id_buf,
span_id,
b3_sampling_decision ? "-" : "", b3_sampling_decision ? b3_sampling_decision : "");
} else if (b3_sampling_decision) {
add_next_index_str(&headers, zend_strpprintf(0, "b3: %s", b3_sampling_decision));
ADD_HEADER("b3", "%s", b3_sampling_decision);
}
}

if (propagated_tags) {
zend_string_release(propagated_tags);
}
}

#undef ADD_HEADER
2 changes: 1 addition & 1 deletion tests/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"require-dev": {
"mockery/mockery": "*",
"phpunit/phpunit": "*",
"phpunit/phpunit": "<10",
"phpspec/prophecy": "*",
"symfony/process": "<5",
"g1a/composer-test-scenarios": "~3.0"
Expand Down
29 changes: 29 additions & 0 deletions tests/ext/distributed_tracing/distributed_trace_generate.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
Test generate_distributed_tracing_headers()
--ENV--
HTTP_X_DATADOG_TRACE_ID=42
HTTP_X_DATADOG_PARENT_ID=10
HTTP_X_DATADOG_ORIGIN=datadog
HTTP_X_DATADOG_SAMPLING_PRIORITY=3
DD_TRACE_GENERATE_ROOT_SPAN=0
--FILE--
<?php

var_dump(DDTrace\generate_distributed_tracing_headers());

?>
--EXPECT--
array(6) {
["x-datadog-sampling-priority"]=>
string(1) "3"
["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(16) "dd=o:datadog;s:3"
}

0 comments on commit 8c8c475

Please sign in to comment.