diff --git a/datadog/dogstatsd/base.py b/datadog/dogstatsd/base.py index d2ab5e67a..5bbd36662 100644 --- a/datadog/dogstatsd/base.py +++ b/datadog/dogstatsd/base.py @@ -1390,12 +1390,13 @@ def _send_to_server(self, packet): if self._queue is not None: # Prevent a race with disable_background_sender. with self._buffer_lock: + packet_with_newline = packet + '\n' if self._queue is not None: try: - self._queue.put(packet + '\n', self._queue_blocking, self._queue_timeout) + self._queue.put(packet_with_newline, self._queue_blocking, self._queue_timeout) except queue.Full: self.packets_dropped_queue += 1 - self.bytes_dropped_queue += 1 + self.bytes_dropped_queue += len(packet_with_newline.encode(self.encoding)) return self._xmit_packet_with_telemetry(packet + '\n') diff --git a/tests/unit/dogstatsd/test_statsd.py b/tests/unit/dogstatsd/test_statsd.py index 6b2da3b17..6548b2090 100644 --- a/tests/unit/dogstatsd/test_statsd.py +++ b/tests/unit/dogstatsd/test_statsd.py @@ -2124,6 +2124,30 @@ def test_sender_calls_task_done(self): def test_sender_queue_no_timeout(self): statsd = DogStatsd(disable_background_sender=False, sender_queue_timeout=None) + def test_bytes_dropped_queue_counts_actual_bytes(self): + # Use a queue of size 1 and a non-blocking timeout so packets are dropped + # when the queue is full, then verify bytes_dropped_queue reflects the real + # byte length of the dropped packet (including the appended newline). + statsd = DogStatsd( + disable_background_sender=False, + sender_queue_size=1, + sender_queue_timeout=0, + ) + statsd.socket = FakeSocket() + + # Build a packet whose serialised form we know, then compute its length. + metric_name = "test.metric" + + # Send two packets: the first fills the queue, the second is dropped. + statsd._send_to_server(metric_name) + statsd._send_to_server(metric_name) + + expected_bytes = len((metric_name + '\n').encode("utf-8")) + self.assertEqual(statsd.bytes_dropped_queue, expected_bytes) + self.assertEqual(statsd.packets_dropped_queue, 1) + + statsd.stop() + def test_set_socket_timeout(self): statsd = DogStatsd(disable_background_sender=False) statsd.socket = FakeSocket()