Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased

* [Changed] DogStatsD background sender queue now evicts the oldest queued payloads when full, and drops payloads without an explicit timestamp after they have been queued for more than 10 seconds. See [#986](https://github.com/DataDog/datadogpy/pull/986).

## v0.53.0 / 2026-07-24

* [Fixed] Add DD_DOGSTATSD_URL support for Unix and UDP URLs. See [#968](https://github.com/DataDog/datadogpy/pull/968).
Expand Down
311 changes: 237 additions & 74 deletions datadog/dogstatsd/base.py

Large diffs are not rendered by default.

7 changes: 1 addition & 6 deletions datadog/dogstatsd/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,9 @@
import sys


try:
from time import monotonic # type: ignore[attr-defined]
except ImportError:
from time import time as monotonic

# datadog
from datadog.dogstatsd.context_async import _get_wrapped_co
from datadog.util.compat import iscoroutinefunction
from datadog.util.compat import iscoroutinefunction, monotonic


if sys.version_info[:2] >= (3, 5):
Expand Down
6 changes: 2 additions & 4 deletions datadog/dogstatsd/context_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@
# https://github.com/python/mypy/issues/6897
ASYNC_SOURCE = r'''
from functools import wraps
try:
from time import monotonic
except ImportError:
from time import time as monotonic

from datadog.util.compat import monotonic


def _get_wrapped_co(self, func):
Expand Down
361 changes: 361 additions & 0 deletions datadog/dogstatsd/sender_queue.py

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions datadog/threadstats/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,13 @@
from functools import wraps
from time import time

try:
from time import monotonic # type: ignore[attr-defined]
except ImportError:
from time import time as monotonic

# datadog
from datadog.api.exceptions import ApiNotInitialized
from datadog.threadstats.constants import MetricType
from datadog.threadstats.events import EventsAggregator
from datadog.threadstats.metrics import MetricsAggregator, Counter, Gauge, Histogram, Timing, Distribution, Set
from datadog.threadstats.reporters import HttpReporter
from datadog.util.compat import monotonic

# Loggers
log = logging.getLogger("datadog.threadstats")
Expand Down
10 changes: 10 additions & 0 deletions datadog/util/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ def emit(self, record):
pass


# Python >= 3.3
if sys.version_info >= (3, 3):
from time import monotonic
# Python 2.x: there is no monotonic clock, so fall back to the wall clock.
# Callers that compare two readings (elapsed time, queue entry age) are
# therefore sensitive to the clock being stepped backwards on Python 2.
else:
from time import time as monotonic


def _is_py_version_higher_than(major, minor=0):
# type: (int, int) -> bool
"""
Expand Down
3 changes: 2 additions & 1 deletion tests/integration/dogstatsd/test_statsd_sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ def test_fork_hooks(disable_background_sender, disable_buffering):
assert statsd._flush_thread is None
assert statsd._sender_thread is None
assert statsd._queue is None or statsd._queue.empty()
assert len(statsd._buffer) == 0
# Buffered lines are split by expiry policy, so check every batch.
assert not statsd._buffer and not statsd._buffer_rs

statsd.post_fork_parent()

Expand Down
905 changes: 886 additions & 19 deletions tests/unit/dogstatsd/test_statsd.py

Large diffs are not rendered by default.

Loading