Skip to content

Commit

Permalink
Refactoring, partially by reverting changes that appear unnecessary
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Jul 24, 2010
1 parent 7945a6f commit d6966ae
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 38 deletions.
31 changes: 14 additions & 17 deletions logbook/base.py
Expand Up @@ -298,7 +298,20 @@ def _log(self, level, args, kwargs):
record.close()


class RecordDispatcher(LoggerMixin):
class Logger(LoggerMixin):
"""Instances of the Logger class reself.level present a single logging
channel. A "logging channel" indicates an area of an application. Exactly
how an "area" is defined is up to the application developer. Since an
application can have any number of areas, logging channels are identified
by a unique string. Application areas can be nested (e.g. an area of "input
processing" might include sub-areas "read CSV files", "read XLS files" and
"read Gnumeric files"). To cater for this natural nesting, channel names
are organized into a namespace hierarchy where levels are separated by
periods, much like the Java or Python package namespace. So in the instance
given above, channel names might be "input" for the upper level, and
"input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no
arbitrary limit to the depth of nesting.
"""

def __init__(self, name=None, level=NOTSET):
self.name = name
Expand Down Expand Up @@ -341,22 +354,6 @@ def process_record(self, record):
self.group.process_record(record)


class Logger(RecordDispatcher, LoggerMixin):
"""Instances of the Logger class reself.level present a single logging
channel. A "logging channel" indicates an area of an application. Exactly
how an "area" is defined is up to the application developer. Since an
application can have any number of areas, logging channels are identified
by a unique string. Application areas can be nested (e.g. an area of "input
processing" might include sub-areas "read CSV files", "read XLS files" and
"read Gnumeric files"). To cater for this natural nesting, channel names
are organized into a namespace hierarchy where levels are separated by
periods, much like the Java or Python package namespace. So in the instance
given above, channel names might be "input" for the upper level, and
"input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no
arbitrary limit to the depth of nesting.
"""


class LoggerGroup(LoggerMixin):

def __init__(self, loggers=None, level=NOTSET):
Expand Down
40 changes: 19 additions & 21 deletions logbook/more.py
Expand Up @@ -11,21 +11,18 @@

import sys

from logbook.base import LogRecord, RecordDispatcher, NOTSET, WARNING
from logbook.base import LogRecord, Logger, NOTSET, WARNING
from logbook.handlers import Handler


class TaggingLogger(RecordDispatcher):
class TaggingLogger(Logger):

def __init__(self, name=None, *tags):
RecordDispatcher.__init__(self, name)
Logger.__init__(self, name)
# create a method for each tag named
list(setattr(self, tag, lambda msg, *args, **kwargs:
self.log(tag, msg, *args, **kwargs)) for tag in tags)

def process_record(self, record):
pass

def log(self, tags, msg, *args, **kwargs):
if isinstance(tags, basestring):
tags = [tags]
Expand Down Expand Up @@ -57,31 +54,32 @@ def emit(self, record):


class FingersCrossedHandler(Handler):
def __init__(self, handler, action_level=WARNING):
"""This handler wraps another handler and will log everything in
memory until a certain level is exceeded.
"""

def __init__(self, handler, action_level=WARNING,
pull_information=True):
Handler.__init__(self)
self._level = action_level
self._handler = handler
self._records = []
self._seen_error = False

def contextbound(self, processor=None, bubble=True):
del self._records[:]
self._seen_error = False
return Handler.contextbound(self, processor, bubble)
self._pull_information = pull_information
self._action_triggered = False

def applicationbound(self, processor=None, bubble=True):
del self._records[:]
self._seen_error = False
return Handler.applicationbound(self, processor, bubble)
def enqueue(self, record):
if self._pull_information:
record.pull_information()
self._records.append(record)

def emit(self, record):
if self._seen_error:
if self._action_triggered:
return self._handler.emit(record)
elif record.level >= self._level:
for old_record in self._records:
self._handler.emit(old_record)
del self._records[:]
self._handler.emit(record)
self._seen_error = True
self._action_triggered = True
else:
#record.pull_information()
self._records.append(record)
self.enqueue(record)
2 changes: 2 additions & 0 deletions test_logbook.py
Expand Up @@ -344,9 +344,11 @@ def test_fingerscrossed(self):
with capture_stderr() as captured:
self.log.info('some info')
self.log.warning('something happened')
self.log.info('something else happened')
logs = captured.getvalue()
self.assert_('some info' in logs)
self.assert_('something happened' in logs)
self.assert_('something else happened' in logs)

def test_tagged(self):
from logbook.more import TaggingLogger, TaggingHandler
Expand Down

0 comments on commit d6966ae

Please sign in to comment.