Monitor set of files and return [(host, line)...]
( outfiles, seconds, timeoutms )
| 17 | |
| 18 | |
| 19 | def monitorFiles( outfiles, seconds, timeoutms ): |
| 20 | "Monitor set of files and return [(host, line)...]" |
| 21 | devnull = open( '/dev/null', 'w' ) # pylint: disable=consider-using-with |
| 22 | tails, fdToFile, fdToHost = {}, {}, {} |
| 23 | for h, outfile in outfiles.items(): |
| 24 | tail = Popen( # pylint: disable=consider-using-with |
| 25 | [ 'tail', '-f', outfile ], |
| 26 | stdout=PIPE, stderr=devnull ) |
| 27 | fd = tail.stdout.fileno() |
| 28 | tails[ h ] = tail |
| 29 | fdToFile[ fd ] = tail.stdout |
| 30 | fdToHost[ fd ] = h |
| 31 | # Prepare to poll output files |
| 32 | readable = poll() |
| 33 | for t in tails.values(): |
| 34 | readable.register( t.stdout.fileno(), POLLIN ) |
| 35 | # Run until a set number of seconds have elapsed |
| 36 | endTime = time() + seconds |
| 37 | while time() < endTime: |
| 38 | fdlist = readable.poll(timeoutms) |
| 39 | if fdlist: |
| 40 | for fd, _flags in fdlist: |
| 41 | f = fdToFile[ fd ] |
| 42 | host = fdToHost[ fd ] |
| 43 | # Wait for a line of output |
| 44 | line = f.readline().strip() |
| 45 | yield host, decode( line ) |
| 46 | else: |
| 47 | # If we timed out, return nothing |
| 48 | yield None, '' |
| 49 | for t in tails.values(): |
| 50 | t.terminate() |
| 51 | devnull.close() # Not really necessary |
| 52 | |
| 53 | |
| 54 | def monitorTest( N=3, seconds=3 ): |