Syntax
newrelic.agent.function_trace(name=None, group=None, label=None, params=None, terminal=False)
Used to instrument functions, methods, generators, and coroutines that aren't instrumented by default.
Description
function_trace
is a decorator for adding to functions, methods, generators, and coroutines. Adding this decorator lets you collect additional transaction information (including transaction trace information). (An alternate way to instrument functions without having to touch your app code is to list them in the config file.)
function_trace
does not give you a full profile of all the functions that happen in a decorated function. What it does is add the decorated function as a node in the New Relic UI and capture the time spent in that function. If you need more detail about what is going on in that function, you would need to also apply the function trace to the function's child functions.
The function_trace
decorator can be used on generators and coroutines with agent version 2.102.0.85 or higher. Timing of these objects begins when consumption starts, and ends when the object is exhausted or goes out of scope. This is a change from earlier versions where the metric represented the time taken to create the generator or coroutine object itself.
You can use the decorator in conjunction with existing decorators, including those for static and class methods. When nesting multiple decorators, have the function_trace
decorator as the outermost decorator.
Importante
For any decorators that are being wrapped, use functools.wraps()
from the Python standard library in their implementation. (Or, otherwise ensure that the decorator propagates the correct name attributes of the innermost wrapped object required to allow correct name introspection.) If this is not done, then when the metric is reported, the name of the nested decorator function (not the innermost wrapped function) will be used.
Alternate call forms
For setups where you cannot use the decorator, these alternate call forms are available:
The context manager
The FunctionTrace
context manager is used when the parameters to be passed cannot be determined before runtime. (For example, you may not know the name of a function at import time.) When using the context manager to name a metric, you must always supply the name and the metric path prefix.
The FunctionTrace
class implements the context manager and is used in conjunction with the with
statement. The FunctionTrace
class is the lowest level primitive available for tracing time against a transaction.
The with
statement defines the bounds of what is timed and not a single function. Thus, the context manager could be applied to an arbitrary block of code. The block of code could therefore contain calls to multiple functions, or it could be a self-contained block of code implementing a time-oriented algorithm that you want to track.
Importante
Avoid tracing blocks of code that are called an excessive number of times. For example, do not use it within the context of a loop that executes many times. The data generated will incur a performance overhead. A better solution is to enclose the loop.
The wrapper
If you know in advance where the specific functions you want to trace are, you could use the function_trace
decorator. However, if you don't know all the functions that need to be traced (for example, if they're being looked up dynamically as part of a routing system), then you must use the FunctionTraceWrapper
to wrap the function at the time of registration or at the time of calling.
Path-based wrapping
wrap_function_trace
is used for wrapping functions outside of the code they're declared in. For example: you might use this to instrument library code that you don't want to modify.
For more about the differences between these call formats, see Different call formats.
Parameters
Parameters for decorator
newrelic.agent.function_trace(name=None, group=None, label=None, params=None, terminal=False)
This call includes these parameters:
Parameter | Description |
---|---|
string | Optional. The function name. If not set, defaults to the captured name of the function. |
string | Optional. The If not supplied, the group will default to |
string | Optional. Adds a callout-style flag to the segment in a transaction trace. Default is |
dict | Optional. Custom parameters to add to the segment in transaction traces. |
boolean | Optional. If true, no children segments will be recorded. Default is False. |
Parameters for context manager
newrelic.agent.FunctionTrace(name, group=None, label=None, params=None, terminal=False)
Parameters for the context manager includes all of the parameters from function_trace
. The name
parameter is required and not optional.
Parameter | Description |
---|---|
string | Required. The function name. |
Wrapper parameters
newrelic.agent.FunctionTraceWrapper(wrapped, name=None, group=None, label=None, params=None, terminal=False)
Parameters for the wrapper include all parameters for function_trace
and a wrapped
parameter:
Parameter | Description |
---|---|
function | Required. The function being wrapped. |
Path-based wrapping parameters
newrelic.agent.wrap_function_trace(module, object_path, name=None, group=None, label=None, params=None, terminal=False)
Parameters include all parameters for function_trace
and these parameters:
Parameter | Description |
---|---|
object | Required. The module containing the function to be instrumented. |
string | The path to the location of the function. |
Examples
function_trace
example
An example of using the function_trace
decorator:
import newrelic.agent
class _Database(UserDict.DictMixin):
...
@newrelic.agent.function_trace() def _commit(self): ...
@newrelic.agent.function_trace()def open(file, flag=None, mode=0666):...
An example of using the function_trace
decorator with native coroutines:
import newrelic.agent
class _Database(UserDict.DictMixin):
...
@newrelic.agent.function_trace() async def _commit(self): ...
@newrelic.agent.function_trace()async def open(file, flag=None, mode=0666):...
Context manager example
An example of using the FunctionTrace
context manager:
import newrelic.agent
def dispatch_request(self, request): adapter = self.url_map.bind_to_environ(request.environ) try: endpoint, values = adapter.match() function = getattr(self, 'on_' + endpoint) with newrelic.agent.FunctionTrace( endpoint, 'Python/EndPoint'): return function(request, <DNT>**values) except HTTPException as e: return e
Wrapper example
An example of using the FunctionTraceWrapper
:
URL routing with Werkzeug yields a name that is used first to dynamically look up a method of a class using getattr()
and the result then invoked:
def dispatch_request(self, request): adapter = self.url_map.bind_to_environ(request.environ) try: endpoint, values = adapter.match() return getattr(self, 'on_' + endpoint)(request, **</DNT>values) except HTTPException as e: return e
If you want to trace the endpoint function, you can rewrite this as:
import newrelic.agent
def dispatch_request(self, request): adapter = self.url_map.bind_to_environ(request.environ) try: endpoint, values = adapter.match() function = getattr(self, 'on_' + endpoint) function = newrelic.agent.FunctionTraceWrapper(function) return function(request, <DNT>**values) except HTTPException as e: return e
If you want to name the metric after the endpoint name (rather than naming the metric based on the identifier for the function being called), you can supply the name to use plus an alternate metric path prefix when the FunctionTraceWrapper
object is created.
import newrelic.agent
def dispatch_request(self, request): adapter = self.url_map.bind_to_environ(request.environ) try: endpoint, values = adapter.match() function = getattr(self, 'on_' + endpoint) function = newrelic.agent.FunctionTraceWrapper( function, name=endpoint, group='Python/EndPoint') return function(request, **</DNT>values) except HTTPException as e: return e
For this example, if the endpoint were called help
, the final metric would be:
Python/EndPoint/help
In the performance breakdown for a transaction, the category would be Python
and the segment name EndPoint/help
. That segment name would also appear in slow transaction traces as the node name.