1#!/usr/local/bin/python3.8 2# 3# Authors: Sergey Satskiy 4# 5# $Id: ns_perf_probe.py 591938 2019-08-22 17:35:24Z satskyse $ 6# 7 8""" 9Netschedule server throughput sampling script 10""" 11 12import sys 13from optparse import OptionParser 14from time import sleep 15from ncbi_grid_1_1.ncbi.grid import ns 16from datetime import datetime 17 18 19def parserError( parser_, message ): 20 " Prints the message and help on stderr " 21 sys.stdout = sys.stderr 22 print(message) 23 parser_.print_help() 24 return 25 26 27def accumulateCounters( counters, values ): 28 " Values came as a list of strings like 'Name: xxx' " 29 for value in values: 30 name, val = value.split( ':', 1 ) 31 val = int( val ) 32 33 if name in counters: 34 counters[ name ] += val 35 else: 36 counters[ name ] = val 37 return 38 39def formatTimestamp( ts ): 40 " As MS Excel likes it " 41 return ts.strftime( "%m/%d/%Y %H:%M:%S" ) 42 43def main(): 44 " main function for the netschedule multi test " 45 46 parser = OptionParser( 47 """ 48 %prog <host> <port> 49 %prog <host:port> 50 Collects the number submitted jobs and the up time periodically and saves into a CSV file 51 """ ) 52 parser.add_option( "-v", "--verbose", 53 action="store_true", dest="verbose", default=False, 54 help="be verbose (default: False)" ) 55 parser.add_option( "--interval", dest="interval", 56 default=60, 57 help="Interval between probes, seconds. (Default: 60)" ) 58 59 # parse the command line options 60 options, args = parser.parse_args() 61 if len( args ) not in [ 1, 2 ]: 62 parserError( parser, "Incorrect number of arguments" ) 63 return 3 64 65 if len( args ) == 2: 66 host = args[ 0 ] 67 port = args[ 1 ] 68 else: 69 parts = args[0].split( ":" ) 70 if len( parts ) != 2 : 71 parserError( parser, "Expected format host:port" ) 72 return 3 73 host = parts[ 0 ] 74 port = parts[ 1 ] 75 76 try: 77 port = int( port ) 78 except: 79 parserError( parser, "The port must be integer" ) 80 return 3 81 82 interval = options.interval 83 try: 84 interval = int( interval ) 85 except: 86 parserError( parser, "The interval must be an integer > 0" ) 87 return 3 88 if interval <= 0: 89 parserError( parser, "The interval must be an integer > 0" ) 90 return 3 91 92 # Get the server start time once 93 server = ns.NetScheduleServer( host + ":" + str( port ), 94 client_name = "performance_probe" ) 95 server.allow_xsite_connections() 96 currentDate = datetime.now() 97 serverStatus = server.get_server_status() 98 if 'Started' not in serverStatus: 99 raise Exception( "Cannot get the server start timestamp" ) 100 startDate = datetime.strptime( serverStatus[ 'Started' ], 101 "%m/%d/%Y %H:%M:%S" ) 102 103 lastTotalSubmits = None 104 while True: 105 # Open a connection 106 server = ns.NetScheduleServer( host + ":" + str( port ), 107 client_name = "performance_probe" ) 108 server.allow_xsite_connections() 109 110 # Interrogate 111 currentDate = datetime.now() 112 serverStatus = server.get_server_status() 113 114 counters = {} 115 for key in serverStatus: 116 if key.startswith( "queue " ): 117 accumulateCounters( counters, serverStatus[ key ] ) 118 if 'submits' not in counters: 119 raise Exception( "Cannot get the total server submits" ) 120 totalSubmits = counters[ 'submits' ] 121 122 # Print results 123 runtime = currentDate - startDate 124 runtime = str( runtime.total_seconds() ).split( '.' )[ 0 ] 125 126 if lastTotalSubmits is None: 127 print("Timestamp,seconds since server started,total submits") 128 print(formatTimestamp(currentDate) + "," + runtime + "," + str(totalSubmits)) 129 130 if totalSubmits == lastTotalSubmits: 131 break 132 lastTotalSubmits = totalSubmits 133 134 # Sleep 135 sleep( interval ) 136 137 return 0 138 139 140 141# The script execution entry point 142if __name__ == "__main__": 143 try: 144 returnValue = main() 145 except KeyboardInterrupt: 146 # Ctrl+C 147 print("Ctrl + C received", file=sys.stderr) 148 returnValue = 2 149 150 except Exception as excpt: 151 print(str(excpt), file=sys.stderr) 152 returnValue = 1 153 154 sys.exit( returnValue ) 155