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.set_transaction_name(name, priority=2)
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, priority=4) with FunctionTrace(transaction, name=name): return wrapped(*args, **kwargs)
def retrieve_current_transaction(): # Retrieves the current transaction regardless of whether it has # been stopped or ignored. We sometimes want to purge the current # transaction from the transaction cache and remove it with the # known current transaction that is being called into asynchronously. return current_transaction(active_only=False)
def httplib_getresponse_wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) connection = instance tracer = getattr(connection, '_nr_external_tracer', None) if not tracer: return wrapped(*args, **kwargs) response = wrapped(*args, **kwargs) # Make sure we remove the tracer from the connection object so that it # doesn't hold onto objects. Do this after we call the wrapped function so # if an exception occurs the higher library might retry the call again with # the same connection object. Both urllib3 and requests do this in Py2.7 del connection._nr_external_tracer if hasattr(tracer, 'process_response_headers'): tracer.process_response_headers(response.getheaders()) return response
def wrapper_GearmanConnectionManager_handle_function(wrapped, instance, args, kwargs): def _bind_params(current_connection, *args, **kwargs): return current_connection transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) tracer = transaction.active_node() if not isinstance(tracer, ExternalTrace): return wrapped(*args, **kwargs) # Now override the URL for the external to be the specific server we # ended up communicating with. This could get overridden multiple # times in the context of a single poll_connections_until_stopped() # call and so will be set to the last server data was processed for. # This thus may not necessarily be correct if commnicating with # multiple servers and data from more than one was being handled for # some reason. Can't really do much better than this though but will # be fine for the expected typical use case of a single server. if not tracer.url.startswith('gearman:'): return wrapped(*args, **kwargs) current_connection = _bind_params(*args, **kwargs) tracer.url = 'gearman://%s:%s' % (current_connection.gearman_host, current_connection.gearman_port) return wrapped(*args, **kwargs)
def _wrapper(context, request): transaction = current_transaction() if not transaction: return wrapper(context, request) name = callable_name(view) with FunctionTrace(transaction, name=name) as tracer: try: return wrapper(context, request) finally: attr = instance.attr if attr: inst = getattr(request, '__view__') name = callable_name(getattr(inst, attr)) transaction.set_transaction_name(name, priority=1) tracer.name = name else: inst = getattr(request, '__view__') method = getattr(inst, '__call__') if method: name = callable_name(method) transaction.set_transaction_name(name, priority=1) tracer.name = name
def _nr_wrapper_Elasticsearch_method_(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) # When arg_extractor is None, it means there is no target field # associated with this method. Hence this method will only # create an operation metric and no statement metric. This is # handled by setting the target to None when calling the # DatastoreTrace. if arg_extractor is None: index = None else: index = arg_extractor(*args, **kwargs) if prefix: operation = '%s.%s' % (prefix, name) else: operation = name with DatastoreTrace(transaction, product='Elasticsearch', target=index, operation=operation): return wrapped(*args, **kwargs)
def wrapper_RoutesDispatcher_find_handler(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) try: # Call the original wrapped function to find the handler. handler = wrapped(*args, **kwargs) except: # Catch all # Can end up here when the URL was invalid in some way. transaction.record_exception() raise if handler: # Should be the actual handler, wrap it with the handler # wrapper. handler = handler_wrapper(handler) else: # No handler could be found so name the web transaction # after the 404 status code. transaction.set_transaction_name('404', group='StatusCode') return handler
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 callproc(self, procname, parameters=DEFAULT): transaction = current_transaction() with DatabaseTrace(transaction, "CALL %s" % procname, self._nr_dbapi2_module): if parameters is not DEFAULT: return self.__wrapped__.callproc(procname, parameters) else: return self.__wrapped__.callproc(procname)
def _nr_wrapper_httplib2_connect_wrapper_inner(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) def _connect_unbound(instance, *args, **kwargs): return instance if instance is None: instance = _connect_unbound(*args, **kwargs) connection = instance url = '%s://%s:%s' % (scheme, connection.host, connection.port) with ExternalTrace(transaction, library='httplib2', url=url) as tracer: # Add the tracer to the connection object. The tracer will be # used in getresponse() to add back into the external trace, # after the trace has already completed, details from the # response headers. connection._nr_external_tracer = tracer return wrapped(*args, **kwargs)
def httplib_endheaders_wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) connection = instance # Check if the NR headers have already been added. This is just in # case a higher level library which uses httplib underneath so # happened to have been instrumented to also add the headers. try: skip_headers = getattr(connection, '_nr_skip_headers', False) if skip_headers: return wrapped(*args, **kwargs) outgoing_headers = ExternalTrace.generate_request_headers(transaction) for header_name, header_value in outgoing_headers: connection.putheader(header_name, header_value) return wrapped(*args, **kwargs) finally: try: del connection._nr_skip_headers except AttributeError: pass
def httplib_connect_wrapper(wrapped, instance, args, kwargs, scheme, library): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) def _connect_unbound(instance, *args, **kwargs): return instance if instance is None: instance = _connect_unbound(*args, **kwargs) connection = instance url = '%s://%s:%s' % (scheme, connection.host, connection.port) with ExternalTrace(transaction, library=library, url=url) as tracer: # Add the tracer to the connection object. The tracer will be # used in getresponse() to add back into the external trace, # after the trace has already completed, details from the # response headers. connection._nr_external_tracer = tracer return wrapped(*args, **kwargs)
def _nr_wrapper_HTTP1Connection_write_headers_(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) # Only add response headers when we're a server! if instance.is_client: return wrapped(*args, **kwargs) def _bind_params(start_line, headers, *args, **kwargs): return start_line, headers start_line, headers = _bind_params(*args, **kwargs) try: http_status = start_line[1] except: cat_headers = [] else: cat_headers = transaction.process_response(http_status, headers) for k, v in cat_headers: headers.add(k, v) return wrapped(*args, **kwargs)
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 httplib_endheaders_wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) connection = instance # Check if the NR headers have already been added. This is just in # case a higher level library which uses httplib underneath so # happened to have been instrumented to also add the headers. try: skip_headers = getattr(connection, "_nr_skip_headers", False) if skip_headers: return wrapped(*args, **kwargs) outgoing_headers = ExternalTrace.generate_request_headers(transaction) for header_name, header_value in outgoing_headers: connection.putheader(header_name, header_value) return wrapped(*args, **kwargs) finally: try: del connection._nr_skip_headers except AttributeError: pass
def httplib_getresponse_wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) connection = instance tracer = getattr(connection, "_nr_external_tracer", None) if not tracer: return wrapped(*args, **kwargs) response = wrapped(*args, **kwargs) # Make sure we remove the tracer from the connection object so that it # doesn't hold onto objects. Do this after we call the wrapped function so # if an exception occurs the higher library might retry the call again with # the same connection object. Both urllib3 and requests do this in Py2.7 del connection._nr_external_tracer if hasattr(tracer, "process_response_headers"): tracer.process_response_headers(response.getheaders()) return response
def wrapper(*args, **kwargs): if agent and agent.current_transaction() is None: with agent.BackgroundTask(agent.application(), name=name, group=group): return func(*args, **kwargs) else: return func(*args, **kwargs)
def callproc(self, procname, parameters=DEFAULT): transaction = current_transaction() with DatabaseTrace(transaction, 'CALL %s' % procname, self._nr_dbapi2_module): if parameters is not DEFAULT: return self.__wrapped__.callproc(procname, parameters) else: return self.__wrapped__.callproc(procname)
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 execute(self, sql, parameters=DEFAULT): transaction = current_transaction() if parameters is not DEFAULT: with DatabaseTrace(transaction, sql, self._nr_dbapi2_module, self._nr_connect_params, None, parameters): return self.__wrapped__.execute(sql, parameters) else: with DatabaseTrace(transaction, sql, self._nr_dbapi2_module, self._nr_connect_params): return self.__wrapped__.execute(sql)
def retrieve_current_transaction(): # Retrieves the current transaction regardless of whether it has # been stopped or ignored. We can't just return the current # transaction gated by whether the transaction has been stopped or # is being ignored as that would screw things up because of all the # funny checks we need to do against the transaction when resuming a # transaction and so on. return current_transaction(active_only=False)
def newrelic_external_trace(url, method): """ This context manager map an external transaction to newrelic :param url: Url to be mapped in newrelic :param method: Method to be mapped in newrelic """ transaction = current_transaction() with ExternalTrace(transaction, 'tornado.httpclient', url, method): yield
def __call__(self, *args, **kwargs): transaction = current_transaction() with FunctionTrace(transaction, callable_name(self.__wrapped__), terminal=True, rollup='Database/all'): return self.__connection_wrapper__( self.__wrapped__(*args, **kwargs), self._nr_dbapi2_module, (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 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_AWSAuthConnection_make_request(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) url = '%s://%s%s' % (instance.protocol, instance.host, instance.path) with ExternalTrace(transaction, 'boto', url): return wrapped(*args, **kwargs)
def _wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) transaction.set_transaction_name(name, priority=2) with FunctionTrace(transaction, name=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._nr_dbapi2_module): return self.__wrapped__.__exit__(exc, value, tb) else: with DatabaseTrace(transaction, "ROLLBACK", self._nr_dbapi2_module): return self.__wrapped__.__exit__(exc, value, tb)
def _wrapper(*args, **kargs): transaction = current_transaction() if transaction is None: return method(*args, **kargs) # name = "{0}:{1}".format(controller_name, action_name) # name = callable_name(wrapped) # console.debug(name) transaction.set_transaction_name(name) with FunctionTrace(transaction, name, group="Python"): return method(*args, **kargs)
def _nr_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 __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._nr_dbapi2_module, self._nr_connect_params, None)
def __exit__(self, exc, value, tb): transaction = current_transaction() name = callable_name(self.__wrapped__.__exit__) with FunctionTrace(transaction, name): if exc is None and value is None and tb is None: with DatabaseTrace(transaction, 'COMMIT', self._nr_dbapi2_module): return self.__wrapped__.__exit__(exc, value, tb) else: with DatabaseTrace(transaction, 'ROLLBACK', self._nr_dbapi2_module): return self.__wrapped__.__exit__(exc, value, tb)
def __exit__(self, exc, value, tb): transaction = current_transaction() name = callable_name(self.__wrapped__.__exit__) with FunctionTrace(transaction, name): if exc is None and value is None and tb is None: with DatabaseTrace(transaction, 'COMMIT', self._nr_dbapi2_module, self._nr_connect_params): return self.__wrapped__.__exit__(exc, value, tb) else: with DatabaseTrace(transaction, 'ROLLBACK', self._nr_dbapi2_module, self._nr_connect_params): return self.__wrapped__.__exit__(exc, value, tb)
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 _nr_wrapper_make_request_(wrapped, instance, args, kwargs): def _bind_params(conn, method, url, *args, **kwargs): return "http://%s" % conn.host transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) url_for_apm_ui = _bind_params(*args, **kwargs) with ExternalTrace(transaction, 'urllib3', url_for_apm_ui): return wrapped(*args, **kwargs)
def wrapper_Dispatcher_find_handler(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) try: # Call the original wrapped function to find the handler. obj, vpath = wrapped(*args, **kwargs) except: # Catch all # Can end up here when a custom _cp_dispatch() method is # used and that raises an exception. transaction.record_exception() raise if obj: if instance.__class__.__name__ == 'MethodDispatcher': # We initially name the web transaction as if the # corresponding method for the HTTP method will not # be found and the request will not be allowed. This # will be overridden with the actual handler name # when the subsequent wrapper around the handler is # executed. transaction.set_transaction_name('405', group='StatusCode') # We have to use a custom object proxy here in order # to intercept accesses made by the dispatcher on the # returned object, after this function returns, to # retrieve the method of the object corresponding to # the HTTP method. For each such access we wrap what # is returned in the handler wrapper. obj = ResourceProxy(obj) else: # Should be the actual handler, wrap it with the # handler wrapper. obj = handler_wrapper(obj) else: # No handler could be found so name the web transaction # after the 404 status code. transaction.set_transaction_name('404', group='StatusCode') return obj, vpath
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 newrelic_external_trace(url, method): """ This context manager map an external transaction to newrelic :param url: Url to be mapped in newrelic :param method: Method to be mapped in newrelic """ transaction = current_transaction() with ExternalTrace( transaction, 'tornado.httpclient', url, method ): yield
def __call__(self, *args, **kwargs): transaction = current_transaction() settings = global_settings() rollup = [] rollup.append('Datastore/all') rollup.append('Datastore/%s/all' % self._nr_dbapi2_module._nr_database_product) with FunctionTrace(transaction, callable_name(self.__wrapped__), terminal=True, rollup=rollup): return self.__connection_wrapper__(self.__wrapped__( *args, **kwargs), self._nr_dbapi2_module, (args, kwargs))