Exemplo n.º 1
0
        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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    def generate_headers_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        transaction._thread_utilization_start = None

        status = '%d ???' % instance.get_status()

        # The HTTPHeaders class with get_all() only started to
        # be used in Tornado 3.0. For older versions have to fall
        # back to combining the dictionary and list of headers.

        try:
            response_headers = instance._headers.get_all()

        except AttributeError:
            try:
                response_headers = itertools.chain(
                        instance._headers.items(),
                        instance._list_headers)

            except AttributeError:
                response_headers = itertools.chain(
                        instance._headers.items(),
                        instance._headers)

        additional_headers = transaction.process_response(
                status, response_headers, *args)

        for name, value in additional_headers:
            instance.add_header(name, value)

        return wrapped(*args, **kwargs)
Exemplo n.º 4
0
    def dynamic_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        if callable(url):
            if instance and inspect.ismethod(wrapped):
                _url = url(instance, *args, **kwargs)
            else:
                _url = url(*args, **kwargs)

        else:
            _url = url

        if callable(method):
            if instance and inspect.ismethod(wrapped):
                _method = method(instance, *args, **kwargs)
            else:
                _method = method(*args, **kwargs)

        else:
            _method = method

        with ExternalTrace(transaction, library, _url, _method):
            return wrapped(*args, **kwargs)
Exemplo n.º 5
0
    def error_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is not None:
            record_exception(transaction, sys.exc_info())

        return wrapped(*args, **kwargs)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    def dynamic_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        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

        if callable(group):
            if instance and inspect.ismethod(wrapped):
                _group = group(instance, *args, **kwargs)
            else:
                _group = group(*args, **kwargs)

        else:
            _group = group

        transaction.name_transaction(_name, _group, priority)

        return wrapped(*args, **kwargs)
Exemplo n.º 8
0
        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)
Exemplo n.º 9
0
    def literal_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        with ExternalTrace(transaction, library, url, method):
            return wrapped(*args, **kwargs)
    def template_generate_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        with FunctionTrace(transaction, name=instance.name, group="Template/Render"):
            return wrapped(*args, **kwargs)
Exemplo n.º 11
0
    def wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        with ErrorTrace(transaction, ignore_errors):
            return wrapped(*args, **kwargs)
Exemplo n.º 12
0
    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)
Exemplo n.º 13
0
    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)
Exemplo n.º 14
0
        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()
Exemplo n.º 15
0
    def literal_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        _name = name or callable_name(wrapped)

        with FunctionTrace(transaction, _name, group, label, params):
            return wrapped(*args, **kwargs)
Exemplo n.º 16
0
    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)
Exemplo n.º 17
0
    def literal_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        _name = name or callable_name(wrapped)

        transaction.name_transaction(_name, group, priority)

        return wrapped(*args, **kwargs)
Exemplo n.º 18
0
    def finish_request_wrapper(wrapped, instance, args, kwargs):
        assert instance is not None

        request = instance._request

        transaction = current_transaction()

        if transaction:
            request._nr_request_finished = True

            try:
                result = wrapped(*args, **kwargs)

                if (hasattr(request, '_nr_wait_function_trace') and
                        request._nr_wait_function_trace):
                    request._nr_wait_function_trace.__exit__(None, None, None)

            finally:
                request._nr_wait_function_trace = None

            return result

        else:
            if not hasattr(request, '_nr_transaction'):
                return wrapped(*args, **kwargs)

            transaction = request._nr_transaction

            if transaction is None:
                return wrapped(*args, **kwargs)

            transaction.save_transaction()

            request._nr_request_finished = True

            try:
                result = wrapped(*args, **kwargs)

                if request._nr_wait_function_trace:
                    request._nr_wait_function_trace.__exit__(None, None, None)

                transaction.__exit__(None, None, None)

            except:  # Catch all
                transaction.__exit__(*sys.exc_info())
                raise

            finally:
                request._nr_wait_function_trace = None
                request._nr_transaction = None

            return result
