1- # (c) Copyright IBM Corp. 2021
2- # (c) Copyright Instana Inc. 2019
1+ # (c) Copyright IBM Corp. 2021, 2025
32
43
54try :
65 import tornado
6+ from typing import TYPE_CHECKING , Callable , Tuple , Dict , Any , Coroutine , Optional
77
88 import wrapt
99
10+ if TYPE_CHECKING :
11+ from tornado .web import RequestHandler
12+
1013 from opentelemetry .semconv .trace import SpanAttributes
1114
1215 from instana .log import logger
13- from instana .singletons import agent , tracer
16+ from instana .singletons import agent , get_tracer
1417 from instana .util .secrets import strip_secrets_from_query
1518 from instana .util .traceutils import extract_custom_headers
1619 from instana .propagators .format import Format
1720
18-
19-
20- @wrapt .patch_function_wrapper ('tornado.web' , 'RequestHandler._execute' )
21- def execute_with_instana (wrapped , instance , argv , kwargs ):
21+ @wrapt .patch_function_wrapper ("tornado.web" , "RequestHandler._execute" )
22+ def execute_with_instana (
23+ wrapped : Callable [..., object ],
24+ instance : "RequestHandler" ,
25+ argv : Tuple [object , ...],
26+ kwargs : Dict [str , Any ],
27+ ) -> Coroutine :
2228 try :
2329 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' ])
30+ tracer = get_tracer ()
31+ if (
32+ hasattr (instance .request .headers , "__dict__" )
33+ and "_dict" in instance .request .headers .__dict__
34+ ):
35+ span_context = tracer .extract (
36+ Format .HTTP_HEADERS , instance .request .headers .__dict__ ["_dict" ]
37+ )
2738
2839 span = tracer .start_span ("tornado-server" , span_context = span_context )
2940
3041 # Query param scrubbing
3142 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 )
43+ cleaned_qp = strip_secrets_from_query (
44+ instance .request .query ,
45+ agent .options .secrets_matcher ,
46+ agent .options .secrets_list ,
47+ )
3448 span .set_attribute ("http.params" , cleaned_qp )
35-
49+
3650 url = f"{ instance .request .protocol } ://{ instance .request .host } { instance .request .path } "
3751 span .set_attribute (SpanAttributes .HTTP_URL , url )
3852 span .set_attribute (SpanAttributes .HTTP_METHOD , instance .request .method )
@@ -52,20 +66,29 @@ def execute_with_instana(wrapped, instance, argv, kwargs):
5266 except Exception :
5367 logger .debug ("tornado execute" , exc_info = True )
5468
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' ):
69+ @wrapt .patch_function_wrapper ("tornado.web" , "RequestHandler.set_default_headers" )
70+ def set_default_headers_with_instana (
71+ wrapped : Callable [..., object ],
72+ instance : "RequestHandler" ,
73+ argv : Tuple [object , ...],
74+ kwargs : Dict [str , Any ],
75+ ) -> Optional [Coroutine ]:
76+ if not hasattr (instance .request , "_instana" ):
5977 return wrapped (* argv , ** kwargs )
6078
6179 span = instance .request ._instana
80+ tracer = get_tracer ()
6281 tracer .inject (span .context , Format .HTTP_HEADERS , instance ._headers )
6382
64-
65- @wrapt .patch_function_wrapper ('tornado.web' , 'RequestHandler.on_finish' )
66- def on_finish_with_instana (wrapped , instance , argv , kwargs ):
83+ @wrapt .patch_function_wrapper ("tornado.web" , "RequestHandler.on_finish" )
84+ def on_finish_with_instana (
85+ wrapped : Callable [..., object ],
86+ instance : "RequestHandler" ,
87+ argv : Tuple [object , ...],
88+ kwargs : Dict [str , Any ],
89+ ) -> Coroutine :
6790 try :
68- if not hasattr (instance .request , ' _instana' ):
91+ if not hasattr (instance .request , " _instana" ):
6992 return wrapped (* argv , ** kwargs )
7093
7194 span = instance .request ._instana
@@ -86,11 +109,15 @@ def on_finish_with_instana(wrapped, instance, argv, kwargs):
86109 except Exception :
87110 logger .debug ("tornado on_finish" , exc_info = True )
88111
89-
90- @wrapt .patch_function_wrapper ('tornado.web' , 'RequestHandler.log_exception' )
91- def log_exception_with_instana (wrapped , instance , argv , kwargs ):
112+ @wrapt .patch_function_wrapper ("tornado.web" , "RequestHandler.log_exception" )
113+ def log_exception_with_instana (
114+ wrapped : Callable [..., object ],
115+ instance : "RequestHandler" ,
116+ argv : Tuple [object , ...],
117+ kwargs : Dict [str , Any ],
118+ ) -> Coroutine :
92119 try :
93- if not hasattr (instance .request , ' _instana' ):
120+ if not hasattr (instance .request , " _instana" ):
94121 return wrapped (* argv , ** kwargs )
95122
96123 if not isinstance (argv [1 ], tornado .web .HTTPError ):
@@ -101,7 +128,6 @@ def log_exception_with_instana(wrapped, instance, argv, kwargs):
101128 except Exception :
102129 logger .debug ("tornado log_exception" , exc_info = True )
103130
104-
105131 logger .debug ("Instrumenting tornado server" )
106132except ImportError :
107133 pass
0 commit comments