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 callback_wrapper(wrapped, instance, args, kwargs): if current_transaction(): return wrapped(*args, **kwargs) if not hasattr(transaction, '_nr_current_request'): return wrapped(*args, **kwargs) request = transaction._nr_current_request() if not request: return wrapped(*args, **kwargs) if not hasattr(request, '_nr_wait_function_trace'): return wrapped(*args, **kwargs) if not request._nr_wait_function_trace: return wrapped(*args, **kwargs) transaction.save_transaction() if request._nr_wait_function_trace: request._nr_wait_function_trace.__exit__(None, None, None) request._nr_wait_function_trace = None try: name = callable_name(wrapped) with FunctionTrace(transaction, name=name): return wrapped(*args, **kwargs) except Exception: transaction.record_exception(*sys.exc_info()) raise finally: if not request._nr_request_finished: request._nr_wait_function_trace = FunctionTrace( transaction, name='Callback/Wait', group='Python/Tornado') request._nr_wait_function_trace.__enter__() transaction.drop_transaction() elif not request.connection.stream.writing(): transaction.__exit__(None, None, None) request._nr_transaction = None else: request._nr_wait_function_trace = FunctionTrace( transaction, name='Request/Output', group='Python/Tornado') request._nr_wait_function_trace.__enter__() transaction.drop_transaction()
async def waiter(asyncio, event, wait): with FunctionTrace(name='waiter1', terminal=True): event.set() # Block until the parent says to exit await wait.wait() with FunctionTrace(name='waiter2', terminal=True): pass await child()
def _test(): transaction = current_transaction() transaction.queue_start = 1.0 transaction._sampled = True with FunctionTrace('trace1') as trace_1: trace_1._add_agent_attribute('trace1_a', 'foobar') trace_1._add_agent_attribute('trace1_b', 'barbaz') with FunctionTrace('trace2') as trace_2: trace_2._add_agent_attribute('trace2_a', 'foobar') trace_2._add_agent_attribute('trace2_b', 'barbaz')
def close(self): try: with FunctionTrace(self.transaction, name='Finalize', group='Python/WSGI'): if hasattr(self.generator, 'close'): name = callable_name(self.generator.close) with FunctionTrace(self.transaction, name): self.generator.close() except: # Catch all self.transaction.record_exception() raise
def __call__(self, environ, start_response): transaction = retrieve_current_transaction() if transaction is None: return self.wsgi_application(environ, start_response) name = callable_name(self.wsgi_application) with FunctionTrace(transaction, name='Application', group='Python/WSGI'): with FunctionTrace(transaction, name=name): result = self.wsgi_application(environ, start_response) return _WSGIApplicationIterable(transaction, result)
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) # set exception views to priority=1 so they won't take precedence over # the original view callable transaction.set_transaction_name( name, priority=1 if args and isinstance(args[0], Exception) else 2) with FunctionTrace(name, source=view_callable) as trace: try: return wrapped(*args, **kwargs) except: # Catch all trace.notice_error(ignore=should_ignore, status_code=status_code) raise
def _wrapper(context, request): transaction = current_transaction() if not transaction: return wrapper(context, request) name = callable_name(view) with FunctionTrace(name=name, source=view) as tracer: try: return wrapper(context, request) finally: attr = instance.attr inst = getattr(request, '__view__', None) if inst is not None: if attr: handler = getattr(inst, attr) name = callable_name(handler) transaction.set_transaction_name(name, priority=2) tracer.name = name tracer.add_code_level_metrics(handler) else: method = getattr(inst, '__call__') if method: name = callable_name(method) transaction.set_transaction_name(name, priority=2) tracer.name = name tracer.add_code_level_metrics(method)
def _wrapper(context, request): transaction = current_transaction() if not transaction: return wrapper(context, request) name = callable_name(view) with FunctionTrace(name=name) as tracer: try: return wrapper(context, request) finally: attr = instance.attr if attr: inst = getattr(request, '__view__', None) if inst is not None: name = callable_name(getattr(inst, attr)) transaction.set_transaction_name(name, priority=1) tracer.name = name else: inst = getattr(request, '__view__', None) if inst is not None: method = getattr(inst, '__call__') if method: name = callable_name(method) transaction.set_transaction_name(name, priority=1) tracer.name = name
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_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) with FunctionTrace(transaction, name): 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 callback_wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) name = callable_name(wrapped) # Needs to be at a higher priority so that error handler processing # below will not override the web transaction being named after the # actual request handler. transaction.set_transaction_name(name, priority=2) with FunctionTrace(name=name, source=wrapped) as trace: try: return wrapped(*args, **kwargs) except: # Catch all # In most cases this seems like it will never be invoked as # bottle will internally capture the exception before we # get a chance and rather than propagate the exception will # return it instead. This doesn't always seem to be the case # though when plugins are used, although that may depend on # the specific bottle version being used. trace.notice_error(status_code=status_code, ignore=should_ignore) raise
def wrapper(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) # We can't intercept the delegated view handler when it # is looked up by the dispatch() method so we need to # duplicate the lookup mechanism. if request.method.lower() in view.http_method_names: handler = getattr(view, request.method.lower(), view.http_method_not_allowed) else: handler = view.http_method_not_allowed name = callable_name(handler) 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() """ expected_error = "not the current trace" try: 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 False, "Did not raise exception" except RuntimeError as e: assert str(e) == expected_error finally: assert sentinel.exited # Make sure to exit properly so cleanup is performed trace.__exit__(None, None, None) txn.__exit__(None, None, None)
def on_connection_close_wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction: return wrapped(*args, **kwargs) handler = instance request = handler.request transaction = getattr(request, '_nr_transaction', None) if not transaction: return wrapped(*args, **kwargs) transaction.save_transaction() if request._nr_wait_function_trace: request._nr_wait_function_trace.__exit__(None, None, None) name = callable_name(wrapped) try: with FunctionTrace(transaction, name): return wrapped(*args, **kwargs) except Exception: transaction.record_exception(*sys.exc_info()) finally: transaction.__exit__(None, None, None)
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() def _wrapped(request, view_func, view_args, view_kwargs): # This strips the view handler wrapper before call. if hasattr(view_func, '_nr_last_object'): view_func = view_func._nr_last_object return wrapped(request, view_func, view_args, view_kwargs) if transaction is None: return _wrapped(*args, **kwargs) before = (transaction.name, transaction.group) with FunctionTrace(transaction, 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.name_transaction(name, priority=2)
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) with FunctionTrace(transaction, name=name): return wrapped(*args, **kwargs)
def _inner(): try: with FunctionTrace(transaction, name): result = yield from coro return result except: transaction.record_exception(ignore_errors=should_ignore) raise
def close(self): # Call close() on the iterable as required by the # WSGI specification. if hasattr(self.iterable, 'close'): name = callable_name(self.iterable.close) with FunctionTrace(name): self.iterable.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 test_async_trace_overlapping_children(): parent_trace = FunctionTrace('parent') with parent_trace: child_trace_1 = FunctionTrace('child_1', parent=parent_trace) child_trace_2 = FunctionTrace('child_2', parent=parent_trace) child_trace_1.__enter__() child_trace_2.__enter__() time.sleep(0.01) child_trace_1.__exit__(None, None, None) child_trace_2.__exit__(None, None, None) assert parent_trace.start_time < child_trace_1.start_time assert child_trace_1.start_time < child_trace_2.start_time assert child_trace_1.end_time < child_trace_2.end_time assert child_trace_2.end_time < parent_trace.end_time
def _nr_wrapper_WSGIContainer___call__no_body_(wrapped, instance, args, kwargs): # This variant of the WSGIContainer.__call__() wrapper is used when # being used direct with HTTPServer and it is believed that we are # being called for a HTTP request where there is no request content. # There should be no transaction associated with the Tornado request # object and also no current active transaction. Create the # transaction but if it is None then it means recording of # transactions is not enabled then do not need to do anything. def _params(request, *args, **kwargs): return request request = _params(*args, **kwargs) transaction = initiate_request_monitoring(request) if transaction is None: return wrapped(*args, **kwargs) # Call the original method in a trace object to give better context # in transaction traces. It should only every return an exception is # situation where application was being shutdown so finalize the # transaction on any error. transaction.set_transaction_name(request.uri, 'Uri', priority=1) try: with FunctionTrace(transaction, name='Request/Process', group='Python/Tornado'): result = wrapped(*args, **kwargs) except: # Catch all finalize_request_monitoring(request, *sys.exc_info()) raise else: # In the case of the response completing immediately or an # exception occuring, then finish() should have been called on # the request already. We can't just exit the transaction in the # finish() call however as will need to still pop back up # through the above function trace. So if it has been flagged # that it is finished, which Tornado does by setting the request # object in the connection to None, then we exit the transaction # here. Otherwise we setup a function trace to track wait time # for deferred and suspend monitoring. if not request_finished(request): suspend_request_monitoring(request, name='Callback/Wait') elif not request.connection.stream.writing(): finalize_request_monitoring(request) else: suspend_request_monitoring(request, name='Request/Output') return result
def transaction_aware(wrapped, instance, args, kwargs): # Variables from the outer scope are not assignable in a closure, # so we use a mutable object to hold the transaction, so we can # change it if we need to. inner_transaction = transaction[0] if inner_transaction is not None: # Callback run outside the main thread must not affect the cache if inner_transaction.thread_id != current_thread_id(): return fxn(*args, **kwargs) if inner_transaction is not None and inner_transaction._is_finalized: inner_transaction = None transaction[0] = None with TransactionContext(inner_transaction): if inner_transaction is None: # A transaction will be None for fxns scheduled on the ioloop # not associated with a transaction. ret = fxn(*args, **kwargs) elif should_trace is False: try: ret = fxn(*args, **kwargs) except: record_exception(sys.exc_info()) wrapped._nr_recorded_exception = True raise else: name = callable_name(fxn_for_name) with FunctionTrace(inner_transaction, name=name) as ft: try: ret = fxn(*args, **kwargs) except: record_exception(sys.exc_info()) wrapped._nr_recorded_exception = True raise # Coroutines are wrapped in lambdas when they are # scheduled. See tornado.gen.Runner.run(). In this # case, we don't know the name until the function # is run. We only know it then because we pass # out the name as an attribute on the result. # We update the name now. if hasattr(fxn, '_nr_coroutine_name'): ft.name = fxn._nr_coroutine_name # If decrementing the ref count in Runner.run() takes it to 0, then # we need to end the transaction here. if inner_transaction: possibly_finalize_transaction(inner_transaction) return ret
def _requesthandler_function_trace(wrapped, instance, args, kwargs): # Use this function tracer when a function you want to trace is called # synchronously from a function that is already in the transaction, such as # web.RequestHandler._execute. transaction = retrieve_current_transaction() name = callable_name(wrapped) with FunctionTrace(transaction, name=name): return wrapped(*args, **kwargs)
async def trace_in_cache_txn_active(asyncio, bg): event = asyncio.Event() with BackgroundTask(application(), 'fg'): with FunctionTrace('fg') as _: task = asyncio.ensure_future(bg(event)) await event.wait() return task
def callback_wrapper(wrapped, instance, args, kwargs): name = callable_name(wrapped) transaction = current_transaction(active_only=False) if transaction and (transaction.ignore_transaction or transaction.stopped): return wrapped(*args, **kwargs) elif transaction: with FunctionTrace(name=name): return wrapped(*args, **kwargs) else: if hasattr(channel, '_nr_disable_txn_tracing'): return wrapped(*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 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 return wrapped(*args, **kwargs)
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) with FunctionTrace(transaction, name=instance.name, group='Template/Block'): return wrapped(*args, **kwargs)
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) with FunctionTrace(transaction, name=name): callback, param_dict = wrapped(*args, **kwargs) return (wrap_view_handler(callback, priority=priority), param_dict)
def test_trace_after_end_of_transaction(caplog): end_of_transaction() with FunctionTrace("foobar"): pass error_messages = [ record for record in caplog.records if record.levelno >= logging.ERROR ] assert not error_messages
def render_wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) name = callable_name(wrapped) with FunctionTrace(transaction, name=name): return wrapped(*args, **kwargs)