Skip to content

Commit

Permalink
AMLII-1086 fix stale client_transport tag (#802)
Browse files Browse the repository at this point in the history
initialize reassigns socket_path property on the global statsd
instance, but the client_transport tag was computed in the constructor
and never updated, causing client to misreport transport as udp when a
unix socket was actually used.

This patch makes the tag dynamic and updates it every time the
socket_path property is updated.
  • Loading branch information
vickenty authored Dec 4, 2023
1 parent 5455e9c commit ff9f020
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
17 changes: 13 additions & 4 deletions datadog/dogstatsd/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,14 +325,12 @@ def __init__(
self.socket_path = socket_path # type: Optional[text]
self.host = None
self.port = None
transport = "uds"
if not self._max_payload_size:
self._max_payload_size = UDS_OPTIMAL_PAYLOAD_LENGTH
else:
self.socket_path = None
self.host = self.resolve_host(host, use_default_route)
self.port = int(port)
transport = "udp"
if not self._max_payload_size:
self._max_payload_size = UDP_OPTIMAL_PAYLOAD_LENGTH

Expand Down Expand Up @@ -381,7 +379,6 @@ def __init__(
self._client_tags = [
"client:py",
"client_version:{}".format(__version__),
"client_transport:{}".format(transport),
]
self._reset_telemetry()
self._telemetry_flush_interval = telemetry_min_flush_interval
Expand Down Expand Up @@ -417,6 +414,15 @@ def __init__(
if not disable_background_sender:
self.enable_background_sender(sender_queue_size, sender_queue_timeout)

@property
def socket_path(self):
return self._socket_path

@socket_path.setter
def socket_path(self, path):
self._socket_path = path
self._transport = "udp" if path is None else "uds"

def enable_background_sender(self, sender_queue_size=0, sender_queue_timeout=0):
"""
Use a background thread to communicate with the dogstatsd server.
Expand Down Expand Up @@ -943,7 +949,10 @@ def bytes_dropped(self):
return self.bytes_dropped_queue + self.bytes_dropped_writer

def _flush_telemetry(self):
telemetry_tags = ",".join(self._add_constant_tags(self._client_tags))
tags = self._client_tags[:]
tags.append("client_transport:{}".format(self._transport))
tags.extend(self.constant_tags)
telemetry_tags = ",".join(tags)

return TELEMETRY_FORMATTING_STR % (
self.metrics_count,
Expand Down
12 changes: 10 additions & 2 deletions tests/unit/dogstatsd/test_statsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ def tearDown(self):
"""
self._procfs_mock.stop()

def assert_equal_telemetry(self, expected_payload, actual_payload, telemetry=None):
def assert_equal_telemetry(self, expected_payload, actual_payload, telemetry=None, **kwargs):
if telemetry is None:
telemetry = telemetry_metrics(bytes_sent=len(expected_payload))
telemetry = telemetry_metrics(bytes_sent=len(expected_payload), **kwargs)

if expected_payload:
expected_payload = "\n".join([expected_payload, telemetry])
Expand Down Expand Up @@ -705,6 +705,14 @@ def test_udp_socket_ensures_min_receive_buffer(self, mock_socket_create):
MIN_SEND_BUFFER_SIZE,
)

def test_socket_path_updates_telemetry(self):
self.statsd.gauge("foo", 1)
self.assert_equal_telemetry("foo:1|g\n", self.recv(2), transport="udp")
self.statsd.socket_path = "/fake/path"
self.statsd._reset_telemetry()
self.statsd.gauge("foo", 2)
self.assert_equal_telemetry("foo:2|g\n", self.recv(2), transport="uds")

def test_distributed(self):
"""
Measure the distribution of a function's run time using distribution custom metric.
Expand Down

0 comments on commit ff9f020

Please sign in to comment.