Skip to content
This repository has been archived by the owner on Jul 23, 2024. It is now read-only.

Commit

Permalink
add support for exc_info kwarg for all of the 'oldstyle' methods, a…
Browse files Browse the repository at this point in the history
…nd default to True for `MetlogClient.exception`
  • Loading branch information
rafrombrc committed Jun 19, 2012
1 parent 4c96b29 commit cf4f6f7
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 17 deletions.
55 changes: 39 additions & 16 deletions metlog/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
40 changes: 39 additions & 1 deletion metlog/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit cf4f6f7

Please sign in to comment.