Skip to content

Commit ab6321c

Browse files
authored
chore(telemetry): add integration version to telemetry integrations payload (#6671)
This PR adds version to the APM Telemetry integrations payload. Version is added by requiring a `get_version` method for all integrations. ## Checklist - [x] Change(s) are motivated and described in the PR description. - [x] Testing strategy is described if automated tests are not included in the PR. - [x] Risk is outlined (performance impact, potential for breakage, maintainability, etc). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) are followed. If no release note is required, add label `changelog/no-changelog`. - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)). - [x] Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Title is accurate. - [x] No unnecessary changes are introduced. - [x] Description motivates each change. - [x] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [x] Testing strategy adequately addresses listed risk(s). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] Release note makes sense to a user of the library. - [x] Reviewer has explicitly acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment. - [x] Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)
1 parent aeb0191 commit ab6321c

File tree

220 files changed

+1052
-135
lines changed

Some content is hidden

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

220 files changed

+1052
-135
lines changed

ddtrace/_monkey.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,14 @@ def on_import(hook):
165165
)
166166
else:
167167
imported_module.patch()
168-
telemetry_writer.add_integration(module, True, PATCH_MODULES.get(module) is True, "")
168+
if hasattr(imported_module, "get_versions"):
169+
versions = imported_module.get_versions()
170+
for name, v in versions.items():
171+
telemetry_writer.add_integration(name, True, PATCH_MODULES.get(module) is True, "", version=v)
172+
else:
173+
version = imported_module.get_version()
174+
telemetry_writer.add_integration(module, True, PATCH_MODULES.get(module) is True, "", version=version)
175+
169176
if hasattr(imported_module, "patch_submodules"):
170177
imported_module.patch_submodules(patch_indicator)
171178

ddtrace/appsec/iast/_patches/json_tainting.py

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
_DEFAULT_ATTR = "_datadog_json_tainting_patch"
1515

1616

17+
def get_version():
18+
# type: () -> str
19+
return ""
20+
21+
1722
def unpatch_iast():
1823
# type: () -> None
1924
set_module_unpatched("json", default_attr=_DEFAULT_ATTR)

ddtrace/appsec/iast/taint_sinks/path_traversal.py

+5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ def report(cls, evidence_value=None, sources=None):
2626
super(PathTraversal, cls).report(evidence_value=evidence_value, sources=sources)
2727

2828

29+
def get_version():
30+
# type: () -> str
31+
return ""
32+
33+
2934
def unpatch_iast():
3035
# type: () -> None
3136
set_module_unpatched("builtins", default_attr="_datadog_path_traversal_patch")

ddtrace/appsec/iast/taint_sinks/weak_cipher.py

+5
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ def unpatch_iast():
5959
try_unwrap("cryptography.hazmat.primitives.ciphers", "Cipher.encryptor")
6060

6161

62+
def get_version():
63+
# type: () -> str
64+
return ""
65+
66+
6267
def patch():
6368
# type: () -> None
6469
"""Wrap hashing functions.

ddtrace/appsec/iast/taint_sinks/weak_hash.py

+5
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ def unpatch_iast():
6666
try_unwrap("Crypto.Hash.SHA1", "SHA1Hash.hexdigest")
6767

6868

69+
def get_version():
70+
# type: () -> str
71+
return ""
72+
73+
6974
def patch():
7075
# type: () -> None
7176
"""Wrap hashing functions.

ddtrace/contrib/aiobotocore/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
with require_modules(required_modules) as missing_modules:
4949
if not missing_modules:
50+
from .patch import get_version
5051
from .patch import patch
5152

52-
__all__ = ["patch"]
53+
__all__ = ["patch", "get_version"]

ddtrace/contrib/aiobotocore/patch.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from ..trace_utils import unwrap
2727

2828

29-
aiobotocore_version_str = getattr(aiobotocore, "__version__", "0.0.0")
29+
aiobotocore_version_str = getattr(aiobotocore, "__version__", "")
3030
AIOBOTOCORE_VERSION = parse_version(aiobotocore_version_str)
3131

3232
if AIOBOTOCORE_VERSION <= (0, 10, 0):
@@ -56,6 +56,11 @@
5656
)
5757

5858

59+
def get_version():
60+
# type: () -> str
61+
return aiobotocore_version_str
62+
63+
5964
def patch():
6065
if getattr(aiobotocore.client, "_datadog_patch", False):
6166
return

ddtrace/contrib/aiohttp/__init__.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,8 @@ async def home_handler(request):
8686
with require_modules(required_modules) as missing_modules:
8787
if not missing_modules:
8888
from .middlewares import trace_app
89+
from .patch import get_version
8990
from .patch import patch
9091
from .patch import unpatch
9192

