#!/usr/local/bin/perl

# ====================================================================
# Copyright (c) 1995 The Apache Group.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer. 
#
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
#
# 3. All advertising materials mentioning features or use of this
#    software must display the following acknowledgment:
#    "This product includes software developed by the Apache Group
#    for use in the Apache HTTP server project (http://www.apache.org/)."
#
# 4. The names "Apache Server" and "Apache Group" must not be used to
#    endorse or promote products derived from this software without
#    prior written permission.
#
# 5. Redistributions of any form whatsoever must retain the following
#    acknowledgment:
#    "This product includes software developed by the Apache Group
#    for use in the Apache HTTP server project (http://www.apache.org/)."
#
# THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
# IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
# ====================================================================
#
# This software consists of voluntary contributions made by many
# individuals on behalf of the Apache Group and was originally based
# on public domain software written at the National Center for
# Supercomputing Applications, University of Illinois, Urbana-Champaign.
# For more information on the Apache Group and the Apache HTTP server
# project, please see <http://www.apache.org/>.


# simple script to monitor the child Apache processes
#   Usage:
#      httpd_monitor N     
#                Will give you an update ever N seconds
#                If you choose 0, it might chew up lots of CPU time.
#
# Output explanation..
#
#  s = sleeping but "ready to go" child
#  R = active child
#  _ = dead child (no longer needed)


$PID_FILE = "/var/log/www/httpd.pid";
$MAX_PROC = 40;    # we never have (or are interested in) more than 40 children

#########################################################################
select STDOUT; $| = 1;

$delay = @ARGV[0];

if ($delay =~ /\-h/i) {
  print STDERR "usage:\n$0 [i]\n  i = interval in seconds (defaults to 1)\n";
  exit(0);
}

$delay = 1 unless $delay =~ /^[0-9]+$/;

open (P, "$PID_FILE") || die "Unable to open $PID_FILE";
$PID = <P>;
$ext = sprintf("a%05d", $PID);
close(P);

open (SB, "/tmp/htstatus.$ext") || die "Unable to open scoreboard file /tmp/htstatus.$ext";

$last_len = 0;
while (1) {

  if ( ($last_mod = (stat("/tmp/htstatus.$ext"))[9]) != $before) {
    open (SB, "/tmp/htstatus.$ext") || die "Unable to open scoreboard file /tmp/htstatus.$ext";
    seek(SB, 2 , 0);
  
    $len = 0; $pad =""; $running = 0; $dead = 0;  $total=0;
    for ( $child=1; $child<=$MAX_PROC; $child++) {

       read(SB, $p1, 1);       # 2nd word = process number
       read(SB, $p2, 1);       # 2nd word = process number
       $p = hex(sprintf("%02X%02X", ord($p1), ord($p2)));

       read(SB, $status, 1);  # next byte = status
       $status = ord($status);
     
       read(SB, $junk, 5);    # skip to next entry
          
       $c = sprintf("%X", $child);
       
       if ($p != 0 && $p != $PID) {
         $total++;
         if ($status == 1) {
            $c = "s";
         } else {
            $c = "R";
            ++$running;
         }
         $printed .= "$pad$c";
         
         $pad = ""; 
         $dead = 0;
       } else {
            $dead++;
            $pad = "_"x$dead;
       } 
    }
    $printed .= " ($running/$total)";
    $len = length($printed);  
    
    if ($last_len > $len) {
       print "\010"x$last_len ;
       print " "x$last_len ;
       print "\010"x$last_len ;
    } else {
       print "\010"x$len ;
    }
    print $printed; $printed = "";

    $before = $last_mod;
    close(SB);
    $last_len = $len;
   }
   sleep($delay) if $delay >0;
}

     
  
