Plack-Middleware-ServerStatus-Lite
view release on metacpan or search on metacpan
bin/server-status view on Meta::CPAN
my $parent_pid = $pstatus->{ppid};
my $upsince = time - $pstatus->{uptime};
my $duration = "";
my @spans = (86400 => 'days', 3600 => 'hours', 60 => 'minutes');
while (@spans) {
my ($seconds,$unit) = (shift @spans, shift @spans);
if ($upsince > $seconds) {
$duration .= int($upsince/$seconds) . " $unit, ";
$upsince = $upsince % $seconds;
}
}
$duration .= "$upsince seconds";
my $body="Uptime: ".$pstatus->{uptime}." ($duration)\n";
my %status = ( 'Uptime' => $pstatus->{uptime} );
if ( $counter_fh ) {
seek $counter_fh, 10, 0;
sysread $counter_fh, my $counter, 20;
sysread $counter_fh, my $total_bytes, 20;
no warnings;
$counter += 0;
$total_bytes += 0;
my $total_kbytes = int($total_bytes / 1_000);
$body .= sprintf "Total Accesses: %s\n", $counter;
$body .= sprintf "Total Kbytes: %s\n", $total_kbytes;
$status{TotalAccesses} = $counter;
$status{TotalKbytes} = $total_kbytes;
}
if ( $skip_ps_command ) {
# none
}
elsif ( $^O eq 'cygwin' ) {
@all_workers = ();
my $ps = `ps -ef`;
$ps =~ s/^\s+//mg;
for my $line ( split /\n/, $ps ) {
next if $line =~ m/^\D/;
my @proc = split /\s+/, $line;
push @all_workers, $proc[1] if $proc[2] == $parent_pid;
}
}
elsif ( $^O !~ m!mswin32!i ) {
@all_workers = ();
my $psopt = $^O =~ m/bsd$/ ? '-ax' : '-e';
my $ps = `LC_ALL=C command ps $psopt -o ppid,pid`;
$ps =~ s/^\s+//mg;
for my $line ( split /\n/, $ps ) {
next if $line =~ m/^\D/;
my ($ppid, $pid) = split /\s+/, $line, 2;
push @all_workers, $pid if $ppid == $parent_pid;
}
}
else {
# todo windows?
}
my $idle = 0;
my $busy = 0;
my $process_status = '';
my @process_status;
for my $pid ( @all_workers ) {
my $json = $stats->{$pid};
my $pstatus = eval {
$JSON->decode($json || '{}');
};
$pstatus ||= {};
if ( $pstatus->{status} && $pstatus->{status} eq 'A' ) {
$busy++;
}
else {
$idle++;
}
if ( defined $pstatus->{time} ) {
$pstatus->{ss} = time - $pstatus->{time};
}
$pstatus->{pid} ||= $pid;
delete $pstatus->{time};
delete $pstatus->{ppid};
delete $pstatus->{uptime};
$process_status .= sprintf "%s\n",
join(" ", map { defined $pstatus->{$_} ? $pstatus->{$_} : '' } qw/pid status remote_addr host method uri protocol ss/);
push @process_status, $pstatus;
}
$body .= <<EOF;
BusyWorkers: $busy
IdleWorkers: $idle
--
pid status remote_addr host method uri protocol ss
$process_status
EOF
chomp $body;
$status{BusyWorkers} = $busy;
$status{IdleWorkers} = $idle;
$status{stats} = \@process_status;
if ( $json ) {
print $JSON->encode(\%status);
}
else {
print $body;
}
exit(0);
__END__
=head1 NAME
server-status - a script to show the status of the local server
=head1 SYNOPSIS
% server-status --scoreboard server-status --counter server-status/access-counter
Total Accesses: 123
BusyWorkers: 2
IdleWorkers: 3
--
pid status remote_addr host method uri protocol ss
20060 A 127.0.0.1 localhost:10001 GET / HTTP/1.1 1
20061 .
20062 A 127.0.0.1 localhost:10001 GET /server-status HTTP/1.1 0
20063 .
20064 .
# JSON format
% server-status --json --counter ~/server-status/access-counter
{"BusyWorkers":"2",
"stats":[
{"protocol":null,"remote_addr":null,"pid":"78639",
"status":".","method":null,"uri":null,"host":null,"ss":null},
{"protocol":"HTTP/1.1","remote_addr":"127.0.0.1","pid":"78640",
"status":"A","method":"GET","uri":"/","host":"localhost:10226","ss":0},
...
],"IdleWorkers":"3"}
=head1 DESCRIPTION
This is a simple command-line script that examines the local server status
files to report on the status of a locally-running server, without incurring
any network overhead nor using a worker.
=head1 OPTIONS
=over 4
=item scoreboard
Required - same as the C<scoreboard> option in the middleware.
=item counter_file
Optional - same as the C<counter_file> option in the middleware.
( run in 1.827 second using v1.01-cache-2.11-cpan-437f7b0c052 )