summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/msg.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/msg.py')
-rw-r--r--bitbake/lib/bb/msg.py38
1 files changed, 32 insertions, 6 deletions
diff --git a/bitbake/lib/bb/msg.py b/bitbake/lib/bb/msg.py
index 291b38ff7f..4f616ff42e 100644
--- a/bitbake/lib/bb/msg.py
+++ b/bitbake/lib/bb/msg.py
@@ -30,7 +30,9 @@ class BBLogFormatter(logging.Formatter):
30 PLAIN = logging.INFO + 1 30 PLAIN = logging.INFO + 1
31 VERBNOTE = logging.INFO + 2 31 VERBNOTE = logging.INFO + 2
32 ERROR = logging.ERROR 32 ERROR = logging.ERROR
33 ERRORONCE = logging.ERROR - 1
33 WARNING = logging.WARNING 34 WARNING = logging.WARNING
35 WARNONCE = logging.WARNING - 1
34 CRITICAL = logging.CRITICAL 36 CRITICAL = logging.CRITICAL
35 37
36 levelnames = { 38 levelnames = {
@@ -42,7 +44,9 @@ class BBLogFormatter(logging.Formatter):
42 PLAIN : '', 44 PLAIN : '',
43 VERBNOTE: 'NOTE', 45 VERBNOTE: 'NOTE',
44 WARNING : 'WARNING', 46 WARNING : 'WARNING',
47 WARNONCE : 'WARNING',
45 ERROR : 'ERROR', 48 ERROR : 'ERROR',
49 ERRORONCE : 'ERROR',
46 CRITICAL: 'ERROR', 50 CRITICAL: 'ERROR',
47 } 51 }
48 52
@@ -58,7 +62,9 @@ class BBLogFormatter(logging.Formatter):
58 PLAIN : BASECOLOR, 62 PLAIN : BASECOLOR,
59 VERBNOTE: BASECOLOR, 63 VERBNOTE: BASECOLOR,
60 WARNING : YELLOW, 64 WARNING : YELLOW,
65 WARNONCE : YELLOW,
61 ERROR : RED, 66 ERROR : RED,
67 ERRORONCE : RED,
62 CRITICAL: RED, 68 CRITICAL: RED,
63 } 69 }
64 70
@@ -83,10 +89,6 @@ class BBLogFormatter(logging.Formatter):
83 msg = logging.Formatter.format(self, record) 89 msg = logging.Formatter.format(self, record)
84 if hasattr(record, 'bb_exc_formatted'): 90 if hasattr(record, 'bb_exc_formatted'):
85 msg += '\n' + ''.join(record.bb_exc_formatted) 91 msg += '\n' + ''.join(record.bb_exc_formatted)
86 elif hasattr(record, 'bb_exc_info'):
87 etype, value, tb = record.bb_exc_info
88 formatted = bb.exceptions.format_exception(etype, value, tb, limit=5)
89 msg += '\n' + ''.join(formatted)
90 return msg 92 return msg
91 93
92 def colorize(self, record): 94 def colorize(self, record):
@@ -121,6 +123,22 @@ class BBLogFilter(object):
121 return True 123 return True
122 return False 124 return False
123 125
126class LogFilterShowOnce(logging.Filter):
127 def __init__(self):
128 self.seen_warnings = set()
129 self.seen_errors = set()
130
131 def filter(self, record):
132 if record.levelno == bb.msg.BBLogFormatter.WARNONCE:
133 if record.msg in self.seen_warnings:
134 return False
135 self.seen_warnings.add(record.msg)
136 if record.levelno == bb.msg.BBLogFormatter.ERRORONCE:
137 if record.msg in self.seen_errors:
138 return False
139 self.seen_errors.add(record.msg)
140 return True
141
124class LogFilterGEQLevel(logging.Filter): 142class LogFilterGEQLevel(logging.Filter):
125 def __init__(self, level): 143 def __init__(self, level):
126 self.strlevel = str(level) 144 self.strlevel = str(level)
@@ -206,8 +224,9 @@ def logger_create(name, output=sys.stderr, level=logging.INFO, preserve_handlers
206 """Standalone logger creation function""" 224 """Standalone logger creation function"""
207 logger = logging.getLogger(name) 225 logger = logging.getLogger(name)
208 console = logging.StreamHandler(output) 226 console = logging.StreamHandler(output)
227 console.addFilter(bb.msg.LogFilterShowOnce())
209 format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") 228 format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
210 if color == 'always' or (color == 'auto' and output.isatty()): 229 if color == 'always' or (color == 'auto' and output.isatty() and os.environ.get('NO_COLOR', '') == ''):
211 format.enable_color() 230 format.enable_color()
212 console.setFormatter(format) 231 console.setFormatter(format)
213 if preserve_handlers: 232 if preserve_handlers:
@@ -293,10 +312,17 @@ def setLoggingConfig(defaultconfig, userconfigfile=None):
293 312
294 # Convert all level parameters to integers in case users want to use the 313 # Convert all level parameters to integers in case users want to use the
295 # bitbake defined level names 314 # bitbake defined level names
296 for h in logconfig["handlers"].values(): 315 for name, h in logconfig["handlers"].items():
297 if "level" in h: 316 if "level" in h:
298 h["level"] = bb.msg.stringToLevel(h["level"]) 317 h["level"] = bb.msg.stringToLevel(h["level"])
299 318
319 # Every handler needs its own instance of the once filter.
320 once_filter_name = name + ".showonceFilter"
321 logconfig.setdefault("filters", {})[once_filter_name] = {
322 "()": "bb.msg.LogFilterShowOnce",
323 }
324 h.setdefault("filters", []).append(once_filter_name)
325
300 for l in logconfig["loggers"].values(): 326 for l in logconfig["loggers"].values():
301 if "level" in l: 327 if "level" in l:
302 l["level"] = bb.msg.stringToLevel(l["level"]) 328 l["level"] = bb.msg.stringToLevel(l["level"])