summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2010-11-06 13:29:29 +0000
committerPaul Buetow <paul@buetow.org>2010-11-06 13:29:29 +0000
commit6b7e6970428d105a4bbd30b541a7762e78042e44 (patch)
tree0b7832d67df5fecdd8a64e10f485469bee09e973
parentc4636b761599ca6f222898ada0f274d2fa13e62a (diff)
initial work
-rwxr-xr-xcpupload.pl158
1 files changed, 94 insertions, 64 deletions
diff --git a/cpupload.pl b/cpupload.pl
index 58b824d..cbb25f2 100755
--- a/cpupload.pl
+++ b/cpupload.pl
@@ -11,13 +11,15 @@ use SDL::App;
use SDL::Rect;
use SDL::Color;
+use Time::HiRes 'usleep';
+
use threads;
use threads::shared;
use constant {
- WIDTH => 800,
- HEIGHT => 600,
- DEPTH => 16,
+ WIDTH => 100,
+ HEIGHT => 500,
+ DEPTH => 8,
};
$| = 1;
@@ -33,19 +35,6 @@ my %GLOBAL_CONF :shared;
sub say (@) { print "$_\n" for @_; return undef }
sub debugsay (@) { say "DEBUG: $_" for @_; return undef }
-sub reduce (&@) {
- my ($func, @params) = @_;
-
- my $sub;
- $sub = sub {
- my ($elem, @rest) = @_;
- $func->($elem, @rest == 1 ? $rest[0] : $sub->(@rest));
- };
-
- return $sub->($func, @params);
-}
-
-#sub sum (@) { reduce { $_[0] + $_[1] } @_ }
sub sum (@) {
my $sum = 0;
$sum += $_ for @_;
@@ -57,9 +46,12 @@ sub loop (&) { $_[0]->() while 1 }
sub parse_cpu_line ($) {
my %load;
@load{qw(name user nice system iowait irq softirq)} = split ' ', shift;
+ my $name = $load{name};
+ delete $load{name};
+
$load{TOTAL} = sum @load{qw(user nice system iowait)};
- return ($load{name}, \%load);
+ return ($name, \%load);
}
sub get_remote_stat ($) {
@@ -88,55 +80,93 @@ sub get_remote_stat ($) {
}
}
-sub graph_stats ($$$) {
- my ($app, $rects, $colors) = @_;
+sub get_rect ($$) {
+ my ($rects, $name) = @_;
- my $width = WIDTH / (keys %GLOBAL_STATS) - 1;
- my ($x, $y) = (0, 0);
+ return $rects->{$name} if exists $rects->{$name};
+ return $rects->{$name} = SDL::Rect->new();
+}
- for my $key (sort keys %GLOBAL_STATS) {
- my ($host, $name) = split ';', $key;
- my %stat = map { my ($k, $v) = split '='; $k => $v } split ';', $GLOBAL_STATS{$key};
- my %load = (
- perc_idle => ($stat{nice}/($stat{TOTAL}/100)),
- perc_iowait => ($stat{iowait}/($stat{TOTAL}/100)),
- perc_system => ($stat{system}/($stat{TOTAL}/100)),
- perc_user => ($stat{user}/($stat{TOTAL}/100))
- );
+sub get_jiffies_diff ($$) {
+ my ($prev_stat, $stat) = @_;
- my $height_user = $load{perc_user}/(HEIGHT/10000);
- $y = HEIGHT - $height_user;
- my $rect_user = SDL::Rect->new(-height => $height_user, -width => $width, -x => $x, -y => $y);
+ return $stat unless defined $prev_stat;
+ return map { $_ => $stat->{$_} - $prev_stat->{$_} } keys %$stat;
+}
- my $height_system = $load{perc_system}/(HEIGHT/10000);
- $y -= $height_system;
- my $rect_system = SDL::Rect->new(-height => $height_system, -width => $width, -x => $x, -y => $y);
+sub normalize_loads (%) {
+ my (%loads) = @_;
- my $height_iowait = $load{perc_iowait}/(HEIGHT/10000);
- $y -= $height_iowait;
- my $rect_iowait = SDL::Rect->new(-height => $height_iowait, -width => $width, -x => $x, -y => $y);
+ return %loads unless exists $loads{TOTAL};
- my $height_idle = $load{perc_idle}/(HEIGHT/10000);
- $y -= $height_idle;
- my $rect_idle = SDL::Rect->new(-height => $height_idle, -width => $width, -x => $x, -y => $y);
+ my $total = $loads{TOTAL} == 0 ? 1 : $loads{TOTAL};
+ return map { $_ => $loads{$_} / ($total / 100) } keys %loads;
+}
+sub graph_stats ($$) {
+ my ($app, $colors) = @_;
- $app->fill($rect_idle, $colors->{blue});
- $app->fill($rect_iowait, $colors->{blue});
- $app->fill($rect_system, $colors->{yellow});
- $app->fill($rect_user, $colors->{red});
+ my $width = WIDTH / (keys %GLOBAL_STATS) - 1;
- $app->update($_) for $rect_idle, $rect_iowait, $rect_system, $rect_user;
-
- $x += $width + 1;
+ my $rects = {};
+ my %prev_stat;
- say $GLOBAL_STATS{$key};
- system('vmstat');
- print Dumper %stat;
- print Dumper %load;
- }
+ loop {
+ my ($x, $y) = (0, 0);
+ for my $key (sort keys %GLOBAL_STATS) {
+ my ($host, $name) = split ';', $key;
+ my %stat = map { my ($k, $v) = split '='; $k => $v } split ';', $GLOBAL_STATS{$key};
- loop { sleep 1 };
+ my %loads = normalize_loads get_jiffies_diff $prev_stat{$key}, \%stat;
+
+ $prev_stat{$key} = \%stat;
+
+ my %heights = map { $_ => $loads{$_} * (HEIGHT/50) } keys %loads;
+ next unless exists $heights{user};
+
+ my $rect_user = get_rect $rects, "$key;user";
+ my $rect_system = get_rect $rects, "$key;system";
+ my $rect_iowait = get_rect $rects, "$key;iowait";
+ my $rect_nice = get_rect $rects, "$key;nice";
+
+
+ $y = HEIGHT - $heights{user};
+ $rect_user->width($width);
+ $rect_user->height($heights{user});
+ $rect_user->x($x);
+ $rect_user->y($y);
+
+ $y -= $heights{system};
+ $rect_system->width($width);
+ $rect_system->height($heights{system});
+ $rect_system->x($x);
+ $rect_system->y($y);
+
+ $y -= $heights{iowait};
+ $rect_iowait->width($width);
+ $rect_iowait->height($heights{iowait});
+ $rect_iowait->x($x);
+ $rect_iowait->y($y);
+
+ $y -= $heights{nice};
+ $rect_nice->width($width);
+ $rect_nice->height($heights{nice});
+ $rect_nice->x($x);
+ $rect_nice->y($y);
+
+ $app->fill($rect_nice, $colors->{green});
+ $app->fill($rect_iowait, $colors->{black});
+ $app->fill($rect_system, $colors->{yellow});
+ $app->fill($rect_user, $colors->{red});
+
+ $app->update($_) for $rect_nice, $rect_iowait, $rect_system, $rect_user;
+
+ $x += $width + 1;
+
+ usleep $GLOBAL_CONF{sleep} * 1000000;
+ };
+
+ };
return undef;
}
@@ -159,26 +189,26 @@ sub display_stats () {
black => SDL::Color->new(-r => 0x00, -g => 0x00, -b => 0x00),
};
- my $rects = {
- };
-
$SIG{STOP} = sub {
say "Shutting down display_stats";
threads->exit();
};
- graph_stats $app, $rects, $colors;;
+ graph_stats $app, $colors;;
}
-sub main () {
+sub main (@_) {
+ my $host = shift;
+ $host = 'localhost' unless defined $host;
+
my @threads;
- push @threads, threads->create('get_remote_stat', 'localhost');
+ push @threads, threads->create('get_remote_stat', $host);
push @threads, threads->create('display_stats');
while (<STDIN>) {
/^q/ && last;
- /^s/ && do { $GLOBAL_CONF{sleep} = <STDIN> };
- /^e/ && do { $GLOBAL_CONF{events} = <STDIN> };
+ /^s/ && do { chomp ($GLOBAL_CONF{sleep} = <STDIN>) };
+ /^e/ && do { chomp ($GLOBAL_CONF{events} = <STDIN>) };
}
for (@threads) {
@@ -190,6 +220,6 @@ sub main () {
exit 0;
}
-main;
+main @ARGV;