Interacting with long-running python script -
i have long running python script collect tweets twitter, , know how doing every 1 time in awhile.
currently, using signal library grab interrupts, @ point phone call print function. this:
import signal def print_info(count): print "#tweets:", count #print out process id can interrupt info print 'pid:', os.getpid() #start listening interrupts signal.signal(signal.sigusr1, functools.partial(print_info, tweet_count)) and whenever want info, open new terminal , issue interrupt:
$kill -usr1 <pid> is there improve way this? aware have script @ scheduled intervals, more interested in knowing on demand, , potentially issuing other commands well.
sending signal process interrupt process. below find approach uses dedicated thread emulate python console. console exposed unix socket.
import traceback import importlib code import interactiveconsole import sys import socket import os import threading logging import getlogger # template used generate file name sock_file_template = '%(dir)s/%(prefix)s-%(pid)d.socket' log = getlogger(__name__) class socketconsole(object): ''' ported form :eventlet.backdoor.socketconsole:. ''' def __init__(self, locals, conn, banner=none): # pylint: diable=w0622 self.locals = locals self.desc = _fileobject(conn) self.banner = banner self.saved = none def switch(self): self.saved = sys.stdin, sys.stderr, sys.stdout sys.stdin = sys.stdout = sys.stderr = self.desc def switch_out(self): sys.stdin, sys.stderr, sys.stdout = self.saved def finalize(self): self.desc = none def _run(self): try: console = interactiveconsole(self.locals) # __builtins__ may either __builtin__ module or # __builtin__.__dict__ in latter case typing # locals() @ backdoor prompt spews out lots of # useless stuff import __builtin__ console.locals["__builtins__"] = __builtin__ console.interact(banner=self.banner) except systemexit: # raised quit() sys.exc_clear() finally: self.switch_out() self.finalize() class _fileobject(socket._fileobject): def write(self, data): self._sock.sendall(data) def isatty(self): homecoming true def flush(self): pass def readline(self, *a): homecoming socket._fileobject.readline(self, *a).replace("\r\n", "\n") def make_threaded_backdoor(prefix=none): ''' :return: started daemon thread running :main_loop: ''' socket_file_name = _get_filename(prefix) db_thread = threading.thread(target=main_loop, args=(socket_file_name,)) db_thread.setdaemon(true) db_thread.start() homecoming db_thread def _get_filename(prefix): homecoming sock_file_template % { 'dir': '/var/run', 'prefix': prefix, 'pid': os.getpid(), } def main_loop(socket_filename): try: log.debug('binding backdoor socket %s', socket_filename) check_socket(socket_filename) sockobj = socket.socket(socket.af_unix, socket.sock_stream) sockobj.bind(socket_filename) sockobj.listen(5) except exception, e: log.exception('failed init backdoor socket %s', e) homecoming while true: conn = none try: conn, _ = sockobj.accept() console = socketconsole(locals=none, conn=conn, banner=none) console.switch() console._run() except ioerror: log.debug('ioerror closing connection') finally: if conn: conn.close() def check_socket(socket_filename): try: os.unlink(socket_filename) except oserror: if os.path.exists(socket_filename): raise example program:
make_threaded_backdoor(prefix='test') while true: pass example session:
mmatczuk@cactus:~$ rlwrap nc -u /var/run/test-3196.socket python 2.7.6 (default, mar 22 2014, 22:59:56) [gcc 4.8.2] on linux2 type "help", "copyright", "credits" or "license" more information. (interactiveconsole) >>> import os >>> os.getpid() 3196 >>> quit() mmatczuk@cactus:~$ this pretty robust tool can used to:
dump threads, inspect process memory, attach debugger on demand, pydev debugger (work both eclipse , pycharm), force gc, monkeypatch function definition on flyand more.
python
No comments:
Post a Comment