X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=t%2Fmoe%2Flog.py;h=f98ee3f3217a49272d3627ca6394efea3231d7e6;hb=ef64f1097b0b3d210ee24f08e91c352865cac59c;hp=592fb846b047bd7b1952c3e6866080aa1074b67d;hpb=c80aa556a07b88cafe5a18f6b86a90f30b199ba9;p=moe.git diff --git a/t/moe/log.py b/t/moe/log.py index 592fb84..f98ee3f 100644 --- a/t/moe/log.py +++ b/t/moe/log.py @@ -1,47 +1,118 @@ #!/usr/bin/env python -import sys -import os -import traceback +""" -orig_stdout_fd = os.dup(1) -orig_stderr_fd = os.dup(2) -progress_file = os.fdopen(orig_stdout_fd, "w", 0) +`Loggers` is a collection of logggers for :class:`~moe.eval.Eval`, initializing 4 subloggers (see class description). -class MoeLog: +Use as `e.log.debug(...)` for main log that goes both to `test` and `main` log, +`e.log.test.debug(...)` for individual logs. - def __init__(self): - self.verbosity = 0 - self.progress_file = progress_file - self.log_file = None +.. :data:: DDEBUG = 5 + Very verbose debugging level - def open(self, name): - self.log_file = open(name, "w") - os.dup2(self.log_file.fileno(), 1) - os.dup2(self.log_file.fileno(), 2) +Defines several logs: - def say(self, msg): - if self.log_file: - self.log_file.write(msg) +`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` - def verbose(self, msg): - if self.verbosity and self.log_file: - self.log_file.write(msg) +.. 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 progress(self, msg): - if self.progress_file: - self.progress_file.write(msg) - def shout(self, msg): - self.say(msg) - self.progress(msg) +# Global logs to be imported by every module - def flush(self): - self.log_file.flush() +__all__ = ['log', 'userlog', 'testlog', 'pipelog' ] -default = MoeLog() +log = None +userlog = None +testlog = None +pipelog = None -def fatal_exception(): - os.dup2(orig_stderr_fd, 2) - traceback.print_exc() - sys.exit(1) +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