92-
__all__ = [
93-
"patch",
94-
"unpatch",
95-
"trace_app",
96-
]
93+
__all__ = ["patch", "unpatch", "trace_app", "get_version"]

ddtrace/contrib/aiohttp/patch.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22

3+
import aiohttp
34
from yarl import URL
45

56
from ddtrace import config
@@ -43,6 +44,11 @@
4344
)
4445

4546

47+
def get_version():
48+
# type: () -> str
49+
return aiohttp.__version__
50+
51+
4652
class _WrappedConnectorClass(wrapt.ObjectProxy):
4753
def __init__(self, obj, pin):
4854
super().__init__(obj)

ddtrace/contrib/aiohttp_jinja2/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020

2121
with require_modules(required_modules) as missing_modules:
2222
if not missing_modules:
23+
from .patch import get_version
2324
from .patch import patch
2425
from .patch import unpatch
2526

26-
__all__ = ["patch", "unpatch"]
27+
__all__ = ["patch", "unpatch", "get_version"]

ddtrace/contrib/aiohttp_jinja2/patch.py

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import aiohttp_jinja2
2+
13
from ddtrace import Pin
24
from ddtrace import config
35
from ddtrace.internal.constants import COMPONENT
@@ -15,6 +17,11 @@
1517
)
1618

1719

20+
def get_version():
21+
# type: () -> str
22+
return getattr(aiohttp_jinja2, "__version__", "")
23+
24+
1825
@with_traced_module
1926
def traced_render_template(aiohttp_jinja2, pin, func, instance, args, kwargs):
2027
# original signature:

ddtrace/contrib/aiomysql/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343

4444
with require_modules(required_modules) as missing_modules:
4545
if not missing_modules:
46+
from .patch import get_version
4647
from .patch import patch
4748
from .patch import unpatch
4849

49-
__all__ = ["patch", "unpatch"]
50+
__all__ = ["patch", "unpatch", "get_version"]

ddtrace/contrib/aiomysql/patch.py

+6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
dict(_default_service=schematize_service_name("mysql")),
2525
)
2626

