]> mj.ucw.cz Git - moe.git/blob - t/moe/log.py
f98ee3f3217a49272d3627ca6394efea3231d7e6
[moe.git] / t / moe / log.py
1 #!/usr/bin/env python
2
3 """
4
5 `Loggers` is a collection of logggers for :class:`~moe.eval.Eval`, initializing 4 subloggers (see class description).
6
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.
9
10 .. :data:: DDEBUG = 5
11         Very verbose debugging level
12
13 Defines several logs:
14
15 `log` 
16   main log, initially a duplicated fd 2 (stderr)
17 `userlog` 
18   public progress log, initially a duplicated fd 1 (stdout)
19 `testlog` 
20   per-test log, initially no handler, to be directed to file like `{TEST}.log`
21
22 .. note:: Currently, the logs and fd's get never closed. 
23 .. warning:: `Loggers.open_eval_log` changes global fd's 1 and 2 by default.
24 """
25
26
27 # Global logs to be imported by every module
28
29 __all__ = ['log', 'userlog', 'testlog', 'pipelog' ]
30
31 log = None
32 userlog = None
33 testlog = None
34 pipelog = None
35
36 orig_stdout_fd = None
37 orig_stdout_file = None
38 orig_stderr_fd = None
39 orig_stderr_file = None
40 testlog_file = None
41
42 import logging, sys
43
44 def __init__():
45     """Very basic loggers setup to stderr."""
46     
47     global orig_stdout_fd, orig_stdout_file, orig_stderr_fd, orig_stderr_file
48     global log, userlog, 
49     
50     orig_stdout_fd = os.dup(1)
51     orig_stdout_file = os.fdopen(orig_stdout_fd, 'w', 0)
52     orig_stderr_fd = os.dup(2)
53     orig_stderr_file = os.fdopen(orig_stderr_fd, 'w', 0)
54     
55     log = logging.getLogger('mainlog')
56     log.addHandler(StreamHandler(orig_stderr_file))
57     
58     userlog = logging.getLogger('userlog')
59     userlog.addHandler(StreamHandler(orig_stdout_file))
60
61     testlog = log
62     pipelog = log
63     
64     logging.addLevelName(5,'DDEBUG')
65
66     log.debug('Logging initialized.')
67
68
69 def open_user_log(filename, level=logging.INFO):
70     """Open user (progress) logfile. Leaves logging to stdout active."""
71     h = StreamHandler(open(filename, 'w', 0))
72     h.setFormatter(Formatter('%(message)s'))
73     userlog.setLevel(level)
74     userlog.addHandler(h)
75     
76     log.debug('User logging to %r started', filename)
77
78 def open_eval_log(filename, redirect_fds = True):
79     """Open main logfile. 
80     Leaves logging to stderr active. If told to, redirects fd's 1 and 2 to this file."""
81
82     eval_file = open(filename, 'w', 0)
83     h = StreamHandler(self.eval_file)
84     h.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s'))
85     log.addHandler(h)
86     log.debug('Opened eval logfile %r')
87     
88     if redirect_fds:
89         os.dup2(eval_file.fileno(), 1)
90         os.dup2(eval_file.fileno(), 2)
91         log.debug('Redirected fds 1,2 -> eval logfile')
92
93
94 def open_test_log(filename, level):
95     """Open per-test log file, usually "{TEST}.log", set its level."""
96     
97     log.debug('Opening per-test log %r', filename)
98
99     global testlog, testlog_file
100     assert testlog_file is None
101  
102     testlog = logging.getLogger('testlog')
103     testlog.setLevel(level)
104     for h in testlog.handlers:
105         testlog.removeHandler(h)
106
107     testlog_file = open(filename, 'w')
108     h = StreamHandler(self.testlog_file)
109     h.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s'))
110     testlog.addHandler(h)
111     
112     testlog.debug('Logging started')
113
114 def close_test_log():
115     """Close per-test logfile, set `testlog` to `log`."""
116     assert testlog_file is not None 
117     testlog_file.close()
118     testlog = log