]> mj.ucw.cz Git - eval.git/blob - t/moe/log.py
19b475c70d9d181dc83d81b51cfac69fe91ad715
[eval.git] / t / moe / log.py
1 #!/usr/bin/env python
2
3 import sys, os
4 import logging 
5 from logging import Logger, StreamHandler
6
7
8 class Loggers(Logger):
9   """Defines several logs:
10
11   `self` 
12     root log, which sends messages to `eval` and `test` logs
13   `self.eval` 
14     main log, initially a duplicated fd 2 (stderr)
15   `self.user` 
16     public progress log, initially a duplicated fd 1 (stdout)
17   `self.test` 
18     per-test log, initially no handler, to be directed to file like `{TEST}.log`
19
20   .. note:: Currently, the logs and fd's get never closed. 
21   .. warning:: `Loggers.open_eval_log` changes global fd's 1 and 2 by default.
22   """
23   def __init__(self):
24     "Initialize loggers as described in class description."
25     Logger.__init__(self, '')
26     # Duplicate the fd's 
27     self.orig_stdout_fd = os.dup(1)
28     self.orig_stdout_file = os.fdopen(self.orig_stdout_fd, 'w', 0)
29     self.orig_stderr_fd = os.dup(2)
30     self.orig_stderr_file = os.fdopen(self.orig_stderr_fd, 'w', 0)
31     # Eval main logger  
32     self.eval = Logger('eval')
33     self.eval.addHandler(StreamHandler(self.orig_stderr_file))
34     # per-test logger
35     self.test = Logger('test')
36     self.test_handler = None
37     self.test_file = None
38     # user progress logger  
39     self.user = Logger('user')
40     self.eval.addHandler(StreamHandler(self.orig_stdout_file))
41  
42     self.addHandler(self.test)
43     self.addHandler(self.eval)
44     self.debug('Logging initialized.')
45
46   def open_user_log(self, filename, level=logging.INFO):
47     """Open user (progress) logfile. Leaves logging to stdout active."""
48     h = StreamHandler(open(filename, 'w', 0))
49     h.setFormatter(Formatter('%(message)s'))
50     self.user.setLevel(level)
51     self.user.addHandler(h)
52     self.user.debug('Logging started')
53
54   def open_eval_log(self, filename, level, redirect_fds = True):
55     """Open main logfile. 
56     Leaves logging to stderr active. If told to, redirects fd's 1 and 2 to this file.
57     Sets level of both `self.eval` and `self`."""
58     self.eval_file = open(filename, 'w', 0)
59     self.eval_handler = StreamHandler(self.eval_file)
60     self.eval_handler.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s'))
61     self.eval.addHandler(self.eval_handler)
62     if redirect_fds:
63       os.dup2(self.eval_file.fileno(), 1)
64       os.dup2(self.eval_file.fileno(), 2)
65     self.eval.setLevel(level)
66     self.setLevel(level)
67     self.eval.debug('Logging started')
68
69
70   def open_test_log(self, filename, level):
71     """Open per-test log file, like "{TEST}.log". Also set handler level to `level`."""
72     self.debug('Opening per-test log %s' % filename)
73     if self.test_handler:
74       self.close_test_log()
75     self.test_file = open(filename, 'w')
76     self.test_handler = StreamHandler(self.test_file)
77     self.test.addHandler(self.test_handler)
78     self.test.setLevel(level)
79     self.test_handler.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s'))
80     self.test.debug('Logging started')
81
82   def close_test_log(self):
83     """Close per-test logfile, leaving only the null handler."""
84     if self.test_handler:
85       self.test.info('Closing logfile' % filename)
86       self.test.removeHandler(self.test_handler)
87     self.test_handler = None
88     self.test_file.close()
89   
90   def ddebug(self, msg, *args, **kwargs):
91     """Log with priority 5 (normal DEBUG is 10)"""
92     self.log(5, msg, *args, **kwargs)