Skip to content

Remove aws-xray-sdk #171

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

Merged
merged 14 commits into from
Sep 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions LICENSE-3rdparty.csv
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
Component,Origin,License,Copyright
aws-xray-sdk-python,github.com/aws/aws-xray-sdk-python,Apache-2.0,
flake8,gitlab.com/pycqa/flake8,MIT,"Copyright (C) 2011-2013 Tarek Ziade <[email protected]>. Copyright (C) 2012-2016 Ian Cordasco <[email protected]>."
nose2,github.com/nose-devs/nose2,BSD-2-Clause,"Copyright (c) 2012, Jason Pellerin. All rights reserved."
requests,github.com/kennethreitz/requests,Apache-2.0,"Copyright 2018 Kenneth Reitz"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

requests was previously removed

wrapt,github.com/GrahamDumpleton/wrapt,BSD-2-Clause,"Copyright (c) 2013-2019, Graham Dumpleton"
7 changes: 7 additions & 0 deletions datadog_lambda/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,10 @@ class TraceContextSource(object):
XRAY = "xray"
EVENT = "event"
DDTRACE = "ddtrace"


# X-Ray deamon
class XrayDaemon(object):
XRAY_TRACE_ID_HEADER_NAME = "_X_AMZN_TRACE_ID"
XRAY_DAEMON_ADDRESS = "AWS_XRAY_DAEMON_ADDRESS"
FUNCTION_NAME_HEADER_NAME = "AWS_LAMBDA_FUNCTION_NAME"
42 changes: 20 additions & 22 deletions datadog_lambda/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
import os
import json

from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core.lambda_launcher import LambdaContext
from datadog_lambda.constants import (
SamplingPriority,
TraceHeader,
XraySubsegment,
TraceContextSource,
XrayDaemon,
)
from datadog_lambda.xray import (
send_segment,
parse_xray_header,
)
from ddtrace import tracer, patch
from ddtrace import __version__ as ddtrace_version
Expand Down Expand Up @@ -57,16 +59,24 @@ def _get_xray_trace_context():
if not is_lambda_context():
return None

xray_trace_entity = xray_recorder.get_trace_entity() # xray (sub)segment
xray_trace_entity = parse_xray_header(
os.environ.get(XrayDaemon.XRAY_TRACE_ID_HEADER_NAME, "")
)
if xray_trace_entity is None:
return None
trace_context = {
"trace-id": _convert_xray_trace_id(xray_trace_entity.trace_id),
"parent-id": _convert_xray_entity_id(xray_trace_entity.id),
"sampling-priority": _convert_xray_sampling(xray_trace_entity.sampled),
"trace-id": _convert_xray_trace_id(xray_trace_entity["trace_id"]),
"parent-id": _convert_xray_entity_id(xray_trace_entity["parent_id"]),
"sampling-priority": _convert_xray_sampling(xray_trace_entity["sampled"]),
}
logger.debug(
"Converted trace context %s from X-Ray segment %s",
trace_context,
(xray_trace_entity.trace_id, xray_trace_entity.id, xray_trace_entity.sampled),
(
xray_trace_entity["trace_id"],
xray_trace_entity["parent_id"],
xray_trace_entity["sampled"],
),
)
return trace_context

Expand Down Expand Up @@ -106,19 +116,7 @@ def create_dd_dummy_metadata_subsegment(
tags into its metadata field, so the X-Ray trace can be converted to a Datadog
trace in the Datadog backend with the correct context.
"""
try:
xray_recorder.begin_subsegment(XraySubsegment.NAME)
subsegment = xray_recorder.current_subsegment()
subsegment.put_metadata(
subsegment_metadata_key, subsegment_metadata_value, XraySubsegment.NAMESPACE
)
xray_recorder.end_subsegment()
except Exception as e:
logger.debug(
"failed to create dd dummy metadata subsegment with error %s",
e,
exc_info=True,
)
send_segment(subsegment_metadata_key, subsegment_metadata_value)


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


def set_dd_trace_py_root(trace_context_source, merge_xray_traces):
Expand Down
113 changes: 113 additions & 0 deletions datadog_lambda/xray.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import os
import logging
import json
import binascii
import time
import socket

from datadog_lambda.constants import XrayDaemon, XraySubsegment, TraceContextSource

logger = logging.getLogger(__name__)


def get_xray_host_port(adress):
if adress == "":
logger.debug("X-Ray daemon env var not set, not sending sub-segment")
return None
parts = adress.split(":")
if len(parts) <= 1:
logger.debug("X-Ray daemon env var not set, not sending sub-segment")
return None
port = int(parts[1])
host = parts[0]
return (host, port)


def send(host_port_tuple, payload):
sock = None
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setblocking(0)
sock.connect(host_port_tuple)
sock.send(payload.encode("utf-8"))
except Exception as e_send:
logger.error("Error occurred submitting to xray daemon: %s", str(e_send))
try:
sock.close()
except Exception as e_close:
logger.error("Error while closing the socket: %s", str(e_close))


def build_segment_payload(payload):
if payload is None:
return None
return '{"format": "json", "version": 1}' + "\n" + payload


def parse_xray_header(raw_trace_id):
# Example: Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=1
logger.debug("Reading trace context from env var %s", raw_trace_id)
if len(raw_trace_id) == 0:
return None
parts = raw_trace_id.split(";")
if len(parts) != 3:
return None
root = parts[0].replace("Root=", "")
parent = parts[1].replace("Parent=", "")
sampled = parts[2].replace("Sampled=", "")
if (
len(root) == len(parts[0])
or len(parent) == len(parts[1])
or len(sampled) == len(parts[2])
):
return None
return {
"parent_id": parent,
"trace_id": root,
"sampled": sampled,
"source": TraceContextSource.XRAY,
}


def generate_random_id():
return binascii.b2a_hex(os.urandom(8)).decode("utf-8")


def build_segment(context, key, metadata):

segment = json.dumps(
{
"id": generate_random_id(),
"trace_id": context["trace_id"],
"parent_id": context["parent_id"],
"name": XraySubsegment.NAME,
"start_time": time.time(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Just want to verify that time.time() returns in the correct unit: https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html . I believe there might be a bug in the node version where this timestamp is off by an order of magnitude.

Copy link
Contributor Author

@maxday maxday Sep 10, 2021

Choose a reason for hiding this comment

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

"end_time": time.time(),
"type": "subsegment",
"metadata": {
XraySubsegment.NAMESPACE: {
key: metadata,
}
},
}
)
return segment


def send_segment(key, metadata):
host_port_tuple = get_xray_host_port(
os.environ.get(XrayDaemon.XRAY_DAEMON_ADDRESS, "")
)
if host_port_tuple is None:
return None
context = parse_xray_header(
os.environ.get(XrayDaemon.XRAY_TRACE_ID_HEADER_NAME, "")
)
if context is None:
logger.debug(
"Failed to create segment since it was not possible to get trace context from header"
)
return None
segment = build_segment(context, key, metadata)
segment_payload = build_segment_payload(segment)
send(host_port_tuple, segment_payload)
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
packages=["datadog_lambda"],
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4",
install_requires=[
"aws-xray-sdk==2.8.0",
"datadog==0.41.0",
"ddtrace==0.48.0",
"wrapt==1.11.2",
Expand Down
Loading