From 36d1dc45eb6add18273b03af4c02dc89966859b0 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Thu, 29 Jun 2017 17:55:33 -0300 Subject: topolog: implement a logging abstraction The default logger (root) is already being used by Mininet, so to allow customizing logging output and configuring log files Topolog was created. Topolog is no more than a thin layer abstraction to call logging functions without using the 'root' logger. --- tests/topotests/lib/topolog.py | 70 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 tests/topotests/lib/topolog.py (limited to 'tests/topotests/lib/topolog.py') diff --git a/tests/topotests/lib/topolog.py b/tests/topotests/lib/topolog.py new file mode 100644 index 0000000000..0a192ce285 --- /dev/null +++ b/tests/topotests/lib/topolog.py @@ -0,0 +1,70 @@ +# +# topolog.py +# Library of helper functions for NetDEF Topology Tests +# +# Copyright (c) 2017 by +# Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Logging utilities for topology tests. + +This file defines our logging abstraction. +""" + +import logging + +# Helper dictionary to convert Topogen logging levels to Python's logging. +DEBUG_TOPO2LOGGING = { + 'debug': logging.DEBUG, + 'info': logging.INFO, + 'output': logging.INFO, + 'warning': logging.WARNING, + 'error': logging.ERROR, + 'critical': logging.CRITICAL, +} + +# +# Logger class definition +# + +class Logger(object): + """ + Logger class that encapsulates logging functions, internaly it uses Python + logging module with a separated instance instead of global. + + Default logging level is 'info'. + """ + + def __init__(self): + self.logger = logging.Logger('topolog', level=logging.INFO) + self.handler = logging.StreamHandler() + self.handler.setFormatter( + logging.Formatter(fmt='%(asctime)s %(levelname)s: %(message)s') + ) + self.logger.addHandler(self.handler) + + def set_log_level(self, level): + "Set the logging level" + self.logger.setLevel(DEBUG_TOPO2LOGGING.get(level)) + +# +# Global variables +# + +logger_config = Logger() +logger = logger_config.logger -- cgit v1.2.3 From 77ebccacf4fa0bd3b6503f31fc3785cac9f4efdb Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Fri, 7 Jul 2017 09:29:41 -0300 Subject: topolog: support adding loggers during runtime Allow topotest subsystems to create their own loggers. This will help increase log organization and allow different settings to fit the subsystems needs. --- tests/topotests/lib/topolog.py | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'tests/topotests/lib/topolog.py') diff --git a/tests/topotests/lib/topolog.py b/tests/topotests/lib/topolog.py index 0a192ce285..3a383c8e73 100644 --- a/tests/topotests/lib/topolog.py +++ b/tests/topotests/lib/topolog.py @@ -26,6 +26,7 @@ Logging utilities for topology tests. This file defines our logging abstraction. """ +import sys import logging # Helper dictionary to convert Topogen logging levels to Python's logging. @@ -51,16 +52,45 @@ class Logger(object): """ def __init__(self): - self.logger = logging.Logger('topolog', level=logging.INFO) - self.handler = logging.StreamHandler() - self.handler.setFormatter( + # Create default global logger + self.log_level = logging.INFO + self.logger = logging.Logger('topolog', level=self.log_level) + handler = logging.StreamHandler() + handler.setFormatter( logging.Formatter(fmt='%(asctime)s %(levelname)s: %(message)s') ) - self.logger.addHandler(self.handler) + self.logger.addHandler(handler) + + # Handle more loggers + self.loggers = {'topolog': self.logger} def set_log_level(self, level): "Set the logging level" - self.logger.setLevel(DEBUG_TOPO2LOGGING.get(level)) + self.log_level = DEBUG_TOPO2LOGGING.get(level) + self.logger.setLevel(self.log_level) + + def get_logger(self, name='topolog', log_level=None, target=sys.stdout): + """ + Get a new logger entry. Allows creating different loggers for formating, + filtering or handling (file, stream or stdout/stderr). + """ + if log_level is None: + log_level = self.log_level + if self.loggers.has_key(name): + return self.loggers[name] + + nlogger = logging.Logger(name, level=log_level) + if isinstance(target, str): + handler = logging.FileHandler(filename=target) + else: + handler = logging.StreamHandler(stream=target) + + handler.setFormatter( + logging.Formatter(fmt='%(asctime)s %(levelname)s: %(message)s') + ) + nlogger.addHandler(handler) + self.loggers[name] = nlogger + return nlogger # # Global variables -- cgit v1.2.3 From 9427b78f65ef04519e568a45374f59b67937e9d8 Mon Sep 17 00:00:00 2001 From: Martin Winter Date: Thu, 27 Jul 2017 04:09:45 -0700 Subject: lib: Change topology to output INFO and DEBUG to stdout and other levels to stderr Previously, all logs were sent to stderr --- tests/topotests/lib/topolog.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'tests/topotests/lib/topolog.py') diff --git a/tests/topotests/lib/topolog.py b/tests/topotests/lib/topolog.py index 3a383c8e73..f149f34eb3 100644 --- a/tests/topotests/lib/topolog.py +++ b/tests/topotests/lib/topolog.py @@ -39,6 +39,10 @@ DEBUG_TOPO2LOGGING = { 'critical': logging.CRITICAL, } +class InfoFilter(logging.Filter): + def filter(self, rec): + return rec.levelno in (logging.DEBUG, logging.INFO) + # # Logger class definition # @@ -55,11 +59,21 @@ class Logger(object): # Create default global logger self.log_level = logging.INFO self.logger = logging.Logger('topolog', level=self.log_level) - handler = logging.StreamHandler() - handler.setFormatter( + + handler_stdout = logging.StreamHandler(sys.stdout) + handler_stdout.setLevel(logging.DEBUG) + handler_stdout.addFilter(InfoFilter()) + handler_stdout.setFormatter( logging.Formatter(fmt='%(asctime)s %(levelname)s: %(message)s') ) - self.logger.addHandler(handler) + handler_stderr = logging.StreamHandler() + handler_stderr.setLevel(logging.WARNING) + handler_stderr.setFormatter( + logging.Formatter(fmt='%(asctime)s %(levelname)s: %(message)s') + ) + + self.logger.addHandler(handler_stdout) + self.logger.addHandler(handler_stderr) # Handle more loggers self.loggers = {'topolog': self.logger} -- cgit v1.2.3