]> mj.ucw.cz Git - moe.git/blob - t/moe/logs.py
Merge branch 'python-newpipe' into python
[moe.git] / t / moe / logs.py
1 """
2
3 `Loggers` is a collection of logggers for :class:`~moe.eval.Eval`, initializing 4 subloggers (see class description).
4
5 Use as `e.log.debug(...)` for main log that goes both to `test` and `main` log,
6 `e.log.test.debug(...)` for individual logs.
7
8 .. :data:: DDEBUG = 5
9         Very verbose debugging level
10
11 Defines several logs:
12
13 `log` 
14   main log, initially a duplicated fd 2 (stderr)
15 `userlog` 
16   public progress log, initially a duplicated fd 1 (stdout)
17 `testlog` 
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
24
25 # Global logs to be imported by every module
26
27 __all__ = ['log', 'userlog', 'testlog', 'pipelog' ]
28
29 log = None
30 userlog = None
31 testlog = None
32 pipelog = None
33
34 orig_stdout_fd = None
35 orig_stdout_file = None
36 orig_stderr_fd = None
37 orig_stderr_file = None
38 testlog_file = None
39
40 import logging, sys, os
41 from logging import Formatter, StreamHandler
42
43 def __init__():
44     """Very basic loggers setup to stderr."""
45     
46     global orig_stdout_fd, orig_stdout_file, orig_stderr_fd, orig_stderr_file
47     global log, userlog
48     
49     orig_stdout_fd = os.dup(1)
50     orig_stdout_file = os.fdopen(orig_stdout_fd, 'w', 0)
51     orig_stderr_fd = os.dup(2)
52     orig_stderr_file = os.fdopen(orig_stderr_fd, 'w', 0)
53     
54     log = logging.getLogger('mainlog')
55     log.addHandler(StreamHandler(orig_stderr_file))
56     
57     userlog = logging.getLogger('userlog')
58     userlog.addHandler(StreamHandler(orig_stdout_file))
59
60     testlog = log
61     pipelog = log
62     
63     logging.addLevelName(5,'DDEBUG')
64
65     log.debug('Logging initialized.')
66
67
68 def open_user_log(filename, level=logging.INFO):
69     """Open user (progress) logfile. Leaves logging to stdout active."""
70     h = StreamHandler(open(filename, 'w', 0))
71     h.setFormatter(Formatter('%(message)s'))
72     userlog.setLevel(level)
73     userlog.addHandler(h)
74     
75     log.debug('User logging to %r started', filename)
76
77 def open_eval_log(filename, level=None, redirect_fds = True):
78     """Open main logfile. 
79     Leaves logging to stderr active. If told to, redirects fd's 1 and 2 to this file."""
80
81     eval_file = open(filename, 'w', 0)
82     h = StreamHandler(eval_file)
83     h.setFormatter(Formatter('%(asctime)s [%(levelno)s] %(message)s'))
84     log.addHandler(h)
85     if (level): log.setLevel(level)
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(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     global testlog_file
117     assert testlog_file is not None 
118     testlog_file.close()
119     testlog_file = None
120     testlog = log
121
122 # Initialise
123
124 __init__()