5 from logging import Logger, StreamHandler
9 """Defines several logs:
12 root log, which sends messages to `eval` and `test` logs
14 main log, initially a duplicated fd 2 (stderr)
16 public progress log, initially a duplicated fd 1 (stdout)
18 per-test log, initially no handler, to be directed to file like `{TEST}.log`
20 Currently, the logs and fd's get never closed.
23 WARN: Currently, the module changes fd's 1 and 2, this is a global change.
26 "Initialize loggers as described in class description."
27 Logger.__init__(self, '')
29 self.orig_stdout_fd = os.dup(1)
30 self.orig_stdout_file = os.fdopen(self.orig_stdout_fd, 'w', 0)
31 self.orig_stderr_fd = os.dup(2)
32 self.orig_stderr_file = os.fdopen(self.orig_stderr_fd, 'w', 0)
34 self.eval = Logger('eval')
35 self.eval.addHandler(StreamHandler(self.orig_stderr_file))
37 self.test = Logger('test')
38 self.test_handler = None
40 # user progress logger
41 self.user = Logger('user')
42 self.eval.addHandler(StreamHandler(self.orig_stdout_file))
44 self.addHandler(self.test)
45 self.addHandler(self.eval)
46 self.debug('Logging initialized.')
48 def open_user_log(self, filename, level=logging.INFO):
49 """Open user (progress) logfile. Leaves logging to stdout active."""
50 h = StreamHandler(open(filename, 'w', 0))
51 h.setFormatter(Formatter('%(message)s'))
52 self.user.addHandler(h)
53 self.user.debug('Logging started')
55 def open_eval_log(self, filename, level, redirect_fds = True):
56 """Open user (progress) logfile.
57 Leaves logging to stderr active. If told to, redirects fd's 1 and 2 to this file."""
58 self.eval_file = open(filename, 'w', 0)
59 self.eval_handler = StreamHandler(self.eval_file)
60 self.eval_handler.setFormatter(Formatter('%(message)s'))
61 self.user.addHandler(self.eval_handler)
63 os.dup2(self.eval_file.fileno(), 1)
64 os.dup2(self.eval_file.fileno(), 2)
65 self.user.debug('Logging started')
67 def open_test_log(self, filename, level):
68 """Open per-test log file, like "{TEST}.log". Also set handler level to `level`."""
69 self.debug('Opening per-test log %s' % filename)
72 self.test_file = open(filename, 'w')
73 self.test_handler = StreamHandler(self.test_file)
74 self.test.addHandler(self.test_handler)
75 self.test.setLevel(level)
76 self.test_handler.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s'))
77 self.test.debug('Logging started')
79 def close_test_log(self):
80 """Close per-test logfile, leaving only the null handler."""
82 self.test.info('Closing logfile' % filename)
83 self.test.removeHandler(self.test_handler)
84 self.test_handler = None
85 self.test_file.close()
87 def ddebug(self, msg, *args, **kwargs):
88 """Log with priority 5 (normal DEBUG is 10)"""
89 self.log(5, msg, *args, **kwargs)