Skip to content
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

Draft
wants to merge 44 commits into
base: master
Choose a base branch
from
Draft

Conversation

PROFeNoM
Copy link
Contributor

@PROFeNoM PROFeNoM commented Feb 19, 2025

Description

Telemetry PR: https://github.com/DataDog/dd-go/pull/171137

image

Reviewer checklist

  • Test coverage seems ok.
  • Appropriate labels assigned.

@PROFeNoM PROFeNoM self-assigned this Feb 19, 2025
@codecov-commenter
Copy link

codecov-commenter commented Feb 19, 2025

Codecov Report

Attention: Patch coverage is 49.01961% with 26 lines in your changes missing coverage. Please review.

Project coverage is 72.87%. Comparing base (445f72a) to head (aaac753).
Report is 7 commits behind head on master.

Files with missing lines Patch % Lines
.../DDTrace/Integrations/Swoole/SwooleIntegration.php 10.52% 17 Missing ⚠️
.../Integrations/Roadrunner/RoadrunnerIntegration.php 71.87% 9 Missing ⚠️

❌ 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

Impacted file tree graph

@@             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     
Flag Coverage Δ
appsec-extension 68.28% <ø> (?)
tracer-php 74.62% <49.01%> (-0.12%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
.../Integrations/Roadrunner/RoadrunnerIntegration.php 70.71% <71.87%> (-1.96%) ⬇️
.../DDTrace/Integrations/Swoole/SwooleIntegration.php 43.44% <10.52%> (-3.48%) ⬇️

... and 27 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 445f72a...aaac753. Read the comment docs.

@pr-commenter
Copy link

pr-commenter bot commented Feb 19, 2025

Benchmarks [ tracer ]

Benchmark execution time: 2025-02-20 10:25:11

Comparing candidate commit 6aecc1f in PR branch alex/AIDM-548_api-gateway-bis with baseline commit 445f72a in branch master.

Found 2 performance improvements and 3 performance regressions! Performance is the same for 173 metrics, 0 unstable metrics.

scenario:ContextPropagationBench/benchInject128Bit-opcache

  • 🟥 execution_time [+48.083ns; +121.917ns] or [+2.890%; +7.327%]

scenario:EmptyFileBench/benchEmptyFileBaseline

  • 🟥 execution_time [+67.659µs; +197.281µs] or [+2.279%; +6.645%]

scenario:MessagePackSerializationBench/benchMessagePackSerialization-opcache

  • 🟥 execution_time [+6.197µs; +8.203µs] or [+2.885%; +3.819%]

scenario:PDOBench/benchPDOBaseline

  • 🟩 execution_time [-17.022µs; -15.824µs] or [-8.451%; -7.856%]

scenario:SamplingRuleMatchingBench/benchRegexMatching3-opcache

  • 🟩 execution_time [-459.266ns; -165.534ns] or [-6.261%; -2.257%]

@PROFeNoM PROFeNoM changed the title wip feat: API Gateway Tracing Feb 19, 2025
'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',
Copy link

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",
Copy link

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',

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

Copy link

@zarirhamza zarirhamza Feb 20, 2025

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) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.

Comment on lines +23 to +26
ddtrace_proxy_info *info;
ZEND_HASH_FOREACH_PTR(&proxy_info_map, info) {
efree(info);
} ZEND_HASH_FOREACH_END();
Copy link
Collaborator

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);
Copy link
Collaborator

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.

Copy link
Contributor Author

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.

Copy link
Collaborator

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.

Comment on lines +1191 to +1195
} 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);
Copy link
Collaborator

@bwoebi bwoebi Feb 21, 2025

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;
Copy link
Collaborator

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?

Copy link
Collaborator

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)
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants