26
26
from opentelemetry .instrumentation .utils import extract_attributes_from_object
27
27
from opentelemetry .instrumentation .wsgi import (
28
28
add_response_attributes ,
29
- collect_request_attributes ,
29
+ collect_request_attributes as wsgi_collect_request_attributes ,
30
30
wsgi_getter ,
31
31
)
32
32
from opentelemetry .propagate import extract
@@ -68,6 +68,25 @@ def __call__(self, request):
68
68
MiddlewareMixin = object
69
69
70
70
71
+ try :
72
+ from django .core .handlers .asgi import ASGIRequest
73
+ except ImportError :
74
+ ASGIRequest = None
75
+
76
+ try :
77
+ from opentelemetry .instrumentation .asgi import (
78
+ asgi_getter ,
79
+ collect_request_attributes as asgi_collect_request_attributes ,
80
+ set_status_code ,
81
+ )
82
+ _is_asgi_supported = True
83
+ except ImportError :
84
+ asgi_getter = None
85
+ asgi_collect_request_attributes = None
86
+ set_status_code = None
87
+ _is_asgi_supported = False
88
+
89
+
71
90
_logger = getLogger (__name__ )
72
91
_attributes_by_preference = [
73
92
[
@@ -132,6 +151,9 @@ def _get_span_name(request):
132
151
except Resolver404 :
133
152
return "HTTP {}" .format (request .method )
134
153
154
+ def _is_asgi_request (self , request ):
155
+ return ASGIRequest and isinstance (request , ASGIRequest )
156
+
135
157
def process_request (self , request ):
136
158
# request.META is a dictionary containing all available HTTP headers
137
159
# Read more about request.META here:
@@ -140,12 +162,23 @@ def process_request(self, request):
140
162
if self ._excluded_urls .url_disabled (request .build_absolute_uri ("?" )):
141
163
return
142
164
165
+ is_asgi_request = self ._is_asgi_request (request )
166
+ if is_asgi_request and not _is_asgi_supported :
167
+ return
168
+
143
169
# pylint:disable=W0212
144
170
request ._otel_start_time = time ()
145
171
146
172
request_meta = request .META
147
173
148
- token = attach (extract (request_meta , getter = wsgi_getter ))
174
+ if is_asgi_request :
175
+ carrier_getter = asgi_getter
176
+ collect_request_attributes = asgi_collect_request_attributes
177
+ else :
178
+ carrier_getter = wsgi_getter
179
+ collect_request_attributes = wsgi_collect_request_attributes
180
+
181
+ token = attach (extract (request_meta , getter = carrier_getter ))
149
182
150
183
span = self ._tracer .start_span (
151
184
self ._get_span_name (request ),
@@ -207,15 +240,22 @@ def process_response(self, request, response):
207
240
if self ._excluded_urls .url_disabled (request .build_absolute_uri ("?" )):
208
241
return response
209
242
243
+ is_asgi_request = self ._is_asgi_request (request )
244
+ if is_asgi_request and not _is_asgi_supported :
245
+ return
246
+
210
247
activation = request .META .pop (self ._environ_activation_key , None )
211
248
span = request .META .pop (self ._environ_span_key , None )
212
249
213
250
if activation and span :
214
- add_response_attributes (
215
- span ,
216
- "{} {}" .format (response .status_code , response .reason_phrase ),
217
- response ,
218
- )
251
+ if is_asgi_request :
252
+ set_status_code (request .META [self ._environ_span_key ], response .status_code )
253
+ else :
254
+ add_response_attributes (
255
+ span ,
256
+ "{} {}" .format (response .status_code , response .reason_phrase ),
257
+ response ,
258
+ )
219
259
220
260
propagator = get_global_response_propagator ()
221
261
if propagator :
@@ -238,7 +278,10 @@ def process_response(self, request, response):
238
278
activation .__exit__ (None , None , None )
239
279
240
280
if self ._environ_token in request .META .keys ():
241
- detach (request .environ .get (self ._environ_token ))
281
+ if is_asgi_request :
282
+ detach (request .META .get (self ._environ_token ))
283
+ else :
284
+ detach (request .environ .get (self ._environ_token ))
242
285
request .META .pop (self ._environ_token )
243
286
244
287
return response
0 commit comments