1- # (c) Copyright IBM Corp. 2021
1+ # (c) Copyright IBM Corp. 2025
22# (c) Copyright Instana Inc. 2019
33
44
55try :
66 import tornado
7+ from typing import TYPE_CHECKING , Callable , Tuple , Dict , Any , Coroutine , Optional
78
89 import wrapt
910
11+ if TYPE_CHECKING :
12+ from tornado .web import RequestHandler
13+
1014 from opentelemetry .semconv .trace import SpanAttributes
1115
1216 from instana .log import logger
13- from instana .singletons import agent , tracer
17+ from instana .singletons import agent , get_tracer
1418 from instana .util .secrets import strip_secrets_from_query
1519 from instana .util .traceutils import extract_custom_headers
1620 from instana .propagators .format import Format
1721
18-
19-
20- @wrapt .patch_function_wrapper ('tornado.web' , 'RequestHandler._execute' )
21- def execute_with_instana (wrapped , instance , argv , kwargs ):
22+ @wrapt .patch_function_wrapper ("tornado.web" , "RequestHandler._execute" )
23+ def execute_with_instana (
24+ wrapped : Callable [..., object ],
25+ instance : "RequestHandler" ,
26+ argv : Tuple [object , ...],
27+ kwargs : Dict [str , Any ],
28+ ) -> Coroutine :
2229 try :
2330 span_context = None
24- if hasattr (instance .request .headers , '__dict__' ) and '_dict' in instance .request .headers .__dict__ :
25- span_context = tracer .extract (Format .HTTP_HEADERS ,
26- instance .request .headers .__dict__ ['_dict' ])
31+ tracer = get_tracer ()
32+ if (
33+ hasattr (instance .request .headers , "__dict__" )
34+ and "_dict" in instance .request .headers .__dict__
35+ ):
36+ span_context = tracer .extract (
37+ Format .HTTP_HEADERS , instance .request .headers .__dict__ ["_dict" ]
38+ )
2739
2840 span = tracer .start_span ("tornado-server" , span_context = span_context )
2941
3042 # Query param scrubbing
3143 if instance .request .query is not None and len (instance .request .query ) > 0 :
32- cleaned_qp = strip_secrets_from_query (instance .request .query , agent .options .secrets_matcher ,
33- agent .options .secrets_list )
44+ cleaned_qp = strip_secrets_from_query (
45+ instance .request .query ,
46+ agent .options .secrets_matcher ,
47+ agent .options .secrets_list ,
48+ )
3449 span .set_attribute ("http.params" , cleaned_qp )
35-
50+
3651 url = f"{ instance .request .protocol } ://{ instance .request .host } { instance .request .path } "
3752 span .set_attribute (SpanAttributes .HTTP_URL , url )
3853 span .set_attribute (SpanAttributes .HTTP_METHOD , instance .request .method )
@@ -52,20 +67,29 @@ def execute_with_instana(wrapped, instance, argv, kwargs):
5267 except Exception :
5368 logger .debug ("tornado execute" , exc_info = True )
5469
55-
56- @wrapt .patch_function_wrapper ('tornado.web' , 'RequestHandler.set_default_headers' )
57- def set_default_headers_with_instana (wrapped , instance , argv , kwargs ):
58- if not hasattr (instance .request , '_instana' ):
70+ @wrapt .patch_function_wrapper ("tornado.web" , "RequestHandler.set_default_headers" )
71+ def set_default_headers_with_instana (
72+ wrapped : Callable [..., object ],
73+ instance : "RequestHandler" ,
74+ argv : Tuple [object , ...],
75+ kwargs : Dict [str , Any ],
76+ ) -> Optional [Coroutine ]:
77+ if not hasattr (instance .request , "_instana" ):
5978 return wrapped (* argv , ** kwargs )
6079
6180 span = instance .request ._instana
81+ tracer = get_tracer ()
6282 tracer .inject (span .context , Format .HTTP_HEADERS , instance ._headers )
6383
64-
65- @wrapt .patch_function_wrapper ('tornado.web' , 'RequestHandler.on_finish' )
66- def on_finish_with_instana (wrapped , instance , argv , kwargs ):
84+ @wrapt .patch_function_wrapper ("tornado.web" , "RequestHandler.on_finish" )
85+ def on_finish_with_instana (
86+ wrapped : Callable [..., object ],
87+ instance : "RequestHandler" ,
88+ argv : Tuple [object , ...],
89+ kwargs : Dict [str , Any ],
90+ ) -> Coroutine :
6791 try :
68- if not hasattr (instance .request , ' _instana' ):
92+ if not hasattr (instance .request , " _instana" ):
6993 return wrapped (* argv , ** kwargs )
7094
7195 span = instance .request ._instana
@@ -86,11 +110,15 @@ def on_finish_with_instana(wrapped, instance, argv, kwargs):
86110 except Exception :
87111 logger .debug ("tornado on_finish" , exc_info = True )
88112
89-
90- @wrapt .patch_function_wrapper ('tornado.web' , 'RequestHandler.log_exception' )
91- def log_exception_with_instana (wrapped , instance , argv , kwargs ):
113+ @wrapt .patch_function_wrapper ("tornado.web" , "RequestHandler.log_exception" )
114+ def log_exception_with_instana (
115+ wrapped : Callable [..., object ],
116+ instance : "RequestHandler" ,
117+ argv : Tuple [object , ...],
118+ kwargs : Dict [str , Any ],
119+ ) -> Coroutine :
92120 try :
93- if not hasattr (instance .request , ' _instana' ):
121+ if not hasattr (instance .request , " _instana" ):
94122 return wrapped (* argv , ** kwargs )
95123
96124 if not isinstance (argv [1 ], tornado .web .HTTPError ):
@@ -101,7 +129,6 @@ def log_exception_with_instana(wrapped, instance, argv, kwargs):
101129 except Exception :
102130 logger .debug ("tornado log_exception" , exc_info = True )
103131
104-
105132 logger .debug ("Instrumenting tornado server" )
106133except ImportError :
107134 pass
0 commit comments