Skip to content

Commit 638d46b

Browse files
Julien Danjoubrettlangdon
andauthored
feat: add support for yaaredis (#2944)
Co-authored-by: Brett Langdon <[email protected]>
1 parent ffaa18b commit 638d46b

18 files changed

+534
-0
lines changed

.circleci/config.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,16 @@ jobs:
817817
docker_services: 'redis'
818818
pattern: 'aredis$'
819819
snapshot: true
820+
821+
yaaredis:
822+
<<: *machine_executor
823+
parallelism: 4
824+
steps:
825+
- run_test:
826+
docker_services: 'redis'
827+
pattern: 'yaaredis$'
828+
snapshot: true
829+
820830
redis:
821831
<<: *machine_executor
822832
parallelism: 4
@@ -995,6 +1005,7 @@ requires_tests: &requires_tests
9951005
- pyramid
9961006
- pytest
9971007
- aredis
1008+
- yaaredis
9981009
- redis
9991010
- rediscluster
10001011
- requests
@@ -1079,6 +1090,7 @@ workflows:
10791090
- pyramid: *requires_base_venvs
10801091
- pytest: *requires_base_venvs
10811092
- aredis: *requires_base_venvs
1093+
- yaaredis: *requires_base_venvs
10821094
- redis: *requires_base_venvs
10831095
- rediscluster: *requires_base_venvs
10841096
- requests: *requires_base_venvs

ddtrace/_monkey.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"pyodbc": True,
7272
"fastapi": True,
7373
"dogpile_cache": True,
74+
"yaaredis": True,
7475
}
7576

7677
_LOCK = threading.Lock()
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"""
2+
The yaaredis integration traces yaaredis requests.
3+
4+
5+
Enabling
6+
~~~~~~~~
7+
8+
The yaaredis integration is enabled automatically when using
9+
:ref:`ddtrace-run<ddtracerun>` or :ref:`patch_all()<patch_all>`.
10+
11+
Or use :ref:`patch()<patch>` to manually enable the integration::
12+
13+
from ddtrace import patch
14+
patch(yaaredis=True)
15+
16+
17+
Global Configuration
18+
~~~~~~~~~~~~~~~~~~~~
19+
20+
.. py:data:: ddtrace.config.yaaredis["service"]
21+
22+
The service name reported by default for yaaredis traces.
23+
24+
This option can also be set with the ``DD_YAAREDIS_SERVICE`` environment
25+
variable.
26+
27+
Default: ``"redis"``
28+
29+
30+
Instance Configuration
31+
~~~~~~~~~~~~~~~~~~~~~~
32+
33+
To configure particular yaaredis instances use the :ref:`Pin<Pin>` API::
34+
35+
import yaaredis
36+
from ddtrace import Pin
37+
38+
client = yaaredis.StrictRedis(host="localhost", port=6379)
39+
40+
# Override service name for this instance
41+
Pin.override(client, service="my-custom-queue")
42+
43+
# Traces reported for this client will now have "my-custom-queue"
44+
# as the service name.
45+
async def example():
46+
await client.get("my-key")
47+
"""
48+
49+
from ...utils.importlib import require_modules
50+
51+
52+
required_modules = ["yaaredis", "yaaredis.client"]
53+
54+
with require_modules(required_modules) as missing_modules:
55+
if not missing_modules:
56+
from .patch import patch
57+
58+
__all__ = ["patch"]

