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 __call__(self, *args): # Temporary work around due to customer calling class method # directly with 'self' as first argument. Need to work out best # practice for dealing with this. if len(args) == 2: # Assume called as unbound method with (self, request). instance, request = args else: # Assume called as bound method with (request). instance = self._bw_instance request = args[-1] assert instance != None transaction = current_transaction() if transaction is None: return self._bw_next_object(*args) # This is wrapping the render() function of the resource. We # name the function node and the web transaction after the name # of the handler function augmented with the method type for the # request. name = "%s.render_%s" % ( callable_name( instance), request.method) transaction.set_transaction_name(name, priority=1) with FunctionTrace(transaction, name): return self._bw_next_object(*args)
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, '_bw_last_object'): view_func = view_func._bw_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.set_transaction_name(name, priority=2)
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(transaction, name): 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. transaction.record_exception(ignore_errors=should_ignore) raise
def _bw_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 _bw_wrapper_Application___call__wsgi_(wrapped, instance, args, kwargs): transaction = retrieve_current_transaction() with FunctionTrace(transaction, name='Request/Process', group='Python/Cyclone'): 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): return wrapped(*args, **kwargs)
def __iter__(self): name = callable_name(self._bw_wrapped) iterable = iter(self._bw_generator) while 1: transaction = current_transaction() with FunctionTrace( transaction, name, group='Python/Twisted/Generator'): yield next(iterable)
def _bw_wrapper__RequestDispatcher_execute(wrapped, instance, args, kwargs): # This variant of the Application.__call__() wrapper is used when 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. dispatcher = instance request = dispatcher.request transaction = retrieve_current_transaction() if transaction is None: 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 return the RequestHandler instance # which the request was passed off to. It should only every return # an exception in situation where application was being shutdown so # finalize the transaction on any error. try: with FunctionTrace(transaction, name='Request/Process', group='Python/Tornado'): future = 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 future
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 __call__(self, *args, **kwargs): transaction = current_transaction() if transaction: transaction.set_transaction_name(self._bw_name, priority=self._bw_priority) with FunctionTrace(transaction, name=self._bw_name): return self._bw_wrapped(*args, **kwargs) else: return self._bw_wrapped(*args, **kwargs)
def _bw_stack_context_function_wrapper_(wrapped, instance, args, kwargs): # We can come in here with either an active transaction # or a request with a transaction bound to it. If there # is an active transaction then call the wrapped function # within function trace and return immediately. transaction = retrieve_current_transaction() if transaction is not None: name = callable_name(wrapped) with FunctionTrace(transaction, name=name): return wrapped(*args, **kwargs) # For the case of a request with a transaction bound to # it, we need to resume the transaction and then call it. # As we resumed the transaction, need to handle # suspending or finalizing it. transaction = resume_request_monitoring(request) if transaction is None: return wrapped(*args, **kwargs) try: name = callable_name(wrapped) with FunctionTrace(transaction, name=name): return wrapped(*args, **kwargs) except: # Catch all. record_exception(transaction, sys.exc_info()) raise finally: 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')
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 template_generate_wrapper(wrapped, instance, args, kwargs): transaction = retrieve_current_transaction() if transaction is None: return wrapped(*args, **kwargs) with FunctionTrace(transaction, name=instance.name, group='Template/Render'): return wrapped(*args, **kwargs)
def __call__(self, *args, **kwargs): transaction = current_transaction() settings = global_settings() rollup = 'Database/all' with FunctionTrace(transaction, callable_name(self.__wrapped__), terminal=True, rollup=rollup): return self.__connection_wrapper__(self.__wrapped__( *args, **kwargs), self._bw_dbapi2_module, (args, kwargs))
def __call__(self, template, *args, **kwargs): transaction = current_transaction() if transaction: if hasattr(template, 'filename'): name = template.filename or '<template>' with FunctionTrace(transaction, name=name, group='Template/Render'): return self.__wrapped(template, *args, **kwargs) else: return self.__wrapped(template, *args, **kwargs) else: return self.__wrapped(template, *args, **kwargs)
def _bw_wrapper_Flask_before_request_wrapped_(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) name = callable_name(wrapped) transaction.set_transaction_name(name) with FunctionTrace(transaction, name): return wrapped(*args, **kwargs)
def wrapper_Resource_method(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) name = callable_name(wrapped) transaction.set_transaction_name(name) with FunctionTrace(transaction, name): return wrapped(*args, **kwargs)
def __exit__(self, exc, value, tb): transaction = current_transaction() name = callable_name(self.__wrapped__.__exit__) with FunctionTrace(transaction, name): if exc is None: with DatabaseTrace(transaction, 'COMMIT', self._bw_dbapi2_module): return self.__wrapped__.__exit__(exc, value, tb) else: with DatabaseTrace(transaction, 'ROLLBACK', self._bw_dbapi2_module): return self.__wrapped__.__exit__(exc, value, tb)
def suspend_request_monitoring(request, name, group='Python/Tornado', terminal=True, rollup=None): # Suspend the monitoring of the transaction. We do this because # we can't rely on thread local data to separate transactions for # requests. We thus have to move it out of the way. transaction = retrieve_request_transaction(request) if transaction is None: _logger.error( 'Runtime instrumentation error. Suspending the ' 'Tornado transaction but there was no transaction cached ' 'against the request object. Report this issue to blueware ' 'support.\n%s', ''.join(traceback.format_stack()[:-1])) return # Create a function trace to track the time while monitoring of # this transaction is suspended. if request._bw_wait_function_trace: _logger.error( 'Runtime instrumentation error. Suspending the ' 'Tornado transaction when it has already been suspended. ' 'Report this issue to blueware support.\n%s', ''.join(traceback.format_stack()[:-1])) last = last_transaction_activation() if last is not None: _logger.info( 'The currently active transaction was possibly ' 'initiated or resumed from %r.', last) return if rollup is None: if tornado_settings.instrumentation.metrics.async_wait_rollup: rollup = 'Async Wait' request._bw_wait_function_trace = FunctionTrace(transaction, name=name, group=group, terminal=terminal, rollup=rollup) request._bw_wait_function_trace.__enter__() transaction.drop_transaction()
def __call__(self, environ, start_response): # Should ignore transaction here because this is the outter wrapper of # wsgi application, which means there is no transaction associate with # current request was initialized or activated at this point. if environ.get('PATH_INFO', '') in IGNORE_TRANSACTION_LIST: environ['blueware.ignore_transaction'] = True transaction = current_transaction(active_only=False) # At this point, no transaction has been initialized or activated. 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 __enter__(self): transaction = current_transaction() name = callable_name(self.__wrapped__.__enter__) with FunctionTrace(transaction, name): cursor = self.__wrapped__.__enter__() # The __enter__() method of original connection object returns # a new cursor instance for use with 'as' assignment. We need # to wrap that in a cursor wrapper otherwise we will not track # any queries done via it. return self.__cursor_wrapper__(cursor, self._bw_dbapi2_module, self._bw_connect_params, None)
def _bw_wrapper_Application___call__wsgi_(wrapped, instance, args, kwargs): # This variant of the Application.__call__() wrapper is used when it # is believed that we are being called via the WSGI application # adapter. That is, someone is trying to use the blocking subset of # the Tornado ASYNC APIs in a WSGI application. It is required that # there is already a current active transaction at this point. transaction = retrieve_current_transaction() with FunctionTrace(transaction, name='Request/Process', group='Python/Tornado'): return wrapped(*args, **kwargs)
def _bw_wrapper_Application___call__body_(wrapped, instance, args, kwargs): # This variant of the Application.__call__() wrapper is used when it # is believed that we are being called for a HTTP request where # there is request content. There should already be a transaction # associated with the Cyclone request object and also a current # active transaction. transaction = retrieve_current_transaction() with FunctionTrace(transaction, name='Request/Process', group='Python/Cyclone'): return wrapped(*args, **kwargs)
def __enter__(self): transaction = current_transaction() name = callable_name(self.__wrapped__.__enter__) with FunctionTrace(transaction, name): self.__wrapped__.__enter__() # Must return a reference to self as otherwise will be # returning the inner connection object. If 'as' is used # with the 'with' statement this will mean no longer # using the wrapped connection object and nothing will be # tracked. return self
def __iter__(self): try: with FunctionTrace(self.transaction, name='Response', group='Python/WSGI'): for item in self.generator: yield item except GeneratorExit: raise except: # Catch all self.transaction.record_exception() raise
def _bw_wrapper_Task_start_(wrapped, instance, args, kwargs): # This wrapper is used around the start() method of the Task class. # The Task class executes a callback and we track that as a function # trace, naming it after the function the Task holds. transaction = retrieve_current_transaction() if transaction is None: return wrapped(*args, **kwargs) name = callable_name(instance.func) 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) 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) # The priority to be used when naming the transaction is # bit tricky. If the transaction name is already that of # the class based view, but not the method, then we want # the name of the method to override. This can occur # where the class based view was registered directly in # urls.py as the view handler. In this case we use the # priority of 5, matching what would be used by the view # handler so that it can override the transaction name. # # If however the transaction name is unrelated, we # preferably don't want it overridden. This can happen # where the class based view was invoked explicitly # within an existing view handler. In this case we use # the priority of 4 so it will not override the view # handler name where used as the transaction name. priority = 4 if transaction.group == 'Function': if transaction.name == callable_name(view): priority = 5 transaction.set_transaction_name(name, priority=priority) with FunctionTrace(transaction, name=name): return wrapped(*args, **kwargs)
def inner_fn_wrapper(inner_fn, instance, args, kwargs): transaction = current_transaction() if transaction is None or name is None: return inner_fn(*args, **kwargs) transaction.set_transaction_name(name, group, priority=5) with FunctionTrace(transaction, name, group): try: return inner_fn(*args, **kwargs) except: # Catch all transaction.record_exception(*sys.exc_info()) raise