Exemplo n.º 19
0
    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.name_transaction(name, group, priority=4)

        with FunctionTrace(transaction, name, group):
            try:
                return inner_fn(*args, **kwargs)
            except:
                transaction.record_exception(*sys.exc_info())
Exemplo n.º 20
0
    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(transaction, name=name):
            try:
                return wrapped(*args, **kwargs)

            except:  # Catch all
                transaction.record_exception(ignore_errors=should_ignore)
                raise
Exemplo n.º 21
0
    def dynamic_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        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

        if callable(group):
            if instance and inspect.ismethod(wrapped):
                _group = group(instance, *args, **kwargs)
            else:
                _group = group(*args, **kwargs)

        else:
            _group = group

        if callable(label):
            if instance and inspect.ismethod(wrapped):
                _label = label(instance, *args, **kwargs)
            else:
                _label = label(*args, **kwargs)

        else:
            _label = label

        if callable(params):
            if instance and inspect.ismethod(wrapped):
                _params = params(instance, *args, **kwargs)
            else:
                _params = params(*args, **kwargs)

        else:
            _params = params

        with FunctionTrace(transaction, _name, _group, _label, _params):
            return wrapped(*args, **kwargs)
Exemplo n.º 22
0
    def wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        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)

        # 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)
Exemplo n.º 23
0
def _nr_sanic_response_get_headers(wrapped, instance, args, kwargs):
    # We call the wrapped function twice to allow the function to mutate the headers
    result = wrapped(*args, **kwargs)
    transaction = current_transaction()

    if transaction is None:
        return result

    # instance is the response object
    cat_headers = transaction.process_response(str(instance.status),
            instance.headers.items())

    for header_name, header_value in cat_headers:
        if header_name not in instance.headers:
            instance.headers[header_name] = header_value

    return wrapped(*args, **kwargs)
Exemplo n.º 24
0
    def get(self, status, default=None):
        transaction = current_transaction()

        if transaction is None:
            return self.__wrapped__.get(status, default)

        handler = self.__wrapped__.get(status)

        if handler:
            name = callable_name(handler)
            transaction.set_transaction_name(name, priority=1)
            handler = FunctionTraceWrapper(handler, name=name)
        else:
            transaction.set_transaction_name(str(status),
                    group='StatusCode', priority=1)

        return handler or default
Exemplo n.º 25
0
    def _test():
        transaction = current_transaction()
        transaction._sampled = True

        with trace_type(*args):
            try:
                raise RuntimeError("whoaa")
            except:
                notice_error()
            try:
                raise RuntimeError("whoo")
            except:
                notice_error()
            try:
                raise ValueError("whoops")
            except:
                notice_error()
Exemplo n.º 26
0
def test_async_cross_process_request(httpx, server, loop, distributed_tracing,
                                     span_events):
    @override_application_settings({
        "distributed_tracing.enabled": distributed_tracing,
        "span_events.enabled": span_events,
    })
    async def _test():
        async with httpx.AsyncClient() as client:
            response = await client.get("http://localhost:%s" % server.port)

        return response

    transaction = current_transaction()
    response = loop.run_until_complete(_test())
    transaction._test_request_headers = response.request.headers

    assert response.status_code == 200
    def literal_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        _name = name or callable_name(wrapped)

        trace = FunctionTrace(transaction, _name, group, label, params,
                              terminal, rollup)

        proxy = async_proxy(wrapped)
        if proxy:
            return proxy(wrapped(*args, **kwargs), TraceContext(trace))

        with trace:
            return wrapped(*args, **kwargs)
