Files
poky/bitbake/lib/bb/msg.py
Joshua Watt 26473bfbea bitbake: lib/bb/msg: Convert default domains to a dictionary
Converts the default domain variable to a dictionary where the keys are
the logging domains and the values are the logging level (instead of the
debug count). This makes it easier to deal with the logging domains and
the awkward conversion from a list to a dictionary only needs to be done
once when logging is initialized. Finally, other code has been written
that already assumes this variable is a dictionary, see:

f04cd93109 ("bitbake: lib/bb: Optimise out debug messages from cooker")

(Bitbake rev: f32a8bc7ff7a0b0750b6934a96f5d48391b1383a)

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2020-03-13 11:29:23 +00:00

212 lines
5.9 KiB
Python

"""
BitBake 'msg' implementation
Message handling infrastructure for bitbake
"""
# Copyright (C) 2006 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
#
import sys
import copy
import logging
from itertools import groupby
import bb
import bb.event
class BBLogFormatter(logging.Formatter):
"""Formatter which ensures that our 'plain' messages (logging.INFO + 1) are used as is"""
DEBUG3 = logging.DEBUG - 2
DEBUG2 = logging.DEBUG - 1
DEBUG = logging.DEBUG
VERBOSE = logging.INFO - 1
NOTE = logging.INFO
PLAIN = logging.INFO + 1
VERBNOTE = logging.INFO + 2
ERROR = logging.ERROR
WARNING = logging.WARNING
CRITICAL = logging.CRITICAL
levelnames = {
DEBUG3 : 'DEBUG',
DEBUG2 : 'DEBUG',
DEBUG : 'DEBUG',
VERBOSE: 'NOTE',
NOTE : 'NOTE',
PLAIN : '',
VERBNOTE: 'NOTE',
WARNING : 'WARNING',
ERROR : 'ERROR',
CRITICAL: 'ERROR',
}
color_enabled = False
BASECOLOR, BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = list(range(29,38))
COLORS = {
DEBUG3 : CYAN,
DEBUG2 : CYAN,
DEBUG : CYAN,
VERBOSE : BASECOLOR,
NOTE : BASECOLOR,
PLAIN : BASECOLOR,
VERBNOTE: BASECOLOR,
WARNING : YELLOW,
ERROR : RED,
CRITICAL: RED,
}
BLD = '\033[1;%dm'
STD = '\033[%dm'
RST = '\033[0m'
def getLevelName(self, levelno):
try:
return self.levelnames[levelno]
except KeyError:
self.levelnames[levelno] = value = 'Level %d' % levelno
return value
def format(self, record):
record.levelname = self.getLevelName(record.levelno)
if record.levelno == self.PLAIN:
msg = record.getMessage()
else:
if self.color_enabled:
record = self.colorize(record)
msg = logging.Formatter.format(self, record)
if hasattr(record, 'bb_exc_formatted'):
msg += '\n' + ''.join(record.bb_exc_formatted)
elif hasattr(record, 'bb_exc_info'):
etype, value, tb = record.bb_exc_info
formatted = bb.exceptions.format_exception(etype, value, tb, limit=5)
msg += '\n' + ''.join(formatted)
return msg
def colorize(self, record):
color = self.COLORS[record.levelno]
if self.color_enabled and color is not None:
record = copy.copy(record)
record.levelname = "".join([self.BLD % color, record.levelname, self.RST])
record.msg = "".join([self.STD % color, record.msg, self.RST])
return record
def enable_color(self):
self.color_enabled = True
class BBLogFilter(object):
def __init__(self, handler, level, debug_domains):
self.stdlevel = level
self.debug_domains = debug_domains
loglevel = level
for domain in debug_domains:
if debug_domains[domain] < loglevel:
loglevel = debug_domains[domain]
handler.setLevel(loglevel)
handler.addFilter(self)
def filter(self, record):
if record.levelno >= self.stdlevel:
return True
if record.name in self.debug_domains and record.levelno >= self.debug_domains[record.name]:
return True
return False
class BBLogFilterStdErr(BBLogFilter):
def filter(self, record):
if not BBLogFilter.filter(self, record):
return False
if record.levelno >= logging.ERROR:
return True
return False
class BBLogFilterStdOut(BBLogFilter):
def filter(self, record):
if not BBLogFilter.filter(self, record):
return False
if record.levelno < logging.ERROR:
return True
return False
# Message control functions
#
loggerDefaultDebugLevel = 0
loggerDefaultVerbose = False
loggerVerboseLogs = False
loggerDefaultDomains = {}
def init_msgconfig(verbose, debug, debug_domains=None):
"""
Set default verbosity and debug levels config the logger
"""
bb.msg.loggerDefaultDebugLevel = debug
bb.msg.loggerDefaultVerbose = verbose
if verbose:
bb.msg.loggerVerboseLogs = True
bb.msg.loggerDefaultDomains = {}
if debug_domains:
for (domainarg, iterator) in groupby(debug_domains):
dlevel = len(tuple(iterator))
bb.msg.loggerDefaultDomains["BitBake.%s" % domainarg] = logging.DEBUG - dlevel + 1
def constructLogOptions():
debug = loggerDefaultDebugLevel
verbose = loggerDefaultVerbose
if debug:
level = BBLogFormatter.DEBUG - debug + 1
elif verbose:
level = BBLogFormatter.VERBOSE
else:
level = BBLogFormatter.NOTE
return level, loggerDefaultDomains
def addDefaultlogFilter(handler, cls = BBLogFilter, forcelevel=None):
level, debug_domains = constructLogOptions()
if forcelevel is not None:
level = forcelevel
cls(handler, level, debug_domains)
#
# Message handling functions
#
def fatal(msgdomain, msg):
if msgdomain:
logger = logging.getLogger("BitBake.%s" % msgdomain)
else:
logger = logging.getLogger("BitBake")
logger.critical(msg)
sys.exit(1)
def logger_create(name, output=sys.stderr, level=logging.INFO, preserve_handlers=False, color='auto'):
"""Standalone logger creation function"""
logger = logging.getLogger(name)
console = logging.StreamHandler(output)
format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
if color == 'always' or (color == 'auto' and output.isatty()):
format.enable_color()
console.setFormatter(format)
if preserve_handlers:
logger.addHandler(console)
else:
logger.handlers = [console]
logger.setLevel(level)
return logger
def has_console_handler(logger):
for handler in logger.handlers:
if isinstance(handler, logging.StreamHandler):
if handler.stream in [sys.stderr, sys.stdout]:
return True
return False