5 `Loggers` is a collection of logggers for :class:`~moe.eval.Eval`, initializing 4 subloggers (see class description).
7 Use as `e.log.debug(...)` for main log that goes both to `test` and `main` log,
8 `e.log.test.debug(...)` for individual logs.
11 Very verbose debugging level
18 from logging import Logger, StreamHandler, Formatter
20 logging.addLevelName(5,'DDEBUG')
23 class Loggers(Logger):
24 """Defines several logs:
27 root log, which sends messages to `eval` and `test` logs
29 main log, initially a duplicated fd 2 (stderr)
31 public progress log, initially a duplicated fd 1 (stdout)
33 per-test log, initially no handler, to be directed to file like `{TEST}.log`
35 .. note:: Currently, the logs and fd's get never closed.
36 .. warning:: `Loggers.open_eval_log` changes global fd's 1 and 2 by default.
39 "Initialize loggers as described in class description."
40 Logger.__init__(self, '')
42 self.orig_stdout_fd = os.dup(1)
43 self.orig_stdout_file = os.fdopen(self.orig_stdout_fd, 'w', 0)
44 self.orig_stderr_fd = os.dup(2)
45 self.orig_stderr_file = os.fdopen(self.orig_stderr_fd, 'w', 0)
47 self.eval = Logger('eval')
48 self.eval.addHandler(StreamHandler(self.orig_stderr_file))
50 self.test = Logger('test')
51 self.test_handler = None
53 # user progress logger
54 self.user = Logger('user')
55 self.user.addHandler(StreamHandler(self.orig_stdout_file))
57 self.addHandler(self.test)
58 self.addHandler(self.eval)
59 self.debug('Logging initialized.')
61 def open_user_log(self, filename, level=logging.INFO):
62 """Open user (progress) logfile. Leaves logging to stdout active."""
63 h = StreamHandler(open(filename, 'w', 0))
64 h.setFormatter(Formatter('%(message)s'))
65 self.user.setLevel(level)
66 self.user.addHandler(h)
67 self.user.debug('Logging started')
69 def open_eval_log(self, filename, level, redirect_fds = True):
71 Leaves logging to stderr active. If told to, redirects fd's 1 and 2 to this file.
72 Sets level of both `self.eval` and `self`."""
73 self.eval_file = open(filename, 'w', 0)
74 self.eval_handler = StreamHandler(self.eval_file)
75 self.eval_handler.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s'))
76 self.eval.addHandler(self.eval_handler)
78 os.dup2(self.eval_file.fileno(), 1)
79 os.dup2(self.eval_file.fileno(), 2)
80 self.eval.setLevel(level)
82 self.eval.debug('Logging started')
85 def open_test_log(self, filename, level):
86 """Open per-test log file, like "{TEST}.log". Also set handler level to `level`."""
87 self.debug('Opening per-test log %s' % filename)
90 self.test_file = open(filename, 'w')
91 self.test_handler = StreamHandler(self.test_file)
92 self.test.addHandler(self.test_handler)
93 self.test.setLevel(level)
94 self.test_handler.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s'))
95 self.test.debug('Logging started')
97 def close_test_log(self):
98 """Close per-test logfile, leaving only the null handler."""
100 self.test.info('Closing logfile' % filename)
101 self.test.removeHandler(self.test_handler)
102 self.test_handler = None
103 self.test_file.close()
105 def ddebug(self, msg, *args, **kwargs):
106 """Log with priority 5 (normal DEBUG is 10)"""
107 self.log(5, msg, *args, **kwargs)