ddtrace/contrib/yaaredis/patch.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import yaaredis
2+
3+
from ddtrace import config
4+
from ddtrace.vendor import wrapt
5+
6+
from ...internal.utils.wrappers import unwrap
7+
from ...pin import Pin
8+
from ..redis.util import _trace_redis_cmd
9+
from ..redis.util import _trace_redis_execute_pipeline
10+
from ..redis.util import format_command_args
11+
12+
13+
config._add("yaaredis", dict(_default_service="redis"))
14+
15+
16+
def patch():
17+
"""Patch the instrumented methods"""
18+
if getattr(yaaredis, "_datadog_patch", False):
19+
return
20+
setattr(yaaredis, "_datadog_patch", True)
21+
22+
_w = wrapt.wrap_function_wrapper
23+
24+
_w("yaaredis.client", "StrictRedis.execute_command", traced_execute_command)
25+
_w("yaaredis.client", "StrictRedis.pipeline", traced_pipeline)
26+
_w("yaaredis.pipeline", "StrictPipeline.execute", traced_execute_pipeline)
27+
_w("yaaredis.pipeline", "StrictPipeline.immediate_execute_command", traced_execute_command)
28+
Pin().onto(yaaredis.StrictRedis)
29+
30+
31+
def unpatch():
32+
if getattr(yaaredis, "_datadog_patch", False):
33+
setattr(yaaredis, "_datadog_patch", False)
34+
35+
unwrap(yaaredis.client.StrictRedis, "execute_command")
36+
unwrap(yaaredis.client.StrictRedis, "pipeline")
37+
unwrap(yaaredis.pipeline.StrictPipeline, "execute")
38+
unwrap(yaaredis.pipeline.StrictPipeline, "immediate_execute_command")
39+
40+
41+
async def traced_execute_command(func, instance, args, kwargs):
42+
pin = Pin.get_from(instance)
43+
if not pin or not pin.enabled():
44+
return await func(*args, **kwargs)
45+
46+
with _trace_redis_cmd(pin, config.yaaredis, instance, args):
47+
return await func(*args, **kwargs)
48+
49+
50+
async def traced_pipeline(func, instance, args, kwargs):
51+
pipeline = await func(*args, **kwargs)
52+
pin = Pin.get_from(instance)
53+
if pin:
54+
pin.onto(pipeline)
55+
return pipeline
56+
57+
58+
async def traced_execute_pipeline(func, instance, args, kwargs):
59+
pin = Pin.get_from(instance)
60+
if not pin or not pin.enabled():
61+
return await func(*args, **kwargs)
62+
63+
cmds = [format_command_args(c) for c, _ in instance.command_stack]
64+
resource = "\n".join(cmds)
65+
with _trace_redis_execute_pipeline(pin, config.yaaredis, resource, instance):
66+
return await func(*args, **kwargs)

docs/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ contacting support.
152152
+--------------------------------------------------+---------------+----------------+
153153
| :ref:`wsgi` | \* | No |
154154
+--------------------------------------------------+---------------+----------------+
155+
| :ref:`yaaredis` | >= 2.0.0 | Yes |
156+
+--------------------------------------------------+---------------+----------------+
155157

156158

157159
.. [1] Libraries that are automatically instrumented when the

docs/integrations.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,11 @@ Vertica
393393
^^^^^^^
394394
.. automodule:: ddtrace.contrib.vertica
395395

396+
.. _yaaredis:
397+
398+
yaaredis
399+
^^^^^^^^
400+
.. automodule:: ddtrace.contrib.yaaredis
396401

397402
.. _wsgi:
398403

docs/spelling_wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,4 @@ whitelist
156156
workflow
157157
wsgi
158158
xfail
159+
yaaredis
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
features:
3+
- |
4+
Add yaaredis ≥ 2.0.0 support.

riotfile.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,18 @@ def select_pys(min_version=MIN_PYTHON_VERSION, max_version=MAX_PYTHON_VERSION):
12521252
],
12531253
},
12541254
),
1255+
Venv(
1256+
name="yaaredis",
1257+
pys=select_pys(min_version="3.6"),
1258+
command="pytest {cmdargs} tests/contrib/yaaredis",
1259+
pkgs={
1260+
"pytest-asyncio": latest,
1261+
"yaaredis": [
1262+
"~=2.0.0",
1263+
latest,
1264+
],
1265+
},
1266+
),
12551267
Venv(
12561268
name="snowflake",
12571269
command="pytest {cmdargs} tests/contrib/snowflake",

tests/contrib/yaaredis/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)