Skip to content

Commit

Permalink
Add 128-bit trace id generation and propagation via _dd.p.tid (#1875)
Browse files Browse the repository at this point in the history
* Add 128 bit trace_id generation and propagation via _dd.p.tid

Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>

* Save start time as seconds on the highest 32 bits of the trace_id

Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>

* Apply suggestions from review

Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>

---------

Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
  • Loading branch information
bwoebi authored Feb 3, 2023
1 parent f59dc7d commit fed56e0
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 9 deletions.
1 change: 1 addition & 0 deletions ext/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ extern bool runtime_config_first_init;
CONFIG(BOOL, DD_LOG_BACKTRACE, "false") \
CONFIG(BOOL, DD_TRACE_GENERATE_ROOT_SPAN, "true", .ini_change = ddtrace_span_alter_root_span_config) \
CONFIG(INT, DD_TRACE_SPANS_LIMIT, "1000") \
CONFIG(BOOL, DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED, "false") \
CONFIG(INT, DD_TRACE_AGENT_MAX_CONSECUTIVE_FAILURES, \
DD_CFG_EXPSTR(DD_TRACE_CIRCUIT_BREAKER_DEFAULT_MAX_CONSECUTIVE_FAILURES)) \
CONFIG(INT, DD_TRACE_AGENT_ATTEMPT_RETRY_TIME_MSEC, \
Expand Down
11 changes: 10 additions & 1 deletion ext/ddtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1856,7 +1856,10 @@ static void dd_apply_propagated_values_to_existing_spans(void) {
while (span) {
zend_array *meta = ddtrace_spandata_property_meta(span);
if (!DDTRACE_G(distributed_trace_id).low && !DDTRACE_G(distributed_trace_id).high) {
span->trace_id = (ddtrace_trace_id){ .high = 0, .low = span->root->span_id };
span->trace_id = (ddtrace_trace_id) {
.low = span->root->span_id,
.time = get_DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED() ? span->start / UINT64_C(1000000000) : 0,
};
} else {
span->trace_id = DDTRACE_G(distributed_trace_id);
}
Expand Down Expand Up @@ -2415,6 +2418,12 @@ void ddtrace_read_distributed_tracing_ids(bool (*read_header)(zai_string_view, c
}
}

zval *tidzv = zend_hash_str_find(&DDTRACE_G(root_span_tags_preset), ZEND_STRL("_dd.p.tid"));
if (tidzv && DDTRACE_G(distributed_trace_id).low) {
DDTRACE_G(distributed_trace_id).high = ddtrace_parse_hex_span_id(tidzv);
zend_hash_str_del(&DDTRACE_G(root_span_tags_preset), ZEND_STRL("_dd.p.tid"));
}

if (priority_sampling != DDTRACE_PRIORITY_SAMPLING_UNKNOWN) {
if (!DDTRACE_G(active_stack)->root_span) {
DDTRACE_G(propagated_priority_sampling) = DDTRACE_G(default_priority_sampling) = priority_sampling;
Expand Down
11 changes: 10 additions & 1 deletion ext/ddtrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,16 @@ typedef struct {

typedef struct {
uint64_t low;
uint64_t high;
union {
uint64_t high;
struct {
ZEND_ENDIAN_LOHI(
uint32_t padding // zeroes
,
uint32_t time
)
};
};
} ddtrace_trace_id;

// clang-format off
Expand Down
4 changes: 4 additions & 0 deletions ext/serializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,10 @@ static void _serialize_meta(zval *el, ddtrace_span_data *span) {
add_assoc_long(el, "error", 1);
}

if (span->trace_id.high) {
add_assoc_str(meta, "_dd.p.tid", zend_strpprintf(0, "%" PRIx64, span->trace_id.high));
}

if (zend_array_count(Z_ARRVAL_P(meta))) {
add_assoc_zval(el, "meta", meta);
} else {
Expand Down
12 changes: 7 additions & 5 deletions ext/span.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ void ddtrace_free_span_stacks(bool silent) {
static uint64_t _get_nanoseconds(bool monotonic_clock) {
struct timespec time;
if (clock_gettime(monotonic_clock ? CLOCK_MONOTONIC : CLOCK_REALTIME, &time) == 0) {
return time.tv_sec * 1000000000L + time.tv_nsec;
return time.tv_sec * UINT64_C(1000000000) + time.tv_nsec;
}
return 0;
}
Expand All @@ -142,6 +142,11 @@ void ddtrace_open_span(ddtrace_span_data *span) {
// All open spans hold a ref to their stack
ZVAL_OBJ_COPY(&span->property_stack, &stack->std);

span->duration_start = _get_nanoseconds(USE_MONOTONIC_CLOCK);
// Start time is nanoseconds from unix epoch
// @see https://docs.datadoghq.com/api/?lang=python#send-traces
span->start = _get_nanoseconds(USE_REALTIME_CLOCK);

span->span_id = ddtrace_generate_span_id();
// if not a root span or the true root span (distributed tracing)
bool root_span = DDTRACE_G(active_stack)->root_span == NULL;
Expand All @@ -158,12 +163,9 @@ void ddtrace_open_span(ddtrace_span_data *span) {
set_trace_id_from_span_id:
span->trace_id = (ddtrace_trace_id){
.low = span->span_id,
.time = get_DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED() ? span->start / UINT64_C(1000000000) : 0,
};
}
span->duration_start = _get_nanoseconds(USE_MONOTONIC_CLOCK);
// Start time is nanoseconds from unix epoch
// @see https://docs.datadoghq.com/api/?lang=python#send-traces
span->start = _get_nanoseconds(USE_REALTIME_CLOCK);

ddtrace_span_data *parent_span = DDTRACE_G(active_stack)->active;
ZVAL_OBJ(&DDTRACE_G(active_stack)->property_active, &span->std);
Expand Down
6 changes: 6 additions & 0 deletions ext/tracer_tag_propagation/tracer_tag_propagation.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ zend_string *ddtrace_format_propagated_tags(void) {
// we propagate all tags on the current root span which were originally propagated, including the explicitly
// defined tags here
zend_hash_str_del(&DDTRACE_G(propagated_root_span_tags), ZEND_STRL("_dd.p.upstream_services"));
zend_hash_str_del(&DDTRACE_G(propagated_root_span_tags), ZEND_STRL("_dd.p.tid"));
zend_hash_str_add_empty_element(&DDTRACE_G(propagated_root_span_tags), ZEND_STRL("_dd.p.dm"));

zend_array *tags = &DDTRACE_G(root_span_tags_preset);
Expand All @@ -112,6 +113,11 @@ zend_string *ddtrace_format_propagated_tags(void) {

smart_str taglist = {0};

ddtrace_trace_id trace_id = ddtrace_peek_trace_id();
if (trace_id.high) {
smart_str_append_printf(&taglist, "_dd.p.tid=%" PRIx64, trace_id.high);
}

zend_string *tagname;
ZEND_HASH_FOREACH_STR_KEY(&DDTRACE_G(propagated_root_span_tags), tagname) {
zval *tag = zend_hash_find(tags, tagname), error_zv = {0};
Expand Down
38 changes: 38 additions & 0 deletions tests/ext/generate_128_bit_trace_id.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--TEST--
Test 128 bit generation
--ENV--
DD_TRACE_GENERATE_ROOT_SPAN=0
--FILE--
<?php

ini_set("datadog.trace.128_bit_traceid_generation_enabled", "1");
DDTrace\start_span();
var_dump(\DDTrace\trace_id() > 2 ** 64);

ini_set("datadog.trace.128_bit_traceid_generation_enabled", "0");
DDTrace\set_distributed_tracing_context(0, 0);
var_dump(\DDTrace\trace_id() < 2 ** 64);

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();
DDTrace\close_span();

ini_set("datadog.trace.128_bit_traceid_generation_enabled", "0");
DDTrace\start_span();
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));

?>
--EXPECT--
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ echo 'Done.' . PHP_EOL;
--EXPECTF--
b3: 12345678901234567890123456789012-6543210987654321-d
traceparent: 00-12345678901234567890123456789012-6543210987654321-01
tracestate: dd=o:phpt-test;s:2;t.test:qvalue;unknown1:val;unknown2:1,foo=bar:;=,baz=qux
tracestate: dd=o:phpt-test;s:2;t.tid:1234567890123456;t.test:qvalue;unknown1:val;unknown2:1,foo=bar:;=,baz=qux
x-datadog-origin: phpt-test
x-datadog-tags: _dd.p.test=qvalue
x-datadog-tags: _dd.p.tid=1234567890123456,_dd.p.test=qvalue
bool(false)
Done.
No finished traces to be sent to the agent

0 comments on commit fed56e0

Please sign in to comment.