Online Book Reader

Home Category

Apache Security - Ivan Ristic [121]

By Root 1999 0
by $url:

# fetch the page

my $ua = new LWP::UserAgent;

$ua->timeout(30);

$ua->agent("apache-monitor/1.0");

my $request = HTTP::Request->new(GET => $url);

my $response = $ua->request($request);

Parsing the output is fairly simple. Watch out for the incompatibility between the mod_status output in Apache 1 and Apache 2.

# Fetch the named fields first

# Set the results associative array. Each line in the file

# results in an element in the array. Each element

# has a key that is the text preceding the colon in a line

# of the file, and a value that is whatever appears after

# any whitespace after the colon on that line.

my %results = split/:\s*|\n/, $response->content;

# There is a slight incompatibility between

# Apache 1 and Apache 2, so the following makes

# the results consistent between the versions. Apache 2 uses

# the term "BusyWorkers" where Apache 1 uses "BusyServers".

if ($results{"BusyServers"}) {

$results{"BusyWorkers"} = $results{"BusyServers"};

$results{"IdleWorkers"} = $results{"IdleServers"};

}

# Count the occurrences of certain characters in the scoreboard

# by using the translation operator to find and replace each

# particular character (with itself) and return the number of

# replacements.

$results{"s_ _"} = $results{"Scoreboard"} =~ tr/_/_/;

$results{"s_s"} = $results{"Scoreboard"} =~ tr/S/S/;

$results{"s_r"} = $results{"Scoreboard"} =~ tr/R/R/;

$results{"s_w"} = $results{"Scoreboard"} =~ tr/W/W/;

$results{"s_k"} = $results{"Scoreboard"} =~ tr/K/K/;

$results{"s_d"} = $results{"Scoreboard"} =~ tr/D/D/;

$results{"s_c"} = $results{"Scoreboard"} =~ tr/C/C/;

$results{"s_l"} = $results{"Scoreboard"} =~ tr/L/L/;

$results{"s_g"} = $results{"Scoreboard"} =~ tr/G/G/;

$results{"s_i"} = $results{"Scoreboard"} =~ tr/I/I/;

After writing this code, I realized some of the fields mod_status gave me were not very useful. ReqPerSec, BytesPerSec, and BytesPerReq are calculated over the lifetime of the server and practically remain constant after a certain time period elapses. To get around this problem, I decided to keep the output from the previous run and manually create the statistics by comparing the values of the Total Accesses and Total kBytes fields, as appropriate, in relation to the amount of time between runs. The code for doing this can be seen in the program (apache-monitor) on the book's web site.

Next, we store the data into an RRD file so that it can be processed by an RRD tool. We need to test to see if the desired RRD file (specified by $rrd_name in the following) exists and create it if it does not:

if (! -e $rrd_name) {

# create the RRD file since it does not exist

RRDs::create($rrd_name,

# store data at 60 second intervals

"-s 60",

# data fields. Each line defines one data source (DS)

# that stores the measured value (GAUGE) at maximum 10 minute

# intervals (600 seconds), and takes values from zero.

# to infinity (U).

"DS:totalAccesses:GAUGE:600:0:U",

"DS:totalKbytes:GAUGE:600:0:U",

"DS:cpuLoad:GAUGE:600:0:U",

"DS:uptime:GAUGE:600:0:U",

"DS:reqPerSec:GAUGE:600:0:U",

"DS:bytesPerSec:GAUGE:600:0:U",

"DS:bytesPerReq:GAUGE:600:0:U",

"DS:busyWorkers:GAUGE:600:0:U",

"DS:idleWorkers:GAUGE:600:0:U",

"DS:sc_ _:GAUGE:600:0:U",

"DS:sc_s:GAUGE:600:0:U",

"DS:sc_r:GAUGE:600:0:U",

"DS:sc_w:GAUGE:600:0:U",

"DS:sc_k:GAUGE:600:0:U",

"DS:sc_d:GAUGE:600:0:U",

"DS:sc_c:GAUGE:600:0:U",

"DS:sc_l:GAUGE:600:0:U",

"DS:sc_g:GAUGE:600:0:U",

"DS:sc_i:GAUGE:600:0:U",

# keep 10080 original samples (one week of data,

# since one sample is made every minute)

"RRA:AVERAGE:0.5:1:10080",

# keep 8760 values calculated by averaging every

# 60 original samples (Each calculated value is one

# day so that comes to one year.)

"RRA:AVERAGE:0.5:60:8760"

}

);

Finally, we add the data to the RRD file:

RRDs::update($rrd_name, $time

. ":" . $results{"Total Accesses"}

. ":" . $results{"Total kBytes"}

. ":" . $results{"CPULoad"}

. ":" . $results{"Uptime"}

. ":" . $results{"ReqPerSec"}

. ":" . $results{"BytesPerSec"}

. ":" . $results{"BytesPerReq"}

. ":" . $results{"BusyWorkers"}

Return Main Page Previous Page Next Page

®Online Book Reader