Skip to content
Browse files

Merge pull request #14 from mozilla-services/ra/metlog_wrapper_refactor

Merged changes to metlog integration for new metlog-py APIs
  • Loading branch information...
2 parents 69ba1e5 + 066e620 commit 8eca0ad87990dd16331af6d6c494ddd8711ecdf4 @rfk rfk committed May 2, 2012
Showing with 64 additions and 65 deletions.
  1. +25 −16 mozsvc/metrics.py
  2. +31 −31 mozsvc/tests/test_metrics.py
  3. +8 −18 mozsvc/tests/test_partial_disable_metrics.py
View
41 mozsvc/metrics.py
@@ -16,43 +16,52 @@
from contextlib import contextmanager
from cornice import Service
+from metlog.config import client_from_dict_config
from metlog.decorators import timeit, incr_count
-from metlog.decorators.base import CLIENT_WRAPPER, MetlogDecorator
+from metlog.decorators.base import MetlogDecorator
+from metlog.holder import CLIENT_HOLDER
import threading
_LOCAL_STORAGE = threading.local()
-def setup_metlog(config_dict):
+def setup_metlog(config_dict, default=False):
"""
- Instantiate the Metlog client and set up the client wrapper.
+ Instantiate a Metlog client and add it to the client holder.
:param config_dict: Dictionary object containing the metlog client
configuration.
+ :param default: Should this be specified as CLIENT_HOLDER's default
+ client? Note that the first client to be added will
+ automatically be specified as the default, regardless
+ of the value of this argument.
"""
- CLIENT_WRAPPER.activate(config_dict)
+ name = config_dict.get('logger', '')
+ client = CLIENT_HOLDER.get_client(name)
+ client = client_from_dict_config(config_dict, client)
+ if default:
+ CLIENT_HOLDER.set_default_client_name(name)
-def teardown_metlog():
+def get_metlog_client(name=None):
"""
- Reset the client wrapper. Usually only needed for tests.
- """
- CLIENT_WRAPPER.reset()
-
+ Return the specified Metlog client from the CLIENT_HOLDER.
-def get_metlog_client():
- """
- Return the currently configured Metlog client. Will not work until
- `setup_metlog` has been called to initialize the client wrapper.
+ :param name: Name of metlog client to fetch. If not provided the
+ holder's specified default client will be used.
"""
- return CLIENT_WRAPPER.client
+ if name is not None:
+ client = CLIENT_HOLDER.get_client(name)
+ else:
+ client = CLIENT_HOLDER.default_client
+ return client
class MetlogPlugin(object):
def __init__(self, **kwargs):
setup_metlog(kwargs)
- self.client = CLIENT_WRAPPER.client
+ self.client = CLIENT_HOLDER.default_client
def get_tlocal():
@@ -105,7 +114,7 @@ def send_logmsg(tl_data):
Stuff the threadlocal data into the message and send it out.
"""
webserv_log['threadlocal'] = tl_data
- CLIENT_WRAPPER.client.metlog('wsgi', fields=webserv_log)
+ self.client.metlog('wsgi', fields=webserv_log)
with thread_context(send_logmsg):
return self._fn(*args, **kwargs)
View
62 mozsvc/tests/test_metrics.py
@@ -67,26 +67,26 @@ def setUp(self):
def test_loading_from_config(self):
plugin = self.plugin
- self.assertTrue(len(plugin.client.sender.msgs) == 0)
+ self.assertEqual(len(plugin.client.sender.msgs), 0)
@timeit
def target_callable(x, y):
return x + y
result = target_callable(5, 6)
- self.assertTrue(result == 11)
- self.assertTrue(len(plugin.client.sender.msgs) == 1)
+ self.assertEqual(result, 11)
+ self.assertEqual(len(plugin.client.sender.msgs), 1)
obj = json.loads(plugin.client.sender.msgs[0])
- expected = 'mozsvc.tests.test_metrics:target_callable'
+ expected = 'mozsvc.tests.test_metrics.target_callable'
actual = obj['fields']['name']
- self.assertTrue(actual == expected)
+ self.assertEqual(actual, expected)
# Now test to make sure we can enque 2 messages using stacked
# decorators
plugin.client.sender.msgs.clear()
- self.assertTrue(len(plugin.client.sender.msgs) == 0)
+ self.assertEqual(len(plugin.client.sender.msgs), 0)
@incr_count
@timeit
@@ -95,20 +95,20 @@ def new_target_callable(x, y):
result = new_target_callable(5, 6)
msgs = [json.loads(m) for m in plugin.client.sender.msgs]
- self.assertTrue(len(msgs) == 2)
+ self.assertEqual(len(msgs), 2)
# Names should be preserved
- self.assertTrue(new_target_callable.__name__ == 'new_target_callable')
+ self.assertEqual(new_target_callable.__name__, 'new_target_callable')
for msg in msgs:
- expected = 'mozsvc.tests.test_metrics:target_callable'
+ expected = 'mozsvc.tests.test_metrics.target_callable'
actual = obj['fields']['name']
- self.assertTrue(actual == expected)
+ self.assertEqual(actual, expected)
# First msg should be timer then the counter
# as decorators just wrap each other
- self.assertTrue(msgs[0]['type'] == 'timer')
- self.assertTrue(msgs[1]['type'] == 'counter')
+ self.assertEqual(msgs[0]['type'], 'timer')
+ self.assertEqual(msgs[1]['type'], 'counter')
class TestCannedDecorators(unittest.TestCase):
@@ -128,7 +128,7 @@ def test_decorator_ordering(self):
plugin = self.plugin
plugin.client.sender.msgs.clear()
- self.assertTrue(len(plugin.client.sender.msgs) == 0)
+ self.assertEqual(len(plugin.client.sender.msgs), 0)
@incr_count
@timeit
@@ -137,20 +137,20 @@ def ordering_1(x, y):
ordering_1(5, 6)
msgs = [json.loads(m) for m in plugin.client.sender.msgs]
- self.assertTrue(len(msgs) == 2)
+ self.assertEqual(len(msgs), 2)
for msg in msgs:
- expected = 'mozsvc.tests.test_metrics:ordering_1'
+ expected = 'mozsvc.tests.test_metrics.ordering_1'
actual = msg['fields']['name']
- self.assertTrue(actual == expected)
+ self.assertEqual(actual, expected)
# First msg should be counter, then timer as decorators are
# applied inside to out, but execution is outside -> in
- self.assertTrue(msgs[0]['type'] == 'timer')
- self.assertTrue(msgs[1]['type'] == 'counter')
+ self.assertEqual(msgs[0]['type'], 'timer')
+ self.assertEqual(msgs[1]['type'], 'counter')
plugin.client.sender.msgs.clear()
- self.assertTrue(len(plugin.client.sender.msgs) == 0)
+ self.assertEqual(len(plugin.client.sender.msgs), 0)
@timeit
@incr_count
@@ -159,24 +159,24 @@ def ordering_2(x, y):
ordering_2(5, 6)
msgs = [json.loads(m) for m in plugin.client.sender.msgs]
- self.assertTrue(len(msgs) == 2)
+ self.assertEqual(len(msgs), 2)
for msg in msgs:
- expected = 'mozsvc.tests.test_metrics:ordering_2'
+ expected = 'mozsvc.tests.test_metrics.ordering_2'
actual = msg['fields']['name']
- self.assertTrue(actual == expected)
+ self.assertEqual(actual, expected)
# Ordering of log messages should occur in the in->out
# ordering of decoration
- self.assertTrue(msgs[0]['type'] == 'counter')
- self.assertTrue(msgs[1]['type'] == 'timer')
+ self.assertEqual(msgs[0]['type'], 'counter')
+ self.assertEqual(msgs[1]['type'], 'timer')
def test_apache_logger(self):
plugin = self.plugin
plugin.client.sender.msgs.clear()
msgs = plugin.client.sender.msgs
- self.assertTrue(len(msgs) == 0)
+ self.assertEqual(len(msgs), 0)
@apache_log
def some_method(request):
@@ -190,7 +190,7 @@ def some_method(request):
some_method(req)
msg = json.loads(plugin.client.sender.msgs[0])
self.assertTrue('foo' in msg['fields']['threadlocal'])
- self.assertTrue(msg['fields']['threadlocal']['foo'] == 'bar')
+ self.assertEqual(msg['fields']['threadlocal']['foo'], 'bar')
user_info = MetricsService(name='users', path='/{username}/info',
@@ -233,11 +233,11 @@ def test_metrics_service(self):
'SERVER_PORT': 80,
})
resp = get_info(req)
- self.assertTrue(resp == 'foo')
+ self.assertEqual(resp, 'foo')
plugin = self.plugin
msgs = [json.loads(m) for m in plugin.client.sender.msgs]
- self.assertTrue(len(msgs) == 2)
+ self.assertEqual(len(msgs), 2)
self.assertTrue('timer' in [m['type'] for m in msgs])
self.assertTrue('wsgi' in [m['type'] for m in msgs])
@@ -247,12 +247,12 @@ def test_decorate_at_constructor(self):
'SERVER_PORT': 80,
})
resp = auto_decorate(req)
- self.assertTrue(resp == 'foo')
+ self.assertEqual(resp, 'foo')
plugin = self.plugin
msgs = [json.loads(m) for m in plugin.client.sender.msgs]
msg_types = [m['type'] for m in msgs]
- self.assertTrue(len(msgs) == 3)
+ self.assertEqual(len(msgs), 3)
self.assertTrue('timer' in msg_types)
self.assertTrue('counter' in msg_types)
self.assertTrue('wsgi' in msg_types)
@@ -267,5 +267,5 @@ def test_decorator_override(self):
plugin = self.plugin
msgs = [json.loads(m) for m in plugin.client.sender.msgs]
- self.assertTrue(len(msgs) == 1)
+ self.assertEqual(len(msgs), 1)
self.assertTrue('counter' in [m['type'] for m in msgs])
View
26 mozsvc/tests/test_partial_disable_metrics.py
@@ -26,31 +26,26 @@
class TestDisabledTimers(unittest.TestCase):
"""
- We want the counter decorators to fire, but the timer decorators
- should not
+ We want the counter decorators to fire, but the timer decorators should not
"""
def setUp(self):
config = Config(StringIO(dedent("""
[test1]
- enabled=true
backend = mozsvc.metrics.MetlogPlugin
sender_class=metlog.senders.DebugCaptureSender
- disable_timeit=true
+ global_disabled_decorators = timeit
+ something
""")))
settings = {"config": config}
config = Configurator(settings=settings)
self.plugin = load_and_register("test1", config)
config.commit()
def test_only_some_decorators(self):
- '''
- decorator ordering may matter when Ops goes to look at the
- logs. Make sure we capture stuff in the right order
- '''
plugin = self.plugin
plugin.client.sender.msgs.clear()
- assert len(plugin.client.sender.msgs) == 0
+ self.assertEqual(len(plugin.client.sender.msgs), 0)
@incr_count
@timeit
@@ -59,15 +54,10 @@ def no_timer(x, y):
no_timer(5, 6)
msgs = [json.loads(m) for m in plugin.client.sender.msgs]
- assert len(msgs) == 1
+ self.assertEqual(len(msgs), 1)
- for msg in msgs:
- expected = 'mozsvc.tests.test_partial_disable_metrics:no_timer'
- actual = msg['fields']['name']
- assert actual == expected
-
- # First msg should be counter, then timer as decorators are
- # applied inside to out, but execution is outside -> in
- assert msgs[0]['type'] == 'counter'
+ expected = 'mozsvc.tests.test_partial_disable_metrics.no_timer'
+ self.assertEqual(msgs[0]['fields']['name'], expected)
+ self.assertEqual(msgs[0]['type'], 'counter')
plugin.client.sender.msgs.clear()

0 comments on commit 8eca0ad

Please sign in to comment.
Something went wrong with that request. Please try again.