Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client / pynacl / log_tools.py
1 #!/usr/bin/python
2 # Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Logging related tools."""
7
8 import logging
9 import os
10 import subprocess
11 import sys
12
13 # Module-level configuration
14 LOG_FH = None
15 VERBOSE = False
16
17 def SetupLogging(verbose, file_handle=None, quiet=False):
18   """Set up python logging.
19
20   Args:
21     verbose: If True, log to stderr at DEBUG level and write subprocess output
22              to stdout. Otherwise log to stderr at INFO level and do not print
23              subprocess output unless there is an error.
24     file_handle: If not None, must be a file-like object. All log output will
25                  be written at DEBUG level, and all subprocess output will be
26                  written, regardless of whether there are errors.
27     quiet: If True, log to stderr at WARNING level only. Only valid if verbose
28            is False.
29   """
30   # Since one of our handlers always wants debug, set the global level to debug.
31   logging.getLogger().setLevel(logging.DEBUG)
32   stderr_handler = logging.StreamHandler()
33   stderr_handler.setFormatter(
34       logging.Formatter(fmt='%(levelname)s: %(message)s'))
35   if verbose:
36     global VERBOSE
37     VERBOSE = True
38     stderr_handler.setLevel(logging.DEBUG)
39   elif quiet:
40     stderr_handler.setLevel(logging.WARN)
41   else:
42     stderr_handler.setLevel(logging.INFO)
43   logging.getLogger().addHandler(stderr_handler)
44
45   if file_handle:
46     global LOG_FH
47     file_handler = logging.StreamHandler(file_handle)
48     file_handler.setLevel(logging.DEBUG)
49     file_handler.setFormatter(
50         logging.Formatter(fmt='%(levelname)s: %(message)s'))
51     logging.getLogger().addHandler(file_handler)
52     LOG_FH = file_handle
53
54
55 def WriteToLog(text):
56   if VERBOSE:
57     sys.stdout.write(text)
58   if LOG_FH:
59     LOG_FH.write(text)
60
61
62 def CheckCall(command, stdout=None, **kwargs):
63   """Modulate command output level based on logging level.
64
65   If a logging file handle is set, always emit all output to it.
66   If the log level is set at debug or lower, also emit all output to stdout.
67   Otherwise, only emit output on error.
68   Args:
69     command: Command to run.
70     stdout (optional): File name to redirect stdout to.
71     **kwargs: Keyword args.
72   """
73   cwd = os.path.abspath(kwargs.get('cwd', os.getcwd()))
74   logging.info('Running: subprocess.check_call(%r, cwd=%r)' % (command, cwd))
75
76   if stdout is None:
77     # Interleave stdout and stderr together and log that.
78     p = subprocess.Popen(command,
79                          stdout=subprocess.PIPE,
80                          stderr=subprocess.STDOUT,
81                          **kwargs)
82     output = p.stdout
83   else:
84     p = subprocess.Popen(command,
85                          stdout=open(stdout, 'w'),
86                          stderr=subprocess.PIPE,
87                          **kwargs)
88     output = p.stderr
89
90   # Capture the output as it comes and emit it immediately.
91   line = output.readline()
92   while line:
93     WriteToLog(line)
94     line = output.readline()
95
96   if p.wait() != 0:
97     raise subprocess.CalledProcessError(cmd=command, returncode=p.returncode)
98
99   # Flush stdout so it does not get interleaved with future log or buildbot
100   # output which goes to stderr.
101   sys.stdout.flush()
102
103
104 def CheckOutput(command, **kwargs):
105   """Capture stdout from a command, while logging its stderr.
106
107   This is essentially subprocess.check_output, but stderr is
108   handled the same way as in log_tools.CheckCall.
109   Args:
110     command: Command to run.
111     **kwargs: Keyword args.
112   """
113   cwd = os.path.abspath(kwargs.get('cwd', os.getcwd()))
114   logging.info('Running: subprocess.check_output(%r, cwd=%r)' % (command, cwd))
115
116   p = subprocess.Popen(command,
117                        stdout=subprocess.PIPE,
118                        stderr=subprocess.PIPE,
119                        **kwargs)
120
121   # Assume the output will not be huge or take a long time to come, so it
122   # is viable to just consume it all synchronously before logging anything.
123   # TODO(mcgrathr): Shovel stderr bits asynchronously if that ever seems
124   # worth the hair.
125   stdout_text, stderr_text = p.communicate()
126
127   WriteToLog(stderr_text)
128
129   if p.wait() != 0:
130     raise subprocess.CalledProcessError(cmd=command, returncode=p.returncode)
131
132   # Flush stdout so it does not get interleaved with future log or buildbot
133   # output which goes to stderr.
134   sys.stdout.flush()
135
136   logging.info('Result: %r' % stdout_text)
137   return stdout_text