diff --git a/.arclint b/.arclint --- a/.arclint +++ b/.arclint @@ -19,6 +19,7 @@ "E131": "disabled", "E201": "disabled", "E202": "disabled", + "E221": "disabled", "E225": "disabled", "E231": "disabled", "E251": "disabled", diff --git a/pykolab/logger.py b/pykolab/logger.py --- a/pykolab/logger.py +++ b/pykolab/logger.py @@ -35,16 +35,27 @@ self.logger = logger self.log_level = log_level self.linebuf = '' + self.skip_next = False def write(self, buf): - # ugly patch to make smtplib debug logging records appear on one line in log file + # ugly patch to make smtplib and smtpd debug logging records appear on one line in log file # smtplib uses "print>>stderr, var, var" statements for debug logging. These # statements are splited into separate lines on separating whitespace. + for line in buf.rstrip().splitlines(): + if self.skip_next: + self.skip_next = False + continue + if buf != '\n': - if line.startswith('send:') or line.startswith('reply:'): + linestarts = line.split(':')[0] + if linestarts in ['send', 'reply', 'Data', 'recips', 'Peer', 'sender']: self.linebuf = line - return + elif linestarts.startswith('===>'): + # Do not log lines starting with ====> + self.linebuf = '' + self.skip_next = True + continue else: self.logger.log(self.log_level, '%s %s', self.linebuf, line.rstrip()[:150]) self.linebuf = '' diff --git a/wallace/__init__.py b/wallace/__init__.py --- a/wallace/__init__.py +++ b/wallace/__init__.py @@ -26,7 +26,7 @@ import os import pwd import traceback -from smtpd import SMTPChannel +import smtpd import socket import struct import sys @@ -42,6 +42,7 @@ # pylint: disable=invalid-name log = pykolab.getLogger('pykolab.wallace') +sys.stderr = pykolab.logger.StderrToLogger(log) conf = pykolab.getConf() @@ -128,10 +129,15 @@ while True: while not self.finished.is_set(): self.finished.wait(self.interval) + log.debug(_("Timer looping function '%s' every %ss") % ( + self.function.__name__, + self.interval + ), level=8) self.function(*self.args, **self.kwargs) self.finished.set() - + log.debug(_("Timer loop %s") % ('still active','finished')[self.finished.is_set()], level=8) + break class WallaceDaemon: def __init__(self): @@ -176,6 +182,15 @@ help=_("Number of threads to use.") ) + daemon_group.add_option( + "--max-tasks", + dest = "max_tasks", + action = "store", + default = 10, + type = int, + help = _("Number of tasks per process.") + ) + daemon_group.add_option( "-p", "--pid-file", dest="pidfile", @@ -226,7 +241,7 @@ self.parent_pid = os.getpid() if version.StrictVersion(sys.version[:3]) >= version.StrictVersion("2.7"): - self.pool = multiprocessing.Pool(conf.max_threads, worker_process, (), 1) + self.pool = multiprocessing.Pool(conf.max_threads, worker_process, (), conf.max_tasks) else: self.pool = multiprocessing.Pool(conf.max_threads, worker_process, ()) @@ -297,16 +312,25 @@ try: while 1: while self.current_connections >= self.max_connections: - log.debug("Out of connections.") + log.debug(_("Reached limit of max connections of: %s. Sleeping for 0.5s") % self.max_connections, level=6) time.sleep(0.5) pair = s.accept() - log.info(_("Accepted connection")) + log.debug(_("Accepted connection %r with address %r") % (pair if pair is not None else (None, None)), level=8) if pair is not None: self.current_connections += 1 connection, address = pair - SMTPChannel(self, connection, address) + + _smtpd = smtpd + # Set DEBUGSTREAM of smtpd to log to pykolab logger + if conf.debuglevel > 8: + _smtpd.DEBUGSTREAM = pykolab.logger.StderrToLogger(log) + + log.debug(_("Creating SMTPChannel for accepted message"), level=8) + channel = _smtpd.SMTPChannel(self, connection, address) asyncore.loop() + else: + log.error(_("Socket accepted, but (conn, address) tuple is None.")) # pylint: disable=broad-except except Exception: @@ -431,6 +455,7 @@ os.write(fp, data) os.close(fp) + log.debug(_("Started processing accepted message %s") % filename, level=8) self.pool.apply_async(pickup_message, (filename, (self.modules))) self.current_connections -= 1