2016-08-24 13:21:41 +00:00
#!/usr/bin/env python2
# -*-coding:UTF-8 -*
import time
import datetime
import redis
import os
2016-08-24 14:52:01 +00:00
import signal
2016-08-25 08:43:04 +00:00
import argparse
2016-08-24 14:52:01 +00:00
from subprocess import PIPE , Popen
2016-08-24 13:21:41 +00:00
import ConfigParser
2016-08-24 13:53:00 +00:00
import json
2016-08-25 08:43:04 +00:00
from terminaltables import AsciiTable
import textwrap
2016-08-24 13:21:41 +00:00
2016-08-24 13:53:00 +00:00
# CONFIG VARIABLES
2016-08-24 15:28:39 +00:00
threshold_stucked_module = 60 * 60 * 1 #1 hour
2016-08-24 13:53:00 +00:00
log_filename = " ../logs/moduleInfo.log "
2016-08-24 14:52:01 +00:00
command_search_pid = " ps a -o pid,cmd | grep {} "
command_restart_module = " screen -S \" Script \" -X screen -t \" {} \" bash -c \" ./ {} .py; read x \" "
2016-08-24 15:28:39 +00:00
def getPid ( module ) :
2016-08-24 14:52:01 +00:00
p = Popen ( [ command_search_pid . format ( module + " .py " ) ] , stdin = PIPE , stdout = PIPE , bufsize = 1 , shell = True )
for line in p . stdout :
splittedLine = line . split ( )
if ' python2 ' in splittedLine :
2016-08-24 15:28:39 +00:00
return int ( splittedLine [ 0 ] )
else :
return None
2016-08-25 14:07:47 +00:00
def clearRedisModuleInfo ( ) :
for k in server . keys ( " MODULE_* " ) :
server . delete ( k )
2016-08-24 15:28:39 +00:00
def kill_module ( module ) :
print ' '
print ' -> trying to kill module: ' , module
pid = getPid ( module )
if pid is not None :
os . kill ( pid , signal . SIGUSR1 )
time . sleep ( 1 )
if getPid ( module ) is None :
print module , ' has been killed '
print ' restarting ' , module , ' ... '
2016-08-24 14:52:01 +00:00
p2 = Popen ( [ command_restart_module . format ( module , module ) ] , stdin = PIPE , stdout = PIPE , bufsize = 1 , shell = True )
2016-08-24 13:53:00 +00:00
2016-08-24 15:28:39 +00:00
else :
print ' killing failed, retrying... '
time . sleep ( 3 )
os . kill ( pid , signal . SIGUSR1 )
time . sleep ( 1 )
if getPid ( module ) is None :
print module , ' has been killed '
print ' restarting ' , module , ' ... '
p2 = Popen ( [ command_restart_module . format ( module , module ) ] , stdin = PIPE , stdout = PIPE , bufsize = 1 , shell = True )
else :
print ' killing failed! '
time . sleep ( 7 )
2016-08-24 13:53:00 +00:00
2016-08-24 13:21:41 +00:00
if __name__ == " __main__ " :
2016-08-25 08:43:04 +00:00
parser = argparse . ArgumentParser ( description = ' Show info concerning running modules and log suspected stucked modules. May be use to automatically kill and restart stucked one. ' )
parser . add_argument ( ' -r ' , ' --refresh ' , type = int , required = False , default = 1 , help = ' Refresh rate ' )
parser . add_argument ( ' -k ' , ' --autokill ' , type = int , required = True , default = 1 , help = ' Enable auto kill option (1 for TRUE, anything else for FALSE) ' )
2016-08-25 14:07:47 +00:00
parser . add_argument ( ' -c ' , ' --clear ' , type = int , required = False , default = 1 , help = ' Clear the current module information (Used to clear data from old launched modules) ' )
2016-08-25 08:43:04 +00:00
args = parser . parse_args ( )
2016-08-24 13:21:41 +00:00
configfile = os . path . join ( os . environ [ ' AIL_BIN ' ] , ' packages/config.cfg ' )
if not os . path . exists ( configfile ) :
raise Exception ( ' Unable to find the configuration file. \
Did you set environment variables ? \
Or activate the virtualenv . ' )
2016-08-25 08:43:04 +00:00
2016-08-24 13:21:41 +00:00
cfg = ConfigParser . ConfigParser ( )
cfg . read ( configfile )
# REDIS #
server = redis . StrictRedis (
host = cfg . get ( " Redis_Queues " , " host " ) ,
port = cfg . getint ( " Redis_Queues " , " port " ) ,
db = cfg . getint ( " Redis_Queues " , " db " ) )
2016-08-25 14:07:47 +00:00
if args . clear == 1 :
clearRedisModuleInfo ( )
2016-08-24 13:21:41 +00:00
while True :
2016-08-25 14:07:47 +00:00
curr_range = 50
2016-08-25 08:43:04 +00:00
printarray1 = [ ]
printarray2 = [ ]
2016-08-24 13:21:41 +00:00
for queue , card in server . hgetall ( " queues " ) . iteritems ( ) :
2016-08-25 14:07:47 +00:00
key = " MODULE_ " + queue + " _ "
for i in range ( 1 , 50 ) :
curr_num = server . get ( " MODULE_ " + queue + " _ " + str ( i ) )
if curr_num is None :
curr_range = i
break
for moduleNum in range ( 1 , curr_range ) :
value = server . get ( key + str ( moduleNum ) )
if value is not None :
timestamp , path = value . split ( " , " )
if timestamp is not None and path is not None :
startTime_readable = datetime . datetime . fromtimestamp ( int ( timestamp ) )
processed_time_readable = str ( ( datetime . datetime . now ( ) - startTime_readable ) ) . split ( ' . ' ) [ 0 ]
if int ( card ) > 0 :
if int ( ( datetime . datetime . now ( ) - startTime_readable ) . total_seconds ( ) ) > threshold_stucked_module :
log = open ( log_filename , ' a ' )
log . write ( json . dumps ( [ queue , card , str ( startTime_readable ) , str ( processed_time_readable ) , path ] ) + " \n " )
if args . autokill == 1 :
kill_module ( queue )
printarray1 . append ( [ str ( queue ) , str ( moduleNum ) , str ( card ) , str ( startTime_readable ) , str ( processed_time_readable ) , str ( path ) ] )
else :
printarray2 . append ( [ str ( queue ) , str ( moduleNum ) , str ( card ) , str ( startTime_readable ) , str ( processed_time_readable ) , str ( path ) ] )
2016-08-25 08:43:04 +00:00
printarray1 . sort ( lambda x , y : cmp ( x [ 4 ] , y [ 4 ] ) , reverse = True )
printarray2 . sort ( lambda x , y : cmp ( x [ 4 ] , y [ 4 ] ) , reverse = True )
2016-08-25 14:07:47 +00:00
printarray1 . insert ( 0 , [ " Queue " , " # " , " Amount " , " Paste start time " , " Processing time for current paste (H:M:S) " , " Paste hash " ] )
printarray2 . insert ( 0 , [ " Queue " , " # " , " Amount " , " Paste start time " , " Time since idle (H:M:S) " , " Last paste hash " ] )
2016-08-25 08:43:04 +00:00
os . system ( ' clear ' )
t1 = AsciiTable ( printarray1 , title = " Working queues " )
t1 . column_max_width ( 1 )
if not t1 . ok :
longest_col = t1 . column_widths . index ( max ( t1 . column_widths ) )
max_length_col = t1 . column_max_width ( longest_col )
if max_length_col > 0 :
for i , content in enumerate ( t1 . table_data ) :
if len ( content [ longest_col ] ) > max_length_col :
temp = ' '
for l in content [ longest_col ] . splitlines ( ) :
if len ( l ) > max_length_col :
temp + = ' \n ' . join ( textwrap . wrap ( l , max_length_col ) ) + ' \n '
else :
temp + = l + ' \n '
content [ longest_col ] = temp . strip ( )
t1 . table_data [ i ] = content
2016-08-25 09:09:31 +00:00
t2 = AsciiTable ( printarray2 , title = " Idling queues " )
2016-08-25 08:43:04 +00:00
t2 . column_max_width ( 1 )
if not t2 . ok :
longest_col = t2 . column_widths . index ( max ( t2 . column_widths ) )
max_length_col = t2 . column_max_width ( longest_col )
if max_length_col > 0 :
for i , content in enumerate ( t2 . table_data ) :
if len ( content [ longest_col ] ) > max_length_col :
temp = ' '
for l in content [ longest_col ] . splitlines ( ) :
if len ( l ) > max_length_col :
temp + = ' \n ' . join ( textwrap . wrap ( l , max_length_col ) ) + ' \n '
else :
temp + = l + ' \n '
content [ longest_col ] = temp . strip ( )
t2 . table_data [ i ] = content
print t1 . table
2016-08-24 13:53:00 +00:00
print ' \n '
2016-08-25 08:43:04 +00:00
print t2 . table
time . sleep ( args . refresh )