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)
Beispiel #3
0
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 _nr_wrapper_httpclient_AsyncHTTPClient_fetch_(wrapped, instance, args,
                                                  kwargs):

    transaction = retrieve_current_transaction()

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

    url = _extract_url(*args, **kwargs)

    # If callback is not passed in to fetch, we don't see its default value,
    # None, in args or kwargs. If callback exists we extract it now and replace
    # it with a wrapped version to associate the url with the callback.
    @function_wrapper
    def _wrap_callback(wrapped, instance, args, kwargs):
        name = callable_name(wrapped)
        name = "%s [%s]" % (name, url)
        with FunctionTrace(transaction, name=name):
            return wrapped(*args, **kwargs)

    if len(args) > 1:
        args = list(args)
        args[1] = _wrap_callback(args[1])
    elif 'callback' in kwargs:
        kwargs['callback'] = _wrap_callback(kwargs['callback'])

    with ExternalTrace(transaction, 'tornado.httpclient', url):
        return wrapped(*args, **kwargs)
Beispiel #5
0
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
Beispiel #6
0
def _nr_wrapper_httpclient_HTTPClient_fetch_(wrapped, instance, args, kwargs):

    transaction = retrieve_current_transaction()

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

    req = _prepare_request(*args, **kwargs)

    # Prepare outgoing CAT headers
    outgoing_headers = ExternalTrace.generate_request_headers(transaction)
    for header_name, header_value in outgoing_headers:
        req.headers.add(header_name, header_value)

    with ExternalTrace(transaction, 'tornado.httpclient', req.url) as trace:
        response = wrapped(req)
        # Process CAT response headers
        trace.process_response_headers(response.headers.get_all())
        return response
def _nr_wrapper_httpclient_HTTPClient_fetch_(wrapped, instance, args, kwargs):

    transaction = retrieve_current_transaction()

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

    url = _extract_url(*args, **kwargs)

    with ExternalTrace(transaction, 'tornado.httpclient', url):
        return wrapped(*args, **kwargs)
Beispiel #8
0
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)
Beispiel #9
0
def _nr_wrapper_httpclient_AsyncHTTPClient_fetch_(wrapped, instance, args,
                                                  kwargs):

    transaction = retrieve_current_transaction()

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

    def _prepare_async_req(request, callback=None, raise_error=True, **kwargs):
        return _prepare_request(request, **kwargs), callback, raise_error

    req, _cb, _raise_error = _prepare_async_req(*args, **kwargs)

    # Prepare outgoing CAT headers
    outgoing_headers = ExternalTrace.generate_request_headers(transaction)
    for header_name, header_value in outgoing_headers:
        req.headers.add(header_name, header_value)

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

    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)
        transaction._ref_count -= 1

    transaction._ref_count += 1
    trace.__enter__()

    future = wrapped(req, _cb, _raise_error)
    future.add_done_callback(external_trace_done)
    return future
    def _nr_wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

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

        url = bind_params_fn(*args, **kwargs)

        details = urlparse.urlparse(url)

        if details.hostname is None:
            return wrapped(*args, **kwargs)

        with ExternalTrace(transaction, library, url):
            return wrapped(*args, **kwargs)
Beispiel #11
0
def wrapper_GearmanClient_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 = 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_opener_director_open_(wrapped, instance, args, kwargs):
    transaction = current_transaction()

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

    def _bind_params(fullurl, *args, **kwargs):
        if isinstance(fullurl, six.string_types):
            return fullurl
        else:
            return fullurl.get_full_url()

    url = _bind_params(*args, **kwargs)

    details = urlparse.urlparse(url)

    if details.hostname is None:
        return wrapped(*args, **kwargs)

    with ExternalTrace(transaction, 'urllib2', url):
        return wrapped(*args, **kwargs)
def _nr_endpoint_make_request_(wrapped, instance, args, kwargs):

    transaction = current_transaction()

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

    def _bind_params(operation_model, request_dict, *args, **kwargs):
        return request_dict

    # Get url and strip everything but scheme, hostname, and port.

    request_dict = _bind_params(*args, **kwargs)
    full_url = request_dict.get('url', '')
    parsed = urlparse.urlparse(full_url)
    url = '%s://%s' % (parsed.scheme, parsed.netloc)

    # Get HTTP verb as method
    method = request_dict.get('method', None)

    with ExternalTrace(transaction, library='botocore', url=url,
            method=method):
        return wrapped(*args, **kwargs)