Add new loglevel to display CLI output only

Also print warning if user chooses a loglevel that will hide CLI output.
This commit is contained in:
Brandon Heller
2010-03-04 18:58:37 -08:00
parent e3a2ef011f
commit 1a40cd0477
4 changed files with 49 additions and 26 deletions
+4
View File
@@ -151,6 +151,10 @@ class MininetRunner( object ):
"Setup and validate environment." "Setup and validate environment."
# set logging verbosity # set logging verbosity
if LEVELS[self.options.verbosity] > LEVELS['cliinfo']:
print ( '*** WARNING: selected verbosity level (%s) will hide CLI '
'output!\n'
'Please restart Mininet with -v [debug, info, cliinfo].' )
lg.setLogLevel( self.options.verbosity ) lg.setLogLevel( self.options.verbosity )
# validate environment setup # validate environment setup
+8 -8
View File
@@ -38,7 +38,7 @@ Bugs/limitations:
from subprocess import call from subprocess import call
from cmd import Cmd from cmd import Cmd
from mininet.log import info, warn from mininet.log import info, warn, cliinfo
class CLI( Cmd ): class CLI( Cmd ):
"Simple command-line interface to talk to nodes." "Simple command-line interface to talk to nodes."
@@ -84,16 +84,16 @@ class CLI( Cmd ):
def do_nodes( self, args ): def do_nodes( self, args ):
"List all nodes." "List all nodes."
nodes = ' '.join( [ node.name for node in sorted( self.nodelist ) ] ) nodes = ' '.join( [ node.name for node in sorted( self.nodelist ) ] )
info( 'available nodes are: \n%s\n' % nodes ) cliinfo( 'available nodes are: \n%s\n' % nodes )
def do_net( self, args ): def do_net( self, args ):
"List network connections." "List network connections."
for switch in self.mn.switches: for switch in self.mn.switches:
info( switch.name, '<->' ) cliinfo( switch.name, '<->' )
for intf in switch.intfs.values(): for intf in switch.intfs.values():
name = switch.connection[ intf ][ 1 ] name = switch.connection[ intf ][ 1 ]
info( ' %s' % name ) cliinfo( ' %s' % name )
info( '\n' ) cliinfo( '\n' )
def do_sh( self, args ): def do_sh( self, args ):
"Run an external shell command" "Run an external shell command"
@@ -128,7 +128,7 @@ class CLI( Cmd ):
def do_iperf( self, args ): def do_iperf( self, args ):
"Simple iperf TCP test between two hosts." "Simple iperf TCP test between two hosts."
self.mn.iperf( verbose=True ) self.mn.iperf()
def do_iperfudp( self, args ): def do_iperfudp( self, args ):
"Simple iperf UDP test between two hosts." "Simple iperf UDP test between two hosts."
@@ -138,13 +138,13 @@ class CLI( Cmd ):
def do_intfs( self, args ): def do_intfs( self, args ):
"List interfaces." "List interfaces."
for node in self.nodelist: for node in self.nodelist:
info( '%s: %s\n' % cliinfo( '%s: %s\n' %
( node.name, ' '.join( sorted( node.intfs.values() ) ) ) ) ( node.name, ' '.join( sorted( node.intfs.values() ) ) ) )
def do_dump( self, args ): def do_dump( self, args ):
"Dump node info." "Dump node info."
for node in self.nodelist: for node in self.nodelist:
info( '%s\n' % node ) cliinfo( '%s\n' % node )
def do_exit( self, args ): def do_exit( self, args ):
"Exit" "Exit"
+24 -2
View File
@@ -4,8 +4,15 @@ import logging
from logging import Logger from logging import Logger
import types import types
# Create a new loglevel, 'CLI info', which enables a Mininet user to see only
# the output of the commands they execute, plus any errors or warnings. This
# level is in between info and warning. CLI info-level commands should not be
# printed during regression tests.
CLIINFO = 25
LEVELS = { 'debug': logging.DEBUG, LEVELS = { 'debug': logging.DEBUG,
'info': logging.INFO, 'info': logging.INFO,
'cliinfo': CLIINFO,
'warning': logging.WARNING, 'warning': logging.WARNING,
'error': logging.ERROR, 'error': logging.ERROR,
'critical': logging.CRITICAL } 'critical': logging.CRITICAL }
@@ -119,6 +126,20 @@ class MininetLogger( Logger, object ):
self.setLevel( level ) self.setLevel( level )
self.handlers[ 0 ].setLevel( level ) self.handlers[ 0 ].setLevel( level )
# See /usr/lib/python2.5/logging/__init__.py; modified from warning()
def cliinfo( self, msg, *args, **kwargs ):
"""Log 'msg % args' with severity 'CLIINFO'.
To pass exception information, use the keyword argument exc_info
with a true value, e.g.
logger.warning("Houston, we have a %s", "cli output", exc_info=1)
"""
if self.manager.disable >= CLIINFO:
return
if self.isEnabledFor( CLIINFO ):
apply( self._log, ( CLIINFO, msg, args ), kwargs )
lg = MininetLogger() lg = MininetLogger()
@@ -144,5 +165,6 @@ def makeListCompatible( fn ):
setattr( newfn, '__doc__', fn.__doc__ ) setattr( newfn, '__doc__', fn.__doc__ )
return newfn return newfn
info, warn, error, debug = lg.info, lg.warn, lg.error, lg.debug = [ info, cliinfo, warn, error, debug = lg.info, lg.cliinfo, lg.warn, lg.error, \
makeListCompatible( f ) for f in lg.info, lg.warn, lg.error, lg.debug ] lg.debug = [ makeListCompatible( f ) for f in lg.info, lg.cliinfo, lg.warn,
lg.error, lg.debug ]
+13 -16
View File
@@ -89,7 +89,7 @@ import signal
from time import sleep from time import sleep
from mininet.cli import CLI from mininet.cli import CLI
from mininet.log import info, error, debug from mininet.log import info, error, debug, cliinfo
from mininet.node import Host, UserSwitch, KernelSwitch, Controller from mininet.node import Host, UserSwitch, KernelSwitch, Controller
from mininet.node import ControllerParams from mininet.node import ControllerParams
from mininet.util import quietRun, fixLimits from mininet.util import quietRun, fixLimits
@@ -402,9 +402,9 @@ class Mininet( object ):
ploss = None ploss = None
if not hosts: if not hosts:
hosts = self.hosts hosts = self.hosts
info( '*** Ping: testing ping reachability\n' ) cliinfo( '*** Ping: testing ping reachability\n' )
for node in hosts: for node in hosts:
info( '%s -> ' % node.name ) cliinfo( '%s -> ' % node.name )
for dest in hosts: for dest in hosts:
if node != dest: if node != dest:
result = node.cmd( 'ping -c1 ' + dest.IP() ) result = node.cmd( 'ping -c1 ' + dest.IP() )
@@ -416,10 +416,10 @@ class Mininet( object ):
node.cmdPrint( 'route' ) node.cmdPrint( 'route' )
exit( 1 ) exit( 1 )
lost += sent - received lost += sent - received
info( ( '%s ' % dest.name ) if received else 'X ' ) cliinfo( ( '%s ' % dest.name ) if received else 'X ' )
info( '\n' ) cliinfo( '\n' )
ploss = 100 * lost / packets ploss = 100 * lost / packets
info( "*** Results: %i%% dropped (%d/%d lost)\n" % cliinfo( "*** Results: %i%% dropped (%d/%d lost)\n" %
( ploss, lost, packets ) ) ( ploss, lost, packets ) )
return ploss return ploss
@@ -446,21 +446,18 @@ class Mininet( object ):
else: else:
raise Exception( 'could not parse iperf output: ' + iperfOutput ) raise Exception( 'could not parse iperf output: ' + iperfOutput )
def iperf( self, hosts=None, l4Type='TCP', udpBw='10M', def iperf( self, hosts=None, l4Type='TCP', udpBw='10M' ):
verbose=False ):
"""Run iperf between two hosts. """Run iperf between two hosts.
hosts: list of hosts; if None, uses opposite hosts hosts: list of hosts; if None, uses opposite hosts
l4Type: string, one of [ TCP, UDP ] l4Type: string, one of [ TCP, UDP ]
verbose: verbose printing
returns: results two-element array of server and client speeds""" returns: results two-element array of server and client speeds"""
log = info if verbose else debug
if not hosts: if not hosts:
hosts = [ self.hosts[ 0 ], self.hosts[ -1 ] ] hosts = [ self.hosts[ 0 ], self.hosts[ -1 ] ]
else: else:
assert len( hosts ) == 2 assert len( hosts ) == 2
host0, host1 = hosts host0, host1 = hosts
log( '*** Iperf: testing ' + l4Type + ' bandwidth between ' ) cliinfo( '*** Iperf: testing ' + l4Type + ' bandwidth between ' )
log( "%s and %s\n" % ( host0.name, host1.name ) ) cliinfo( "%s and %s\n" % ( host0.name, host1.name ) )
host0.cmd( 'killall -9 iperf' ) host0.cmd( 'killall -9 iperf' )
iperfArgs = 'iperf ' iperfArgs = 'iperf '
bwArgs = '' bwArgs = ''
@@ -470,16 +467,16 @@ class Mininet( object ):
elif l4Type != 'TCP': elif l4Type != 'TCP':
raise Exception( 'Unexpected l4 type: %s' % l4Type ) raise Exception( 'Unexpected l4 type: %s' % l4Type )
server = host0.cmd( iperfArgs + '-s &' ) server = host0.cmd( iperfArgs + '-s &' )
log( '%s\n' % server ) debug( '%s\n' % server )
client = host1.cmd( iperfArgs + '-t 5 -c ' + host0.IP() + ' ' + client = host1.cmd( iperfArgs + '-t 5 -c ' + host0.IP() + ' ' +
bwArgs ) bwArgs )
log( '%s\n' % client ) debug( '%s\n' % client )
server = host0.cmd( 'killall -9 iperf' ) server = host0.cmd( 'killall -9 iperf' )
log( '%s\n' % server ) debug( '%s\n' % server )
result = [ self._parseIperf( server ), self._parseIperf( client ) ] result = [ self._parseIperf( server ), self._parseIperf( client ) ]
if l4Type == 'UDP': if l4Type == 'UDP':
result.insert( 0, udpBw ) result.insert( 0, udpBw )
log( '*** Results: %s\n' % result ) cliinfo( '*** Results: %s\n' % result )
return result return result
def iperfUdp( self, udpBw='10M' ): def iperfUdp( self, udpBw='10M' ):