39
39
from newrelic .config import extra_settings
40
40
from newrelic .core .config import global_settings
41
41
42
+ # These middleware are not useful to wrap as they don't do anything particularly
43
+ # interesting that could cause performance issues.
44
+ MIDDLEWARE_DENY_WRAP = frozenset (
45
+ {
46
+ "django.middleware.csrf:CsrfViewMiddleware" ,
47
+ "django.middleware.clickjacking:XFrameOptionsMiddleware" ,
48
+ "django.contrib.messages.middleware:MessageMiddleware" ,
49
+ "django.middleware.csrf:CsrfViewMiddleware" ,
50
+ "django.middleware.common:CommonMiddleware" ,
51
+ "django.middleware.security:SecurityMiddleware" ,
52
+ }
53
+ )
54
+
42
55
_logger = logging .getLogger (__name__ )
43
56
44
57
_boolean_states = {
@@ -144,6 +157,7 @@ def should_add_browser_timing(response, transaction):
144
157
# Response middleware for automatically inserting RUM header into HTML response returned by application
145
158
146
159
160
+
147
161
def browser_timing_insertion (response , transaction ):
148
162
# No point continuing if header is empty. This can occur if RUM is not enabled within the UI. We don't want to
149
163
# generate the header just yet as we want to do that as late as possible so that application server time in header
@@ -176,6 +190,7 @@ def browser_timing_insertion(response, transaction):
176
190
# will be automatically inserted into set of tag libraries when performing step to instrument the middleware.
177
191
178
192
193
+
179
194
def newrelic_browser_timing_header ():
180
195
from django .utils .safestring import mark_safe
181
196
@@ -238,77 +253,12 @@ def wrapper(wrapped, instance, args, kwargs):
238
253
return FunctionWrapper (wrapped , wrapper )
239
254
240
255
for wrapped in middleware :
241
- yield wrapper (wrapped )
242
-
243
-
244
- # Because this is not being used in any version of Django that is
245
- # within New Relic's support window, no tests will be added
246
- # for this. However, value exists to keeping backwards compatible
247
- # functionality, so instead of removing this instrumentation, this
248
- # will be excluded from the coverage analysis.
249
- def wrap_view_middleware (middleware ): # pragma: no cover
250
- # This is no longer being used. The changes to strip the
251
- # wrapper from the view handler when passed into the function
252
- # urlresolvers.reverse() solves most of the problems. To back
253
- # that up, the object wrapper now proxies various special
254
- # methods so that comparisons like '==' will work. The object
255
- # wrapper can even be used as a standin for the wrapped object
256
- # when used as a key in a dictionary and will correctly match
257
- # the original wrapped object.
258
-
259
- # Wrapper to be applied to view middleware. Records the time
260
- # spent in the middleware as separate function node and also
261
- # attempts to name the web transaction after the name of the
262
- # middleware with success being determined by the priority.
263
- # This wrapper is special in that it must strip the wrapper
264
- # from the view handler when being passed to the view
265
- # middleware to avoid issues where middleware wants to do
266
- # comparisons between the passed middleware and some other
267
- # value. It is believed that the view handler should never
268
- # actually be called from the view middleware so not an
269
- # issue that no longer wrapped at this point.
270
-
271
- def wrapper (wrapped ):
272
- # The middleware if a class method would already be
273
- # bound at this point, so is safe to determine the name
274
- # when it is being wrapped rather than on each
275
- # invocation.
276
-
277
- name = callable_name (wrapped )
278
-
279
- def wrapper (wrapped , instance , args , kwargs ):
280
- transaction = current_transaction ()
281
-
282
- def _wrapped (request , view_func , view_args , view_kwargs ):
283
- # This strips the view handler wrapper before call.
284
-
285
- if hasattr (view_func , "_nr_last_object" ):
286
- view_func = view_func ._nr_last_object
287
-
288
- return wrapped (request , view_func , view_args , view_kwargs )
289
-
290
- if transaction is None :
291
- return _wrapped (* args , ** kwargs )
292
-
293
- before = (transaction .name , transaction .group )
256
+ do_not_wrap = is_denied_middleware (callable_name (wrapped ))
294
257
295
- with FunctionTrace (name = name , source = wrapped ):
296
- try :
297
- return _wrapped (* args , ** kwargs )
298
-
299
- finally :
300
- # We want to name the transaction after this
301
- # middleware but only if the transaction wasn't
302
- # named from within the middleware itself explicitly.
303
-
304
- after = (transaction .name , transaction .group )
305
- if before == after :
306
- transaction .set_transaction_name (name , priority = 2 )
307
-
308
- return FunctionWrapper (wrapped , wrapper )
309
-
310
- for wrapped in middleware :
311
- yield wrapper (wrapped )
258
+ if do_not_wrap :
259
+ yield wrapped
260
+ else :
261
+ yield wrapper (wrapped )
312
262
313
263
314
264
def wrap_trailing_middleware (middleware ):
@@ -323,7 +273,13 @@ def wrap_trailing_middleware(middleware):
323
273
# invocation.
324
274
325
275
for wrapped in middleware :
326
- yield FunctionTraceWrapper (wrapped , name = callable_name (wrapped ))
276
+ name = callable_name (wrapped )
277
+ do_not_wrap = is_denied_middleware (name )
278
+
279
+ if do_not_wrap :
280
+ yield wrapped
281
+ else :
282
+ yield FunctionTraceWrapper (wrapped , name = name )
327
283
328
284
329
285
def insert_and_wrap_middleware (handler , * args , ** kwargs ):
@@ -1149,17 +1105,28 @@ def _wrapper(wrapped, instance, args, kwargs):
1149
1105
return _wrapper (middleware )
1150
1106
1151
1107
1108
+ def is_denied_middleware (callable_name ):
1109
+ for middleware in MIDDLEWARE_DENY_WRAP :
1110
+ if middleware in callable_name :
1111
+ return True
1112
+ return False
1113
+
1114
+
1152
1115
def _nr_wrapper_convert_exception_to_response_ (wrapped , instance , args , kwargs ):
1153
1116
def _bind_params (original_middleware , * args , ** kwargs ):
1154
1117
return original_middleware
1155
1118
1156
1119
original_middleware = _bind_params (* args , ** kwargs )
1157
1120
converted_middleware = wrapped (* args , ** kwargs )
1158
1121
name = callable_name (original_middleware )
1122
+ do_not_wrap = is_denied_middleware (name )
1159
1123
1160
- if is_coroutine_function (converted_middleware ) or is_asyncio_coroutine (converted_middleware ):
1161
- return _nr_wrap_converted_middleware_async_ (converted_middleware , name )
1162
- return _nr_wrap_converted_middleware_ (converted_middleware , name )
1124
+ if do_not_wrap :
1125
+ return converted_middleware
1126
+ else :
1127
+ if is_coroutine_function (converted_middleware ) or is_asyncio_coroutine (converted_middleware ):
1128
+ return _nr_wrap_converted_middleware_async_ (converted_middleware , name )
1129
+ return _nr_wrap_converted_middleware_ (converted_middleware , name )
1163
1130
1164
1131
1165
1132
def instrument_django_core_handlers_exception (module ):
0 commit comments