X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=t%2Fmoe%2Flog.py;h=c2ab4d23fd575cd2d5cdcdb74c36cfd2657617de;hb=c5561169bd9291368179825d380a55e4dbc2a339;hp=4b8e586040cfef37cdffd214c3044f868719fd67;hpb=0a77788ddfe8a82e97cee71d31f9a79f5bf1cee4;p=eval.git diff --git a/t/moe/log.py b/t/moe/log.py index 4b8e586..c2ab4d2 100644 --- a/t/moe/log.py +++ b/t/moe/log.py @@ -1,12 +1,89 @@ #!/usr/bin/env python -import sys +import sys, os +import logging +from logging import Logger, StreamHandler -def say(msg): - sys.stdout.write(msg + "\n") -def verbose(msg): - sys.stdout.write(msg) +class Loggers(Logger): + """Defines several logs: -def progress(msg): - sys.stdout.write(msg) + `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` + + Currently, the logs and fd's get never closed. + + TODO: formatters + WARN: Currently, the module changes fd's 1 and 2, this is a global change. + """ + 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.addHandler(h) + self.user.debug('Logging started') + + def open_eval_log(self, filename, level, redirect_fds = True): + """Open user (progress) logfile. + Leaves logging to stderr active. If told to, redirects fd's 1 and 2 to this file.""" + self.eval_file = open(filename, 'w', 0) + self.eval_handler = StreamHandler(self.eval_file) + self.eval_handler.setFormatter(Formatter('%(message)s')) + self.user.addHandler(self.eval_handler) + if redirect_fds: + os.dup2(self.eval_file.fileno(), 1) + os.dup2(self.eval_file.fileno(), 2) + self.user.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)