Exemplo n.º 28
0
def _nr_Connection_send_command_wrapper_(wrapped, instance, args, kwargs):
    transaction = current_transaction()

    if transaction is None or not args:
        return wrapped(*args, **kwargs)

    host, port_path_or_id, db = (None, None, None)

    try:
        dt = transaction.settings.datastore_tracer
        if (dt.instance_reporting.enabled
                or dt.database_name_reporting.enabled):
            conn_kwargs = _conn_attrs_to_dict(instance)
            host, port_path_or_id, db = _instance_info(conn_kwargs)
    except:
        pass

    transaction._nr_datastore_instance_info = (host, port_path_or_id, db)

    # Older Redis clients would when sending multi part commands pass
    # them in as separate arguments to send_command(). Need to therefore
    # detect those and grab the next argument from the set of arguments.

    operation = args[0].strip().lower()

    # If it's not a multi part command, there's no need to trace it, so
    # we can return early.

    if operation.split()[0] not in _redis_multipart_commands:
        return wrapped(*args, **kwargs)

    # Convert multi args to single arg string

    if operation in _redis_multipart_commands and len(args) > 1:
        operation = '%s %s' % (operation, args[1].strip().lower())

    operation = _redis_operation_re.sub('_', operation)

    with DatastoreTrace(transaction,
                        product='Redis',
                        target=None,
                        operation=operation,
                        host=host,
                        port_path_or_id=port_path_or_id,
                        database_name=db):
        return wrapped(*args, **kwargs)
Exemplo n.º 29
0
def _nr_wrapper_Flask_handle_exception_(wrapped, instance, args, kwargs):
    transaction = current_transaction()

    if transaction is None:
        return wrapped(*args, **kwargs)

    # The Flask.handle_exception() method is always called in the
    # context of the except clause of the try block. We can therefore
    # rely on grabbing current exception details so we have access to
    # the addition stack trace information.

    transaction.record_exception(ignore_errors=should_ignore)

    name = callable_name(wrapped)

    with FunctionTrace(name):
        return wrapped(*args, **kwargs)
Exemplo n.º 30
0
def _nr_wrapper_httpclient_AsyncHTTPClient_fetch_(wrapped, instance, args,
                                                  kwargs):

    transaction = current_transaction()

    if transaction is None:
        return wrapped(*args, **kwargs)

    try:
        req, _cb, _raise_error = _prepare_request(*args, **kwargs)
    except:
        return wrapped(*args, **kwargs)

    # Prepare outgoing CAT headers
    outgoing_headers = ExternalTrace.generate_request_headers(transaction)
    for header_name, header_value in outgoing_headers:
        # User headers should override our CAT headers
        if header_name in req.headers:
            continue
        req.headers[header_name] = header_value

    trace = ExternalTrace(transaction, 'tornado.httpclient', req.url,
                          req.method.upper())

    def external_trace_done(future):
        exc_info = future.exc_info()
        if exc_info:
            trace.__exit__(*exc_info)
        else:
            response = future.result()
            # Process CAT response headers
            trace.process_response_headers(response.headers.get_all())
            trace.__exit__(None, None, None)

    trace.__enter__()
    if trace.transaction and trace.transaction.current_node is trace:
        # externals should not have children
        trace.transaction._pop_current(trace)

    try:
        future = wrapped(req, _cb, _raise_error)
        future.add_done_callback(external_trace_done)
    except Exception:
        trace.__exit__(*sys.exc_info())
        raise
    return future
Exemplo n.º 31
0
    def wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        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)

        # 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 _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)
    if view_class:
        try:
            method = args[0].method.lower()
            name = callable_name(view_class) + '.' + method
        except:
            pass
    transaction.set_transaction_name(name, priority=3)

    return function_trace(name=name)(wrapped)(*args, **kwargs)
