X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=inline;f=t%2Fmoe%2Flog.py;h=9a7f9d8c4256398a3bb5d874289aa58516d95d1c;hb=8020078dd0c80b9b6680244c586c8a34c1912682;hp=0695b79dbad43d967a39f88aba96812c1cc81a6b;hpb=fdf195df30677b8552bb7fedc34f760120268a30;p=eval.git diff --git a/t/moe/log.py b/t/moe/log.py index 0695b79..9a7f9d8 100644 --- a/t/moe/log.py +++ b/t/moe/log.py @@ -1,24 +1,107 @@ #!/usr/bin/env python -import sys +""" -class MoeLog: +`Loggers` is a collection of logggers for :class:`~moe.eval.Eval`, initializing 4 subloggers (see class description). - def __init__(self): - self.verbosity = 0 - self.progress_file = sys.stdout - self.log_file = None +Use as `e.log.debug(...)` for main log that goes both to `test` and `main` log, +`e.log.test.debug(...)` for individual logs. - def say(self, msg): - if self.log_file: - self.log_file.write(msg) +.. :data:: DDEBUG = 5 + Very verbose debugging level - def verbose(self, msg): - if self.verbosity and self.log_file: - self.log_file.write(msg) +""" - def progress(self, msg): - if self.progress: - self.progress.write(msg) -default = MoeLog() +import sys, os +import logging +from logging import Logger, StreamHandler + +logging.addLevelName(5,'DDEBUG') + + +class Loggers(Logger): + """Defines several logs: + + `self` + root log, which sends messages to `eval` and `test` logs + `self.eval` + main log, initially a duplicated fd 2 (stderr) + `self.user` + public progress log, initially a duplicated fd 1 (stdout) + `self.test` + per-test log, initially no handler, to be directed to file like `{TEST}.log` + + .. note:: Currently, the logs and fd's get never closed. + .. warning:: `Loggers.open_eval_log` changes global fd's 1 and 2 by default. + """ + def __init__(self): + "Initialize loggers as described in class description." + Logger.__init__(self, '') + # Duplicate the fd's + self.orig_stdout_fd = os.dup(1) + self.orig_stdout_file = os.fdopen(self.orig_stdout_fd, 'w', 0) + self.orig_stderr_fd = os.dup(2) + self.orig_stderr_file = os.fdopen(self.orig_stderr_fd, 'w', 0) + # Eval main logger + self.eval = Logger('eval') + self.eval.addHandler(StreamHandler(self.orig_stderr_file)) + # per-test logger + self.test = Logger('test') + self.test_handler = None + self.test_file = None + # user progress logger + self.user = Logger('user') + self.eval.addHandler(StreamHandler(self.orig_stdout_file)) + + self.addHandler(self.test) + self.addHandler(self.eval) + self.debug('Logging initialized.') + + def open_user_log(self, filename, level=logging.INFO): + """Open user (progress) logfile. Leaves logging to stdout active.""" + h = StreamHandler(open(filename, 'w', 0)) + h.setFormatter(Formatter('%(message)s')) + self.user.setLevel(level) + self.user.addHandler(h) + self.user.debug('Logging started') + + def open_eval_log(self, filename, level, redirect_fds = True): + """Open main logfile. + Leaves logging to stderr active. If told to, redirects fd's 1 and 2 to this file. + Sets level of both `self.eval` and `self`.""" + self.eval_file = open(filename, 'w', 0) + self.eval_handler = StreamHandler(self.eval_file) + self.eval_handler.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s')) + self.eval.addHandler(self.eval_handler) + if redirect_fds: + os.dup2(self.eval_file.fileno(), 1) + os.dup2(self.eval_file.fileno(), 2) + self.eval.setLevel(level) + self.setLevel(level) + self.eval.debug('Logging started') + + + def open_test_log(self, filename, level): + """Open per-test log file, like "{TEST}.log". Also set handler level to `level`.""" + self.debug('Opening per-test log %s' % filename) + if self.test_handler: + self.close_test_log() + self.test_file = open(filename, 'w') + self.test_handler = StreamHandler(self.test_file) + self.test.addHandler(self.test_handler) + self.test.setLevel(level) + self.test_handler.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s')) + self.test.debug('Logging started') + + def close_test_log(self): + """Close per-test logfile, leaving only the null handler.""" + if self.test_handler: + self.test.info('Closing logfile' % filename) + self.test.removeHandler(self.test_handler) + self.test_handler = None + self.test_file.close() + + def ddebug(self, msg, *args, **kwargs): + """Log with priority 5 (normal DEBUG is 10)""" + self.log(5, msg, *args, **kwargs)