#!/usr/bin/perl # ilf - input line frequency/time event visualization (slf@dreamscape.org) # a steven fountain creation most definitely:) hire me? # i do it all for the praise and the word of mouth # # psuedo-math for 'blinky light over time' w/duct tape for general unixy things # # screenshots of its predecessor's output at http://dreamscape.org/swim/index.php/article/1120892317 # this version is capable of much much more:) # >> instant war room << # screenshots @ http://dreamscape.org/code/ilf-war.png # (using xterm's) http://dreamscape.org/code/ilf-war # (using eterm's) http://dreamscape.org/code/ilf-war-eterm # # Come back later and check out this file again at http://dreamscape.org/code/ilf # as it may be updated and improved! # $usage = "-------------------------------------------------------------------- ilf - input line frequency/time event visualization DSC Ops Research Group - http://dreamscape.org/ (slf@) organicly evolved from: http://dreamscape.org/code/tdpc -------------------------------------------------------------------- you will see two things: symbols that show timechanges (also indicating a line was seen), and secondly symbols that happen so quickly a timechange has not happened. you can customize the colors of each of these w/ -c -t -------------------------------------------------------------------- psuedo-math for 'blinky light over time' w/ducttape it all started because I pondered to myself . o O \"I wonder how frequently I make my neighbors w/love:) wireless light blink..\" ..then it evolved! -------------------------------------------------------------------- screenshots of its predecessor's output can be found at http://dreamscape.org/swim/index.php/article/1120892317 this version is capable of much much more:) screenshots @ http://dreamscape.org/code/ilf-war.png >> instant war room << (using xterm's) http://dreamscape.org/code/ilf-war (using eterm's) http://dreamscape.org/code/ilf-war-eterm -------------------------------------------------------------------- General options: -b 'REGEX' pattern that allways triggers bold -i 'REGEX' pattern that allways triggers reverse -F 'REGEX' pattern that allways triggers blink -r 'REGEX' pattern that triggers reverse ON -R 'REGEX' pattern that triggers reverse OFF -k 'REGEX' pattern that triggers blinking ON -K 'REGEX' pattern that triggers blinking OFF -f 'STR' color choice for \"he's on fire!\" mode -L INT the limit that triggers \"he's on fire!\" mode (the default is 50 within .1s (1 ms)) -l enable internal logging to ilf.log ($0 | tee -a ilf.log.color is cooler) -m INT number of lines to represent on each line in our visualization (the default is 50) -c 'STR' color choice for really fast lines -t 'STR' color choice for time changes -h display this help -H drop this help text to ilf.txt and less it -z FLOAT sleep this much time instead of default 1s \"builtin\" function: -N [-n[O]] [-d] : track output of lsof (network status) -S [-n[O]] [-d] : track output of lsof (system status) -W [-n[0]] [-d] : track output of who (login activity) -s [-n[O]] [-d] : track output of ps auxfw (process activity) -D 'command line' [-n[o]] [-d] : track \"command\" output Usage: $0 'command line' $0 -- command [args ...] $0 -d command [args ...] (is equivilant to -- but with debug) $0 builtin {-D|-N|-S|-W|-s} [options ...] $0 builtin -D 'tail -1000 /var/log/*.log' -n $0 -w $0 -H "; use Term::ANSIColor; use Time::HiRes qw(time); $|=1; # autoflushing (required) use Getopt::Std; $specificly = shift || die "$usage"; if ($specificly =~ /^-H/) { open HELP, "> ilf.txt"; print HELP "$usage"; close HELP; system "less ilf.txt"; print "The help file exists as ilf.txt if you need to refer to it again.\n"; exit; } sub printandorlog { # no color for the log, sorry ;) just perl ilf -- blah | tee -a ilf.log.color my $msg=shift; print "$msg"; print LOG "$msg" if ($l eq 1); } if ($specificly eq '-d') { printandorlog "# Letting you get away with ghetto option evading. ;)\n"; $specificly = join ' ', @ARGV; printandorlog "# Enabling debugging too. This is the only option you get. ;);)\n"; $d = 1; } elsif ($specificly eq '-w') { print "Retrieving http://dreamscape.org/code/ilf-war to ./ilf-war ..\n"; system "wget -O ilf-war http://dreamscape.org/code/ilf-war"; print "Adding execute bit to ./ilf-war ..\n"; system "chmod +x ilf-war"; print "Running ./ilf-war ..\n"; system "./ilf-war &"; exit; } elsif ($specificly eq '--') { printandorlog "# Letting you get away with ghetto option evading. ;)\n"; $specificly = join ' ', @ARGV; } else { getopts('i:b:K:k:m:c:t:D:F:r:R:L:hlsdSNWnoHwz', \%switches); (print "$usage" and exit) if ($specificly =~ /^-(?:h|help|\-help)(?:$|\s)/); foreach(sort keys %switches) { $usedaswitch=1; ${$_}= "$switches{$_}"; (print "$usage" and exit) if ($h eq 1); #warn "# * Hint: -D usage is supposed to be something like -D 'tail /var/log/messages' and NOT 'tail -f /var/log/messages'\n * Maybe you might want $0 \'$D\' instead if you dont see changes.\n" if ($D && $D =~ /(?:tail|tcpdump|watch)/); printandorlog "# * $_ is \"$switches{$_}\""; if ($switches{$_} eq '1') { printandorlog " (ON)"; } if ($switches{$_} eq '0') { printandorlog " (OFF)"; } printandorlog "\n"; } } if ($l eq 1) { system "mv ilf.log.2ago ilf.log.3ago 2>/dev/null"; system "mv ilf.log.1ago ilf.log.2ago 2>/dev/null"; system "mv ilf.log ilf.log.1ago 2>/dev/null"; die "I tried to move ilf.log out of the way but it's still there? Yo?\n" if (-e "ilf.log"); open LOG, "+>> ilf.log" or die "Cant create ilf.log, given reason is: $!\n"; printandorlog "# Logging enabled to ilf.log\n"; } $SLEEP=$z || "1s"; # the number of seconds to sleep when diffing output $max=$m || 50; # the number of lines to represent on one line $hesonfire=$L || 50; # the number of lines that trigger the special "he's on fire!" mode $reallyfastcolor = $c || "blue"; #(items within the same second are displayed as this color) $hesonfirecolor = $f || "red"; #(items that have triggered the "he's on fire!" mode are displayed as this color) $timechangecolor = $t || "cyan"; #(time changes are represented by this color) $na = " - - NOT APPLICABLE - - (?: never..) "; #(hopefully you arent running ilf 'cat ilf' ? ;) $blinkon = $k || $na; $blinkoff = $K || $na; $reverseon = $r || $na; $reverseoff = $R || $na; $whenbold = $b || $na; $whenreverse = $i || $na; $whenblink = $F || $na; $blinkon =~ /NOT APPLICABLE/ ? 1 : printandorlog " pattern that hilights everything bold: /$whenbold/\n"; $blinkoff =~ /NOT APPLICABLE/ ? 1 : printandorlog " pattern that hilights everything reverse: /$whenreverse/\n"; $whenbold =~ /NOT APPLICABLE/ ? 1 : printandorlog " pattern that flips the blink switch to the ON position: /$blinkon/\n"; $whenreverse =~ /NOT APPLICABLE/ ? 1 : printandorlog "pattern that flips the blink switch to the OFF position: /$blinkoff/\n"; $c eq '' ? 1 : printandorlog "reallyfastcolor: $reallyfastcolor\n"; $t eq '' ? 1 : printandorlog "timechangecolor: $timechangecolor\n"; $char = ">"; # input lines are flowing character (if you see nothing but these, we never successfully encoded a symbol) $otime = " "; # intialize it to something so NEW!=OLD works w/no bs $oldsize = 0; # initializing the byte-counter & byte-incremental math if ($n eq 1 && $o eq 1) { $diffmethod = '[<>]'; } elsif ($n eq 1) { $diffmethod = '>'; } elsif ($o eq 1) { $diffmethod = '<'; } else { $diffmethod = '[<>]'; } # control-C binding $SIG{INT} = sub { close LOG if $l; die " <- ok, exiting.\n"; }; # open TD, "tcpdump -n -i $device -s 2000 -l $specificly 2>/dev/null |" or die "cannot open $specificly because of: $!\n"; sub rndStr{local $"=''; "@_[map{rand$#_} 1 .. shift]"; } $magic = `mcookie 2> /dev/null && date 2> /dev/null` || rndStr 16, 'A'..'Z', 0..9, 'a-z'; $magic =~ s/\n/__/g; $magic =~ s/ /_/g; if ($s eq 1 && $specificly eq 'builtin') { $specificly = "while true; do mv /tmp/diff.now.$magic /tmp/.diff.then.$magic ; ps auxfw | grep -v auxfw | grep -v grep | grep -v builtin | grep -v sleep > /tmp/diff.now.$magic 2> /dev/null ; diff /tmp/.diff.then.$magic /tmp/diff.now.$magic 2>/dev/null | grep \"^$diffmethod\" 2> /dev/null ; sleep ${SLEEP}; done"; } if (defined $D && $specificly eq 'builtin') { open DTEST, "$D 2\>\&1 |" or die "couldnt execute $D: $!\n"; close DTEST; $specificly = "while true; do mv /tmp/.custom.now.$magic /tmp/.custom.then.$magic 2> /dev/null ; $D > /tmp/.custom.now.$magic 2> /dev/null ; diff /tmp/.custom.then.$magic /tmp/.custom.now.$magic | grep \"^$diffmethod\" 2> /dev/null ; sleep ${SLEEP}; done"; } if (defined $N && $specificly eq 'builtin') { open LSOF, "lsof -n 2\>\&1 |" or die "couldnt execute lsof: $!\n"; close LSOF; $specificly = "while true; do mv /tmp/.custom.now.$magic /tmp/.custom.then.$magic 2> /dev/null ; lsof -i -n > /tmp/.custom.now.$magic 2> /dev/null ; diff /tmp/.custom.then.$magic /tmp/.custom.now.$magic | grep \"^$diffmethod\" 2> /dev/null ; sleep ${SLEEP}; done"; } if (defined $S && $specificly eq 'builtin') { open LSOF, "lsof -n 2\>\&1 |" or die "couldnt execute lsof: $!\n"; close LSOF; $specificly = "while true; do mv /tmp/.custom.now.$magic /tmp/.custom.then.$magic 2> /dev/null ; lsof -n | grep -v $$ | grep -v grep | grep -v lsof > /tmp/.custom.now.$magic 2> /dev/null ; diff /tmp/.custom.then.$magic /tmp/.custom.now.$magic | grep -E \"^$diffmethod\" 2> /dev/null ; sleep ${SLEEP}; done"; } if (defined $W && $specificly eq 'builtin') { open WHO, "who -a 2\>\&1 |" or die "couldnt execute who: $!\n"; close WHO; $specificly = "while true; do mv /tmp/.custom.now.$magic /tmp/.custom.then.$magic 2> /dev/null ; who > /tmp/.custom.now.$magic 2> /dev/null ; diff /tmp/.custom.then.$magic /tmp/.custom.now.$magic | grep \"^$diffmethod\" 2> /dev/null ; sleep ${SLEEP}; done"; } printandorlog "# Opening: $specificly 2\>\&1\n"; open TD, "$specificly 2\>\&1 |" or die "cannot open $specificly because of: $!\n"; printandorlog "# high-res legend: !=0.0-0.1 sec, @=0.1-0.2, #=0.2-0.3 ... )=0.9-1 seconds\n"; printandorlog "# bulk-res legend: 0=.'s 1..9=1..9 10..35=a..z >35=C >40=D >50=E >60=F\n"; printandorlog "# " . showtime() . "ilf - input line frequency/time event visualization (slf\@dreamscape.org)\n"; printandorlog "#(freq/time)"; #printandorlog "# input lines: "; while(