Skip to content
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
30 changes: 22 additions & 8 deletions ddtrace/internal/_encoding.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ cdef class MsgpackEncoderBase(BufferedEncoder):
cdef int ret
cdef Py_ssize_t L
cdef void * dd_origin = NULL
cdef unsigned long long trace_id_64bits = 0

L = len(trace)
if L > ITEM_LIMIT:
Expand All @@ -503,12 +504,26 @@ cdef class MsgpackEncoderBase(BufferedEncoder):
if ret != 0:
raise RuntimeError("Couldn't pack trace")

if L > 0 and trace[0].context is not None and trace[0].context.dd_origin is not None:
# TODO: Can we skip packing an empty array?
if L == 0:
return 0

if trace[0].context is not None and trace[0].context.dd_origin is not None:
dd_origin = self.get_dd_origin_ref(trace[0].context.dd_origin)

# PERF: _trace_id_64bits is a computed property, cache/convert once for all spans
try:
trace_id_64bits = trace[0]._trace_id_64bits

# We can get TypeError if the trace_id is not an int
# e.g. "unsupported operand type(s) for &: 'int' and 'str'"
except Exception as e:
raise RuntimeError(
"failed to pack span: {!r}. Exception: {}".format(trace[0], e)
)
for span in trace:
try:
ret = self.pack_span(span, dd_origin)
ret = self.pack_span(span, trace_id_64bits, dd_origin)
except Exception as e:
raise RuntimeError("failed to pack span: {!r}. Exception: {}".format(span, e))

Expand Down Expand Up @@ -558,7 +573,7 @@ cdef class MsgpackEncoderBase(BufferedEncoder):
cpdef flush(self):
raise NotImplementedError()

cdef int pack_span(self, object span, void *dd_origin) except? -1:
cdef int pack_span(self, object span, unsigned long long trace_id_64bits, void *dd_origin) except? -1:
raise NotImplementedError()


Expand Down Expand Up @@ -740,7 +755,7 @@ cdef class MsgpackEncoderV04(MsgpackEncoderBase):

raise TypeError("Unhandled metrics type: %r" % type(metrics))

cdef int pack_span(self, object span, void *dd_origin) except? -1:
cdef int pack_span(self, object span, unsigned long long trace_id_64bits, void *dd_origin) except? -1:
cdef int ret
cdef Py_ssize_t L
cdef int has_span_type
Expand Down Expand Up @@ -771,7 +786,7 @@ cdef class MsgpackEncoderV04(MsgpackEncoderBase):
ret = pack_bytes(&self.pk, <char *> b"trace_id", 8)
if ret != 0:
return ret
ret = pack_number(&self.pk, span._trace_id_64bits)
ret = msgpack_pack_unsigned_long_long(&self.pk, trace_id_64bits)
if ret != 0:
return ret

Expand Down Expand Up @@ -1016,7 +1031,7 @@ cdef class MsgpackEncoderV05(MsgpackEncoderBase):
cdef void * get_dd_origin_ref(self, str dd_origin):
return <void *> PyLong_AsLong(self._st._index(dd_origin))

cdef int pack_span(self, object span, void *dd_origin) except? -1:
cdef int pack_span(self, object span, unsigned long long trace_id_64bits, void *dd_origin) except? -1:
cdef int ret

ret = msgpack_pack_array(&self.pk, 12)
Expand All @@ -1033,8 +1048,7 @@ cdef class MsgpackEncoderV05(MsgpackEncoderBase):
if ret != 0:
return ret

_ = span._trace_id_64bits
ret = msgpack_pack_uint64(&self.pk, _ if _ is not None else 0)
ret = msgpack_pack_unsigned_long_long(&self.pk, trace_id_64bits)
if ret != 0:
return ret

Expand Down
2 changes: 2 additions & 0 deletions tests/tracer/test_encoders.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ def gen_trace(nspans=1000, ntags=50, key_size=15, value_size=20, nmetrics=10):
resource="/fsdlajfdlaj/afdasd%s" % i,
service="myservice",
parent_id=parent_id,
# All spans in a trace must share a trace_id
trace_id=root.trace_id if root else None,
) as span:
span._parent = root
span.set_tags({rands(key_size): rands(value_size) for _ in range(0, ntags)})
Expand Down
Loading