-
Notifications
You must be signed in to change notification settings - Fork 161
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
feat: API Gateway Tracing #3095
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
❌ Your patch status has failed because the patch coverage (49.01%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## master #3095 +/- ##
============================================
- Coverage 74.74% 72.87% -1.88%
- Complexity 2791 2806 +15
============================================
Files 112 139 +27
Lines 11044 15317 +4273
Branches 0 1047 +1047
============================================
+ Hits 8255 11162 +2907
- Misses 2789 3602 +813
- Partials 0 553 +553
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 27 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
Benchmarks [ tracer ]Benchmark execution time: 2025-02-20 10:25:11 Comparing candidate commit 6aecc1f in PR branch Found 2 performance improvements and 3 performance regressions! Performance is the same for 173 metrics, 0 unstable metrics. scenario:ContextPropagationBench/benchInject128Bit-opcache
scenario:EmptyFileBench/benchEmptyFileBaseline
scenario:MessagePackSerializationBench/benchMessagePackSerialization-opcache
scenario:PDOBench/benchPDOBaseline
scenario:SamplingRuleMatchingBench/benchRegexMatching3-opcache
|
'DD_ENV' => 'local-test', | ||
'DD_VERSION' => '1.0', | ||
'DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED' => 'true', | ||
//'DD_TRACE_HEADER_TAGS' => 'x-dd-proxy-domain-name,x-dd-proxy,x-dd-proxy-httpmethod,x-dd-proxy-path,x-dd-proxy-request-time-ms,x-dd-proxy-stage', |
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.
Should this be commented out?
@@ -0,0 +1,381 @@ | |||
[[ | |||
{ | |||
"name": "aws-apigateway", |
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.
The span name in the Python, Go, and JS implementation is aws.apigateway
. Any way to change this?
'A simple GET request returning a string', | ||
'/simple?key=value&pwd=should_redact', | ||
[ | ||
'x-dd-proxy: aws.apigateway', |
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.
The way we implemented it in other languages was to have a map w/the header value of aws-apigateway
to map to a span name value of aws.apigateway
. We want the header value to remain unchanged and we want the span name to be slightly different which can be represented by a key value map.
That way we can add more values in the future if we have more proxy headers that correspond to different operation names
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.
Refer to this as an example
Note, they also include the component value in the map which would change for future proxies as well that may not necessarily be equal to the proxy header
UNUSED(old_value, new_str); | ||
|
||
ddtrace_span_properties *pspan = ddtrace_active_span_props(); | ||
while (pspan) { | ||
if (skip_inferred) { | ||
ddtrace_span_data *span = SPANDATA(pspan); | ||
if (span && span->type == DDTRACE_INFERRED_SPAN) { |
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.
if (span && span->type == DDTRACE_INFERRED_SPAN) { | |
if (span->type == DDTRACE_INFERRED_SPAN) { |
Nit, but SPANDATA() is just an offset calculation from pspan and will never be NULL.
ddtrace_proxy_info *info; | ||
ZEND_HASH_FOREACH_PTR(&proxy_info_map, info) { | ||
efree(info); | ||
} ZEND_HASH_FOREACH_END(); |
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.
Nit: the idiomatic way would be using:
static dd_proxy_info_dtor(zval *zv) {
efree(Z_PTR_P(zv));
}
and passing it to zend_hash_init as destructor.
} | ||
|
||
void ddtrace_init_proxy_info_map(void) { | ||
zend_hash_init(&proxy_info_map, 8, NULL, NULL, 1); |
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.
This should be 0 as last parameter right? persistent=1 is for memory supposed to survive the request cycle.
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.
Oops, indeed. I initially wanted to do the initialization/free in MINIT/MSHUTDOWN, but faced issues. Nice catch, ty.
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.
this should be in minit/mshutdown though. No point in reinitializing that every request.
} else if (span->std.ce == ddtrace_ce_root_span_data) { | ||
ddtrace_root_span_data *root = ROOTSPANDATA(&span->std); | ||
if (root->child_root) { // Can't check for DDTRACE_INFERRED_SPAN because the span is now closed | ||
zval *child_exception_zv = &root->child_root->span.property_exception; | ||
has_exception = Z_TYPE_P(child_exception_zv) == IS_OBJECT && instanceof_function(Z_OBJCE_P(child_exception_zv), zend_ce_throwable); |
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.
Can you move this before the if (has_exception) above?
// inherit exception on inferred span from child root
if (!has_exception && span->std.ce == ddtrace_ce_root_span_data) {
ddtrace_root_span_data *root = ROOTSPANDATA(&span->std);
if (root->child_root) { // Can't check for DDTRACE_INFERRED_SPAN because the span is now closed
exception_zv = &root->child_root->span.property_exception;
has_exception = Z_TYPE_P(child_exception_zv) == IS_OBJECT && instanceof_function(Z_OBJCE_P(child_exception_zv), zend_ce_throwable);
}
}
The duplication was confusing me
@@ -86,6 +87,7 @@ struct ddtrace_span_data { | |||
bool notify_user_req_end; | |||
struct ddtrace_span_data *next; | |||
struct ddtrace_root_span_data *root; | |||
bool is_child_of_inferred_span; |
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.
Why do we have this property at all? Isn't it redundant with child_root != NULL on the root_span_data?
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.
I see only one usage of it, and it's trivially replaced.
@@ -107,6 +109,7 @@ struct ddtrace_root_span_data { | |||
ddtrace_rule_result sampling_rule; | |||
bool explicit_sampling_priority; | |||
enum ddtrace_trace_limited trace_is_limited; | |||
struct ddtrace_root_span_data *child_root; // Only used when inferring proxy services (type: DDTRACE_INFERRED_SPAN) |
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.
let's rename it to inferred_root
Description
Telemetry PR: https://github.com/DataDog/dd-go/pull/171137
Reviewer checklist