aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSander Vrijders <sander.vrijders@intec.ugent.be>2017-04-24 14:44:35 +0000
committerSander Vrijders <sander.vrijders@intec.ugent.be>2017-04-24 14:44:35 +0000
commita2a031857a0ea60e63a0e36ed9b429ef5ae0cdff (patch)
tree39f89b4f949fca88724e10e2ab00ddc230effa72
parentb59e143880f910e9d504a190407f69ed2ffbc72a (diff)
parent58b1a46bfbf7960336fa25a3a9c3b8916530328f (diff)
downloadrumba-a2a031857a0ea60e63a0e36ed9b429ef5ae0cdff.tar.gz
rumba-a2a031857a0ea60e63a0e36ed9b429ef5ae0cdff.zip
Merge branch 'logging-levels' into 'master'
Logging: added set and reset logging level method, small logging modifications. See merge request !40
-rwxr-xr-xexamples/example.py5
-rwxr-xr-xexamples/two-layers.py6
-rw-r--r--rumba/log.py115
-rw-r--r--rumba/prototypes/irati.py12
-rw-r--r--rumba/ssh_support.py4
-rw-r--r--rumba/testbeds/qemu.py9
-rwxr-xr-xtools/democonf2rumba.py14
7 files changed, 141 insertions, 24 deletions
diff --git a/examples/example.py b/examples/example.py
index 8d91102..56193c2 100755
--- a/examples/example.py
+++ b/examples/example.py
@@ -15,6 +15,11 @@ import rumba.prototypes.ouroboros as our
import rumba.prototypes.rlite as rl
import rumba.prototypes.irati as irati
+import rumba.log as log
+
+
+log.set_logging_level('DEBUG')
+
n1 = NormalDIF("n1", policies = {"rmt.pff": "lfa",
"security-manager": "passwd"})
diff --git a/examples/two-layers.py b/examples/two-layers.py
index fff3866..9d1a6b3 100755
--- a/examples/two-layers.py
+++ b/examples/two-layers.py
@@ -15,6 +15,12 @@ import rumba.prototypes.ouroboros as our
import rumba.prototypes.rlite as rl
import rumba.prototypes.irati as irati
+import rumba.log as log
+
+
+log.set_logging_level('DEBUG')
+
+
n1 = NormalDIF("n1")
n2 = NormalDIF("n2")
n3 = NormalDIF("n3")
diff --git a/rumba/log.py b/rumba/log.py
index e856b42..8c95330 100644
--- a/rumba/log.py
+++ b/rumba/log.py
@@ -1,3 +1,22 @@
+#
+# Logging wrapper for Rumba
+#
+# Marco Capitani <m.capitani@nextworks.it>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
import logging
import sys
@@ -5,21 +24,43 @@ import sys
import multiprocessing
+loggers_set = set()
+
+
+class RumbaFormatter(logging.Formatter):
+ """The logging.Formatter subclass used by Rumba"""
+
+ level_name_table = {
+ 'CRITICAL': 'CRT',
+ 'ERROR': 'ERR',
+ 'WARNING': 'WRN',
+ 'INFO': 'INF',
+ 'DEBUG': 'DBG'
+ }
+
+ def __init__(self):
+ super(RumbaFormatter, self).__init__(
+ fmt='{asctime} | {levelname:3.3} | '
+ '{name:11.11} | {message}',
+ style='{',
+ datefmt='%H:%M:%S')
+
+ def format(self, record):
+ record.name = record.name.split('.')[-1]
+ record.levelname = self.level_name_table[record.levelname]
+ return super(RumbaFormatter, self).format(record)
+
+
def setup():
+ """Configures the logging framework with default values."""
handler = logging.StreamHandler(sys.stdout)
handler.lock = multiprocessing.RLock()
- logging.basicConfig(format='{asctime} | {levelname:3.3} | '
- '{name:11.11} | {message}',
- style='{',
- datefmt='%H:%M:%S',
- handlers=[handler],
- level=logging.DEBUG)
- logging.addLevelName(logging.CRITICAL, 'CRT')
- logging.addLevelName(logging.ERROR, 'ERR')
- logging.addLevelName(logging.WARNING, 'WRN')
- logging.addLevelName(logging.INFO, 'INF')
- logging.addLevelName(logging.DEBUG, 'DBG')
+ handler.setLevel(logging.DEBUG)
+ formatter = RumbaFormatter()
+ handler.setFormatter(formatter)
+ logging.basicConfig(handlers=[handler], level=logging.DEBUG)
logging.getLogger('').setLevel(logging.ERROR)
+ logging.getLogger('rumba').setLevel(logging.DEBUG)
# Used for the first call, in order to configure logging
@@ -40,6 +81,52 @@ _get_logger = _get_logger_with_setup
def get_logger(name):
- logger = _get_logger(name.split('.')[-1])
- logger.setLevel(logging.DEBUG)
- return logger
+ """
+ Returns the logger named <name>.
+ <name> should be the module name, for consistency. If setup has not been
+ called yet, it will call it first.
+ :param name: the name of the desired logger
+ :return: The logger
+ """
+ return _get_logger(name)
+
+
+def set_logging_level(level, name=None):
+ """
+ Set the current logging level to <level> for logger named <name>.
+ If name is not specified, sets the logging level for all rumba loggers.
+ Accepted levels are:
+ DEBUG == 10,
+ INFO == 20,
+ WARNING == 30,
+ ERROR == 40,
+ CRITICAL == 50,
+ NOTSET == 0
+ (resets the logger: its level is set to the default or its parents' level)
+ :param level: the desired logging level.
+ :param name: The name of the logger to configure
+ """
+ if name is None:
+ if level == 'NOTSET' or level == 0:
+ set_logging_level(logging.INFO)
+ return
+ name = 'rumba'
+ if (level == 'NOTSET' or level == 0) and name == '':
+ set_logging_level(logging.ERROR, '')
+ return
+ logger = get_logger(name)
+ loggers_set.add(logger)
+ logger.setLevel(level)
+
+
+def reset_logging_level():
+ """
+ Resets the current logging levels to the defaults.
+ Defaults are: rumba -> INFO,
+ everything else -> ERROR
+ """
+ # Un-sets every logger previously set
+ for logger in loggers_set:
+ logger.setLevel(logging.NOTSET)
+ set_logging_level(logging.INFO)
+ set_logging_level(logging.ERROR, '')
diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index 346b39a..b2f54d9 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -117,6 +117,7 @@ class Experiment(mod.Experiment):
"""
name = node.name
+ logger.info('Setting up vlans for node %s', node.name)
for ipcp in node.ipcps:
if isinstance(ipcp, mod.ShimEthIPCP):
if_name = ipcp.ifname
@@ -147,7 +148,7 @@ class Experiment(mod.Experiment):
'verb': 'DBG',
'ipcmcomps': ipcm_components}
- # TODO: watch out for empty path...
+ logger.info('Copying configuration files to node %s', node.name)
ssh.copy_paths_to_testbed(self.testbed,
node.ssh_config,
gen_files,
@@ -164,16 +165,16 @@ class Experiment(mod.Experiment):
'-c /etc/%(name)s.ipcm.conf -l %(verb)s &> log &'
% format_args)]
- logger.info('Sending node setup via ssh.')
+ logger.info('Sending setup commands to node %s.', node.name)
ssh.execute_commands(self.testbed, node.ssh_config, cmds)
def enroll_nodes(self):
"""Runs the enrollments one by one, respecting dependencies"""
for enrollment_list in self.enrollments:
for e in enrollment_list:
- logger.debug(
- 'I am going to enroll %s to DIF %s against neighbor %s,'
- ' through lower DIF %s',
+ logger.info(
+ 'Enrolling %s to DIF %s against neighbor %s,'
+ ' through lower DIF %s.',
e['enrollee'].name,
e['dif'].name,
e['enroller'].name,
@@ -192,7 +193,6 @@ class Experiment(mod.Experiment):
'--enrollee-name %(iname)s.IPCP '
'--enroller-name %(o_iname)s.IPCP'
% e_args)
- logger.info('Sending enrollment operation via ssh.')
ssh.execute_command(self.testbed,
e['enrollee'].node.ssh_config,
cmd)
diff --git a/rumba/ssh_support.py b/rumba/ssh_support.py
index 84ff607..26d64fb 100644
--- a/rumba/ssh_support.py
+++ b/rumba/ssh_support.py
@@ -174,7 +174,7 @@ def copy_paths_to_testbed(testbed, ssh_config, paths, destination):
for path in paths:
file_name = os.path.basename(path)
dest_file = destination + file_name
- logger.info("Copying %s to %s@%s:%s path %s" % (
+ logger.debug("Copying %s to %s@%s:%s path %s" % (
path,
testbed.username,
ssh_config.hostname,
@@ -215,7 +215,7 @@ def setup_vlan(testbed, node, vlan_id, int_name):
def sudo(s):
return 'sudo ' + s
- logger.info("Setting up VLAN on node " + node.name)
+ logger.debug("Setting up VLAN on node %s, if %s.", node.name, int_name)
args = {'ifname': str(int_name), 'vlan': str(vlan_id)}
diff --git a/rumba/testbeds/qemu.py b/rumba/testbeds/qemu.py
index 6121e6b..a916525 100644
--- a/rumba/testbeds/qemu.py
+++ b/rumba/testbeds/qemu.py
@@ -114,6 +114,7 @@ class Testbed(mod.Testbed):
raise Exception('Not authenticated')
logger.info("swapping in")
+ logger.info('Setting up interfaces.')
# Building bridges and taps
shim_processes = []
@@ -203,6 +204,9 @@ class Testbed(mod.Testbed):
except:
max_waiting_time -= 1
+ logger.info('Interfaces setup complete. '
+ 'Building VMs (this might take a while).')
+
# Building vms
boot_batch_size = max(1, multiprocessing.cpu_count() // 2)
@@ -300,11 +304,14 @@ class Testbed(mod.Testbed):
self.recover_if_names(experiment)
+ logger.info('Experiment has been successfully swapped in.')
+
def swap_out(self, experiment):
"""
:rtype str
:return: The script to tear down the experiment
"""
+ logger.info('Killing qemu processes.')
# TERM qemu processes
for process in self.boot_processes:
process.terminate()
@@ -313,6 +320,7 @@ class Testbed(mod.Testbed):
for process in self.boot_processes:
process.wait()
+ logger.info('Destroying interfaces.')
port_processes = []
error_queue = multiprocessing.Queue()
results_queue = multiprocessing.Queue()
@@ -394,3 +402,4 @@ class Testbed(mod.Testbed):
% (over_processes, total_processes))
except:
max_waiting_time -= 1
+ logger.info('Experiment has been swapped out.')
diff --git a/tools/democonf2rumba.py b/tools/democonf2rumba.py
index 9d909c7..a73d6b7 100755
--- a/tools/democonf2rumba.py
+++ b/tools/democonf2rumba.py
@@ -4,10 +4,11 @@ import argparse
import re
import rumba.model as mod
+import rumba.log as log
def make_experiment(filename, experiment_class, experiment_kwargs,
- testbed_class, testbed_kwargs):
+ testbed_class, testbed_kwargs, verbosity):
"""
:type filename str
:param filename: path to the .conf file
@@ -118,6 +119,8 @@ def make_experiment(filename, experiment_class, experiment_kwargs,
.items()}
parsed_nodes.append(mod.Node(name, difs, dif_registrations))
+ log.set_logging_level(verbosity)
+
testbed = testbed_class(**testbed_kwargs)
experiment_kwargs['testbed'] = testbed
@@ -161,6 +164,12 @@ if __name__ == '__main__':
required=True,
help='Path to the config file to parse')
+ parser.add_argument(
+ '--verbosity', metavar='VERBOSITY', type=str,
+ default='INFO',
+ choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
+ help='Path to the config file to parse')
+
subparsers = parser.add_subparsers(dest='testbed')
emulab_p = subparsers.add_parser('emulab', help='Use emulab testbed')
jfed_p = subparsers.add_parser('jfed', help='Use jfed testbed')
@@ -254,7 +263,8 @@ if __name__ == '__main__':
experiment_class=exp_class,
experiment_kwargs={},
testbed_class=test_class,
- testbed_kwargs=testbed_args)
+ testbed_kwargs=testbed_args,
+ verbosity=args.verbosity)
except KeyboardInterrupt:
print("Interrupted. Closing down.")