Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 51
feat: lambda support for DSM#622
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
18bcf3caf174d4eeea7621c780727a39290e7d8a726e7e5eb4733bb0fd395e398355733bbe48df533c0986cf5ff39547146f9d42c33cdc6c3672f3912deafcd8a4379b5af84f3ffd16fc84ea144ad2bab9996fbb8b0313bcfbb1f80b019789dca396d849b75a375d81f465407ec5dfe58dfab67123e5a3e0497d081237b304638621a9df0ab8ff3fb021c8f8ef984270f71f84c4fa49be467dd2018994b0665401647c447e390af55ffb0e7520a54f24821b85f838e26625dfc3bbdb88f0a7d88828a05048e07d1ae8ee9d19765e21cd76e4File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -67,6 +67,24 @@ | ||
| LOWER_64_BITS = "LOWER_64_BITS" | ||
| def _dsm_set_checkpoint(context_json, event_type, arn): | ||
| if not config.data_streams_enabled: | ||
| return | ||
| if not arn: | ||
| return | ||
| try: | ||
| from ddtrace.data_streams import set_consume_checkpoint | ||
| carrier_get = lambda k: context_json and context_json.get(k) # noqa: E731 | ||
michael-zhao459 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| set_consume_checkpoint(event_type, arn, carrier_get, manual_checkpoint=False) | ||
| except Exception as e: | ||
| logger.debug( | ||
| f"DSM:Failed to set consume checkpoint for {event_type} {arn}: {e}" | ||
| ) | ||
| def _convert_xray_trace_id(xray_trace_id): | ||
| """ | ||
| Convert X-Ray trace id (hex)'s last 63 bits to a Datadog trace id (int). | ||
| @@ -202,7 +220,9 @@ def create_sns_event(message): | ||
| } | ||
| def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context): | ||
| def extract_context_from_sqs_or_sns_event_or_context( | ||
| event, lambda_context, event_source | ||
| ): | ||
| """ | ||
| Extract Datadog trace context from an SQS event. | ||
| @@ -214,7 +234,10 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context): | ||
| Lambda Context. | ||
| Falls back to lambda context if no trace data is found in the SQS message attributes. | ||
| Set a DSM checkpoint if DSM is enabled and the method for context propagation is supported. | ||
| """ | ||
| source_arn = "" | ||
michael-zhao459 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| event_type = "sqs" if event_source.equals(EventTypes.SQS) else "sns" | ||
| # EventBridge => SQS | ||
| try: | ||
| @@ -226,6 +249,7 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context): | ||
| try: | ||
| first_record = event.get("Records")[0] | ||
purple4reina marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| source_arn = first_record.get("eventSourceARN", "") | ||
| # logic to deal with SNS => SQS event | ||
| if "body" in first_record: | ||
michael-zhao459 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| @@ -241,6 +265,9 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context): | ||
| msg_attributes = first_record.get("messageAttributes") | ||
| if msg_attributes is None: | ||
| sns_record = first_record.get("Sns") or {} | ||
| # SNS->SQS event would extract SNS arn without this check | ||
purple4reina marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if event_source.equals(EventTypes.SNS): | ||
| source_arn = sns_record.get("TopicArn", "") | ||
| msg_attributes = sns_record.get("MessageAttributes") or {} | ||
| dd_payload = msg_attributes.get("_datadog") | ||
| if dd_payload: | ||
| @@ -272,8 +299,9 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context): | ||
| logger.debug( | ||
| "Failed to extract Step Functions context from SQS/SNS event." | ||
| ) | ||
| return propagator.extract(dd_data) | ||
| context = propagator.extract(dd_data) | ||
| _dsm_set_checkpoint(dd_data, event_type, source_arn) | ||
| return context | ||
| else: | ||
| # Handle case where trace context is injected into attributes.AWSTraceHeader | ||
| # example: Root=1-654321ab-000000001234567890abcdef;Parent=0123456789abcdef;Sampled=1 | ||
| @@ -296,9 +324,13 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context): | ||
| span_id=int(x_ray_context["parent_id"], 16), | ||
| sampling_priority=float(x_ray_context["sampled"]), | ||
| ) | ||
| # Still want to set a DSM checkpoint even if DSM context not propagated | ||
ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We want to set a checkpoint even when context is not propagated because we can still track the consume call, even if the produce call wasn't tracked. | ||
| _dsm_set_checkpoint(None, event_type, source_arn) | ||
| return extract_context_from_lambda_context(lambda_context) | ||
| except Exception as e: | ||
| logger.debug("The trace extractor returned with error %s", e) | ||
| # Still want to set a DSM checkpoint even if DSM context not propagated | ||
| _dsm_set_checkpoint(None, event_type, source_arn) | ||
| return extract_context_from_lambda_context(lambda_context) | ||
| @@ -357,9 +389,12 @@ def extract_context_from_eventbridge_event(event, lambda_context): | ||
| def extract_context_from_kinesis_event(event, lambda_context): | ||
| """ | ||
| Extract datadog trace context from a Kinesis Stream's base64 encoded data string | ||
| Set a DSM checkpoint if DSM is enabled and the method for context propagation is supported. | ||
| """ | ||
| source_arn = "" | ||
| try: | ||
| record = get_first_record(event) | ||
| source_arn = record.get("eventSourceARN", "") | ||
| kinesis = record.get("kinesis") | ||
| if not kinesis: | ||
| return extract_context_from_lambda_context(lambda_context) | ||
| @@ -373,10 +408,13 @@ def extract_context_from_kinesis_event(event, lambda_context): | ||
| data_obj = json.loads(data_str) | ||
| dd_ctx = data_obj.get("_datadog") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when would that be set for Kinesis? ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://github.com/DataDog/dd-trace-py/blob/926d8383af8e71c6a83494adf85918a4ad7cf920/ddtrace/internal/datastreams/botocore.py#L230 Where we inject DSM context for Kinesis produce call | ||
| if dd_ctx: | ||
| return propagator.extract(dd_ctx) | ||
| context = propagator.extract(dd_ctx) | ||
| _dsm_set_checkpoint(dd_ctx, "kinesis", source_arn) | ||
| return context | ||
| except Exception as e: | ||
| logger.debug("The trace extractor returned with error %s", e) | ||
| # Still want to set a DSM checkpoint even if DSM context not propagated | ||
| _dsm_set_checkpoint(None, "kinesis", source_arn) | ||
| return extract_context_from_lambda_context(lambda_context) | ||
| @@ -594,7 +632,7 @@ def extract_dd_trace_context( | ||
| ) | ||
| elif event_source.equals(EventTypes.SNS) or event_source.equals(EventTypes.SQS): | ||
| context = extract_context_from_sqs_or_sns_event_or_context( | ||
| event, lambda_context | ||
| event, lambda_context, event_source | ||
| ) | ||
| elif event_source.equals(EventTypes.EVENTBRIDGE): | ||
| context = extract_context_from_eventbridge_event(event, lambda_context) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -28,7 +28,7 @@ classifiers = [ | ||
| python = ">=3.8.0,<4" | ||
| datadog = ">=0.51.0,<1.0.0" | ||
| wrapt = "^1.11.2" | ||
| ddtrace = ">=2.20.0,<4" | ||
| ddtrace = ">=3.10.2,<4" | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be good to release this now that v3.10.2 is up in pypi. | ||
| ujson = ">=5.9.0" | ||
| botocore = { version = "^1.34.0", optional = true } | ||
| requests = { version ="^2.22.0", optional = true } | ||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.