From 908a42edf70230656aa6709111ea1c78267fc348 Mon Sep 17 00:00:00 2001 From: Andrew Rodriguez Date: Mon, 11 Mar 2024 11:04:23 -0700 Subject: [PATCH 1/5] use route key --- datadog_lambda/tracing.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/datadog_lambda/tracing.py b/datadog_lambda/tracing.py index 5e338253..068a766c 100644 --- a/datadog_lambda/tracing.py +++ b/datadog_lambda/tracing.py @@ -891,9 +891,15 @@ def create_inferred_span_from_api_gateway_event( service_name = determine_service_name( service_mapping, api_id, "lambda_api_gateway", domain ) - method = event.get("httpMethod") - path = event.get("path") - resource = "{0} {1}".format(method, path) + + method = request_context.get("httpMethod") + if not method: + method = request_context.get("http", {}).get("method") + + path = event.get("rawPath") or request_context.get("path") or request_context.get("routeKey") + resource_path = event.get("rawPath") or request_context.get("resourcePath") or request_context.get("routeKey") + + resource = "{} {}".format(method if method else domain, resource_path) tags = { "operation_name": "aws.apigateway.rest", "http.url": domain + path, From 812751ba0a8479a2c5bfdf85824fef1d4812f5ff Mon Sep 17 00:00:00 2001 From: Rey Abolofia Date: Tue, 26 Mar 2024 14:02:53 -0700 Subject: [PATCH 2/5] Align with js implementation. --- datadog_lambda/tracing.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/datadog_lambda/tracing.py b/datadog_lambda/tracing.py index 068a766c..300eb933 100644 --- a/datadog_lambda/tracing.py +++ b/datadog_lambda/tracing.py @@ -885,21 +885,17 @@ def create_inferred_span_from_api_gateway_websocket_event( def create_inferred_span_from_api_gateway_event( event, context, decode_authorizer_context: bool = True ): - request_context = event.get("requestContext") - domain = request_context.get("domainName", "") + request_context = event.get("requestContext") or {} + domain = request_context.get("domainName") or "" api_id = request_context.get("apiId") service_name = determine_service_name( service_mapping, api_id, "lambda_api_gateway", domain ) - - method = request_context.get("httpMethod") - if not method: - method = request_context.get("http", {}).get("method") - - path = event.get("rawPath") or request_context.get("path") or request_context.get("routeKey") - resource_path = event.get("rawPath") or request_context.get("resourcePath") or request_context.get("routeKey") - - resource = "{} {}".format(method if method else domain, resource_path) + method = request_context.get("httpMethod") or request_context.get("http", {}).get("method") + path = event.get("rawPath") or request_context.get("path") or request_context.get("routeKey", "") + resource_path = _get_resource_path(event, request_context) + + resource = "{} {}".format(method, resource_path) tags = { "operation_name": "aws.apigateway.rest", "http.url": domain + path, @@ -942,6 +938,16 @@ def create_inferred_span_from_api_gateway_event( return span +def _get_resource_path(event, request_context): + route_key = request_context.get("routeKey") or "" + if "{" in route_key: + try: + return route_key.split(" ")[1] + except Exception as e: + logger.debug("Error parsing routeKey: %s", e) + return event.get("rawPath") or request_context.get("resourcePath") or route_key + + def create_inferred_span_from_http_api_event( event, context, decode_authorizer_context: bool = True ): From 0db470969ae06a670492aac22450e71b6a5f4920 Mon Sep 17 00:00:00 2001 From: Rey Abolofia Date: Thu, 28 Mar 2024 10:09:54 -0700 Subject: [PATCH 3/5] Update existing tests. --- tests/test_tracing.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/test_tracing.py b/tests/test_tracing.py index d38bb7d3..8158be27 100644 --- a/tests/test_tracing.py +++ b/tests/test_tracing.py @@ -1373,12 +1373,12 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "1234567890", "apiname": "1234567890", - "endpoint": "/path/to/resource", + "endpoint": "/prod/path/to/resource", "http.method": "POST", - "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource", + "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/prod/path/to/resource", "operation_name": "aws.apigateway.rest", "request_id": "123", - "resource_names": "POST /path/to/resource", + "resource_names": "POST /{proxy+}", "stage": "prod", }, ), @@ -1395,9 +1395,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "lgxbo6a518", "apiname": "lgxbo6a518", - "endpoint": "/http/get", + "endpoint": "/dev/http/get", "http.method": "GET", - "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get", + "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/dev/http/get", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /http/get", @@ -1417,9 +1417,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "lgxbo6a518", "apiname": "lgxbo6a518", - "endpoint": "/http/get", + "endpoint": "/dev/http/get", "http.method": "GET", - "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get", + "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/dev/http/get", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /http/get", @@ -1711,12 +1711,12 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "None", "apiname": "None", - "endpoint": "/path/to/resource", + "endpoint": "/prod/path/to/resource", "http.method": "POST", - "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource", + "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/prod/path/to/resource", "operation_name": "aws.apigateway.rest", "request_id": "123", - "resource_names": "POST /path/to/resource", + "resource_names": "POST /{proxy+}", "stage": "prod", }, ), @@ -1734,9 +1734,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "amddr1rix9", "apiname": "amddr1rix9", - "endpoint": "/hello", + "endpoint": "/dev/hello", "http.method": "GET", - "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", + "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/dev/hello", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /hello", @@ -1756,9 +1756,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "amddr1rix9", "apiname": "amddr1rix9", - "endpoint": "/hello", + "endpoint": "/dev/hello", "http.method": "GET", - "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", + "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/dev/hello", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /hello", @@ -1779,9 +1779,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "amddr1rix9", "apiname": "amddr1rix9", - "endpoint": "/hello", + "endpoint": "/dev/hello", "http.method": "GET", - "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", + "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/dev/hello", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /hello", @@ -1801,9 +1801,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "amddr1rix9", "apiname": "amddr1rix9", - "endpoint": "/hello", + "endpoint": "/dev/hello", "http.method": "GET", - "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", + "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/dev/hello", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /hello", From e8d3b62d807635612e3c2beca3d68b0f3660b4c5 Mon Sep 17 00:00:00 2001 From: Rey Abolofia Date: Thu, 28 Mar 2024 10:10:14 -0700 Subject: [PATCH 4/5] Add new parametrized tests. --- .../api-gateway-v1-parametrized.json | 111 ++++++++++++++++++ .../api-gateway-v2-parametrized.json | 38 ++++++ tests/test_tracing.py | 44 +++++++ 3 files changed, 193 insertions(+) create mode 100644 tests/event_samples/api-gateway-v1-parametrized.json create mode 100644 tests/event_samples/api-gateway-v2-parametrized.json diff --git a/tests/event_samples/api-gateway-v1-parametrized.json b/tests/event_samples/api-gateway-v1-parametrized.json new file mode 100644 index 00000000..65527ccb --- /dev/null +++ b/tests/event_samples/api-gateway-v1-parametrized.json @@ -0,0 +1,111 @@ +{ + "resource": "/user/{id}", + "path": "/user/42", + "httpMethod": "GET", + "headers": { + "Accept": "*/*", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-ASN": "7922", + "CloudFront-Viewer-Country": "US", + "Host": "mcwkra0ya4.execute-api.sa-east-1.amazonaws.com", + "User-Agent": "curl/8.1.2", + "Via": "2.0 xxx.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "Tz3yUVcJkwOhQGqZgKTzrEHqAoOd8ZprYAHpg2S6BNxdd-Ym79pb6g==", + "X-Amzn-Trace-Id": "Root=1-65f49d20-7ba106216238dd0078a5db31", + "X-Forwarded-For": "76.115.124.192, 15.158.54.119", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "multiValueHeaders": { + "Accept": [ + "*/*" + ], + "CloudFront-Forwarded-Proto": [ + "https" + ], + "CloudFront-Is-Desktop-Viewer": [ + "true" + ], + "CloudFront-Is-Mobile-Viewer": [ + "false" + ], + "CloudFront-Is-SmartTV-Viewer": [ + "false" + ], + "CloudFront-Is-Tablet-Viewer": [ + "false" + ], + "CloudFront-Viewer-ASN": [ + "7922" + ], + "CloudFront-Viewer-Country": [ + "US" + ], + "Host": [ + "mcwkra0ya4.execute-api.sa-east-1.amazonaws.com" + ], + "User-Agent": [ + "curl/8.1.2" + ], + "Via": [ + "2.0 xxx.cloudfront.net (CloudFront)" + ], + "X-Amz-Cf-Id": [ + "Tz3yUVcJkwOhQGqZgKTzrEHqAoOd8ZprYAHpg2S6BNxdd-Ym79pb6g==" + ], + "X-Amzn-Trace-Id": [ + "Root=1-65f49d20-7ba106216238dd0078a5db31" + ], + "X-Forwarded-For": [ + "76.115.124.192, 15.158.54.119" + ], + "X-Forwarded-Port": [ + "443" + ], + "X-Forwarded-Proto": [ + "https" + ] + }, + "queryStringParameters": null, + "multiValueQueryStringParameters": null, + "pathParameters": { + "id": "42" + }, + "stageVariables": null, + "requestContext": { + "resourceId": "ojg3nk", + "resourcePath": "/user/{id}", + "httpMethod": "GET", + "extendedRequestId": "Ur19IHYDmjQEU5A=", + "requestTime": "15/Mar/2024:19:10:24 +0000", + "path": "/dev/user/42", + "accountId": "425362996713", + "protocol": "HTTP/1.1", + "stage": "dev", + "domainPrefix": "mcwkra0ya4", + "requestTimeEpoch": 1710529824520, + "requestId": "e16399f7-e984-463a-9931-745ba021a27f", + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "sourceIp": "76.115.124.192", + "principalOrgId": null, + "accessKey": null, + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "curl/8.1.2", + "user": null + }, + "domainName": "mcwkra0ya4.execute-api.sa-east-1.amazonaws.com", + "apiId": "mcwkra0ya4" + }, + "body": null, + "isBase64Encoded": false +} diff --git a/tests/event_samples/api-gateway-v2-parametrized.json b/tests/event_samples/api-gateway-v2-parametrized.json new file mode 100644 index 00000000..89ff72b9 --- /dev/null +++ b/tests/event_samples/api-gateway-v2-parametrized.json @@ -0,0 +1,38 @@ +{ + "version": "2.0", + "routeKey": "GET /user/{id}", + "rawPath": "/user/42", + "rawQueryString": "", + "headers": { + "accept": "*/*", + "content-length": "0", + "host": "9vj54we5ih.execute-api.sa-east-1.amazonaws.com", + "user-agent": "curl/8.1.2", + "x-amzn-trace-id": "Root=1-65f49d71-505edb3b69b8abd513cfa08b", + "x-forwarded-for": "76.115.124.192", + "x-forwarded-port": "443", + "x-forwarded-proto": "https" + }, + "requestContext": { + "accountId": "425362996713", + "apiId": "9vj54we5ih", + "domainName": "9vj54we5ih.execute-api.sa-east-1.amazonaws.com", + "domainPrefix": "9vj54we5ih", + "http": { + "method": "GET", + "path": "/user/42", + "protocol": "HTTP/1.1", + "sourceIp": "76.115.124.192", + "userAgent": "curl/8.1.2" + }, + "requestId": "Ur2JtjEfGjQEPOg=", + "routeKey": "GET /user/{id}", + "stage": "$default", + "time": "15/Mar/2024:19:11:45 +0000", + "timeEpoch": 1710529905066 + }, + "pathParameters": { + "id": "42" + }, + "isBase64Encoded": false +} diff --git a/tests/test_tracing.py b/tests/test_tracing.py index 8158be27..4412a37f 100644 --- a/tests/test_tracing.py +++ b/tests/test_tracing.py @@ -1452,6 +1452,50 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): }, ), ), + ( + "api-gateway-v1-parametrized", + _Span( + service="mcwkra0ya4.execute-api.sa-east-1.amazonaws.com", + start=1710529824.52, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "mcwkra0ya4", + "apiname": "mcwkra0ya4", + "endpoint": "/dev/user/42", + "http.method": "GET", + "http.url": "mcwkra0ya4.execute-api.sa-east-1.amazonaws.com/dev/user/42", + "operation_name": "aws.apigateway.rest", + "request_id": "123", + "resource_names": "GET /user/{id}", + "stage": "dev", + }, + ), + ), + ( + "api-gateway-v2-parametrized", + _Span( + service="9vj54we5ih.execute-api.sa-east-1.amazonaws.com", + start=1710529905.066, + span_type="http", + tags={ + "_dd.origin": "lambda", + "_inferred_span.synchronicity": "sync", + "_inferred_span.tag_source": "self", + "apiid": "9vj54we5ih", + "apiname": "9vj54we5ih", + "endpoint": "/user/42", + "http.method": "GET", + "http.url": "9vj54we5ih.execute-api.sa-east-1.amazonaws.com/user/42", + "operation_name": "aws.httpapi", + "request_id": "123", + "resource_names": "GET /user/{id}", + "stage": "$default", + }, + ), + ), ( "api-gateway-websocket-default", _Span( From 0f16ebbe884047e92bc62fe7c85524062e7b5f00 Mon Sep 17 00:00:00 2001 From: Rey Abolofia Date: Thu, 28 Mar 2024 10:10:26 -0700 Subject: [PATCH 5/5] Revert v1 to original. --- datadog_lambda/tracing.py | 14 +++++++------- tests/test_tracing.py | 36 ++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/datadog_lambda/tracing.py b/datadog_lambda/tracing.py index 300eb933..ae2a0112 100644 --- a/datadog_lambda/tracing.py +++ b/datadog_lambda/tracing.py @@ -885,17 +885,16 @@ def create_inferred_span_from_api_gateway_websocket_event( def create_inferred_span_from_api_gateway_event( event, context, decode_authorizer_context: bool = True ): - request_context = event.get("requestContext") or {} - domain = request_context.get("domainName") or "" + request_context = event.get("requestContext") + domain = request_context.get("domainName", "") api_id = request_context.get("apiId") service_name = determine_service_name( service_mapping, api_id, "lambda_api_gateway", domain ) - method = request_context.get("httpMethod") or request_context.get("http", {}).get("method") - path = event.get("rawPath") or request_context.get("path") or request_context.get("routeKey", "") + method = event.get("httpMethod") + path = event.get("path") resource_path = _get_resource_path(event, request_context) - - resource = "{} {}".format(method, resource_path) + resource = "{0} {1}".format(method, resource_path) tags = { "operation_name": "aws.apigateway.rest", "http.url": domain + path, @@ -959,7 +958,8 @@ def create_inferred_span_from_http_api_event( ) method = request_context.get("http", {}).get("method") path = event.get("rawPath") - resource = "{0} {1}".format(method, path) + resource_path = _get_resource_path(event, request_context) + resource = "{0} {1}".format(method, resource_path) tags = { "operation_name": "aws.httpapi", "endpoint": path, diff --git a/tests/test_tracing.py b/tests/test_tracing.py index 4412a37f..0f7b84b4 100644 --- a/tests/test_tracing.py +++ b/tests/test_tracing.py @@ -1373,9 +1373,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "1234567890", "apiname": "1234567890", - "endpoint": "/prod/path/to/resource", + "endpoint": "/path/to/resource", "http.method": "POST", - "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/prod/path/to/resource", + "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "POST /{proxy+}", @@ -1395,9 +1395,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "lgxbo6a518", "apiname": "lgxbo6a518", - "endpoint": "/dev/http/get", + "endpoint": "/http/get", "http.method": "GET", - "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/dev/http/get", + "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /http/get", @@ -1417,9 +1417,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "lgxbo6a518", "apiname": "lgxbo6a518", - "endpoint": "/dev/http/get", + "endpoint": "/http/get", "http.method": "GET", - "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/dev/http/get", + "http.url": "lgxbo6a518.execute-api.eu-west-1.amazonaws.com/http/get", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /http/get", @@ -1464,9 +1464,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "mcwkra0ya4", "apiname": "mcwkra0ya4", - "endpoint": "/dev/user/42", + "endpoint": "/user/42", "http.method": "GET", - "http.url": "mcwkra0ya4.execute-api.sa-east-1.amazonaws.com/dev/user/42", + "http.url": "mcwkra0ya4.execute-api.sa-east-1.amazonaws.com/user/42", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /user/{id}", @@ -1755,9 +1755,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "None", "apiname": "None", - "endpoint": "/prod/path/to/resource", + "endpoint": "/path/to/resource", "http.method": "POST", - "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/prod/path/to/resource", + "http.url": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com/path/to/resource", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "POST /{proxy+}", @@ -1778,9 +1778,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "amddr1rix9", "apiname": "amddr1rix9", - "endpoint": "/dev/hello", + "endpoint": "/hello", "http.method": "GET", - "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/dev/hello", + "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /hello", @@ -1800,9 +1800,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "amddr1rix9", "apiname": "amddr1rix9", - "endpoint": "/dev/hello", + "endpoint": "/hello", "http.method": "GET", - "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/dev/hello", + "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /hello", @@ -1823,9 +1823,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "amddr1rix9", "apiname": "amddr1rix9", - "endpoint": "/dev/hello", + "endpoint": "/hello", "http.method": "GET", - "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/dev/hello", + "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /hello", @@ -1845,9 +1845,9 @@ def __init__(self, service, start, span_type, parent_name=None, tags=None): "_inferred_span.tag_source": "self", "apiid": "amddr1rix9", "apiname": "amddr1rix9", - "endpoint": "/dev/hello", + "endpoint": "/hello", "http.method": "GET", - "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/dev/hello", + "http.url": "amddr1rix9.execute-api.eu-west-1.amazonaws.com/hello", "operation_name": "aws.apigateway.rest", "request_id": "123", "resource_names": "GET /hello",