diff --git a/agent/README.txt b/agent/README.txt index 8406555..9b6596b 100644 --- a/agent/README.txt +++ b/agent/README.txt @@ -307,8 +307,26 @@ Configuration - log format(s) - log file(s) (or other forms of persistence) +Example +------- + +We set the logging configuration to log level 20 (INFO) using the +standard log handler that prints to ``sys.stdout``. + + >>> agent.config.logging.standard = 20 >>> logger = agent.logger + >>> logger.setup() + +The we can log an event providing a dictionary with the data to be logged. + >>> logger.log(dict(object='job', event='start')) + 20... event:start object:job + +We can also look at the logging records collected in the logger. + + >>> len(logger) + 1 + >>> print logger[-1] 20... event:start object:job diff --git a/agent/core.py b/agent/core.py index a6dafe7..9f3c531 100644 --- a/agent/core.py +++ b/agent/core.py @@ -49,7 +49,7 @@ class Agent(object): transportTypes = transportTypes def __init__(self, conf=None): - config = self.config = Configurator('ui', 'crawl', 'transport', 'logger') + config = self.config = Configurator('ui', 'crawl', 'transport', 'logging') config.load(conf) self.scheduler = Scheduler(self) self.stopper = Stopper() diff --git a/agent/interfaces.py b/agent/interfaces.py index f53a977..ff2db0d 100644 --- a/agent/interfaces.py +++ b/agent/interfaces.py @@ -98,6 +98,10 @@ class ILogger(Interface): externalLoggers = Attribute('A collection of logger objects ' 'to which the logging records should be written.') + def setup(): + """ Initialize the logger with the current configuration settings. + """ + def log(data): """ Record the information given by the ``data`` argument (a mapping). @@ -108,9 +112,6 @@ class ILogRecord(Interface): """ """ - format = Attribute('An optional format string for rendering the ' - 'recorded information.') - def __str__(): """ Return a string representation suitable for writing on a log file. @@ -126,7 +127,7 @@ class ICrawlingJob(IScheduledJob): def collect(): """ Return a deferred that upon callback will provide a - collection of resource/metadata pairs that should be transferred + collection of resource objects that should be transferred to the server. Use the selection criteria given to filter the resources that diff --git a/agent/log.py b/agent/log.py index 8d6f7c7..6732edf 100644 --- a/agent/log.py +++ b/agent/log.py @@ -22,6 +22,8 @@ Log information management. $Id$ """ +import logging +import sys import time from zope.interface import implements @@ -32,15 +34,15 @@ class LogRecord(object): implements(ILogRecord) - format = None - timeFormat = '%Y-%m-%dT%H:%S' + datefmt = '%Y-%m-%dT%H:%S' - def __init__(self, data): + def __init__(self, logger, data): + self.logger = logger self.data = data self.timeStamp = time.time() def __str__(self): - msg = [str(time.strftime(self.timeFormat, time.localtime(self.timeStamp)))] + msg = [str(time.strftime(self.datefmt, time.localtime(self.timeStamp)))] for k in sorted(self.data): msg.append('%s:%s' % (str(k), str(self.data[k]))) return ' '.join(msg) @@ -52,10 +54,23 @@ class Logger(list): recordFactory = LogRecord - def __init__(self, agent, externalLoggers=[]): + + def __init__(self, agent): self.agent = agent - self.externalLoggers = externalLoggers + self.setup() + + def setup(self): + self.externalLoggers = [] + conf = self.agent.config.logging + if conf.standard: + logger = logging.getLogger() + logger.level = conf.standard + logger.addHandler(logging.StreamHandler(sys.stdout)) + self.externalLoggers.append(logger) def log(self, data): - self.append(self.recordFactory(data)) + record = self.recordFactory(self, data) + self.append(record) + for logger in self.externalLoggers: + logger.info(str(record)) diff --git a/agent/schedule.py b/agent/schedule.py index 89e31eb..9219cbf 100644 --- a/agent/schedule.py +++ b/agent/schedule.py @@ -37,7 +37,10 @@ class Scheduler(object): def __init__(self, agent): self.agent = agent self.queue = {} - self.logger = None + + @property + def logger(self): + return self.agent.logger() def schedule(self, job, startTime=None): if startTime is None: