From d64b3af2afe5e627c3b4003f964594ec8f432ce7 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Wed, 15 Oct 2025 11:44:33 -0700 Subject: [PATCH 1/6] remove deprecated telemetry interval environment variable --- ddtrace/internal/runtime/constants.py | 1 + ddtrace/internal/runtime/runtime_metrics.py | 39 +++++++-------------- 2 files changed, 13 insertions(+), 27 deletions(-) diff --git a/ddtrace/internal/runtime/constants.py b/ddtrace/internal/runtime/constants.py index 78b9c5e032f..41b7edb8cd2 100644 --- a/ddtrace/internal/runtime/constants.py +++ b/ddtrace/internal/runtime/constants.py @@ -18,6 +18,7 @@ ) DEFAULT_RUNTIME_METRICS = GC_RUNTIME_METRICS | PSUTIL_RUNTIME_METRICS +DEFAULT_RUNTIME_METRICS_INTERVAL = 10 SERVICE = "service" ENV = "env" diff --git a/ddtrace/internal/runtime/runtime_metrics.py b/ddtrace/internal/runtime/runtime_metrics.py index 124b97ae262..9709ff8dbb4 100644 --- a/ddtrace/internal/runtime/runtime_metrics.py +++ b/ddtrace/internal/runtime/runtime_metrics.py @@ -15,6 +15,7 @@ from ..dogstatsd import get_dogstatsd_client from ..logger import get_logger from .constants import DEFAULT_RUNTIME_METRICS +from .constants import DEFAULT_RUNTIME_METRICS_INTERVAL from .metric_collectors import GCRuntimeMetricCollector from .metric_collectors import PSUtilRuntimeMetricCollector from .tag_collectors import PlatformTagCollector @@ -68,25 +69,14 @@ class RuntimeMetrics(RuntimeCollectorsIterable): ] -def _get_interval_or_default(): - if "DD_RUNTIME_METRICS_INTERVAL" in os.environ: - deprecate( - "`DD_RUNTIME_METRICS_INTERVAL` is deprecated and will be removed in a future version.", - removal_version="4.0.0", - ) - return float(os.getenv("DD_RUNTIME_METRICS_INTERVAL", default=10)) - - class RuntimeWorker(periodic.PeriodicService): - """Worker thread for collecting and writing runtime metrics to a DogStatsd - client. - """ + """Worker thread for collecting and writing runtime metrics to a DogStatsd client.""" enabled = False - _instance = None # type: ClassVar[Optional[RuntimeWorker]] + _instance: ClassVar[Optional[RuntimeWorker]] = None _lock = forksafe.Lock() - def __init__(self, interval=_get_interval_or_default(), tracer=None, dogstatsd_url=None) -> None: + def __init__(self, interval=DEFAULT_RUNTIME_METRICS_INTERVAL, tracer=None, dogstatsd_url=None) -> None: super().__init__(interval=interval) self.dogstatsd_url: Optional[str] = dogstatsd_url self._dogstatsd_client: DogStatsd = get_dogstatsd_client( @@ -107,8 +97,7 @@ def __init__(self, interval=_get_interval_or_default(), tracer=None, dogstatsd_u self._platform_tags = self._format_tags(PlatformTags()) @classmethod - def disable(cls): - # type: () -> None + def disable(cls) -> None: with cls._lock: if cls._instance is None: return @@ -134,13 +123,15 @@ def _restart(cls): cls.enable() @classmethod - def enable(cls, flush_interval=None, tracer=None, dogstatsd_url=None): - # type: (Optional[float], Optional[ddtrace.trace.Tracer], Optional[str]) -> None + def enable( + cls, + flush_interval: Optional[float] = DEFAULT_RUNTIME_METRICS_INTERVAL, + tracer: Optional[ddtrace.trace.Tracer] = None, + dogstatsd_url: Optional[str] = None, + ) -> None: with cls._lock: if cls._instance is not None: return - if flush_interval is None: - flush_interval = _get_interval_or_default() runtime_worker = cls(flush_interval, tracer, dogstatsd_url) runtime_worker.start() @@ -150,8 +141,7 @@ def enable(cls, flush_interval=None, tracer=None, dogstatsd_url=None): cls._instance = runtime_worker cls.enabled = True - def flush(self): - # type: () -> None + def flush(self) -> None: # Ensure runtime metrics have up-to-date tags (ex: service, env, version) rumtime_tags = self._format_tags(TracerTags()) + self._platform_tags log.debug("Sending runtime metrics with the following tags: %s", rumtime_tags) @@ -162,11 +152,6 @@ def flush(self): log.debug("Sending ddtrace runtime metric %s:%s", key, value) self.send_metric(key, value) - def _stop_service(self): - # type: (...) -> None - # De-register span hook - super(RuntimeWorker, self)._stop_service() - def _format_tags(self, tags: RuntimeCollectorsIterable) -> List[str]: # DEV: ddstatsd expects tags in the form ['key1:value1', 'key2:value2', ...] return ["{}:{}".format(k, v) for k, v in tags] From 18a6239be3a94d91463ef8d63f4f37d51a7c2395 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Fri, 24 Oct 2025 09:56:11 -0700 Subject: [PATCH 2/6] reno --- .../notes/remove-interval-envvar-88c126a791a448a0.yaml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 releasenotes/notes/remove-interval-envvar-88c126a791a448a0.yaml diff --git a/releasenotes/notes/remove-interval-envvar-88c126a791a448a0.yaml b/releasenotes/notes/remove-interval-envvar-88c126a791a448a0.yaml new file mode 100644 index 00000000000..2dcd05f9c50 --- /dev/null +++ b/releasenotes/notes/remove-interval-envvar-88c126a791a448a0.yaml @@ -0,0 +1,4 @@ +--- +other: + - | + This change removes the deprecated environment variable `DEFAULT_RUNTIME_METRICS_INTERVAL`. From 3d82c388ad7500a9318bdcdb0fa49d7c00345370 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Fri, 24 Oct 2025 10:22:33 -0700 Subject: [PATCH 3/6] lint --- ddtrace/internal/runtime/runtime_metrics.py | 4 +--- tests/contrib/yaaredis/test_yaaredis.py | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/ddtrace/internal/runtime/runtime_metrics.py b/ddtrace/internal/runtime/runtime_metrics.py index 9709ff8dbb4..e83b2c568ab 100644 --- a/ddtrace/internal/runtime/runtime_metrics.py +++ b/ddtrace/internal/runtime/runtime_metrics.py @@ -1,5 +1,4 @@ import itertools -import os from typing import ClassVar # noqa:F401 from typing import List # noqa:F401 from typing import Optional # noqa:F401 @@ -8,7 +7,6 @@ from ddtrace.internal import atexit from ddtrace.internal import forksafe from ddtrace.internal.constants import EXPERIMENTAL_FEATURES -from ddtrace.vendor.debtcollector import deprecate from ddtrace.vendor.dogstatsd import DogStatsd from .. import periodic @@ -73,7 +71,7 @@ class RuntimeWorker(periodic.PeriodicService): """Worker thread for collecting and writing runtime metrics to a DogStatsd client.""" enabled = False - _instance: ClassVar[Optional[RuntimeWorker]] = None + _instance = None # type: ClassVar[Optional[RuntimeWorker]] _lock = forksafe.Lock() def __init__(self, interval=DEFAULT_RUNTIME_METRICS_INTERVAL, tracer=None, dogstatsd_url=None) -> None: diff --git a/tests/contrib/yaaredis/test_yaaredis.py b/tests/contrib/yaaredis/test_yaaredis.py index 84185652ba0..d3fa5743b70 100644 --- a/tests/contrib/yaaredis/test_yaaredis.py +++ b/tests/contrib/yaaredis/test_yaaredis.py @@ -9,7 +9,6 @@ from ddtrace.contrib.internal.yaaredis.patch import patch from ddtrace.contrib.internal.yaaredis.patch import unpatch from ddtrace.internal.compat import is_wrapted -from tests.opentracer.utils import init_tracer from tests.utils import override_config from ..config import REDIS_CONFIG From 3cc53970a3d5b7ee48054bc9ccfcbf3fbc1387a8 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Tue, 28 Oct 2025 10:11:06 -0400 Subject: [PATCH 4/6] fix failing test --- ddtrace/internal/runtime/runtime_metrics.py | 3 +-- ddtrace/runtime/__init__.py | 18 +++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/ddtrace/internal/runtime/runtime_metrics.py b/ddtrace/internal/runtime/runtime_metrics.py index e83b2c568ab..c541b333748 100644 --- a/ddtrace/internal/runtime/runtime_metrics.py +++ b/ddtrace/internal/runtime/runtime_metrics.py @@ -123,14 +123,13 @@ def _restart(cls): @classmethod def enable( cls, - flush_interval: Optional[float] = DEFAULT_RUNTIME_METRICS_INTERVAL, tracer: Optional[ddtrace.trace.Tracer] = None, dogstatsd_url: Optional[str] = None, ) -> None: with cls._lock: if cls._instance is not None: return - runtime_worker = cls(flush_interval, tracer, dogstatsd_url) + runtime_worker = cls(DEFAULT_RUNTIME_METRICS_INTERVAL, tracer, dogstatsd_url) runtime_worker.start() forksafe.register(cls._restart) diff --git a/ddtrace/runtime/__init__.py b/ddtrace/runtime/__init__.py index 79745217f11..2963023fc29 100644 --- a/ddtrace/runtime/__init__.py +++ b/ddtrace/runtime/__init__.py @@ -1,5 +1,6 @@ from typing import Optional # noqa:F401 +import ddtrace import ddtrace.internal.runtime.runtime_metrics from ddtrace.internal.telemetry import telemetry_writer @@ -29,27 +30,22 @@ class RuntimeMetrics(metaclass=_RuntimeMetricsStatus): """ @staticmethod - def enable(tracer=None, dogstatsd_url=None, flush_interval=None): - # type: (Optional[ddtrace.trace.Tracer], Optional[str], Optional[float]) -> None + def enable( + tracer: Optional[ddtrace.trace.Tracer] = None, + dogstatsd_url: Optional[str] = None, + ) -> None: """ - Enable the runtime metrics collection service. - If the service has already been activated before, this method does nothing. Use ``disable`` to turn off the runtime metric collection service. :param tracer: The tracer instance to correlate with. - :param dogstatsd_url: The DogStatsD URL. - :param flush_interval: The flush interval. """ telemetry_writer.add_configuration(TELEMETRY_RUNTIMEMETRICS_ENABLED, True, origin="code") - ddtrace.internal.runtime.runtime_metrics.RuntimeWorker.enable( - tracer=tracer, dogstatsd_url=dogstatsd_url, flush_interval=flush_interval - ) + ddtrace.internal.runtime.runtime_metrics.RuntimeWorker.enable(tracer=tracer, dogstatsd_url=dogstatsd_url) @staticmethod - def disable(): - # type: () -> None + def disable() -> None: """ Disable the runtime metrics collection service. From 98d7b498b98ec71cccdf5b41e4c69e176c55b602 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Tue, 28 Oct 2025 10:35:28 -0400 Subject: [PATCH 5/6] remove uses of removed parameter --- tests/tracer/runtime/test_runtime_metrics.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/tracer/runtime/test_runtime_metrics.py b/tests/tracer/runtime/test_runtime_metrics.py index 984142380e1..d6d7cfec819 100644 --- a/tests/tracer/runtime/test_runtime_metrics.py +++ b/tests/tracer/runtime/test_runtime_metrics.py @@ -20,8 +20,8 @@ @contextlib.contextmanager -def runtime_metrics_service(tracer=None, flush_interval=None): - RuntimeWorker.enable(tracer=tracer, flush_interval=flush_interval) +def runtime_metrics_service(tracer=None): + RuntimeWorker.enable(tracer=tracer) assert RuntimeWorker._instance is not None assert RuntimeWorker._instance.status == ServiceStatus.RUNNING @@ -151,9 +151,7 @@ def test_tracer_metrics(self): # Mock socket.socket to hijack the dogstatsd socket with mock.patch("socket.socket") as sock: sock.return_value.getsockopt.return_value = 0 - # configure tracer for runtime metrics - interval = 1.0 / 4 - with runtime_metrics_service(tracer=self.tracer, flush_interval=interval): + with runtime_metrics_service(tracer=self.tracer): self.tracer.set_tags({"env": "tests.dog"}) with self.override_global_tracer(self.tracer): From 20a3863fb5a24688784c6c20d73e9deb7294b591 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Tue, 28 Oct 2025 10:46:31 -0400 Subject: [PATCH 6/6] lint --- tests/tracer/runtime/test_runtime_metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tracer/runtime/test_runtime_metrics.py b/tests/tracer/runtime/test_runtime_metrics.py index d6d7cfec819..118e85df126 100644 --- a/tests/tracer/runtime/test_runtime_metrics.py +++ b/tests/tracer/runtime/test_runtime_metrics.py @@ -165,7 +165,7 @@ def test_tracer_metrics(self): with self.start_span( "query", service="db", span_type=SpanTypes.SQL, child_of=child.context ): - time.sleep(interval * 4) + time.sleep(4) # Get the mocked socket for inspection later statsd_socket = RuntimeWorker._instance._dogstatsd_client.socket received = [s.args[0].decode("utf-8") for s in statsd_socket.send.mock_calls]