X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=t%2Fmoe%2Flog.py;h=f98ee3f3217a49272d3627ca6394efea3231d7e6;hb=ef64f1097b0b3d210ee24f08e91c352865cac59c;hp=4b8e586040cfef37cdffd214c3044f868719fd67;hpb=0a77788ddfe8a82e97cee71d31f9a79f5bf1cee4;p=moe.git diff --git a/t/moe/log.py b/t/moe/log.py index 4b8e586..f98ee3f 100644 --- a/t/moe/log.py +++ b/t/moe/log.py @@ -1,12 +1,118 @@ #!/usr/bin/env python -import sys +""" -def say(msg): - sys.stdout.write(msg + "\n") +`Loggers` is a collection of logggers for :class:`~moe.eval.Eval`, initializing 4 subloggers (see class description). -def verbose(msg): - sys.stdout.write(msg) +Use as `e.log.debug(...)` for main log that goes both to `test` and `main` log, +`e.log.test.debug(...)` for individual logs. -def progress(msg): - sys.stdout.write(msg) +.. :data:: DDEBUG = 5 + Very verbose debugging level + +Defines several logs: + +`log` + main log, initially a duplicated fd 2 (stderr) +`userlog` + public progress log, initially a duplicated fd 1 (stdout) +`testlog` + 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. +""" + + +# Global logs to be imported by every module + +__all__ = ['log', 'userlog', 'testlog', 'pipelog' ] + +log = None +userlog = None +testlog = None +pipelog = None + +orig_stdout_fd = None +orig_stdout_file = None +orig_stderr_fd = None +orig_stderr_file = None +testlog_file = None + +import logging, sys + +def __init__(): + """Very basic loggers setup to stderr.""" + + global orig_stdout_fd, orig_stdout_file, orig_stderr_fd, orig_stderr_file + global log, userlog, + + orig_stdout_fd = os.dup(1) + orig_stdout_file = os.fdopen(orig_stdout_fd, 'w', 0) + orig_stderr_fd = os.dup(2) + orig_stderr_file = os.fdopen(orig_stderr_fd, 'w', 0) + + log = logging.getLogger('mainlog') + log.addHandler(StreamHandler(orig_stderr_file)) + + userlog = logging.getLogger('userlog') + userlog.addHandler(StreamHandler(orig_stdout_file)) + + testlog = log + pipelog = log + + logging.addLevelName(5,'DDEBUG') + + log.debug('Logging initialized.') + + +def open_user_log(filename, level=logging.INFO): + """Open user (progress) logfile. Leaves logging to stdout active.""" + h = StreamHandler(open(filename, 'w', 0)) + h.setFormatter(Formatter('%(message)s')) + userlog.setLevel(level) + userlog.addHandler(h) + + log.debug('User logging to %r started', filename) + +def open_eval_log(filename, redirect_fds = True): + """Open main logfile. + Leaves logging to stderr active. If told to, redirects fd's 1 and 2 to this file.""" + + eval_file = open(filename, 'w', 0) + h = StreamHandler(self.eval_file) + h.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s')) + log.addHandler(h) + log.debug('Opened eval logfile %r') + + if redirect_fds: + os.dup2(eval_file.fileno(), 1) + os.dup2(eval_file.fileno(), 2) + log.debug('Redirected fds 1,2 -> eval logfile') + + +def open_test_log(filename, level): + """Open per-test log file, usually "{TEST}.log", set its level.""" + + log.debug('Opening per-test log %r', filename) + + global testlog, testlog_file + assert testlog_file is None + + testlog = logging.getLogger('testlog') + testlog.setLevel(level) + for h in testlog.handlers: + testlog.removeHandler(h) + + testlog_file = open(filename, 'w') + h = StreamHandler(self.testlog_file) + h.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s')) + testlog.addHandler(h) + + testlog.debug('Logging started') + +def close_test_log(): + """Close per-test logfile, set `testlog` to `log`.""" + assert testlog_file is not None + testlog_file.close() + testlog = log