diff --git a/bitbake/bin/bitbake b/bitbake/bin/bitbake index 960d8d0bc7..9b2cfdf5c5 100755 --- a/bitbake/bin/bitbake +++ b/bitbake/bin/bitbake @@ -23,7 +23,7 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import os -import sys +import sys, logging sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib')) @@ -31,6 +31,7 @@ import optparse import warnings from traceback import format_exception import bb +from bb import event import bb.msg from bb import cooker from bb import ui @@ -39,7 +40,7 @@ from bb.server import none #from bb.server import xmlrpc __version__ = "1.11.0" - +logger = logging.getLogger("BitBake") #============================================================================# @@ -163,6 +164,8 @@ Default BBFILES are the .bb files in the current directory.""") configuration.pkgs_to_build.extend(args[1:]) configuration.initial_path = os.environ['PATH'] + logger.addHandler(event.LogHandler()) + #server = bb.server.xmlrpc server = bb.server.none diff --git a/bitbake/lib/bb/__init__.py b/bitbake/lib/bb/__init__.py index 88adfc1dfa..8cda4255bc 100644 --- a/bitbake/lib/bb/__init__.py +++ b/bitbake/lib/bb/__init__.py @@ -28,8 +28,18 @@ if sys.version_info < (2, 6, 0): raise RuntimeError("Sorry, python 2.6.0 or later is required for this version of bitbake") import os +import logging import bb.msg +class NullHandler(logging.Handler): + def emit(self, record): + pass + +logging.raiseExceptions = False +logger = logging.getLogger("BitBake") +logger.addHandler(NullHandler()) +logger.setLevel(logging.INFO) + if "BBDEBUG" in os.environ: level = int(os.environ["BBDEBUG"]) if level: diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py index 45458c2d63..c04ffd5ac1 100644 --- a/bitbake/lib/bb/event.py +++ b/bitbake/lib/bb/event.py @@ -24,8 +24,9 @@ BitBake build tools. import os, sys import warnings -import bb.utils import pickle +import logging +import bb.utils # This is the pid for which we should generate the event. This is set when # the runqueue forks off. @@ -56,7 +57,7 @@ bb.utils._context["Handled"] = Handled def fire_class_handlers(event, d): import bb.msg - if isinstance(event, bb.msg.MsgBase): + if isinstance(event, MsgBase): return for handler in _handlers: @@ -298,3 +299,49 @@ class DepTreeGenerated(Event): def __init__(self, depgraph): Event.__init__(self) self._depgraph = depgraph + +class MsgBase(Event): + """Base class for messages""" + + def __init__(self, msg): + self._message = msg + Event.__init__(self) + +class MsgDebug(MsgBase): + """Debug Message""" + +class MsgNote(MsgBase): + """Note Message""" + +class MsgWarn(MsgBase): + """Warning Message""" + +class MsgError(MsgBase): + """Error Message""" + +class MsgFatal(MsgBase): + """Fatal Message""" + +class MsgPlain(MsgBase): + """General output""" + +class LogHandler(logging.Handler): + """Dispatch logging messages as bitbake events""" + + messages = ( + (logging.DEBUG, MsgDebug), + (logging.INFO, MsgNote), + (logging.WARNING, MsgWarn), + (logging.ERROR, MsgError), + (logging.CRITICAL, MsgFatal), + ) + + def emit(self, record): + for level, msgclass in self.messages: + if record.levelno <= level: + msg = self.format(record) + fire(msgclass(msg), None) + if bb.event.useStdout: + print(record.levelname + ": " + record.getMessage()) + break + diff --git a/bitbake/lib/bb/msg.py b/bitbake/lib/bb/msg.py index 21692d930d..254ba07a04 100644 --- a/bitbake/lib/bb/msg.py +++ b/bitbake/lib/bb/msg.py @@ -23,12 +23,26 @@ Message handling infrastructure for bitbake # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import sys +import logging import collections +from itertools import groupby import bb import bb.event -debug_level = collections.defaultdict(lambda: 0) -verbose = False +class Loggers(dict): + def __getitem__(self, key): + if key in self: + return dict.__getitem__(self, key) + else: + log = logging.getLogger("BitBake.%s" % domain._fields[key]) + dict.__setitem__(self, key, log) + return log + +class DebugLevel(dict): + def __getitem__(self, key): + if key == "default": + key = domain.Default + return get_debug_level(key) def _NamedTuple(name, fields): Tuple = collections.namedtuple(name, " ".join(fields)) @@ -49,96 +63,84 @@ domain = _NamedTuple("Domain", ( "TaskData", "Util")) - -class MsgBase(bb.event.Event): - """Base class for messages""" - - def __init__(self, msg): - self._message = msg - bb.event.Event.__init__(self) - -class MsgDebug(MsgBase): - """Debug Message""" - -class MsgNote(MsgBase): - """Note Message""" - -class MsgWarn(MsgBase): - """Warning Message""" - -class MsgError(MsgBase): - """Error Message""" - -class MsgFatal(MsgBase): - """Fatal Message""" - -class MsgPlain(MsgBase): - """General output""" +logger = logging.getLogger("BitBake") +loggers = Loggers() +debug_level = DebugLevel() # # Message control functions # def set_debug_level(level): - for d in domain: - debug_level[d] = level - debug_level[domain.Default] = level + for log in loggers.itervalues(): + log.setLevel(logging.NOTSET) + + if level: + logger.setLevel(logging.DEBUG - level + 1) + else: + logger.setLevel(logging.INFO) def get_debug_level(msgdomain = domain.Default): - return debug_level[msgdomain] + if not msgdomain: + level = logger.getEffectiveLevel() + else: + level = loggers[msgdomain].getEffectiveLevel() + return max(0, logging.DEBUG - level + 1) def set_verbose(level): - verbose = level + if level: + logger.setLevel(logging.INFO - 1) + else: + logger.setLevel(logging.INFO) -def set_debug_domains(strdomains): - for domainstr in strdomains: - for d in domain: - if domain._fields[d] == domainstr: - debug_level[d] += 1 +def set_debug_domains(domainargs): + for (domainarg, iterator) in groupby(domainargs): + for index, msgdomain in enumerate(domain._fields): + if msgdomain == domainarg: + level = len(tuple(iterator)) + if level: + loggers[index].setLevel(logging.DEBUG - level + 1) break else: - warn(None, "Logging domain %s is not valid, ignoring" % domainstr) + warn(None, "Logging domain %s is not valid, ignoring" % domainarg) # # Message handling functions # def debug(level, msgdomain, msg, fn = None): + level = logging.DEBUG - (level - 1) if not msgdomain: - msgdomain = domain.Default - - if debug_level[msgdomain] >= level: - bb.event.fire(MsgDebug(msg), None) - if bb.event.useStdout: - print('DEBUG: %s' % (msg)) - -def note(level, msgdomain, msg, fn = None): - if not msgdomain: - msgdomain = domain.Default - - if level == 1 or verbose or debug_level[msgdomain] >= 1: - bb.event.fire(MsgNote(msg), None) - if bb.event.useStdout: - print('NOTE: %s' % (msg)) - -def warn(msgdomain, msg, fn = None): - bb.event.fire(MsgWarn(msg), None) - if bb.event.useStdout: - print('WARNING: %s' % (msg)) - -def error(msgdomain, msg, fn = None): - bb.event.fire(MsgError(msg), None) - if bb.event.useStdout: - print('ERROR: %s' % (msg)) - -def fatal(msgdomain, msg, fn = None): - bb.event.fire(MsgFatal(msg), None) - - if bb.event.useStdout: - print('FATAL: %s' % (msg)) - sys.exit(1) + logger.log(level, msg) + else: + loggers[msgdomain].log(level, msg) def plain(msg, fn = None): - bb.event.fire(MsgPlain(msg), None) - if bb.event.useStdout: - print(msg) + logger.log(logging.INFO + 1, msg) + +def note(level, msgdomain, msg, fn = None): + level = logging.INFO - (level - 1) + if not msgdomain: + logger.log(level, msg) + else: + loggers[msgdomain].log(level, msg) + +def warn(msgdomain, msg, fn = None): + if not msgdomain: + logger.warn(msg) + else: + loggers[msgdomain].warn(msg) + +def error(msgdomain, msg, fn = None): + if not msgdomain: + logger.error(msg) + else: + loggers[msgdomain].error(msg) + +def fatal(msgdomain, msg, fn = None): + if not msgdomain: + logger.critical(msg) + else: + loggers[msgdomain].critical(msg) + sys.exit(1) + diff --git a/bitbake/lib/bb/ui/knotty.py b/bitbake/lib/bb/ui/knotty.py index 858a00b568..9162c79f6a 100644 --- a/bitbake/lib/bb/ui/knotty.py +++ b/bitbake/lib/bb/ui/knotty.py @@ -72,23 +72,23 @@ def init(server, eventHandler): print("%s: %s (pid %s)" % (tasknum, activetasks[task]["title"], task)) tasknum = tasknum + 1 - if isinstance(event, bb.msg.MsgPlain): + if isinstance(event, bb.event.MsgPlain): print(event._message) continue - if isinstance(event, bb.msg.MsgDebug): + if isinstance(event, bb.event.MsgDebug): print('DEBUG: ' + event._message) continue - if isinstance(event, bb.msg.MsgNote): + if isinstance(event, bb.event.MsgNote): print('NOTE: ' + event._message) continue - if isinstance(event, bb.msg.MsgWarn): + if isinstance(event, bb.event.MsgWarn): print('WARNING: ' + event._message) continue - if isinstance(event, bb.msg.MsgError): + if isinstance(event, bb.event.MsgError): return_value = 1 print('ERROR: ' + event._message) continue - if isinstance(event, bb.msg.MsgFatal): + if isinstance(event, bb.event.MsgFatal): return_value = 1 print('FATAL: ' + event._message) continue diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py index 922b7256e3..8330c80b72 100644 --- a/bitbake/lib/bb/utils.py +++ b/bitbake/lib/bb/utils.py @@ -793,13 +793,12 @@ def init_logger(logger, verbose, debug, debug_domains): Set verbosity and debug levels in the logger """ - if verbose: - logger.set_verbose(True) - if debug: - logger.set_debug_level(debug) + bb.msg.set_debug_level(debug) + elif verbose: + bb.msg.set_verbose(True) else: - logger.set_debug_level(0) + bb.msg.set_debug_level(0) if debug_domains: - logger.set_debug_domains(debug_domains) + bb.msg.set_debug_domains(debug_domains)