-
-
Notifications
You must be signed in to change notification settings - Fork 195
feat: outgoing traceparent
header support
#1394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
27247f1
initial traceparent support
JoshuaMoelans 3e51545
CHANGELOG.md update
JoshuaMoelans 8e1d492
consolidate tests
JoshuaMoelans 32b33fd
Merge branch 'master' into joshua/feat/traceparent
JoshuaMoelans 707fcc8
remove redundant value_len check
JoshuaMoelans 1ee9ef4
check for exact length
JoshuaMoelans 8b9a7fa
reuse header key comparison + extract parsing per header type
JoshuaMoelans 51c2711
static internal helper
JoshuaMoelans c0ea44a
add size bounds + checks for headers
JoshuaMoelans 4714c61
only accept 00 or 01 sampling flag
JoshuaMoelans 5ee684f
Apply suggestion from @supervacuus
JoshuaMoelans e269903
Apply suggestion from @supervacuus
JoshuaMoelans 6561f7e
Apply suggestion from @supervacuus
JoshuaMoelans 28226e7
Apply suggestion from @supervacuus
JoshuaMoelans 3262fa4
fix(traceparent): only support outgoing for now (#1406)
JoshuaMoelans fb4ad87
add tests to verify consistency of trace and span IDs across headers …
JoshuaMoelans 866e799
use trace header sizes in header propagation
JoshuaMoelans 763acd4
update CHANGELOG.md
JoshuaMoelans File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1815,5 +1815,135 @@ SENTRY_TEST(propagation_context_init) | |
sentry_close(); | ||
} | ||
|
||
typedef struct { | ||
int sentry_trace_found; | ||
int traceparent_found; | ||
char sentry_trace_value[64]; | ||
char traceparent_value[64]; | ||
} traceparent_header_collector_t; | ||
|
||
static void | ||
collect_traceparent_headers(const char *key, const char *value, void *userdata) | ||
{ | ||
traceparent_header_collector_t *collector | ||
= (traceparent_header_collector_t *)userdata; | ||
if (strcmp(key, "sentry-trace") == 0) { | ||
collector->sentry_trace_found = 1; | ||
const size_t value_len = sizeof(collector->sentry_trace_value) - 1; | ||
strncpy(collector->sentry_trace_value, value, value_len); | ||
collector->sentry_trace_value[value_len] = '\0'; | ||
} else if (strcmp(key, "traceparent") == 0) { | ||
collector->traceparent_found = 1; | ||
const size_t value_len = sizeof(collector->traceparent_value) - 1; | ||
strncpy(collector->traceparent_value, value, value_len); | ||
collector->traceparent_value[value_len] = '\0'; | ||
} | ||
} | ||
|
||
SENTRY_TEST(traceparent_header_disabled_by_default) | ||
{ | ||
SENTRY_TEST_OPTIONS_NEW(options); | ||
sentry_options_set_dsn(options, "https://[email protected]/42"); | ||
sentry_options_set_traces_sample_rate(options, 1.0); | ||
// Note: not enabling traceparent propagation | ||
sentry_init(options); | ||
|
||
sentry_transaction_context_t *tx_ctx | ||
= sentry_transaction_context_new("test", "test"); | ||
sentry_transaction_t *tx | ||
= sentry_transaction_start(tx_ctx, sentry_value_new_null()); | ||
|
||
traceparent_header_collector_t collector = { 0 }; | ||
sentry_transaction_iter_headers( | ||
tx, collect_traceparent_headers, &collector); | ||
|
||
// Should have sentry-trace but not traceparent | ||
TEST_CHECK(collector.sentry_trace_found); | ||
TEST_CHECK(!collector.traceparent_found); | ||
|
||
TEST_CHECK_INT_EQUAL( | ||
strlen(collector.sentry_trace_value), SENTRY_TRACE_LEN); | ||
|
||
sentry_transaction_finish(tx); | ||
sentry_close(); | ||
} | ||
|
||
SENTRY_TEST(traceparent_header_generation) | ||
{ | ||
SENTRY_TEST_OPTIONS_NEW(options); | ||
sentry_options_set_dsn(options, "https://[email protected]/42"); | ||
sentry_options_set_traces_sample_rate(options, 1.0); | ||
sentry_options_set_propagate_traceparent(options, 1); | ||
sentry_init(options); | ||
|
||
sentry_transaction_context_t *tx_ctx | ||
= sentry_transaction_context_new("test", "test"); | ||
sentry_transaction_t *tx | ||
= sentry_transaction_start(tx_ctx, sentry_value_new_null()); | ||
|
||
// Test transaction header generation | ||
traceparent_header_collector_t collector = { 0 }; | ||
sentry_transaction_iter_headers( | ||
tx, collect_traceparent_headers, &collector); | ||
|
||
// Should have both headers | ||
TEST_CHECK(collector.sentry_trace_found); | ||
TEST_CHECK(collector.traceparent_found); | ||
|
||
// Verify expected traceparent length | ||
TEST_CHECK_INT_EQUAL( | ||
strlen(collector.traceparent_value), SENTRY_W3C_TRACEPARENT_LEN); | ||
// Verify traceparent format: starts with "00-" | ||
TEST_CHECK(strncmp(collector.traceparent_value, "00-", 3) == 0); | ||
|
||
// Extract components from both headers to verify consistency | ||
const char *trace_id = sentry_value_as_string( | ||
sentry_value_get_by_key(tx->inner, "trace_id")); | ||
const char *tx_span_id | ||
= sentry_value_as_string(sentry_value_get_by_key(tx->inner, "span_id")); | ||
|
||
// Verify sentry-trace contains the correct trace and span IDs | ||
TEST_CHECK(strstr(collector.sentry_trace_value, trace_id) != NULL); | ||
TEST_CHECK(strstr(collector.sentry_trace_value, tx_span_id) != NULL); | ||
|
||
// Verify traceparent contains the correct trace and span IDs | ||
TEST_CHECK(strstr(collector.traceparent_value, trace_id) != NULL); | ||
TEST_CHECK(strstr(collector.traceparent_value, tx_span_id) != NULL); | ||
|
||
// Test span header generation | ||
sentry_span_t *span | ||
= sentry_transaction_start_child(tx, "child", "child-span"); | ||
|
||
traceparent_header_collector_t span_collector = { 0 }; | ||
sentry_span_iter_headers( | ||
span, collect_traceparent_headers, &span_collector); | ||
|
||
// Should have both headers for spans too | ||
TEST_CHECK(span_collector.sentry_trace_found); | ||
TEST_CHECK(span_collector.traceparent_found); | ||
|
||
// Verify traceparent format for spans | ||
TEST_CHECK(strncmp(span_collector.traceparent_value, "00-", 3) == 0); | ||
|
||
// Extract components from both headers to verify consistency | ||
const char *span_trace_id = sentry_value_as_string( | ||
sentry_value_get_by_key(span->inner, "trace_id")); | ||
const char *span_id = sentry_value_as_string( | ||
sentry_value_get_by_key(span->inner, "span_id")); | ||
|
||
// Verify sentry-trace contains the correct trace and span IDs | ||
TEST_CHECK( | ||
strstr(span_collector.sentry_trace_value, span_trace_id) != NULL); | ||
TEST_CHECK(strstr(span_collector.sentry_trace_value, span_id) != NULL); | ||
|
||
// Verify traceparent contains the correct trace and span IDs | ||
TEST_CHECK(strstr(span_collector.traceparent_value, span_trace_id) != NULL); | ||
TEST_CHECK(strstr(span_collector.traceparent_value, span_id) != NULL); | ||
|
||
sentry_span_finish(span); | ||
sentry_transaction_finish(tx); | ||
sentry_close(); | ||
} | ||
|
||
#undef IS_NULL | ||
#undef CHECK_STRING_PROPERTY |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of these days, we should convert all these flags to bitfields. But not in this PR.