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