#!/usr/bin/perl

use Term::ANSIColor qw(:constants);

my %last;

my @list = qw(r b w swpd free buff cache si so bi bo in cs us sy id);
my @order = qw(si so bi bo swpd free buff cache in cs);
my $swaps;
open(IF, "vmstat -n 1| ");
# Skip the 2 header lines
<IF>;
<IF>;
while (1){
    my @it = split(/\s+/, <IF>);
    shift @it;
#    print "It is ", join(',', @it), "\n";
    my $printed = 0;
    my %msgs;
    for (my $i = 0; $i < @list; $i++){
	next if ($i < 3);
	next if ($i > 12);
	my $key = $list[$i];
	my $old = $last{$key};
	my $new = $it[$i];
	my $delta = $new - $old;
	$msg{$key} = "";
	if ($new ne $old){
	    my $watch = 0;
	    if ($key =~ /si/){
		$msg{$key} .= sprintf(GREEN);
		$watch = 2;
		$swaps += $new;
	    } elsif ($key =~ /so/){
		$msg{$key} .= sprintf(YELLOW);
		$watch = 1;
	    } elsif ($key =~ /bi/){
		$msg{$key} .= sprintf(RED);
		$watch = 1;
	    } elsif ($key =~ /bo/){
		$msg{$key} .= sprintf(CYAN);
		$watch = 1;
	    }
	    if (($watch == 1) && ($new > 500)){
		$msg{$key} .= sprintf(REVERSE);
	    }
	    if (($watch == 2) && ($new > 30)){
		$msg{$key} .= sprintf(REVERSE);
	    }
	    $msg{$key} .= " $key: $old->$new($delta)";
	    if ($watch){
		$msg{$key} .= sprintf(RESET);
	    }
	    $last{$key} = $new;
	    $printed = 1;
	}
    }
    if ($printed){
	print((scalar localtime) . " $swaps ->");
	foreach my $key (@order){
	    print " " . $msg{$key} if ($msg{$key});
	}
	print "\n";
    }
}
close(IF);
