Skip to content

Commit 98e7757

Browse files
authored
Remove aws-xray-sdk (#171)
1 parent cd6be68 commit 98e7757

File tree

7 files changed

+241
-70
lines changed

7 files changed

+241
-70
lines changed

LICENSE-3rdparty.csv

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
Component,Origin,License,Copyright
2-
aws-xray-sdk-python,github.com/aws/aws-xray-sdk-python,Apache-2.0,
32
flake8,gitlab.com/pycqa/flake8,MIT,"Copyright (C) 2011-2013 Tarek Ziade <[email protected]>. Copyright (C) 2012-2016 Ian Cordasco <[email protected]>."
43
nose2,github.com/nose-devs/nose2,BSD-2-Clause,"Copyright (c) 2012, Jason Pellerin. All rights reserved."
5-
requests,github.com/kennethreitz/requests,Apache-2.0,"Copyright 2018 Kenneth Reitz"
64
wrapt,github.com/GrahamDumpleton/wrapt,BSD-2-Clause,"Copyright (c) 2013-2019, Graham Dumpleton"

datadog_lambda/constants.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,10 @@ class TraceContextSource(object):
3434
XRAY = "xray"
3535
EVENT = "event"
3636
DDTRACE = "ddtrace"
37+
38+
39+
# X-Ray deamon
40+
class XrayDaemon(object):
41+
XRAY_TRACE_ID_HEADER_NAME = "_X_AMZN_TRACE_ID"
42+
XRAY_DAEMON_ADDRESS = "AWS_XRAY_DAEMON_ADDRESS"
43+
FUNCTION_NAME_HEADER_NAME = "AWS_LAMBDA_FUNCTION_NAME"

datadog_lambda/tracing.py

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
import os
88
import json
99

10-
from aws_xray_sdk.core import xray_recorder
11-
from aws_xray_sdk.core.lambda_launcher import LambdaContext
1210
from datadog_lambda.constants import (
1311
SamplingPriority,
1412
TraceHeader,
15-
XraySubsegment,
1613
TraceContextSource,
14+
XrayDaemon,
15+
)
16+
from datadog_lambda.xray import (
17+
send_segment,
18+
parse_xray_header,
1719
)
1820
from ddtrace import tracer, patch
1921
from ddtrace import __version__ as ddtrace_version
@@ -57,16 +59,24 @@ def _get_xray_trace_context():
5759
if not is_lambda_context():
5860
return None
5961

60-
xray_trace_entity = xray_recorder.get_trace_entity() # xray (sub)segment
62+
xray_trace_entity = parse_xray_header(
63+
os.environ.get(XrayDaemon.XRAY_TRACE_ID_HEADER_NAME, "")
64+
)
65+
if xray_trace_entity is None:
66+
return None
6167
trace_context = {
62-
"trace-id": _convert_xray_trace_id(xray_trace_entity.trace_id),
63-
"parent-id": _convert_xray_entity_id(xray_trace_entity.id),
64-
"sampling-priority": _convert_xray_sampling(xray_trace_entity.sampled),
68+
"trace-id": _convert_xray_trace_id(xray_trace_entity["trace_id"]),
69+
"parent-id": _convert_xray_entity_id(xray_trace_entity["parent_id"]),
70+
"sampling-priority": _convert_xray_sampling(xray_trace_entity["sampled"]),
6571
}
6672
logger.debug(
6773
"Converted trace context %s from X-Ray segment %s",
6874
trace_context,
69-
(xray_trace_entity.trace_id, xray_trace_entity.id, xray_trace_entity.sampled),
75+
(
76+
xray_trace_entity["trace_id"],
77+
xray_trace_entity["parent_id"],
78+
xray_trace_entity["sampled"],
79+
),
7080
)
7181
return trace_context
7282

@@ -106,19 +116,7 @@ def create_dd_dummy_metadata_subsegment(
106116
tags into its metadata field, so the X-Ray trace can be converted to a Datadog
107117
trace in the Datadog backend with the correct context.
108118
"""
109-
try:
110-
xray_recorder.begin_subsegment(XraySubsegment.NAME)
111-
subsegment = xray_recorder.current_subsegment()
112-
subsegment.put_metadata(
113-
subsegment_metadata_key, subsegment_metadata_value, XraySubsegment.NAMESPACE
114-
)
115-
xray_recorder.end_subsegment()
116-
except Exception as e:
117-
logger.debug(
118-
"failed to create dd dummy metadata subsegment with error %s",
119-
e,
120-
exc_info=True,
121-
)
119+
send_segment(subsegment_metadata_key, subsegment_metadata_value)
122120

123121

124122
def extract_context_from_lambda_context(lambda_context):
@@ -359,7 +357,7 @@ def is_lambda_context():
359357
Return True if the X-Ray context is `LambdaContext`, rather than the
360358
regular `Context` (e.g., when testing lambda functions locally).
361359
"""
362-
return type(xray_recorder.context) == LambdaContext
360+
return os.environ.get(XrayDaemon.FUNCTION_NAME_HEADER_NAME, "") != ""
363361

364362

365363
def set_dd_trace_py_root(trace_context_source, merge_xray_traces):

datadog_lambda/xray.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import os
2+
import logging
3+
import json
4+
import binascii
5+
import time
6+
import socket
7+
8+
from datadog_lambda.constants import XrayDaemon, XraySubsegment, TraceContextSource
9+
10+
logger = logging.getLogger(__name__)
11+
12+
13+
def get_xray_host_port(adress):
14+
if adress == "":
15+
logger.debug("X-Ray daemon env var not set, not sending sub-segment")
16+
return None
17+
parts = adress.split(":")
18+
if len(parts) <= 1:
19+
logger.debug("X-Ray daemon env var not set, not sending sub-segment")
20+
return None
21+
port = int(parts[1])
22+
host = parts[0]
23+
return (host, port)
24+
25+
26+
def send(host_port_tuple, payload):
27+
sock = None
28+
try:
29+
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
30+
sock.setblocking(0)
31+
sock.connect(host_port_tuple)
32+
sock.send(payload.encode("utf-8"))
33+
except Exception as e_send:
34+
logger.error("Error occurred submitting to xray daemon: %s", str(e_send))
35+
try:
36+
sock.close()
37+
except Exception as e_close:
38+
logger.error("Error while closing the socket: %s", str(e_close))
39+
40+
41+
def build_segment_payload(payload):
42+
if payload is None:
43+
return None
44+
return '{"format": "json", "version": 1}' + "\n" + payload
45+
46+
47+
def parse_xray_header(raw_trace_id):
48+
# Example: Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=1
49+
logger.debug("Reading trace context from env var %s", raw_trace_id)
50+
if len(raw_trace_id) == 0:
51+
return None
52+
parts = raw_trace_id.split(";")
53+
if len(parts) != 3:
54+
return None
55+
root = parts[0].replace("Root=", "")
56+
parent = parts[1].replace("Parent=", "")
57+
sampled = parts[2].replace("Sampled=", "")
58+
if (
59+
len(root) == len(parts[0])
60+
or len(parent) == len(parts[1])
61+
or len(sampled) == len(parts[2])
62+
):
63+
return None
64+
return {
65+
"parent_id": parent,
66+
"trace_id": root,
67+
"sampled": sampled,
68+
"source": TraceContextSource.XRAY,
69+
}
70+
71+
72+
def generate_random_id():
73+
return binascii.b2a_hex(os.urandom(8)).decode("utf-8")
74+
75+
76+
def build_segment(context, key, metadata):
77+
78+
segment = json.dumps(
79+
{
80+
"id": generate_random_id(),
81+
"trace_id": context["trace_id"],
82+
"parent_id": context["parent_id"],
83+
"name": XraySubsegment.NAME,
84+
"start_time": time.time(),
85+
"end_time": time.time(),
86+
"type": "subsegment",
87+
"metadata": {
88+
XraySubsegment.NAMESPACE: {
89+
key: metadata,
90+
}
91+
},
92+
}
93+
)
94+
return segment
95+
96+
97+
def send_segment(key, metadata):
98+
host_port_tuple = get_xray_host_port(
99+
os.environ.get(XrayDaemon.XRAY_DAEMON_ADDRESS, "")
100+
)
101+
if host_port_tuple is None:
102+
return None
103+
context = parse_xray_header(
104+
os.environ.get(XrayDaemon.XRAY_TRACE_ID_HEADER_NAME, "")
105+
)
106+
if context is None:
107+
logger.debug(
108+
"Failed to create segment since it was not possible to get trace context from header"
109+
)
110+
return None
111+
segment = build_segment(context, key, metadata)
112+
segment_payload = build_segment_payload(segment)
113+
send(host_port_tuple, segment_payload)

setup.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
packages=["datadog_lambda"],
3030
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4",
3131
install_requires=[
32-
"aws-xray-sdk==2.8.0",
3332
"datadog==0.41.0",
3433
"ddtrace==0.48.0",
3534
"wrapt==1.11.2",

0 commit comments

Comments
 (0)