aboutsummaryrefslogtreecommitdiff
path: root/wa/utils
diff options
context:
space:
mode:
authorsergei Trofimov <sergei.trofimov@arm.com>2018-04-30 11:30:45 +0100
committerMarc Bonnici <marc.bonnici@arm.com>2018-05-09 15:06:31 +0100
commit1e750c659b387733309352eaff58b4909301a227 (patch)
tree84dc2b7f57033300a4213c28948c830d3f8dae69 /wa/utils
parent8d330924dc7b79c75094f24923cf7811226dd3da (diff)
utils/log: add early record buffering
Buffer early log records until a log file becomes available, flush records to said file afterwards. This ensures that early log output, which, among other things, contains plugin discovery logging, is not lost. Buffer capacity is configurable via an environment variable.
Diffstat (limited to 'wa/utils')
-rw-r--r--wa/utils/log.py47
1 files changed, 45 insertions, 2 deletions
diff --git a/wa/utils/log.py b/wa/utils/log.py
index 3ac4baf8..e554a109 100644
--- a/wa/utils/log.py
+++ b/wa/utils/log.py
@@ -16,9 +16,11 @@
# pylint: disable=E1101
import logging
+import logging.handlers
+import os
import string
-import threading
import subprocess
+import threading
import colorama
@@ -39,16 +41,19 @@ COLOR_MAP = {
RESET_COLOR = colorama.Style.RESET_ALL
+DEFAULT_INIT_BUFFER_CAPACITY = 1000
+
_indent_level = 0
_indent_width = 4
_console_handler = None
+_init_handler = None
def init(verbosity=logging.INFO, color=True, indent_with=4,
regular_fmt='%(levelname)-8s %(message)s',
verbose_fmt='%(asctime)s %(levelname)-8s %(name)10.10s: %(message)s',
debug=False):
- global _indent_width, _console_handler
+ global _indent_width, _console_handler, _init_handler
_indent_width = indent_with
signal.log_error_func = lambda m: log_error(m, signal.logger)
@@ -70,6 +75,13 @@ def init(verbosity=logging.INFO, color=True, indent_with=4,
_console_handler.setLevel(logging.INFO)
_console_handler.setFormatter(formatter(regular_fmt))
root_logger.addHandler(_console_handler)
+
+ buffer_capacity = os.getenv('WA_LOG_BUFFER_CAPACITY',
+ DEFAULT_INIT_BUFFER_CAPACITY)
+ _init_handler = InitHandler(buffer_capacity)
+ _init_handler.setLevel(logging.DEBUG)
+ root_logger.addHandler(_init_handler)
+
logging.basicConfig(level=logging.DEBUG)
if not debug:
logging.raiseExceptions = False
@@ -84,10 +96,17 @@ def set_level(level):
def add_file(filepath, level=logging.DEBUG,
fmt='%(asctime)s %(levelname)-8s %(name)10.10s: %(message)s'):
+ global _init_handler
root_logger = logging.getLogger()
file_handler = logging.FileHandler(filepath)
file_handler.setLevel(level)
file_handler.setFormatter(LineFormatter(fmt))
+
+ if _init_handler:
+ _init_handler.flush_to_target(file_handler)
+ root_logger.removeHandler(_init_handler)
+ _init_handler = None
+
root_logger.addHandler(file_handler)
@@ -196,6 +215,30 @@ class ErrorSignalHandler(logging.Handler):
signal.send(signal.WARNING_LOGGED, self, record)
+class InitHandler(logging.handlers.BufferingHandler):
+ """
+ Used to buffer early logging records before a log file is created.
+
+ """
+
+ def __init__(self, capacity):
+ super(InitHandler, self).__init__(capacity)
+ self.targets = []
+
+ def add_target(self, target):
+ if target not in self.targets:
+ self.targets.append(target)
+
+ def flush(self):
+ for target in self.targets:
+ self.flush_to_target(target)
+ self.buffer = []
+
+ def flush_to_target(self, target):
+ for record in self.buffer:
+ target.emit(record)
+
+
class LineFormatter(logging.Formatter):
"""
Logs each line of the message separately.