| #!/usr/bin/python |
| |
| """ |
| Simple example of sending output to multiple files and |
| monitoring them |
| """ |
| |
| from mininet.topo import SingleSwitchTopo |
| from mininet.net import Mininet |
| from mininet.log import setLogLevel |
| |
| from time import time |
| from select import poll, POLLIN |
| from subprocess import Popen, PIPE |
| |
| def monitorFiles( outfiles, seconds, timeoutms ): |
| "Monitor set of files and return [(host, line)...]" |
| devnull = open( '/dev/null', 'w' ) |
| tails, fdToFile, fdToHost = {}, {}, {} |
| for h, outfile in outfiles.iteritems(): |
| tail = Popen( [ 'tail', '-f', outfile ], |
| stdout=PIPE, stderr=devnull ) |
| fd = tail.stdout.fileno() |
| tails[ h ] = tail |
| fdToFile[ fd ] = tail.stdout |
| fdToHost[ fd ] = h |
| # Prepare to poll output files |
| readable = poll() |
| for t in tails.values(): |
| readable.register( t.stdout.fileno(), POLLIN ) |
| # Run until a set number of seconds have elapsed |
| endTime = time() + seconds |
| while time() < endTime: |
| fdlist = readable.poll(timeoutms) |
| if fdlist: |
| for fd, _flags in fdlist: |
| f = fdToFile[ fd ] |
| host = fdToHost[ fd ] |
| # Wait for a line of output |
| line = f.readline().strip() |
| yield host, line |
| else: |
| # If we timed out, return nothing |
| yield None, '' |
| for t in tails.values(): |
| t.terminate() |
| devnull.close() # Not really necessary |
| |
| |
| def monitorTest( N=3, seconds=3 ): |
| "Run pings and monitor multiple hosts" |
| topo = SingleSwitchTopo( N ) |
| net = Mininet( topo ) |
| net.start() |
| hosts = net.hosts |
| print "Starting test..." |
| server = hosts[ 0 ] |
| outfiles, errfiles = {}, {} |
| for h in hosts: |
| # Create and/or erase output files |
| outfiles[ h ] = '/tmp/%s.out' % h.name |
| errfiles[ h ] = '/tmp/%s.err' % h.name |
| h.cmd( 'echo >', outfiles[ h ] ) |
| h.cmd( 'echo >', errfiles[ h ] ) |
| # Start pings |
| h.cmdPrint('ping', server.IP(), |
| '>', outfiles[ h ], |
| '2>', errfiles[ h ], |
| '&' ) |
| print "Monitoring output for", seconds, "seconds" |
| for h, line in monitorFiles( outfiles, seconds, timeoutms=500 ): |
| if h: |
| print '%s: %s' % ( h.name, line ) |
| for h in hosts: |
| h.cmd('kill %ping') |
| net.stop() |
| |
| |
| if __name__ == '__main__': |
| setLogLevel('info') |
| monitorTest() |