#!/usr/bin/perl -w
#
# apache-monitor-graph - create Apache usage graphs from RRD files
# Apache Security, http://www.apachesecurity.net
# Copyright (C) 2004 Ivan Ristic <ivanr@webkreator.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#

# This script will take an existing RRD file created with the
# apache-monitor script and generate four graphs showing Apache
# activity in the last 24 hrs (you can change this by changing
# the value of the variable $DURATION).
#
# Usage:
#
#   apache-monitor-graph /path/to/apache.org /output/path/
#
# The script will use the duration as part of the image names
# to allow you to store multiple-period graphs in the same
# directory.

use RRDs;

# show the last 24 hrs (the value is in seconds)
$DURATION = 3600;
$SUFFIX = 86400;

sub create_graphs_today {
    my $name = shift(@_);
    my $output = shift(@_);

    $end_time = time();
    $start_time = $end_time - $DURATION;

    create_graph_servers($name, "-servers-$SUFFIX", $start_time, $end_time, $output);
    create_graph_hits($name, "-hits-$SUFFIX", $start_time, $end_time, $output);
    create_graph_transfer($name, "-transfer-$SUFFIX", $start_time, $end_time, $output);
    create_graph_scoreboard($name, "-scoreboard-$SUFFIX", $start_time, $end_time, $output);
}

sub create_graph_servers {
    my $name = shift(@_);
    my $suffix = shift(@_);
    my $start_time = shift(@_);
    my $end_time = shift(@_);
    my $output_path = shift(@_);

    my $rrd_name = $name . ".rrd";
    my $justname = $name;

    if ($justname =~ m/\/([^\/]+)$/) {
        $justname = $1;
    }

    my $pic_name = $output_path . "/" . $justname . $suffix . ".gif";

    RRDs::graph($pic_name,
            "-v Servers",
            "-s $start_time",
            "-e $end_time",
            "DEF:r=$rrd_name:busyWorkers:AVERAGE",
            "DEF:r2=$rrd_name:idleWorkers:AVERAGE",
            "AREA:r#0000ff",
            "LINE2:r2#00ff00",
            "GPRINT:r:AVERAGE:Busy average %.2lf",
            "GPRINT:r2:AVERAGE:Idle average %.2lf"
        );

    my $err = RRDs::error;
    die "RRD error: $err\n" if $err;
}

sub create_graph_hits {
    my $name = shift(@_);
    my $suffix = shift(@_);
    my $start_time = shift(@_);
    my $end_time = shift(@_);
    my $output_path = shift(@_);

    my $rrd_name = $name . ".rrd";
    my $justname = $name;

    if ($justname =~ m/\/([^\/]+)$/) {
        $justname = $1;
    }

    my $pic_name = $output_path . "/" . $justname . $suffix . ".gif";

    RRDs::graph($pic_name,
            "-v hits/sec",
            "-s $start_time",
            "-e $end_time",
            "DEF:r=$rrd_name:reqPerSec:AVERAGE",
            "AREA:r#0000ff",
            "GPRINT:r:AVERAGE:Average %.2lf hits/sec",
        );

    my $err = RRDs::error;
    die "RRD error: $err\n" if $err;
}

sub create_graph_transfer {
    my $name = shift(@_);
    my $suffix = shift(@_);
    my $start_time = shift(@_);
    my $end_time = shift(@_);
    my $output_path = shift(@_);

    my $rrd_name = $name . ".rrd";
    my $justname = $name;

    if ($justname =~ m/\/([^\/]+)$/) {
        $justname = $1;
    }

    my $pic_name = $output_path . "/" . $justname . $suffix . ".gif";

    RRDs::graph($pic_name,
            "-v KB/sec",
            "-s $start_time",
            "-e $end_time",
            "DEF:r=$rrd_name:bytesPerSec:AVERAGE",
            "CDEF:rkb=r,1024,/",
            "AREA:rkb#0000ff",
            "GPRINT:rkb:AVERAGE:Average %.2lf KB/sec",
        );

    my $err = RRDs::error;
    die "RRD error: $err\n" if $err;
}

sub create_graph_scoreboard {
    my $name = shift(@_);
    my $suffix = shift(@_);
    my $start_time = shift(@_);
    my $end_time = shift(@_);
    my $output_path = shift(@_);

    my $rrd_name = $name . ".rrd";
    my $justname = $name;

    if ($justname =~ m/\/([^\/]+)$/) {
        $justname = $1;
    }

    my $pic_name = $output_path . "/" . $justname . $suffix . ".gif";

    RRDs::graph($pic_name,
            "-v Scoreboard",
            "-s $start_time",
            "-e $end_time",
            "DEF:sc__=$rrd_name:sc__:AVERAGE",
            "DEF:sc_s=$rrd_name:sc_s:AVERAGE",
            "DEF:sc_r=$rrd_name:sc_r:AVERAGE",
            "DEF:sc_w=$rrd_name:sc_w:AVERAGE",
            "DEF:sc_k=$rrd_name:sc_k:AVERAGE",
            "DEF:sc_d=$rrd_name:sc_d:AVERAGE",
            "DEF:sc_c=$rrd_name:sc_c:AVERAGE",
            "DEF:sc_l=$rrd_name:sc_l:AVERAGE",
            "DEF:sc_g=$rrd_name:sc_g:AVERAGE",
            "DEF:sc_i=$rrd_name:sc_i:AVERAGE",
            "LINE2:sc_r#0000ff:Reading",
            "LINE2:sc_w#ff00ff:Writing",
            "LINE2:sc_k#009090:KeepAlive",
            "LINE2:sc_d#ffff00:DNS",
            "LINE2:sc_c#ff0000:Closing",
            "LINE2:sc_g#900090:Graceful"
        );

    my $err = RRDs::error;
    die "RRD error: $err\n" if $err;
}

if (@ARGV != 3) {
    print "Usage: <file path w/o extension> <output path> <duration>\n";
    exit;
}

my($name, $output, $duration) = @ARGV;
# remove the .rrd extension if present
$name =~ s/\.rrd$//;
$DURATION = $duration;
$SUFFIX = $duration;
create_graphs_today($name, $output);
