summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2011-08-12 23:24:43 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2011-08-15 09:14:28 +0100
commit7ee93b206a6389e6eb7b9440dc2fae801c77bc9b (patch)
tree6700acff792125542187590c5633c61c29b1005b
parentfce0b963b437c5b0660dca6f5b0a099e4befa03c (diff)
downloadpoky-7ee93b206a6389e6eb7b9440dc2fae801c77bc9b.tar.gz
bitbake/logging: Overhaul internal logging process
At the moment it bugs me a lot that we only have one effective logging level for bitbake, despite the logging module having provision to do more advanced things. This patch: * Changes the core log level to the lowest level we have messages of (DEBUG-2) so messages always flow through the core logger * Allows build.py's task logging code to log all the output regardless of what output is on the console and sets this so log files now always contain debug level messages even if these don't appear on the console * Moves the verbose/debug/debug-domains code to be a UI side setting * Adds a filter to the UI to only print the user requested output. The result is more complete logfiles on disk but the usual output to the console. There are some behaviour changes intentionally made by this patch: a) the -v option now controls whether output is tee'd to the console. Ultimately, we likely want to output a message to the user about where the log file is and avoid placing output directly onto the console for every executing task. b) The functions get_debug_levels, the debug_levels variable, the set_debug_levels, the set_verbosity and set_debug_domains functions are removed from bb.msg. c) The "logging" init function changes format. d) All messages get fired to all handlers all the time leading to an increase in inter-process traffic. This could likely be hacked around short term with a function for a UI to only request events greater than level X. Longer term, having masks for event handlers would be better. e) logger.getEffectiveLevel() is no longer a reliable guide to what will/won't get logged so for now we look at the default log levels instead. [YOCTO #304] (Bitbake rev: 45aad2f9647df14bcfa5e755b57e1ddab377939a) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rwxr-xr-xbitbake/bin/bitbake3
-rwxr-xr-xbitbake/bin/bitdoc5
-rw-r--r--bitbake/lib/bb/__init__.py2
-rw-r--r--bitbake/lib/bb/build.py6
-rw-r--r--bitbake/lib/bb/msg.py74
-rw-r--r--bitbake/lib/bb/ui/knotty.py5
-rw-r--r--bitbake/lib/bb/utils.py15
7 files changed, 57 insertions, 53 deletions
diff --git a/bitbake/bin/bitbake b/bitbake/bin/bitbake
index fdeeb36a40..56f39f8efe 100755
--- a/bitbake/bin/bitbake
+++ b/bitbake/bin/bitbake
@@ -190,7 +190,7 @@ Default BBFILES are the .bb files in the current directory.""")
190 # server is daemonized this logfile will be truncated. 190 # server is daemonized this logfile will be truncated.
191 cooker_logfile = os.path.join(os.getcwd(), "cooker.log") 191 cooker_logfile = os.path.join(os.getcwd(), "cooker.log")
192 192
193 bb.utils.init_logger(bb.msg, configuration.verbose, configuration.debug, 193 bb.msg.init_msgconfig(configuration.verbose, configuration.debug,
194 configuration.debug_domains) 194 configuration.debug_domains)
195 195
196 # Ensure logging messages get sent to the UI as events 196 # Ensure logging messages get sent to the UI as events
@@ -228,6 +228,7 @@ Default BBFILES are the .bb files in the current directory.""")
228 try: 228 try:
229 return server.launchUI(ui_main, server_connection.connection, server_connection.events) 229 return server.launchUI(ui_main, server_connection.connection, server_connection.events)
230 finally: 230 finally:
231 bb.event.ui_queue = []
231 server_connection.terminate() 232 server_connection.terminate()
232 233
233 return 1 234 return 1
diff --git a/bitbake/bin/bitdoc b/bitbake/bin/bitdoc
index 98fb025a50..08a0173d72 100755
--- a/bitbake/bin/bitdoc
+++ b/bitbake/bin/bitdoc
@@ -430,9 +430,8 @@ Create a set of html pages (documentation) for a bitbake.conf....
430 action = "store_true", dest = "verbose", default = False ) 430 action = "store_true", dest = "verbose", default = False )
431 431
432 options, args = parser.parse_args( sys.argv ) 432 options, args = parser.parse_args( sys.argv )
433 433
434 if options.debug: 434 bb.msg.init_msgconfig(options.verbose, options.debug)
435 bb.msg.set_debug_level(options.debug)
436 435
437 return options.config, options.output 436 return options.config, options.output
438 437
diff --git a/bitbake/lib/bb/__init__.py b/bitbake/lib/bb/__init__.py
index 06d865994c..3c8572476c 100644
--- a/bitbake/lib/bb/__init__.py
+++ b/bitbake/lib/bb/__init__.py
@@ -56,7 +56,7 @@ logging.setLoggerClass(BBLogger)
56 56
57logger = logging.getLogger("BitBake") 57logger = logging.getLogger("BitBake")
58logger.addHandler(NullHandler()) 58logger.addHandler(NullHandler())
59logger.setLevel(logging.INFO) 59logger.setLevel(logging.DEBUG - 2)
60 60
61# This has to be imported after the setLoggerClass, as the import of bb.msg 61# This has to be imported after the setLoggerClass, as the import of bb.msg
62# can result in construction of the various loggers. 62# can result in construction of the various loggers.
diff --git a/bitbake/lib/bb/build.py b/bitbake/lib/bb/build.py
index 5c703095b7..31fde06e6a 100644
--- a/bitbake/lib/bb/build.py
+++ b/bitbake/lib/bb/build.py
@@ -223,7 +223,7 @@ def exec_func_shell(function, d, runfile, cwd=None):
223 223
224 with open(runfile, 'w') as script: 224 with open(runfile, 'w') as script:
225 script.write('#!/bin/sh -e\n') 225 script.write('#!/bin/sh -e\n')
226 if logger.isEnabledFor(logging.DEBUG): 226 if bb.msg.loggerVerbose[1]:
227 script.write("set -x\n") 227 script.write("set -x\n")
228 data.emit_func(function, script, d) 228 data.emit_func(function, script, d)
229 if cwd: 229 if cwd:
@@ -234,7 +234,7 @@ def exec_func_shell(function, d, runfile, cwd=None):
234 234
235 cmd = runfile 235 cmd = runfile
236 236
237 if logger.isEnabledFor(logging.DEBUG): 237 if bb.msg.loggerVerbose[1]:
238 logfile = LogTee(logger, sys.stdout) 238 logfile = LogTee(logger, sys.stdout)
239 else: 239 else:
240 logfile = sys.stdout 240 logfile = sys.stdout
@@ -308,6 +308,8 @@ def _exec_task(fn, task, d, quieterr):
308 # Ensure python logging goes to the logfile 308 # Ensure python logging goes to the logfile
309 handler = logging.StreamHandler(logfile) 309 handler = logging.StreamHandler(logfile)
310 handler.setFormatter(logformatter) 310 handler.setFormatter(logformatter)
311 # Always enable full debug output into task logfiles
312 handler.setLevel(logging.DEBUG - 2)
311 bblogger.addHandler(handler) 313 bblogger.addHandler(handler)
312 314
313 localdata.setVar('BB_LOGFILE', logfn) 315 localdata.setVar('BB_LOGFILE', logfn)
diff --git a/bitbake/lib/bb/msg.py b/bitbake/lib/bb/msg.py
index 12d19ff8e1..77a7a0fed2 100644
--- a/bitbake/lib/bb/msg.py
+++ b/bitbake/lib/bb/msg.py
@@ -75,6 +75,25 @@ class BBLogFormatter(logging.Formatter):
75 msg += '\n' + ''.join(formatted) 75 msg += '\n' + ''.join(formatted)
76 return msg 76 return msg
77 77
78class BBLogFilter(object):
79 def __init__(self, handler, level, debug_domains):
80 self.stdlevel = level
81 self.debug_domains = debug_domains
82 loglevel = level
83 for domain in debug_domains:
84 if debug_domains[domain] < loglevel:
85 loglevel = debug_domains[domain]
86 handler.setLevel(loglevel)
87 handler.addFilter(self)
88
89 def filter(self, record):
90 if record.levelno >= self.stdlevel:
91 return True
92 if record.name in self.debug_domains and record.levelno >= self.debug_domains[record.name]:
93 return True
94 return False
95
96
78class Loggers(dict): 97class Loggers(dict):
79 def __getitem__(self, key): 98 def __getitem__(self, key):
80 if key in self: 99 if key in self:
@@ -84,12 +103,6 @@ class Loggers(dict):
84 dict.__setitem__(self, key, log) 103 dict.__setitem__(self, key, log)
85 return log 104 return log
86 105
87class DebugLevel(dict):
88 def __getitem__(self, key):
89 if key == "default":
90 key = domain.Default
91 return get_debug_level(key)
92
93def _NamedTuple(name, fields): 106def _NamedTuple(name, fields):
94 Tuple = collections.namedtuple(name, " ".join(fields)) 107 Tuple = collections.namedtuple(name, " ".join(fields))
95 return Tuple(*range(len(fields))) 108 return Tuple(*range(len(fields)))
@@ -110,44 +123,47 @@ domain = _NamedTuple("Domain", (
110 "Util")) 123 "Util"))
111logger = logging.getLogger("BitBake") 124logger = logging.getLogger("BitBake")
112loggers = Loggers() 125loggers = Loggers()
113debug_level = DebugLevel()
114 126
115# Message control functions 127# Message control functions
116# 128#
117 129
118def set_debug_level(level): 130loggerDefaultDebugLevel = 0
119 for log in loggers.itervalues(): 131loggerDefaultVerbose = False
120 log.setLevel(logging.NOTSET) 132loggerDefaultDomains = []
121 133
122 if level: 134def init_msgconfig(verbose, debug, debug_domains = []):
123 logger.setLevel(logging.DEBUG - level + 1) 135 """
124 else: 136 Set default verbosity and debug levels config the logger
125 logger.setLevel(logging.INFO) 137 """
138 bb.msg.loggerDebugLevel = debug
139 bb.msg.loggerVerbose = verbose
140 bb.msg.loggerDefaultDomains = debug_domains
126 141
127def get_debug_level(msgdomain = domain.Default): 142def addDefaultlogFilter(handler):
128 if not msgdomain:
129 level = logger.getEffectiveLevel()
130 else:
131 level = loggers[msgdomain].getEffectiveLevel()
132 return max(0, logging.DEBUG - level + 1)
133 143
134def set_verbose(level): 144 debug = loggerDefaultDebugLevel
135 if level: 145 verbose = loggerDefaultVerbose
136 logger.setLevel(BBLogFormatter.VERBOSE) 146 domains = loggerDefaultDomains
147
148 if debug:
149 level = BBLogFormatter.DEBUG - debug + 1
150 elif verbose:
151 level = BBLogFormatter.VERBOSE
137 else: 152 else:
138 logger.setLevel(BBLogFormatter.INFO) 153 level = BBLogFormatter.NOTE
139 154
140def set_debug_domains(domainargs): 155 debug_domains = {}
141 for (domainarg, iterator) in groupby(domainargs): 156 for (domainarg, iterator) in groupby(domains):
157 dlevel = len(tuple(iterator))
158 debug_domains["BitBake.%s" % domainarg] = logging.DEBUG - dlevel + 1
142 for index, msgdomain in enumerate(domain._fields): 159 for index, msgdomain in enumerate(domain._fields):
143 if msgdomain == domainarg: 160 if msgdomain == domainarg:
144 level = len(tuple(iterator))
145 if level:
146 loggers[index].setLevel(logging.DEBUG - level + 1)
147 break 161 break
148 else: 162 else:
149 warn(None, "Logging domain %s is not valid, ignoring" % domainarg) 163 warn(None, "Logging domain %s is not valid, ignoring" % domainarg)
150 164
165 BBLogFilter(handler, level, debug_domains)
166
151# 167#
152# Message handling functions 168# Message handling functions
153# 169#
diff --git a/bitbake/lib/bb/ui/knotty.py b/bitbake/lib/bb/ui/knotty.py
index 7a2681d2bf..7c645adcc4 100644
--- a/bitbake/lib/bb/ui/knotty.py
+++ b/bitbake/lib/bb/ui/knotty.py
@@ -74,6 +74,7 @@ def main(server, eventHandler):
74 74
75 console = logging.StreamHandler(sys.stdout) 75 console = logging.StreamHandler(sys.stdout)
76 format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") 76 format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
77 bb.msg.addDefaultlogFilter(console)
77 console.setFormatter(format) 78 console.setFormatter(format)
78 logger.addHandler(console) 79 logger.addHandler(console)
79 80
@@ -120,8 +121,8 @@ def main(server, eventHandler):
120 # For "normal" logging conditions, don't show note logs from tasks 121 # For "normal" logging conditions, don't show note logs from tasks
121 # but do show them if the user has changed the default log level to 122 # but do show them if the user has changed the default log level to
122 # include verbose/debug messages 123 # include verbose/debug messages
123 if logger.getEffectiveLevel() > format.VERBOSE: 124 #if logger.getEffectiveLevel() > format.VERBOSE:
124 if event.taskpid != 0 and event.levelno <= format.NOTE: 125 if event.taskpid != 0 and event.levelno <= format.NOTE:
125 continue 126 continue
126 logger.handle(event) 127 logger.handle(event)
127 continue 128 continue
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py
index 4eac2852ed..1cf1a8da44 100644
--- a/bitbake/lib/bb/utils.py
+++ b/bitbake/lib/bb/utils.py
@@ -830,21 +830,6 @@ def which(path, item, direction = 0):
830 830
831 return "" 831 return ""
832 832
833def init_logger(logger, verbose, debug, debug_domains):
834 """
835 Set verbosity and debug levels in the logger
836 """
837
838 if debug:
839 bb.msg.set_debug_level(debug)
840 elif verbose:
841 bb.msg.set_verbose(True)
842 else:
843 bb.msg.set_debug_level(0)
844
845 if debug_domains:
846 bb.msg.set_debug_domains(debug_domains)
847
848def to_boolean(string, default=None): 833def to_boolean(string, default=None):
849 if not string: 834 if not string:
850 return default 835 return default