Skip to content

Commit ce6f6a0

Browse files
committed
instrumentation(spyne): Handle errors and support custom headers
Signed-off-by: Varsha GS <[email protected]>
1 parent e4ea2e9 commit ce6f6a0

File tree

1 file changed

+58
-5
lines changed

1 file changed

+58
-5
lines changed

src/instana/instrumentation/spyne.py

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,62 @@
1010
from instana.singletons import agent, tracer
1111
from instana.propagators.format import Format
1212
from instana.util.secrets import strip_secrets_from_query
13+
from instana.util.traceutils import extract_custom_headers
14+
15+
16+
@wrapt.patch_function_wrapper("spyne.server.wsgi", "WsgiApplication.handle_error")
17+
def handle_error_with_instana(wrapped, instance, args, kwargs):
18+
ctx = args[0]
19+
span = ctx.udc
20+
if span:
21+
return wrapped(*args, **kwargs)
22+
23+
headers = ctx.in_document
24+
span_context = tracer.extract(Format.HTTP_HEADERS, headers)
25+
26+
with tracer.start_as_current_span(
27+
"spyne", span_context=span_context
28+
) as span:
29+
extract_custom_headers(span, headers, format=True)
30+
31+
if "REQUEST_METHOD" in headers:
32+
span.set_attribute(SpanAttributes.HTTP_METHOD, headers["REQUEST_METHOD"])
33+
if "PATH_INFO" in headers:
34+
span.set_attribute(SpanAttributes.HTTP_URL, headers["PATH_INFO"])
35+
if "QUERY_STRING" in headers and len(headers["QUERY_STRING"]):
36+
scrubbed_params = strip_secrets_from_query(
37+
headers["QUERY_STRING"],
38+
agent.options.secrets_matcher,
39+
agent.options.secrets_list,
40+
)
41+
span.set_attribute("http.params", scrubbed_params)
42+
if "HTTP_HOST" in headers:
43+
span.set_attribute("http.host", headers["HTTP_HOST"])
44+
45+
response_headers = ctx.transport.resp_headers
46+
47+
extract_custom_headers(span, response_headers, format=False)
48+
tracer.inject(span.context, Format.HTTP_HEADERS, response_headers)
49+
50+
response = wrapped(*args, **kwargs)
51+
52+
resp_code = int(ctx.transport.resp_code.split()[0])
53+
54+
if 500 <= resp_code:
55+
span.mark_as_errored()
56+
57+
span.set_attribute(
58+
SpanAttributes.HTTP_STATUS_CODE, int(resp_code)
59+
)
60+
return response
61+
1362

14-
1563
@wrapt.patch_function_wrapper("spyne.server.wsgi", "WsgiApplication._WsgiApplication__finalize")
1664
def finalize_with_instana(wrapped, instance, args, kwargs):
1765
ctx = args[0]
1866
span = ctx.udc
19-
if span:
67+
68+
if span and ctx.transport.resp_code:
2069
resp_code = int(ctx.transport.resp_code.split()[0])
2170

2271
if 500 <= resp_code:
@@ -28,7 +77,7 @@ def finalize_with_instana(wrapped, instance, args, kwargs):
2877
if span.is_recording():
2978
span.end()
3079

31-
ctx.udc = None
80+
ctx.udc = None
3281
return wrapped(*args, **kwargs)
3382

3483

@@ -41,6 +90,8 @@ def process_request_with_instana(wrapped, instance, args, kwargs):
4190
with tracer.start_as_current_span(
4291
"spyne", span_context=span_context, end_on_exit=False,
4392
) as span:
93+
extract_custom_headers(span, headers, format=True)
94+
4495
if "REQUEST_METHOD" in headers:
4596
span.set_attribute(SpanAttributes.HTTP_METHOD, headers["REQUEST_METHOD"])
4697
if "PATH_INFO" in headers:
@@ -56,8 +107,10 @@ def process_request_with_instana(wrapped, instance, args, kwargs):
56107
span.set_attribute("http.host", headers["HTTP_HOST"])
57108

58109
response = wrapped(*args, **kwargs)
59-
ctx = args[0]
60-
tracer.inject(span.context, Format.HTTP_HEADERS, ctx.transport.resp_headers)
110+
response_headers = ctx.transport.resp_headers
111+
112+
extract_custom_headers(span, response_headers, format=False)
113+
tracer.inject(span.context, Format.HTTP_HEADERS, response_headers)
61114

62115
## Store the span in the user defined context object offered by Spyne
63116
ctx.udc = span

0 commit comments

Comments
 (0)