Skip to content

Commit ec02b06

Browse files
umaannamalailrafeeijshortznrCharlyCDeF
authored andcommitted
Add aredis method wrapper. (#488)
* Add aredis method wrapper. Co-authored-by: Lalleh Rafeei <[email protected]> Co-authored-by: Jessica Shortz <[email protected]> Co-authored-by: Charly DeFreitas <[email protected]> * Drop py310 from aredis test matrix. Co-authored-by: Lalleh Rafeei <[email protected]> Co-authored-by: Jessica Shortz <[email protected]> Co-authored-by: Charly DeFreitas <[email protected]>
1 parent 6295f25 commit ec02b06

File tree

4 files changed

+46
-196
lines changed

4 files changed

+46
-196
lines changed

Diff for: newrelic/config.py

+2
Original file line numberDiff line numberDiff line change
@@ -2547,6 +2547,8 @@ def _process_module_builtin_defaults():
25472547

25482548
_process_module_definition("solr", "newrelic.hooks.datastore_solrpy", "instrument_solrpy")
25492549

2550+
_process_module_definition("aredis.client", "newrelic.hooks.datastore_aredis", "instrument_aredis_client")
2551+
25502552
_process_module_definition(
25512553
"aredis.connection",
25522554
"newrelic.hooks.datastore_aredis",

Diff for: newrelic/hooks/datastore_aredis.py

+30-185
Original file line numberDiff line numberDiff line change
@@ -12,196 +12,41 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import re
1615

1716
from newrelic.api.datastore_trace import DatastoreTrace
1817
from newrelic.api.transaction import current_transaction
1918
from newrelic.common.object_wrapper import wrap_function_wrapper
19+
from newrelic.hooks.datastore_redis import _conn_attrs_to_dict, _instance_info, _redis_client_methods, _redis_multipart_commands, _redis_operation_re
2020

21-
_redis_client_methods = (
22-
"bgrewriteaof",
23-
"bgsave",
24-
"client_kill",
25-
"client_list",
26-
"client_getname",
27-
"client_setname",
28-
"config_get",
29-
"config_set",
30-
"config_resetstat",
31-
"config_rewrite",
32-
"dbsize",
33-
"debug_object",
34-
"echo",
35-
"flushall",
36-
"flushdb",
37-
"info",
38-
"lastsave",
39-
"object",
40-
"ping",
41-
"save",
42-
"sentinel",
43-
"sentinel_get_master_addr_by_name",
44-
"sentinel_master",
45-
"sentinel_masters",
46-
"sentinel_monitor",
47-
"sentinel_remove",
48-
"sentinel_sentinels",
49-
"sentinel_set",
50-
"sentinel_slaves",
51-
"shutdown",
52-
"slaveof",
53-
"slowlog_get",
54-
"slowlog_reset",
55-
"time",
56-
"append",
57-
"bitcount",
58-
"bitop",
59-
"bitpos",
60-
"decr",
61-
"delete",
62-
"dump",
63-
"exists",
64-
"expire",
65-
"expireat",
66-
"get",
67-
"getbit",
68-
"getrange",
69-
"getset",
70-
"incr",
71-
"incrby",
72-
"incrbyfloat",
73-
"keys",
74-
"mget",
75-
"mset",
76-
"msetnx",
77-
"move",
78-
"persist",
79-
"pexpire",
80-
"pexpireat",
81-
"psetex",
82-
"pttl",
83-
"randomkey",
84-
"rename",
85-
"renamenx",
86-
"restore",
87-
"set",
88-
"setbit",
89-
"setex",
90-
"setnx",
91-
"setrange",
92-
"strlen",
93-
"substr",
94-
"ttl",
95-
"type",
96-
"watch",
97-
"unwatch",
98-
"blpop",
99-
"brpop",
100-
"brpoplpush",
101-
"lindex",
102-
"linsert",
103-
"llen",
104-
"lpop",
105-
"lpush",
106-
"lpushx",
107-
"lrange",
108-
"lrem",
109-
"lset",
110-
"ltrim",
111-
"rpop",
112-
"rpoplpush",
113-
"rpush",
114-
"rpushx",
115-
"sort",
116-
"scan",
117-
"scan_iter",
118-
"sscan",
119-
"sscan_iter",
120-
"hscan",
121-
"hscan_inter",
122-
"zscan",
123-
"zscan_iter",
124-
"sadd",
125-
"scard",
126-
"sdiff",
127-
"sdiffstore",
128-
"sinter",
129-
"sinterstore",
130-
"sismember",
131-
"smembers",
132-
"smove",
133-
"spop",
134-
"srandmember",
135-
"srem",
136-
"sunion",
137-
"sunionstore",
138-
"zadd",
139-
"zcard",
140-
"zcount",
141-
"zincrby",
142-
"zinterstore",
143-
"zlexcount",
144-
"zrange",
145-
"zrangebylex",
146-
"zrangebyscore",
147-
"zrank",
148-
"zrem",
149-
"zremrangebylex",
150-
"zremrangebyrank",
151-
"zremrangebyscore",
152-
"zrevrange",
153-
"zrevrangebyscore",
154-
"zrevrank",
155-
"zscore",
156-
"zunionstore",
157-
"pfadd",
158-
"pfcount",
159-
"pfmerge",
160-
"hdel",
161-
"hexists",
162-
"hget",
163-
"hgetall",
164-
"hincrby",
165-
"hincrbyfloat",
166-
"hkeys",
167-
"hlen",
168-
"hset",
169-
"hsetnx",
170-
"hmset",
171-
"hmget",
172-
"hvals",
173-
"publish",
174-
"eval",
175-
"evalsha",
176-
"script_exists",
177-
"script_flush",
178-
"script_kill",
179-
"script_load",
180-
"setex",
181-
"lrem",
182-
"zadd",
183-
)
184-
185-
_redis_multipart_commands = set(["client", "cluster", "command", "config", "debug", "sentinel", "slowlog", "script"])
186-
187-
_redis_operation_re = re.compile(r"[-\s]+")
188-
189-
190-
def _conn_attrs_to_dict(connection):
191-
return {
192-
"host": getattr(connection, "host", None),
193-
"port": getattr(connection, "port", None),
194-
"path": getattr(connection, "path", None),
195-
"db": getattr(connection, "db", None),
196-
}
197-
198-
199-
def _instance_info(kwargs):
200-
host = kwargs.get("host") or "localhost"
201-
port_path_or_id = str(kwargs.get("port") or kwargs.get("path", "unknown"))
202-
db = str(kwargs.get("db") or 0)
203-
204-
return (host, port_path_or_id, db)
21+
22+
def _wrap_Aredis_method_wrapper_(module, instance_class_name, operation):
23+
async def _nr_wrapper_Aredis_method_(wrapped, instance, args, kwargs):
24+
transaction = current_transaction()
25+
if transaction is None:
26+
return await wrapped(*args, **kwargs)
27+
28+
dt = DatastoreTrace(product="Redis", target=None, operation=operation)
29+
30+
transaction._nr_datastore_instance_info = (None, None, None)
31+
32+
with dt:
33+
result = await wrapped(*args, **kwargs)
34+
35+
host, port_path_or_id, db = transaction._nr_datastore_instance_info
36+
dt.host = host
37+
dt.port_path_or_id = port_path_or_id
38+
dt.database_name = db
39+
return result
40+
41+
name = "%s.%s" % (instance_class_name, operation)
42+
wrap_function_wrapper(module, name, _nr_wrapper_Aredis_method_)
43+
44+
45+
def instrument_aredis_client(module):
46+
if hasattr(module, "StrictRedis"):
47+
for name in _redis_client_methods:
48+
if hasattr(module.StrictRedis, name):
49+
_wrap_Aredis_method_wrapper_(module, "StrictRedis", name)
20550

20651

20752
async def _nr_Connection_send_command_wrapper_(wrapped, instance, args, kwargs):

Diff for: tests/datastore_aredis/test_execute_command.py

+13-10
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
from testing_support.fixtures import (validate_transaction_metrics,
2121
override_application_settings)
22+
from testing_support.fixture.event_loop import event_loop as loop
2223
from testing_support.db_settings import redis_settings
2324
from testing_support.util import instance_hostname
2425

@@ -67,20 +68,22 @@
6768
(_instance_metric_name, None)
6869
)
6970

70-
def exercise_redis_multi_args(client):
71-
client.execute_command('CLIENT', 'LIST', parse='LIST')
71+
async def exercise_redis_multi_args(client):
72+
await client.execute_command('CLIENT', 'LIST', parse='LIST')
73+
74+
async def exercise_redis_single_arg(client):
75+
await client.execute_command('CLIENT LIST')
7276

73-
def exercise_redis_single_arg(client):
74-
client.execute_command('CLIENT LIST')
7577

7678
@override_application_settings(_enable_instance_settings)
7779
@validate_transaction_metrics(
78-
'test_execute_command:test_strict_redis_execute_command_two_args_enable',
79-
scoped_metrics=_enable_scoped_metrics,
80-
rollup_metrics=_enable_rollup_metrics,
81-
background_task=True)
80+
'test_execute_command:test_strict_redis_execute_command_two_args_enable',
81+
scoped_metrics=_enable_scoped_metrics,
82+
rollup_metrics=_enable_rollup_metrics,
83+
background_task=True)
8284
@background_task()
83-
def test_strict_redis_execute_command_two_args_enable():
85+
def test_strict_redis_execute_command_two_args_enable(loop):
8486
r = aredis.StrictRedis(host=DB_SETTINGS['host'],
8587
port=DB_SETTINGS['port'], db=0)
86-
exercise_redis_multi_args(r)
88+
loop.run_until_complete(exercise_redis_multi_args(r))
89+

Diff for: tox.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ envlist =
8484
solr-datastore_pysolr-{py27,py36,py37,py38,py39,py310,pypy,pypy3},
8585
redis-datastore_redis-{py27,py36,py37,py38,pypy,pypy3}-redis03,
8686
redis-datastore_redis-{py36,py37,py38,py39,py310,pypy3}-redis{0400,latest},
87-
redis-datastore_aredis-{py36,py37,py38,py39,py310,pypy3}-aredislatest,
87+
redis-datastore_aredis-{py36,py37,py38,py39,pypy3}-aredislatest,
8888
solr-datastore_solrpy-{py27,pypy}-solrpy{00,01},
8989
python-datastore_sqlite-{py27,py36,py37,py38,py39,py310,pypy,pypy3},
9090
memcached-datastore_umemcache-{py27,pypy},

0 commit comments

Comments
 (0)