Skip to content

Commit 3fb6a6c

Browse files
committed
Add async collection instrumentation
1 parent 7851baf commit 3fb6a6c

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

newrelic/config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,6 +2294,11 @@ def _process_module_builtin_defaults():
22942294
"newrelic.hooks.datastore_firestore",
22952295
"instrument_google_cloud_firestore_v1_collection",
22962296
)
2297+
_process_module_definition(
2298+
"google.cloud.firestore_v1.async_collection",
2299+
"newrelic.hooks.datastore_firestore",
2300+
"instrument_google_cloud_firestore_v1_async_collection",
2301+
)
22972302
_process_module_definition(
22982303
"google.cloud.firestore_v1.query",
22992304
"newrelic.hooks.datastore_firestore",

newrelic/hooks/datastore_firestore.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,20 @@ def instrument_google_cloud_firestore_v1_collection(module):
100100
wrap_generator_method(module, "CollectionReference", method, target=_get_object_id)
101101

102102

103+
def instrument_google_cloud_firestore_v1_async_collection(module):
104+
if hasattr(module, "AsyncCollectionReference"):
105+
class_ = module.AsyncCollectionReference
106+
for method in ("add", "get"):
107+
if hasattr(class_, method):
108+
wrap_datastore_trace(
109+
module, "AsyncCollectionReference.%s" % method, product="Firestore", target=_get_object_id, operation=method
110+
)
111+
112+
for method in ("stream", "list_documents"):
113+
if hasattr(class_, method):
114+
wrap_async_generator_method(module, "AsyncCollectionReference", method, target=_get_object_id)
115+
116+
103117
def instrument_google_cloud_firestore_v1_document(module):
104118
if hasattr(module, "DocumentReference"):
105119
class_ = module.DocumentReference
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Copyright 2010 New Relic, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from testing_support.validators.validate_transaction_metrics import validate_transaction_metrics
16+
from newrelic.api.background_task import background_task
17+
from testing_support.validators.validate_database_duration import (
18+
validate_database_duration,
19+
)
20+
21+
22+
async def _exercise_collections(async_collection):
23+
async_collection.document("DoesNotExist")
24+
await async_collection.add({"capital": "Rome", "currency": "Euro", "language": "Italian"}, "Italy")
25+
await async_collection.add({"capital": "Mexico City", "currency": "Peso", "language": "Spanish"}, "Mexico")
26+
27+
documents_get = await async_collection.get()
28+
assert len(documents_get) == 2
29+
documents_stream = [_ async for _ in async_collection.stream()]
30+
assert len(documents_stream) == 2
31+
documents_list = [_ async for _ in async_collection.list_documents()]
32+
assert len(documents_list) == 2
33+
34+
35+
def test_firestore_async_collections(loop, async_collection):
36+
_test_scoped_metrics = [
37+
("Datastore/statement/Firestore/%s/stream" % async_collection.id, 1),
38+
("Datastore/statement/Firestore/%s/get" % async_collection.id, 1),
39+
("Datastore/statement/Firestore/%s/list_documents" % async_collection.id, 1),
40+
("Datastore/statement/Firestore/%s/add" % async_collection.id, 2),
41+
]
42+
43+
_test_rollup_metrics = [
44+
("Datastore/operation/Firestore/add", 2),
45+
("Datastore/operation/Firestore/get", 1),
46+
("Datastore/operation/Firestore/stream", 1),
47+
("Datastore/operation/Firestore/list_documents", 1),
48+
("Datastore/all", 5),
49+
("Datastore/allOther", 5),
50+
]
51+
@validate_database_duration()
52+
@validate_transaction_metrics(
53+
"test_firestore_async_collections",
54+
scoped_metrics=_test_scoped_metrics,
55+
rollup_metrics=_test_rollup_metrics,
56+
background_task=True,
57+
)
58+
@background_task(name="test_firestore_async_collections")
59+
def _test():
60+
loop.run_until_complete(_exercise_collections(async_collection))
61+
62+
_test()
63+
64+
65+
@background_task()
66+
def test_firestore_async_collections_generators(loop, collection, async_collection, assert_trace_for_async_generator):
67+
collection.add({})
68+
collection.add({})
69+
assert len([_ for _ in collection.list_documents()]) == 2
70+
71+
assert_trace_for_async_generator(async_collection.stream)
72+
assert_trace_for_async_generator(async_collection.list_documents)

0 commit comments

Comments
 (0)