Skip to content

Commit edc0a92

Browse files
committed
More debug.
1 parent a33611d commit edc0a92

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ ENV PATH=/root/.cargo/bin:$PATH
1616
COPY . .
1717
RUN pip install --no-cache-dir . -t ./python/lib/$runtime/site-packages
1818

19+
COPY debug_encoding.py ./python/lib/$runtime/site-packages/ddtrace/internal/encoding.py
20+
1921
# Remove botocore (40MB) to reduce package size. aws-xray-sdk
2022
# installs it, while it's already provided by the Lambda Runtime.
2123
RUN rm -rf ./python/lib/$runtime/site-packages/botocore*

datadog_lambda/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def _getter(self):
2929
default,
3030
)
3131
val = default
32+
print('key,val: ', key,val)
3233
setattr(self, prop_key, val)
3334
return getattr(self, prop_key)
3435

debug_encoding.py

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import json
2+
from typing import TYPE_CHECKING
3+
from typing import Any # noqa:F401
4+
from typing import Dict # noqa:F401
5+
from typing import List # noqa:F401
6+
from typing import Optional # noqa:F401
7+
from typing import Tuple # noqa:F401
8+
9+
from ..settings._agent import config as agent_config # noqa:F401
10+
from ._encoding import ListStringTable
11+
from ._encoding import MsgpackEncoderV04
12+
from ._encoding import MsgpackEncoderV05
13+
from .compat import ensure_text
14+
from .logger import get_logger
15+
16+
17+
__all__ = ["MsgpackEncoderV04", "MsgpackEncoderV05", "ListStringTable", "MSGPACK_ENCODERS"]
18+
19+
20+
if TYPE_CHECKING: # pragma: no cover
21+
from ddtrace._trace.span import Span # noqa:F401
22+
23+
log = get_logger(__name__)
24+
25+
26+
class _EncoderBase(object):
27+
"""
28+
Encoder interface that provides the logic to encode traces and service.
29+
"""
30+
31+
def encode_traces(self, traces):
32+
# type: (List[List[Span]]) -> str
33+
"""
34+
Encodes a list of traces, expecting a list of items where each items
35+
is a list of spans. Before dumping the string in a serialized format all
36+
traces are normalized according to the encoding format. The trace
37+
nesting is not changed.
38+
39+
:param traces: A list of traces that should be serialized
40+
"""
41+
raise NotImplementedError()
42+
43+
def encode(self, obj):
44+
# type: (List[List[Any]]) -> Tuple[str, int]
45+
"""
46+
Defines the underlying format used during traces or services encoding.
47+
This method must be implemented and should only be used by the internal
48+
functions.
49+
"""
50+
raise NotImplementedError()
51+
52+
@staticmethod
53+
def _span_to_dict(span):
54+
# type: (Span) -> Dict[str, Any]
55+
d = {
56+
"trace_id": span._trace_id_64bits,
57+
"parent_id": span.parent_id,
58+
"span_id": span.span_id,
59+
"service": span.service,
60+
"resource": span.resource,
61+
"name": span.name,
62+
"error": span.error,
63+
} # type: Dict[str, Any]
64+
65+
# a common mistake is to set the error field to a boolean instead of an
66+
# int. let's special case that here, because it's sure to happen in
67+
# customer code.
68+
err = d.get("error")
69+
if err and type(err) == bool:
70+
d["error"] = 1
71+
72+
if span.start_ns:
73+
d["start"] = span.start_ns
74+
75+
if span.duration_ns:
76+
d["duration"] = span.duration_ns
77+
78+
if span._meta:
79+
d["meta"] = span._meta
80+
81+
if span._metrics:
82+
d["metrics"] = span._metrics
83+
84+
if span.span_type:
85+
d["type"] = span.span_type
86+
87+
if span._links:
88+
d["span_links"] = [link.to_dict() for link in span._links]
89+
90+
if span._events and agent_config.trace_native_span_events:
91+
d["span_events"] = [dict(event) for event in span._events]
92+
93+
return d
94+
95+
96+
class JSONEncoder(_EncoderBase):
97+
content_type = "application/json"
98+
99+
def encode_traces(self, traces):
100+
normalized_traces = [
101+
[JSONEncoder._normalize_span(JSONEncoder._span_to_dict(span)) for span in trace] for trace in traces
102+
]
103+
return self.encode(normalized_traces)[0]
104+
105+
@staticmethod
106+
def _normalize_span(span):
107+
# Ensure all string attributes are actually strings and not bytes
108+
# DEV: We are deferring meta/metrics to reduce any performance issues.
109+
# Meta/metrics may still contain `bytes` and have encoding issues.
110+
print('----------------------------------------')
111+
print('span["resource"],type(span["resource"]): ',
112+
span["resource"],type(span["resource"]))
113+
print('span["name"],type(span["name"]): ',
114+
span["name"], type(span["name"]))
115+
print('span["service"],type(span["service"]): ',
116+
span["service"], type(span["service"]))
117+
import traceback; traceback.print_stack()
118+
import time; time.sleep(0.5)
119+
print('----------------------------------------')
120+
span["resource"] = JSONEncoder._normalize_str(span["resource"])
121+
span["name"] = JSONEncoder._normalize_str(span["name"])
122+
span["service"] = JSONEncoder._normalize_str(span["service"])
123+
return span
124+
125+
@staticmethod
126+
def _normalize_str(obj):
127+
if obj is None:
128+
return obj
129+
130+
return ensure_text(obj, errors="backslashreplace")
131+
132+
def encode(self, obj):
133+
return json.JSONEncoder().encode(obj), len(obj)
134+
135+
136+
class JSONEncoderV2(JSONEncoder):
137+
"""
138+
JSONEncoderV2 encodes traces to the new intake API format.
139+
"""
140+
141+
content_type = "application/json"
142+
143+
def encode_traces(self, traces):
144+
# type: (List[List[Span]]) -> str
145+
normalized_traces = [[JSONEncoderV2._convert_span(span) for span in trace] for trace in traces]
146+
return self.encode({"traces": normalized_traces})[0]
147+
148+
@staticmethod
149+
def _convert_span(span):
150+
# type: (Span) -> Dict[str, Any]
151+
sp = JSONEncoderV2._span_to_dict(span)
152+
sp = JSONEncoderV2._normalize_span(sp)
153+
sp["trace_id"] = JSONEncoderV2._encode_id_to_hex(sp.get("trace_id"))
154+
sp["parent_id"] = JSONEncoderV2._encode_id_to_hex(sp.get("parent_id"))
155+
sp["span_id"] = JSONEncoderV2._encode_id_to_hex(sp.get("span_id"))
156+
return sp
157+
158+
@staticmethod
159+
def _encode_id_to_hex(dd_id):
160+
# type: (Optional[int]) -> str
161+
if not dd_id:
162+
return "0000000000000000"
163+
return "%0.16X" % int(dd_id)
164+
165+
def encode(self, obj):
166+
res, _ = super().encode(obj)
167+
return res, len(obj.get("traces", []))
168+
169+
170+
MSGPACK_ENCODERS = {
171+
"v0.4": MsgpackEncoderV04,
172+
"v0.5": MsgpackEncoderV05,
173+
}

0 commit comments

Comments
 (0)