Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- #
- # Runner with stdout/stderr catcher
- #
- from sys import argv
- from subprocess import Popen, PIPE
- import os, io
- from threading import Thread
- import Queue
- import logging, logging.handlers
- def __main__():
- if (len(argv) > 1) and (argv[-1] == "-sub-"):
- import time, sys
- print "Application runned!"
- time.sleep(2)
- rootLogger = logging.getLogger('')
- rootLogger.setLevel(logging.DEBUG)
- socketHandler = logging.handlers.SocketHandler('localhost', logging.handlers.DEFAULT_TCP_LOGGING_PORT)
- rootLogger.addHandler(socketHandler)
- # Now, we can log to the root logger, or any other logger. First the root...
- logging.info('Jackdaws love my big sphinx of quartz.')
- print "Slept 2 second"
- time.sleep(1)
- print "Slept 1 additional second",
- time.sleep(2)
- sys.stderr.write("Stderr output after 5 seconds")
- logger1 = logging.getLogger('myapp.area1')
- logger1.debug('Quick zephyrs blow, vexing daft Jim.')
- logger1.info('How quickly daft jumping zebras vex.')
- print "Eol on stdin"
- logger2 = logging.getLogger('myapp.area2')
- logger2.warning('Jail zesty vixen who grabbed pay from quack.')
- logger2.error('The five boxing wizards jump quickly.')
- sys.stderr.write("Eol on stderr\n")
- time.sleep(1)
- print "Wow, we have end of work!",
- else:
- import pickle
- import SocketServer
- import struct
- class LogRecordStreamHandler(SocketServer.StreamRequestHandler):
- """Handler for a streaming logging request.
- This basically logs the record using whatever logging policy is
- configured locally.
- """
- def handle(self):
- """
- Handle multiple requests - each expected to be a 4-byte length,
- followed by the LogRecord in pickle format. Logs the record
- according to whatever policy is configured locally.
- """
- while True:
- chunk = self.connection.recv(4)
- if len(chunk) < 4:
- break
- slen = struct.unpack('>L', chunk)[0]
- chunk = self.connection.recv(slen)
- while len(chunk) < slen:
- chunk = chunk + self.connection.recv(slen - len(chunk))
- obj = self.unPickle(chunk)
- record = logging.makeLogRecord(obj)
- self.handleLogRecord(record)
- def unPickle(self, data):
- return pickle.loads(data)
- def handleLogRecord(self, record):
- # if a name is specified, we use the named logger rather than the one
- # implied by the record.
- if self.server.logname is not None:
- name = self.server.logname
- else:
- name = record.name
- logger = logging.getLogger(name)
- # N.B. EVERY record gets logged. This is because Logger.handle
- # is normally called AFTER logger-level filtering. If you want
- # to do filtering, do it at the client end to save wasting
- # cycles and network bandwidth!
- logger.handle(record)
- class LogRecordSocketReceiver(SocketServer.ThreadingTCPServer):
- """
- Simple TCP socket-based logging receiver suitable for testing.
- """
- allow_reuse_address = 1
- def __init__(self, host='localhost',
- port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
- handler=LogRecordStreamHandler):
- SocketServer.ThreadingTCPServer.__init__(self, (host, port), handler)
- self.abort = 0
- self.timeout = 1
- self.logname = None
- def serve_until_stopped(self):
- import select
- abort = 0
- while not abort:
- rd, wr, ex = select.select([self.socket.fileno()],
- [], [],
- self.timeout)
- if rd:
- self.handle_request()
- abort = self.abort
- logging.basicConfig(level=logging.DEBUG, filename='debug.log', filemode='a',
- format='====== %(asctime)s %(relativeCreated)7d %(levelname)-8s %(module)s %(funcName)s %(lineno)d %(threadName)s %(name)s ======\n%(message)s\n')
- tcpserver = LogRecordSocketReceiver()
- th = Thread(target=tcpserver.serve_until_stopped)
- th.setDaemon(True)
- th.start()
- logout = logging.getLogger('STDOUT')
- logerr = logging.getLogger('STDERR')
- os.environ["PYTHONUNBUFFERED"]="1"
- try:
- p = Popen( argv + ["-sub-"],
- bufsize=0, # line-buffered
- stdin=PIPE, stdout=PIPE, stderr=PIPE )
- except WindowsError, W:
- if W.winerror==193:
- p = Popen( argv + ["-sub-"],
- shell=True, # Try to run via shell
- bufsize=0, # line-buffered
- stdin=PIPE, stdout=PIPE, stderr=PIPE )
- else:
- raise
- inp = Queue.Queue()
- sout = io.open(p.stdout.fileno(), 'rb', closefd=False)
- serr = io.open(p.stderr.fileno(), 'rb', closefd=False)
- def Pump(stream, category):
- queue = Queue.Queue()
- def rdr():
- while True:
- buf = stream.read1(8192)
- if len(buf)>0:
- queue.put( buf )
- else:
- queue.put( None )
- return
- def clct():
- active = True
- while active:
- r = queue.get()
- try:
- while True:
- r1 = queue.get(timeout=0.005)
- if r1 is None:
- active = False
- break
- else:
- r += r1
- except Queue.Empty:
- pass
- inp.put( (category, r) )
- for tgt in [rdr, clct]:
- th = Thread(target=tgt)
- th.setDaemon(True)
- th.start()
- Pump(sout, 'stdout')
- Pump(serr, 'stderr')
- while p.poll() is None:
- # App still working
- try:
- chan,line = inp.get(timeout = 1.0)
- if chan=='stdout':
- logout.info("%s",line)
- elif chan=='stderr':
- logerr.error("%s",line)
- except Queue.Empty:
- pass
- if __name__ == '__main__':
- __main__()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement