diff --git a/CHANGELOG.md b/CHANGELOG.md index 6952112d8..cedad0d3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ## Unreleased * [Fixed] Fix missing transport attribute when flushing telemetry. +* [Added] Add ability to disable statsd via new `statsd_disable` parameter in `initialize`. ## v0.52.0 / 2025-07-08 diff --git a/README.md b/README.md index 2bb40165b..a6d13bfc6 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,9 @@ tags = ["version:1", "application:web"] api.Event.create(title=title, text=text, tags=tags) ``` -In development, you can disable any `statsd` metric collection using `DD_DOGSTATSD_DISABLE=True` (or any not-empty value). +In development, you can disable any `statsd` metric collection by either: +1. Setting environment variable `DD_DOGSTATSD_DISABLE` to `True`, `true`, `yes`, or `1`. +2. Setting the `statsd_disable` option to `True` in the `initialize` function. ## DogStatsD diff --git a/datadog/__init__.py b/datadog/__init__.py index 50f1d0475..a7e0a4559 100644 --- a/datadog/__init__.py +++ b/datadog/__init__.py @@ -37,6 +37,7 @@ def initialize( api_host=None, # type: Optional[str] statsd_host=None, # type: Optional[str] statsd_port=None, # type: Optional[int] + statsd_disable=False, # type: bool statsd_disable_aggregation=True, # type: bool statsd_disable_buffering=True, # type: bool statsd_aggregation_flush_interval=0.3, # type: float @@ -76,6 +77,9 @@ def initialize( :param statsd_port: Port of DogStatsd server or statsd daemon :type statsd_port: port + :param statsd_disable: Disable any statsd metric collection (default False). + :type statsd_disable: bool + :param statsd_disable_buffering: Enable/disable statsd client buffering support (default: True). :type statsd_disable_buffering: boolean @@ -151,6 +155,11 @@ def initialize( if statsd_constant_tags: statsd.constant_tags += statsd_constant_tags + if statsd_disable: + statsd.disable_statsd() + else: + statsd.enable_statsd() + if statsd_disable_aggregation: statsd.disable_aggregation() else: diff --git a/datadog/dogstatsd/base.py b/datadog/dogstatsd/base.py index 5f9bd2f63..9079ee1f9 100644 --- a/datadog/dogstatsd/base.py +++ b/datadog/dogstatsd/base.py @@ -158,6 +158,7 @@ def __init__( port=DEFAULT_PORT, # type: int max_buffer_size=None, # type: None flush_interval=DEFAULT_BUFFERING_FLUSH_INTERVAL, # type: float + disable_statsd=False, # type: bool disable_aggregation=True, # type: bool disable_buffering=True, # type: bool namespace=None, # type: Optional[Text] @@ -250,6 +251,10 @@ def __init__( it overrides the default value. :type flush_interval: float + :disable_statsd: Disable any statsd metric collection (default False). + Overridden by DD_DOGSTATSD_DISABLE enviroment variable. + :type disable_statsd: bool + :disable_aggregation: If true, metrics (Count, Gauge, Set) are no longer aggregated by the client :type disable_aggregation: bool @@ -396,10 +401,10 @@ def __init__( telemetry_port = os.environ.get("DD_TELEMETRY_PORT", telemetry_port) or port # Check enabled - if os.environ.get("DD_DOGSTATSD_DISABLE") not in {"True", "true", "yes", "1"}: - self._enabled = True - else: + if os.environ.get("DD_DOGSTATSD_DISABLE", disable_statsd) in {True, "True", "true", "yes", "1"}: self._enabled = False + else: + self._enabled = True # Connection self._max_buffer_len = max_buffer_len @@ -693,6 +698,12 @@ def disable_buffering(self, is_disabled): self._send = self._send_to_buffer self._start_flush_thread() + def disable_statsd(self): + self._enabled = False + + def enable_statsd(self): + self._enabled = True + def disable_aggregation(self): with self._config_lock: # If the toggle didn't change anything, this method is a noop diff --git a/tests/unit/dogstatsd/test_statsd.py b/tests/unit/dogstatsd/test_statsd.py index 6b2da3b17..32dbbca6b 100644 --- a/tests/unit/dogstatsd/test_statsd.py +++ b/tests/unit/dogstatsd/test_statsd.py @@ -1164,6 +1164,20 @@ def _test_flush_interval(self, socket_kind): u'page.®views®:1|c\n', fake_socket.recv(2, no_wait=True) ) + + def test_statsd_disabled_dgram(self): + self._test_statsd_disabled(socket.SOCK_DGRAM) + + def test_statsd_disabled_stream(self): + self._test_statsd_disabled(socket.SOCK_STREAM) + + def _test_statsd_disabled(self, socket_kind): + dogstatsd = DogStatsd(disable_statsd=True, telemetry_min_flush_interval=0) + fake_socket = FakeSocket(socket_kind=socket_kind) + dogstatsd.socket = fake_socket + dogstatsd.increment('_test_statsd_disabled') + dogstatsd.flush() + self.assertIsNone(fake_socket.recv(no_wait=True)) def test_aggregation_buffering_simultaneously_dgram(self): self._test_aggregation_buffering_simultaneously(socket.SOCK_DGRAM) @@ -2209,4 +2223,4 @@ def test_transport_attribute_present_on_connection_error(self): statsd.gauge('test.metric', 1) assert statsd.socket is None - assert statsd._transport is not None \ No newline at end of file + assert statsd._transport is not None