|
1 # Copyright (c) 2009, Google Inc. All rights reserved. |
|
2 # Copyright (c) 2009 Apple Inc. All rights reserved. |
|
3 # |
|
4 # Redistribution and use in source and binary forms, with or without |
|
5 # modification, are permitted provided that the following conditions are |
|
6 # met: |
|
7 # |
|
8 # * Redistributions of source code must retain the above copyright |
|
9 # notice, this list of conditions and the following disclaimer. |
|
10 # * Redistributions in binary form must reproduce the above |
|
11 # copyright notice, this list of conditions and the following disclaimer |
|
12 # in the documentation and/or other materials provided with the |
|
13 # distribution. |
|
14 # * Neither the name of Google Inc. nor the names of its |
|
15 # contributors may be used to endorse or promote products derived from |
|
16 # this software without specific prior written permission. |
|
17 # |
|
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
29 # |
|
30 # WebKit's Python module for logging |
|
31 # This module is now deprecated in favor of python's built-in logging.py. |
|
32 |
|
33 import codecs |
|
34 import os |
|
35 import sys |
|
36 |
|
37 |
|
38 def log(string): |
|
39 print >> sys.stderr, string |
|
40 |
|
41 |
|
42 def error(string): |
|
43 log("ERROR: %s" % string) |
|
44 exit(1) |
|
45 |
|
46 |
|
47 # Simple class to split output between multiple destinations |
|
48 class tee: |
|
49 def __init__(self, *files): |
|
50 self.files = files |
|
51 |
|
52 # Callers should pass an already encoded string for writing. |
|
53 def write(self, bytes): |
|
54 for file in self.files: |
|
55 file.write(bytes) |
|
56 |
|
57 |
|
58 class OutputTee: |
|
59 def __init__(self): |
|
60 self._original_stdout = None |
|
61 self._original_stderr = None |
|
62 self._files_for_output = [] |
|
63 |
|
64 def add_log(self, path): |
|
65 log_file = self._open_log_file(path) |
|
66 self._files_for_output.append(log_file) |
|
67 self._tee_outputs_to_files(self._files_for_output) |
|
68 return log_file |
|
69 |
|
70 def remove_log(self, log_file): |
|
71 self._files_for_output.remove(log_file) |
|
72 self._tee_outputs_to_files(self._files_for_output) |
|
73 log_file.close() |
|
74 |
|
75 @staticmethod |
|
76 def _open_log_file(log_path): |
|
77 (log_directory, log_name) = os.path.split(log_path) |
|
78 if log_directory and not os.path.exists(log_directory): |
|
79 os.makedirs(log_directory) |
|
80 return codecs.open(log_path, "a+", "utf-8") |
|
81 |
|
82 def _tee_outputs_to_files(self, files): |
|
83 if not self._original_stdout: |
|
84 self._original_stdout = sys.stdout |
|
85 self._original_stderr = sys.stderr |
|
86 if files and len(files): |
|
87 sys.stdout = tee(self._original_stdout, *files) |
|
88 sys.stderr = tee(self._original_stderr, *files) |
|
89 else: |
|
90 sys.stdout = self._original_stdout |
|
91 sys.stderr = self._original_stderr |