Skip to content

Commit 17e067c

Browse files
author
David Bouchare
committed
Default sample rate (DataDog#470)
* add support for default_sample_rate The idea is quite similar to constant_tags: when initializing a DogStatsd object, you can specify a value that should apply to *all* metrics. This change is backwards compatible. You can still pass in sample_rate on a per-call basis and the value will override the default. * Fix typo t.assert...
1 parent ee50d4f commit 17e067c

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

datadog/dogstatsd/base.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class DogStatsd(object):
3030

3131
def __init__(self, host=DEFAULT_HOST, port=DEFAULT_PORT, max_buffer_size=50, namespace=None,
3232
constant_tags=None, use_ms=False, use_default_route=False,
33-
socket_path=None):
33+
socket_path=None, default_sample_rate=1):
3434
"""
3535
Initialize a DogStatsd object.
3636
@@ -76,6 +76,9 @@ def __init__(self, host=DEFAULT_HOST, port=DEFAULT_PORT, max_buffer_size=50, nam
7676
:param socket_path: Communicate with dogstatsd through a UNIX socket instead of
7777
UDP. If set, disables UDP transmission (Linux only)
7878
:type socket_path: string
79+
80+
:param default_sample_rate: Sample rate to use by default for all metrics
81+
:type default_sample_rate: float
7982
"""
8083

8184
self.lock = Lock()
@@ -122,6 +125,7 @@ def __init__(self, host=DEFAULT_HOST, port=DEFAULT_PORT, max_buffer_size=50, nam
122125
namespace = text(namespace)
123126
self.namespace = namespace
124127
self.use_ms = use_ms
128+
self.default_sample_rate = default_sample_rate
125129

126130
def __enter__(self):
127131
self.open_buffer(self.max_buffer_size)
@@ -190,7 +194,7 @@ def close_buffer(self):
190194
# Only send packets if there are packets to send
191195
self._flush_buffer()
192196

193-
def gauge(self, metric, value, tags=None, sample_rate=1):
197+
def gauge(self, metric, value, tags=None, sample_rate=None):
194198
"""
195199
Record the value of a gauge, optionally setting a list of tags and a
196200
sample rate.
@@ -200,7 +204,7 @@ def gauge(self, metric, value, tags=None, sample_rate=1):
200204
"""
201205
return self._report(metric, 'g', value, tags, sample_rate)
202206

203-
def increment(self, metric, value=1, tags=None, sample_rate=1):
207+
def increment(self, metric, value=1, tags=None, sample_rate=None):
204208
"""
205209
Increment a counter, optionally setting a value, tags and a sample
206210
rate.
@@ -210,7 +214,7 @@ def increment(self, metric, value=1, tags=None, sample_rate=1):
210214
"""
211215
self._report(metric, 'c', value, tags, sample_rate)
212216

213-
def decrement(self, metric, value=1, tags=None, sample_rate=1):
217+
def decrement(self, metric, value=1, tags=None, sample_rate=None):
214218
"""
215219
Decrement a counter, optionally setting a value, tags and a sample
216220
rate.
@@ -221,7 +225,7 @@ def decrement(self, metric, value=1, tags=None, sample_rate=1):
221225
metric_value = -value if value else value
222226
self._report(metric, 'c', metric_value, tags, sample_rate)
223227

224-
def histogram(self, metric, value, tags=None, sample_rate=1):
228+
def histogram(self, metric, value, tags=None, sample_rate=None):
225229
"""
226230
Sample a histogram value, optionally setting tags and a sample rate.
227231
@@ -230,7 +234,7 @@ def histogram(self, metric, value, tags=None, sample_rate=1):
230234
"""
231235
self._report(metric, 'h', value, tags, sample_rate)
232236

233-
def distribution(self, metric, value, tags=None, sample_rate=1):
237+
def distribution(self, metric, value, tags=None, sample_rate=None):
234238
"""
235239
Send a global distribution value, optionally setting tags and a sample rate.
236240
@@ -241,15 +245,15 @@ def distribution(self, metric, value, tags=None, sample_rate=1):
241245
"""
242246
self._report(metric, 'd', value, tags, sample_rate)
243247

244-
def timing(self, metric, value, tags=None, sample_rate=1):
248+
def timing(self, metric, value, tags=None, sample_rate=None):
245249
"""
246250
Record a timing, optionally setting tags and a sample rate.
247251
248252
>>> statsd.timing("query.response.time", 1234)
249253
"""
250254
self._report(metric, 'ms', value, tags, sample_rate)
251255

252-
def timed(self, metric=None, tags=None, sample_rate=1, use_ms=None):
256+
def timed(self, metric=None, tags=None, sample_rate=None, use_ms=None):
253257
"""
254258
A decorator or context manager that will measure the distribution of a
255259
function's/context's run time. Optionally specify a list of tags or a
@@ -277,7 +281,7 @@ def get_user(user_id):
277281
"""
278282
return TimedContextManagerDecorator(self, metric, tags, sample_rate, use_ms)
279283

280-
def set(self, metric, value, tags=None, sample_rate=1):
284+
def set(self, metric, value, tags=None, sample_rate=None):
281285
"""
282286
Sample a set value.
283287
@@ -302,6 +306,9 @@ def _report(self, metric, metric_type, value, tags, sample_rate):
302306
if value is None:
303307
return
304308

309+
if sample_rate is None:
310+
sample_rate = self.default_sample_rate
311+
305312
if sample_rate != 1 and random() > sample_rate:
306313
return
307314

tests/unit/dogstatsd/test_statsd.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,13 @@ def test_sample_rate(self):
193193
self.assert_almost_equal(3000, len(self.statsd.socket.payloads), 150)
194194
assert_equal('sampled_counter:1|c|@0.3', self.recv())
195195

196+
def test_default_sample_rate(self):
197+
self.statsd.default_sample_rate = 0.3
198+
for i in range(10000):
199+
self.statsd.increment('sampled_counter')
200+
self.assert_almost_equal(3000, len(self.statsd.socket.payloads), 150)
201+
assert_equal('sampled_counter:1|c|@0.3', self.recv())
202+
196203
def test_tags_and_samples(self):
197204
for i in range(100):
198205
self.statsd.gauge('gst', 23, tags=["sampled"], sample_rate=0.9)

0 commit comments

Comments
 (0)