def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) before = (transaction.name, transaction.group) with FunctionTrace(name=name): try: return wrapped(*args, **kwargs) finally: # We want to name the transaction after this # middleware but only if the transaction wasn't # named from within the middleware itself explicity. after = (transaction.name, transaction.group) if before == after: transaction.set_transaction_name(name, priority=2)
def _nr_wrapper_django_template_base_InclusionNode_render_( wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) if wrapped.__self__ is None: return wrapped(*args, **kwargs) file_name = getattr(wrapped.__self__, '_nr_file_name', None) if file_name is None: return wrapped(*args, **kwargs) name = wrapped.__self__._nr_file_name with FunctionTrace(transaction, name, 'Template/Include'): return wrapped(*args, **kwargs)
def _nr_wrapper_WSGIContainer___call__body_(wrapped, instance, args, kwargs): # This variant of the WSGIContainer.__call__() wrapper is used when # being used with HTTPServer directly and it is believed that we are # being called for a HTTP request where there is request content. # This would also be used where FallbackHandler was being used. # There should already be a transaction associated with the Tornado # request object and also a current active transaction. def _params(request, *args, **kwargs): return request request = _params(*args, **kwargs) transaction = retrieve_current_transaction() transaction.set_transaction_name(request.uri, 'Uri', priority=1) with FunctionTrace(transaction, name='Request/Process', group='Python/Tornado'): return wrapped(*args, **kwargs)
def _generator(generator): try: value = None exc = None while True: transaction = current_transaction() params = {} params['filename'] = \ generator.gi_frame.f_code.co_filename params['lineno'] = \ generator.gi_frame.f_lineno with FunctionTrace(transaction, name, params=params): try: if exc is not None: yielded = generator.throw(*exc) exc = None else: yielded = generator.send(value) except (Return, StopIteration): raise except Exception: if transaction: transaction.record_exception( *sys.exc_info()) raise try: value = yield yielded except Exception: exc = sys.exc_info() finally: generator.close()
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) transaction.set_transaction_name(name, priority=priority) with FunctionTrace(name=name): try: return wrapped(*args, **kwargs) except: # Catch all exc_info = sys.exc_info() try: # Store exc_info on the request to check response code # prior to reporting args[0]._nr_exc_info = exc_info except: record_exception(*exc_info) raise
def _nr_wrapper_django_inclusion_tag_wrapper_(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) name = hasattr(wrapped, '__name__') and wrapped.__name__ if name is None: return wrapped(*args, **kwargs) qualname = callable_name(wrapped) tags = django_settings.instrumentation.templates.inclusion_tag if '*' not in tags and name not in tags and qualname not in tags: return wrapped(*args, **kwargs) with FunctionTrace(transaction, name, group='Template/Tag'): return wrapped(*args, **kwargs)
def _nr_wrapper_GZipMiddleware_process_response_(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) def _bind_params(request, response, *args, **kwargs): return request, response request, response = _bind_params(*args, **kwargs) if should_add_browser_timing(response, transaction): with FunctionTrace(name=callable_name(browser_timing_insertion)): response_with_browser = browser_timing_insertion( response, transaction) return wrapped(request, response_with_browser) return wrapped(request, response)
def view_handler_wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if not transaction: return wrapped(*args, **kwargs) try: view_callable = wrapped.__original_view__ or wrapped except AttributeError: view_callable = wrapped name = callable_name(view_callable) transaction.set_transaction_name(name) with FunctionTrace(name) as trace: try: return wrapped(*args, **kwargs) except: # Catch all trace.record_exception(ignore_errors=should_ignore) raise
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if callable(name): if instance and inspect.ismethod(wrapped): _name = name(instance, *args, **kwargs) else: _name = name(*args, **kwargs) elif name is None: _name = callable_name(wrapped) else: _name = name # Helper for obtaining the appropriate application object. If # has an activate() method assume it is a valid application # object. Don't check by type so se can easily mock it for # testing if need be. def _application(): if hasattr(application, 'activate'): return application return application_instance(application) # Check to see if we are being called within the context of an # existing transaction. If we are, then we will record the call # as a function trace node instead. This situation can occur # when a function wrapped with Celery task decorator is called # explicitly in the context of an existing transaction. if transaction: with FunctionTrace(transaction, callable_name(wrapped)): return wrapped(*args, **kwargs) # Otherwise treat it as top level background task. with BackgroundTask(_application(), _name, 'Celery'): return wrapped(*args, **kwargs)
def wrapped_callback(*args, **kwargs): transaction = current_transaction() if transaction is None: return callback(*args, **kwargs) if not kwargs: method, properties = args[1:3] start_time = getattr(wrapped_callback, '_nr_start_time', None) _add_consume_rabbitmq_trace(transaction, method=method, properties=properties, nr_start_time=start_time, queue_name=queue) else: m = transaction._transaction_metrics.get(KWARGS_ERROR, 0) transaction._transaction_metrics[KWARGS_ERROR] = m + 1 name = callable_name(callback) with FunctionTrace(transaction=transaction, name=name): return callback(*args, **kwargs)
def _nr_wrapper_APIView_dispatch_(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) def _args(request, *args, **kwargs): return request view = instance request = _args(*args, **kwargs) request_method = request.method.lower() if request_method in view.http_method_names: handler = getattr(view, request_method, view.http_method_not_allowed) else: handler = view.http_method_not_allowed view_func = getattr(view, '_nr_view_func', None) view_func_callable_name = getattr(view, '_nr_view_func_callable_name', None) if view_func_callable_name: if handler == view.http_method_not_allowed: name = '%s.%s' % (view_func_callable_name, 'http_method_not_allowed') else: name = '%s.%s' % (view_func_callable_name, request_method) else: name = callable_name(handler) transaction.set_transaction_name(name) # catch exceptions handled by view.handle_exception view.handle_exception = _nr_wrapper_APIView_handle_exception_( view.handle_exception, request) with FunctionTrace(name=name, source=view_func or handler): return wrapped(*args, **kwargs)
def _nr_wrapper_handler_(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) name = callable_name(wrapped) view_class = getattr(wrapped, 'view_class', None) view = view_class or wrapped if view_class: try: method = args[0].method.lower() name = callable_name(view_class) + '.' + method view = getattr(view_class, method) except: pass transaction.set_transaction_name(name, priority=3) import sanic transaction.add_framework_info(name='Sanic', version=sanic.__version__) with FunctionTrace(name=name, source=view): return wrapped(*args, **kwargs)
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) transaction.name_transaction(name, priority=priority) with FunctionTrace(transaction, name=name): try: return wrapped(*args, **kwargs) except: # Catch all # Python 2.5 doesn't allow *args before keywords. # See http://bugs.python.org/issue3473. exc_info = sys.exc_info() transaction.record_exception(exc_info[0], exc_info[1], exc_info[2], ignore_errors=['django.http:Http404', 'django.http.response:Http404']) raise finally: exc_info = None
def _nr_wrapper_gen_coroutine_function_(wrapped, instance, args, kwargs): # This wrapper is applied outside of any instance of the gen.engine # and gen.coroutine decorators. We record the call as a function # trace, flagging it as a special coroutine instance. This also # works on conjunction with the wrapper on the Runner class, which # applies a wrapper to the generator when passed to the generator. # When this wrapped function is called, if the result of the # function that gen.engine or gen.coroutine calls is a generator, # the Runner is created and run. If running it, it will always call # into the generator at least once. On that first time the wrapper # for the generator will see the active transaction and can keep a # reference to it to allow the transaction to be reinstated across # calls of the generator to yield an item. transaction = retrieve_current_transaction() if transaction is None: return wrapped(*args, **kwargs) name = callable_name(wrapped) with FunctionTrace(transaction, '%s (coroutine)' % name): return wrapped(*args, **kwargs)
def _nr_wrapper_RequestHandler_on_connection_close(wrapped, instance, args, kwargs): # The RequestHandler.on_connection_close() method is called when the # client closes the connection prematurely before the request had # been completed. The callback itself wasn't registered at a point # where there was any request tracking so there shouldn't be any # active transaction when this is called. We track the call of the # wrapped method and then finalize the whole transaction. transaction = retrieve_current_transaction() if transaction: return wrapped(*args, **kwargs) handler = instance request = handler.request transaction = resume_request_monitoring(request) if transaction is None: return wrapped(*args, **kwargs) name = callable_name(wrapped) try: with FunctionTrace(transaction, name): result = wrapped(*args, **kwargs) except: # Catch all finalize_request_monitoring(request, *sys.exc_info()) raise else: finalize_request_monitoring(request) return result
def execute_wrapper(wrapped, instance, args, kwargs): assert instance is not None handler = instance request = handler.request # Check to see if we are being called within the context of any # sort of transaction. If we are, then we don't bother doing # anything and just call the wrapped function. This should not # really ever occur but check anyway. transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) if request.method not in handler.SUPPORTED_METHODS: return wrapped(*args, **kwargs) name = callable_name(getattr(handler, request.method.lower())) transaction.set_transaction_name(name) with FunctionTrace(transaction, name=name): return wrapped(*args, **kwargs)
def test_sentinel_exited_complete_root_exception(): """ This test forces a transaction to exit while it still has an active trace this causes an exception to be raised in TraceCache complete_root(). It verifies that the sentinel.exited property is set to true if an exception is raised in complete_root(), and that the exception is caught. """ txn = None sentinel = None txn = BackgroundTask(application_instance(), "Parent") txn.__enter__() sentinel = txn.root_span trace = FunctionTrace("trace") trace.__enter__() txn.__exit__(None, None, None) assert sentinel.exited # Make sure to exit properly so cleanup is performed trace.__exit__(None, None, None) txn.__exit__(None, None, None)
async def __call__(self, scope, receive, send): await send({"type": "http.response.start", "status": 200, "headers": []}) with FunctionTrace(name=callable_name(self.route)): await self.route(None)
def __call__(self, frame, event, arg): if event not in [ 'call', 'c_call', 'return', 'c_return', 'exception', 'c_exception' ]: return parent = current_trace() if not parent: return # Not sure if setprofile() is reliable in the face of # coroutine systems based on greenlets so don't run # if we detect may be using greenlets. if (hasattr(sys, '_current_frames') and parent.thread_id not in sys._current_frames()): return co = frame.f_code func_name = co.co_name func_line_no = frame.f_lineno func_filename = co.co_filename def _callable_name(): # A stack frame doesn't provide any information about the # original callable object. We thus need to try and # deduce what it is by searching through the stack # frame globals. This will still not work in many # cases, including lambdas, generator expressions, # and decorated attributes such as properties of # classes. try: if func_name in frame.f_globals: if frame.f_globals[func_name].func_code is co: return callable_name(frame.f_globals[func_name]) except Exception: pass for name, obj in six.iteritems(frame.f_globals): try: if obj.__dict__[func_name].func_code is co: return callable_name(obj.__dict__[func_name]) except Exception: pass if event in ['call', 'c_call']: # Skip the outermost as we catch that with the root # function traces for the profile trace. if len(self.function_traces) == 0: self.function_traces.append(None) return if self.current_depth >= self.maximum_depth: self.function_traces.append(None) return if func_filename.startswith(AGENT_PACKAGE_DIRECTORY): self.function_traces.append(None) return if event == 'call': name = _callable_name() if not name: name = '%s:%s#%s' % (func_filename, func_name, func_line_no) else: name = callable_name(arg) if not name: name = '%s:@%s#%s' % (func_filename, func_name, func_line_no) function_trace = FunctionTrace(name=name, parent=parent) function_trace.__enter__() self.function_traces.append(function_trace) self.current_depth += 1 elif event in ['return', 'c_return', 'c_exception']: if not self.function_traces: return try: function_trace = self.function_traces.pop() except IndexError: pass else: if function_trace: function_trace.__exit__(None, None, None) self.current_depth -= 1
def wrapper(wrapped, instance, args, kwargs): parent = current_trace() if parent is None: return wrapped(*args, **kwargs) if callable(name): if instance is not None: _name = name(instance, *args, **kwargs) else: _name = name(*args, **kwargs) elif name is None: _name = callable_name(wrapped) else: _name = name if callable(group): if instance is not None: _group = group(instance, *args, **kwargs) else: _group = group(*args, **kwargs) else: _group = group if callable(label): if instance is not None: _label = label(instance, *args, **kwargs) else: _label = label(*args, **kwargs) else: _label = label if callable(params): if instance is not None: _params = params(instance, *args, **kwargs) else: _params = params(*args, **kwargs) else: _params = params with FunctionTrace(_name, _group, _label, _params, parent=parent): if not hasattr(sys, 'getprofile'): return wrapped(*args, **kwargs) profiler = sys.getprofile() if profiler: return wrapped(*args, **kwargs) sys.setprofile(ProfileTrace(depth)) try: return wrapped(*args, **kwargs) finally: sys.setprofile(None)
def _test(): with FunctionTrace("trace", params={"secret": "super secret"}): pass
def __call__(self, frame, event, arg): if event not in ['call', 'c_call', 'return', 'c_return', 'exception', 'c_exception']: return transaction = current_transaction() if not transaction: return # Not sure if setprofile() is reliable in the face of # coroutine systems based on greenlets so don't run # if we detect may be using greenlets. if (hasattr(sys, '_current_frames') and not transaction.thread_id in sys._current_frames()): return co = frame.f_code func_name = co.co_name func_line_no = frame.f_lineno func_filename = co.co_filename def _callable_name(): # This is pretty ugly and inefficient, but a stack # frame doesn't provide any information about the # original callable object. We thus need to try and # deduce what it is by searching through the stack # frame globals. This will still not work in many # cases, including lambdas, generator expressions, # and decoratored attributes such as properties of # classes. try: if func_name in frame.f_globals: if frame.f_globals[func_name].func_code is co: return callable_name(frame.f_globals[func_name]) except Exception: pass for name, obj in six.iteritems(frame.f_globals): try: if obj.__dict__[func_name].func_code is co: return callable_name(obj.__dict__[func_name]) except Exception: pass if event in ['call', 'c_call']: # Skip the outermost as we catch that with the root # function traces for the profile trace. if len(self.function_traces) == 0: self.function_traces.append(None) return if self.current_depth >= self.maximum_depth: self.function_traces.append(None) return if func_filename.startswith(AGENT_PACKAGE_DIRECTORY): self.function_traces.append(None) return if event == 'call': name = _callable_name() if not name: name = '%s:%s#%s' % (func_filename, func_name, func_line_no) else: name = callable_name(arg) if not name: name = '%s:@%s#%s' % (func_filename, func_name, func_line_no) function_trace = FunctionTrace(transaction, name=name) function_trace.__enter__() self.function_traces.append(function_trace) self.current_depth += 1 elif event in ['return', 'c_return', 'c_exception']: if not self.function_traces: return try: function_trace = self.function_traces.pop() except IndexError: pass else: if function_trace: function_trace.__exit__(None, None, None) self.current_depth -= 1
def _test(): transaction = current_transaction() transaction._sampled = True with FunctionTrace('span_generator'): pass
def wrapped_callback(*args, **kwargs): transaction = current_transaction(active_only=False) if transaction and (transaction.ignore_transaction or transaction.stopped): return callback(*args, **kwargs) elif transaction: with FunctionTrace(transaction=transaction, name=name): return callback(*args, **kwargs) else: if hasattr(instance, '_nr_disable_txn_tracing'): return callback(*args, **kwargs) # Keyword arguments are unknown since this is a user # defined callback exchange = 'Unknown' routing_key = None headers = None reply_to = None correlation_id = None unknown_kwargs = False if not kwargs: method, properties = args[1:3] exchange = method.exchange or 'Default' routing_key = getattr(method, 'routing_key', None) if properties is not None: headers = getattr(properties, 'headers', None) reply_to = getattr(properties, 'reply_to', None) correlation_id = getattr(properties, 'correlation_id', None) else: unknown_kwargs = True # If headers are available, attempt to process CAT cat_id, cat_transaction = None, None if headers: cat_id = headers.pop(MessageTrace.cat_id_key, None) cat_transaction = headers.pop( MessageTrace.cat_transaction_key, None) with MessageTransaction(application=application_instance(), library='RabbitMQ', destination_type='Exchange', destination_name=exchange, routing_key=routing_key, headers=headers, queue_name=queue, reply_to=reply_to, correlation_id=correlation_id) as mt: # Improve transaction naming _new_txn_name = 'RabbitMQ/Exchange/%s/%s' % (exchange, name) mt.set_transaction_name(_new_txn_name, group='Message') # Record that something went horribly wrong if unknown_kwargs: m = mt._transaction_metrics.get(KWARGS_ERROR, 0) mt._transaction_metrics[KWARGS_ERROR] = m + 1 # Process CAT headers mt._process_incoming_cat_headers(cat_id, cat_transaction) return callback(*args, **kwargs)
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) if callable(name): if instance is not None: _name = name(instance, *args, **kwargs) else: _name = name(*args, **kwargs) elif name is None: _name = callable_name(wrapped) else: _name = name if callable(group): if instance is not None: _group = group(instance, *args, **kwargs) else: _group = group(*args, **kwargs) else: _group = group if callable(label): if instance is not None: _label = label(instance, *args, **kwargs) else: _label = label(*args, **kwargs) else: _label = label if callable(params): if instance is not None: _params = params(instance, *args, **kwargs) else: _params = params(*args, **kwargs) else: _params = params def _generator(generator): _gname = '%s (generator)' % _name try: value = None exc = None while True: transaction = current_transaction() params = {} frame = generator.gi_frame params['filename'] = frame.f_code.co_filename params['lineno'] = frame.f_lineno with FunctionTrace(transaction, _gname, _group, params=params): try: if exc is not None: yielded = generator.throw(*exc) exc = None else: yielded = generator.send(value) except StopIteration: raise except Exception: raise try: value = yield yielded except Exception: exc = sys.exc_info() finally: generator.close() with FunctionTrace(transaction, _name, _group, _label, _params): try: result = wrapped(*args, **kwargs) except: # Catch all raise else: if isinstance(result, types.GeneratorType): return _generator(result) else: return result
class _WSGIApplicationIterable(object): def __init__(self, transaction, generator): self.transaction = transaction self.generator = generator self.response_trace = None self.closed = False def __iter__(self): self.start_trace() try: for item in self.generator: try: self.transaction._calls_yield += 1 self.transaction._bytes_sent += len(item) except Exception: pass yield item except GeneratorExit: raise except: # Catch all self.transaction.record_exception(*sys.exc_info()) raise finally: self.close() def start_trace(self): if not self.transaction._sent_start: self.transaction._sent_start = time.time() if not self.response_trace: self.response_trace = FunctionTrace( name='Response', group='Python/WSGI') self.response_trace.__enter__() def close(self): if self.closed: return if self.response_trace: self.response_trace.__exit__(None, None, None) self.response_trace = None try: with FunctionTrace( name='Finalize', group='Python/WSGI'): if isinstance(self.generator, _WSGIApplicationMiddleware): self.generator.close() elif hasattr(self.generator, 'close'): name = callable_name(self.generator.close) with FunctionTrace(name): self.generator.close() except: # Catch all self.transaction.__exit__(*sys.exc_info()) raise else: self.transaction.__exit__(None, None, None) self.transaction._sent_end = time.time() finally: self.closed = True
def _test(): with FunctionTrace("_test", source=obj): pass
def test_get_linking_metadata_api_inside_transaction(): with FunctionTrace("test_linking_metadata") as trace: metadata = trace.get_linking_metadata() validate_metadata(metadata, EXPECTED_KEYS_TXN) metadata = trace.get_linking_metadata() validate_metadata(metadata, EXPECTED_KEYS_TRACE_ENDED)
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction(active_only=False) if callable(name): # Start Hotfix v2.2.1. # if instance and inspect.ismethod(wrapped): # _name = name(instance, *args, **kwargs) # else: # _name = name(*args, **kwargs) if instance is not None: _name = name(instance, *args, **kwargs) else: _name = name(*args, **kwargs) # End Hotfix v2.2.1. elif name is None: _name = callable_name(wrapped) else: _name = name # Helper for obtaining the appropriate application object. If # has an activate() method assume it is a valid application # object. Don't check by type so se can easily mock it for # testing if need be. def _application(): if hasattr(application, 'activate'): return application return application_instance(application) # A Celery Task can be called either outside of a transaction, or # within the context of an existing transaction. There are 3 # possibilities we need to handle: # # 1. In an inactive transaction # # If the end_of_transaction() or ignore_transaction() API calls # have been invoked, this task may be called in the context # of an inactive transaction. In this case, don't wrap the task # in any way. Just run the original function. # # 2. In an active transaction # # Run the original function inside a FunctionTrace. # # 3. Outside of a transaction # # This is the typical case for a celery Task. Since it's not # running inside of an existing transaction, we want to create # a new background transaction for it. if transaction and (transaction.ignore_transaction or transaction.stopped): return wrapped(*args, **kwargs) elif transaction: with FunctionTrace(callable_name(wrapped)): return wrapped(*args, **kwargs) else: with BackgroundTask(_application(), _name, 'Celery'): return wrapped(*args, **kwargs)
def _nr_wsgi_application_wrapper_(wrapped, instance, args, kwargs): # Check to see if any transaction is present, even an inactive # one which has been marked to be ignored or which has been # stopped already. transaction = current_transaction(active_only=False) if transaction: # If there is any active transaction we will return without # applying a new WSGI application wrapper context. In the # case of a transaction which is being ignored or which has # been stopped, we do that without doing anything further. if transaction.ignore_transaction or transaction.stopped: return wrapped(*args, **kwargs) # For any other transaction, we record the details of any # framework against the transaction for later reporting as # supportability metrics. if framework: transaction.add_framework_info( name=framework[0], version=framework[1]) # Also override the web transaction name to be the name of # the wrapped callable if not explicitly named, and we want # the default name to be that of the WSGI component for the # framework. This will override the use of a raw URL which # can result in metric grouping issues where a framework is # not instrumented or is leaking URLs. settings = transaction._settings if name is None and settings: if framework is not None: naming_scheme = settings.transaction_name.naming_scheme if naming_scheme in (None, 'framework'): transaction.set_transaction_name( callable_name(wrapped), priority=1) elif name: transaction.set_transaction_name(name, group, priority=1) return wrapped(*args, **kwargs) # Otherwise treat it as top level transaction. We have to though # look first to see whether the application name has been # overridden through the WSGI environ dictionary. def _args(environ, start_response, *args, **kwargs): return environ, start_response environ, start_response = _args(*args, **kwargs) target_application = application if 'newrelic.app_name' in environ: app_name = environ['newrelic.app_name'] if ';' in app_name: app_names = [n.strip() for n in app_name.split(';')] app_name = app_names[0] target_application = application_instance(app_name) for altname in app_names[1:]: target_application.link_to_application(altname) else: target_application = application_instance(app_name) else: # If application has an activate() method we assume it is an # actual application. Do this rather than check type so that # can easily mock it for testing. # FIXME Should this allow for multiple apps if a string. if not hasattr(application, 'activate'): target_application = application_instance(application) # Now start recording the actual web transaction. transaction = WSGIWebTransaction(target_application, environ) transaction.__enter__() # Record details of framework against the transaction for later # reporting as supportability metrics. if framework: transaction.add_framework_info( name=framework[0], version=framework[1]) # Override the initial web transaction name to be the supplied # name, or the name of the wrapped callable if wanting to use # the callable as the default. This will override the use of a # raw URL which can result in metric grouping issues where a # framework is not instrumented or is leaking URLs. # # Note that at present if default for naming scheme is still # None and we aren't specifically wrapping a designated # framework, then we still allow old URL based naming to # override. When we switch to always forcing a name we need to # check for naming scheme being None here. settings = transaction._settings if name is None and settings: naming_scheme = settings.transaction_name.naming_scheme if framework is not None: if naming_scheme in (None, 'framework'): transaction.set_transaction_name( callable_name(wrapped), priority=1) elif naming_scheme in ('component', 'framework'): transaction.set_transaction_name( callable_name(wrapped), priority=1) elif name: transaction.set_transaction_name(name, group, priority=1) def _start_response(status, response_headers, *args): additional_headers = transaction.process_response( status, response_headers, *args) _write = start_response(status, response_headers + additional_headers, *args) def write(data): if not transaction._sent_start: transaction._sent_start = time.time() result = _write(data) transaction._calls_write += 1 try: transaction._bytes_sent += len(data) except Exception: pass transaction._sent_end = time.time() return result return write try: # Should always exist, but check as test harnesses may not # have it. if 'wsgi.input' in environ: environ['wsgi.input'] = _WSGIInputWrapper(transaction, environ['wsgi.input']) with FunctionTrace( name='Application', group='Python/WSGI'): with FunctionTrace(name=callable_name(wrapped)): if (settings and settings.browser_monitoring.enabled and not transaction.autorum_disabled): result = _WSGIApplicationMiddleware(wrapped, environ, _start_response, transaction) else: result = wrapped(environ, _start_response) except: # Catch all transaction.__exit__(*sys.exc_info()) raise return _WSGIApplicationIterable(transaction, result)
def _make_request(): with FunctionTrace(name="parent", terminal=True): response = yield client.fetch("http://localhost:%s" % port) return response