27+
28+
def get_version():
29+
# type: () -> str
30+
return getattr(aiomysql, "__version__", "")
31+
32+
2733
CONN_ATTR_BY_TAG = {
2834
net.TARGET_HOST: "host",
2935
net.TARGET_PORT: "port",

ddtrace/contrib/aiopg/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
with require_modules(required_modules) as missing_modules:
2424
if not missing_modules:
25+
from .patch import get_version
2526
from .patch import patch
2627

27-
__all__ = ["patch"]
28+
__all__ = ["patch", "get_version"]

ddtrace/contrib/aiopg/patch.py

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
from ddtrace.vendor import wrapt
1313

1414

15+
def get_version():
16+
# type: () -> str
17+
return getattr(aiopg, "__version__", "")
18+
19+
1520
def patch():
1621
"""Patch monkey patches psycopg's connection function
1722
so that the connection's functions are traced.

ddtrace/contrib/aioredis/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757

5858
with require_modules(required_modules) as missing_modules:
5959
if not missing_modules:
60+
from .patch import get_version
6061
from .patch import patch
6162
from .patch import unpatch
6263

63-
__all__ = ["patch", "unpatch"]
64+
__all__ = ["patch", "unpatch", "get_version"]

ddtrace/contrib/aioredis/patch.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,15 @@
4040
),
4141
)
4242

43-
aioredis_version_str = getattr(aioredis, "__version__", "0.0.0")
43+
aioredis_version_str = getattr(aioredis, "__version__", "")
4444
aioredis_version = tuple([int(i) for i in aioredis_version_str.split(".")])
4545

4646

47+
def get_version():
48+
# type: () -> str
49+
return aioredis_version_str
50+
51+
4752
def patch():
4853
if getattr(aioredis, "_datadog_patch", False):
4954
return

ddtrace/contrib/algoliasearch/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030

3131
with require_modules(required_modules) as missing_modules:
3232
if not missing_modules:
33+
from .patch import get_version
3334
from .patch import patch
3435
from .patch import unpatch
3536

36-
__all__ = ["patch", "unpatch"]
37+
__all__ = ["patch", "unpatch", "get_version"]

ddtrace/contrib/algoliasearch/patch.py

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
APP_NAME = "algoliasearch"
2020

2121
try:
22+
VERSION = "0.0.0"
2223
import algoliasearch
2324
from algoliasearch.version import VERSION
2425

@@ -30,6 +31,11 @@
3031
algoliasearch_version = (0, 0)
3132

3233

34+
def get_version():
35+
# type: () -> str
36+
return VERSION
37+
38+
3339
def patch():
3440
if algoliasearch_version == (0, 0):
3541
return

ddtrace/contrib/aredis/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ async def example():
6363

6464
with require_modules(required_modules) as missing_modules:
6565
if not missing_modules:
66+
from .patch import get_version
6667
from .patch import patch
6768

68-
__all__ = ["patch"]
69+
__all__ = ["patch", "get_version"]

ddtrace/contrib/aredis/patch.py

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
)
2424

2525

26+
def get_version():
27+
# type: () -> str
28+
return getattr(aredis, "__version__", "")
29+
30+
2631
def patch():
2732
"""Patch the instrumented methods"""
2833
if getattr(aredis, "_datadog_patch", False):

ddtrace/contrib/asgi/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def handle_request(scope, send):
6969
with require_modules(required_modules) as missing_modules:
7070
if not missing_modules:
7171
from .middleware import TraceMiddleware
72+
from .middleware import get_version
7273
from .middleware import span_from_scope
7374

74-
__all__ = ["TraceMiddleware", "span_from_scope"]
75+
__all__ = ["TraceMiddleware", "span_from_scope", "get_version"]

ddtrace/contrib/asgi/middleware.py

+5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
ASGI_SPEC_VERSION = "asgi.spec_version"
4242

4343

44+
def get_version():
45+
# type: () -> str
46+
return ""
47+
48+
4449
def bytes_to_str(str_or_bytes):
4550
return str_or_bytes.decode() if isinstance(str_or_bytes, bytes) else str_or_bytes
4651

ddtrace/contrib/asyncio/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ async def some_work():
5959
from .helpers import ensure_future
6060
from .helpers import run_in_executor
6161
from .helpers import set_call_context
62+
from .patch import get_version
6263
from .patch import patch
6364

64-
__all__ = ["context_provider", "set_call_context", "ensure_future", "run_in_executor", "patch"]
65+
__all__ = ["context_provider", "set_call_context", "ensure_future", "run_in_executor", "patch", "get_version"]

ddtrace/contrib/asyncio/patch.py

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
from .wrappers import wrapped_create_task
99

1010

11+
def get_version():
12+
# type: () -> str
13+
return ""
14+
15+
1116
def patch():
1217
"""Patches current loop `create_task()` method to enable spawned tasks to
1318
parent to the base task context.

ddtrace/contrib/asyncpg/__init__.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,8 @@
5050

5151
with require_modules(required_modules) as missing_modules:
5252
if not missing_modules:
53+
from .patch import get_version
5354
from .patch import patch
5455
from .patch import unpatch
5556

56-
__all__ = [
57-
"patch",
58-
"unpatch",
59-
]
57+
__all__ = ["patch", "unpatch", "get_version"]

ddtrace/contrib/asyncpg/patch.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from typing import TYPE_CHECKING
22

3+
import asyncpg
4+
35
from ddtrace import Pin
46
from ddtrace import config
57
from ddtrace.internal.constants import COMPONENT
@@ -26,7 +28,6 @@
2628
from typing import Dict
2729
from typing import Union
2830

29-
import asyncpg
3031
from asyncpg.prepared_stmt import PreparedStatement
3132

3233

@@ -44,6 +45,11 @@
4445
log = get_logger(__name__)
4546

4647

48+
def get_version():
49+
# type: () -> str
50+
return getattr(asyncpg, "__version__", "")
51+
52+
4753
def _get_connection_tags(conn):
4854
# type: (asyncpg.Connection) -> Dict[str, str]
4955
addr = conn._addr

ddtrace/contrib/aws_lambda/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@
3838
For additional configuration refer to
3939
`Instrumenting Python Serverless Applications by Datadog <https://docs.datadoghq.com/serverless/installation/python>`_.
4040
"""
41+
from .patch import get_version
4142
from .patch import patch
4243
from .patch import unpatch
4344

4445

45-
__all__ = ["patch", "unpatch"]
46+
__all__ = ["patch", "unpatch", "get_version"]

ddtrace/contrib/aws_lambda/patch.py

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
from ._cold_start import set_cold_start
1616

1717

18+
def get_version():
19+
# type: () -> str
20+
return ""
21+
22+
1823
class DDLambdaLogger:
1924
"""Uses `DDLogger` to log only on cold start invocations."""
2025

ddtrace/contrib/boto/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151

5252
with require_modules(required_modules) as missing_modules:
5353
if not missing_modules:
54+
from .patch import get_version
5455
from .patch import patch
5556

56-
__all__ = ["patch"]
57+
__all__ = ["patch", "get_version"]

0 commit comments

Comments
 (0)