summaryrefslogtreecommitdiff
path: root/statsd
diff options
context:
space:
mode:
authorJames Socol <james@bit.ly>2014-01-07 16:00:09 -0500
committerJames Socol <james@bit.ly>2014-01-07 16:01:26 -0500
commitff0365e05a6390d43faa9462b1af261f247d286b (patch)
tree3b78da1b50a7dbc05b7bb9eb5f02045136d6b67f /statsd
parent3baf3f916718203c4b9263f14aec563c2a676eda (diff)
downloadpystatsd-ff0365e05a6390d43faa9462b1af261f247d286b.tar.gz
Handle negative absolute gauges.
- For negative absolute gauge values, zero out the gauge first, since StatsD can't distinguish it from a delta. - Add tests. - Patch via Ben Gilbert (https://github.com/bgilbert) - Fixes #40.
Diffstat (limited to 'statsd')
-rw-r--r--statsd/client.py12
-rw-r--r--statsd/tests.py27
2 files changed, 37 insertions, 2 deletions
diff --git a/statsd/client.py b/statsd/client.py
index 1e3f80f..8b4f8e0 100644
--- a/statsd/client.py
+++ b/statsd/client.py
@@ -87,8 +87,16 @@ class StatsClient(object):
def gauge(self, stat, value, rate=1, delta=False):
"""Set a gauge value."""
- prefix = '+' if delta and value >= 0 else ''
- self._send_stat(stat, '%s%s|g' % (prefix, value), rate)
+ if value < 0 and not delta:
+ if rate < 1:
+ if random.random() > rate:
+ return
+ with self.pipeline() as pipe:
+ pipe._send_stat(stat, '0|g', 1)
+ pipe._send_stat(stat, '%s|g' % value, 1)
+ else:
+ prefix = '+' if delta and value >= 0 else ''
+ self._send_stat(stat, '%s%s|g' % (prefix, value), rate)
def set(self, stat, value, rate=1):
"""Set a set value."""
diff --git a/statsd/tests.py b/statsd/tests.py
index 54a3773..c5d9ce9 100644
--- a/statsd/tests.py
+++ b/statsd/tests.py
@@ -146,6 +146,24 @@ def test_gauge_delta():
yield _check, num, result
+def test_gauge_absolute_negative():
+ sc = _client()
+ sc.gauge('foo', -5, delta=False)
+ _sock_check(sc, 1, 'foo:0|g\nfoo:-5|g')
+
+
+@mock.patch.object(random, 'random')
+def test_gauge_absolute_negative_rate(mock_random):
+ sc = _client()
+ mock_random.return_value = -1
+ sc.gauge('foo', -1, rate=0.5, delta=False)
+ _sock_check(sc, 1, 'foo:0|g\nfoo:-1|g')
+
+ mock_random.return_value = 2
+ sc.gauge('foo', -2, rate=0.5, delta=False)
+ _sock_check(sc, 1, 'foo:0|g\nfoo:-1|g') # Should not have changed.
+
+
@mock.patch.object(random, 'random', lambda: -1)
def test_set():
sc = _client()
@@ -412,6 +430,15 @@ def test_pipeline_packet_size():
assert len(sc._sock.sendto.call_args_list[1][0][0]) <= 512
+def test_pipeline_negative_absolute_gauge():
+ """Negative absolute gauges use an internal pipeline."""
+ sc = _client()
+ with sc.pipeline() as pipe:
+ pipe.gauge('foo', -10, delta=False)
+ pipe.incr('bar')
+ _sock_check(sc, 1, 'foo:0|g\nfoo:-10|g\nbar:1|c')
+
+
def test_big_numbers():
num = 1234568901234
result = 'foo:1234568901234|%s'