Add Connector.timer.

This improves compatibility with python-statsd.
This commit is contained in:
Dave Shawley 2021-07-18 10:10:41 -04:00
parent 3291306305
commit 75bb621784
No known key found for this signature in database
GPG key ID: F41A8A99298F8EED
4 changed files with 52 additions and 1 deletions

View file

@ -1,3 +1,7 @@
Next release
------------
- Added ``Connector.timer`` method (addresses :issue:`8`)
:tag:`0.1.0 <0.0.1...0.1.0>` (10-May-2021)
------------------------------------------
- Added :envvar:`STATSD_ENABLED` environment variable to disable the Tornado integration

View file

@ -19,6 +19,7 @@ intersphinx_mapping = {
# https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html
extensions.append('sphinx.ext.extlinks')
extlinks = {
'issue': ("https://github.com/sprockets/sprockets-statsd/issues/%s", "#%s"),
'tag': ("https://github.com/sprockets/sprockets-statsd/compare/%s", "%s"),
}

View file

@ -1,6 +1,8 @@
import asyncio
import contextlib
import logging
import socket
import time
import typing
@ -108,6 +110,20 @@ class AbstractConnector:
"""
self.inject_metric(f'timers.{path}', str(seconds * 1000.0), 'ms')
@contextlib.contextmanager
def timer(self, path):
"""Send a timer metric using a context manager.
:param path: timer to append the measured time to
"""
start = time.time()
try:
yield
finally:
fini = time.time()
self.timing(path, max(fini, start) - start)
class Connector(AbstractConnector):
"""Sends metrics to a statsd server.

View file

@ -286,6 +286,12 @@ class ConnectorTests(ProcessorTestCase):
recvd_path, _, rest = decoded.partition(':')
recvd_value, _, recvd_code = rest.partition('|')
self.assertEqual(path, recvd_path, 'metric path mismatch')
if type_code == 'ms':
self.assertAlmostEqual(float(recvd_value),
value,
places=3,
msg='metric value mismatch')
else:
self.assertEqual(recvd_value, str(value), 'metric value mismatch')
self.assertEqual(recvd_code, type_code, 'metric type mismatch')
@ -331,6 +337,30 @@ class ConnectorTests(ProcessorTestCase):
self.assert_metrics_equal(self.statsd_server.metrics[0],
'timers.simple.timer', 12340.0, 'ms')
async def test_timing_context_manager(self):
with unittest.mock.patch(
'sprockets_statsd.statsd.time.time') as time_function:
time_function.side_effect = [10.0, 22.345]
with self.connector.timer('some.timer'):
pass
self.assertEqual(2, time_function.call_count)
await self.wait_for(self.statsd_server.message_received.acquire())
self.assert_metrics_equal(self.statsd_server.metrics[0],
'timers.some.timer', 12345.0, 'ms')
async def test_timer_is_monotonic(self):
with unittest.mock.patch(
'sprockets_statsd.statsd.time.time') as time_function:
time_function.side_effect = [10.001, 10.000]
with self.connector.timer('some.timer'):
pass
self.assertEqual(2, time_function.call_count)
await self.wait_for(self.statsd_server.message_received.acquire())
self.assert_metrics_equal(self.statsd_server.metrics[0],
'timers.some.timer', 0.0, 'ms')
async def test_that_queued_metrics_are_drained(self):
# The easiest way to test that the internal metrics queue
# is drained when the processor is stopped is to monkey