Advertisement
datacompboy

Runner&logger process

Jun 12th, 2013
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.08 KB | None | 0 0
  1. #!/usr/bin/python
  2. #
  3. # Runner with stdout/stderr catcher
  4. #
  5. from sys import argv
  6. from subprocess import Popen, PIPE
  7. import os, io
  8. from threading import Thread
  9. import Queue
  10. import logging, logging.handlers
  11. def __main__():
  12.     if (len(argv) > 1) and (argv[-1] == "-sub-"):
  13.         import time, sys
  14.         print "Application runned!"
  15.         time.sleep(2)
  16.  
  17.         rootLogger = logging.getLogger('')
  18.         rootLogger.setLevel(logging.DEBUG)
  19.         socketHandler = logging.handlers.SocketHandler('localhost', logging.handlers.DEFAULT_TCP_LOGGING_PORT)
  20.         rootLogger.addHandler(socketHandler)
  21.         # Now, we can log to the root logger, or any other logger. First the root...
  22.         logging.info('Jackdaws love my big sphinx of quartz.')
  23.  
  24.         print "Slept 2 second"
  25.         time.sleep(1)
  26.         print "Slept 1 additional second",
  27.         time.sleep(2)
  28.         sys.stderr.write("Stderr output after 5 seconds")
  29.  
  30.         logger1 = logging.getLogger('myapp.area1')
  31.         logger1.debug('Quick zephyrs blow, vexing daft Jim.')
  32.         logger1.info('How quickly daft jumping zebras vex.')
  33.  
  34.         print "Eol on stdin"
  35.  
  36.         logger2 = logging.getLogger('myapp.area2')
  37.         logger2.warning('Jail zesty vixen who grabbed pay from quack.')
  38.         logger2.error('The five boxing wizards jump quickly.')
  39.  
  40.         sys.stderr.write("Eol on stderr\n")
  41.         time.sleep(1)
  42.         print "Wow, we have end of work!",
  43.     else:
  44.         import pickle
  45.         import SocketServer
  46.         import struct
  47.         class LogRecordStreamHandler(SocketServer.StreamRequestHandler):
  48.             """Handler for a streaming logging request.
  49.  
  50.            This basically logs the record using whatever logging policy is
  51.            configured locally.
  52.            """
  53.  
  54.             def handle(self):
  55.                 """
  56.                Handle multiple requests - each expected to be a 4-byte length,
  57.                followed by the LogRecord in pickle format. Logs the record
  58.                according to whatever policy is configured locally.
  59.                """
  60.                 while True:
  61.                     chunk = self.connection.recv(4)
  62.                     if len(chunk) < 4:
  63.                         break
  64.                     slen = struct.unpack('>L', chunk)[0]
  65.                     chunk = self.connection.recv(slen)
  66.                     while len(chunk) < slen:
  67.                         chunk = chunk + self.connection.recv(slen - len(chunk))
  68.                     obj = self.unPickle(chunk)
  69.                     record = logging.makeLogRecord(obj)
  70.                     self.handleLogRecord(record)
  71.  
  72.             def unPickle(self, data):
  73.                 return pickle.loads(data)
  74.  
  75.             def handleLogRecord(self, record):
  76.                 # if a name is specified, we use the named logger rather than the one
  77.                 # implied by the record.
  78.                 if self.server.logname is not None:
  79.                     name = self.server.logname
  80.                 else:
  81.                     name = record.name
  82.                 logger = logging.getLogger(name)
  83.                 # N.B. EVERY record gets logged. This is because Logger.handle
  84.                 # is normally called AFTER logger-level filtering. If you want
  85.                 # to do filtering, do it at the client end to save wasting
  86.                 # cycles and network bandwidth!
  87.                 logger.handle(record)
  88.  
  89.         class LogRecordSocketReceiver(SocketServer.ThreadingTCPServer):
  90.             """
  91.            Simple TCP socket-based logging receiver suitable for testing.
  92.            """
  93.  
  94.             allow_reuse_address = 1
  95.  
  96.             def __init__(self, host='localhost',
  97.                          port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
  98.                          handler=LogRecordStreamHandler):
  99.                 SocketServer.ThreadingTCPServer.__init__(self, (host, port), handler)
  100.                 self.abort = 0
  101.                 self.timeout = 1
  102.                 self.logname = None
  103.  
  104.             def serve_until_stopped(self):
  105.                 import select
  106.                 abort = 0
  107.                 while not abort:
  108.                     rd, wr, ex = select.select([self.socket.fileno()],
  109.                                                [], [],
  110.                                                self.timeout)
  111.                     if rd:
  112.                         self.handle_request()
  113.                     abort = self.abort
  114.  
  115.         logging.basicConfig(level=logging.DEBUG, filename='debug.log', filemode='a',
  116.                             format='====== %(asctime)s %(relativeCreated)7d %(levelname)-8s %(module)s %(funcName)s %(lineno)d %(threadName)s %(name)s ======\n%(message)s\n')
  117.         tcpserver = LogRecordSocketReceiver()
  118.         th = Thread(target=tcpserver.serve_until_stopped)
  119.         th.setDaemon(True)
  120.         th.start()
  121.         logout = logging.getLogger('STDOUT')
  122.         logerr = logging.getLogger('STDERR')
  123.  
  124.         os.environ["PYTHONUNBUFFERED"]="1"
  125.         try:
  126.             p = Popen( argv + ["-sub-"],
  127.                        bufsize=0, # line-buffered
  128.                        stdin=PIPE, stdout=PIPE, stderr=PIPE )
  129.         except WindowsError, W:
  130.             if W.winerror==193:
  131.                 p = Popen( argv + ["-sub-"],
  132.                            shell=True, # Try to run via shell
  133.                            bufsize=0, # line-buffered
  134.                            stdin=PIPE, stdout=PIPE, stderr=PIPE )
  135.             else:
  136.                 raise
  137.         inp = Queue.Queue()
  138.         sout = io.open(p.stdout.fileno(), 'rb', closefd=False)
  139.         serr = io.open(p.stderr.fileno(), 'rb', closefd=False)
  140.         def Pump(stream, category):
  141.             queue = Queue.Queue()
  142.             def rdr():
  143.                 while True:
  144.                     buf = stream.read1(8192)
  145.                     if len(buf)>0:
  146.                         queue.put( buf )
  147.                     else:
  148.                         queue.put( None )
  149.                         return
  150.             def clct():
  151.                 active = True
  152.                 while active:
  153.                     r = queue.get()
  154.                     try:
  155.                         while True:
  156.                             r1 = queue.get(timeout=0.005)
  157.                             if r1 is None:
  158.                                 active = False
  159.                                 break
  160.                             else:
  161.                                 r += r1
  162.                     except Queue.Empty:
  163.                         pass
  164.                     inp.put( (category, r) )
  165.             for tgt in [rdr, clct]:
  166.                 th = Thread(target=tgt)
  167.                 th.setDaemon(True)
  168.                 th.start()
  169.         Pump(sout, 'stdout')
  170.         Pump(serr, 'stderr')
  171.  
  172.         while p.poll() is None:
  173.             # App still working
  174.             try:
  175.                 chan,line = inp.get(timeout = 1.0)
  176.                 if chan=='stdout':
  177.                     logout.info("%s",line)
  178.                 elif chan=='stderr':
  179.                     logerr.error("%s",line)
  180.             except Queue.Empty:
  181.                 pass
  182.  
  183. if __name__ == '__main__':
  184.     __main__()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement