Skip to content

Commit ad65494

Browse files
TimPansinolrafeeiumaannamalai
authored
Code Level Metrics (CodeStream) (#513)
* Initial experiment Co-authored-by: Lalleh Rafeei <[email protected]> * Expand source code testing * Move source code context to traces * Add source context to external traces * First pass at finalizing attributes * Inspection tweaking * Attribute cacheing Co-authored-by: Lalleh Rafeei <[email protected]> * Add initial source context setting. * Revert "Add initial source context setting." This reverts commit 1512e19. * Move source code context init Co-authored-by: Uma Annamalai <[email protected]> Co-authored-by: Lalleh Rafeei <[email protected]> * Add setting to gate attribute collection. * Add source code node * Add database trace source context * Add error trace attributes * Add source code context to transaction types * Fix settings in timetrace enter * Fix function traces in flask Co-authored-by: Lalleh Rafeei <[email protected]> Co-authored-by: Uma Annamalai <[email protected]> * Remove attributes from transactions * Instrument django with source context * Update all traces to include source context kwargs * Wire source context into wsgi applications * Source context instrumentation updates * Wire source context into sentinels * Add framework instrumentation updates. * Swap FunctionTrace for FunctionTraceWrapper (or modify FunctionTrace to include "source") * Finish framework instrumentation updates * Add source to MessageTrace. * Add setting override for source context tests Co-authored-by: Lalleh Rafeei <[email protected]> * Fix validate_database_trace_inputs validator Co-authored-by: Lalleh Rafeei <[email protected]> Co-authored-by: Uma Annamalai <[email protected]> * Fix redis wrappers * Add source context to pika instrumentation. * Fix failing tests * Fix asyncpg wrappers * Add source context to SolrTrace. * Add source context to strawberry * Fix strawberry versions * Update Twisted framework instrumentation with source context. * Clean up code * More code cleanup * Enable codestream attributes by default * Fix Django CBV dispatch wrapper. * TEMP: update agent version guessing logic. * Fix django rest CBV dispatch wrapper. * Add better discovery and testing for builtins Co-authored-by: Lalleh Rafeei <[email protected]> Co-authored-by: Uma Annamalai <[email protected]> * Update agent version. * Fix gRPC web transaction source issue. * Rename to code level metrics * Add testing for code level metrics * Rename extract function * Fix extraction of objects and class types * Add testing for tornado Co-authored-by: Uma Annamalai <[email protected]> * Add flask testing * Add grpc testing * Fix celery instrumentation * Add starlette testing * Fastapi tests * Falcon tests * Django rest testing * Aiohttp tests * Starting django tests * Add CodeStream spans for GraphQL * Fix pyramid golden signals * Add cherrypy testing * Correct flask rest views Co-authored-by: Uma Annamalai <[email protected]> * Fix sanic golden signals * Fix partials inspection for code level metrics * Add pika codestream tests * Add django codestream tests * Remove beta versioning logic. * Patch pika tests for py2 * Fix Py2 issues * Pin grpc of agent_streaming py27 * Standardize all python workflows * Fix graphql 2 middleware double wrapping * Fix graphql span counts * Fix flask dependencies * More exact pypy versions * Fix tox running in pypy * Rearrange python versions * Move pypy3 to 3.6 * Update cross agent tests for AWS * Fix PyPy code level metrics tests * Fix flask blueprints tests * Fix graphqlserver tests * Patch py27 django rest tests * Fix py2 syntax * Fix py2 metrics for flaskrest Co-authored-by: Lalleh Rafeei <[email protected]> Co-authored-by: Uma Annamalai <[email protected]> Co-authored-by: Uma Annamalai <[email protected]> Co-authored-by: Lalleh Rafeei <[email protected]>
1 parent 367e57b commit ad65494

File tree

103 files changed

+1290
-623
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+1290
-623
lines changed

.github/workflows/tests.yml

Lines changed: 234 additions & 245 deletions
Large diffs are not rendered by default.

newrelic/api/asgi_application.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ async def send_inject_browser_agent(self, message):
215215

216216

217217
class ASGIWebTransaction(WebTransaction):
218-
def __init__(self, application, scope, receive, send):
218+
def __init__(self, application, scope, receive, send, source=None):
219219
self.receive = receive
220220
self._send = send
221221
scheme = scope.get("scheme", "http")
@@ -237,6 +237,7 @@ def __init__(self, application, scope, receive, send):
237237
request_path=request_path,
238238
query_string=query_string,
239239
headers=headers,
240+
source=source,
240241
)
241242

