Skip to content

Commit f975f3d

Browse files
committed
Support explicit metric timestamps
1 parent 5c297c0 commit f975f3d

3 files changed

Lines changed: 31 additions & 8 deletions

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ client.rate("sensor.samples_per_second", 2.0)
103103
client.flush()
104104
```
105105

106+
Pass `timestamp=` to use an explicit Unix timestamp instead of `time.time()`:
107+
108+
```python
109+
client.gauge("sensor.temperature", 23.8, timestamp=1710000123)
110+
```
111+
106112
`flush()` returns `True` when Datadog accepts the payload with a 2xx HTTP status.
107113
It returns `False` on network errors, socket errors, HTTP error status codes, or
108114
unexpected request failures. It never intentionally raises an exception, and it

datadog.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,17 @@ def __init__(
4949
"Content-Type": "application/json",
5050
}
5151

52-
def gauge(self, metric, value, tags=None):
52+
def gauge(self, metric, value, tags=None, timestamp=None):
5353
"""Buffer a gauge metric."""
54-
self._add_metric(metric, value, _TYPE_GAUGE, tags)
54+
self._add_metric(metric, value, _TYPE_GAUGE, tags, timestamp)
5555

56-
def count(self, metric, value, tags=None):
56+
def count(self, metric, value, tags=None, timestamp=None):
5757
"""Buffer a count metric."""
58-
self._add_metric(metric, value, _TYPE_COUNT, tags)
58+
self._add_metric(metric, value, _TYPE_COUNT, tags, timestamp)
5959

60-
def rate(self, metric, value, tags=None):
60+
def rate(self, metric, value, tags=None, timestamp=None):
6161
"""Buffer a rate metric."""
62-
self._add_metric(metric, value, _TYPE_RATE, tags)
62+
self._add_metric(metric, value, _TYPE_RATE, tags, timestamp)
6363

6464
def flush(self):
6565
"""Send buffered metrics.
@@ -111,9 +111,12 @@ def flush(self):
111111
self._buffer = []
112112
return False
113113

114-
def _add_metric(self, metric, value, metric_type, tags):
114+
def _add_metric(self, metric, value, metric_type, tags, timestamp):
115+
if timestamp is None:
116+
timestamp = time.time()
117+
115118
point = {
116-
"timestamp": int(time.time()),
119+
"timestamp": int(timestamp),
117120
"value": value,
118121
}
119122
item = {

tests/test_datadog.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,20 @@ def test_builds_metric_payloads_with_types_and_tags(self):
8888
self.assertEqual(series[2]["type"], 2)
8989
self.assertEqual(series[2]["tags"], ["env:test"])
9090

91+
def test_accepts_explicit_metric_timestamps(self):
92+
session = FakeSession([202])
93+
client = datadog.DatadogClient(session, "api-key")
94+
95+
client.gauge("sensor.temperature", 22.5, timestamp=1710000123)
96+
client.count("button.press", 1, timestamp=1710000124)
97+
client.rate("sensor.samples_per_second", 2.0, timestamp=1710000125)
98+
99+
self.assertTrue(client.flush())
100+
series = session.posts[0]["json"]["series"]
101+
self.assertEqual(series[0]["points"][0]["timestamp"], 1710000123)
102+
self.assertEqual(series[1]["points"][0]["timestamp"], 1710000124)
103+
self.assertEqual(series[2]["points"][0]["timestamp"], 1710000125)
104+
91105
def test_constructs_datadog_site_urls(self):
92106
cases = (
93107
("datadoghq.com", "https://api.datadoghq.com/api/v2/series"),

0 commit comments

Comments
 (0)