Skip to content

Commit ba58ecd

Browse files
hghotrachris.agocs
and
chris.agocs
authored
[SLS-1674] Additional attributes for different managed services (#200)
* Additional attributes for sqs spans * Add additional attributes for sns * Add event subscription arn for sns * Add additional attributes for kinesis spans * Add additional attributes for dynamodb spans * Add additional attributes for s3 spans * Additional attribute for eventbridge spans * Add additional attributes for websocket spans * Fix websocket resource name * Additional attributes for apigateway v1 spans * Additional attributes for api-gateway v2 spans * Fix api-gateway v1 resource name * Fix merge issue * Add space to resource name * Update tests * black * Add typing_extensions to pyproject.toml * Update snapshots * Fix snapshots Co-authored-by: chris.agocs <[email protected]>
1 parent 6901afa commit ba58ecd

11 files changed

+183
-110
lines changed

datadog_lambda/tracing.py

Lines changed: 91 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77
import os
88
import json
99
from datetime import datetime, timezone
10-
from typing import Optional, Literal, Dict
10+
from typing import Optional, Dict
11+
12+
try:
13+
from typing import Literal
14+
except ImportError:
15+
# Literal was added to typing in python 3.8
16+
from typing_extensions import Literal
1117

1218
from datadog_lambda.constants import (
1319
SamplingPriority,
@@ -442,24 +448,30 @@ def is_api_gateway_invocation_async(event):
442448

443449

444450
def create_inferred_span_from_api_gateway_websocket_event(event, context):
445-
domain = event["requestContext"]["domainName"]
446-
endpoint = event["requestContext"]["routeKey"]
451+
request_context = event["requestContext"]
452+
domain = request_context["domainName"]
453+
endpoint = request_context["routeKey"]
447454
tags = {
448455
"operation_name": "aws.apigateway.websocket",
449456
"http.url": domain + endpoint,
450457
"endpoint": endpoint,
451-
"resource_names": domain + endpoint,
452-
"request_id": context.aws_request_id,
453-
"connection_id": event["requestContext"]["connectionId"],
458+
"resource_names": endpoint,
459+
"apiid": request_context["apiId"],
460+
"apiname": request_context["apiId"],
461+
"stage": request_context["stage"],
462+
"request_id": request_context["requestId"],
463+
"connection_id": request_context["connectionId"],
464+
"event_type": request_context["eventType"],
465+
"message_direction": request_context["messageDirection"],
454466
}
467+
request_time_epoch = request_context["requestTimeEpoch"]
455468
if is_api_gateway_invocation_async(event):
456469
InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async")
457470
else:
458471
InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="sync")
459-
request_time_epoch = event["requestContext"]["requestTimeEpoch"]
460472
args = {
461473
"service": domain,
462-
"resource": domain + endpoint,
474+
"resource": endpoint,
463475
"span_type": "web",
464476
}
465477
tracer.set_tags({"_dd.origin": "lambda"})
@@ -471,24 +483,30 @@ def create_inferred_span_from_api_gateway_websocket_event(event, context):
471483

472484

473485
def create_inferred_span_from_api_gateway_event(event, context):
474-
domain = event["requestContext"]["domainName"]
486+
request_context = event["requestContext"]
487+
domain = request_context["domainName"]
488+
method = event["httpMethod"]
475489
path = event["path"]
490+
resource = "{0} {1}".format(method, path)
476491
tags = {
477492
"operation_name": "aws.apigateway.rest",
478493
"http.url": domain + path,
479494
"endpoint": path,
480-
"http.method": event["httpMethod"],
481-
"resource_names": domain + path,
482-
"request_id": context.aws_request_id,
495+
"http.method": method,
496+
"resource_names": resource,
497+
"apiid": request_context["apiId"],
498+
"apiname": request_context["apiId"],
499+
"stage": request_context["stage"],
500+
"request_id": request_context["requestId"],
483501
}
502+
request_time_epoch = request_context["requestTimeEpoch"]
484503
if is_api_gateway_invocation_async(event):
485504
InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async")
486505
else:
487506
InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="sync")
488-
request_time_epoch = event["requestContext"]["requestTimeEpoch"]
489507
args = {
490508
"service": domain,
491-
"resource": domain + path,
509+
"resource": resource,
492510
"span_type": "http",
493511
}
494512
tracer.set_tags({"_dd.origin": "lambda"})
@@ -500,24 +518,33 @@ def create_inferred_span_from_api_gateway_event(event, context):
500518

