summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomás Touceda <chiiph@leap.se>2013-09-03 17:59:50 -0300
committerTomás Touceda <chiiph@leap.se>2013-09-03 17:59:50 -0300
commit5dc4bf2886e13a914f8888bc4e49ac813f3cd56c (patch)
tree8f8fe1e7cf87d70f828f97ea8bc4afdbfe170f26
parent247242b4fe3845fce89f66aaad11e27270024243 (diff)
parent4b3f00962cbce75f5120c0d370e03c3007dfe92d (diff)
Merge remote-tracking branch 'kali/feature/logging-filter' into develop
-rw-r--r--changes/feature_3504_add_log_silencer1
-rw-r--r--src/leap/bitmask/app.py11
-rw-r--r--src/leap/bitmask/util/leap_log_handler.py3
-rw-r--r--src/leap/bitmask/util/log_silencer.py95
4 files changed, 108 insertions, 2 deletions
diff --git a/changes/feature_3504_add_log_silencer b/changes/feature_3504_add_log_silencer
new file mode 100644
index 00000000..7c551162
--- /dev/null
+++ b/changes/feature_3504_add_log_silencer
@@ -0,0 +1 @@
+ o Allow to selectively silence logs from different leap components. Closes: #3504
diff --git a/src/leap/bitmask/app.py b/src/leap/bitmask/app.py
index 6ffa1d25..0dce5e61 100644
--- a/src/leap/bitmask/app.py
+++ b/src/leap/bitmask/app.py
@@ -25,6 +25,7 @@ from functools import partial
from PySide import QtCore, QtGui
from leap.bitmask.util import leap_argparse
+from leap.bitmask.util import log_silencer
from leap.bitmask.util.leap_log_handler import LeapLogHandler
from leap.bitmask.util.streamtologger import StreamToLogger
from leap.common.events import server as event_server
@@ -51,7 +52,7 @@ def install_qtreactor(logger):
logger.debug("Qt4 reactor installed")
-def add_logger_handlers(debug=False, logfile=None):
+def add_logger_handlers(debug=False, logfile=None, standalone=False):
"""
Create the logger and attach the handlers.
@@ -71,6 +72,7 @@ def add_logger_handlers(debug=False, logfile=None):
# Create logger and formatter
logger = logging.getLogger(name='leap')
logger.setLevel(level)
+
log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
formatter = logging.Formatter(log_format)
@@ -78,12 +80,16 @@ def add_logger_handlers(debug=False, logfile=None):
console = logging.StreamHandler()
console.setLevel(level)
console.setFormatter(formatter)
+
+ silencer = log_silencer.SelectiveSilencerFilter(standalone=standalone)
+ console.addFilter(silencer)
logger.addHandler(console)
logger.debug('Console handler plugged!')
# LEAP custom handler
leap_handler = LeapLogHandler()
leap_handler.setLevel(level)
+ leap_handler.addFilter(silencer)
logger.addHandler(leap_handler)
logger.debug('Leap handler plugged!')
@@ -93,6 +99,7 @@ def add_logger_handlers(debug=False, logfile=None):
fileh = logging.FileHandler(logfile)
fileh.setLevel(logging.DEBUG)
fileh.setFormatter(formatter)
+ fileh.addFilter(silencer)
logger.addHandler(fileh)
logger.debug('File handler plugged!')
@@ -155,7 +162,7 @@ def main():
# pylint: avoid unused import
assert(locale_rc)
- logger = add_logger_handlers(debug, logfile)
+ logger = add_logger_handlers(debug, logfile, standalone)
replace_stdout_stderr_with_logging(logger)
if not we_are_the_one_and_only():
diff --git a/src/leap/bitmask/util/leap_log_handler.py b/src/leap/bitmask/util/leap_log_handler.py
index 9adb21a5..98924c12 100644
--- a/src/leap/bitmask/util/leap_log_handler.py
+++ b/src/leap/bitmask/util/leap_log_handler.py
@@ -90,6 +90,9 @@ class HandlerAdapter(object):
def setLevel(self, *args, **kwargs):
return self._handler.setLevel(*args, **kwargs)
+ def addFilter(self, *args, **kwargs):
+ return self._handler.addFilter(*args, **kwargs)
+
def handle(self, *args, **kwargs):
return self._handler.handle(*args, **kwargs)
diff --git a/src/leap/bitmask/util/log_silencer.py b/src/leap/bitmask/util/log_silencer.py
new file mode 100644
index 00000000..09aa2cff
--- /dev/null
+++ b/src/leap/bitmask/util/log_silencer.py
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+# log_silencer.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 <http://www.gnu.org/licenses/>.
+"""
+Filter for leap logs.
+"""
+import logging
+import os
+import re
+
+from leap.common.config import get_path_prefix
+
+
+class SelectiveSilencerFilter(logging.Filter):
+ """
+ Configurable filter for root leap logger.
+
+ If you want to ignore components from the logging, just add them,
+ one by line, to ~/.config/leap/leap.dev.conf
+ """
+ # TODO we can augment this by properly parsing the log-silencer file
+ # and having different sections: ignore, levels, ...
+
+ # TODO use ConfigParser to unify sections [log-ignore] [log-debug] etc
+
+ CONFIG_NAME = "leap.dev.conf"
+
+ # Components to be completely silenced in the main bitmask logs.
+ # You probably should think twice before adding a component to
+ # the tuple below. Only very well tested components should go here, and
+ # only in those cases in which we gain more from silencing them than from
+ # having their logs into the main log file that the user will likely send
+ # to us.
+ SILENCER_RULES = (
+ 'leap.common.events',
+ )
+
+ def __init__(self, standalone=False):
+ """
+ Tries to load silencer rules from the default path,
+ or load from the SILENCER_RULES tuple if not found.
+ """
+ self.standalone = standalone
+ self.rules = None
+ if os.path.isfile(self._rules_path):
+ self.rules = self._load_rules()
+ if not self.rules:
+ self.rules = self.SILENCER_RULES
+
+ @property
+ def _rules_path(self):
+ """
+ The configuration file for custom ignore rules.
+ """
+ return os.path.join(
+ get_path_prefix(standalone=self.standalone),
+ "leap", self.CONFIG_NAME)
+
+ def _load_rules(self):
+ """
+ Loads a list of paths to be ignored from the logging.
+ """
+ lines = open(self._rules_path).readlines()
+ return map(lambda line: re.sub('\s', '', line),
+ lines)
+
+ def filter(self, record):
+ """
+ Implements the filter functionality for this Filter
+
+ :param record: the record to be examined
+ :type record: logging.LogRecord
+ :returns: a bool indicating whether the record should be logged or not.
+ :rtype: bool
+ """
+ if not self.rules:
+ return True
+ logger_path = record.name
+ for path in self.rules:
+ if logger_path.startswith(path):
+ return False
+ return True