Skip to content

Commit 6c58173

Browse files
feat: dogstatsd client sends timestamp
1 parent 72caf0a commit 6c58173

File tree

2 files changed

+25
-18
lines changed

2 files changed

+25
-18
lines changed

datadog_lambda/dogstatsd.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
import errno
12
import logging
23
import os
3-
import socket
4-
import errno
54
import re
5+
import socket
66
from threading import Lock
77

8-
98
MIN_SEND_BUFFER_SIZE = 32 * 1024
109
log = logging.getLogger("datadog_lambda.dogstatsd")
1110

@@ -55,14 +54,17 @@ def _get_udp_socket(cls, host, port):
5554

5655
return sock
5756

58-
def distribution(self, metric, value, tags=None):
57+
def distribution(self, metric, value, tags=None, timestamp=None):
5958
"""
60-
Send a global distribution value, optionally setting tags.
59+
Send a global distribution value, optionally setting tags. The optional
60+
timestamp should be an integer representing seconds since the epoch
61+
(January 1, 1970, 00:00:00 UTC).
6162
6263
>>> statsd.distribution("uploaded.file.size", 1445)
6364
>>> statsd.distribution("album.photo.count", 26, tags=["gender:female"])
65+
>>> statsd.distribution("historic.file.count", 5, timestamp=int(datetime(2020, 2, 14, 12, 0, 0).timestamp()))
6466
"""
65-
self._report(metric, "d", value, tags)
67+
self._report(metric, "d", value, tags, timestamp)
6668

6769
def close_socket(self):
6870
"""
@@ -84,20 +86,21 @@ def normalize_tags(self, tag_list):
8486
for tag in tag_list
8587
]
8688

87-
def _serialize_metric(self, metric, metric_type, value, tags):
89+
def _serialize_metric(self, metric, metric_type, value, tags, timestamp):
8890
# Create/format the metric packet
89-
return "%s:%s|%s%s" % (
91+
return "%s:%s|%s%s%s" % (
9092
metric,
9193
value,
9294
metric_type,
9395
("|#" + ",".join(self.normalize_tags(tags))) if tags else "",
96+
("|T" + str(timestamp)) if timestamp is not None else "",
9497
)
9598

96-
def _report(self, metric, metric_type, value, tags):
99+
def _report(self, metric, metric_type, value, tags, timestamp):
97100
if value is None:
98101
return
99102

100-
payload = self._serialize_metric(metric, metric_type, value, tags)
103+
payload = self._serialize_metric(metric, metric_type, value, tags, timestamp)
101104

102105
# Send it
103106
self._send_to_server(payload)

tests/test_dogstatsd.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from collections import deque
21
import unittest
2+
from collections import deque
33

44
from datadog_lambda.dogstatsd import statsd
55

@@ -36,16 +36,20 @@ def test_init(self):
3636
self.assertEqual(statsd.port, 8125)
3737
self.assertEqual(statsd.encoding, "utf-8")
3838

39-
def test_distribution_no_tags(self):
40-
statsd.distribution("my.test.metric", 3)
39+
def _checkOnlyOneMetric(self, value):
4140
payload = self.recv()
4241
metrics = payload.split("\n")
4342
self.assertEqual(len(metrics), 1)
44-
self.assertEqual("my.test.metric:3|d", metrics[0])
43+
self.assertEqual(value, metrics[0])
44+
45+
def test_distribution_no_tags(self):
46+
statsd.distribution("my.test.metric", 3)
47+
self._checkOnlyOneMetric("my.test.metric:3|d")
4548

4649
def test_distribution_with_tags(self):
4750
statsd.distribution("my.test.tags.metric", 3, tags=["taga:valuea,tagb:valueb"])
48-
payload = self.recv()
49-
metrics = payload.split("\n")
50-
self.assertEqual(len(metrics), 1)
51-
self.assertEqual("my.test.tags.metric:3|d|#taga:valuea_tagb:valueb", metrics[0])
51+
self._checkOnlyOneMetric("my.test.tags.metric:3|d|#taga:valuea_tagb:valueb")
52+
53+
def test_distribution_with_timestamp(self):
54+
statsd.distribution("my.test.timestamp.metric", 9, timestamp=123456789)
55+
self._checkOnlyOneMetric("my.test.timestamp.metric:9|d|T123456789")

0 commit comments

Comments
 (0)