501519

502520
def create_inferred_span_from_http_api_event(event, context):
503-
domain = event["requestContext"]["domainName"]
521+
request_context = event["requestContext"]
522+
domain = request_context["domainName"]
523+
method = request_context["http"]["method"]
504524
path = event["rawPath"]
525+
resource = "{0} {1}".format(method, path)
505526
tags = {
506527
"operation_name": "aws.httpapi",
507-
"http.url": domain + path,
508528
"endpoint": path,
509-
"http.method": event["requestContext"]["http"]["method"],
510-
"resource_names": domain + path,
529+
"http.url": domain + path,
530+
"http.method": request_context["http"]["method"],
531+
"http.protocol": request_context["http"]["protocol"],
532+
"http.source_ip": request_context["http"]["sourceIp"],
533+
"http.user_agent": request_context["http"]["userAgent"],
534+
"resource_names": resource,
511535
"request_id": context.aws_request_id,
536+
"apiid": request_context["apiId"],
537+
"apiname": request_context["apiId"],
538+
"stage": request_context["stage"],
512539
}
540+
request_time_epoch = request_context["timeEpoch"]
513541
if is_api_gateway_invocation_async(event):
514542
InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async")
515543
else:
516544
InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="sync")
517-
request_time_epoch = event["requestContext"]["timeEpoch"]
518545
args = {
519546
"service": domain,
520-
"resource": domain + path,
547+
"resource": resource,
521548
"span_type": "http",
522549
}
523550
tracer.set_tags({"_dd.origin": "lambda"})
@@ -530,10 +557,15 @@ def create_inferred_span_from_http_api_event(event, context):
530557

531558
def create_inferred_span_from_sqs_event(event, context):
532559
event_record = get_first_record(event)
533-
queue_name = event_record["eventSourceARN"].split(":")[-1]
560+
event_source_arn = event_record["eventSourceARN"]
561+
queue_name = event_source_arn.split(":")[-1]
534562
tags = {
535563
"operation_name": "aws.sqs",
536564
"resource_names": queue_name,
565+
"queuename": queue_name,
566+
"event_source_arn": event_source_arn,
567+
"receipt_handle": event_record["receiptHandle"],
568+
"sender_id": event_record["attributes"]["SenderId"],
537569
}
538570
InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async")
539571
request_time_epoch = event_record["attributes"]["SentTimestamp"]
@@ -552,10 +584,18 @@ def create_inferred_span_from_sqs_event(event, context):
552584

553585
def create_inferred_span_from_sns_event(event, context):
554586
event_record = get_first_record(event)
555-
topic_name = event_record["Sns"]["TopicArn"].split(":")[-1]
587+
sns_message = event_record["Sns"]
588+
topic_arn = event_record["Sns"]["TopicArn"]
589+
topic_name = topic_arn.split(":")[-1]
556590
tags = {
557591
"operation_name": "aws.sns",
558592
"resource_names": topic_name,
593+
"topicname": topic_name,
594+
"topic_arn": topic_arn,
595+
"message_id": sns_message["MessageId"],
596+
"type": sns_message["Type"],
597+
"subject": sns_message["Subject"],
598+
"event_subscription_arn": event_record["EventSubscriptionArn"],
559599
}
560600
InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async")
561601
sns_dt_format = "%Y-%m-%dT%H:%M:%S.%fZ"
@@ -577,10 +617,20 @@ def create_inferred_span_from_sns_event(event, context):
577617

