20
20
from opentelemetry .instrumentation .utils import extract_attributes_from_object
21
21
from opentelemetry .instrumentation .wsgi import (
22
22
add_response_attributes ,
23
- collect_request_attributes ,
23
+ collect_request_attributes as wsgi_collect_request_attributes ,
24
24
wsgi_getter ,
25
25
)
26
26
from opentelemetry .propagate import extract
40
40
except ImportError :
41
41
MiddlewareMixin = object
42
42
43
+ try :
44
+ from django .core .handlers .asgi import ASGIRequest
45
+ except ImportError :
46
+ ASGIRequest = None
47
+
48
+ try :
49
+ from opentelemetry .instrumentation .asgi import (
50
+ asgi_getter ,
51
+ collect_request_attributes as asgi_collect_request_attributes ,
52
+ set_status_code ,
53
+ )
54
+ _is_asgi_supported = True
55
+ except ImportError :
56
+ asgi_getter = None
57
+ asgi_collect_request_attributes = None
58
+ set_status_code = None
59
+ _is_asgi_supported = False
60
+
61
+
43
62
_logger = getLogger (__name__ )
44
63
_attributes_by_preference = [
45
64
["http.scheme" , "http.host" , "http.target" ],
@@ -84,6 +103,9 @@ def _get_span_name(request):
84
103
except Resolver404 :
85
104
return "HTTP {}" .format (request .method )
86
105
106
+ def _is_asgi_request (self , request ):
107
+ return ASGIRequest and isinstance (request , ASGIRequest )
108
+
87
109
def process_request (self , request ):
88
110
# request.META is a dictionary containing all available HTTP headers
89
111
# Read more about request.META here:
@@ -92,12 +114,23 @@ def process_request(self, request):
92
114
if self ._excluded_urls .url_disabled (request .build_absolute_uri ("?" )):
93
115
return
94
116
117
+ is_asgi_request = self ._is_asgi_request (request )
118
+ if is_asgi_request and not _is_asgi_supported :
119
+ return
120
+
95
121
# pylint:disable=W0212
96
122
request ._otel_start_time = time ()
97
123
98
124
request_meta = request .META
99
125
100
- token = attach (extract (request_meta , getter = wsgi_getter ))
126
+ if is_asgi_request :
127
+ carrier_getter = asgi_getter
128
+ collect_request_attributes = asgi_collect_request_attributes
129
+ else :
130
+ carrier_getter = wsgi_getter
131
+ collect_request_attributes = wsgi_collect_request_attributes
132
+
133
+ token = attach (extract (request_meta , getter = carrier_getter ))
101
134
102
135
tracer = get_tracer (__name__ , __version__ )
103
136
@@ -156,15 +189,22 @@ def process_response(self, request, response):
156
189
if self ._excluded_urls .url_disabled (request .build_absolute_uri ("?" )):
157
190
return response
158
191
192
+ is_asgi_request = self ._is_asgi_request (request )
193
+ if is_asgi_request and not _is_asgi_supported :
194
+ return
195
+
159
196
if (
160
197
self ._environ_activation_key in request .META .keys ()
161
198
and self ._environ_span_key in request .META .keys ()
162
199
):
163
- add_response_attributes (
164
- request .META [self ._environ_span_key ],
165
- "{} {}" .format (response .status_code , response .reason_phrase ),
166
- response ,
167
- )
200
+ if is_asgi_request :
201
+ set_status_code (request .META [self ._environ_span_key ], response .status_code )
202
+ else :
203
+ add_response_attributes (
204
+ request .META [self ._environ_span_key ],
205
+ "{} {}" .format (response .status_code , response .reason_phrase ),
206
+ response ,
207
+ )
168
208
169
209
request .META .pop (self ._environ_span_key )
170
210
@@ -182,7 +222,10 @@ def process_response(self, request, response):
182
222
request .META .pop (self ._environ_activation_key )
183
223
184
224
if self ._environ_token in request .META .keys ():
185
- detach (request .environ .get (self ._environ_token ))
225
+ if is_asgi_request :
226
+ detach (request .META .get (self ._environ_token ))
227
+ else :
228
+ detach (request .environ .get (self ._environ_token ))
186
229
request .META .pop (self ._environ_token )
187
230
188
231
return response
0 commit comments