Log to RAM and display log in crash dialog

This commit is contained in:
Florian Bruhin 2014-05-25 18:46:15 +02:00
parent 353a447dd6
commit f87e7b76f4
2 changed files with 57 additions and 9 deletions

View File

@ -19,6 +19,7 @@
import logging
from logging import getLogger
from collections import deque
# The different loggers used.
@ -38,29 +39,44 @@ hints = getLogger('hints')
keyboard = getLogger('keyboard')
ram_handler = None
def init_log(args):
"""Init loggers based on the argparse namespace passed."""
global ram_handler
logfilter = LogFilter(None if args.logfilter is None
else args.logfilter.split(','))
level = 'DEBUG' if args.debug else args.loglevel.upper()
try:
# pylint: disable=protected-access
numeric_level = logging._nameToLevel[level]
except KeyError:
raise ValueError("Invalid log level: {}".format(args.loglevel))
extended_fmt = ('{asctime} [{levelname}] [{name}|{module}:{funcName}:'
'{lineno}] {message}')
extended_datefmt = '%H:%M:%S'
simple_fmt = '{levelname}: {message}'
simple_datefmt = None
if numeric_level <= logging.DEBUG:
fmt = ('{asctime} [{levelname}] [{name}|{module}:{funcName}:{lineno}] '
'{message}')
datefmt = '%Y-%m-%d %H:%M:%S'
console_formatter = logging.Formatter(extended_fmt, extended_datefmt,
'{')
else:
fmt = '{levelname}: {message}'
datefmt = None
formatter = logging.Formatter(fmt, datefmt, '{')
console_formatter = logging.Formatter(simple_fmt, simple_datefmt, '{')
console_handler = logging.StreamHandler()
console_handler.addFilter(logfilter)
console_handler.setLevel(level)
console_handler.setFormatter(formatter)
console_handler.setFormatter(console_formatter)
ram_formatter = logging.Formatter(extended_fmt, extended_datefmt, '{')
ram_handler = RAMHandler(capacity=200)
ram_handler.setLevel(logging.NOTSET)
ram_handler.setFormatter(ram_formatter)
root = getLogger()
root.addHandler(console_handler)
root.addHandler(ram_handler)
root.setLevel(logging.NOTSET)
@ -91,3 +107,29 @@ class LogFilter(logging.Filter):
elif record.name[len(name)] == '.':
return True
return False
class RAMHandler(logging.Handler):
"""Logging handler which keeps the messages in a deque in RAM.
Loosly based on logging.BufferingHandler which is unsuitable because it
uses a simple list rather than a deque.
Attributes:
data: A deque containing the logging records.
"""
def __init__(self, capacity):
super().__init__()
self.data = deque(maxlen=capacity)
def emit(self, record):
self.data.append(record)
def dump_log(self):
"""Dump the complete formatted log data as as string."""
lines = []
for record in self.data:
lines.append(self.format(record))
return '\n'.join(lines)

View File

@ -21,13 +21,14 @@ import sys
import traceback
from urllib.error import URLError
from PyQt5.QtCore import Qt
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QClipboard
from PyQt5.QtWidgets import (QDialog, QLabel, QTextEdit, QPushButton,
QVBoxLayout, QHBoxLayout, QApplication)
import qutebrowser.config.config as config
import qutebrowser.utils.misc as utils
import qutebrowser.utils.log as logutils
from qutebrowser.utils.version import version
@ -52,8 +53,8 @@ class _CrashDialog(QDialog):
self._hbox = None
self._lbl = None
self._gather_crash_info()
self.setFixedSize(500, 350)
self.setWindowTitle("Whoops!")
self.resize(QSize(800, 600))
self._vbox = QVBoxLayout(self)
self._init_text()
self._txt = QTextEdit()
@ -110,6 +111,11 @@ class _CrashDialog(QDialog):
config.instance().dump_userconfig()))
except AttributeError:
pass
try:
self._crash_info.append(("Debug log",
logutils.ram_handler.dump_log()))
except AttributeError:
pass
def _format_crash_info(self):
"""Format the gathered crash info to be displayed.