242243
if self._settings:
@@ -314,6 +315,7 @@ async def nr_async_asgi(receive, send):
314315
scope=scope,
315316
receive=receive,
316317
send=send,
318+
source=wrapped,
317319
) as transaction:
318320

319321
# Record details of framework against the transaction for later

newrelic/api/background_task.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424

2525
class BackgroundTask(Transaction):
2626

27-
def __init__(self, application, name, group=None):
27+
def __init__(self, application, name, group=None, source=None):
2828

2929
# Initialise the common transaction base class.
3030

31-
super(BackgroundTask, self).__init__(application)
31+
super(BackgroundTask, self).__init__(application, source=source)
3232

3333
# Mark this as a background task even if disabled.
3434

@@ -97,7 +97,7 @@ def create_transaction(transaction):
9797

9898
return None
9999

100-
return BackgroundTask(_application, _name, _group)
100+
return BackgroundTask(_application, _name, _group, source=wrapped)
101101

102102
proxy = async_proxy(wrapped)
103103

newrelic/api/database_trace.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ def __init__(
6868
database_name=None,
6969
**kwargs
7070
):
71-
parent = None
71+
parent = kwargs.pop("parent", None)
72+
source = kwargs.pop("source", None)
7273
if kwargs:
73-
if len(kwargs) > 1:
74-
raise TypeError("Invalid keyword arguments:", kwargs)
75-
parent = kwargs["parent"]
76-
super(DatabaseTrace, self).__init__(parent)
74+
raise TypeError("Invalid keyword arguments:", kwargs)
75+
76+
super(DatabaseTrace, self).__init__(parent=parent, source=source)
7777

7878
self.sql = sql
7979

@@ -260,7 +260,7 @@ def _nr_database_trace_wrapper_(wrapped, instance, args, kwargs):
260260
else:
261261
_sql = sql
262262

263-
trace = DatabaseTrace(_sql, dbapi2_module, parent=parent)
263+
trace = DatabaseTrace(_sql, dbapi2_module, parent=parent, source=wrapped)
264264

265265
if wrapper: # pylint: disable=W0125,W0126
266266
return wrapper(wrapped, trace)(*args, **kwargs)

