diff --git a/os_performance_tools/counters2statsd.py b/os_performance_tools/counters2statsd.py index 977a290..5316884 100644 --- a/os_performance_tools/counters2statsd.py +++ b/os_performance_tools/counters2statsd.py @@ -33,13 +33,45 @@ OPTS = [ _statsd_client = None +class Pipeline(object): + '''Wrapper for statsd.Pipeline + + statsd's API doesn't say if prefix can be changed on the fly so + we're going to assume it cannot be and make a wrapper that does that. + ''' + def __init__(self, pipeline, dynamic_prefix=None): + self.pipeline = pipeline + self.dynamic_prefix = dynamic_prefix + + def _add_dynamic_prefix(self, call, *args, **kwargs): + if args: + args = list(args) + stat = args.pop(0) + elif 'stat' in kwargs: + stat = kwargs.pop('stat') + else: + return call(*args, **kwargs) + if self.dynamic_prefix: + stat = '{}.{}'.format(self.dynamic_prefix, stat) + call(stat, *args, **kwargs) + + def incr(self, *args, **kwargs): + return self._add_dynamic_prefix(self.pipeline.incr, *args, **kwargs) + + def timing(self, *args, **kwargs): + return self._add_dynamic_prefix(self.pipeline.timing, *args, **kwargs) + + def send(self): + return self.pipeline.send() + + def get_statsd_client(): global _statsd_client if _statsd_client is None: _statsd_client = statsd.StatsClient(cfg.CONF.counters2statsd.host, cfg.CONF.counters2statsd.port, cfg.CONF.counters2statsd.prefix) - _statsd_client = _statsd_client.pipeline() + _statsd_client = Pipeline(_statsd_client.pipeline()) return _statsd_client @@ -94,6 +126,7 @@ class AttachmentResult(testtools.StreamResult): continue if not isinstance(counters, dict): continue + client.dynamic_prefix = counters.get('__meta__', {}).get('prefix') for groupname, values in counters.items(): if not isinstance(values, dict): continue diff --git a/os_performance_tools/tests/test_counters2statsd.py b/os_performance_tools/tests/test_counters2statsd.py index 45e2e1e..379c0b3 100644 --- a/os_performance_tools/tests/test_counters2statsd.py +++ b/os_performance_tools/tests/test_counters2statsd.py @@ -62,6 +62,7 @@ class TestCounters2Statsd(base.TestCase): '__meta__': { 'unixtime': time.time(), 'delta_seconds': 10.5, + 'prefix': 'all-tests', }, 'mysql': { 'Queries': 50 @@ -73,6 +74,6 @@ class TestCounters2Statsd(base.TestCase): result.status(file_name='counters.json', file_bytes=fake_counters) result.stopTestRun() statsd_mock.assert_called_with('localhost', 8125, None) - mock_pipeline.timing.assert_called_with('testrun', 10500) - mock_pipeline.incr.assert_called_with('mysql.Queries', 50) + mock_pipeline.timing.assert_called_with('all-tests.testrun', 10500) + mock_pipeline.incr.assert_called_with('all-tests.mysql.Queries', 50) mock_pipeline.send.assert_called_with()