From 9218215a037d01094640b0094cc197e8a698e898 Mon Sep 17 00:00:00 2001 From: Clint Byrum Date: Tue, 3 Nov 2015 16:13:05 -0800 Subject: [PATCH] Add counters2statsd This is intended as a plugin for use with subunit2sql to "store" attachments in statsd. Implements: counter-inspection --- openstack_qa_tools/counters2statsd.py | 59 +++++++++++++++++++ .../tests/test_counters2statsd.py | 41 +++++++++++++ requirements.txt | 2 + 3 files changed, 102 insertions(+) create mode 100644 openstack_qa_tools/counters2statsd.py create mode 100644 openstack_qa_tools/tests/test_counters2statsd.py diff --git a/openstack_qa_tools/counters2statsd.py b/openstack_qa_tools/counters2statsd.py new file mode 100644 index 0000000..fa89f10 --- /dev/null +++ b/openstack_qa_tools/counters2statsd.py @@ -0,0 +1,59 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +from oslo_config import cfg +import statsd + +OPTS_GROUP = cfg.OptGroup(name='counters2statsd', title='Counters2Statsd') + +OPTS = [ + cfg.StrOpt('host', help='Statsd host to connect to', default=None), + cfg.IntOpt('port', help='Port on statsd host to connect to', default=None), + cfg.StrOpt('prefix', help='Prefix to add to stats', default=None), +] + +_statsd_client = None + + +def get_statsd_client(): + global _statsd_client + if _statsd_client is None: + cfg.CONF.register_group(OPTS_GROUP) + cfg.CONF.register_opts(OPTS, group=OPTS_GROUP) + _statsd_client = statsd.StatsClient(cfg.CONF.counters2statsd.host, + cfg.CONF.counters2statsd.port, + cfg.CONF.counters2statsd.prefix) + return _statsd_client + + +def add_test_run_attachments(attachments, test_run_id, session): + for attachment in attachments: + try: + counters = json.loads(attachment) + except ValueError: + continue + if not isinstance(counters, dict): + continue + if '__counters_meta__' not in counters: + continue + client = get_statsd_client() + for groupname, values in counters.items(): + if not isinstance(values, dict): + continue + for k, v in values.items(): + k = '{}.{}'.format(groupname, k) + try: + v = int(v) + except ValueError: + continue + client.incr(k, v) diff --git a/openstack_qa_tools/tests/test_counters2statsd.py b/openstack_qa_tools/tests/test_counters2statsd.py new file mode 100644 index 0000000..9aa754e --- /dev/null +++ b/openstack_qa_tools/tests/test_counters2statsd.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +test_counters2statsd +---------------------------------- + +Tests for `openstack_qa_tools.counters2statsd` +""" + +import json +import mock + +from openstack_qa_tools import counters2statsd +from openstack_qa_tools.tests import base + + +class TestOpenStackQaTols(base.TestCase): + + @mock.patch('statsd.StatsClient') + def test_add_test_run_attachments(self, statsd_mock): + mock_client = mock.MagicMock('statsd_client') + mock_client.incr = mock.MagicMock('statds_incr') + statsd_mock.return_value = mock_client + fake_counters = {'mysql': {'Queries': 10}} + fake_counters['__counters_meta__'] = {} + fake_counters = json.dumps(fake_counters) + counters2statsd.add_test_run_attachments([fake_counters], 'foo', None) + statsd_mock.assert_called_with(None, None, None) + mock_client.incr.assert_called_with('mysql.Queries', 10) diff --git a/requirements.txt b/requirements.txt index 2dff530..2797be4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,5 @@ pbr>=1.6 PyMySQL>=0.6.2 # MIT License +statsd>=1.0.0,<3.0 +oslo.config>=1.4.0.0a3