OLD | NEW |
1 # Copyright 2015 The LUCI Authors. All rights reserved. | 1 # Copyright 2015 The LUCI Authors. All rights reserved. |
2 # Use of this source code is governed under the Apache License, Version 2.0 | 2 # Use of this source code is governed under the Apache License, Version 2.0 |
3 # that can be found in the LICENSE file. | 3 # that can be found in the LICENSE file. |
4 | 4 |
5 """Utility relating to logging.""" | 5 """Utility relating to logging.""" |
6 | 6 |
7 import argparse | 7 import argparse |
8 import codecs | 8 import codecs |
9 import ctypes | 9 import ctypes |
10 import logging | 10 import logging |
11 import logging.handlers | 11 import logging.handlers |
12 import optparse | 12 import optparse |
13 import os | 13 import os |
14 import sys | 14 import sys |
15 import tempfile | 15 import tempfile |
16 import time | 16 import time |
17 | 17 |
| 18 from utils import file_path |
18 | 19 |
19 # This works around file locking issue on Windows specifically in the case of | 20 # This works around file locking issue on Windows specifically in the case of |
20 # long lived child processes. | 21 # long lived child processes. |
21 # | 22 # |
22 # Python opens files with inheritable handle and without file sharing by | 23 # Python opens files with inheritable handle and without file sharing by |
23 # default. This causes the RotatingFileHandler file handle to be duplicated in | 24 # default. This causes the RotatingFileHandler file handle to be duplicated in |
24 # the subprocesses even if the log file is not used in it. Because of this | 25 # the subprocesses even if the log file is not used in it. Because of this |
25 # handle in the child process, when the RotatingFileHandler tries to os.rename() | 26 # handle in the child process, when the RotatingFileHandler tries to os.rename() |
26 # the file in the parent process, it fails with: | 27 # the file in the parent process, it fails with: |
27 # WindowsError: [Error 32] The process cannot access the file because | 28 # WindowsError: [Error 32] The process cannot access the file because |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 stderr = logging.StreamHandler() | 193 stderr = logging.StreamHandler() |
193 stderr.setFormatter(formatter) | 194 stderr.setFormatter(formatter) |
194 stderr.addFilter(Filter()) | 195 stderr.addFilter(Filter()) |
195 # Default to ERROR. | 196 # Default to ERROR. |
196 stderr.setLevel(logging.ERROR) | 197 stderr.setLevel(logging.ERROR) |
197 logger.addHandler(stderr) | 198 logger.addHandler(stderr) |
198 | 199 |
199 # Setup up logging to a constant file so we can debug issues where | 200 # Setup up logging to a constant file so we can debug issues where |
200 # the results aren't properly sent to the result URL. | 201 # the results aren't properly sent to the result URL. |
201 if filename: | 202 if filename: |
| 203 file_path.ensure_tree(os.path.dirname(os.path.abspath(unicode(filename)))) |
202 try: | 204 try: |
203 rotating_file = NoInheritRotatingFileHandler( | 205 rotating_file = NoInheritRotatingFileHandler( |
204 filename, maxBytes=10 * 1024 * 1024, backupCount=5, | 206 filename, maxBytes=10 * 1024 * 1024, backupCount=5, |
205 encoding='utf-8') | 207 encoding='utf-8') |
206 rotating_file.setLevel(logging.DEBUG) | 208 rotating_file.setLevel(logging.DEBUG) |
207 rotating_file.setFormatter(formatter) | 209 rotating_file.setFormatter(formatter) |
208 rotating_file.addFilter(Filter()) | 210 rotating_file.addFilter(Filter()) |
209 logger.addHandler(rotating_file) | 211 logger.addHandler(rotating_file) |
210 except Exception: | 212 except Exception: |
211 # May happen on cygwin. Do not crash. | 213 # May happen on cygwin. Do not crash. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 | 293 |
292 def parse_args(self, *args, **kwargs): | 294 def parse_args(self, *args, **kwargs): |
293 # Make sure this group is always the last one. | 295 # Make sure this group is always the last one. |
294 self._add_logging_group() | 296 self._add_logging_group() |
295 | 297 |
296 args = super(ArgumentParserWithLogging, self).parse_args(*args, **kwargs) | 298 args = super(ArgumentParserWithLogging, self).parse_args(*args, **kwargs) |
297 prepare_logging(self.enable_log_file and args.log_file, self.logger_root) | 299 prepare_logging(self.enable_log_file and args.log_file, self.logger_root) |
298 set_console_level( | 300 set_console_level( |
299 LEVELS[min(len(LEVELS) - 1, args.verbose)], self.logger_root) | 301 LEVELS[min(len(LEVELS) - 1, args.verbose)], self.logger_root) |
300 return args | 302 return args |
OLD | NEW |