Skip to content

Commit 5a3431f

Browse files
authored
Adds instrumentation for aiomcache (#1173)
1 parent 8890cde commit 5a3431f

File tree

5 files changed

+174
-0
lines changed

5 files changed

+174
-0
lines changed

newrelic/config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3201,6 +3201,11 @@ def _process_module_builtin_defaults():
32013201
"newrelic.hooks.datastore_pymemcache",
32023202
"instrument_pymemcache_client",
32033203
)
3204+
_process_module_definition(
3205+
"aiomcache.client",
3206+
"newrelic.hooks.datastore_aiomcache",
3207+
"instrument_aiomcache_client",
3208+
)
32043209

32053210
_process_module_definition("jinja2.environment", "newrelic.hooks.template_jinja2")
32063211

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from newrelic.api.datastore_trace import wrap_datastore_trace
2+
3+
_memcache_client_methods = (
4+
"get",
5+
"gets",
6+
"get_multi",
7+
"set",
8+
"cas",
9+
"set_multi",
10+
"add",
11+
"replace",
12+
"delete",
13+
"delete_multi",
14+
"incr",
15+
"decr",
16+
"flush_all",
17+
"stats",
18+
)
19+
20+
21+
def instrument_aiomcache_client(module):
22+
for name in _memcache_client_methods:
23+
if hasattr(module.Client, name):
24+
wrap_datastore_trace(module, "Client.%s" % name, product="Memcached", target=None, operation=name)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
16+
from testing_support.fixtures import ( # noqa: F401; pylint: disable=W0611
17+
collector_agent_registration_fixture,
18+
collector_available_fixture,
19+
)
20+
21+
_default_settings = {
22+
"package_reporting.enabled": False, # Turn off package reporting for testing as it causes slow downs.
23+
"transaction_tracer.explain_threshold": 0.0,
24+
"transaction_tracer.transaction_threshold": 0.0,
25+
"transaction_tracer.stack_trace_threshold": 0.0,
26+
"debug.log_data_collector_payloads": True,
27+
"debug.record_transaction_failure": True,
28+
}
29+
30+
collector_agent_registration = collector_agent_registration_fixture(
31+
app_name="Python Agent Test (datastore_aiomcache)",
32+
default_settings=_default_settings,
33+
linked_applications=["Python Agent Test (datastore)"],
34+
)
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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+
import os
16+
17+
import aiomcache
18+
from testing_support.db_settings import memcached_settings
19+
from testing_support.validators.validate_transaction_metrics import (
20+
validate_transaction_metrics,
21+
)
22+
23+
from newrelic.api.background_task import background_task
24+
from newrelic.api.transaction import set_background_task
25+
26+
from testing_support.validators.validate_transaction_metrics import validate_transaction_metrics
27+
from testing_support.fixture.event_loop import event_loop as loop
28+
29+
DB_SETTINGS = memcached_settings()[0]
30+
31+
MEMCACHED_HOST = DB_SETTINGS["host"]
32+
MEMCACHED_PORT = DB_SETTINGS["port"]
33+
MEMCACHED_NAMESPACE = str(os.getpid())
34+
35+
_test_bt_set_get_delete_scoped_metrics = [
36+
("Datastore/operation/Memcached/set", 1),
37+
("Datastore/operation/Memcached/get", 1),
38+
("Datastore/operation/Memcached/delete", 1),
39+
]
40+
41+
_test_bt_set_get_delete_rollup_metrics = [
42+
("Datastore/all", 3),
43+
("Datastore/allOther", 3),
44+
("Datastore/Memcached/all", 3),
45+
("Datastore/Memcached/allOther", 3),
46+
("Datastore/operation/Memcached/set", 1),
47+
("Datastore/operation/Memcached/get", 1),
48+
("Datastore/operation/Memcached/delete", 1),
49+
]
50+
51+
52+
@validate_transaction_metrics(
53+
"test_aiomcache:test_bt_set_get_delete",
54+
scoped_metrics=_test_bt_set_get_delete_scoped_metrics,
55+
rollup_metrics=_test_bt_set_get_delete_rollup_metrics,
56+
background_task=True,
57+
)
58+
@background_task()
59+
def test_bt_set_get_delete(loop):
60+
set_background_task(True)
61+
client = aiomcache.Client(host=MEMCACHED_HOST, port=MEMCACHED_PORT)
62+
63+
key = (MEMCACHED_NAMESPACE + "key").encode()
64+
data = "value".encode()
65+
66+
loop.run_until_complete(client.set(key, data))
67+
value = loop.run_until_complete(client.get(key))
68+
loop.run_until_complete(client.delete(key))
69+
70+
assert value == data
71+
72+
73+
_test_wt_set_get_delete_scoped_metrics = [
74+
("Datastore/operation/Memcached/set", 1),
75+
("Datastore/operation/Memcached/get", 1),
76+
("Datastore/operation/Memcached/delete", 1),
77+
]
78+
79+
_test_wt_set_get_delete_rollup_metrics = [
80+
("Datastore/all", 3),
81+
("Datastore/allWeb", 3),
82+
("Datastore/Memcached/all", 3),
83+
("Datastore/Memcached/allWeb", 3),
84+
("Datastore/operation/Memcached/set", 1),
85+
("Datastore/operation/Memcached/get", 1),
86+
("Datastore/operation/Memcached/delete", 1),
87+
]
88+
89+
90+
@validate_transaction_metrics(
91+
"test_aiomcache:test_wt_set_get_delete",
92+
scoped_metrics=_test_wt_set_get_delete_scoped_metrics,
93+
rollup_metrics=_test_wt_set_get_delete_rollup_metrics,
94+
background_task=False,
95+
)
96+
@background_task()
97+
def test_wt_set_get_delete(loop):
98+
set_background_task(False)
99+
client = aiomcache.Client(host=MEMCACHED_HOST, port=MEMCACHED_PORT)
100+
101+
key = (MEMCACHED_NAMESPACE + "key").encode()
102+
data = "value".encode()
103+
104+
loop.run_until_complete(client.set(key, data))
105+
value = loop.run_until_complete(client.get(key))
106+
loop.run_until_complete(client.delete(key))
107+
108+
assert value == data