Exemplo n.º 33
0
    def _test():
        # Always mark sampled as True. current_transaction() is guaranteed to
        # be non-None here as test fixtures ensure activation prior to testing.
        current_transaction()._sampled = True

        reply = method(request)

        if isinstance(reply, tuple):
            reply = reply[0]

        try:
            # If the reply was canceled or the server code raises an exception,
            # this will raise an exception which will be recorded by the agent
            if streaming_response:
                reply = list(reply)
            else:
                reply = [reply.result()]
        except (AttributeError, TypeError):
            reply = [reply]

        metadata = json.loads(reply[0].text)

        if not dt_enabled or dt_error:
            assert 'newrelic' not in metadata
            assert 'traceparent' not in metadata
            assert 'tracestate' not in metadata
        else:
            decoded = DistributedTracePayload.decode(metadata['newrelic'])

            # The external span should be the parent
            exact_intrinsics['guid'] = decoded['d']['id']

            # Check that tracestate / traceparent payload matches newrelic
            # payload
            w3c_data = W3CTraceParent.decode(metadata['traceparent'])
            nr_tracestate = list(
                W3CTraceState.decode(metadata['tracestate']).values())[0]
            nr_tracestate = NrTraceState.decode(nr_tracestate, None)
            w3c_data.update(nr_tracestate)

            # Remove all trust keys
            decoded['d'].pop('tk', None)
            w3c_data.pop('tk')

            assert decoded['d'] == w3c_data
def wrapper_GearmanConnectionManager_poll_connections_until_stopped(
        wrapped, instance, args, kwargs):

    def _bind_params(submitted_connections, *args, **kwargs):
        return submitted_connections

    transaction = current_transaction()

    if transaction is None:
        return wrapped(*args, **kwargs)

    # Because gearman uses a custom message based protocol over a raw
    # socket, we can't readily wrap a single function which is
    # performing a request and then returning a response. The best we
    # can do is wrap as an external the poll_connections_until_stopped()
    # function. This is what manages looking for whether data is
    # available from the server, or whether data can be written, and
    # then handles those events.
    #
    # This is complicated somewhat though due to a gearman client being
    # able to be supplied multiple servers to communicate with. We can
    # not actually determine which server communication will occur with
    # until the specific handle function for read, write or error is
    # called but that is too late in cases where a failure of some sort
    # occurs such as a timeout. What we therefore do is presume
    # initially that the server will be whatever is the first in the
    # list of server connections and we will override this latter based
    # on which server we ended up communicating with. It is possible this
    # still will not always be correct if data is handled for multiple
    # servers in the one call, but it is likely as close as we can get.
    # As likely that most clients will only be talking to a single
    # server, it likely will not matter too much.

    submitted_connections = _bind_params(*args, **kwargs)

    if not submitted_connections:
        return wrapped(*args, **kwargs)

    first_connection = list(submitted_connections)[0]

    url = 'gearman://%s:%s' % (first_connection.gearman_host,
            first_connection.gearman_port)

    with ExternalTrace(transaction, 'gearman', url):
        return wrapped(*args, **kwargs)
def _nr_wrapper_basic_publish(wrapped, instance, args, kwargs):
    transaction = current_transaction()

    if transaction is None:
        return wrapped(*args, **kwargs)

    from pika import BasicProperties

    (exchange, routing_key, body, properties, mandatory,
     immediate) = (_bind_basic_publish(*args, **kwargs))
    properties = properties or BasicProperties()
    properties.headers = properties.headers or {}
    user_headers = properties.headers.copy()

    # Do not record cat headers in the segment parameters
    if MessageTrace.cat_id_key in user_headers:
        del user_headers[MessageTrace.cat_id_key]
    if MessageTrace.cat_transaction_key in user_headers:
        del user_headers[MessageTrace.cat_transaction_key]
    if MessageTrace.cat_distributed_trace_key in user_headers:
        del user_headers[MessageTrace.cat_distributed_trace_key]

    args = (exchange, routing_key, body, properties, mandatory, immediate)

    params = {}
    if routing_key is not None:
        params['routing_key'] = routing_key
    if properties.correlation_id is not None:
        params['correlation_id'] = properties.correlation_id
    if properties.reply_to is not None:
        params['reply_to'] = properties.reply_to
    if user_headers:
        params['headers'] = user_headers

    with MessageTrace(transaction,
                      library='RabbitMQ',
                      operation='Produce',
                      destination_type='Exchange',
                      destination_name=exchange or 'Default',
                      params=params):
        cat_headers = MessageTrace.generate_request_headers(transaction)

        for name, value in cat_headers:
            properties.headers[name] = value
        return wrapped(*args)
