Skip to content

Commit 7bf8247

Browse files
GSVarshapvital
authored andcommitted
fix: aws/01_lambda failures
- fix: handle `str` internal ids with all digit chars - rename the methods to handle internal ids Signed-off-by: Varsha GS <[email protected]>
1 parent 79cdc7a commit 7bf8247

File tree

8 files changed

+97
-67
lines changed

8 files changed

+97
-67
lines changed

src/instana/collector/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from opentelemetry.trace.span import format_span_id
66
from opentelemetry.trace import SpanKind
77

8-
from instana.util.ids import hex_id, header_to_32
8+
from instana.util.ids import hex_id, internal_id
99

1010
if TYPE_CHECKING:
1111
from instana.span.base_span import BaseSpan
@@ -24,7 +24,7 @@ def format_span(
2424
span.t = format_span_id(span.t)
2525
span.s = format_span_id(span.s)
2626
span.p = format_span_id(span.p) if span.p else None
27-
span.lt = hex_id(header_to_32(span.lt)) if hasattr(span, "lt") else None
27+
span.lt = hex_id(internal_id(span.lt)) if hasattr(span, "lt") else None
2828
if isinstance(span.k, SpanKind):
2929
span.k = span.k.value if not span.k is SpanKind.INTERNAL else 3
3030
spans.append(span)

src/instana/instrumentation/aws/lambda_inst.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import wrapt
1313
from opentelemetry.semconv.trace import SpanAttributes
14+
from opentelemetry.trace.span import format_span_id
1415

1516
from instana import get_aws_lambda_handler
1617
from instana.instrumentation.aws.triggers import enrich_lambda_span, get_context
@@ -44,7 +45,7 @@ def lambda_handler_with_instana(
4445
result = wrapped(*args, **kwargs)
4546

4647
if isinstance(result, dict):
47-
server_timing_value = define_server_timing(span.context.trace_id)
48+
server_timing_value = define_server_timing(format_span_id(span.context.trace_id))
4849
if "headers" in result:
4950
result["headers"]["Server-Timing"] = server_timing_value
5051
elif "multiValueHeaders" in result:

src/instana/propagators/base_propagator.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from instana.log import logger
1010
from instana.span_context import SpanContext
11-
from instana.util.ids import header_to_id, header_to_long_id, hex_id, header_to_32, header_to_16, hex_id_16
11+
from instana.util.ids import header_to_id, header_to_long_id, hex_id, internal_id, internal_id_limited, hex_id_limited
1212
from instana.w3c_trace_context.traceparent import Traceparent
1313
from instana.w3c_trace_context.tracestate import Tracestate
1414

@@ -149,7 +149,7 @@ def _get_participating_trace_context(self, span_context: SpanContext):
149149
if span_context.suppression:
150150
return traceparent, tracestate
151151

152-
tracestate = self._ts.update_tracestate(tracestate, hex_id_16(span_context.trace_id), hex_id(span_context.span_id))
152+
tracestate = self._ts.update_tracestate(tracestate, hex_id_limited(span_context.trace_id), hex_id(span_context.span_id))
153153
return traceparent, tracestate
154154

155155
def __determine_span_context(
@@ -219,7 +219,7 @@ def __determine_span_context(
219219
instana_ancestor = self._ts.get_instana_ancestor(tracestate)
220220

221221
if disable_traceparent == "":
222-
ctx_trace_id = hex_id_16(tp_trace_id)
222+
ctx_trace_id = hex_id_limited(tp_trace_id)
223223
ctx_span_id = tp_parent_id
224224
ctx_synthetic = synthetic
225225
ctx_trace_parent = True
@@ -241,11 +241,21 @@ def __determine_span_context(
241241
ctx_traceparent = traceparent
242242
ctx_tracestate = tracestate
243243

244+
if ctx_trace_id:
245+
if isinstance(ctx_trace_id, int):
246+
# check if ctx_trace_id is a valid internal trace id
247+
if (ctx_trace_id <= 2**64 - 1):
248+
trace_id = ctx_trace_id
249+
else:
250+
trace_id = internal_id(hex_id_limited(ctx_trace_id))
251+
else:
252+
trace_id = internal_id(ctx_trace_id)
253+
else:
254+
trace_id = INVALID_TRACE_ID
255+
244256
return SpanContext(
245-
# trace_id=int(ctx_trace_id) if ctx_trace_id else INVALID_TRACE_ID,
246-
# span_id=int(ctx_span_id) if ctx_span_id else INVALID_SPAN_ID,
247-
trace_id=header_to_32(hex_id_16(header_to_32(ctx_trace_id))) if ctx_trace_id else INVALID_TRACE_ID,
248-
span_id=header_to_16(ctx_span_id) if ctx_span_id else INVALID_SPAN_ID,
257+
trace_id=trace_id,
258+
span_id=internal_id_limited(ctx_span_id) if ctx_span_id else INVALID_SPAN_ID,
249259
is_remote=False,
250260
level=ctx_level,
251261
synthetic=ctx_synthetic,

src/instana/propagators/http_propagator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from instana.log import logger
66
from instana.propagators.base_propagator import BasePropagator
7-
from instana.util.ids import define_server_timing, hex_id_16
7+
from instana.util.ids import define_server_timing, hex_id_limited
88

99
from opentelemetry.trace.span import format_span_id
1010

@@ -55,7 +55,7 @@ def inject_key_value(carrier, key, value):
5555
if span_context.suppression:
5656
return
5757

58-
inject_key_value(carrier, self.HEADER_KEY_T, hex_id_16(trace_id))
58+
inject_key_value(carrier, self.HEADER_KEY_T, hex_id_limited(trace_id))
5959
inject_key_value(carrier, self.HEADER_KEY_S, format_span_id(span_id))
6060
inject_key_value(
6161
carrier, self.HEADER_KEY_SERVER_TIMING, define_server_timing(trace_id)

src/instana/span/base_span.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from instana.log import logger
77
from instana.util import DictionaryOfStan
8-
from instana.util.ids import hex_id_16, header_to_32
98
from instana.span.kind import ENTRY_SPANS
109

1110
if TYPE_CHECKING:
@@ -23,7 +22,7 @@ def __repr__(self) -> str:
2322

2423
def __init__(self, span: Type["Span"], source, **kwargs) -> None:
2524
# pylint: disable=invalid-name
26-
self.t = header_to_32(hex_id_16(span.context.trace_id))
25+
self.t = span.context.trace_id
2726
self.p = span.parent_id
2827
self.s = span.context.span_id
2928
self.ts = round(span.start_time / 10**6)

src/instana/util/ids.py

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -92,61 +92,82 @@ def header_to_id(header: Union[bytes, str]) -> int:
9292
def hex_id(id: Union[int, str]) -> str:
9393
"""
9494
Returns the hexadecimal representation of the given ID.
95+
Left pad with zeros when the length is not equal to 16
9596
"""
9697

9798
hex_id = hex(int(id))[2:]
98-
if len(hex_id) < 16:
99+
length = len(hex_id)
100+
# Left pad ID with zeros
101+
if length < 16:
99102
hex_id = hex_id.zfill(16)
100-
elif len(hex_id) > 16 and len(hex_id) < 32:
103+
elif length > 16 and length < 32:
101104
hex_id = hex_id.zfill(32)
102105
return hex_id
103106

104-
def hex_id_16(id: Union[int, str]) -> str:
107+
def hex_id_limited(id: Union[int, str]) -> str:
105108
"""
106109
Returns the hexadecimal representation of the given ID.
110+
Limit longer IDs to 16 characters
107111
"""
108-
109-
hex_id = hex(int(id))[2:]
110-
length = len(hex_id)
111-
if length < 16:
112-
hex_id = hex_id.zfill(16)
113-
elif length > 16:
114-
# Phase 0: Discard everything but the last 16byte
115-
hex_id = hex_id[-16:]
116-
return hex_id
117-
112+
try:
113+
hex_id = hex(int(id))[2:]
114+
length = len(hex_id)
115+
if length < 16:
116+
# Left pad ID with zeros
117+
hex_id = hex_id.zfill(16)
118+
elif length > 16:
119+
# Phase 0: Discard everything but the last 16byte
120+
hex_id = hex_id[-16:]
121+
return hex_id
122+
except ValueError: # ValueError: invalid literal for int() with base 10:
123+
return id
118124

119125
def define_server_timing(trace_id: Union[int, str]) -> str:
120126
# Note: The key `intid` is short for Instana Trace ID.
121-
return f"intid;desc={hex_id_16(trace_id)}"
127+
return f"intid;desc={hex_id_limited(trace_id)}"
122128

123129

124-
def header_to_32(header) -> int:
125-
if isinstance(header, int):
126-
return header
130+
def internal_id(id: Union[int, str]) -> int:
131+
"""
132+
Returns a valid id to be used internally. Handles both str and int types.
133+
"""
134+
if isinstance(id, int):
135+
return id
136+
137+
if isinstance(id, str) and id.isdigit():
138+
return int(id)
127139

128140
try:
129-
if len(header) < 16:
141+
if len(id) < 16:
130142
# Left pad ID with zeros
131-
header = header.zfill(16)
143+
id = id.zfill(16)
132144

133-
return int(header, 16)
145+
# hex string -> int
146+
return int(id, 16)
134147
except ValueError:
135148
return INVALID_TRACE_ID
136149

137-
def header_to_16(header) -> int:
138-
if isinstance(header, int):
139-
return header
150+
def internal_id_limited(id: Union[int, str]) -> int:
151+
"""
152+
Returns a valid id to be used internally. Handles both str and int types.
153+
Note: Limits the hex string to 16 chars before conversion.
154+
"""
155+
if isinstance(id, int):
156+
return id
157+
158+
if isinstance(id, str) and id.isdigit():
159+
return int(id)
140160

141161
try:
142-
length = len(header)
162+
length = len(id)
143163
if length < 16:
144164
# Left pad ID with zeros
145-
header = header.zfill(16)
165+
id = id.zfill(16)
146166
elif length > 16:
147167
# Phase 0: Discard everything but the last 16byte
148-
header = header[-16:]
168+
id = id[-16:]
149169

150-
return int(header, 16)
170+
# hex string -> int
171+
return int(id, 16)
151172
except ValueError:
152-
return INVALID_SPAN_ID
173+
return INVALID_SPAN_ID

tests/propagators/test_http_propagator.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
from instana.propagators.http_propagator import HTTPPropagator
1616
from instana.span_context import SpanContext
17-
from instana.util.ids import header_to_id
17+
from instana.util.ids import header_to_long_id, internal_id
1818

1919

2020
class TestHTTPPropagator:
@@ -62,7 +62,6 @@ def test_extract_carrier_dict(
6262
span_id: int,
6363
_instana_long_tracer_id: str,
6464
_instana_span_id: str,
65-
_long_tracer_id: int,
6665
_trace_id: int,
6766
_span_id: int,
6867
_traceparent: str,
@@ -82,7 +81,7 @@ def test_extract_carrier_dict(
8281
assert ctx.correlation_type == "web"
8382
assert not ctx.instana_ancestor
8483
assert ctx.level == 1
85-
assert ctx.long_trace_id == header_to_id(_instana_long_tracer_id)
84+
assert ctx.long_trace_id == header_to_long_id(_instana_long_tracer_id)
8685
assert ctx.span_id == _span_id
8786
assert not ctx.synthetic
8887
assert ctx.trace_id == _trace_id
@@ -92,8 +91,8 @@ def test_extract_carrier_dict(
9291

9392
def test_extract_carrier_list(
9493
self,
95-
trace_id: int,
96-
span_id: int,
94+
_trace_id: int,
95+
_span_id: int,
9796
_instana_long_tracer_id: str,
9897
_instana_span_id: str,
9998
_traceparent: str,
@@ -106,8 +105,8 @@ def test_extract_carrier_list(
106105
("connection", "keep-alive"),
107106
("traceparent", _traceparent),
108107
("tracestate", _tracestate),
109-
("X-INSTANA-T", f"{trace_id}"),
110-
("X-INSTANA-S", f"{span_id}"),
108+
("X-INSTANA-T", f"{_trace_id}"),
109+
("X-INSTANA-S", f"{_span_id}"),
111110
("X-INSTANA-L", "1"),
112111
]
113112

@@ -118,9 +117,9 @@ def test_extract_carrier_list(
118117
assert not ctx.instana_ancestor
119118
assert ctx.level == 1
120119
assert not ctx.long_trace_id
121-
assert ctx.span_id == span_id
120+
assert ctx.span_id == _span_id
122121
assert not ctx.synthetic
123-
assert ctx.trace_id == trace_id
122+
assert ctx.trace_id == internal_id(_trace_id)
124123
assert not ctx.trace_parent
125124
assert ctx.traceparent == f"00-{_instana_long_tracer_id}-{_instana_span_id}-01"
126125
assert ctx.tracestate == _tracestate
@@ -199,7 +198,7 @@ def test_extract_carrier_dict_corrupted_level_header(
199198
assert ctx.correlation_type == "web"
200199
assert not ctx.instana_ancestor
201200
assert ctx.level == 1
202-
assert ctx.long_trace_id == header_to_id(_instana_long_tracer_id)
201+
assert ctx.long_trace_id == header_to_long_id(_instana_long_tracer_id)
203202
assert ctx.span_id == _span_id
204203
assert not ctx.synthetic
205204
assert ctx.trace_id == _trace_id
@@ -209,16 +208,16 @@ def test_extract_carrier_dict_corrupted_level_header(
209208

210209
def test_extract_carrier_dict_level_header_not_splitable(
211210
self,
212-
trace_id: int,
213-
span_id: int,
211+
_trace_id: int,
212+
_span_id: int,
214213
_traceparent: str,
215214
_tracestate: str,
216215
) -> None:
217216
carrier = {
218217
"traceparent": _traceparent,
219218
"tracestate": _tracestate,
220-
"X-INSTANA-T": f"{trace_id}",
221-
"X-INSTANA-S": f"{span_id}",
219+
"X-INSTANA-T": f"{_trace_id}",
220+
"X-INSTANA-S": f"{_span_id}",
222221
"X-INSTANA-L": ["1"],
223222
}
224223

@@ -229,9 +228,9 @@ def test_extract_carrier_dict_level_header_not_splitable(
229228
assert not ctx.instana_ancestor
230229
assert ctx.level == 1
231230
assert not ctx.long_trace_id
232-
assert ctx.span_id == span_id
231+
assert ctx.span_id == _span_id
233232
assert not ctx.synthetic
234-
assert ctx.trace_id == trace_id
233+
assert ctx.trace_id == internal_id(_trace_id)
235234
assert not ctx.trace_parent
236235
assert ctx.traceparent == _traceparent
237236
assert ctx.tracestate == _tracestate
@@ -304,7 +303,7 @@ def test_w3c_off_x_instana_l_0(
304303
# Assert that the traceparent is propagated when it is enabled
305304
if "traceparent" in carrier_header.keys():
306305
assert ctx.traceparent
307-
tp_trace_id = header_to_id(carrier_header["traceparent"].split("-")[1])
306+
tp_trace_id = header_to_long_id(carrier_header["traceparent"].split("-")[1])
308307
else:
309308
assert not ctx.traceparent
310309
tp_trace_id = ctx.trace_id

tests_aws/01_lambda/test_lambda.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,9 @@ def test_custom_service_name(self, trace_id: int, span_id: int) -> None:
221221

222222
span = payload["spans"].pop()
223223
assert span.n == "aws.lambda.entry"
224-
assert span.t == hex(trace_id)[2:]
224+
assert span.t == hex_id(trace_id)
225225
assert span.s
226-
assert span.p == hex(span_id)[2:]
226+
assert span.p == hex_id(span_id)
227227
assert span.ts
228228

229229
server_timing_value = f"intid;desc={hex_id(trace_id)}"
@@ -293,9 +293,9 @@ def test_api_gateway_trigger_tracing(self, trace_id: int, span_id: int) -> None:
293293

294294
span = payload["spans"].pop()
295295
assert span.n == "aws.lambda.entry"
296-
assert span.t == hex(trace_id)[2:]
296+
assert span.t == hex_id(trace_id)
297297
assert span.s
298-
assert span.p == hex(span_id)[2:]
298+
assert span.p == hex_id(span_id)
299299
assert span.ts
300300

301301
server_timing_value = f"intid;desc={hex_id(trace_id)}"
@@ -405,9 +405,9 @@ def test_application_lb_trigger_tracing(self, trace_id: int, span_id: int) -> No
405405

406406
span = payload["spans"].pop()
407407
assert span.n == "aws.lambda.entry"
408-
assert span.t == hex(trace_id)[2:]
408+
assert span.t == hex_id(trace_id)
409409
assert span.s
410-
assert span.p == hex(span_id)[2:]
410+
assert span.p == hex_id(span_id)
411411
assert span.ts
412412

413413
server_timing_value = f"intid;desc={hex_id(trace_id)}"
@@ -803,9 +803,9 @@ def __validate_result_and_payload_for_gateway_v2_trace(self, result: Dict[str, A
803803

804804
span = payload["spans"].pop()
805805
assert span.n == "aws.lambda.entry"
806-
assert span.t == hex(int("0000000000001234"))[2:].zfill(16)
806+
assert span.t == hex_id("0000000000001234")
807807
assert span.s
808-
assert span.p == hex(int("0000000000004567"))[2:].zfill(16)
808+
assert span.p == hex_id("0000000000004567")
809809
assert span.ts
810810

811811
server_timing_value = f"intid;desc={hex_id(int('0000000000001234'))}"

0 commit comments

Comments
 (0)