From 92d43151bad2f2ac6e292d725555249082462f81 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 27 May 2013 15:05:08 -0300 Subject: Add logging handler with history and signal emision --- src/leap/util/leap_log_handler.py | 99 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/leap/util/leap_log_handler.py (limited to 'src/leap/util/leap_log_handler.py') diff --git a/src/leap/util/leap_log_handler.py b/src/leap/util/leap_log_handler.py new file mode 100644 index 00000000..0e598032 --- /dev/null +++ b/src/leap/util/leap_log_handler.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# leap_log_handler.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Custom handler for the logger window. +""" +import logging + +from PySide import QtCore + + +class LeapLogHandler(logging.Handler, QtCore.QObject): + """ + Custom logging handler. It emits Qt signals so it can be plugged to a gui. + Also stores an history of logs that can be fetched after connect to a gui. + """ + # All dicts returned are of the form + # {'record': LogRecord, 'message': str} + new_log = QtCore.Signal(dict) + + MESSAGE_KEY = 'message' + RECORD_KEY = 'record' + + def __init__(self): + logging.Handler.__init__(self) + QtCore.QObject.__init__(self) + + self._log_history = [] + + def _set_format(self, logging_level): + """ + Sets the log format depending on the parameter. + It uses html and css to set the colors for the logs. + + :param logging_level: the debug level to define the color. + :type logging_level: str. + """ + html_style = { + 'DEBUG': "color: blue", + 'INFO': "color: black", + 'WARNING': "color: black; background: yellow;", + 'ERROR': "color: red", + 'CRITICAL': "color: red; font-weight: bold;" + } + + style_open = "" + style_close = "" + time = "%(asctime)s" + name = style_open + "%(name)s" + level = "%(levelname)s" + message = "%(message)s" + style_close + format_attrs = [time, name, level, message] + log_format = ' - '.join(format_attrs) + formatter = logging.Formatter(log_format) + self.setFormatter(formatter) + + def emit(self, logRecord): + """ + This method is fired every time that a record is logged by the + logging module. + This method reimplements logging.Handler.emit that is fired + in every logged message. + QObject.emit gets in the way on the PySide signal model but we + workarouded that issue. + + :param logRecord: the record emitted by the logging module. + :type logRecord: logging.LogRecord. + """ + self._set_format(logRecord.levelname) + log = self.format(logRecord) + log_item = {self.RECORD_KEY: logRecord, self.MESSAGE_KEY: log} + self._log_history.append(log_item) + + # WARNING: the new-style connection does NOT work because PySide + # translates the emit method to self.emit, and that collides with + # the emit method for logging.Handler + # self.new_log.emit(log_item) + QtCore.QObject.emit(self, QtCore.SIGNAL('new_log(PyObject)'), log_item) + + @property + def log_history(self): + """ + Returns the history of the logged messages. + """ + return self._log_history -- cgit v1.2.3 From 9b2c0d673a1a8a4641508188c87662c9eacfd0ce Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 12 Jun 2013 02:15:20 +0900 Subject: workaround for pyside multiple inheritance problem --- src/leap/util/leap_log_handler.py | 74 ++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 17 deletions(-) (limited to 'src/leap/util/leap_log_handler.py') diff --git a/src/leap/util/leap_log_handler.py b/src/leap/util/leap_log_handler.py index 0e598032..3264e05c 100644 --- a/src/leap/util/leap_log_handler.py +++ b/src/leap/util/leap_log_handler.py @@ -14,32 +14,30 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . - """ Custom handler for the logger window. """ import logging +from functools import partial from PySide import QtCore - -class LeapLogHandler(logging.Handler, QtCore.QObject): +class LogHandler(logging.Handler): """ - Custom logging handler. It emits Qt signals so it can be plugged to a gui. - Also stores an history of logs that can be fetched after connect to a gui. + This is the custom handler that implements our desired formatting + and also keeps a history of all the logged events. """ - # All dicts returned are of the form - # {'record': LogRecord, 'message': str} - new_log = QtCore.Signal(dict) MESSAGE_KEY = 'message' RECORD_KEY = 'record' - def __init__(self): - logging.Handler.__init__(self) - QtCore.QObject.__init__(self) + # TODO This is going to eat lots of memory after some time. + # Should be pruned at some moment. + _log_history = [] - self._log_history = [] + def __init__(self, qtsignal): + logging.Handler.__init__(self) + self._qtsignal = qtsignal def _set_format(self, logging_level): """ @@ -66,6 +64,7 @@ class LeapLogHandler(logging.Handler, QtCore.QObject): format_attrs = [time, name, level, message] log_format = ' - '.join(format_attrs) formatter = logging.Formatter(log_format) + self.setFormatter(formatter) def emit(self, logRecord): @@ -74,8 +73,6 @@ class LeapLogHandler(logging.Handler, QtCore.QObject): logging module. This method reimplements logging.Handler.emit that is fired in every logged message. - QObject.emit gets in the way on the PySide signal model but we - workarouded that issue. :param logRecord: the record emitted by the logging module. :type logRecord: logging.LogRecord. @@ -83,17 +80,60 @@ class LeapLogHandler(logging.Handler, QtCore.QObject): self._set_format(logRecord.levelname) log = self.format(logRecord) log_item = {self.RECORD_KEY: logRecord, self.MESSAGE_KEY: log} - self._log_history.append(log_item) + self._qtsignal(log_item) + + +class HandlerAdapter(object): + """ + New style class that accesses all attributes from the LogHandler. + + Used as a workaround for a problem with multiple inheritance with Pyside + that surfaced under OSX with pyside 1.1.0. + """ + MESSAGE_KEY = 'message' + RECORD_KEY = 'record' + + def __init__(self, qtsignal): + self._handler = LogHandler(qtsignal=qtsignal) + + def setLevel(self, *args, **kwargs): + return self._handler.setLevel(*args, **kwargs) + + def handle(self, *args, **kwargs): + return self._handler.handle(*args, **kwargs) + + @property + def level(self): + return self._handler.level + + +class LeapLogHandler(QtCore.QObject, HandlerAdapter): + """ + Custom logging handler. It emits Qt signals so it can be plugged to a gui. + + Its inner handler also stores an history of logs that can be fetched after + having been connected to a gui. + """ + # All dicts returned are of the form + # {'record': LogRecord, 'message': str} + new_log = QtCore.Signal(dict) + + def __init__(self): + QtCore.QObject.__init__(self) + HandlerAdapter.__init__(self, qtsignal=self.qtsignal) + def qtsignal(self, log_item): # WARNING: the new-style connection does NOT work because PySide # translates the emit method to self.emit, and that collides with # the emit method for logging.Handler # self.new_log.emit(log_item) - QtCore.QObject.emit(self, QtCore.SIGNAL('new_log(PyObject)'), log_item) + QtCore.QObject.emit( + self, + QtCore.SIGNAL('new_log(PyObject)'), log_item) @property def log_history(self): """ Returns the history of the logged messages. """ - return self._log_history + return self._handler._log_history -- cgit v1.2.3 From ba27c14ba84c6869c187bdd09138bfae4424445d Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 13 Jun 2013 01:19:49 +0900 Subject: copy missing updown scripts if missing --- src/leap/util/leap_log_handler.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/leap/util/leap_log_handler.py') diff --git a/src/leap/util/leap_log_handler.py b/src/leap/util/leap_log_handler.py index 3264e05c..5b8ae789 100644 --- a/src/leap/util/leap_log_handler.py +++ b/src/leap/util/leap_log_handler.py @@ -18,10 +18,10 @@ Custom handler for the logger window. """ import logging -from functools import partial from PySide import QtCore + class LogHandler(logging.Handler): """ This is the custom handler that implements our desired formatting @@ -36,6 +36,11 @@ class LogHandler(logging.Handler): _log_history = [] def __init__(self, qtsignal): + """ + LogHander initialization. + Calls parent method and keeps a reference to the qtsignal + that will be used to fire the gui update. + """ logging.Handler.__init__(self) self._qtsignal = qtsignal @@ -119,6 +124,10 @@ class LeapLogHandler(QtCore.QObject, HandlerAdapter): new_log = QtCore.Signal(dict) def __init__(self): + """ + LeapLogHandler initialization. + Initializes parent classes. + """ QtCore.QObject.__init__(self) HandlerAdapter.__init__(self, qtsignal=self.qtsignal) -- cgit v1.2.3 From e6e88154f3b274ff97474a26a36dd6453f55de0b Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 14 Jun 2013 12:51:18 -0300 Subject: Bugfix: add logs to history. Closes #2871. --- src/leap/util/leap_log_handler.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/leap/util/leap_log_handler.py') diff --git a/src/leap/util/leap_log_handler.py b/src/leap/util/leap_log_handler.py index 5b8ae789..e5bc87e1 100644 --- a/src/leap/util/leap_log_handler.py +++ b/src/leap/util/leap_log_handler.py @@ -31,16 +31,16 @@ class LogHandler(logging.Handler): MESSAGE_KEY = 'message' RECORD_KEY = 'record' - # TODO This is going to eat lots of memory after some time. - # Should be pruned at some moment. - _log_history = [] - def __init__(self, qtsignal): """ LogHander initialization. Calls parent method and keeps a reference to the qtsignal that will be used to fire the gui update. """ + # TODO This is going to eat lots of memory after some time. + # Should be pruned at some moment. + self._log_history = [] + logging.Handler.__init__(self) self._qtsignal = qtsignal @@ -85,6 +85,7 @@ class LogHandler(logging.Handler): self._set_format(logRecord.levelname) log = self.format(logRecord) log_item = {self.RECORD_KEY: logRecord, self.MESSAGE_KEY: log} + self._log_history.append(log_item) self._qtsignal(log_item) -- cgit v1.2.3 From 36657c76b4c8511d5938dc6b81fde34c833ab7c7 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 25 Jun 2013 11:37:36 -0300 Subject: Change method for 'dependency injection' in test. --- src/leap/util/leap_log_handler.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/leap/util/leap_log_handler.py') diff --git a/src/leap/util/leap_log_handler.py b/src/leap/util/leap_log_handler.py index e5bc87e1..271096d3 100644 --- a/src/leap/util/leap_log_handler.py +++ b/src/leap/util/leap_log_handler.py @@ -44,7 +44,7 @@ class LogHandler(logging.Handler): logging.Handler.__init__(self) self._qtsignal = qtsignal - def _set_format(self, logging_level): + def _get_format(self, logging_level): """ Sets the log format depending on the parameter. It uses html and css to set the colors for the logs. @@ -70,7 +70,7 @@ class LogHandler(logging.Handler): log_format = ' - '.join(format_attrs) formatter = logging.Formatter(log_format) - self.setFormatter(formatter) + return formatter def emit(self, logRecord): """ @@ -82,7 +82,7 @@ class LogHandler(logging.Handler): :param logRecord: the record emitted by the logging module. :type logRecord: logging.LogRecord. """ - self._set_format(logRecord.levelname) + self.setFormatter(self._get_format(logRecord.levelname)) log = self.format(logRecord) log_item = {self.RECORD_KEY: logRecord, self.MESSAGE_KEY: log} self._log_history.append(log_item) -- cgit v1.2.3