Exemplo n.º 36
0
    def _nr_message_trace_wrapper_(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        if callable(library):
            if instance is not None:
                _library = library(instance, *args, **kwargs)
            else:
                _library = library(*args, **kwargs)
        else:
            _library = library

        if callable(operation):
            if instance is not None:
                _operation = operation(instance, *args, **kwargs)
            else:
                _operation = operation(*args, **kwargs)
        else:
            _operation = operation

        if callable(destination_type):
            if instance is not None:
                _destination_type = destination_type(instance, *args, **kwargs)
            else:
                _destination_type = destination_type(*args, **kwargs)
        else:
            _destination_type = destination_type

        if callable(destination_name):
            if instance is not None:
                _destination_name = destination_name(instance, *args, **kwargs)
            else:
                _destination_name = destination_name(*args, **kwargs)
        else:
            _destination_name = destination_name

        trace = MessageTrace(transaction,
                             _library,
                             _operation,
                             _destination_type,
                             _destination_name,
                             params={})
        return return_value(trace, lambda: wrapped(*args, **kwargs))
Exemplo n.º 37
0
def _nr_wrapper_Flask_try_trigger_before_first_request_functions_(wrapped, instance, args, kwargs):

    transaction = current_transaction()

    if transaction is None:
        return wrapped(*args, **kwargs)

    if not instance.before_first_request_funcs:
        return wrapped(*args, **kwargs)

    if instance._got_first_request:
        return wrapped(*args, **kwargs)

    name = callable_name(wrapped)

    transaction.set_transaction_name(name)

    return FunctionTraceWrapper(wrapped, name=name)(*args, **kwargs)
Exemplo n.º 38
0
    def wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        def _wrapped(request, resolver, exc_info):
            transaction.set_transaction_name(name, priority=1)
            notice_error(exc_info)

            try:
                return wrapped(request, resolver, exc_info)

            except:  # Catch all
                notice_error()
                raise

        return FunctionTraceWrapper(_wrapped, name=name)(*args, **kwargs)
Exemplo n.º 39
0
def wrap_validate(wrapped, instance, args, kwargs):
    transaction = current_transaction()
    if transaction is None:
        return wrapped(*args, **kwargs)

    transaction.set_transaction_name(callable_name(wrapped), "GraphQL", priority=10)

    # Run and collect errors
    errors = wrapped(*args, **kwargs)

    # Raise errors and immediately catch them so we can record them
    for error in errors:
        try:
            raise error
        except:
            notice_error(ignore=ignore_graphql_duplicate_exception)

    return errors
Exemplo n.º 40
0
async def _nr_sanic_response_send(wrapped, instance, args, kwargs):
    transaction = current_transaction()
    result = wrapped(*args, **kwargs)
    if isawaitable(result):
        await result

    if transaction is None:
        return wrapped(*args, **kwargs)

    # instance is the response object
    cat_headers = transaction.process_response(str(instance.status),
            instance.headers.items())

    for header_name, header_value in cat_headers:
        if header_name not in instance.headers:
            instance.headers[header_name] = header_value

    return result
Exemplo n.º 41
0
def exercise(override_expected=None, override_ignore=None, status_code=None):
    try:
        raise RuntimeError(_error_message)
    except RuntimeError:
        if current_transaction() is not None:
            # Record exception inside transaction
            notice_error(
                expected=override_expected,
                ignore=override_ignore,
                status_code=status_code,
            )
        else:
            # Record exception outside context of transaction
            application_instance().notice_error(
                expected=override_expected,
                ignore=override_ignore,
                status_code=status_code,
            )
Exemplo n.º 42
0
def httplib_putheader_wrapper(wrapped, instance, args, kwargs):
    transaction = current_transaction()

    if transaction is None:
        return wrapped(*args, **kwargs)

    # Remember if we see any NR headers being set. This is only doing
    # it if we see either, but they should always both be getting set.

    def nr_header(header, *args, **kwargs):
        return header.upper() in ('X-NEWRELIC-ID', 'X-NEWRELIC-TRANSACTION')

    connection = instance

    if nr_header(*args, **kwargs):
        connection._nr_skip_headers = True

    return wrapped(*args, **kwargs)
    def _nr_datastore_trace_wrapper_(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        transaction._nr_datastore_instance_info = (None, None, None)

        dt = DatastoreTrace(product, target, operation)

        with dt:
            result = wrapped(*args, **kwargs)

            instance_info = transaction._nr_datastore_instance_info
            (host, port_path_or_id, db) = instance_info
            dt.host = host
            dt.port_path_or_id = port_path_or_id

            return result
    def wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        def _wrapped(request, resolver, exc_info):
            transaction.name_transaction(name, priority=1)
            transaction.record_exception(*exc_info)

            try:
                return wrapped(request, resolver, exc_info)

            except:  # Catch all
                transaction.record_exception(*sys.exc_info())
                raise

        with FunctionTrace(transaction, name=name):
            return _wrapped(*args, **kwargs)
Exemplo n.º 45
0
def handler_wrapper(wrapped, instance, args, kwargs):
    transaction = current_transaction()

    # Name the web transaction after the handler function.

    name = callable_name(wrapped)
    transaction.set_transaction_name(name=name)

    # Track how long is spent in the handler and record any exceptions
    # except those which are used for controlling the actions of the
    # application.

    with FunctionTrace(transaction, name=name):
        try:
            return wrapped(*args, **kwargs)

        except:  # Catch all
            transaction.record_exception(ignore_errors=should_ignore)
            raise
Exemplo n.º 46
0
    def _test():
        headers = {}
        if user_header:
            headers = {user_header: 'USER'}

        response = make_request(port,
                                request_type,
                                client_class,
                                headers=headers,
                                count=num_requests,
                                as_kwargs=as_kwargs)
        assert response.code == 200

        body = response.body
        if hasattr(body, 'decode'):
            body = body.decode('utf-8')

        headers = {}
        for header_line in body.split('\n'):
            if ':' not in header_line:
                continue
            header_key, header_val = header_line.split(':', 1)
            header_key = header_key.strip()
            header_val = header_val.strip()
            headers[header_key] = header_val

        # User headers override all inserted NR headers
        if user_header:
            assert headers[user_header] == 'USER'
        elif cat_enabled:
            t = current_transaction()
            assert t
            t._test_request_headers = headers

            if distributed_tracing:
                validate_distributed_tracing_header(header='Newrelic')
            else:
                validate_outbound_headers()
        else:
            # new relic shouldn't add anything to the outgoing
            assert 'x-newrelic' not in body, body

        assert 'X-NewRelic-App-Data' not in headers
Exemplo n.º 47
0
    def _future_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()
        if transaction is None:
            return wrapped(*args, **kwargs)

        guid = '%016x' % random.getrandbits(64)
        uri, method = _get_uri_method(instance)

        args, kwargs = prepare(transaction, guid, *args, **kwargs)
        future = wrapped(*args, **kwargs)
        future._nr_guid = guid
        future._nr_args = ('gRPC', uri, method)
        future._nr_start_time = time.time()

        # In non-streaming responses, result is typically called instead of
        # using the iterator. In streaming calls, the iterator is typically
        # used.

        return future
Exemplo n.º 48
0
    def wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        def _wrapped(request, resolver, exc_info):
            transaction.name_transaction(name, priority=1)
            transaction.record_exception(*exc_info)

            try:
                return wrapped(request, resolver, exc_info)

            except:  # Catch all
                transaction.record_exception(*sys.exc_info())
                raise

        with FunctionTrace(transaction, name=name):
            return _wrapped(*args, **kwargs)
Exemplo n.º 49
0
def wrap_kazoo(wrapped, instance, args, kwargs):
    transaction = current_transaction()
    host, port, db = (None, None, None)
    operation = wrapped.__name__

    if transaction is None or not args:
        return wrapped(*args, **kwargs)

    if instance._connection and instance._connection._socket:
        host, port = instance._connection._socket.getsockname()

    with DatastoreTrace(transaction,
                        product='Zookeeper',
                        target=None,
                        operation=operation,
                        host=host,
                        port_path_or_id=port,
                        database_name=db):
        return wrapped(*args, **kwargs)
Exemplo n.º 50
0
    def on_receive(ch, method, properties, msg):
        headers = properties.headers
        assert headers
        assert 'NewRelicID' not in headers
        assert 'NewRelicTransaction' not in headers
        assert msg == b'Testing distributed_tracing 123'
        txn = current_transaction()

        assert txn
        assert txn._distributed_trace_state
        assert txn.parent_type == 'App'
        assert txn._trace_id.startswith(txn.parent_tx)
        assert txn.parent_span is not None
        assert txn.parent_account == txn.settings.account_id
        assert txn.parent_transport_type == 'AMQP'
        assert txn._priority is not None
        assert txn._sampled is not None

        ch.stop_consuming()
Exemplo n.º 51
0
def wrapper_callback_function(wrapped, instance, args, kwargs):
    transaction = current_transaction()

    if transaction is None:
        return wrapped(*args, **kwargs)

    # This tracks as a separate function trace the call of the actual
    # task function so that the original function name also appears in
    # the performance breakdown. We catch exceptions and record them at
    # this point as otherwise they are caught by the gearman worker
    # dispatch code and do not actually propagate up to the level of the
    # background task wrapper.

    with FunctionTrace(transaction, callable_name(wrapped)):
        try:
            return wrapped(*args, **kwargs)
        except:  # Catch all
            transaction.record_exception()
            raise
Exemplo n.º 52
0
    def _nr_wrapper_Redis_method_(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        dt = DatastoreTrace(product='Redis', target=None, operation=operation)

        transaction._nr_datastore_instance_info = (None, None, None)

        with dt:
            result = wrapped(*args, **kwargs)

            host, port_path_or_id, db = transaction._nr_datastore_instance_info
            dt.host = host
            dt.port_path_or_id = port_path_or_id
            dt.database_name = db

            return result
Exemplo n.º 53
0
    def _nr_wrap_api_call_(wrapped, instance, args, kwargs):
        settings = global_settings()

        # agent is not initialized / enabled
        if (settings.debug.disable_api_supportability_metrics
                or not Agent._instance or not settings.enabled):
            return wrapped(*args, **kwargs)

        transaction = current_transaction()

        if transaction:
            m = transaction._transaction_metrics.get(metric_name, 0)
            transaction._transaction_metrics[metric_name] = m + 1
        else:
            agent = agent_instance()
            app_name = settings.app_name
            agent.record_custom_metric(app_name, metric_name, {'count': 1})

        return wrapped(*args, **kwargs)
Exemplo n.º 54
0
        def wrapper(wrapped, instance, args, kwargs):
            transaction = current_transaction()

            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)
Exemplo n.º 55
0
                    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 _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()
Exemplo n.º 57
0
    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:
                # 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'])
                raise

            finally:
                exc_info = None
Exemplo n.º 58
0
    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)
Exemplo n.º 59
0
    def wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if transaction is None:
            return wrapped(*args, **kwargs)

        if hasattr(transaction, '_nr_django_url_resolver'):
            return wrapped(*args, **kwargs)

        # Tag the transaction so we know when we are in the top
        # level call to the URL resolver as don't want to show
        # the inner ones as would be one for each url pattern.

        transaction._nr_django_url_resolver = True

        def _wrapped(path):
            # XXX This can raise a Resolver404. If this is not dealt
            # with, is this the source of our unnamed 404 requests.

            with FunctionTrace(transaction, name=name, label=path):
                result = wrapped(path)

                if type(result) == type(()):
                    callback, callback_args, callback_kwargs = result
                    result = (wrap_view_handler(callback, priority=3),
                            callback_args, callback_kwargs)
                else:
                    result.func = wrap_view_handler(result.func, priority=3)

                return result

        try:
            return _wrapped(*args, **kwargs)

        finally:
            del transaction._nr_django_url_resolver
Exemplo n.º 60
0
    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