def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() def _wrapped(request, view_func, view_args, view_kwargs): # This strips the view handler wrapper before call. if hasattr(view_func, '_nr_last_object'): view_func = view_func._nr_last_object return wrapped(request, view_func, view_args, view_kwargs) if transaction is None: return _wrapped(*args, **kwargs) before = (transaction.name, transaction.group) with FunctionTrace(transaction, name=name): try: return _wrapped(*args, **kwargs) finally: # We want to name the transaction after this # middleware but only if the transaction wasn't # named from within the middleware itself explicity. after = (transaction.name, transaction.group) if before == after: transaction.name_transaction(name, priority=2)
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) def _args(request, *args, **kwargs): return request view = instance request = _args(*args, **kwargs) # We can't intercept the delegated view handler when it # is looked up by the dispatch() method so we need to # duplicate the lookup mechanism. if request.method.lower() in view.http_method_names: handler = getattr(view, request.method.lower(), view.http_method_not_allowed) else: handler = view.http_method_not_allowed name = callable_name(handler) transaction.set_transaction_name(name) with FunctionTrace(transaction, name=name): return wrapped(*args, **kwargs)
def 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)
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)
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)
def on_connection_close_wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction: return wrapped(*args, **kwargs) handler = instance request = handler.request transaction = getattr(request, '_nr_transaction', None) if not transaction: return wrapped(*args, **kwargs) transaction.save_transaction() if request._nr_wait_function_trace: request._nr_wait_function_trace.__exit__(None, None, None) name = callable_name(wrapped) try: with FunctionTrace(transaction, name): return wrapped(*args, **kwargs) except Exception: transaction.record_exception(*sys.exc_info()) finally: transaction.__exit__(None, None, None)
def 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)
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 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)
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)
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 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)
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()
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)
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 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)
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
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())
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
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)
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_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)
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
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()
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)
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)
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)
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
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)
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)
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))
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)
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)
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
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
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, )
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)
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
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
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
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)
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)
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()
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
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
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)
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)
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()
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
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)
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
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