10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# Copyright (c) 2009, Google Inc. All rights reserved. 20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# Copyright (c) 2009 Apple Inc. All rights reserved. 30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# 40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# Redistribution and use in source and binary forms, with or without 50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# modification, are permitted provided that the following conditions are 60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# met: 70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# 80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# * Redistributions of source code must retain the above copyright 90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# notice, this list of conditions and the following disclaimer. 100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# * Redistributions in binary form must reproduce the above 110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# copyright notice, this list of conditions and the following disclaimer 120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# in the documentation and/or other materials provided with the 130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# distribution. 140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# * Neither the name of Google Inc. nor the names of its 150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# contributors may be used to endorse or promote products derived from 160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# this software without specific prior written permission. 170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# 180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# 300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# WebKit's Python module for logging 31d0825bca7fe65beaee391d30da42e937db621564Steve Block# This module is now deprecated in favor of python's built-in logging.py. 320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3321939df44de1705786c545cd1bf519d47250322dBen Murdochimport codecs 34643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockimport os 350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport sys 360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3721939df44de1705786c545cd1bf519d47250322dBen Murdoch 380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdef log(string): 390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch print >> sys.stderr, string 400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4121939df44de1705786c545cd1bf519d47250322dBen Murdoch 420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdef error(string): 43231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block log("ERROR: %s" % string) 440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch exit(1) 45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 4621939df44de1705786c545cd1bf519d47250322dBen Murdoch 47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block# Simple class to split output between multiple destinations 48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockclass tee: 49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block def __init__(self, *files): 50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block self.files = files 51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 5221939df44de1705786c545cd1bf519d47250322dBen Murdoch # Callers should pass an already encoded string for writing. 5321939df44de1705786c545cd1bf519d47250322dBen Murdoch def write(self, bytes): 54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for file in self.files: 5521939df44de1705786c545cd1bf519d47250322dBen Murdoch file.write(bytes) 5621939df44de1705786c545cd1bf519d47250322dBen Murdoch 57643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 58643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockclass OutputTee: 59643ca7872b450ea4efacab6188849e5aac2ba161Steve Block def __init__(self): 60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block self._original_stdout = None 61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block self._original_stderr = None 62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block self._files_for_output = [] 63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block def add_log(self, path): 65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block log_file = self._open_log_file(path) 66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block self._files_for_output.append(log_file) 67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block self._tee_outputs_to_files(self._files_for_output) 68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return log_file 69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 70643ca7872b450ea4efacab6188849e5aac2ba161Steve Block def remove_log(self, log_file): 71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block self._files_for_output.remove(log_file) 72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block self._tee_outputs_to_files(self._files_for_output) 73643ca7872b450ea4efacab6188849e5aac2ba161Steve Block log_file.close() 74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block @staticmethod 76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block def _open_log_file(log_path): 77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block (log_directory, log_name) = os.path.split(log_path) 78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if log_directory and not os.path.exists(log_directory): 79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block os.makedirs(log_directory) 8021939df44de1705786c545cd1bf519d47250322dBen Murdoch return codecs.open(log_path, "a+", "utf-8") 81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block def _tee_outputs_to_files(self, files): 83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if not self._original_stdout: 84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block self._original_stdout = sys.stdout 85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block self._original_stderr = sys.stderr 86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if files and len(files): 87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block sys.stdout = tee(self._original_stdout, *files) 88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block sys.stderr = tee(self._original_stderr, *files) 89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else: 90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block sys.stdout = self._original_stdout 91643ca7872b450ea4efacab6188849e5aac2ba161Steve Block sys.stderr = self._original_stderr 92