diff --git a/reporting/diskfree-tracker b/reporting/diskfree-tracker new file mode 100755 index 0000000..bdf2a96 --- /dev/null +++ b/reporting/diskfree-tracker @@ -0,0 +1,259 @@ +#!/usr/bin/env python + +import sys,os,glob +from datetime import datetime +from datetime import timedelta +import re,signal,time +import subprocess +#,threading + +VERSION=2 + +W= '30' +R= '31' +G= '32' +Y= '33' +B= '34' +M= '35' +C= '36' +S= '1' +E= '0' +BR= '41' +CLR = '\033[2J' +SAVE = '\033[s' +LOAD = '\033[u' +CLRLN = '\033[K' +CLRBLN = '\033[1K' +DOWN = '\033[1B' + +SORTKEY = lambda key: (key[2].split('/')[-1].lower()) + +def setup_options(): + ''' Setup the command line options ''' + from argparse import ArgumentParser + import argparse + + parser=ArgumentParser(description=''' +Tool to clean up and colorize the output of Anduril. +Example: anduril run yourscript.and | %(prog)s +You can tap in to an existing log with: + tail -f -n +0 log/_global | %(prog)s''',formatter_class=argparse.RawTextHelpFormatter) + + parser.add_argument("--no-colors",'--nc',action="store_false",dest="colors",default=True, + help="Disable colored output") + parser.add_argument("-n",type=int,dest="delay",default=3, + help="Refresh delay") + + parser.add_argument("--version",action='version', version=VERSION) + options=parser.parse_args() + + return options + +def c(attribs): + ''' ANSI colorizer ''' + if not options.colors: + return "" + return '\033['+';'.join(attribs)+'m' + +def pos(y,x): + ''' ANSI absolute position set ''' + return "\033["+str(y)+";"+str(x)+"H" + + +def colorize(string): + ''' colorizes a string based on color_match ''' + if not options.colors: + return string + for co in color_match: + string=color_match[co][0].sub(color_match[co][1],string) + return string + + +def count_running(string, stats): + ''' Counts the running executions ''' + + spl=[i for i in " ".join(string.split()).split(' ')] + if len(spl)!=7: + return stats + if spl[6] in stats['files']: + index=stats['files'].index(spl[6]) + speed_history=stats['running'][index][1][1:] + speed_history.append((int(spl[4])*1024-(stats['running'][index][0]))/stats['delay']) + stats['running'][index]=(int(spl[4])*1024, # free space + speed_history, # change speed + spl[6], # mount point + stats['running'][index][3], # free space program start + spl[5], # usage in % + spl[1], # mount type + int(spl[2])*1024 # total space + ) + else: + stats['running'].append((int(spl[4])*1024, + [int(0)]*5, + spl[6], + int(spl[4])*1024, + spl[5], + spl[1], + int(spl[2])*1024 + )) + stats['running'].sort(key=SORTKEY) + + stats['files']=[i[2] for i in stats['running']] + totalfree=sum([i[0] for i in stats['running']]) + total=sum([i[6] for i in stats['running']]) + stats['totals']=[totalfree, total] + return stats + +class EndProgram( Exception ): + ''' Nice way of exiting the program ''' + pass + + +def is_number(s): + ''' Check if string is float ''' + try: + out=float(s) + return True + except: + return False + +def str_short(s,stats): + ''' shorten text to fit screen ''' + maxL=stats['size'][1] - 16 + if len(s) 1024: + suffixIndex += 1 + size = size/1024.0 + defPrecision=precision + return "%s%.*f%s"%(sign,defPrecision,size,suffixes[suffixIndex]) + +def readinput(lf): + try: + line = lf.stdout.readline() + #line=lf.readline() + return line + except: + return "CleanerTimeout" + +def termsize(): + rows, columns = os.popen('stty size', 'r').read().split() + return (int(rows),int(columns)) + + +options=setup_options() + +color_match={#'line_ends':(re.compile('$'),c.END), + 'err':(re.compile('(Failed)'),c([R,S])+'\\1'+c([E])), + 'done':(re.compile('(Done)'),c([G,S])+'\\1'+c([E])), + 'percent':(re.compile('([0-9]+%)'),c([Y,S])+'\\1'+c([E])), +} + +stats={'time':datetime.now(), + 'running':[], + 'files':[], + 'totals':[], + 'size': termsize(), + 'delay': options.delay + } + +sys.stdout.write(CLR+pos(0,0)+"Launching...") +while 1: + + try: + + proc = subprocess.Popen(['df','-x','tmpfs','-x','devtmpfs','-T'],stdout=subprocess.PIPE) + # set a 5 second timeout for the line read. + #~ signal.signal(signal.SIGALRM, transfers.readline) + #~ signal.alarm(5) + stdout,stderr=proc.communicate() + if not stdout: + raise EndProgram + + for line in stdout.split('\n')[1:]: + stats=count_running(line,stats) + + print_stats(stats) + sys.stdout.flush() + time.sleep(options.delay) + + except EndProgram,KeyboardInterrupt: + sys.stdout.write(DOWN+'\n') + sys.stdout.flush() + + sys.exit(0) + +