578618
def create_inferred_span_from_kinesis_event(event, context):
579619
event_record = get_first_record(event)
580-
stream_name = event_record["eventSourceARN"].split(":")[-1]
620+
event_source_arn = event_record["eventSourceARN"]
621+
event_id = event_record["eventID"]
622+
stream_name = event_source_arn.split(":")[-1]
623+
shard_id = event_id.split(":")[0]
581624
tags = {
582625
"operation_name": "aws.kinesis",
583626
"resource_names": stream_name,
627+
"streamname": stream_name,
628+
"shardid": shard_id,
629+
"event_source_arn": event_source_arn,
630+
"event_id": event_id,
631+
"event_name": event_record["eventName"],
632+
"event_version": event_record["eventVersion"],
633+
"partition_key": event_record["kinesis"]["partitionKey"],
584634
}
585635
InferredSpanInfo.set_tags(tags, tag_source="self", synchronicity="async")
586636
request_time_epoch = event_record["kinesis"]["approximateArrivalTimestamp"]
@@ -600,14 +650,22 @@ def create_inferred_span_from_kinesis_event(event, context):
600650

601651
def create_inferred_span_from_dynamodb_event(event, context):
602652
event_record = get_first_record(event)
603-
table_name = event_record["eventSourceARN"].split("/")[1]
653+
event_source_arn = event_record["eventSourceARN"]
654+
table_name = event_source_arn.split("/")[1]
655+
dynamodb_message = event_record["dynamodb"]
604656
tags = {
605657
"operation_name": "aws.dynamodb",
606658
"resource_names": table_name,
659+
"tablename": table_name,
660+
"event_source_arn": event_source_arn,
661+
"event_id": event_record["eventID"],
662+
"event_name": event_record["eventName"],
663+
"event_version": event_record["eventVersion"],
664+
"stream_view_type": dynamodb_message["StreamViewType"],
665+
"size_bytes": dynamodb_message["SizeBytes"],
607666
}
608667
InferredSpanInfo.set_tags(tags, synchronicity="async", tag_source="self")
609668
request_time_epoch = event_record["dynamodb"]["ApproximateCreationDateTime"]
610-
611669
args = {
612670
"service": "dynamodb",
613671
"resource": table_name,
@@ -617,6 +675,7 @@ def create_inferred_span_from_dynamodb_event(event, context):
617675
span = tracer.trace("aws.dynamodb", **args)
618676
if span:
619677
span.set_tags(tags)
678+
620679
span.start = int(request_time_epoch)
621680
return span
622681

@@ -627,6 +686,12 @@ def create_inferred_span_from_s3_event(event, context):
627686
tags = {
628687
"operation_name": "aws.s3",
629688
"resource_names": bucket_name,
689+
"event_name": event_record["eventName"],
690+
"bucketname": bucket_name,
691+
"bucket_arn": event_record["s3"]["bucket"]["arn"],
692+
"object_key": event_record["s3"]["object"]["key"],
693+
"object_size": event_record["s3"]["object"]["size"],
694+
"object_etag": event_record["s3"]["etag"],
630695
}
631696
InferredSpanInfo.set_tags(tags, synchronicity="async", tag_source="self")
632697
dt_format = "%Y-%m-%dT%H:%M:%S.%fZ"
@@ -651,6 +716,7 @@ def create_inferred_span_from_eventbridge_event(event, context):
651716
tags = {
652717
"operation_name": "aws.eventbridge",
653718
"resource_names": source,
719+
"detail_type": event["detail-type"],
654720
}
655721
InferredSpanInfo.set_tags(
656722
tags,

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ datadog = "^0.41.0"
2828
wrapt = "^1.11.2"
2929
ddtrace = "^0.50.0"
3030
importlib_metadata = {version = "^1.0", python = "<3.8"}
31+
typing_extensions = {version = "^4.0", python = "<3.8"}
3132
boto3 = { version = "^1.10.33", optional = true }
3233
requests = { version ="^2.22.0", optional = true }
3334
nose2 = { version= "^0.9.1", optional = true }

0 commit comments

Comments
 (0)