Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 2 commits
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jun 19, 2012
@rafrombrc rafrombrc add support for `exc_info` kwarg for all of the 'oldstyle' methods, a…
…nd default to True for `MetlogClient.exception`
cf4f6f7
@rafrombrc rafrombrc Merge pull request #27 from mozilla-services/ra/exc_info_support
add support for `exc_info` kwarg, r=rfkelly
c024cf7
Showing with 78 additions and 17 deletions.
  1. +39 −16 metlog/client.py
  2. +39 −1 metlog/tests/test_client.py
View
55 metlog/client.py
@@ -14,11 +14,17 @@
#
# ***** END LICENSE BLOCK *****
from __future__ import absolute_import
+try:
+ import cStringIO as StringIO
+except ImportError:
+ import StringIO # NOQA
import os
import random
import socket
+import sys
import threading
import time
+import traceback
import types
from datetime import datetime
@@ -297,35 +303,52 @@ def incr(self, name, count=1, timestamp=None, logger=None, severity=None,
self.metlog('counter', timestamp, logger, severity, payload, fields)
# Standard Python logging API emulation
- def _oldstyle(self, severity, msg, *args):
+ def _oldstyle(self, severity, msg, *args, **kwargs):
"""Do any necessary string formatting and then generate the msg"""
# if `args` is a mapping then extract it
if (len(args) == 1 and hasattr(args[0], 'keys')
and hasattr(args[0], '__getitem__')):
args = args[0]
msg = msg % args
+ exc_info = kwargs.get('exc_info', False)
+ if exc_info:
+ if not isinstance(exc_info, tuple):
+ exc_info = sys.exc_info()
+ sio = StringIO.StringIO()
+ traceback.print_exception(exc_info[0], exc_info[1], exc_info[2],
+ None, sio)
+ s = sio.getvalue()
+ sio.close()
+ if s[-1:] == '\n':
+ s = s[:-1]
+ if msg[-1:] != '\n':
+ msg = msg + '\n'
+ try:
+ msg = msg + s
+ except UnicodeError:
+ msg = msg + s.decode(sys.getfilesystemencoding())
self.metlog(type='oldstyle', severity=severity, payload=msg)
- def debug(self, msg, *args):
+ def debug(self, msg, *args, **kwargs):
""" Log a DEBUG level message """
- self._oldstyle(SEVERITY.DEBUG, msg, *args)
+ self._oldstyle(SEVERITY.DEBUG, msg, *args, **kwargs)
- def info(self, msg, *args):
- """ Log a INFO level message """
- self._oldstyle(SEVERITY.INFORMATIONAL, msg, *args)
+ def info(self, msg, *args, **kwargs):
+ """ Log an INFO level message """
+ self._oldstyle(SEVERITY.INFORMATIONAL, msg, *args, **kwargs)
- def warn(self, msg, *args):
+ def warn(self, msg, *args, **kwargs):
""" Log a WARN level message """
- self._oldstyle(SEVERITY.WARNING, msg, *args)
+ self._oldstyle(SEVERITY.WARNING, msg, *args, **kwargs)
- def error(self, msg, *args):
- """ Log a ERROR level message """
- self._oldstyle(SEVERITY.ERROR, msg, *args)
+ def error(self, msg, *args, **kwargs):
+ """ Log an ERROR level message """
+ self._oldstyle(SEVERITY.ERROR, msg, *args, **kwargs)
- def exception(self, msg, *args):
- """ Log a ALERT level message """
- self._oldstyle(SEVERITY.ALERT, msg, *args)
+ def exception(self, msg, exc_info=True, *args, **kwargs):
+ """ Log an ALERT level message """
+ self._oldstyle(SEVERITY.ALERT, msg, exc_info=exc_info, *args, **kwargs)
- def critical(self, msg, *args):
+ def critical(self, msg, *args, **kwargs):
""" Log a CRITICAL level message """
- self._oldstyle(SEVERITY.CRITICAL, msg, *args)
+ self._oldstyle(SEVERITY.CRITICAL, msg, *args, **kwargs)
View
40 metlog/tests/test_client.py
@@ -18,8 +18,9 @@
from nose.tools import eq_, ok_
from metlog.senders.dev import DebugCaptureSender
-import socket
import os
+import socket
+import sys
import threading
import time
@@ -105,6 +106,43 @@ def test_oldstyle_mapping_arg(self):
full_msg = self._extract_full_msg()
eq_(full_msg['payload'], payload % args)
+ def test_oldstyle_exc_info(self):
+ payload = 'traceback ahead -->'
+ try:
+ a = b # NOQA
+ except NameError:
+ self.client.error(payload, exc_info=True)
+ full_msg = self._extract_full_msg()
+ ok_(full_msg['payload'].startswith(payload))
+ ok_("NameError: global name 'b' is not defined" in full_msg['payload'])
+ ok_('test_client.py' in full_msg['payload'])
+
+ def test_oldstyle_exc_info_auto(self):
+ payload = 'traceback ahead -->'
+ try:
+ a = b # NOQA
+ except NameError:
+ self.client.exception(payload)
+ full_msg = self._extract_full_msg()
+ ok_(full_msg['payload'].startswith(payload))
+ ok_("NameError: global name 'b' is not defined" in full_msg['payload'])
+ ok_('test_client.py' in full_msg['payload'])
+
+ def test_oldstyle_exc_info_passed(self):
+ def name_error():
+ try:
+ a = b # NOQA
+ except NameError:
+ return sys.exc_info()
+
+ ei = name_error()
+ payload = 'traceback ahead -->'
+ self.client.critical(payload, exc_info=ei)
+ full_msg = self._extract_full_msg()
+ ok_(full_msg['payload'].startswith(payload))
+ ok_("NameError: global name 'b' is not defined" in full_msg['payload'])
+ ok_('test_client.py' in full_msg['payload'])
+
def test_timer_contextmanager(self):
name = self.timer_name
with self.client.timer(name) as timer:

No commit comments for this range

Something went wrong with that request. Please try again.