tox.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ envlist =
5757
kafka-messagebroker_kafkapython-{py27,py38}-kafkapython{020001,020000},
5858
kafka-messagebroker_kafkapython-{pypy27,py27,py37,py38,pypy310}-kafkapythonlatest,
5959
memcached-datastore_bmemcached-{pypy27,py27,py37,py38,py39,py310,py311,py312}-memcached030,
60+
memcached-datastore_aiomcache-{py38,py39,py310,py311,py312}-memcached030,
6061
memcached-datastore_memcache-{py37,py38,py39,py310,py311,py312,pypy310}-memcached01,
6162
memcached-datastore_pylibmc-{py27,py37},
6263
memcached-datastore_pymemcache-{py27,py37,py38,py39,py310,py311,py312,pypy27,pypy310},
@@ -240,6 +241,7 @@ deps =
240241
cross_agent: mock==1.0.1
241242
cross_agent: requests
242243
datastore_asyncpg: asyncpg
244+
datastore_aiomcache-memcached030: aiomcache
243245
datastore_bmemcached-memcached030: python-binary-memcached<0.31
244246
datastore_bmemcached-memcached030: uhashring<2.0
245247
datastore_elasticsearch: requests
@@ -455,6 +457,7 @@ changedir =
455457
cross_agent: tests/cross_agent
456458
datastore_asyncpg: tests/datastore_asyncpg
457459
datastore_bmemcached: tests/datastore_bmemcached
460+
datastore_aiomcache: tests/datastore_aiomcache
458461
datastore_elasticsearch: tests/datastore_elasticsearch
459462
datastore_firestore: tests/datastore_firestore
460463
datastore_memcache: tests/datastore_memcache

0 commit comments

Comments
 (0)