newrelic/api/datastore_trace.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,12 @@ class DatastoreTrace(TimeTrace):
5656
"""
5757

5858
def __init__(self, product, target, operation, host=None, port_path_or_id=None, database_name=None, **kwargs):
59-
parent = None
59+
parent = kwargs.pop("parent", None)
60+
source = kwargs.pop("source", None)
6061
if kwargs:
61-
if len(kwargs) > 1:
62-
raise TypeError("Invalid keyword arguments:", kwargs)
63-
parent = kwargs["parent"]
64-
super(DatastoreTrace, self).__init__(parent)
62+
raise TypeError("Invalid keyword arguments:", kwargs)
63+
64+
super(DatastoreTrace, self).__init__(parent=parent, source=source)
6565

6666
self.instance_reporting_enabled = False
6767
self.database_name_enabled = False
@@ -187,7 +187,7 @@ def _nr_datastore_trace_wrapper_(wrapped, instance, args, kwargs):
187187
else:
188188
_operation = operation
189189

190-
trace = DatastoreTrace(_product, _target, _operation, parent=parent)
190+
trace = DatastoreTrace(_product, _target, _operation, parent=parent, source=wrapped)
191191

192192
if wrapper: # pylint: disable=W0125,W0126
193193
return wrapper(wrapped, trace)(*args, **kwargs)

newrelic/api/external_trace.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@
2323

2424
class ExternalTrace(CatHeaderMixin, TimeTrace):
2525
def __init__(self, library, url, method=None, **kwargs):
26-
parent = None
26+
parent = kwargs.pop("parent", None)
27+
source = kwargs.pop("source", None)
2728
if kwargs:
28-
if len(kwargs) > 1:
29-
raise TypeError("Invalid keyword arguments:", kwargs)
30-
parent = kwargs["parent"]
31-
super(ExternalTrace, self).__init__(parent)
29+
raise TypeError("Invalid keyword arguments:", kwargs)
30+
31+
super(ExternalTrace, self).__init__(parent=parent, source=source)
3232

3333
self.library = library
3434
self.url = url
@@ -94,7 +94,7 @@ def dynamic_wrapper(wrapped, instance, args, kwargs):
9494
else:
9595
_method = method
9696

97-
trace = ExternalTrace(library, _url, _method, parent=parent)
97+
trace = ExternalTrace(library, _url, _method, parent=parent, source=wrapped)
9898

9999
if wrapper: # pylint: disable=W0125,W0126
100100
return wrapper(wrapped, trace)(*args, **kwargs)
@@ -111,7 +111,7 @@ def literal_wrapper(wrapped, instance, args, kwargs):
111111
else:
112112
parent = None
113113

114-
trace = ExternalTrace(library, url, method, parent=parent)
114+
trace = ExternalTrace(library, url, method, parent=parent, source=wrapped)
115115

116116
if wrapper: # pylint: disable=W0125,W0126
117117
return wrapper(wrapped, trace)(*args, **kwargs)

newrelic/api/function_trace.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@
2323

2424
class FunctionTrace(TimeTrace):
2525
def __init__(self, name, group=None, label=None, params=None, terminal=False, rollup=None, **kwargs):
26-
parent = None
26+
parent = kwargs.pop("parent", None)
27+
source = kwargs.pop("source", None)
2728
if kwargs:
28-
if len(kwargs) > 1:
29-
raise TypeError("Invalid keyword arguments:", kwargs)
30-
parent = kwargs["parent"]
31-
super(FunctionTrace, self).__init__(parent)
29+
raise TypeError("Invalid keyword arguments:", kwargs)
30+
31+
super(FunctionTrace, self).__init__(parent=parent, source=source)
3232

3333
# Handle incorrect groupings and leading slashes. This will
3434
# cause an empty segment which we want to avoid. In that case
@@ -138,7 +138,7 @@ def dynamic_wrapper(wrapped, instance, args, kwargs):
138138
else:
139139
_params = params
140140

141-
trace = FunctionTrace(_name, _group, _label, _params, terminal, rollup, parent=parent)
141+
trace = FunctionTrace(_name, _group, _label, _params, terminal, rollup, parent=parent, source=wrapped)
142142

143143
if wrapper: # pylint: disable=W0125,W0126
144144
return wrapper(wrapped, trace)(*args, **kwargs)
@@ -157,7 +157,7 @@ def literal_wrapper(wrapped, instance, args, kwargs):
157157

158158
_name = name or callable_name(wrapped)
159159

160-
trace = FunctionTrace(_name, group, label, params, terminal, rollup, parent=parent)
160+
trace = FunctionTrace(_name, group, label, params, terminal, rollup, parent=parent, source=wrapped)
161161

162162
if wrapper: # pylint: disable=W0125,W0126
163163
return wrapper(wrapped, trace)(*args, **kwargs)

newrelic/api/graphql_trace.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@
2323

2424
class GraphQLOperationTrace(TimeTrace):
2525
def __init__(self, **kwargs):
26-
parent = None
26+
parent = kwargs.pop("parent", None)
27+
source = kwargs.pop("source", None)
2728
if kwargs:
28-
if len(kwargs) > 1:
29-
raise TypeError("Invalid keyword arguments:", kwargs)
30-
parent = kwargs["parent"]
31-
super(GraphQLOperationTrace, self).__init__(parent)
29+
raise TypeError("Invalid keyword arguments:", kwargs)
30+
31+
super(GraphQLOperationTrace, self).__init__(parent=parent, source=source)
3232

3333
self.operation_name = "<anonymous>"
3434
self.operation_type = "<unknown>"
@@ -114,7 +114,7 @@ def _nr_graphql_trace_wrapper_(wrapped, instance, args, kwargs):
114114
else:
115115
parent = None
116116

117-
trace = GraphQLOperationTrace(parent=parent)
117+
trace = GraphQLOperationTrace(parent=parent, source=wrapped)
118118

119119
if wrapper: # pylint: disable=W0125,W0126
120120
return wrapper(wrapped, trace)(*args, **kwargs)
@@ -135,7 +135,13 @@ def wrap_graphql_operation_trace(module, object_path):
135135

136136
class GraphQLResolverTrace(TimeTrace):
137137
def __init__(self, field_name=None, **kwargs):
138-
super(GraphQLResolverTrace, self).__init__(**kwargs)
138+
parent = kwargs.pop("parent", None)
139+
source = kwargs.pop("source", None)
140+
if kwargs:
141+
raise TypeError("Invalid keyword arguments:", kwargs)
142+
143+
super(GraphQLResolverTrace, self).__init__(parent=parent, source=source)
144+
139145
self.field_name = field_name
140146
self._product = None
141147

@@ -192,7 +198,7 @@ def _nr_graphql_trace_wrapper_(wrapped, instance, args, kwargs):
192198
else:
193199
parent = None
194200

195-
trace = GraphQLResolverTrace(parent=parent)
201+
trace = GraphQLResolverTrace(parent=parent, source=wrapped)
196202

197203
if wrapper: # pylint: disable=W0125,W0126
198204
return wrapper(wrapped, trace)(*args, **kwargs)

newrelic/api/memcache_trace.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222

2323
class MemcacheTrace(TimeTrace):
2424
def __init__(self, command, **kwargs):
25-
parent = None
25+
parent = kwargs.pop("parent", None)
26+
source = kwargs.pop("source", None)
2627
if kwargs:
27-
if len(kwargs) > 1:
28-
raise TypeError("Invalid keyword arguments:", kwargs)
29-
parent = kwargs["parent"]
30-
super(MemcacheTrace, self).__init__(parent)
28+
raise TypeError("Invalid keyword arguments:", kwargs)
29+
30+
super(MemcacheTrace, self).__init__(parent=parent, source=source)
3131

3232
self.command = command
3333

@@ -69,7 +69,7 @@ def _nr_wrapper_memcache_trace_(wrapped, instance, args, kwargs):
6969
else:
7070
_command = command
7171

72-
trace = MemcacheTrace(_command, parent=parent)
72+
trace = MemcacheTrace(_command, parent=parent, source=wrapped)
7373

7474
if wrapper: # pylint: disable=W0125,W0126
7575
return wrapper(wrapped, trace)(*args, **kwargs)

newrelic/api/message_trace.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,12 @@ class MessageTrace(CatHeaderMixin, TimeTrace):
2929
cat_synthetics_key = "NewRelicSynthetics"
3030

3131
def __init__(self, library, operation, destination_type, destination_name, params=None, **kwargs):
32-
33-
parent = None
32+
parent = kwargs.pop("parent", None)
33+
source = kwargs.pop("source", None)
3434
if kwargs:
35-
if len(kwargs) > 1:
36-
raise TypeError("Invalid keyword arguments:", kwargs)
37-
parent = kwargs["parent"]
38-
super(MessageTrace, self).__init__(parent)
35+
raise TypeError("Invalid keyword arguments:", kwargs)
36+
37+
super(MessageTrace, self).__init__(parent=parent, source=source)
3938

4039
self.library = library
4140
self.operation = operation
@@ -132,7 +131,7 @@ def _nr_message_trace_wrapper_(wrapped, instance, args, kwargs):
132131
else:
133132
_destination_name = destination_name
134133

135-
trace = MessageTrace(_library, _operation, _destination_type, _destination_name, params={}, parent=parent)
134+
trace = MessageTrace(_library, _operation, _destination_type, _destination_name, params={}, parent=parent, source=wrapped)
136135

137136
if wrapper: # pylint: disable=W0125,W0126
138137
return wrapper(wrapped, trace)(*args, **kwargs)

0 commit comments

Comments
 (0)