#!/usr/bin/perl -w use strict; $|++; use LWP::Simple; use Curses; my $STATUS = "http://localhost/server-status"; my $SLEEPTIME = 10; my @FIELDS = qw( pid comm state ppid pgrp session tty tpgid flags minflt cminflt majflt cmajflt utime stime cutime cstime counter priority timeout itrealvalue starttime vsize rss rlim startcode endcode startstack kstkesp kstkeip signal blocked sigignore sigcatch wchan nswap cnswap ); my $SHOWLABELF = "%11s %5s %12s %1s %6s %6s %6s %6s %6s %6s"; my $SHOWLABEL = sprintf $SHOWLABELF, qw(START_TIME PID STATUS S MINFLT MAJFLT CPU PCPU RSS NSWAP); my @SHOWFIELDS = qw(starttime pid STATUS state minflt majflt CPU PCPU rss nswap); my $BOOTTIME = do { local *FOO; open FOO, "/proc/stat" or die "/proc/stat: $!"; local $/; ( =~ /btime (\d+)/)[0]; }; my %cpu_history; initscr; { $_ = get "$STATUS?notable" or die "no status!"; s/[\d\D]+Server Details.*\n//; s/^
.*//osmosis; # :-) my %info; my %cpu; $cpu{TIME} = time; my $seconds = exists $cpu_history{TIME} ? $cpu{TIME} - $cpu_history{TIME} : 0; my %http_status = /Server \d+-.*?\((\d+)\).*\[(?:<.*?>)?(.*?)(?:<.*?>)?\]/g; for my $file (map "/proc/$_/stat", keys %http_status) { local *FILE; open FILE, $file or next; $_ = ; close FILE; my %fields; (@fields{@FIELDS}, my @rest) = split; my $pid = $fields{pid}; $info{$pid} = \%fields; $info{$pid}{STATUS} = $http_status{$pid}; my $cpu = $fields{utime} + $fields{stime} + $fields{cutime} + $fields{cstime}; $cpu{$pid} = $info{$pid}{CPU} = $cpu; if ($seconds and exists $cpu_history{$pid}) { ## delta jiffies over seconds is already percentage! $info{$pid}{PCPU} = sprintf "%5.1f%%", ($cpu-$cpu_history{$pid}) / $seconds; } else { $info{$pid}{PCPU} = "??????"; } } %cpu_history = %cpu; erase; addstr(0,0,$SHOWLABEL); my $row = 1; for my $pid (sort { $info{$a}->{starttime} <=> $info{$b}->{starttime} or $info{$a}->{pid} <=> $info{$b}->{pid} } keys %info) { addstr($row,0, sprintf($SHOWLABELF, time_convert($info{$pid}{starttime}), @{$info{$pid}}{@SHOWFIELDS[1..$#SHOWFIELDS]})); $row++; } move(0,0); refresh; sleep $SLEEPTIME; redo; } endwin; sub time_convert { my $jiffies = shift; my $when = $BOOTTIME + $jiffies/100; my $string = localtime $when; if ($when < time - 12*60*60) { substr($string, 4, 7) . substr($string, -4, 4); } else { substr($string, 11, 8); } }