Skip to content

Commit 7c4ca59

Browse files
committed
chore: introduce APM_TRACING RC product
We introduce the APM_TRACING remote configuration product that allows dispatching remote configuration to the library for remote enablement/ configuration of library components and features.
1 parent 4183671 commit 7c4ca59

File tree

7 files changed

+92
-5
lines changed

7 files changed

+92
-5
lines changed

ddtrace/debugging/_debugger.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,6 @@ def enable(cls) -> None:
274274

275275
di_config.enabled = True
276276

277-
cls.__watchdog__.install()
278-
279277
if di_config.metrics:
280278
metrics.enable()
281279

@@ -307,7 +305,6 @@ def disable(cls, join: bool = True) -> None:
307305
cls._instance.stop(join=join)
308306
cls._instance = None
309307

310-
cls.__watchdog__.uninstall()
311308
if di_config.metrics:
312309
metrics.disable()
313310

ddtrace/debugging/_products/dynamic_instrumentation.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1+
from ddtrace.internal.core.event_hub import on
12
from ddtrace.settings.dynamic_instrumentation import config
23

34

45
requires = ["remote-configuration"]
56

67

78
def post_preload():
8-
pass
9+
from ddtrace.debugging._debugger import Debugger
10+
11+
# We need to install this on start-up because if DI gets enabled remotely
12+
# we won't be able to capture many of the code objects from the modules
13+
# that are already loaded.
14+
Debugger.__watchdog__.install()
915

1016

1117
def start():
@@ -29,3 +35,15 @@ def stop(join=False):
2935

3036
def at_exit(join=False):
3137
stop(join=join)
38+
39+
40+
def apm_tracing_rc(config):
41+
enabled = config.get("dynamic_instrumentation_enabled")
42+
if enabled is not None: # and config.spec.enabled.full_name not in config.source:
43+
if (config.spec.enabled.full_name not in config.source or config.enabled) and enabled:
44+
start()
45+
else:
46+
stop()
47+
48+
49+
on("apm-tracing.rc", apm_tracing_rc, "dynamic-instrumentation")

ddtrace/internal/remoteconfig/products/__init__.py

Whitespace-only changes.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from ddtrace import config
2+
3+
4+
requires = ["remote-configuration"]
5+
6+
7+
def post_preload():
8+
pass
9+
10+
11+
def start():
12+
if config._remote_config_enabled:
13+
from ddtrace.internal.remoteconfig.worker import remoteconfig_poller
14+
from ddtrace.settings.remoteconfig import APMTracingAdapter
15+
16+
remoteconfig_poller.register("APM_TRACING", APMTracingAdapter())
17+
18+
19+
def restart(join=False):
20+
pass
21+
22+
23+
def stop(join=False):
24+
if config._remote_config_enabled:
25+
from ddtrace.internal.remoteconfig.worker import remoteconfig_poller
26+
27+
remoteconfig_poller.unregister("APM_TRACING")
28+
29+
30+
def at_exit(join=False):
31+
stop(join=join)

ddtrace/settings/remoteconfig.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from ddtrace import config
2+
from ddtrace.internal.core.event_hub import dispatch
3+
from ddtrace.internal.logger import get_logger
4+
from ddtrace.internal.remoteconfig._connectors import PublisherSubscriberConnector
5+
from ddtrace.internal.remoteconfig._publishers import RemoteConfigPublisher
6+
from ddtrace.internal.remoteconfig._pubsub import PubSub
7+
from ddtrace.internal.remoteconfig._subscribers import RemoteConfigSubscriber
8+
9+
10+
log = get_logger(__name__)
11+
12+
13+
def _rc_callback(data, test_tracer=None):
14+
for metadata, data in zip(data["metadata"], data["config"]):
15+
if metadata is None or not isinstance(data, dict):
16+
continue
17+
18+
service_target = data.get("service_target")
19+
if service_target is not None:
20+
service = service_target.get("service")
21+
if service is not None and service != config.service:
22+
continue
23+
24+
env = service_target.get("env")
25+
if env is not None and env != config.env:
26+
continue
27+
28+
lib_config = data.get("lib_config")
29+
if lib_config is not None:
30+
dispatch("apm-tracing.rc", (lib_config,))
31+
32+
33+
class APMTracingAdapter(PubSub):
34+
__publisher_class__ = RemoteConfigPublisher
35+
__subscriber_class__ = RemoteConfigSubscriber
36+
__shared_data__ = PublisherSubscriberConnector()
37+
38+
def __init__(self):
39+
self._publisher = self.__publisher_class__(self.__shared_data__)
40+
self._subscriber = self.__subscriber_class__(self.__shared_data__, _rc_callback, "APM_TRACING")

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ ddtrace = "ddtrace.contrib.pytest.plugin"
6060
"ddtrace.pytest_benchmark" = "ddtrace.contrib.pytest_benchmark.plugin"
6161

6262
[project.entry-points.'ddtrace.products']
63+
"apm-tracing-rc" = "ddtrace.internal.remoteconfig.products.apm_tracing"
6364
"code-origin-for-spans" = "ddtrace.debugging._products.code_origin.span"
6465
"dynamic-instrumentation" = "ddtrace.debugging._products.dynamic_instrumentation"
6566
"exception-replay" = "ddtrace.debugging._products.exception_replay"
66-
"remote-configuration" = "ddtrace.internal.remoteconfig.product"
67+
"remote-configuration" = "ddtrace.internal.remoteconfig.products.client"
6768
"symbol-database" = "ddtrace.internal.symbol_db.product"
6869

6970
[project.urls]

0 commit comments

Comments
 (0)