new 3.0 branch created

This commit is contained in:
Jordi Sanfeliu 2013-01-04 09:27:05 +01:00
parent 252417ead9
commit a1a283e745
30 changed files with 21749 additions and 21172 deletions

16
Changes
View File

@ -1,5 +1,6 @@
N.N.N - NN-XXX-NNNN
3.0.0 - NN-XXX-2013
====================
- Complete rewrite.
- Introduced some modifications to the device name detection for FreeBSD.
(thanks to Chris Rees, utisoft AT gmail.com)
- Improved support of Linux NFSv4 spliting the operation names in two different
@ -10,6 +11,19 @@ N.N.N - NN-XXX-NNNN
pause().
- Fixed a bug in multihost introduced by the groups code.
- Added a new option in 'port' to define the number of graphs per row.
- Fixed a missing description in the first entry of each network interface in
the options list.
- Fixed a missing argument on each *_init() function preventing show an "Ok"
message when debugging is enabled.
- Fixed some bugs in Groups.
- Fixed a typo in the percentage variable in FS alert.
- Fixed variables naming in 'mail' graph when using Postfix MTA that prevented
to see the values bounced, discarded and forwarded.
- Fixed a number of small bugs.
- Fixed a bad naming of the bitrate variables when creating the Bitrate graph
of the Icecast Streaming Media Server.
2.6.0 - 19-Sep-2012
====================

218
lib/Monitorix.pm Normal file
View File

@ -0,0 +1,218 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package Monitorix;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT = qw(logger trim get_nvidia_data flush_accounting_rules);
sub logger {
my ($msg) = @_;
$msg = localtime() . " - " . $msg;
print("$msg\n");
}
sub trim {
my $str = shift;
if($str) {
$str =~ s/^\s+//;
$str =~ s/\s+$//;
return $str;
}
}
sub get_nvidia_data {
my ($gpu) = @_;
my $total = 0;
my $used = 0;
my $mem = 0;
my $cpu = 0;
my $temp = 0;
my $check_mem = 0;
my $check_cpu = 0;
my $check_temp = 0;
my $l;
open(IN, "nvidia-smi -q -i $gpu -d MEMORY,UTILIZATION,TEMPERATURE |");
my @data = <IN>;
close(IN);
for($l = 0; $l < scalar(@data); $l++) {
if($data[$l] =~ /Memory Usage/) {
$check_mem = 1;
next;
}
if($check_mem) {
if($data[$l] =~ /Total/) {
my (undef, $tmp) = split(':', $data[$l]);
if($tmp eq "\n") {
$l++;
$tmp = $data[$l];
}
my ($value, undef) = split(' ', $tmp);
$value =~ s/[-]/./;
$value =~ s/[^0-9.]//g;
if(int($value) > 0) {
$total = int($value);
}
}
if($data[$l] =~ /Used/) {
my (undef, $tmp) = split(':', $data[$l]);
if($tmp eq "\n") {
$l++;
$tmp = $data[$l];
}
my ($value, undef) = split(' ', $tmp);
$value =~ s/[-]/./;
$value =~ s/[^0-9.]//g;
if(int($value) > 0) {
$used = int($value);
}
$check_mem = 0;
}
}
if($data[$l] =~ /Utilization/) {
$check_cpu = 1;
next;
}
if($check_cpu) {
if($data[$l] =~ /Gpu/) {
my (undef, $tmp) = split(':', $data[$l]);
if($tmp eq "\n") {
$l++;
$tmp = $data[$l];
}
my ($value, undef) = split(' ', $tmp);
$value =~ s/[-]/./;
$value =~ s/[^0-9.]//g;
if(int($value) > 0) {
$cpu = int($value);
}
}
if($data[$l] =~ /Memory/) {
my (undef, $tmp) = split(':', $data[$l]);
if($tmp eq "\n") {
$l++;
$tmp = $data[$l];
}
my ($value, undef) = split(' ', $tmp);
$value =~ s/[-]/./;
$value =~ s/[^0-9.]//g;
if(int($value) > 0) {
$mem = int($value);
}
}
$check_cpu = 0;
}
if($data[$l] =~ /Temperature/) {
$check_temp = 1;
next;
}
if($check_temp) {
if($data[$l] =~ /Gpu/) {
my (undef, $tmp) = split(':', $data[$l]);
if($tmp eq "\n") {
$l++;
$tmp = $data[$l];
}
my ($value, undef) = split(' ', $tmp);
$value =~ s/[-]/./;
$value =~ s/[^0-9.]//g;
if(int($value) > 0) {
$temp = int($value);
}
}
$check_temp = 0;
}
}
# NVIDIA driver v285.+ not supported (needs new output parsing).
# This is to avoid a divide by zero message.
if($total) {
$mem = ($used * 100) / $total;
} else {
$mem = $used = $total = 0;
}
return join(" ", $mem, $cpu, $temp);
}
# flushes out all Monitorix iptables/ipfw rules
sub flush_accounting_rules {
my ($config, $debug) = @_;
if($config->{os} eq "Linux") {
my $num = 0;
logger("Flushing out iptables rules.") if $debug;
if(open(IN, "iptables -nxvL INPUT --line-numbers |")) {
my @rules;
my @names;
while(<IN>) {
my ($rule, undef, undef, $name) = split(' ', $_);
if($name =~ /monitorix_IN/ || /monitorix_nginx_IN/) {
push(@rules, $rule);
push(@names, $name);
}
}
close(IN);
@rules = reverse(@rules);
foreach(@rules) {
system("iptables -D INPUT $_");
$num++;
}
foreach(@names) {
system("iptables -X $_");
}
}
if(open(IN, "iptables -nxvL OUTPUT --line-numbers |")) {
my @rules;
my @names;
while(<IN>) {
my ($rule, undef, undef, $name) = split(' ', $_);
if($name =~ /monitorix_OUT/ || /monitorix_nginx_OUT/) {
push(@rules, $rule);
push(@names, $name);
}
}
close(IN);
@rules = reverse(@rules);
foreach(@rules) {
system("iptables -D OUTPUT $_");
$num++;
}
foreach(@names) {
system("iptables -X $_");
}
}
logger("$num iptables rules have been flushed.") if $debug;
}
if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) {
logger("Flushing out ipfw rules.") if $debug;
system("ipfw delete $config->{port}->{rule} 2>/dev/null");
system("ipfw delete $config->{nginx}->{rule} 2>/dev/null");
}
}
1;

562
lib/apache.pm Normal file
View File

@ -0,0 +1,562 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package apache;
use strict;
use warnings;
use Monitorix;
use RRDs;
use LWP::UserAgent;
use Exporter 'import';
our @EXPORT = qw(apache_init apache_update apache_cgi);
sub apache_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $apache = $config->{apache};
my $info;
my @ds;
my @tmp;
my $n;
if(!scalar(my @al = split(',', $apache->{list}))) {
logger("$myself: ERROR: missing or not defined 'list' option.");
return 0;
}
if(-e $rrd) {
$info = RRDs::info($rrd);
for my $key (keys %$info) {
if(index($key, 'ds[') == 0) {
if(index($key, '.type') != -1) {
push(@ds, substr($key, 3, index($key, ']') - 3));
}
}
}
if(scalar(@ds) / 5 != scalar(my @al = split(',', $apache->{list}))) {
logger("Detected size mismatch between 'list' option (" . scalar(my @al = split(',', $apache->{list})) . ") and $rrd (" . scalar(@ds) / 5 . "). Resizing it accordingly. All historic data will be lost. Backup file created.");
rename($rrd, "$rrd.bak");
}
}
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
for($n = 0; $n < scalar(my @al = split(',', $apache->{list})); $n++) {
push(@tmp, "DS:apache" . $n . "_acc:GAUGE:120:0:U");
push(@tmp, "DS:apache" . $n . "_kb:GAUGE:120:0:U");
push(@tmp, "DS:apache" . $n . "_cpu:GAUGE:120:0:U");
push(@tmp, "DS:apache" . $n . "_busy:GAUGE:120:0:U");
push(@tmp, "DS:apache" . $n . "_idle:GAUGE:120:0:U");
}
eval {
RRDs::create($rrd,
"--step=60",
@tmp,
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
$config->{apache_hist} = ();
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub apache_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $apache = $config->{apache};
my $str;
my $rrdata = "N";
my $n = 0;
foreach(my @al = split(',', $apache->{list})) {
my $url = trim($_) . "/server-status?auto";
my $ua = LWP::UserAgent->new(timeout => 30);
my $response = $ua->request(HTTP::Request->new('GET', $url));
my $acc = 0;
my $kb = 0;
my $cpu = 0;
my $busy = 0;
my $idle = 0;
foreach(split('\n', $response->content)) {
if(/^Total Accesses:\s+(\d+)$/) {
$str = $n . "acc";
$acc = $1 - ($config->{apache_hist}->{$str} || 0);
$acc = 0 unless $acc != $1;
$acc /= 60;
$config->{apache_hist}->{$str} = $1;
next;
}
if(/^Total kBytes:\s+(\d+)$/) {
$str = $n . "kb";
$kb = $1 - ($config->{apache_hist}->{$str} || 0);
$kb = 0 unless $kb != $1;
$config->{apache_hist}->{$str} = $1;
next;
}
if(/^CPULoad:\s+(\d*\.\d+)$/) {
$cpu = abs($1) || 0;
next;
}
if(/^BusyWorkers:\s+(\d+)/ || /^BusyServers:\s+(\d+)/) {
$busy = int($1) || 0;
next;
}
if(/^IdleWorkers:\s+(\d+)/ || /^IdleServers:\s+(\d+)/) {
$idle = int($1) || 0;
last;
}
}
$rrdata .= ":$acc:$kb:$cpu:$busy:$idle";
$n++;
}
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub apache_cgi {
my ($package, $config, $cgi) = @_;
my $apache = $config->{apache};
my @rigid = split(',', $apache->{rigid});
my @limit = split(',', $apache->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @PNG;
my @PNGz;
my @tmp;
my @tmpz;
my $e;
my $e2;
my $n;
my $n2;
my $str;
my $err;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
my $line1;
my $line2;
my $line3;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print(" ");
for($n = 0; $n < scalar(my @al = split(',', $apache->{list})); $n++) {
$line1 = " ";
$line2 .= " Acceses kbytes CPU Busy Idle";
$line3 .= "------------------------------------------";
if($line1) {
my $i = length($line1);
printf(sprintf("%${i}s", sprintf("%s", trim($al[$n]))));
}
}
print("\n");
print("Time$line2\n");
print("----$line3 \n");
my $line;
my @row;
my $time;
my $n2;
my $from;
my $to;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc}", $time);
for($n2 = 0; $n2 < scalar(my @al = split(',', $apache->{list})); $n2++) {
undef(@row);
$from = $n2 * 5;
$to = $from + 5;
push(@row, @$line[$from..$to]);
printf(" %7d %9d %4.2f%% %3d %3d", @row);
}
print("\n");
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
for($n = 0; $n < scalar(my @al = split(',', $apache->{list})); $n++) {
for($n2 = 1; $n2 <= 3; $n2++) {
$str = $u . $package . $n . $n2 . "." . $tf->{when} . ".png";
push(@PNG, $str);
unlink("$PNG_DIR" . $str);
if(lc($config->{enable_zoom}) eq "y") {
$str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".png";
push(@PNGz, $str);
unlink("$PNG_DIR" . $str);
}
}
}
$e = 0;
foreach my $url (my @al = split(',', $apache->{list})) {
if($e) {
print(" <br>\n");
}
if($title) {
main::graph_header($title, 2);
}
undef(@riglim);
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
if($title) {
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:apache" . $e . "_idle#4444EE:Idle");
push(@tmp, "GPRINT:apache" . $e . "_idle:LAST: Current\\: %3.0lf");
push(@tmp, "GPRINT:apache" . $e . "_idle:AVERAGE: Average\\: %3.0lf");
push(@tmp, "GPRINT:apache" . $e . "_idle:MIN: Min\\: %3.0lf");
push(@tmp, "GPRINT:apache" . $e . "_idle:MAX: Max\\: %3.0lf\\n");
push(@tmp, "AREA:apache" . $e . "_busy#44EEEE:Busy");
push(@tmp, "GPRINT:apache" . $e . "_busy:LAST: Current\\: %3.0lf");
push(@tmp, "GPRINT:apache" . $e . "_busy:AVERAGE: Average\\: %3.0lf");
push(@tmp, "GPRINT:apache" . $e . "_busy:MIN: Min\\: %3.0lf");
push(@tmp, "GPRINT:apache" . $e . "_busy:MAX: Max\\: %3.0lf\\n");
push(@tmp, "LINE1:apache" . $e . "_idle#0000EE");
push(@tmp, "LINE1:apache" . $e . "_busy#00EEEE");
push(@tmp, "LINE1:apache" . $e . "_tot#EE0000");
push(@tmpz, "AREA:apache" . $e . "_idle#4444EE:Idle");
push(@tmpz, "AREA:apache" . $e . "_busy#44EEEE:Busy");
push(@tmpz, "LINE2:apache" . $e . "_idle#0000EE");
push(@tmpz, "LINE2:apache" . $e . "_busy#00EEEE");
push(@tmpz, "LINE2:apache" . $e . "_tot#EE0000");
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
}
RRDs::graph("$PNG_DIR" . "$PNG[$e * 3]",
"--title=$config->{graphs}->{_apache1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Workers",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:apache" . $e . "_busy=$rrd:apache" . $e . "_busy:AVERAGE",
"DEF:apache" . $e . "_idle=$rrd:apache" . $e . "_idle:AVERAGE",
"CDEF:apache" . $e . "_tot=apache" . $e . "_busy,apache" . $e . "_idle,+",
"COMMENT: \\n",
@tmp,
"COMMENT: \\n",
"COMMENT: \\n");
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$e * 3]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$e * 3]",
"--title=$config->{graphs}->{_apache1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Workers",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:apache" . $e . "_busy=$rrd:apache" . $e . "_busy:AVERAGE",
"DEF:apache" . $e . "_idle=$rrd:apache" . $e . "_idle:AVERAGE",
"CDEF:apache" . $e . "_tot=apache" . $e . "_busy,apache" . $e . "_idle,+",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$e * 3]: $err\n") if $err;
}
$e2 = $e + 1;
if($title || ($silent =~ /imagetag/ && $graph =~ /apache$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@riglim);
if(trim($rigid[1]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
} else {
if(trim($rigid[1]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:apache" . $e . "_cpu#44AAEE:CPU");
push(@tmp, "GPRINT:apache" . $e . "_cpu:LAST: Current\\: %5.2lf%%\\n");
push(@tmp, "LINE1:apache" . $e . "_cpu#00EEEE");
push(@tmpz, "AREA:apache" . $e . "_cpu#44AAEE:CPU");
push(@tmpz, "LINE1:apache" . $e . "_cpu#00EEEE");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG[$e * 3 + 1]",
"--title=$config->{graphs}->{_apache2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Percent (%)",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:apache" . $e . "_cpu=$rrd:apache" . $e . "_cpu:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$e * 3 + 1]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$e * 3 + 1]",
"--title=$config->{graphs}->{_apache2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Percent",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:apache" . $e . "_cpu=$rrd:apache" . $e . "_cpu:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$e * 3 + 1]: $err\n") if $err;
}
$e2 = $e + 2;
if($title || ($silent =~ /imagetag/ && $graph =~ /apache$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 1] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 1] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "'>\n");
}
}
undef(@riglim);
if(trim($rigid[2]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
} else {
if(trim($rigid[2]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:apache" . $e . "_acc#44EE44:Accesses");
push(@tmp, "GPRINT:apache" . $e . "_acc:LAST: Current\\: %5.2lf\\n");
push(@tmp, "LINE1:apache" . $e . "_acc#00EE00");
push(@tmpz, "AREA:apache" . $e . "_acc#44EE44:Accesses");
push(@tmpz, "LINE1:apache" . $e . "_acc#00EE00");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG[$e * 3 + 2]",
"--title=$config->{graphs}->{_apache3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Accesses/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:apache" . $e . "_acc=$rrd:apache" . $e . "_acc:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$e * 3 + 2]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$e * 3 + 2]",
"--title=$config->{graphs}->{_apache3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Accesses/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:apache" . $e . "_acc=$rrd:apache" . $e . "_acc:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$e * 3 + 2]: $err\n") if $err;
}
$e2 = $e + 3;
if($title || ($silent =~ /imagetag/ && $graph =~ /apache$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 2] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 2] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
print(" <tr>\n");
print " <td bgcolor='$colors->{title_bg_color}' colspan='2'>\n";
print " <font face='Verdana, sans-serif' color='$colors->{title_fg_color}'>\n";
print " <font size='-1'>\n";
print " <b style='{color: " . $colors->{title_fg_color} . "}'>&nbsp;&nbsp;$url<b>\n";
print " </font></font>\n";
print " </td>\n";
print(" </tr>\n");
main::graph_footer();
}
$e++;
}
print(" <br>\n");
return;
}
1;

1403
lib/bind.pm Normal file

File diff suppressed because it is too large Load Diff

598
lib/disk.pm Normal file
View File

@ -0,0 +1,598 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package disk;
use strict;
use warnings;
use Monitorix;
use RRDs;
use Exporter 'import';
our @EXPORT = qw(disk_init disk_update disk_cgi);
sub disk_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $disk = $config->{disk};
my $info;
my @ds;
my @tmp;
my $n;
if(-e $rrd) {
$info = RRDs::info($rrd);
for my $key (keys %$info) {
if(index($key, 'ds[') == 0) {
if(index($key, '.type') != -1) {
push(@ds, substr($key, 3, index($key, ']') - 3));
}
}
}
if(scalar(@ds) / 24 != keys(%{$disk->{list}})) {
logger("Detected size mismatch between <list>...</list> (" . keys(%{$disk->{list}}) . ") and $rrd (" . scalar(@ds) / 24 . "). Resizing it accordingly. All historic data will be lost. Backup file created.");
rename($rrd, "$rrd.bak");
}
}
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
for($n = 0; $n < keys(%{$disk->{list}}); $n++) {
push(@tmp, "DS:disk" . $n . "_hd0_temp:GAUGE:120:0:100");
push(@tmp, "DS:disk" . $n . "_hd0_smart1:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd0_smart2:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd1_temp:GAUGE:120:0:100");
push(@tmp, "DS:disk" . $n . "_hd1_smart1:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd1_smart2:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd2_temp:GAUGE:120:0:100");
push(@tmp, "DS:disk" . $n . "_hd2_smart1:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd2_smart2:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd3_temp:GAUGE:120:0:100");
push(@tmp, "DS:disk" . $n . "_hd3_smart1:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd3_smart2:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd4_temp:GAUGE:120:0:100");
push(@tmp, "DS:disk" . $n . "_hd4_smart1:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd4_smart2:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd5_temp:GAUGE:120:0:100");
push(@tmp, "DS:disk" . $n . "_hd5_smart1:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd5_smart2:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd6_temp:GAUGE:120:0:100");
push(@tmp, "DS:disk" . $n . "_hd6_smart1:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd6_smart2:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd7_temp:GAUGE:120:0:100");
push(@tmp, "DS:disk" . $n . "_hd7_smart1:GAUGE:120:0:U");
push(@tmp, "DS:disk" . $n . "_hd7_smart2:GAUGE:120:0:U");
}
eval {
RRDs::create($rrd,
"--step=60",
@tmp,
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub disk_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $disk = $config->{disk};
my $temp;
my $smart1;
my $smart2;
my $n;
my $rrdata = "N";
foreach my $k (sort keys %{$disk->{list}}) {
my @dsk = split(',', $disk->{list}->{$k});
for($n = 0; $n < 8; $n++) {
$temp = 0;
$smart1 = 0;
$smart2 = 0;
if($dsk[$n]) {
my $d = trim($dsk[$n]);
open(IN, "smartctl -A $d |");
while(<IN>) {
if(/^ 5/ && /Reallocated_Sector_Ct/) {
my @tmp = split(' ', $_);
$smart1 = $tmp[9];
chomp($smart1);
}
if(/^194/ && /Temperature_Celsius/) {
my @tmp = split(' ', $_);
$temp = $tmp[9];
chomp($temp);
}
if(/^197/ && /Current_Pending_Sector/) {
my @tmp = split(' ', $_);
$smart2 = $tmp[9];
chomp($smart2);
}
if(/^Current Drive Temperature: /) {
my @tmp = split(' ', $_);
$temp = $tmp[3] unless $temp;
chomp($temp);
}
}
close(IN);
$temp = `hddtemp -wqn $d` unless $temp;
chomp($temp);
}
$rrdata .= ":$temp";
$rrdata .= ":$smart1";
$rrdata .= ":$smart2";
}
}
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub disk_cgi {
my ($package, $config, $cgi) = @_;
my $disk = $config->{disk};
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @PNG;
my @PNGz;
my @tmp;
my @tmpz;
my $n;
my $n2;
my $e;
my $e2;
my $str;
my $err;
my @LC = (
"#FFA500",
"#44EEEE",
"#44EE44",
"#4444EE",
"#448844",
"#EE4444",
"#EE44EE",
"#EEEE44",
);
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
my $line1;
my $line2;
my $line3;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
foreach my $k (sort keys %{$disk->{list}}) {
my @d = split(',', $disk->{list}->{$k});
for($n = 0; $n < scalar(@d); $n++) {
$str = sprintf(" DISK %d ", $n + 1);
$line1 .= $str;
$str = sprintf(" Temp Realloc Pending ");
$line2 .= $str;
$line3 .= "----------------------";
}
}
print(" $line1\n");
print("Time $line2\n");
print("-----$line3\n");
my $line;
my @row;
my $time;
my $from;
my $to;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc} ", $time);
$e = 0;
foreach my $k (sort keys %{$disk->{list}}) {
my @d = split(',', $disk->{list}->{$k});
for($n2 = 0; $n2 < scalar(@d); $n2++) {
$from = ($e * 8 * 3) + ($n2 * 3);
$to = $from + 3;
my ($temp, $realloc, $pending) = @$line[$from..$to];
@row = ($temp, $realloc, $pending);
printf(" %4.0f %7.0f %7.0f ", @row);
}
$e++;
}
print("\n");
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
for($n = 0; $n < keys(%{$disk->{list}}); $n++) {
for($n2 = 1; $n2 <= 8; $n2++) {
$str = $u . $package . $n . $n2 . "." . $tf->{when} . ".png";
push(@PNG, $str);
unlink("$PNG_DIR" . $str);
if(lc($config->{enable_zoom}) eq "y") {
$str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".png";
push(@PNGz, $str);
unlink("$PNG_DIR" . $str);
}
}
}
$e = 0;
foreach my $k (sort keys %{$disk->{list}}) {
my @d = split(',', $disk->{list}->{$k});
if($e) {
print(" <br>\n");
}
if($title) {
main::graph_header($title, 2);
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "COMMENT: \\n");
for($n = 0; $n < 8; $n++) {
if($d[$n]) {
my ($dstr) = (split /\s+/, trim($d[$n]));
$str = sprintf("%-20s", $dstr);
push(@tmp, "LINE2:hd" . $n . $LC[$n] . ":$str");
push(@tmpz, "LINE2:hd" . $n . $LC[$n] . ":$dstr");
push(@tmp, "GPRINT:hd" . $n . ":LAST: Current\\: %2.0lf");
push(@tmp, "GPRINT:hd" . $n . ":AVERAGE: Average\\: %2.0lf");
push(@tmp, "GPRINT:hd" . $n . ":MIN: Min\\: %2.0lf");
push(@tmp, "GPRINT:hd" . $n . ":MAX: Max\\: %2.0lf\\n");
}
}
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
if(scalar(@d) && (scalar(@d) % 2)) {
push(@tmp, "COMMENT: \\n");
}
if($title) {
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG[$e * 3]",
"--title=$config->{graphs}->{_disk1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Celsius",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:hd0=$rrd:disk" . $e ."_hd0_temp:AVERAGE",
"DEF:hd1=$rrd:disk" . $e ."_hd1_temp:AVERAGE",
"DEF:hd2=$rrd:disk" . $e ."_hd2_temp:AVERAGE",
"DEF:hd3=$rrd:disk" . $e ."_hd3_temp:AVERAGE",
"DEF:hd4=$rrd:disk" . $e ."_hd4_temp:AVERAGE",
"DEF:hd5=$rrd:disk" . $e ."_hd5_temp:AVERAGE",
"DEF:hd6=$rrd:disk" . $e ."_hd6_temp:AVERAGE",
"DEF:hd7=$rrd:disk" . $e ."_hd7_temp:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$e * 3]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$e * 3]",
"--title=$config->{graphs}->{_disk1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Celsius",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:hd0=$rrd:disk" . $e ."_hd0_temp:AVERAGE",
"DEF:hd1=$rrd:disk" . $e ."_hd1_temp:AVERAGE",
"DEF:hd2=$rrd:disk" . $e ."_hd2_temp:AVERAGE",
"DEF:hd3=$rrd:disk" . $e ."_hd3_temp:AVERAGE",
"DEF:hd4=$rrd:disk" . $e ."_hd4_temp:AVERAGE",
"DEF:hd5=$rrd:disk" . $e ."_hd5_temp:AVERAGE",
"DEF:hd6=$rrd:disk" . $e ."_hd6_temp:AVERAGE",
"DEF:hd7=$rrd:disk" . $e ."_hd7_temp:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$e * 3]: $err\n") if $err;
}
$e2 = $e + 1;
if($title || ($silent =~ /imagetag/ && $graph =~ /disk$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@tmp);
undef(@tmpz);
for($n = 0; $n < 8; $n += 2) {
if($d[$n]) {
$str = sprintf("%-17s", substr($d[$n], 0, 17));
push(@tmp, "LINE2:rsc" . $n . $LC[$n] . ":$str");
push(@tmpz, "LINE2:rsc" . $n . $LC[$n] . ":$d[$n]\\g");
}
if($d[$n + 1]) {
$str = sprintf("%-17s", substr($d[$n + 1], 0, 17));
push(@tmp, "LINE2:rsc" . ($n + 1) . $LC[$n + 1] . ":$str\\n");
push(@tmpz, "LINE2:rsc" . ($n + 1) . $LC[$n + 1] . ":$d[$n + 1]\\g");
}
}
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG[$e * 3 + 1]",
"--title=$config->{graphs}->{_disk2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Sectors",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:rsc0=$rrd:disk" . $e . "_hd0_smart1:AVERAGE",
"DEF:rsc1=$rrd:disk" . $e . "_hd1_smart1:AVERAGE",
"DEF:rsc2=$rrd:disk" . $e . "_hd2_smart1:AVERAGE",
"DEF:rsc3=$rrd:disk" . $e . "_hd3_smart1:AVERAGE",
"DEF:rsc4=$rrd:disk" . $e . "_hd4_smart1:AVERAGE",
"DEF:rsc5=$rrd:disk" . $e . "_hd5_smart1:AVERAGE",
"DEF:rsc6=$rrd:disk" . $e . "_hd6_smart1:AVERAGE",
"DEF:rsc7=$rrd:disk" . $e . "_hd7_smart1:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$e * 3 + 1]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$e * 3 + 1]",
"--title=$config->{graphs}->{_disk2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Sectors",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:rsc0=$rrd:disk" . $e . "_hd0_smart1:AVERAGE",
"DEF:rsc1=$rrd:disk" . $e . "_hd1_smart1:AVERAGE",
"DEF:rsc2=$rrd:disk" . $e . "_hd2_smart1:AVERAGE",
"DEF:rsc3=$rrd:disk" . $e . "_hd3_smart1:AVERAGE",
"DEF:rsc4=$rrd:disk" . $e . "_hd4_smart1:AVERAGE",
"DEF:rsc5=$rrd:disk" . $e . "_hd5_smart1:AVERAGE",
"DEF:rsc6=$rrd:disk" . $e . "_hd6_smart1:AVERAGE",
"DEF:rsc7=$rrd:disk" . $e . "_hd7_smart1:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$e * 3 + 1]: $err\n") if $err;
}
$e2 = $e + 2;
if($title || ($silent =~ /imagetag/ && $graph =~ /disk$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 1] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 1] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "'>\n");
}
}
undef(@tmp);
undef(@tmpz);
for($n = 0; $n < 8; $n += 2) {
if($d[$n]) {
$str = sprintf("%-17s", substr($d[$n], 0, 17));
push(@tmp, "LINE2:cps" . $n . $LC[$n] . ":$str");
push(@tmpz, "LINE2:cps" . $n . $LC[$n] . ":$d[$n]\\g");
}
if($d[$n + 1]) {
$str = sprintf("%-17s", substr($d[$n + 1], 0, 17));
push(@tmp, "LINE2:cps" . ($n + 1) . $LC[$n + 1] . ":$str\\n");
push(@tmpz, "LINE2:cps" . ($n + 1) . $LC[$n + 1] . ":$d[$n + 1]\\g");
}
}
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG[$e * 3 + 2]",
"--title=$config->{graphs}->{_disk3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Sectors",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:cps0=$rrd:disk" . $e . "_hd0_smart2:AVERAGE",
"DEF:cps1=$rrd:disk" . $e . "_hd1_smart2:AVERAGE",
"DEF:cps2=$rrd:disk" . $e . "_hd2_smart2:AVERAGE",
"DEF:cps3=$rrd:disk" . $e . "_hd3_smart2:AVERAGE",
"DEF:cps4=$rrd:disk" . $e . "_hd4_smart2:AVERAGE",
"DEF:cps5=$rrd:disk" . $e . "_hd5_smart2:AVERAGE",
"DEF:cps6=$rrd:disk" . $e . "_hd6_smart2:AVERAGE",
"DEF:cps7=$rrd:disk" . $e . "_hd7_smart2:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$e * 3 + 2]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$e * 3 + 2]",
"--title=$config->{graphs}->{_disk3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Sectors",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:cps0=$rrd:disk" . $e . "_hd0_smart2:AVERAGE",
"DEF:cps1=$rrd:disk" . $e . "_hd1_smart2:AVERAGE",
"DEF:cps2=$rrd:disk" . $e . "_hd2_smart2:AVERAGE",
"DEF:cps3=$rrd:disk" . $e . "_hd3_smart2:AVERAGE",
"DEF:cps4=$rrd:disk" . $e . "_hd4_smart2:AVERAGE",
"DEF:cps5=$rrd:disk" . $e . "_hd5_smart2:AVERAGE",
"DEF:cps6=$rrd:disk" . $e . "_hd6_smart2:AVERAGE",
"DEF:cps7=$rrd:disk" . $e . "_hd7_smart2:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$e * 3 + 2]: $err\n") if $err;
}
$e2 = $e + 3;
if($title || ($silent =~ /imagetag/ && $graph =~ /disk$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 2] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 2] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
$e++;
}
print(" <br>\n");
return;
}
1;

436
lib/fail2ban.pm Normal file
View File

@ -0,0 +1,436 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package fail2ban;
use strict;
use warnings;
use Monitorix;
use RRDs;
use POSIX qw(strftime);
use Exporter 'import';
our @EXPORT = qw(fail2ban_init fail2ban_update fail2ban_cgi);
sub fail2ban_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $fail2ban = $config->{fail2ban};
my $info;
my @ds;
my @tmp;
my $n;
if(-e $rrd) {
$info = RRDs::info($rrd);
for my $key (keys %$info) {
if(index($key, 'ds[') == 0) {
if(index($key, '.type') != -1) {
push(@ds, substr($key, 3, index($key, ']') - 3));
}
}
}
if(scalar(@ds) / 9 != scalar(my @fl = split(',', $fail2ban->{list}))) {
logger("Detected size mismatch between 'list' (" . scalar(my @fl = split(',', $fail2ban->{list})) . ") and $rrd (" . scalar(@ds) / 9 . "). Resizing it accordingly. All historic data will be lost. Backup file created.");
rename($rrd, "$rrd.bak");
}
}
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
for($n = 0; $n < scalar(my @fl = split(',', $fail2ban->{list})); $n++) {
push(@tmp, "DS:fail2ban" . $n . "_j1:GAUGE:120:0:U");
push(@tmp, "DS:fail2ban" . $n . "_j2:GAUGE:120:0:U");
push(@tmp, "DS:fail2ban" . $n . "_j3:GAUGE:120:0:U");
push(@tmp, "DS:fail2ban" . $n . "_j4:GAUGE:120:0:U");
push(@tmp, "DS:fail2ban" . $n . "_j5:GAUGE:120:0:U");
push(@tmp, "DS:fail2ban" . $n . "_j6:GAUGE:120:0:U");
push(@tmp, "DS:fail2ban" . $n . "_j7:GAUGE:120:0:U");
push(@tmp, "DS:fail2ban" . $n . "_j8:GAUGE:120:0:U");
push(@tmp, "DS:fail2ban" . $n . "_j9:GAUGE:120:0:U");
}
eval {
RRDs::create($rrd,
"--step=60",
@tmp,
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
$config->{fail2ban_hist} = 0;
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub fail2ban_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $fail2ban = $config->{fail2ban};
my $seek_pos;
my $logsize;
my @jails;
my $n;
my $str;
my $rrdata = "N";
if(! -r $config->{fail2ban_log}) {
logger("Couldn't find file '$config->{fail2ban_log}': $!");
return;
}
$seek_pos = $config->{fail2ban_hist} || 0;
$seek_pos = defined($seek_pos) ? int($seek_pos) : 0;
open(IN, $config->{fail2ban_log});
if(!seek(IN, 0, 2)) {
logger("Couldn't seek to the end of '$config->{fail2ban_log}': $!");
return;
}
$logsize = tell(IN);
if($logsize < $seek_pos) {
$seek_pos = 0;
}
if(!seek(IN, $seek_pos, 0)) {
logger("Couldn't seek to $seek_pos in '$config->{fail2ban_log}': $!");
return;
}
if($config->{fail2ban_hist} > 0) { # avoids initial spike
my $date = strftime("%Y-%m-%d", localtime);
while(<IN>) {
if(/^$date/) {
my $e = 0;
while($e < scalar(my @fl = split(',', $fail2ban->{list}))) {
foreach my $i (split(',', $fail2ban->{desc}->{$e})) {
my $e2 = 0;
($str = trim($i)) =~ s/\[/\\[/;
$str =~ s/\]/\\]/;
$jails[$e][$e2] = 0 unless defined $jails[$e][$e2];
if(/ $str Ban /) {
$jails[$e][$e2]++;
}
$e2++;
}
$e++;
}
}
}
}
close(IN);
my $e = 0;
while($e < scalar(my @fl = split(',', $fail2ban->{list}))) {
for($n = 0; $n < 9; $n++) {
$jails[$e][$n] = 0 unless defined $jails[$e][$n];
$rrdata .= ":" . $jails[$e][$n];
}
$e++;
}
$config->{fail2ban_hist} = $logsize;
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub fail2ban_cgi {
my ($package, $config, $cgi) = @_;
my $fail2ban = $config->{fail2ban};
my @rigid = split(',', $fail2ban->{rigid});
my @limit = split(',', $fail2ban->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @PNG;
my @PNGz;
my @tmp;
my @tmpz;
my $n;
my $n2;
my $str;
my $err;
my @LC = (
"#4444EE",
"#EEEE44",
"#44EEEE",
"#EE44EE",
"#888888",
"#E29136",
"#44EE44",
"#448844",
"#EE4444",
);
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
my $line1;
my $line2;
my $line3;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print(" ");
for($n = 0; $n < scalar(my @fl = split(',', $fail2ban->{list})); $n++) {
$line1 = "";
foreach my $i (split(',', $fail2ban->{desc}->{$n})) {
$str = sprintf("%20s", substr(trim($i), 0, 20));
$line1 .= " ";
$line2 .= sprintf(" %20s", $str);
$line3 .= "---------------------";
}
if($line1) {
my $i = length($line1);
printf(sprintf("%${i}s", sprintf("%s", trim($fl[$n]))));
}
}
print("\n");
print("Time$line2\n");
print("----$line3 \n");
my $line;
my @row;
my $time;
my $n2;
my $n3;
my $from;
my $to;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc} ", $time);
for($n2 = 0; $n2 < scalar(my @fl = split(',', $fail2ban->{list})); $n2++) {
$n3 = 0;
foreach my $i (split(',', $fail2ban->{desc}->{$n2})) {
$from = $n2 * 9 + $n3++;
$to = $from + 1;
my ($j) = @$line[$from..$to];
@row = ($j);
printf("%20d ", @row);
}
}
print("\n");
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
for($n = 0; $n < scalar(my @fl = split(',', $fail2ban->{list})); $n++) {
$str = $u . $package . $n . "." . $tf->{when} . ".png";
push(@PNG, $str);
unlink("$PNG_DIR" . $str);
if(lc($config->{enable_zoom}) eq "y") {
$str = $u . $package . $n . "z." . $tf->{when} . ".png";
push(@PNGz, $str);
unlink("$PNG_DIR" . $str);
}
}
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
$n = 0;
while($n < scalar(my @fl = split(',', $fail2ban->{list}))) {
if($title) {
if($n == 0) {
main::graph_header($title, $fail2ban->{graphs_per_row});
}
print(" <tr>\n");
}
for($n2 = 0; $n2 < $fail2ban->{graphs_per_row}; $n2++) {
last unless $n < scalar(my @fl = split(',', $fail2ban->{list}));
if($title) {
print(" <td bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@tmp);
undef(@tmpz);
my $e = 0;
foreach my $i (split(',', $fail2ban->{desc}->{$n})) {
$str = sprintf("%-25s", substr(trim($i), 0, 25));
push(@tmp, "LINE1:j" . ($e + 1) . $LC[$e] . ":$str");
push(@tmp, "GPRINT:j" . ($e + 1) . ":LAST: Cur\\:%2.0lf\\g");
push(@tmp, "GPRINT:j" . ($e + 1) . ":AVERAGE: Avg\\:%2.0lf\\g");
push(@tmp, "GPRINT:j" . ($e + 1) . ":MIN: Min\\:%2.0lf\\g");
push(@tmp, "GPRINT:j" . ($e + 1) . ":MAX: Max\\:%2.0lf\\n");
push(@tmpz, "LINE2:j" . ($e + 1) . $LC[$e] . ":$str");
$e++;
}
while($e < 9) {
push(@tmp, "COMMENT: \\n");
$e++;
}
($width, $height) = split('x', $config->{graph_size}->{medium});
$str = substr(trim($fl[$n]), 0, 25);
RRDs::graph("$PNG_DIR" . "$PNG[$n]",
"--title=$str ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=bans/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:j1=$rrd:fail2ban" . $n . "_j1:AVERAGE",
"DEF:j2=$rrd:fail2ban" . $n . "_j2:AVERAGE",
"DEF:j3=$rrd:fail2ban" . $n . "_j3:AVERAGE",
"DEF:j4=$rrd:fail2ban" . $n . "_j4:AVERAGE",
"DEF:j5=$rrd:fail2ban" . $n . "_j5:AVERAGE",
"DEF:j6=$rrd:fail2ban" . $n . "_j6:AVERAGE",
"DEF:j7=$rrd:fail2ban" . $n . "_j7:AVERAGE",
"DEF:j8=$rrd:fail2ban" . $n . "_j8:AVERAGE",
"DEF:j9=$rrd:fail2ban" . $n . "_j9:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$n]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$n]",
"--title=$str ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=bans/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:j1=$rrd:fail2ban" . $n . "_j1:AVERAGE",
"DEF:j2=$rrd:fail2ban" . $n . "_j2:AVERAGE",
"DEF:j3=$rrd:fail2ban" . $n . "_j3:AVERAGE",
"DEF:j4=$rrd:fail2ban" . $n . "_j4:AVERAGE",
"DEF:j5=$rrd:fail2ban" . $n . "_j5:AVERAGE",
"DEF:j6=$rrd:fail2ban" . $n . "_j6:AVERAGE",
"DEF:j7=$rrd:fail2ban" . $n . "_j7:AVERAGE",
"DEF:j8=$rrd:fail2ban" . $n . "_j8:AVERAGE",
"DEF:j9=$rrd:fail2ban" . $n . "_j9:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$n]: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /fail2ban$n/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$n] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$n] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$n] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$n] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$n] . "'>\n");
}
}
if($title) {
print(" </td>\n");
}
$n++;
}
if($title) {
print(" </tr>\n");
}
}
if($title) {
main::graph_footer();
}
print(" <br>\n");
return;
}
1;

1012
lib/fs.pm Normal file

File diff suppressed because it is too large Load Diff

604
lib/hptemp.pm Normal file
View File

@ -0,0 +1,604 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package hptemp;
use strict;
use warnings;
use Monitorix;
use RRDs;
use Exporter 'import';
our @EXPORT = qw(hptemp_init hptemp_update hptemp_cgi);
sub hptemp_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
# checks if 'hplog' does exists.
if(!open(IN, "hplog -t |")) {
logger("$myself: unable to execute 'hplog'. $!");
return;
}
# save the output of 'hplog -t' since only 'root' is able to run it
my @data = <IN>;
close(IN);
open(OUT, "> $config->{base_dir}/cgi-bin/monitorix.hplog");
print(OUT @data);
close(OUT);
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
eval {
RRDs::create($rrd,
"--step=60",
"DS:hptemp1_1:GAUGE:120:0:100",
"DS:hptemp1_2:GAUGE:120:0:100",
"DS:hptemp1_3:GAUGE:120:0:100",
"DS:hptemp1_4:GAUGE:120:0:100",
"DS:hptemp1_5:GAUGE:120:0:100",
"DS:hptemp1_6:GAUGE:120:0:100",
"DS:hptemp1_7:GAUGE:120:0:100",
"DS:hptemp1_8:GAUGE:120:0:100",
"DS:hptemp2_1:GAUGE:120:0:100",
"DS:hptemp2_2:GAUGE:120:0:100",
"DS:hptemp2_3:GAUGE:120:0:100",
"DS:hptemp2_4:GAUGE:120:0:100",
"DS:hptemp2_5:GAUGE:120:0:100",
"DS:hptemp2_6:GAUGE:120:0:100",
"DS:hptemp3_1:GAUGE:120:0:100",
"DS:hptemp3_2:GAUGE:120:0:100",
"DS:hptemp3_3:GAUGE:120:0:100",
"DS:hptemp3_4:GAUGE:120:0:100",
"DS:hptemp3_5:GAUGE:120:0:100",
"DS:hptemp3_6:GAUGE:120:0:100",
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub hptemp_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $hptemp = $config->{hptemp};
my @hptemp1;
my @hptemp2;
my @hptemp3;
my $l;
my $n;
my $rrdata = "N";
if(!open(IN, "hplog -t |")) {
logger("$myself: unable to execute 'hplog'. $!");
return;
}
my @data = <IN>;
close(IN);
my $str;
for($l = 0; $l < scalar(@data); $l++) {
foreach my $t (split(',', $hptemp->{list}->{0})) {
$str = sprintf("%2d", trim($t));
if($data[$l] =~ m/^$str /) {
my $temp = trim(substr($data[$l], 47, 3));
chomp($temp);
push(@hptemp1, map {$_ eq "---" ? 0 : $_} ($temp));
}
}
foreach my $t (split(',', $hptemp->{list}->{1})) {
$str = sprintf("%2d", trim($t));
if($data[$l] =~ m/^$str /) {
my $temp = trim(substr($data[$l], 47, 3));
chomp($temp);
push(@hptemp2, map {$_ eq "---" ? 0 : $_} ($temp));
}
}
foreach my $t (split(',', $hptemp->{list}->{2})) {
$str = sprintf("%2d", trim($t));
if($data[$l] =~ m/^$str /) {
my $temp = trim(substr($data[$l], 47, 3));
chomp($temp);
push(@hptemp3, map {$_ eq "---" ? 0 : $_} ($temp));
}
}
}
for($n = 0; $n < 8; $n++) {
$hptemp1[$n] = 0 unless $hptemp1[$n];
$rrdata .= ":$hptemp1[$n]";
}
for($n = 0; $n < 6; $n++) {
$hptemp2[$n] = 0 unless $hptemp2[$n];
$rrdata .= ":$hptemp2[$n]";
}
for($n = 0; $n < 6; $n++) {
$hptemp3[$n] = 0 unless $hptemp3[$n];
$rrdata .= ":$hptemp3[$n]";
}
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub hptemp_cgi {
my ($package, $config, $cgi) = @_;
my $hptemp = $config->{hptemp};
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @tmp;
my @tmpz;
my $n;
my $id;
my $str;
my $err;
my @LC = (
"#FFA500",
"#44EEEE",
"#44EE44",
"#4444EE",
"#448844",
"#EE4444",
"#EE44EE",
"#EEEE44",
);
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
open(IN, "monitorix.hplog");
my @hplog = <IN>;
close(IN);
if(!scalar(@hplog)) {
print("WARNING: 'hplog' command output is empty.");
}
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
my $str;
my $line1;
my $line2;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
foreach my $t (split(',', $hptemp->{list}->{0}), split(',', $hptemp->{list}->{1}), split(',', $hptemp->{list}->{2})) {
$id = sprintf("%2d", trim($t));
for($n = 0; $n < scalar(@hplog); $n++) {
$_ = $hplog[$n];
if(/^$id /) {
$str = substr($_, 17, 8);
$str = sprintf("%8s", $str);
$line1 .= " ";
$line1 .= $str;
$line2 .= "----------";
}
}
}
print("Time $line1 \n");
print("-----$line2\n");
my $line;
my @row;
my $time;
my $n2;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc} ", $time);
undef($line1);
undef(@row);
for($n2 = 0; $n2 < scalar(my @hp = split(',', $hptemp->{list}->{0})); $n2++) {
my $temp = @$line[$n2];
push(@row, $temp);
$line1 .= " %8.0f ";
}
for($n2 = 0; $n2 < scalar(my @hp = split(',', $hptemp->{list}->{1})); $n2++) {
my $temp = @$line[8 + $n2];
push(@row, $temp);
$line1 .= " %8.0f ";
}
for($n2 = 0; $n2 < scalar(my @hp = split(',', $hptemp->{list}->{2})); $n2++) {
my $temp = @$line[8 + 3 + $n2];
push(@row, $temp);
$line1 .= " %8.0f ";
}
print(sprintf($line1, @row));
print("\n");
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
my $PNG1 = $u . $package . "1." . $tf->{when} . ".png";
my $PNG2 = $u . $package . "2." . $tf->{when} . ".png";
my $PNG3 = $u . $package . "3." . $tf->{when} . ".png";
my $PNG1z = $u . $package . "1z." . $tf->{when} . ".png";
my $PNG2z = $u . $package . "2z." . $tf->{when} . ".png";
my $PNG3z = $u . $package . "3z." . $tf->{when} . ".png";
unlink ("$PNG_DIR" . "$PNG1",
"$PNG_DIR" . "$PNG2",
"$PNG_DIR" . "$PNG3");
if(lc($config->{enable_zoom}) eq "y") {
unlink ("$PNG_DIR" . "$PNG1z",
"$PNG_DIR" . "$PNG2z",
"$PNG_DIR" . "$PNG3z");
}
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
if(scalar(my @hptemp0 = split(',', $hptemp->{list}->{0}))) {
undef(@tmp);
undef(@tmpz);
for($n = 0; $n < 8; $n++) {
if($hptemp0[$n]) {
foreach(@hplog) {
$id = sprintf("%2d", trim($hptemp0[$n]));
if(/^$id /) {
$str = substr($_, 17, 8);
$str = sprintf("%-20s", $str);
push(@tmp, "LINE2:temp" . $n . $LC[$n] . ":$str");
push(@tmp, "GPRINT:temp" . $n . ":LAST:Current\\: %2.0lf");
push(@tmp, "GPRINT:temp" . $n . ":AVERAGE: Average\\: %2.0lf");
push(@tmp, "GPRINT:temp" . $n . ":MIN: Min\\: %2.0lf");
push(@tmp, "GPRINT:temp" . $n . ":MAX: Max\\: %2.0lf\\n");
$str =~ s/\s+$//;
push(@tmpz, "LINE2:temp" . $n . $LC[$n] . ":$str");
last;
}
}
} else {
push(@tmp, "COMMENT: \\n");
}
}
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
}
RRDs::graph("$PNG_DIR" . "$PNG1",
"--title=$config->{graphs}->{_hptemp1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Celsius",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:temp0=$rrd:hptemp1_1:AVERAGE",
"DEF:temp1=$rrd:hptemp1_2:AVERAGE",
"DEF:temp2=$rrd:hptemp1_3:AVERAGE",
"DEF:temp3=$rrd:hptemp1_4:AVERAGE",
"DEF:temp4=$rrd:hptemp1_5:AVERAGE",
"DEF:temp5=$rrd:hptemp1_6:AVERAGE",
"DEF:temp6=$rrd:hptemp1_7:AVERAGE",
"DEF:temp7=$rrd:hptemp1_8:AVERAGE",
@tmp,
"COMMENT: \\n");
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG1z",
"--title=$config->{graphs}->{_hptemp1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Celsius",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:temp0=$rrd:hptemp1_1:AVERAGE",
"DEF:temp1=$rrd:hptemp1_2:AVERAGE",
"DEF:temp2=$rrd:hptemp1_3:AVERAGE",
"DEF:temp3=$rrd:hptemp1_4:AVERAGE",
"DEF:temp4=$rrd:hptemp1_5:AVERAGE",
"DEF:temp5=$rrd:hptemp1_6:AVERAGE",
"DEF:temp6=$rrd:hptemp1_7:AVERAGE",
"DEF:temp7=$rrd:hptemp1_8:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /hptemp1/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG1z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG1z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "'>\n");
}
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
if(scalar(my @hptemp1 = split(',', $hptemp->{list}->{1}))) {
undef(@tmp);
undef(@tmpz);
for($n = 0; $n < 6; $n++) {
if($hptemp1[$n]) {
foreach(@hplog) {
$id = sprintf("%2d", trim($hptemp1[$n]));
if(/^$id /) {
$str = substr($_, 17, 8);
$str = sprintf("%-8s", $str);
push(@tmp, "LINE2:temp" . $n . $LC[$n] . ":$str");
push(@tmp, "GPRINT:temp" . $n . ":LAST:\\: %2.0lf");
if(!(($n + 1) % 2)) {
push(@tmp, "COMMENT: \\n");
} else {
push(@tmp, "COMMENT: ");
}
$str =~ s/\s+$//;
push(@tmpz, "LINE2:temp" . $n . $LC[$n] . ":$str");
last;
}
}
} else {
push(@tmp, "COMMENT: \\n") unless ($n + 1) % 2;
}
}
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
}
RRDs::graph("$PNG_DIR" . "$PNG2",
"--title=$config->{graphs}->{_hptemp2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Celsius",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:temp0=$rrd:hptemp2_1:AVERAGE",
"DEF:temp1=$rrd:hptemp2_2:AVERAGE",
"DEF:temp2=$rrd:hptemp2_3:AVERAGE",
"DEF:temp3=$rrd:hptemp2_4:AVERAGE",
"DEF:temp4=$rrd:hptemp2_5:AVERAGE",
"DEF:temp5=$rrd:hptemp2_6:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG2z",
"--title=$config->{graphs}->{_hptemp2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Celsius",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:temp0=$rrd:hptemp2_1:AVERAGE",
"DEF:temp1=$rrd:hptemp2_2:AVERAGE",
"DEF:temp2=$rrd:hptemp2_3:AVERAGE",
"DEF:temp3=$rrd:hptemp2_4:AVERAGE",
"DEF:temp4=$rrd:hptemp2_5:AVERAGE",
"DEF:temp5=$rrd:hptemp2_6:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /hptemp2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG2z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG2z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "'>\n");
}
}
}
if(scalar(my @hptemp2 = split(',', $hptemp->{list}->{2}))) {
undef(@tmp);
undef(@tmpz);
for($n = 0; $n < 6; $n++) {
if($hptemp2[$n]) {
foreach(@hplog) {
$id = sprintf("%2d", trim($hptemp2[$n]));
if(/^$id /) {
$str = substr($_, 17, 8);
$str = sprintf("%-8s", $str);
push(@tmp, "LINE2:temp" . $n . $LC[$n] . ":$str");
push(@tmp, "GPRINT:temp" . $n . ":LAST:\\: %2.0lf");
if(!(($n + 1) % 2)) {
push(@tmp, "COMMENT: \\n");
} else {
push(@tmp, "COMMENT: ");
}
$str =~ s/\s+$//;
push(@tmpz, "LINE2:temp" . $n . $LC[$n] . ":$str");
last;
}
}
} else {
push(@tmp, "COMMENT: \\n") unless ($n + 1) % 2;
}
}
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
}
RRDs::graph("$PNG_DIR" . "$PNG3",
"--title=$config->{graphs}->{_hptemp3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Celsius",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:temp0=$rrd:hptemp3_1:AVERAGE",
"DEF:temp1=$rrd:hptemp3_2:AVERAGE",
"DEF:temp2=$rrd:hptemp3_3:AVERAGE",
"DEF:temp3=$rrd:hptemp3_4:AVERAGE",
"DEF:temp4=$rrd:hptemp3_5:AVERAGE",
"DEF:temp5=$rrd:hptemp3_6:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG3z",
"--title=$config->{graphs}->{_hptemp3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Celsius",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:temp0=$rrd:hptemp3_1:AVERAGE",
"DEF:temp1=$rrd:hptemp3_2:AVERAGE",
"DEF:temp2=$rrd:hptemp3_3:AVERAGE",
"DEF:temp3=$rrd:hptemp3_4:AVERAGE",
"DEF:temp4=$rrd:hptemp3_5:AVERAGE",
"DEF:temp5=$rrd:hptemp3_6:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /hptemp3/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG3z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG3z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "'>\n");
}
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
1;

566
lib/icecast.pm Normal file
View File

@ -0,0 +1,566 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package icecast;
use strict;
use warnings;
use Monitorix;
use RRDs;
use LWP::UserAgent;
use Exporter 'import';
our @EXPORT = qw(icecast_init icecast_update icecast_cgi);
sub icecast_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $icecast = $config->{icecast};
my $info;
my @ds;
my @tmp;
my $n;
if(-e $rrd) {
$info = RRDs::info($rrd);
for my $key (keys %$info) {
if(index($key, 'ds[') == 0) {
if(index($key, '.type') != -1) {
push(@ds, substr($key, 3, index($key, ']') - 3));
}
}
}
if(scalar(@ds) / 36 != scalar(my @il = split(',', $icecast->{list}))) {
logger("Detected size mismatch between 'list' (" . scalar(my @il = split(',', $icecast->{list})) . ") and $rrd (" . scalar(@ds) / 36 . "). Resizing it accordingly. All historic data will be lost. Backup file created.");
rename($rrd, "$rrd.bak");
}
}
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
for($n = 0; $n < scalar(my @il = split(',', $icecast->{list})); $n++) {
push(@tmp, "DS:icecast" . $n . "_mp0_ls:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp0_br:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp0_v0:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp0_v1:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp1_ls:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp1_br:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp1_v0:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp1_v1:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp2_ls:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp2_br:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp2_v0:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp2_v1:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp3_ls:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp3_br:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp3_v0:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp3_v1:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp4_ls:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp4_br:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp4_v0:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp4_v1:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp5_ls:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp5_br:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp5_v0:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp5_v1:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp6_ls:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp6_br:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp6_v0:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp6_v1:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp7_ls:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp7_br:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp7_v0:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp7_v1:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp8_ls:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp8_br:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp8_v0:GAUGE:120:0:U");
push(@tmp, "DS:icecast" . $n . "_mp8_v1:GAUGE:120:0:U");
}
eval {
RRDs::create($rrd,
"--step=60",
@tmp,
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub icecast_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $icecast = $config->{icecast};
my @ls;
my @br;
my $n;
my $rrdata = "N";
my $e = 0;
foreach(my @il = split(',', $icecast->{list})) {
my $ils = trim($il[$e]);
my $ua = LWP::UserAgent->new(timeout => 30);
my $response = $ua->request(HTTP::Request->new('GET', trim($_)));
my $data = $response->content;
$data =~ s/\n//g;
undef(@ls);
undef(@br);
foreach my $i (split(',', $icecast->{desc}->{$ils})) {
my $m = "Mount Point " . trim($i);
my ($l) = ($data =~ m/$m.*?<tr><td>Current Listeners:<\/td><td class=\"streamdata\">(\d*?)<\/td>/g);
my ($b) = ($data =~ m/$m.*?<tr><td>Bitrate:<\/td><td class=\"streamdata\">(\d*?)<\/td><\/tr>/g);
$l = 0 unless defined($l);
$b = 0 unless defined($b);
push(@ls, $l);
push(@br, $b);
}
for($n = 0; $n < 9; $n++) {
$ls[$n] = 0 unless defined($ls[$n]);
$br[$n] = 0 unless defined($br[$n]);
$rrdata .= ":" . $ls[$n];
$rrdata .= ":" . $br[$n];
$rrdata .= ":" . "0";
$rrdata .= ":" . "0";
}
$e++;
}
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub icecast_cgi {
my ($package, $config, $cgi) = @_;
my $icecast = $config->{icecast};
my @rigid = split(',', $icecast->{rigid});
my @limit = split(',', $icecast->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @PNG;
my @PNGz;
my @tmp;
my @tmpz;
my $e;
my $n;
my $str;
my $stack;
my $err;
my @AC = (
"#FFA500",
"#44EEEE",
"#44EE44",
"#4444EE",
"#448844",
"#EE4444",
"#EE44EE",
"#EEEE44",
"#444444",
);
my @LC = (
"#FFA500",
"#00EEEE",
"#00EE00",
"#0000EE",
"#448844",
"#EE0000",
"#EE00EE",
"#EEEE00",
"#444444",
);
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
my $line1;
my $line2;
my $line3;
my $line4;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print(" ");
for($n = 0; $n < scalar(my @il = split(',', $icecast->{list})); $n++) {
my $l = trim($il[$n]);
$line1 = " ";
$line2 .= " ";
$line3 .= " ";
$line4 .= "--";
foreach my $i (split(',', $icecast->{desc}->{$l})) {
$line1 .= " ";
$line2 .= sprintf(" %10s", trim($i));
$line3 .= " List BitR";
$line4 .= "-----------";
}
if($line1) {
my $i = length($line1);
printf(sprintf("%${i}s", sprintf("Icecast Server %2d", $n)));
}
}
print("\n");
print(" $line2");
print("\n");
print("Time$line3\n");
print("----$line4 \n");
my $line;
my @row;
my $time;
my $n2;
my $n3;
my $from;
my $to;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc}", $time);
for($n2 = 0; $n2 < scalar(my @il = split(',', $icecast->{list})); $n2++) {
my $ls = trim($il[$n2]);
print(" ");
$n3 = 0;
foreach my $i (split(',', $icecast->{desc}->{$ls})) {
$from = $n2 * 36 + ($n3++ * 4);
$to = $from + 4;
my ($l, $b, undef, undef) = @$line[$from..$to];
@row = ($l, $b);
printf(" %4d %4d", @row);
}
}
print("\n");
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
for($n = 0; $n < scalar(my @il = split(',', $icecast->{list})); $n++) {
$str = $u . $package . $n . "1." . $tf->{when} . ".png";
push(@PNG, $str);
unlink("$PNG_DIR" . $str);
$str = $u . $package . $n . "2." . $tf->{when} . ".png";
push(@PNG, $str);
unlink("$PNG_DIR" . $str);
if(lc($config->{enable_zoom}) eq "y") {
$str = $u . $package . $n . "1z." . $tf->{when} . ".png";
push(@PNGz, $str);
unlink("$PNG_DIR" . $str);
$str = $u . $package . $n . "2z." . $tf->{when} . ".png";
push(@PNGz, $str);
unlink("$PNG_DIR" . $str);
}
}
$e = 0;
foreach my $url (my @il = split(',', $icecast->{list})) {
$url = trim($url);
if($e) {
print(" <br>\n");
}
if($title) {
main::graph_header($title, 2);
}
undef(@riglim);
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
$n = 0;
foreach my $i (split(',', $icecast->{desc}->{$url})) {
$i = trim($i);
$str = sprintf("%-15s", substr($i, 0, 15));
$stack = "";
if(lc($icecast->{graph_mode}) eq "s") {
$stack = ":STACK";
}
push(@tmp, "AREA:ice" . $e . "_mp$n" . $AC[$n] . ":$str" . $stack);
push(@tmpz, "AREA:ice" . $e . "_mp$n" . $AC[$n] . ":$i" . $stack);
push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":LAST: Cur\\:%4.0lf");
push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":AVERAGE: Avg\\:%4.0lf");
push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":MIN: Min\\:%4.0lf");
push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":MAX: Max\\:%4.0lf\\n");
$n++;
}
if(lc($icecast->{graph_mode}) ne "s") {
foreach my $i (split(',', $icecast->{desc}->{$url})) {
push(@tmp, "LINE1:ice" . $e . "_mp$n" . $LC[$n]);
push(@tmpz, "LINE2:ice" . $e . "_mp$n" . $LC[$n]);
}
}
if($title) {
print(" <tr>\n");
print(" <td bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
($width, $height) = split('x', $config->{graph_size}->{medium});
RRDs::graph("$PNG_DIR" . "$PNG[$e * 2]",
"--title=$config->{graphs}->{_icecast1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Listeners",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:ice" . $e . "_mp0=$rrd:icecast" . $e . "_mp0_ls:AVERAGE",
"DEF:ice" . $e . "_mp1=$rrd:icecast" . $e . "_mp1_ls:AVERAGE",
"DEF:ice" . $e . "_mp2=$rrd:icecast" . $e . "_mp2_ls:AVERAGE",
"DEF:ice" . $e . "_mp3=$rrd:icecast" . $e . "_mp3_ls:AVERAGE",
"DEF:ice" . $e . "_mp4=$rrd:icecast" . $e . "_mp4_ls:AVERAGE",
"DEF:ice" . $e . "_mp5=$rrd:icecast" . $e . "_mp5_ls:AVERAGE",
"DEF:ice" . $e . "_mp6=$rrd:icecast" . $e . "_mp6_ls:AVERAGE",
"DEF:ice" . $e . "_mp7=$rrd:icecast" . $e . "_mp7_ls:AVERAGE",
"DEF:ice" . $e . "_mp8=$rrd:icecast" . $e . "_mp8_ls:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$e * 2]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$e * 2]",
"--title=$config->{graphs}->{_icecast1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Listeners",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:ice" . $e . "_mp0=$rrd:icecast" . $e . "_mp0_ls:AVERAGE",
"DEF:ice" . $e . "_mp1=$rrd:icecast" . $e . "_mp1_ls:AVERAGE",
"DEF:ice" . $e . "_mp2=$rrd:icecast" . $e . "_mp2_ls:AVERAGE",
"DEF:ice" . $e . "_mp3=$rrd:icecast" . $e . "_mp3_ls:AVERAGE",
"DEF:ice" . $e . "_mp4=$rrd:icecast" . $e . "_mp4_ls:AVERAGE",
"DEF:ice" . $e . "_mp5=$rrd:icecast" . $e . "_mp5_ls:AVERAGE",
"DEF:ice" . $e . "_mp6=$rrd:icecast" . $e . "_mp6_ls:AVERAGE",
"DEF:ice" . $e . "_mp7=$rrd:icecast" . $e . "_mp7_ls:AVERAGE",
"DEF:ice" . $e . "_mp8=$rrd:icecast" . $e . "_mp8_ls:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$e * 2]: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /icecast$e/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 2] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 2] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 2] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 2] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 2] . "'>\n");
}
}
if($title) {
print(" </td>\n");
}
undef(@riglim);
if(trim($rigid[1]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
} else {
if(trim($rigid[1]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
$n = 0;
foreach my $i (split(',', $icecast->{desc}->{$url})) {
$i = trim($i);
$str = sprintf("%-15s", $i);
push(@tmp, "LINE1:ice" . $e . "_mp$n" . $LC[$n] . ":$str");
push(@tmpz, "LINE2:ice" . $e . "_mp$n" . $LC[$n] . ":$i");
push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":LAST: Cur\\:%3.0lf");
push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":AVERAGE: Avg\\:%3.0lf");
push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":MIN: Min\\:%3.0lf");
push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":MAX: Max\\:%3.0lf\\n");
$n++;
}
if($title) {
print(" <td bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
($width, $height) = split('x', $config->{graph_size}->{medium});
RRDs::graph("$PNG_DIR" . $PNG[$e * 2 + 1],
"--title=$config->{graphs}->{_icecast2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Bitrate",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:ice" . $e . "_mp0=$rrd:icecast" . $e . "_mp0_br:AVERAGE",
"DEF:ice" . $e . "_mp1=$rrd:icecast" . $e . "_mp1_br:AVERAGE",
"DEF:ice" . $e . "_mp2=$rrd:icecast" . $e . "_mp2_br:AVERAGE",
"DEF:ice" . $e . "_mp3=$rrd:icecast" . $e . "_mp3_br:AVERAGE",
"DEF:ice" . $e . "_mp4=$rrd:icecast" . $e . "_mp4_br:AVERAGE",
"DEF:ice" . $e . "_mp5=$rrd:icecast" . $e . "_mp5_br:AVERAGE",
"DEF:ice" . $e . "_mp6=$rrd:icecast" . $e . "_mp6_br:AVERAGE",
"DEF:ice" . $e . "_mp7=$rrd:icecast" . $e . "_mp7_br:AVERAGE",
"DEF:ice" . $e . "_mp8=$rrd:icecast" . $e . "_mp8_br:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . $PNG[$e * 2 + 1] . ": $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . $PNGz[$e * 2 + 1],
"--title=$config->{graphs}->{_icecast2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Bitrate",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:ice" . $e . "_mp0=$rrd:icecast" . $e . "_mp0_br:AVERAGE",
"DEF:ice" . $e . "_mp1=$rrd:icecast" . $e . "_mp1_br:AVERAGE",
"DEF:ice" . $e . "_mp2=$rrd:icecast" . $e . "_mp2_br:AVERAGE",
"DEF:ice" . $e . "_mp3=$rrd:icecast" . $e . "_mp3_br:AVERAGE",
"DEF:ice" . $e . "_mp4=$rrd:icecast" . $e . "_mp4_br:AVERAGE",
"DEF:ice" . $e . "_mp5=$rrd:icecast" . $e . "_mp5_br:AVERAGE",
"DEF:ice" . $e . "_mp6=$rrd:icecast" . $e . "_mp6_br:AVERAGE",
"DEF:ice" . $e . "_mp7=$rrd:icecast" . $e . "_mp7_br:AVERAGE",
"DEF:ice" . $e . "_mp8=$rrd:icecast" . $e . "_mp8_br:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . $PNGz[$e * 2 + 1] . ": $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /icecast$e/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 2 + 1] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 2 + 1] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 2 + 1] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 2 + 1] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 2 + 1] . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
print(" <tr>\n");
print " <td bgcolor='$colors->{title_bg_color}' colspan='2'>\n";
print " <font face='Verdana, sans-serif' color='$colors->{title_fg_color}'>\n";
print " <font size='-1'>\n";
print " <b>&nbsp;&nbsp;<a href='" . $url . "' style='{color: " . $colors->{title_fg_color} . "}'>$url</a><b>\n";
print " </font></font>\n";
print " </td>\n";
print(" </tr>\n");
main::graph_footer();
}
$e++;
}
print(" <br>\n");
return;
}
1;

1165
lib/int.pm Normal file

File diff suppressed because it is too large Load Diff

892
lib/kern.pm Normal file
View File

@ -0,0 +1,892 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package kern;
use strict;
use warnings;
use Monitorix;
use RRDs;
use Exporter 'import';
our @EXPORT = qw(kern_init kern_update kern_cgi);
sub kern_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
eval {
RRDs::create($rrd,
"--step=60",
"DS:kern_user:GAUGE:120:0:100",
"DS:kern_nice:GAUGE:120:0:100",
"DS:kern_sys:GAUGE:120:0:100",
"DS:kern_idle:GAUGE:120:0:100",
"DS:kern_iow:GAUGE:120:0:100",
"DS:kern_irq:GAUGE:120:0:100",
"DS:kern_sirq:GAUGE:120:0:100",
"DS:kern_steal:GAUGE:120:0:100",
"DS:kern_guest:GAUGE:120:0:100",
"DS:kern_cs:COUNTER:120:0:U",
"DS:kern_dentry:GAUGE:120:0:100",
"DS:kern_file:GAUGE:120:0:100",
"DS:kern_inode:GAUGE:120:0:100",
"DS:kern_forks:COUNTER:120:0:U",
"DS:kern_vforks:COUNTER:120:0:U",
"DS:kern_val03:GAUGE:120:0:100",
"DS:kern_val04:GAUGE:120:0:100",
"DS:kern_val05:GAUGE:120:0:100",
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
$config->{kern_hist} = ();
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub kern_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $user;
my $nice;
my $sys;
my $idle;
my $iow;
my $irq;
my $sirq;
my $steal;
my $guest;
my $cs = "U";
my $dentry;
my $file;
my $inode;
my $forks = "U";
my $vforks = "U";
my $val03 = 0;
my $val04 = 0;
my $val05 = 0;
my $lastuser = 0;
my $lastnice = 0;
my $lastsys = 0;
my $lastidle = 0;
my $lastiow = 0;
my $lastirq = 0;
my $lastsirq = 0;
my $laststeal = 0;
my $lastguest = 0;
my $rrdata = "N";
if($config->{kern_hist}->{kernel}) {
(undef, $lastuser, $lastnice, $lastsys, $lastidle, $lastiow, $lastirq, $lastsirq, $laststeal, $lastguest) = split(' ', $config->{kern_hist}->{kernel});
}
if($config->{os} eq "Linux") {
open(IN, "/proc/stat");
while(<IN>) {
if(/^cpu /) {
(undef, $user, $nice, $sys, $idle, $iow, $irq, $sirq, $steal, $guest) = split(' ', $_);
$config->{kern_hist}->{kernel} = $_;
next;
}
if(/^ctxt (\d+)$/) {
# avoid initial spike
$cs = int($1) unless !$config->{kern_hist}->{cs};
$config->{kern_hist}->{cs} = int($1) unless $config->{kern_hist}->{cs};
next;
}
if(/^processes (\d+)$/) {
# avoid initial spike
$forks = int($1) unless !$config->{kern_hist}->{forks};
$config->{kern_hist}->{forks} = int($1) unless $config->{kern_hist}->{forks};
$vforks = 0;
last;
}
}
close(IN);
open(IN, "/proc/sys/fs/dentry-state");
while(<IN>) {
if(/^(\d+)\s+(\d+)\s+/) {
$dentry = ($1 * 100) / ($1 + $2);
}
}
close(IN);
open(IN, "/proc/sys/fs/file-nr");
while(<IN>) {
if(/^(\d+)\s+\d+\s+(\d+)$/) {
$file = ($1 * 100) / $2;
}
}
close(IN);
open(IN, "/proc/sys/fs/inode-nr");
while(<IN>) {
if(/^(\d+)\s+(\d+)$/) {
$inode = ($1 * 100) / ($1 + $2);
}
}
close(IN);
} elsif($config->{os} eq "FreeBSD") {
my $max;
my $num;
my $data;
my $cptime = `sysctl -n kern.cp_time`;
chomp($cptime);
my @tmp = split(' ', $cptime);
($user, $nice, $sys, $iow, $idle) = @tmp;
$config->{kern_hist}->{kernel} = join(' ', "cpu", $user, $nice, $sys, $idle, $iow);
$data = `sysctl -n vm.stats.sys.v_swtch`;
chomp($data);
$cs = int($data) unless !$config->{kern_hist}->{cs};
$config->{kern_hist}->{cs} = int($data) unless $config->{kern_hist}->{cs};
$data = `sysctl -n vm.stats.vm.v_forks`;
chomp($data);
$forks = int($data) unless !$config->{kern_hist}->{forks};
$config->{kern_hist}->{forks} = int($data) unless $config->{kern_hist}->{forks};
$data = `sysctl -n vm.stats.vm.v_vforks`;
chomp($data);
$vforks = int($data) unless !$config->{kern_hist}->{vforks};
$config->{kern_hist}->{vforks} = int($data) unless $config->{kern_hist}->{vforks};
$max = `sysctl -n kern.maxfiles`;
chomp($max);
$num = `sysctl -n kern.openfiles`;
chomp($num);
$file = ($num * 100) / $max;
$max = `sysctl -n kern.maxvnodes`;
chomp($max);
$num = `sysctl -n vfs.numvnodes`;
chomp($num);
$inode = ($num * 100) / $max;
} elsif($config->{os} eq "OpenBSD") {
my $max;
my $num;
my $data;
my $cptime = `sysctl -n kern.cp_time`;
chomp($cptime);
my @tmp = split(',', $cptime);
($user, $nice, $sys, $iow, $idle) = @tmp;
$config->{kern_hist}->{kernel} = join(' ', "cpu", $user, $nice, $sys, $idle, $iow);
open(IN, "vmstat -s |");
while(<IN>) {
if(/^\s*(\d+) cpu context switches$/) {
$cs = int($1) unless !$config->{kern_hist}->{cs};
$config->{kern_hist}->{cs} = int($1) unless $config->{kern_hist}->{cs};
last;
}
}
close(IN);
$data = `sysctl -n kern.forkstat.forks`;
chomp($data);
$forks = int($data) unless !$config->{kern_hist}->{forks};
$config->{kern_hist}->{forks} = int($data) unless $config->{kern_hist}->{forks};
$data = `sysctl -n kern.forkstat.vforks`;
chomp($data);
$vforks = int($data) unless !$config->{kern_hist}->{vforks};
$config->{kern_hist}->{vforks} = int($data) unless $config->{kern_hist}->{vforks};
$max = `sysctl -n kern.maxfiles`;
chomp($max);
$num = `sysctl -n kern.nfiles`;
chomp($num);
$file = ($num * 100) / $max;
$max = `sysctl -n kern.maxvnodes`;
chomp($max);
$data = `sysctl -n kern.malloc.kmemstat.vnodes`;
($num) = ($data =~ m/^\(inuse = (\d+), /);
$inode = ($num * 100) / $max;
} elsif($config->{os} eq "NetBSD") {
my $max;
my $num;
my $data;
my $cptime = `sysctl -n kern.cp_time`;
chomp($cptime);
my @tmp = ($cptime =~ m/user = (\d+), nice = (\d+), sys = (\d+), intr = (\d+), idle = (\d+)/);
($user, $nice, $sys, $iow, $idle) = @tmp;
$config->{kern_hist}->{kernel} = join(' ', "cpu", $user, $nice, $sys, $idle, $iow);
open(IN, "vmstat -s |");
while(<IN>) {
if(/^\s*(\d+) CPU context switches$/) {
$cs = int($1) unless !$config->{kern_hist}->{cs};
$config->{kern_hist}->{cs} = int($1) unless $config->{kern_hist}->{cs};
next;
}
if(/^\s*(\d+) forks total$/) {
$forks = int($1) unless !$config->{kern_hist}->{forks};
$config->{kern_hist}->{forks} = int($1) unless $config->{kern_hist}->{forks};
next;
}
}
close(IN);
$vforks = 0;
open(IN, "pstat -T |");
while(<IN>) {
if(/^(\d+)\/(\d+) files$/) {
$file = ($1 * 100) / $2;
}
}
close(IN);
$inode = 0;
}
# Linux 2.4, early Linux 2.6 versions and other systems don't have
# these values.
$iow = 0 unless $iow;
$irq = 0 unless $irq;
$sirq = 0 unless $sirq;
$steal = 0 unless $sirq;
$guest = 0 unless $guest;
$lastiow = 0 unless $lastiow;
$lastirq = 0 unless $lastirq;
$lastsirq = 0 unless $lastsirq;
$laststeal = 0 unless $lastsirq;
$lastguest = 0 unless $lastguest;
if($user >= $lastuser && $nice >= $lastnice && $sys >= $lastsys && $idle >= $lastidle && $iow >= $lastiow && $irq >= $lastirq && $sirq >= $lastsirq && $steal >= $laststeal && $guest >= $lastguest) {
my $user_ = $user - $lastuser;
my $nice_ = $nice - $lastnice;
my $sys_ = $sys - $lastsys;
my $idle_ = $idle - $lastidle;
my $iow_ = $iow - $lastiow;
my $irq_ = $irq - $lastirq;
my $sirq_ = $sirq - $lastsirq;
my $steal_ = $steal - $laststeal;
my $guest_ = $guest - $lastguest;
my $total = $user_ + $nice_ + $sys_ + $idle_ + $iow_ + $irq_ + $sirq_ + $steal_ + $guest_;
$user = ($user_ * 100) / $total;
$nice = ($nice_ * 100) / $total;
$sys = ($sys_ * 100) / $total;
$idle = ($idle_ * 100) / $total;
$iow = ($iow_ * 100) / $total;
$irq = ($irq_ * 100) / $total;
$sirq = ($sirq_ * 100) / $total;
$steal = ($steal_ * 100) / $total;
$guest = ($guest_ * 100) / $total;
} else {
$user = "nan";
$nice = "nan";
$sys = "nan";
$idle = "nan";
$iow = "nan";
$irq = "nan";
$sirq = "nan";
$steal = "nan";
$guest = "nan";
}
$rrdata .= ":$user:$nice:$sys:$idle:$iow:$irq:$sirq:$steal:$guest:$cs:$dentry:$file:$inode:$forks:$vforks:$val03:$val04:$val05";
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub kern_cgi {
my ($package, $config, $cgi) = @_;
my $kern = $config->{kern};
my @rigid = split(',', $kern->{rigid});
my @limit = split(',', $kern->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @tmp;
my @tmpz;
my $vlabel;
my $n;
my $err;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print(" Kernel usage VFS usage\n");
print("Time User Nice Sys Idle I/Ow IRQ sIRQ Steal Guest Ctxt.Sw Forks VForks dentry file inode\n");
print("------------------------------------------------------------------------------------------------------------------\n");
my $line;
my @row;
my $time;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
my ($usr, $nic, $sys, $idle, $iow, $irq, $sirq, $steal, $guest, $cs, $dentry, $file, $inode, $forks, $vforks) = @$line;
@row = ($usr, $nic, $sys, $idle, $iow, $irq, $sirq, $steal, $guest, $cs, $forks, $vforks, $dentry, $file, $inode);
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc} %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %7d %6d %6d %4.1f%% %4.1f%% %4.1f%% \n", $time, @row);
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
my $PNG1 = $u . $package . "1." . $tf->{when} . ".png";
my $PNG2 = $u . $package . "2." . $tf->{when} . ".png";
my $PNG3 = $u . $package . "3." . $tf->{when} . ".png";
my $PNG1z = $u . $package . "1z." . $tf->{when} . ".png";
my $PNG2z = $u . $package . "2z." . $tf->{when} . ".png";
my $PNG3z = $u . $package . "3z." . $tf->{when} . ".png";
unlink ("$PNG_DIR" . "$PNG1",
"$PNG_DIR" . "$PNG2",
"$PNG_DIR" . "$PNG3");
if(lc($config->{enable_zoom}) eq "y") {
unlink ("$PNG_DIR" . "$PNG1z",
"$PNG_DIR" . "$PNG2z",
"$PNG_DIR" . "$PNG3z");
}
if($title) {
main::graph_header($title, 2);
}
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
if(lc($kern->{graph_mode}) eq "r") {
$vlabel = "Percent (%)";
if(lc($kern->{list}->{user}) eq "y") {
push(@tmp, "AREA:user#4444EE:user");
push(@tmpz, "AREA:user#4444EE:user");
push(@tmp, "GPRINT:user:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:user:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:user:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:user:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{nice}) eq "y") {
push(@tmp, "AREA:nice#EEEE44:nice");
push(@tmpz, "AREA:nice#EEEE44:nice");
push(@tmp, "GPRINT:nice:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{sys}) eq "y") {
push(@tmp, "AREA:sys#44EEEE:system");
push(@tmpz, "AREA:sys#44EEEE:system");
push(@tmp, "GPRINT:sys:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{iow}) eq "y") {
push(@tmp, "AREA:iow#EE44EE:I/O wait");
push(@tmpz, "AREA:iow#EE44EE:I/O wait");
push(@tmp, "GPRINT:iow:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:MAX: Max\\: %4.1lf%%\\n");
}
if($config->{os} eq "Linux") {
if(lc($kern->{list}->{irq}) eq "y") {
push(@tmp, "AREA:irq#888888:IRQ");
push(@tmpz, "AREA:irq#888888:IRQ");
push(@tmp, "GPRINT:irq:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{sirq}) eq "y") {
push(@tmp, "AREA:sirq#E29136:softIRQ");
push(@tmpz, "AREA:sirq#E29136:softIRQ");
push(@tmp, "GPRINT:sirq:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{steal}) eq "y") {
push(@tmp, "AREA:steal#44EE44:steal");
push(@tmpz, "AREA:steal#44EE44:steal");
push(@tmp, "GPRINT:steal:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{guest}) eq "y") {
push(@tmp, "AREA:guest#448844:guest");
push(@tmpz, "AREA:guest#448844:guest");
push(@tmp, "GPRINT:guest:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:MAX: Max\\: %4.1lf%%\\n");
}
push(@tmp, "LINE1:guest#1F881F") unless lc($kern->{list}->{guest} ne "y");
push(@tmpz, "LINE1:guest#1F881F") unless lc($kern->{list}->{guest} ne "y");
push(@tmp, "LINE1:steal#00EE00") unless lc($kern->{list}->{steal} ne "y");
push(@tmpz, "LINE1:steal#00EE00") unless lc($kern->{list}->{steal} ne "y");
push(@tmp, "LINE1:sirq#D86612") unless lc($kern->{list}->{sirq} ne "y");
push(@tmpz, "LINE1:sirq#D86612") unless lc($kern->{list}->{sirq} ne "y");
push(@tmp, "LINE1:irq#CCCCCC") unless lc($kern->{list}->{irq} ne "y");
push(@tmpz, "LINE1:irq#CCCCCC") unless lc($kern->{list}->{irq} ne "y");
}
push(@tmp, "LINE1:iow#EE00EE") unless lc($kern->{list}->{iow} ne "y");
push(@tmpz, "LINE1:iow#EE00EE") unless lc($kern->{list}->{iow} ne "y");
push(@tmp, "LINE1:sys#00EEEE") unless lc($kern->{list}->{sys} ne "y");
push(@tmpz, "LINE1:sys#00EEEE") unless lc($kern->{list}->{sys} ne "y");
push(@tmp, "LINE1:nice#EEEE00") unless lc($kern->{list}->{nice} ne "y");
push(@tmpz, "LINE1:nice#EEEE00") unless lc($kern->{list}->{nice} ne "y");
push(@tmp, "LINE1:user#0000EE") unless lc($kern->{list}->{user} ne "y");
push(@tmpz, "LINE1:user#0000EE") unless lc($kern->{list}->{user} ne "y");
} else {
$vlabel = "Stacked Percent (%)";
push(@tmp, "CDEF:s_nice=user,nice,+");
push(@tmpz, "CDEF:s_nice=user,nice,+");
push(@tmp, "CDEF:s_sys=s_nice,sys,+");
push(@tmpz, "CDEF:s_sys=s_nice,sys,+");
push(@tmp, "CDEF:s_iow=s_sys,iow,+");
push(@tmpz, "CDEF:s_iow=s_sys,iow,+");
if($config->{os} eq "Linux") {
push(@tmp, "CDEF:s_irq=s_iow,irq,+");
push(@tmpz, "CDEF:s_irq=s_iow,irq,+");
push(@tmp, "CDEF:s_sirq=s_irq,sirq,+");
push(@tmpz, "CDEF:s_sirq=s_irq,sirq,+");
push(@tmp, "CDEF:s_steal=s_sirq,steal,+");
push(@tmpz, "CDEF:s_steal=s_sirq,steal,+");
push(@tmp, "CDEF:s_guest=s_steal,guest,+");
push(@tmpz, "CDEF:s_guest=s_steal,guest,+");
if(lc($kern->{list}->{guest}) eq "y") {
push(@tmp, "AREA:s_guest#448844:guest");
push(@tmpz, "AREA:s_guest#448844:guest");
push(@tmp, "GPRINT:guest:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{steal}) eq "y") {
push(@tmp, "AREA:s_steal#44EE44:steal");
push(@tmpz, "AREA:s_steal#44EE44:steal");
push(@tmp, "GPRINT:steal:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{sirq}) eq "y") {
push(@tmp, "AREA:s_sirq#E29136:softIRQ");
push(@tmpz, "AREA:s_sirq#E29136:softIRQ");
push(@tmp, "GPRINT:sirq:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{irq}) eq "y") {
push(@tmp, "AREA:s_irq#888888:IRQ");
push(@tmpz, "AREA:s_irq#888888:IRQ");
push(@tmp, "GPRINT:irq:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{iow}) eq "y") {
push(@tmp, "AREA:s_iow#EE44EE:I/O wait");
push(@tmpz, "AREA:s_iow#EE44EE:I/O wait");
push(@tmp, "GPRINT:iow:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{sys}) eq "y") {
push(@tmp, "AREA:s_sys#44EEEE:system");
push(@tmpz, "AREA:s_sys#44EEEE:system");
push(@tmp, "GPRINT:sys:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{nice}) eq "y") {
push(@tmp, "AREA:s_nice#EEEE44:nice");
push(@tmpz, "AREA:s_nice#EEEE44:nice");
push(@tmp, "GPRINT:nice:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:MAX: Max\\: %4.1lf%%\\n");
}
if(lc($kern->{list}->{user}) eq "y") {
push(@tmp, "AREA:user#4444EE:user");
push(@tmpz, "AREA:user#4444EE:user");
push(@tmp, "GPRINT:user:LAST: Current\\: %4.1lf%%");
push(@tmp, "GPRINT:user:AVERAGE: Average\\: %4.1lf%%");
push(@tmp, "GPRINT:user:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:user:MAX: Max\\: %4.1lf%%\\n");
}
if($config->{os} eq "Linux") {
push(@tmp, "LINE1:s_guest#1F881F");
push(@tmpz, "LINE1:s_guest#1F881F");
push(@tmp, "LINE1:s_steal#00EE00");
push(@tmpz, "LINE1:s_steal#00EE00");
push(@tmp, "LINE1:s_sirq#D86612");
push(@tmpz, "LINE1:s_sirq#D86612");
push(@tmp, "LINE1:s_irq#CCCCCC");
push(@tmpz, "LINE1:s_irq#CCCCCC");
}
push(@tmp, "LINE1:s_iow#EE00EE");
push(@tmpz, "LINE1:s_iow#EE00EE");
push(@tmp, "LINE1:s_sys#00EEEE");
push(@tmpz, "LINE1:s_sys#00EEEE");
push(@tmp, "LINE1:s_nice#EEEE00");
push(@tmpz, "LINE1:s_nice#EEEE00");
push(@tmp, "LINE1:user#0000EE");
push(@tmpz, "LINE1:user#0000EE");
}
if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) {
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
if($title) {
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG1",
"--title=$config->{graphs}->{_kern1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:user=$rrd:kern_user:AVERAGE",
"DEF:nice=$rrd:kern_nice:AVERAGE",
"DEF:sys=$rrd:kern_sys:AVERAGE",
"DEF:iow=$rrd:kern_iow:AVERAGE",
"DEF:irq=$rrd:kern_irq:AVERAGE",
"DEF:sirq=$rrd:kern_sirq:AVERAGE",
"DEF:steal=$rrd:kern_steal:AVERAGE",
"DEF:guest=$rrd:kern_guest:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG1z",
"--title=$config->{graphs}->{_kern1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:user=$rrd:kern_user:AVERAGE",
"DEF:nice=$rrd:kern_nice:AVERAGE",
"DEF:sys=$rrd:kern_sys:AVERAGE",
"DEF:iow=$rrd:kern_iow:AVERAGE",
"DEF:irq=$rrd:kern_irq:AVERAGE",
"DEF:sirq=$rrd:kern_sirq:AVERAGE",
"DEF:steal=$rrd:kern_steal:AVERAGE",
"DEF:guest=$rrd:kern_guest:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /kern1/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG1z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG1z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:cs#44AAEE:Context switches");
push(@tmpz, "AREA:cs#44AAEE:Context switches");
push(@tmp, "GPRINT:cs:LAST: Current\\: %6.0lf\\n");
push(@tmp, "AREA:forks#4444EE:Forks");
push(@tmpz, "AREA:forks#4444EE:Forks");
push(@tmp, "GPRINT:forks:LAST: Current\\: %6.0lf\\n");
push(@tmp, "LINE1:cs#00EEEE");
push(@tmp, "LINE1:forks#0000EE");
push(@tmpz, "LINE1:cs#00EEEE");
push(@tmpz, "LINE1:forks#0000EE");
if($config->{os} eq "FreeBSD" || $config->{os} eq "OpenBSD") {
push(@tmp, "AREA:vforks#EE4444:VForks");
push(@tmpz, "AREA:vforks#EE4444:VForks");
push(@tmp, "GPRINT:vforks:LAST: Current\\: %6.0lf\\n");
push(@tmp, "LINE1:vforks#EE0000");
push(@tmpz, "LINE1:vforks#EE0000");
}
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG2",
"--title=$config->{graphs}->{_kern2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=CS & forks/s",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:cs=$rrd:kern_cs:AVERAGE",
"DEF:forks=$rrd:kern_forks:AVERAGE",
"DEF:vforks=$rrd:kern_vforks:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG2z",
"--title=$config->{graphs}->{_kern2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=CS & forks/s",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:cs=$rrd:kern_cs:AVERAGE",
"DEF:forks=$rrd:kern_forks:AVERAGE",
"DEF:vforks=$rrd:kern_vforks:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /kern2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG2z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG2z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "'>\n");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:inode#4444EE:inode");
push(@tmpz, "AREA:inode#4444EE:inode");
push(@tmp, "GPRINT:inode:LAST: Current\\: %4.1lf%%\\n");
if($config->{os} eq "Linux") {
push(@tmp, "AREA:dentry#EEEE44:dentry");
push(@tmpz, "AREA:dentry#EEEE44:dentry");
push(@tmp, "GPRINT:dentry:LAST: Current\\: %4.1lf%%\\n");
}
push(@tmp, "AREA:file#EE44EE:file");
push(@tmpz, "AREA:file#EE44EE:file");
push(@tmp, "GPRINT:file:LAST: Current\\: %4.1lf%%\\n");
push(@tmp, "LINE2:inode#0000EE");
push(@tmpz, "LINE2:inode#0000EE");
if($config->{os} eq "Linux") {
push(@tmp, "LINE2:dentry#EEEE00");
push(@tmpz, "LINE2:dentry#EEEE00");
}
push(@tmp, "LINE2:file#EE00EE");
push(@tmpz, "LINE2:file#EE00EE");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG3",
"--title=$config->{graphs}->{_kern3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Percent (%)",
"--width=$width",
"--height=$height",
"--upper-limit=100",
"--lower-limit=0",
"--rigid",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:dentry=$rrd:kern_dentry:AVERAGE",
"DEF:file=$rrd:kern_file:AVERAGE",
"DEF:inode=$rrd:kern_inode:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG3z",
"--title=$config->{graphs}->{_kern3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Percent (%)",
"--width=$width",
"--height=$height",
"--upper-limit=100",
"--lower-limit=0",
"--rigid",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:dentry=$rrd:kern_dentry:AVERAGE",
"DEF:file=$rrd:kern_file:AVERAGE",
"DEF:inode=$rrd:kern_inode:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /kern3/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG3z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG3z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
1;

575
lib/lighttpd.pm Normal file
View File

@ -0,0 +1,575 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package lighttpd;
use strict;
use warnings;
use Monitorix;
use RRDs;
use LWP::UserAgent;
use Exporter 'import';
our @EXPORT = qw(lighttpd_init lighttpd_update lighttpd_cgi);
sub lighttpd_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $lighttpd = $config->{lighttpd};
my $info;
my @ds;
my @tmp;
my $n;
if(!scalar(my @ll = split(',', $lighttpd->{list}))) {
logger("$myself: ERROR: missing or not defined 'list' option.");
return 0;
}
if(-e $rrd) {
$info = RRDs::info($rrd);
for my $key (keys %$info) {
if(index($key, 'ds[') == 0) {
if(index($key, '.type') != -1) {
push(@ds, substr($key, 3, index($key, ']') - 3));
}
}
}
if(scalar(@ds) / 9 != scalar(my @ll = split(',', $lighttpd->{list}))) {
logger("Detected size mismatch between 'list' option (" . scalar(my @ll = split(',', $lighttpd->{list})) . ") and $rrd (" . scalar(@ds) / 9 . "). Resizing it accordingly. All historic data will be lost. Backup file created.");
rename($rrd, "$rrd.bak");
}
}
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
for($n = 0; $n < scalar(my @ll = split(',', $lighttpd->{list})); $n++) {
push(@tmp, "DS:lighttpd" . $n . "_acc:GAUGE:120:0:U");
push(@tmp, "DS:lighttpd" . $n . "_kb:GAUGE:120:0:U");
push(@tmp, "DS:lighttpd" . $n . "_busy:GAUGE:120:0:U");
push(@tmp, "DS:lighttpd" . $n . "_idle:GAUGE:120:0:U");
push(@tmp, "DS:lighttpd" . $n . "_val01:GAUGE:120:0:U");
push(@tmp, "DS:lighttpd" . $n . "_val02:GAUGE:120:0:U");
push(@tmp, "DS:lighttpd" . $n . "_val03:GAUGE:120:0:U");
push(@tmp, "DS:lighttpd" . $n . "_val04:GAUGE:120:0:U");
push(@tmp, "DS:lighttpd" . $n . "_val05:GAUGE:120:0:U");
}
eval {
RRDs::create($rrd,
"--step=60",
@tmp,
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
$config->{lighttpd_hist} = ();
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub lighttpd_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $lighttpd = $config->{lighttpd};
my $str;
my $rrdata = "N";
my $n = 0;
foreach(my @ll = split(',', $lighttpd->{list})) {
my $url = trim($_) . "/server-status?auto";
my $ua = LWP::UserAgent->new(timeout => 30);
my $response = $ua->request(HTTP::Request->new('GET', $url));
my $acc = 0;
my $kb = 0;
my $busy = 0;
my $idle = 0;
foreach(split('\n', $response->content)) {
if(/^Total Accesses:\s+(\d+)$/) {
$str = $n . "acc";
$acc = $1 - ($config->{lighttpd_hist}->{$str} || 0);
$acc = 0 unless $acc != $1;
$acc /= 60;
$config->{lighttpd_hist}->{$str} = $1;
next;
}
if(/^Total kBytes:\s+(\d+)$/) {
$str = $n . "kb";
$kb = $1 - ($config->{lighttpd_hist}->{$str} || 0);
$kb = 0 unless $kb != $1;
$config->{lighttpd_hist}->{$str} = $1;
next;
}
if(/^BusyServers:\s+(\d+)/) {
$busy = int($1);
next;
}
if(/^IdleServers:\s+(\d+)/) {
$idle = int($1);
last;
}
}
$rrdata .= ":$acc:$kb:$busy:$idle:0:0:0:0:0";
$n++;
}
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub lighttpd_cgi {
my ($package, $config, $cgi) = @_;
my $lighttpd = $config->{lighttpd};
my @rigid = split(',', $lighttpd->{rigid});
my @limit = split(',', $lighttpd->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @PNG;
my @PNGz;
my @tmp;
my @tmpz;
my @CDEF;
my $vlabel = "bytes/s";
my $e;
my $e2;
my $n;
my $n2;
my $str;
my $err;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
if(lc($config->{netstats_in_bps}) eq "y") {
$vlabel = "bits/s";
}
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
my $line1;
my $line2;
my $line3;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print(" ");
for($n = 0; $n < scalar(my @ll = split(',', $lighttpd->{list})); $n++) {
$line1 = " ";
$line2 .= " Acceses k$vlabel Busy Idle";
$line3 .= "------------------------------------";
if($line1) {
my $i = length($line1);
printf(sprintf("%${i}s", sprintf("%s", trim($ll[$n]))));
}
}
print("\n");
print("Time$line2\n");
print("----$line3 \n");
my $line;
my @row;
my $time;
my $n2;
my $from;
my $to;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc}", $time);
for($n2 = 0; $n2 < scalar(my @ll = split(',', $lighttpd->{list})); $n2++) {
undef(@row);
$from = $n2 * 9;
$to = $from + 9;
push(@row, @$line[$from..$to]);
printf(" %7d %9d %3d %3d", @row);
}
print("\n");
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
for($n = 0; $n < scalar(my @ll = split(',', $lighttpd->{list})); $n++) {
for($n2 = 1; $n2 <= 3; $n2++) {
$str = $u . $package . $n . $n2 . "." . $tf->{when} . ".png";
push(@PNG, $str);
unlink("$PNG_DIR" . $str);
if(lc($config->{enable_zoom}) eq "y") {
$str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".png";
push(@PNGz, $str);
unlink("$PNG_DIR" . $str);
}
}
}
$e = 0;
foreach my $url (my @ll = split(',', $lighttpd->{list})) {
if($e) {
print(" <br>\n");
}
if($title) {
main::graph_header($title, 2);
}
undef(@riglim);
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
if($title) {
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:lighttpd" . $e . "_idle#4444EE:Idle");
push(@tmp, "GPRINT:lighttpd" . $e . "_idle:LAST: Current\\: %3.0lf");
push(@tmp, "GPRINT:lighttpd" . $e . "_idle:AVERAGE: Average\\: %3.0lf");
push(@tmp, "GPRINT:lighttpd" . $e . "_idle:MIN: Min\\: %3.0lf");
push(@tmp, "GPRINT:lighttpd" . $e . "_idle:MAX: Max\\: %3.0lf\\n");
push(@tmp, "AREA:lighttpd" . $e . "_busy#44EEEE:Busy");
push(@tmp, "GPRINT:lighttpd" . $e . "_busy:LAST: Current\\: %3.0lf");
push(@tmp, "GPRINT:lighttpd" . $e . "_busy:AVERAGE: Average\\: %3.0lf");
push(@tmp, "GPRINT:lighttpd" . $e . "_busy:MIN: Min\\: %3.0lf");
push(@tmp, "GPRINT:lighttpd" . $e . "_busy:MAX: Max\\: %3.0lf\\n");
push(@tmp, "LINE1:lighttpd" . $e . "_idle#0000EE");
push(@tmp, "LINE1:lighttpd" . $e . "_busy#00EEEE");
push(@tmp, "LINE1:lighttpd" . $e . "_tot#EE0000");
push(@tmpz, "AREA:lighttpd" . $e . "_idle#4444EE:Idle");
push(@tmpz, "AREA:lighttpd" . $e . "_busy#44EEEE:Busy");
push(@tmpz, "LINE2:lighttpd" . $e . "_idle#0000EE");
push(@tmpz, "LINE2:lighttpd" . $e . "_busy#00EEEE");
push(@tmpz, "LINE2:lighttpd" . $e . "_tot#EE0000");
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
}
RRDs::graph("$PNG_DIR" . "$PNG[$e * 3]",
"--title=$config->{graphs}->{_lighttpd1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Workers",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:lighttpd" . $e . "_busy=$rrd:lighttpd" . $e . "_busy:AVERAGE",
"DEF:lighttpd" . $e . "_idle=$rrd:lighttpd" . $e . "_idle:AVERAGE",
"CDEF:lighttpd" . $e . "_tot=lighttpd" . $e . "_busy,lighttpd" . $e . "_idle,+",
"COMMENT: \\n",
@tmp,
"COMMENT: \\n",
"COMMENT: \\n");
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$e * 3]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$e * 3]",
"--title=$config->{graphs}->{_lighttpd1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Workers",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:lighttpd" . $e . "_busy=$rrd:lighttpd" . $e . "_busy:AVERAGE",
"DEF:lighttpd" . $e . "_idle=$rrd:lighttpd" . $e . "_idle:AVERAGE",
"CDEF:lighttpd" . $e . "_tot=lighttpd" . $e . "_busy,lighttpd" . $e . "_idle,+",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$e * 3]: $err\n") if $err;
}
$e2 = $e + 1;
if($title || ($silent =~ /imagetag/ && $graph =~ /lighttpd$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@riglim);
if(trim($rigid[1]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
} else {
if(trim($rigid[1]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
undef(@CDEF);
push(@tmp, "AREA:Bytes#44AAEE:KBytes");
push(@tmp, "GPRINT:lighttpd" . $e . "_kb:LAST: Current\\: %6.1lf\\n");
push(@tmp, "LINE1:lighttpd" . $e . "_kb#00EEEE");
push(@tmpz, "AREA:Bytes#44AAEE:Bytes");
push(@tmpz, "LINE1:lighttpd" . $e . "_kb#00EEEE");
if(lc($config->{netstats_in_bps}) eq "y") {
push(@CDEF, "CDEF:Bytes=lighttpd" . $e . "_kb,8,*,1024,*");
} else {
push(@CDEF, "CDEF:Bytes=lighttpd" . $e . "_kb,1024,*");
}
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG[$e * 3 + 1]",
"--title=$config->{graphs}->{_lighttpd2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:lighttpd" . $e . "_kb=$rrd:lighttpd" . $e . "_kb:AVERAGE",
@CDEF,
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$e * 3 + 1]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$e * 3 + 1]",
"--title=$config->{graphs}->{_lighttpd2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:lighttpd" . $e . "_kb=$rrd:lighttpd" . $e . "_kb:AVERAGE",
@CDEF,
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$e * 3 + 1]: $err\n") if $err;
}
$e2 = $e + 2;
if($title || ($silent =~ /imagetag/ && $graph =~ /lighttpd$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 1] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 1] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "'>\n");
}
}
undef(@riglim);
if(trim($rigid[2]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
} else {
if(trim($rigid[2]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:lighttpd" . $e . "_acc#44EE44:Accesses");
push(@tmp, "GPRINT:lighttpd" . $e . "_acc:LAST: Current\\: %5.2lf\\n");
push(@tmp, "LINE1:lighttpd" . $e . "_acc#00EE00");
push(@tmpz, "AREA:lighttpd" . $e . "_acc#44EE44:Accesses");
push(@tmpz, "LINE1:lighttpd" . $e . "_acc#00EE00");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG[$e * 3 + 2]",
"--title=$config->{graphs}->{_lighttpd3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Accesses/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:lighttpd" . $e . "_acc=$rrd:lighttpd" . $e . "_acc:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$e * 3 + 2]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$e * 3 + 2]",
"--title=$config->{graphs}->{_lighttpd3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Accesses/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:lighttpd" . $e . "_acc=$rrd:lighttpd" . $e . "_acc:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$e * 3 + 2]: $err\n") if $err;
}
$e2 = $e + 3;
if($title || ($silent =~ /imagetag/ && $graph =~ /lighttpd$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 2] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 2] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
print(" <tr>\n");
print " <td bgcolor='$colors->{title_bg_color}' colspan='2'>\n";
print " <font face='Verdana, sans-serif' color='$colors->{title_fg_color}'>\n";
print " <font size='-1'>\n";
print " <b style='{color: " . $colors->{title_fg_color} . "}'>&nbsp;&nbsp;" . trim($url) . "<b>\n";
print " </font></font>\n";
print " </td>\n";
print(" </tr>\n");
main::graph_footer();
}
$e++;
}
print(" <br>\n");
return;
}
1;

1040
lib/lmsens.pm Normal file

File diff suppressed because it is too large Load Diff

1139
lib/mail.pm Normal file

File diff suppressed because it is too large Load Diff

1187
lib/mysql.pm Normal file

File diff suppressed because it is too large Load Diff

648
lib/net.pm Normal file
View File

@ -0,0 +1,648 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package net;
use strict;
use warnings;
use Monitorix;
use RRDs;
use Exporter 'import';
our @EXPORT = qw(net_init net_update net_cgi);
sub net_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
eval {
RRDs::create($rrd,
"--step=60",
"DS:net0_bytes_in:COUNTER:120:0:U",
"DS:net0_bytes_out:COUNTER:120:0:U",
"DS:net0_packs_in:COUNTER:120:0:U",
"DS:net0_packs_out:COUNTER:120:0:U",
"DS:net0_error_in:COUNTER:120:0:U",
"DS:net0_error_out:COUNTER:120:0:U",
"DS:net1_bytes_in:COUNTER:120:0:U",
"DS:net1_bytes_out:COUNTER:120:0:U",
"DS:net1_packs_in:COUNTER:120:0:U",
"DS:net1_packs_out:COUNTER:120:0:U",
"DS:net1_error_in:COUNTER:120:0:U",
"DS:net1_error_out:COUNTER:120:0:U",
"DS:net2_bytes_in:COUNTER:120:0:U",
"DS:net2_bytes_out:COUNTER:120:0:U",
"DS:net2_packs_in:COUNTER:120:0:U",
"DS:net2_packs_out:COUNTER:120:0:U",
"DS:net2_error_in:COUNTER:120:0:U",
"DS:net2_error_out:COUNTER:120:0:U",
"DS:net3_bytes_in:COUNTER:120:0:U",
"DS:net3_bytes_out:COUNTER:120:0:U",
"DS:net3_packs_in:COUNTER:120:0:U",
"DS:net3_packs_out:COUNTER:120:0:U",
"DS:net3_error_in:COUNTER:120:0:U",
"DS:net3_error_out:COUNTER:120:0:U",
"DS:net4_bytes_in:COUNTER:120:0:U",
"DS:net4_bytes_out:COUNTER:120:0:U",
"DS:net4_packs_in:COUNTER:120:0:U",
"DS:net4_packs_out:COUNTER:120:0:U",
"DS:net4_error_in:COUNTER:120:0:U",
"DS:net4_error_out:COUNTER:120:0:U",
"DS:net5_bytes_in:COUNTER:120:0:U",
"DS:net5_bytes_out:COUNTER:120:0:U",
"DS:net5_packs_in:COUNTER:120:0:U",
"DS:net5_packs_out:COUNTER:120:0:U",
"DS:net5_error_in:COUNTER:120:0:U",
"DS:net5_error_out:COUNTER:120:0:U",
"DS:net6_bytes_in:COUNTER:120:0:U",
"DS:net6_bytes_out:COUNTER:120:0:U",
"DS:net6_packs_in:COUNTER:120:0:U",
"DS:net6_packs_out:COUNTER:120:0:U",
"DS:net6_error_in:COUNTER:120:0:U",
"DS:net6_error_out:COUNTER:120:0:U",
"DS:net7_bytes_in:COUNTER:120:0:U",
"DS:net7_bytes_out:COUNTER:120:0:U",
"DS:net7_packs_in:COUNTER:120:0:U",
"DS:net7_packs_out:COUNTER:120:0:U",
"DS:net7_error_in:COUNTER:120:0:U",
"DS:net7_error_out:COUNTER:120:0:U",
"DS:net8_bytes_in:COUNTER:120:0:U",
"DS:net8_bytes_out:COUNTER:120:0:U",
"DS:net8_packs_in:COUNTER:120:0:U",
"DS:net8_packs_out:COUNTER:120:0:U",
"DS:net8_error_in:COUNTER:120:0:U",
"DS:net8_error_out:COUNTER:120:0:U",
"DS:net9_bytes_in:COUNTER:120:0:U",
"DS:net9_bytes_out:COUNTER:120:0:U",
"DS:net9_packs_in:COUNTER:120:0:U",
"DS:net9_packs_out:COUNTER:120:0:U",
"DS:net9_error_in:COUNTER:120:0:U",
"DS:net9_error_out:COUNTER:120:0:U",
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub net_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $net = $config->{net};
my @net_bytes_in;
my @net_bytes_out;
my @net_packs_in;
my @net_packs_out;
my @net_error_in;
my @net_error_out;
my $n;
my $rrdata = "N";
for($n = 0; $n < 10 ; $n++) {
$net_bytes_in[$n] = 0;
$net_bytes_out[$n] = 0;
$net_packs_in[$n] = 0;
$net_packs_out[$n] = 0;
$net_error_in[$n] = 0;
$net_error_out[$n] = 0;
if($n < scalar(my @nl = split(',', $net->{list}))) {
$nl[$n] = trim($nl[$n]);
if($config->{os} eq "Linux") {
open(IN, "/proc/net/dev");
while(<IN>) {
my ($dev, $data) = split(':', $_);
if($dev =~ /$nl[$n]/) {
($net_bytes_in[$n], $net_packs_in[$n], $net_error_in[$n], undef, undef, undef, undef, undef, $net_bytes_out[$n], $net_packs_out[$n], $net_error_out[$n]) = split(' ', $data);
last;
}
}
close(IN);
} elsif($config->{os} eq "FreeBSD") {
open(IN, "netstat -nibd |");
while(<IN>) {
if(/Link/ && /$nl[$n]/) {
# Idrop column added in 8.0
if($config->{kernel} > 7.2) {
(undef, undef, undef, undef, $net_packs_in[$n], $net_error_in[$n], undef, $net_bytes_in[$n], $net_packs_out[$n], $net_error_out[$n], $net_bytes_out[$n]) = split(' ', $_);
} else {
(undef, undef, undef, undef, $net_packs_in[$n], $net_error_in[$n], $net_bytes_in[$n], $net_packs_out[$n], $net_error_out[$n], $net_bytes_out[$n]) = split(' ', $_);
}
last;
}
}
close(IN);
} elsif($config->{os} eq "OpenBSD" || $config->{os} eq "NetBSD") {
open(IN, "netstat -nibd |");
while(<IN>) {
if(/Link/ && /^$nl[$n]/) {
(undef, undef, undef, undef, $net_bytes_in[$n], $net_bytes_out[$n]) = split(' ', $_);
$net_packs_in[$n] = 0;
$net_error_in[$n] = 0;
$net_packs_out[$n] = 0;
$net_error_out[$n] = 0;
last;
}
}
close(IN);
}
}
chomp($net_bytes_in[$n],
$net_bytes_out[$n],
$net_packs_in[$n],
$net_packs_out[$n],
$net_error_in[$n],
$net_error_out[$n]);
$rrdata .= ":$net_bytes_in[$n]:$net_bytes_out[$n]:$net_packs_in[$n]:$net_packs_out[$n]:$net_error_in[$n]:$net_error_out[$n]";
}
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub net_cgi {
my ($package, $config, $cgi) = @_;
my $net = $config->{net};
my @rigid = split(',', $net->{rigid});
my @limit = split(',', $net->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my $netname;
my @tmp;
my @tmpz;
my @CDEF;
my $T = "B";
my $vlabel = "bytes/s";
my $n;
my $str;
my $err;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
if(lc($config->{netstats_in_bps}) eq "y") {
$T = "b";
$vlabel = "bits/s";
}
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print(" ");
for($n = 0; $n < scalar(my @nl = split(',', $net->{list})); $n++) {
$nl[$n] = trim($nl[$n]);
my $nd = trim((split(',', $net->{desc}->{$nl[$n]}))[0]);
print(trim($nl[$n]) . " ($nd) ");
}
print("\nTime");
for($n = 0; $n < scalar(my @nl = split(',', $net->{list})); $n++) {
print(" K$T/s_I K$T/s_O Pk/s_I Pk/s_O Er/s_I Er/s_O");
}
print(" \n----");
for($n = 0; $n < scalar(my @nl = split(',', $net->{list})); $n++) {
print("-------------------------------------------------");
}
print " \n";
my $line;
my @row;
my $time;
my $n2;
my $from;
my $to;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc}", $time);
for($n2 = 0; $n2 < scalar(my @nl = split(',', $net->{list})); $n2++) {
$from = $n2 * 6;
$to = $from + 6;
my ($ki, $ko, $pi, $po, $ei, $eo) = @$line[$from..$to];
$ki /= 1024;
$ko /= 1024;
$pi /= 1024;
$po /= 1024;
$ei /= 1024;
$eo /= 1024;
if(lc($config->{netstats_in_bps}) eq "y") {
$ki *= 8;
$ko *= 8;
}
@row = ($ki, $ko, $pi, $po, $ei, $eo);
printf(" %6d %6d %6d %6d %6d %6d", @row);
}
print(" \n");
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
my $PNG1;
my $PNG2;
my $PNG3;
my $PNG1z;
my $PNG2z;
my $PNG3z;
for($n = 0; $n < scalar(my @nl = split(',', $net->{list})); $n++) {
$PNG1 = $u . $package . $n . "1." . $tf->{when} . ".png";
$PNG2 = $u . $package . $n . "2." . $tf->{when} . ".png";
$PNG3 = $u . $package . $n . "3." . $tf->{when} . ".png";
unlink("$PNG_DIR" . $PNG1);
unlink("$PNG_DIR" . $PNG2);
unlink("$PNG_DIR" . $PNG3);
if(lc($config->{enable_zoom}) eq "y") {
$PNG1z = $u . $package . $n . "1z." . $tf->{when} . ".png";
$PNG2z = $u . $package . $n . "2z." . $tf->{when} . ".png";
$PNG3z = $u . $package . $n . "3z." . $tf->{when} . ".png";
unlink("$PNG_DIR" . $PNG1z);
unlink("$PNG_DIR" . $PNG2z);
unlink("$PNG_DIR" . $PNG3z);
}
$nl[$n] = trim($nl[$n]);
my $nd = trim((split(',', $net->{desc}->{$nl[$n]}))[0]);
if($title) {
if($n) {
print(" <br>\n");
}
main::graph_header($nl[$n] . " " . $title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
undef(@riglim);
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
undef(@CDEF);
push(@tmp, "AREA:B_in#44EE44:K$T/s Input");
push(@tmp, "GPRINT:K_in:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:K_in:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:K_in:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:K_in:MAX: Max\\: %5.0lf\\n");
push(@tmp, "AREA:B_out#4444EE:K$T/s Output");
push(@tmp, "GPRINT:K_out:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:K_out:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:K_out:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:K_out:MAX: Max\\: %5.0lf\\n");
push(@tmp, "AREA:B_out#4444EE:");
push(@tmp, "AREA:B_in#44EE44:");
push(@tmp, "LINE1:B_out#0000EE");
push(@tmp, "LINE1:B_in#00EE00");
push(@tmpz, "AREA:B_in#44EE44:Input");
push(@tmpz, "AREA:B_out#4444EE:Output");
push(@tmpz, "AREA:B_out#4444EE:");
push(@tmpz, "AREA:B_in#44EE44:");
push(@tmpz, "LINE1:B_out#0000EE");
push(@tmpz, "LINE1:B_in#00EE00");
if(lc($config->{netstats_in_bps}) eq "y") {
push(@CDEF, "CDEF:B_in=in,8,*");
push(@CDEF, "CDEF:B_out=out,8,*");
} else {
push(@CDEF, "CDEF:B_in=in");
push(@CDEF, "CDEF:B_out=out");
}
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG1",
"--title=$nl[$n] $nd ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:in=$rrd:net" . $n . "_bytes_in:AVERAGE",
"DEF:out=$rrd:net" . $n . "_bytes_out:AVERAGE",
@CDEF,
"CDEF:K_in=B_in,1024,/",
"CDEF:K_out=B_out,1024,/",
"COMMENT: \\n",
@tmp,
"COMMENT: \\n",
"COMMENT: \\n",
);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG1z",
"--title=$nl[$n] $nd ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:in=$rrd:net" . $n . "_bytes_in:AVERAGE",
"DEF:out=$rrd:net" . $n . "_bytes_out:AVERAGE",
@CDEF,
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1z: $err\n") if $err;
}
$netname="net" . $n . "1";
if($title || ($silent =~ /imagetag/ && $graph =~ /$netname/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG1z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG1z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@riglim);
if(trim($rigid[1]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
} else {
if(trim($rigid[1]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:p_in#44EE44:Input");
push(@tmp, "AREA:p_out#4444EE:Output");
push(@tmp, "AREA:p_out#4444EE:");
push(@tmp, "AREA:p_in#44EE44:");
push(@tmp, "LINE1:p_out#0000EE");
push(@tmp, "LINE1:p_in#00EE00");
push(@tmpz, "AREA:p_in#44EE44:Input");
push(@tmpz, "AREA:p_out#4444EE:Output");
push(@tmpz, "AREA:p_out#4444EE:");
push(@tmpz, "AREA:p_in#44EE44:");
push(@tmpz, "LINE1:p_out#0000EE");
push(@tmpz, "LINE1:p_in#00EE00");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG2",
"--title=$nl[$n] $config->{graphs}->{_net2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Packets/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:p_in=$rrd:net" . $n . "_packs_in:AVERAGE",
"DEF:p_out=$rrd:net" . $n . "_packs_out:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG2z",
"--title=$nl[$n] $config->{graphs}->{_net2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Packets/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:p_in=$rrd:net" . $n . "_packs_in:AVERAGE",
"DEF:p_out=$rrd:net" . $n . "_packs_out:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2z: $err\n") if $err;
}
$netname="net" . $n . "2";
if($title || ($silent =~ /imagetag/ && $graph =~ /$netname/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG2z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG2z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "'>\n");
}
}
undef(@riglim);
if(trim($rigid[2]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
} else {
if(trim($rigid[2]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:e_in#44EE44:Input");
push(@tmp, "AREA:e_out#4444EE:Output");
push(@tmp, "AREA:e_out#4444EE:");
push(@tmp, "AREA:e_in#44EE44:");
push(@tmp, "LINE1:e_out#0000EE");
push(@tmp, "LINE1:e_in#00EE00");
push(@tmpz, "AREA:e_in#44EE44:Input");
push(@tmpz, "AREA:e_out#4444EE:Output");
push(@tmpz, "AREA:e_out#4444EE:");
push(@tmpz, "AREA:e_in#44EE44:");
push(@tmpz, "LINE1:e_out#0000EE");
push(@tmpz, "LINE1:e_in#00EE00");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG3",
"--title=$nl[$n] $config->{graphs}->{_net3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Errors/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:e_in=$rrd:net" . $n . "_error_in:AVERAGE",
"DEF:e_out=$rrd:net" . $n . "_error_out:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG3z",
"--title=$nl[$n] $config->{graphs}->{_net3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Errors/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:e_in=$rrd:net" . $n . "_error_in:AVERAGE",
"DEF:e_out=$rrd:net" . $n . "_error_out:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3z: $err\n") if $err;
}
$netname="net" . $n . "3";
if($title || ($silent =~ /imagetag/ && $graph =~ /$netname/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG3z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG3z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
}
print(" <br>\n");
return;
}
1;

879
lib/nfsc.pm Normal file
View File

@ -0,0 +1,879 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package nfsc;
use strict;
use warnings;
use Monitorix;
use RRDs;
use Exporter 'import';
our @EXPORT = qw(nfsc_init nfsc_update nfsc_cgi);
sub nfsc_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) {
logger("$myself is not supported yet by your operating system ($config->{os}).");
return;
}
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
eval {
RRDs::create($rrd,
"--step=60",
"DS:nfsc_0:COUNTER:120:0:U",
"DS:nfsc_1:COUNTER:120:0:U",
"DS:nfsc_2:COUNTER:120:0:U",
"DS:nfsc_3:COUNTER:120:0:U",
"DS:nfsc_4:COUNTER:120:0:U",
"DS:nfsc_5:COUNTER:120:0:U",
"DS:nfsc_6:COUNTER:120:0:U",
"DS:nfsc_7:COUNTER:120:0:U",
"DS:nfsc_8:COUNTER:120:0:U",
"DS:nfsc_9:COUNTER:120:0:U",
"DS:nfsc_10:COUNTER:120:0:U",
"DS:nfsc_11:COUNTER:120:0:U",
"DS:nfsc_12:COUNTER:120:0:U",
"DS:nfsc_13:COUNTER:120:0:U",
"DS:nfsc_14:COUNTER:120:0:U",
"DS:nfsc_15:COUNTER:120:0:U",
"DS:nfsc_16:COUNTER:120:0:U",
"DS:nfsc_17:COUNTER:120:0:U",
"DS:nfsc_18:COUNTER:120:0:U",
"DS:nfsc_19:COUNTER:120:0:U",
"DS:nfsc_20:COUNTER:120:0:U",
"DS:nfsc_21:COUNTER:120:0:U",
"DS:nfsc_22:COUNTER:120:0:U",
"DS:nfsc_23:COUNTER:120:0:U",
"DS:nfsc_24:COUNTER:120:0:U",
"DS:nfsc_25:COUNTER:120:0:U",
"DS:nfsc_26:COUNTER:120:0:U",
"DS:nfsc_27:COUNTER:120:0:U",
"DS:nfsc_28:COUNTER:120:0:U",
"DS:nfsc_29:COUNTER:120:0:U",
"DS:nfsc_30:COUNTER:120:0:U",
"DS:nfsc_31:COUNTER:120:0:U",
"DS:nfsc_32:COUNTER:120:0:U",
"DS:nfsc_33:COUNTER:120:0:U",
"DS:nfsc_34:COUNTER:120:0:U",
"DS:nfsc_35:COUNTER:120:0:U",
"DS:nfsc_36:COUNTER:120:0:U",
"DS:nfsc_37:COUNTER:120:0:U",
"DS:nfsc_38:COUNTER:120:0:U",
"DS:nfsc_39:COUNTER:120:0:U",
"DS:nfsc_40:COUNTER:120:0:U",
"DS:nfsc_41:COUNTER:120:0:U",
"DS:nfsc_42:COUNTER:120:0:U",
"DS:nfsc_43:COUNTER:120:0:U",
"DS:nfsc_44:COUNTER:120:0:U",
"DS:nfsc_45:COUNTER:120:0:U",
"DS:nfsc_46:COUNTER:120:0:U",
"DS:nfsc_47:COUNTER:120:0:U",
"DS:nfsc_48:COUNTER:120:0:U",
"DS:nfsc_49:COUNTER:120:0:U",
"DS:nfsc_rpc_1:COUNTER:120:0:U",
"DS:nfsc_rpc_2:COUNTER:120:0:U",
"DS:nfsc_rpc_3:COUNTER:120:0:U",
"DS:nfsc_rpc_4:COUNTER:120:0:U",
"DS:nfsc_rpc_5:COUNTER:120:0:U",
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub nfsc_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $nfsc = $config->{nfsc};
my @rpc;
my @nfsc;
my $n;
my $rrdata = "N";
if($config->{os} eq "Linux") {
if(open(IN, "/proc/net/rpc/nfs")) {
while(<IN>) {
if(/^rpc\s+(\d+)\s+(\d+)\s+(\d+)$/) {
@rpc = ($1, $2, $3);
}
if(/^proc$nfsc->{version} /) {
my @tmp = split(' ', $_);
(undef, undef, @nfsc) = @tmp;
}
}
close(IN);
} else {
logger("$myself: it doesn't seems you have a NFS client running in this machine.");
return;
}
}
for($n = 0; $n < 50; $n++) {
if(!defined($nfsc[$n])) {
$nfsc[$n] = 0;
}
$rrdata .= ":" . $nfsc[$n];
}
$rrdata .= ":$rpc[0]:$rpc[1]:$rpc[2]:0:0";
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub nfsc_cgi {
my ($package, $config, $cgi) = @_;
my $nfsc = $config->{nfsc};
my @rigid = split(',', $nfsc->{rigid});
my @limit = split(',', $nfsc->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @tmp;
my @tmpz;
my @tmp1;
my @tmp2;
my @tmp1z;
my @tmp2z;
my @DEF;
my $n;
my $err;
my @AC = (
"#FFA500",
"#44EEEE",
"#44EE44",
"#4444EE",
"#448844",
"#EE4444",
"#EE44EE",
"#EEEE44",
"#963C74",
"#CCCCCC",
);
my @LC = (
"#FFA500",
"#00EEEE",
"#00EE00",
"#0000EE",
"#448844",
"#EE0000",
"#EE00EE",
"#EEEE00",
"#B4B444",
"#888888",
);
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
my @nfsv2 = ("null", "getattr", "setattr", "root", "lookup", "readlink", "read", "wrcache", "write", "create", "remove", "rename", "link", "symlink", "mkdir", "rmdir", "readdir", "fsstat");
my @nfsv3 = ("null", "getattr", "setattr", "lookup", "access", "readlink", "read", "write", "create", "mkdir", "symlink", "mknod", "remove", "rmdir", "rename", "link", "readdir", "readdirplus", "fsstat", "fsinfo", "pathconf", "commit");
my @nfscv4 = ("null", "read", "write", "commit", "open", "open_conf", "open_noat", "open_dgrd", "close", "setattr", "fsinfo", "renew", "setclntid", "confirm", "lock", "lockt", "locku", "access", "getattr", "lookup", "lookup_root", "remove", "rename", "link", "symlink", "create", "pathconf", "statfs", "readlink", "readdir", "server_caps", "delegreturn", "getacl", "setacl", "fs_locations", "exchange_id", "create_ses", "destroy_ses", "sequence", "get_lease_t", "reclaim_comp", "layoutget", "layoutcommit", "layoutreturn", "getdevlist", "getdevinfo", "ds_write", "ds_commit");
my @nfsv;
# default version is NFS v3
if($nfsc->{version} eq "2") {
@nfsv = @nfsv2;
} elsif($nfsc->{version} eq "4") {
@nfsv = @nfscv4;
} else {
@nfsv = @nfsv3;
}
$title = !$silent ? $title : "";
$title =~ s/NFS/NFS v$nfsc->{version}/;
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
my $str;
my $line1;
my $line2;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
foreach my $t (@nfsv) {
$str = sprintf("%12s ", $t);
$line1 .= $str;
$line2 .= "-------------";
}
$line1 .= sprintf("%12s %12s %12s", "calls", "retrans", "authrefrsh");
$line2 .= "-------------" . "-------------" . "-------------";
print("Time $line1\n");
print("-----$line2\n");
my $line;
my @row;
my $time;
my $n2;
my @nfs;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
undef($line1);
undef(@row);
(@nfs) = @$line[0..scalar(@nfsv) - 1];
for($n2 = 0; $n2 < scalar(@nfs);$n2++) {
push(@row, $nfs[$n2]);
$line1 .= "%12d ";
}
push(@row, @$line[50..52]);
$line1 .= "%12d %12d %12d ";
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc} $line1\n", $time, @row);
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
my $PNG1 = $u . $package . "1." . $tf->{when} . ".png";
my $PNG2 = $u . $package . "2." . $tf->{when} . ".png";
my $PNG3 = $u . $package . "3." . $tf->{when} . ".png";
my $PNG4 = $u . $package . "4." . $tf->{when} . ".png";
my $PNG5 = $u . $package . "5." . $tf->{when} . ".png";
my $PNG6 = $u . $package . "6." . $tf->{when} . ".png";
my $PNG1z = $u . $package . "1z." . $tf->{when} . ".png";
my $PNG2z = $u . $package . "2z." . $tf->{when} . ".png";
my $PNG3z = $u . $package . "3z." . $tf->{when} . ".png";
my $PNG4z = $u . $package . "4z." . $tf->{when} . ".png";
my $PNG5z = $u . $package . "5z." . $tf->{when} . ".png";
my $PNG6z = $u . $package . "6z." . $tf->{when} . ".png";
unlink ("$PNG_DIR" . "$PNG1",
"$PNG_DIR" . "$PNG2",
"$PNG_DIR" . "$PNG3",
"$PNG_DIR" . "$PNG4",
"$PNG_DIR" . "$PNG5",
"$PNG_DIR" . "$PNG6");
if(lc($config->{enable_zoom}) eq "y") {
unlink ("$PNG_DIR" . "$PNG1z",
"$PNG_DIR" . "$PNG2z",
"$PNG_DIR" . "$PNG3z",
"$PNG_DIR" . "$PNG4z",
"$PNG_DIR" . "$PNG5z",
"$PNG_DIR" . "$PNG6z");
}
if($title) {
main::graph_header($title, 2);
}
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
if($title) {
print(" <tr>\n");
print(" <td valign='top' bgcolor='$colors->{title_bg_color}'>\n");
}
for($n = 0; $n < 10; $n++) {
my $str = trim((split(',', $nfsc->{graph_0}))[$n]) || "";
if(grep { $_ eq $str } @nfsv) {
my ($i) = grep { $nfsv[$_] eq $str } 0..$#nfsv;
push(@DEF, "DEF:nfs_$i=$rrd:nfsc_$i:AVERAGE");
push(@tmp, "LINE1:nfs_$i$AC[$n]:" . sprintf("%-12s", $str));
push(@tmp, "GPRINT:nfs_$i:LAST: Cur\\: %6.1lf");
push(@tmp, "GPRINT:nfs_$i:AVERAGE: Avg\\: %6.1lf");
push(@tmp, "GPRINT:nfs_$i:MIN: Min\\: %6.1lf");
push(@tmp, "GPRINT:nfs_$i:MAX: Max\\: %6.1lf\\n");
push(@tmpz, "LINE2:nfs_$i$AC[$n]:" . sprintf("%-12s", $str));
} else {
push(@tmp, "COMMENT: \\n");
}
}
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG1",
"--title=$config->{graphs}->{_nfsc1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
@DEF,
@tmp,
"COMMENT: \\n");
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG1z",
"--title=$config->{graphs}->{_nfsc1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
@DEF,
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc1/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG1z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG1z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "'>\n");
}
}
undef(@riglim);
if(trim($rigid[1]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
} else {
if(trim($rigid[1]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
undef(@DEF);
for($n = 0; $n < 10; $n++) {
my $str = trim((split(',', $nfsc->{graph_1}))[$n]) || "";
if(grep { $_ eq $str } @nfsv) {
my ($i) = grep { $nfsv[$_] eq $str } 0..$#nfsv;
push(@DEF, "DEF:nfs_$i=$rrd:nfsc_$i:AVERAGE");
push(@tmp, "LINE1:nfs_$i$AC[$n]:" . sprintf("%-12s", $str));
push(@tmp, "GPRINT:nfs_$i:LAST: Cur\\: %6.1lf");
push(@tmp, "GPRINT:nfs_$i:AVERAGE: Avg\\: %6.1lf");
push(@tmp, "GPRINT:nfs_$i:MIN: Min\\: %6.1lf");
push(@tmp, "GPRINT:nfs_$i:MAX: Max\\: %6.1lf\\n");
push(@tmpz, "LINE2:nfs_$i$AC[$n]:" . sprintf("%-12s", $str));
} else {
push(@tmp, "COMMENT: \\n");
}
}
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG2",
"--title=$config->{graphs}->{_nfsc2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
@DEF,
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG2z",
"--title=$config->{graphs}->{_nfsc2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
@DEF,
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG2z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG2z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@riglim);
if(trim($rigid[2]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
} else {
if(trim($rigid[2]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
undef(@tmp1);
undef(@tmp2);
undef(@tmp1z);
undef(@tmp2z);
undef(@DEF);
for($n = 0; $n < 4; $n++) {
my $str = trim((split(',', $nfsc->{graph_2}))[$n]) || "";
if(grep { $_ eq $str } @nfsv) {
my ($i) = grep { $nfsv[$_] eq $str } 0..$#nfsv;
push(@DEF, "DEF:nfs_$i=$rrd:nfsc_$i:AVERAGE");
push(@tmp1, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str));
push(@tmp1, "GPRINT:nfs_$i:LAST: Current\\: %6.1lf\\n");
push(@tmp2, "LINE1:nfs_$i$LC[$n]");
push(@tmp1z, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str));
push(@tmp2z, "LINE1:nfs_$i$LC[$n]");
} else {
push(@tmp1, "COMMENT: \\n");
}
}
@tmp = (@tmp1, @tmp2);
@tmpz = (@tmp1z, @tmp2z);
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG3",
"--title=$config->{graphs}->{_nfsc3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
@DEF,
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG3z",
"--title=$config->{graphs}->{_nfsc3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
@DEF,
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc3/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG3z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG3z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "'>\n");
}
}
undef(@riglim);
if(trim($rigid[3]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[3]));
} else {
if(trim($rigid[3]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[3]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
undef(@tmp1);
undef(@tmp2);
undef(@tmp1z);
undef(@tmp2z);
undef(@DEF);
for($n = 0; $n < 4; $n++) {
my $str = trim((split(',', $nfsc->{graph_3}))[$n]) || "";
if(grep { $_ eq $str } @nfsv) {
my ($i) = grep { $nfsv[$_] eq $str } 0..$#nfsv;
push(@DEF, "DEF:nfs_$i=$rrd:nfsc_$i:AVERAGE");
push(@tmp1, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str));
push(@tmp1, "GPRINT:nfs_$i:LAST: Current\\: %6.1lf\\n");
push(@tmp2, "LINE1:nfs_$i$LC[$n]");
push(@tmp1z, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str));
push(@tmp2z, "LINE1:nfs_$i$LC[$n]");
} else {
push(@tmp1, "COMMENT: \\n");
}
}
@tmp = (@tmp1, @tmp2);
@tmpz = (@tmp1z, @tmp2z);
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG4",
"--title=$config->{graphs}->{_nfsc4} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
@DEF,
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG4: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG4z",
"--title=$config->{graphs}->{_nfsc4} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
@DEF,
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG4z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc4/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG4z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG4 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG4z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG4 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG4 . "'>\n");
}
}
undef(@riglim);
if(trim($rigid[4]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[4]));
} else {
if(trim($rigid[4]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[4]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
undef(@tmp1);
undef(@tmp2);
undef(@tmp1z);
undef(@tmp2z);
undef(@DEF);
for($n = 0; $n < 4; $n++) {
my $str = trim((split(',', $nfsc->{graph_4}))[$n]);
if(grep { $_ eq $str } @nfsv) {
my ($i) = grep { $nfsv[$_] eq $str } 0..$#nfsv;
push(@DEF, "DEF:nfs_$i=$rrd:nfsc_$i:AVERAGE");
push(@tmp1, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str));
push(@tmp1, "GPRINT:nfs_$i:LAST: Current\\: %6.1lf\\n");
push(@tmp2, "LINE1:nfs_$i$LC[$n]");
push(@tmp1z, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str));
push(@tmp2z, "LINE1:nfs_$i$LC[$n]");
} else {
push(@tmp1, "COMMENT: \\n");
}
}
@tmp = (@tmp1, @tmp2);
@tmpz = (@tmp1z, @tmp2z);
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG5",
"--title=$config->{graphs}->{_nfsc5} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
@DEF,
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG5: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG5z",
"--title=$config->{graphs}->{_nfsc5} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
@DEF,
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG5z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc5/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG5z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG5 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG5z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG5 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG5 . "'>\n");
}
}
undef(@riglim);
if(trim($rigid[5]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[5]));
} else {
if(trim($rigid[5]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[5]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:calls#44EEEE:Calls");
push(@tmp, "GPRINT:calls:LAST: Current\\: %7.1lf\\n");
push(@tmp, "AREA:retrans#EEEE44:Retransmissions");
push(@tmp, "GPRINT:retrans:LAST: Current\\: %7.1lf\\n");
push(@tmp, "AREA:authref#EE4444:Auth Refresh");
push(@tmp, "GPRINT:authref:LAST: Current\\: %7.1lf\\n");
push(@tmp, "LINE1:calls#00EEEE");
push(@tmp, "LINE1:retrans#EEEE00");
push(@tmp, "LINE1:authref#EE0000");
push(@tmpz, "AREA:calls#44EEEE:Calls");
push(@tmpz, "AREA:retrans#EEEE44:Retransmissions");
push(@tmpz, "AREA:authref#EE4444:Auth Refresh");
push(@tmpz, "LINE1:calls#00EEEE");
push(@tmpz, "LINE1:retrans#EEEE00");
push(@tmpz, "LINE1:authref#EE0000");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG6",
"--title=$config->{graphs}->{_nfsc6} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:calls=$rrd:nfsc_rpc_1:AVERAGE",
"DEF:retrans=$rrd:nfsc_rpc_2:AVERAGE",
"DEF:authref=$rrd:nfsc_rpc_3:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG6: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG6z",
"--title=$config->{graphs}->{_nfsc6} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:calls=$rrd:nfsc_rpc_1:AVERAGE",
"DEF:retrans=$rrd:nfsc_rpc_2:AVERAGE",
"DEF:authref=$rrd:nfsc_rpc_3:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG6z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc6/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG6z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG6 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG6z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG6 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG6 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
1;

1251
lib/nfss.pm Normal file

File diff suppressed because it is too large Load Diff

626
lib/nginx.pm Normal file
View File

@ -0,0 +1,626 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package nginx;
use strict;
use warnings;
use Monitorix;
use RRDs;
use LWP::UserAgent;
use Exporter 'import';
our @EXPORT = qw(nginx_init nginx_update nginx_cgi);
sub nginx_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $nginx = $config->{nginx};
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
eval {
RRDs::create($rrd,
"--step=60",
"DS:nginx_requests:GAUGE:120:0:U",
"DS:nginx_total:GAUGE:120:0:U",
"DS:nginx_reading:GAUGE:120:0:U",
"DS:nginx_writing:GAUGE:120:0:U",
"DS:nginx_waiting:GAUGE:120:0:U",
"DS:nginx_bytes_in:GAUGE:120:0:U",
"DS:nginx_bytes_out:GAUGE:120:0:U",
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
if(!defined($rrd)) {
logger("$myself: ERROR: undefined 'port' option.");
return 0;
}
if($config->{os} eq "Linux") {
system("iptables -N nginx_IN 2>/dev/null");
system("iptables -I INPUT -p tcp --dport $nginx->{port} -j nginx_IN -c 0 0");
system("iptables -N nginx_OUT 2>/dev/null");
system("iptables -I OUTPUT -p tcp --sport $nginx->{port} -j nginx_OUT -c 0 0");
}
if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) {
system("ipfw delete $nginx->{rule} 2>/dev/null");
system("ipfw -q add $nginx->{rule} count tcp from me $nginx->{port} to any");
system("ipfw -q add $nginx->{rule} count tcp from any to me $nginx->{port}");
}
$config->{nginx_hist} = ();
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub nginx_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $nginx = $config->{nginx};
my $reqs;
my $tot;
my $reads;
my $writes;
my $waits;
my $in;
my $out;
my $val;
my $url = "http://127.0.0.1:" . $nginx->{port} . "/nginx_status";
my $ua = LWP::UserAgent->new(timeout => 30);
my $response = $ua->request(HTTP::Request->new('GET', $url));
my $rrdata = "N";
foreach(split('\n', $response->content)) {
if(/^Active connections:\s+(\d+)\s*/) {
$tot = $1;
next;
}
if(/^\s+(\d+)\s+(\d+)\s+(\d+)\s*/) {
$reqs = $3 - ($config->{nginx_hist}->{'requests'} || 0);
$reqs = 0 unless $reqs != $3;
$config->{nginx_hist}->{'requests'} = $3;
}
if(/^Reading:\s+(\d+).*Writing:\s+(\d+).*Waiting:\s+(\d+)\s*/) {
$reads = $1;
$writes = $2;
$waits = $3;
}
}
if($config->{os} eq "Linux") {
open(IN, "iptables -nxvL INPUT |");
while(<IN>) {
if(/ nginx_IN /) {
(undef, $val) = split(' ', $_);
chomp($val);
$in = $val - ($config->{nginx_hist}->{'in'} || 0);
$in = 0 unless $in != $val;
$config->{nginx_hist}->{'in'} = $val;
$in /= 60;
last;
}
}
close(IN);
open(IN, "iptables -nxvL OUTPUT |");
while(<IN>) {
if(/ nginx_OUT /) {
(undef, $val) = split(' ', $_);
chomp($val);
$out = $val - ($config->{nginx_hist}->{'out'} || 0);
$out = 0 unless $out != $val;
$config->{nginx_hist}->{'out'} = $val;
$out /= 60;
last;
}
}
close(IN);
}
if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) {
open(IN, "ipfw show $nginx->{rule} 2>/dev/null |");
while(<IN>) {
if(/ from any to me dst-port $nginx->{port}$/) {
(undef, undef, $val) = split(' ', $_);
chomp($val);
$in = $val - ($config->{nginx_hist}->{'in'} || 0);
$in = 0 unless $in != $val;
$config->{nginx_hist}->{'in'} = $val;
$in /= 60;
}
if(/ from me $nginx->{port} to any$/) {
(undef, undef, $val) = split(' ', $_);
chomp($val);
$out = $val - ($config->{nginx_hist}->{'out'} || 0);
$out = 0 unless $out != $val;
$config->{nginx_hist}->{'out'} = $val;
$out /= 60;
}
}
close(IN);
}
$rrdata .= ":$reqs:$tot:$reads:$writes:$waits:$in:$out";
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub nginx_cgi {
my ($package, $config, $cgi) = @_;
my $nginx = $config->{nginx};
my @rigid = split(',', $nginx->{rigid});
my @limit = split(',', $nginx->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @warning;
my @tmp;
my @tmpz;
my @CDEF;
my $T = "B";
my $vlabel = "bytes/s";
my $n;
my $err;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
if(lc($config->{netstats_in_bps}) eq "y") {
$T = "b";
$vlabel = "bits/s";
}
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print("Time Total Reading Writing Waiting Requests K$T/s_I K$T/s_O\n");
print("------------------------------------------------------------------ \n");
my $line;
my @row;
my $time;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
my ($req, $tot, $rea, $wri, $wai, $ki, $ko) = @$line;
$ki /= 1024;
$ko /= 1024;
if(lc($config->{netstats_in_bps}) eq "y") {
$ki *= 8;
$ko *= 8;
}
@row = ($tot, $rea, $wri, $wai, $req, $ki, $ko);
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc} %6d %6d %6d %6d %6d %6d %6d\n", $time, @row);
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
my $PNG1 = $u . $package . "1." . $tf->{when} . ".png";
my $PNG2 = $u . $package . "2." . $tf->{when} . ".png";
my $PNG3 = $u . $package . "3." . $tf->{when} . ".png";
my $PNG1z = $u . $package . "1z." . $tf->{when} . ".png";
my $PNG2z = $u . $package . "2z." . $tf->{when} . ".png";
my $PNG3z = $u . $package . "3z." . $tf->{when} . ".png";
unlink ("$PNG_DIR" . "$PNG1",
"$PNG_DIR" . "$PNG2",
"$PNG_DIR" . "$PNG3");
if(lc($config->{enable_zoom}) eq "y") {
unlink ("$PNG_DIR" . "$PNG1z",
"$PNG_DIR" . "$PNG2z",
"$PNG_DIR" . "$PNG3z");
}
if($title) {
main::graph_header($title, 2);
}
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
if($title) {
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
push(@tmp, "AREA:total#44EEEE:Total");
push(@tmp, "GPRINT:total:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:total:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:total:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:total:MAX: Max\\: %5.0lf\\n");
push(@tmp, "AREA:reading#44EE44:Reading");
push(@tmp, "GPRINT:reading:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:reading:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:reading:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:reading:MAX: Max\\: %5.0lf\\n");
push(@tmp, "AREA:writing#4444EE:Writing");
push(@tmp, "GPRINT:writing:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:writing:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:writing:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:writing:MAX: Max\\: %5.0lf\\n");
push(@tmp, "AREA:waiting#EE44EE:Waiting");
push(@tmp, "GPRINT:waiting:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:waiting:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:waiting:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:waiting:MAX: Max\\: %5.0lf\\n");
push(@tmp, "LINE1:total#00EEEE");
push(@tmp, "LINE1:reading#00EE00");
push(@tmp, "LINE1:writing#0000EE");
push(@tmp, "LINE1:waiting#EE00EE");
push(@tmpz, "AREA:total#44EEEE:Total");
push(@tmpz, "AREA:reading#44EE44:Reading");
push(@tmpz, "AREA:writing#4444EE:Writing");
push(@tmpz, "AREA:waiting#EE44EE:Waiting");
push(@tmpz, "LINE1:total#00EEEE");
push(@tmpz, "LINE1:reading#00EE00");
push(@tmpz, "LINE1:writing#0000EE");
push(@tmpz, "LINE1:waiting#EE00EE");
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG1",
"--title=$config->{graphs}->{_nginx1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Connections/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:total=$rrd:nginx_total:AVERAGE",
"DEF:reading=$rrd:nginx_reading:AVERAGE",
"DEF:writing=$rrd:nginx_writing:AVERAGE",
"DEF:waiting=$rrd:nginx_waiting:AVERAGE",
@tmp,
"COMMENT: \\n");
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG1z",
"--title=$config->{graphs}->{_nginx1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Connections/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:total=$rrd:nginx_total:AVERAGE",
"DEF:reading=$rrd:nginx_reading:AVERAGE",
"DEF:writing=$rrd:nginx_writing:AVERAGE",
"DEF:waiting=$rrd:nginx_waiting:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nginx1/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG1z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG1z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@riglim);
if(trim($rigid[1]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
} else {
if(trim($rigid[1]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:requests#44EEEE:Requests");
push(@tmp, "GPRINT:requests:LAST: Current\\: %5.1lf\\n");
push(@tmp, "LINE1:requests#00EEEE");
push(@tmpz, "AREA:requests#44EEEE:Requests");
push(@tmpz, "LINE1:requests#00EEEE");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG2",
"--title=$config->{graphs}->{_nginx2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:requests=$rrd:nginx_requests:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG2z",
"--title=$config->{graphs}->{_nginx2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Requests/s",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:requests=$rrd:nginx_requests:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nginx2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG2z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG2z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "'>\n");
}
}
undef(@warning);
my $pnum;
if($config->{os} eq "Linux") {
open(IN, "netstat -nl --tcp |");
while(<IN>) {
(undef, undef, undef, $pnum) = split(' ', $_);
chomp($pnum);
$pnum =~ s/.*://;
if($pnum eq $nginx->{port}) {
last;
}
}
close(IN);
}
if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) {
open(IN, "netstat -anl -p tcp |");
my $stat;
while(<IN>) {
(undef, undef, undef, $pnum, undef, $stat) = split(' ', $_);
chomp($stat);
if($stat eq "LISTEN") {
chomp($pnum);
($pnum) = ($pnum =~ m/^.*?(\.\d+$)/);
$pnum =~ s/\.//;
if($pnum eq $nginx->{port}) {
last;
}
}
}
close(IN);
}
if($pnum ne $nginx->{port}) {
push(@warning, $colors->{warning_color});
}
undef(@riglim);
if(trim($rigid[2]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
} else {
if(trim($rigid[2]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
undef(@CDEF);
push(@tmp, "AREA:B_in#44EE44:Input");
push(@tmp, "AREA:B_out#4444EE:Output");
push(@tmp, "AREA:B_out#4444EE:");
push(@tmp, "AREA:B_in#44EE44:");
push(@tmp, "LINE1:B_out#0000EE");
push(@tmp, "LINE1:B_in#00EE00");
push(@tmpz, "AREA:B_in#44EE44:Input");
push(@tmpz, "AREA:B_out#4444EE:Output");
push(@tmpz, "AREA:B_out#4444EE:");
push(@tmpz, "AREA:B_in#44EE44:");
push(@tmpz, "LINE1:B_out#0000EE");
push(@tmpz, "LINE1:B_in#00EE00");
if(lc($config->{netstats_in_bps}) eq "y") {
push(@CDEF, "CDEF:B_in=in,8,*");
push(@CDEF, "CDEF:B_out=out,8,*");
} else {
push(@CDEF, "CDEF:B_in=in");
push(@CDEF, "CDEF:B_out=out");
}
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG3",
"--title=$config->{graphs}->{_nginx3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
@warning,
"DEF:in=$rrd:nginx_bytes_in:AVERAGE",
"DEF:out=$rrd:nginx_bytes_out:AVERAGE",
@CDEF,
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG3z",
"--title=$config->{graphs}->{_nginx3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
@warning,
"DEF:in=$rrd:nginx_bytes_in:AVERAGE",
"DEF:out=$rrd:nginx_bytes_out:AVERAGE",
@CDEF,
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nginx3/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG3z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG3z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
1;

601
lib/ntp.pm Normal file
View File

@ -0,0 +1,601 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package ntp;
use strict;
use warnings;
use Monitorix;
use RRDs;
use Exporter 'import';
our @EXPORT = qw(ntp_init ntp_update ntp_cgi);
sub ntp_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $ntp = $config->{ntp};
my $info;
my @ds;
my @tmp;
my $n;
if(-e $rrd) {
$info = RRDs::info($rrd);
for my $key (keys %$info) {
if(index($key, 'ds[') == 0) {
if(index($key, '.type') != -1) {
push(@ds, substr($key, 3, index($key, ']') - 3));
}
}
}
if(scalar(@ds) / 14 != scalar(my @nl = split(',', $ntp->{list}))) {
logger("Detected size mismatch between 'list' (" . scalar(my @nl = split(',', $ntp->{list})) . ") and $rrd (" . scalar(@ds) / 14 . "). Resizing it accordingly. All historic data will be lost. Backup file created.");
rename($rrd, "$rrd.bak");
}
}
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
for($n = 0; $n < scalar(my @nl = split(',', $ntp->{list})); $n++) {
push(@tmp, "DS:ntp" . $n . "_del:GAUGE:120:U:U");
push(@tmp, "DS:ntp" . $n . "_off:GAUGE:120:U:U");
push(@tmp, "DS:ntp" . $n . "_jit:GAUGE:120:U:U");
push(@tmp, "DS:ntp" . $n . "_str:GAUGE:120:0:U");
push(@tmp, "DS:ntp" . $n . "_c01:GAUGE:120:0:U");
push(@tmp, "DS:ntp" . $n . "_c02:GAUGE:120:0:U");
push(@tmp, "DS:ntp" . $n . "_c03:GAUGE:120:0:U");
push(@tmp, "DS:ntp" . $n . "_c04:GAUGE:120:0:U");
push(@tmp, "DS:ntp" . $n . "_c05:GAUGE:120:0:U");
push(@tmp, "DS:ntp" . $n . "_c06:GAUGE:120:0:U");
push(@tmp, "DS:ntp" . $n . "_c07:GAUGE:120:0:U");
push(@tmp, "DS:ntp" . $n . "_c08:GAUGE:120:0:U");
push(@tmp, "DS:ntp" . $n . "_c09:GAUGE:120:0:U");
push(@tmp, "DS:ntp" . $n . "_c10:GAUGE:120:0:U");
}
eval {
RRDs::create($rrd,
"--step=60",
@tmp,
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub ntp_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $ntp = $config->{ntp};
my @data;
my $del;
my $off;
my $jit;
my $str;
my $cod;
my $n;
my $rrdata = "N";
my $e = 0;
foreach my $h (split(',', $ntp->{list})) {
$h = trim($h);
open(IN, "ntpq -pn $h |");
@data = <IN>;
close(IN);
$cod = $str = $del = $off = $jit = 0;
foreach(@data) {
if(/^\*/) {
(undef, $cod, $str, undef, undef, undef, undef, $del, $off, $jit) = split(' ', $_);
$cod =~ s/\.//g;
chomp($jit);
last;
}
}
$del = 0 unless defined($del);
$off = 0 unless defined($off);
$jit = 0 unless defined($jit);
$str = 0 unless defined($str);
$del /= 1000;
$off /= 1000;
$jit /= 1000;
$rrdata .= ":$del:$off:$jit:$str";
my @i = split(',', $ntp->{desc}->{$h});
for($n = 0; $n < 10; $n++) {
if($cod eq trim($i[$n])) {
$rrdata .= ":1";
} else {
$rrdata .= ":0";
}
}
$e++;
}
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub ntp_cgi {
my ($package, $config, $cgi) = @_;
my $ntp = $config->{ntp};
my @rigid = split(',', $ntp->{rigid});
my @limit = split(',', $ntp->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @PNG;
my @PNGz;
my @tmp;
my @tmpz;
my $e;
my $e2;
my $n;
my $n2;
my $str;
my $err;
my @AC = (
"#FFA500",
"#44EEEE",
"#44EE44",
"#4444EE",
"#448844",
"#EE4444",
"#EE44EE",
"#EEEE44",
"#B4B444",
"#444444",
);
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
my $line1;
my $line2;
my $line3;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print(" ");
for($n = 0; $n < scalar(my @nl = split(',', $ntp->{list})); $n++) {
my $l = trim($nl[$n]);
$line1 = " ";
$line2 .= " Delay Offset Jitter Str";
$line3 .= "----------------------------------";
foreach (split(',', $ntp->{desc}->{$l})) {
$line1 .= " ";
$line2 .= sprintf(" %4s", trim($_));
$line3 .= "-----";
}
if($line1) {
my $i = length($line1);
printf(sprintf("%${i}s", sprintf("NTP Server: %s", $l)));
}
}
print("\n");
print("Time$line2\n");
print("----$line3 \n");
my $line;
my @row;
my $time;
my $n2;
my $n3;
my $from;
my $to;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc}", $time);
for($n2 = 0; $n2 < scalar(my @nl = split(',', $ntp->{list})); $n2++) {
my $l = trim($nl[$n2]);
undef(@row);
$from = $n2 * 14;
$to = $from + 4;
push(@row, @$line[$from..$to]);
printf(" %8.3f %8.3f %8.3f %2d ", @row);
for($n3 = 0; $n3 < scalar(my @i = (split(',', $ntp->{desc}->{$l}))); $n3++) {
$from = $n2 * 14 + 4 + $n3;
my ($c) = @$line[$from] || 0;
printf(" %4d", $c);
}
}
print("\n");
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
for($n = 0; $n < scalar(my @nl = split(',', $ntp->{list})); $n++) {
for($n2 = 1; $n2 <= 3; $n2++) {
$str = $u . $package . $n . $n2 . "." . $tf->{when} . ".png";
push(@PNG, $str);
unlink("$PNG_DIR" . $str);
if(lc($config->{enable_zoom}) eq "y") {
$str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".png";
push(@PNGz, $str);
unlink("$PNG_DIR" . $str);
}
}
}
$e = 0;
foreach my $host (split(',', $ntp->{list})) {
$host = trim($host);
if($e) {
print(" <br>\n");
}
if($title) {
main::graph_header($title, 2);
}
undef(@riglim);
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "LINE2:ntp" . $e . "_del#4444EE:Delay");
push(@tmp, "GPRINT:ntp" . $e . "_del" . ":LAST: Current\\:%6.3lf");
push(@tmp, "GPRINT:ntp" . $e . "_del" . ":AVERAGE: Average\\:%6.3lf");
push(@tmp, "GPRINT:ntp" . $e . "_del" . ":MIN: Min\\:%6.3lf");
push(@tmp, "GPRINT:ntp" . $e . "_del" . ":MAX: Max\\:%6.3lf\\n");
push(@tmp, "LINE2:ntp" . $e . "_off#44EEEE:Offset");
push(@tmp, "GPRINT:ntp" . $e . "_off" . ":LAST: Current\\:%6.3lf");
push(@tmp, "GPRINT:ntp" . $e . "_off" . ":AVERAGE: Average\\:%6.3lf");
push(@tmp, "GPRINT:ntp" . $e . "_off" . ":MIN: Min\\:%6.3lf");
push(@tmp, "GPRINT:ntp" . $e . "_off" . ":MAX: Max\\:%6.3lf\\n");
push(@tmp, "LINE2:ntp" . $e . "_jit#EE4444:Jitter");
push(@tmp, "GPRINT:ntp" . $e . "_jit" . ":LAST: Current\\:%6.3lf");
push(@tmp, "GPRINT:ntp" . $e . "_jit" . ":AVERAGE: Average\\:%6.3lf");
push(@tmp, "GPRINT:ntp" . $e . "_jit" . ":MIN: Min\\:%6.3lf");
push(@tmp, "GPRINT:ntp" . $e . "_jit" . ":MAX: Max\\:%6.3lf\\n");
push(@tmpz, "LINE2:ntp" . $e . "_del#4444EE:Delay");
push(@tmpz, "LINE2:ntp" . $e . "_off#44EEEE:Offset");
push(@tmpz, "LINE2:ntp" . $e . "_jit#EE4444:Jitter");
if($title) {
print(" <tr>\n");
print(" <td bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
}
RRDs::graph("$PNG_DIR" . "$PNG[$e * 3]",
"--title=$config->{graphs}->{_ntp1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Seconds",
"--width=$width",
"--height=$height",
@riglim,
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:ntp" . $e . "_del=$rrd:ntp" . $e . "_del:AVERAGE",
"DEF:ntp" . $e . "_off=$rrd:ntp" . $e . "_off:AVERAGE",
"DEF:ntp" . $e . "_jit=$rrd:ntp" . $e . "_jit:AVERAGE",
"COMMENT: \\n",
@tmp,
"COMMENT: \\n",
"COMMENT: \\n",);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$e * 3]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$e * 3]",
"--title=$config->{graphs}->{_ntp1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Seconds",
"--width=$width",
"--height=$height",
@riglim,
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:ntp" . $e . "_del=$rrd:ntp" . $e . "_del:AVERAGE",
"DEF:ntp" . $e . "_off=$rrd:ntp" . $e . "_off:AVERAGE",
"DEF:ntp" . $e . "_jit=$rrd:ntp" . $e . "_jit:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$e * 3]: $err\n") if $err;
}
$e2 = $e + 1;
if($title || ($silent =~ /imagetag/ && $graph =~ /ntp$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3] . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@riglim);
if(trim($rigid[1]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
} else {
if(trim($rigid[1]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "LINE2:ntp" . $e . "_str#44EEEE:Stratum");
push(@tmp, "GPRINT:ntp" . $e . "_str" . ":LAST: Current\\:%2.0lf\\n");
push(@tmpz, "LINE2:ntp" . $e . "_str#44EEEE:Stratum");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
}
RRDs::graph("$PNG_DIR" . $PNG[$e * 3 + 1],
"--title=$config->{graphs}->{_ntp2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Level",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:ntp" . $e . "_str=$rrd:ntp" . $e . "_str:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . $PNG[$e * 3 + 1] . ": $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . $PNGz[$e * 3 + 1],
"--title=$config->{graphs}->{_ntp2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Level",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:ntp" . $e . "_str=$rrd:ntp" . $e . "_str:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . $PNGz[$e * 3 + 1] . ": $err\n") if $err;
}
$e2 = $e + 2;
if($title || ($silent =~ /imagetag/ && $graph =~ /ntp$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 1] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 1] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 1] . "'>\n");
}
}
undef(@riglim);
if(trim($rigid[2]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
} else {
if(trim($rigid[2]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
my @i = split(',', $ntp->{desc}->{$host});
for($n = 0; $n < 10; $n++) {
if(trim($i[$n])) {
$str = sprintf("%-4s", trim($i[$n]));
push(@tmp, "LINE2:ntp" . $e . "_c" . sprintf("%02d", ($n + 1)) . $AC[$n] . ":$str");
push(@tmp, "COMMENT: \\g");
push(@tmpz, "LINE2:ntp" . $e . "_c" . sprintf("%02d", ($n + 1)) . $AC[$n] . ":$str");
if(!(($n + 1) % 5)) {
push(@tmp, ("COMMENT: \\n"));
}
}
}
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
}
RRDs::graph("$PNG_DIR" . $PNG[$e * 3 + 2],
"--title=$config->{graphs}->{_ntp3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Hits",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:ntp" . $e . "_c01=$rrd:ntp" . $e . "_c01:AVERAGE",
"DEF:ntp" . $e . "_c02=$rrd:ntp" . $e . "_c02:AVERAGE",
"DEF:ntp" . $e . "_c03=$rrd:ntp" . $e . "_c03:AVERAGE",
"DEF:ntp" . $e . "_c04=$rrd:ntp" . $e . "_c04:AVERAGE",
"DEF:ntp" . $e . "_c05=$rrd:ntp" . $e . "_c05:AVERAGE",
"DEF:ntp" . $e . "_c06=$rrd:ntp" . $e . "_c06:AVERAGE",
"DEF:ntp" . $e . "_c07=$rrd:ntp" . $e . "_c07:AVERAGE",
"DEF:ntp" . $e . "_c08=$rrd:ntp" . $e . "_c08:AVERAGE",
"DEF:ntp" . $e . "_c09=$rrd:ntp" . $e . "_c09:AVERAGE",
"DEF:ntp" . $e . "_c10=$rrd:ntp" . $e . "_c10:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . $PNG[$e * 3 + 2] . ": $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . $PNGz[$e * 3 + 2],
"--title=$config->{graphs}->{_ntp3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Hits",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:ntp" . $e . "_c01=$rrd:ntp" . $e . "_c01:AVERAGE",
"DEF:ntp" . $e . "_c02=$rrd:ntp" . $e . "_c02:AVERAGE",
"DEF:ntp" . $e . "_c03=$rrd:ntp" . $e . "_c03:AVERAGE",
"DEF:ntp" . $e . "_c04=$rrd:ntp" . $e . "_c04:AVERAGE",
"DEF:ntp" . $e . "_c05=$rrd:ntp" . $e . "_c05:AVERAGE",
"DEF:ntp" . $e . "_c06=$rrd:ntp" . $e . "_c06:AVERAGE",
"DEF:ntp" . $e . "_c07=$rrd:ntp" . $e . "_c07:AVERAGE",
"DEF:ntp" . $e . "_c08=$rrd:ntp" . $e . "_c08:AVERAGE",
"DEF:ntp" . $e . "_c09=$rrd:ntp" . $e . "_c09:AVERAGE",
"DEF:ntp" . $e . "_c10=$rrd:ntp" . $e . "_c10:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . $PNGz[$e * 3 + 2] . ": $err\n") if $err;
}
$e2 = $e + 3;
if($title || ($silent =~ /imagetag/ && $graph =~ /ntp$e2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 2] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$e * 3 + 2] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$e * 3 + 2] . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
print(" <tr>\n");
print " <td bgcolor='$colors->{title_bg_color}' colspan='2'>\n";
print " <font face='Verdana, sans-serif' color='$colors->{title_fg_color}'>\n";
print " <font size='-1'>\n";
print " <b style='{color: " . $colors->{title_fg_color} . "}'>&nbsp;&nbsp;$host<b>\n";
print " </font></font>\n";
print " </td>\n";
print(" </tr>\n");
main::graph_footer();
}
$e++;
}
print(" <br>\n");
return;
}
1;

626
lib/nvidia.pm Normal file
View File

@ -0,0 +1,626 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package nvidia;
use strict;
use warnings;
use Monitorix;
use RRDs;
use Exporter 'import';
our @EXPORT = qw(nvidia_init nvidia_update nvidia_cgi);
sub nvidia_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
eval {
RRDs::create($rrd,
"--step=60",
"DS:nvidia_temp0:GAUGE:120:0:U",
"DS:nvidia_temp1:GAUGE:120:0:U",
"DS:nvidia_temp2:GAUGE:120:0:U",
"DS:nvidia_temp3:GAUGE:120:0:U",
"DS:nvidia_temp4:GAUGE:120:0:U",
"DS:nvidia_temp5:GAUGE:120:0:U",
"DS:nvidia_temp6:GAUGE:120:0:U",
"DS:nvidia_temp7:GAUGE:120:0:U",
"DS:nvidia_temp8:GAUGE:120:0:U",
"DS:nvidia_gpu0:GAUGE:120:0:100",
"DS:nvidia_gpu1:GAUGE:120:0:100",
"DS:nvidia_gpu2:GAUGE:120:0:100",
"DS:nvidia_gpu3:GAUGE:120:0:100",
"DS:nvidia_gpu4:GAUGE:120:0:100",
"DS:nvidia_gpu5:GAUGE:120:0:100",
"DS:nvidia_gpu6:GAUGE:120:0:100",
"DS:nvidia_gpu7:GAUGE:120:0:100",
"DS:nvidia_gpu8:GAUGE:120:0:100",
"DS:nvidia_mem0:GAUGE:120:0:100",
"DS:nvidia_mem1:GAUGE:120:0:100",
"DS:nvidia_mem2:GAUGE:120:0:100",
"DS:nvidia_mem3:GAUGE:120:0:100",
"DS:nvidia_mem4:GAUGE:120:0:100",
"DS:nvidia_mem5:GAUGE:120:0:100",
"DS:nvidia_mem6:GAUGE:120:0:100",
"DS:nvidia_mem7:GAUGE:120:0:100",
"DS:nvidia_mem8:GAUGE:120:0:100",
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub nvidia_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $nvidia = $config->{nvidia};
my @temp;
my @gpu;
my @mem;
my @data;
my $utilization;
my $l;
my $n;
my $rrdata = "N";
for($n = 0; $n < 9; $n++) {
$temp[$n] = 0;
$gpu[$n] = 0;
$mem[$n] = 0;
if($n < $nvidia->{max}) {
($mem[$n], $gpu[$n], $temp[$n]) = split(' ', get_nvidia_data($n));
if(!$temp[$n] && !$gpu[$n] && !$mem[$n]) {
# attempt to get data using the old driver version
$utilization = 0;
open(IN, "nvidia-smi -g $n |");
@data = <IN>;
close(IN);
for($l = 0; $l < scalar(@data); $l++) {
if($data[$l] =~ /Temperature/) {
my (undef, $tmp) = split(':', $data[$l]);
if($tmp eq "\n") {
$l++;
$tmp = $data[$l];
}
my ($value, undef) = split(' ', $tmp);
$value =~ s/[-]/./;
$value =~ s/[^0-9.]//g;
if(int($value) > 0) {
$temp[$n] = int($value);
}
}
if($data[$l] =~ /Utilization/) {
$utilization = 1;
}
if($utilization == 1) {
if($data[$l] =~ /GPU/) {
my (undef, $tmp) = split(':', $data[$l]);
if($tmp eq "\n") {
$l++;
$tmp = $data[$l];
}
my ($value, undef) = split(' ', $tmp);
$value =~ s/[-]/./;
$value =~ s/[^0-9.]//g;
if(int($value) > 0) {
$gpu[$n] = int($value);
}
}
if($data[$l] =~ /Memory/) {
my (undef, $tmp) = split(':', $data[$l]);
if($tmp eq "\n") {
$l++;
$tmp = $data[$l];
}
my ($value, undef) = split(' ', $tmp);
$value =~ s/[-]/./;
$value =~ s/[^0-9.]//g;
if(int($value) > 0) {
$mem[$n] = int($value);
}
}
}
}
}
}
}
for($n = 0; $n < scalar(@temp); $n++) {
$rrdata .= ":$temp[$n]";
}
for($n = 0; $n < scalar(@gpu); $n++) {
$rrdata .= ":$gpu[$n]";
}
for($n = 0; $n < scalar(@mem); $n++) {
$rrdata .= ":$mem[$n]";
}
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub nvidia_cgi {
my ($package, $config, $cgi) = @_;
my $nvidia = $config->{nvidia};
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @tmp;
my @tmpz;
my $n;
my $err;
my @LC = (
"#FFA500",
"#44EEEE",
"#44EE44",
"#4444EE",
"#448844",
"#EE4444",
"#EE44EE",
"#EEEE44",
"#963C74",
);
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
my $line1;
my $line2;
my $line3;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print(" ");
for($n = 0; $n < $nvidia->{max}; $n++) {
print(" NVIDIA card $n");
}
print("\n");
for($n = 0; $n < $nvidia->{max}; $n++) {
$line2 .= " Temp GPU Mem";
$line3 .= "-----------------";
}
print("Time$line2\n");
print("----$line3 \n");
my $line;
my @row;
my $time;
my $n2;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc} ", $time);
undef($line1);
undef(@row);
for($n2 = 0; $n2 < $nvidia->{max}; $n2++) {
push(@row, @$line[$n2]);
push(@row, @$line[$n2 + 9]);
push(@row, @$line[$n2 + 18]);
$line1 .= " %3d %3d%% %3d%%";
}
print(sprintf($line1, @row));
print("\n");
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
my $PNG1 = $u . $package . "1." . $tf->{when} . ".png";
my $PNG2 = $u . $package . "2." . $tf->{when} . ".png";
my $PNG3 = $u . $package . "3." . $tf->{when} . ".png";
my $PNG1z = $u . $package . "1z." . $tf->{when} . ".png";
my $PNG2z = $u . $package . "2z." . $tf->{when} . ".png";
my $PNG3z = $u . $package . "3z." . $tf->{when} . ".png";
unlink ("$PNG_DIR" . "$PNG1",
"$PNG_DIR" . "$PNG2",
"$PNG_DIR" . "$PNG3");
if(lc($config->{enable_zoom}) eq "y") {
unlink ("$PNG_DIR" . "$PNG1z",
"$PNG_DIR" . "$PNG2z",
"$PNG_DIR" . "$PNG3z");
}
if($title) {
main::graph_header($title, 2);
}
for($n = 0; $n < 9; $n++) {
if($n < $nvidia->{max}) {
push(@tmp, "LINE2:temp" . $n . $LC[$n] . ":Card $n");
push(@tmpz, "LINE2:temp" . $n . $LC[$n] . ":Card $n");
push(@tmp, "GPRINT:temp" . $n . ":LAST: Current\\: %2.0lf");
push(@tmp, "GPRINT:temp" . $n . ":AVERAGE: Average\\: %2.0lf");
push(@tmp, "GPRINT:temp" . $n . ":MIN: Min\\: %2.0lf");
push(@tmp, "GPRINT:temp" . $n . ":MAX: Max\\: %2.0lf\\n");
} else {
push(@tmp, "COMMENT: \\n");
}
}
if($title) {
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG1",
"--title=$config->{graphs}->{_nvidia1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Celsius",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:temp0=$rrd:nvidia_temp0:AVERAGE",
"DEF:temp1=$rrd:nvidia_temp1:AVERAGE",
"DEF:temp2=$rrd:nvidia_temp2:AVERAGE",
"DEF:temp3=$rrd:nvidia_temp3:AVERAGE",
"DEF:temp4=$rrd:nvidia_temp4:AVERAGE",
"DEF:temp5=$rrd:nvidia_temp5:AVERAGE",
"DEF:temp6=$rrd:nvidia_temp6:AVERAGE",
"DEF:temp7=$rrd:nvidia_temp7:AVERAGE",
"DEF:temp8=$rrd:nvidia_temp8:AVERAGE",
@tmp,
"COMMENT: \\n",
"COMMENT: \\n");
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG1z",
"--title=$config->{graphs}->{_nvidia1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Celsius",
"--width=$width",
"--height=$height",
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:temp0=$rrd:nvidia_temp0:AVERAGE",
"DEF:temp1=$rrd:nvidia_temp1:AVERAGE",
"DEF:temp2=$rrd:nvidia_temp2:AVERAGE",
"DEF:temp3=$rrd:nvidia_temp3:AVERAGE",
"DEF:temp4=$rrd:nvidia_temp4:AVERAGE",
"DEF:temp5=$rrd:nvidia_temp5:AVERAGE",
"DEF:temp6=$rrd:nvidia_temp6:AVERAGE",
"DEF:temp7=$rrd:nvidia_temp7:AVERAGE",
"DEF:temp8=$rrd:nvidia_temp8:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nvidia1/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG1z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG1z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "LINE2:gpu0#FFA500:Card 0\\g");
push(@tmp, "GPRINT:gpu0:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:gpu3#4444EE:Card 3\\g");
push(@tmp, "GPRINT:gpu3:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:gpu6#EE44EE:Card 6\\g");
push(@tmp, "GPRINT:gpu6:LAST:\\:%3.0lf%%\\n");
push(@tmp, "LINE2:gpu1#44EEEE:Card 1\\g");
push(@tmp, "GPRINT:gpu1:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:gpu4#448844:Card 4\\g");
push(@tmp, "GPRINT:gpu4:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:gpu7#EEEE44:Card 7\\g");
push(@tmp, "GPRINT:gpu7:LAST:\\:%3.0lf%%\\n");
push(@tmp, "LINE2:gpu2#44EE44:Card 2\\g");
push(@tmp, "GPRINT:gpu2:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:gpu5#EE4444:Card 5\\g");
push(@tmp, "GPRINT:gpu5:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:gpu8#963C74:Card 8\\g");
push(@tmp, "GPRINT:gpu8:LAST:\\:%3.0lf%%\\n");
push(@tmpz, "LINE2:gpu0#FFA500:Card 0");
push(@tmpz, "LINE2:gpu3#4444EE:Card 3");
push(@tmpz, "LINE2:gpu6#EE44EE:Card 6");
push(@tmpz, "LINE2:gpu1#44EEEE:Card 1");
push(@tmpz, "LINE2:gpu4#448844:Card 4");
push(@tmpz, "LINE2:gpu7#EEEE44:Card 7");
push(@tmpz, "LINE2:gpu2#44EE44:Card 2");
push(@tmpz, "LINE2:gpu5#EE4444:Card 5");
push(@tmpz, "LINE2:gpu8#963C74:Card 8");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG2",
"--title=$config->{graphs}->{_nvidia2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Percent",
"--width=$width",
"--height=$height",
"--upper-limit=100",
"--lower-limit=0",
"--rigid",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:gpu0=$rrd:nvidia_gpu0:AVERAGE",
"DEF:gpu1=$rrd:nvidia_gpu1:AVERAGE",
"DEF:gpu2=$rrd:nvidia_gpu2:AVERAGE",
"DEF:gpu3=$rrd:nvidia_gpu3:AVERAGE",
"DEF:gpu4=$rrd:nvidia_gpu4:AVERAGE",
"DEF:gpu5=$rrd:nvidia_gpu5:AVERAGE",
"DEF:gpu6=$rrd:nvidia_gpu6:AVERAGE",
"DEF:gpu7=$rrd:nvidia_gpu7:AVERAGE",
"DEF:gpu8=$rrd:nvidia_gpu8:AVERAGE",
"COMMENT: \\n",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG2z",
"--title=$config->{graphs}->{_nvidia2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Percent",
"--width=$width",
"--height=$height",
"--upper-limit=100",
"--lower-limit=0",
"--rigid",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:gpu0=$rrd:nvidia_gpu0:AVERAGE",
"DEF:gpu1=$rrd:nvidia_gpu1:AVERAGE",
"DEF:gpu2=$rrd:nvidia_gpu2:AVERAGE",
"DEF:gpu3=$rrd:nvidia_gpu3:AVERAGE",
"DEF:gpu4=$rrd:nvidia_gpu4:AVERAGE",
"DEF:gpu5=$rrd:nvidia_gpu5:AVERAGE",
"DEF:gpu6=$rrd:nvidia_gpu6:AVERAGE",
"DEF:gpu7=$rrd:nvidia_gpu7:AVERAGE",
"DEF:gpu8=$rrd:nvidia_gpu8:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nvidia2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG2z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG2z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "'>\n");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "LINE2:mem0#FFA500:Card 0\\g");
push(@tmp, "GPRINT:mem0:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:mem3#4444EE:Card 3\\g");
push(@tmp, "GPRINT:mem3:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:mem6#EE44EE:Card 6\\g");
push(@tmp, "GPRINT:mem6:LAST:\\:%3.0lf%%\\n");
push(@tmp, "LINE2:mem1#44EEEE:Card 1\\g");
push(@tmp, "GPRINT:mem1:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:mem4#448844:Card 4\\g");
push(@tmp, "GPRINT:mem4:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:mem7#EEEE44:Card 7\\g");
push(@tmp, "GPRINT:mem7:LAST:\\:%3.0lf%%\\n");
push(@tmp, "LINE2:mem2#44EE44:Card 2\\g");
push(@tmp, "GPRINT:mem2:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:mem5#EE4444:Card 5\\g");
push(@tmp, "GPRINT:mem5:LAST:\\:%3.0lf%%");
push(@tmp, "LINE2:mem8#963C74:Card 8\\g");
push(@tmp, "GPRINT:mem8:LAST:\\:%3.0lf%%\\n");
push(@tmpz, "LINE2:mem0#FFA500:Card 0");
push(@tmpz, "LINE2:mem3#4444EE:Card 3");
push(@tmpz, "LINE2:mem6#EE44EE:Card 6");
push(@tmpz, "LINE2:mem1#44EEEE:Card 1");
push(@tmpz, "LINE2:mem4#448844:Card 4");
push(@tmpz, "LINE2:mem7#EEEE44:Card 7");
push(@tmpz, "LINE2:mem2#44EE44:Card 2");
push(@tmpz, "LINE2:mem5#EE4444:Card 5");
push(@tmpz, "LINE2:mem8#963C74:Card 8");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG3",
"--title=$config->{graphs}->{_nvidia3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Percent",
"--width=$width",
"--height=$height",
"--upper-limit=100",
"--lower-limit=0",
"--rigid",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:mem0=$rrd:nvidia_mem0:AVERAGE",
"DEF:mem1=$rrd:nvidia_mem1:AVERAGE",
"DEF:mem2=$rrd:nvidia_mem2:AVERAGE",
"DEF:mem3=$rrd:nvidia_mem3:AVERAGE",
"DEF:mem4=$rrd:nvidia_mem4:AVERAGE",
"DEF:mem5=$rrd:nvidia_mem5:AVERAGE",
"DEF:mem6=$rrd:nvidia_mem6:AVERAGE",
"DEF:mem7=$rrd:nvidia_mem7:AVERAGE",
"DEF:mem8=$rrd:nvidia_mem8:AVERAGE",
"COMMENT: \\n",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG3z",
"--title=$config->{graphs}->{_nvidia3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Percent",
"--width=$width",
"--height=$height",
"--upper-limit=100",
"--lower-limit=0",
"--rigid",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:mem0=$rrd:nvidia_mem0:AVERAGE",
"DEF:mem1=$rrd:nvidia_mem1:AVERAGE",
"DEF:mem2=$rrd:nvidia_mem2:AVERAGE",
"DEF:mem3=$rrd:nvidia_mem3:AVERAGE",
"DEF:mem4=$rrd:nvidia_mem4:AVERAGE",
"DEF:mem5=$rrd:nvidia_mem5:AVERAGE",
"DEF:mem6=$rrd:nvidia_mem6:AVERAGE",
"DEF:mem7=$rrd:nvidia_mem7:AVERAGE",
"DEF:mem8=$rrd:nvidia_mem8:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /nvidia3/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG3z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG3z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
1;

497
lib/port.pm Normal file
View File

@ -0,0 +1,497 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package port;
use strict;
use warnings;
use Monitorix;
use RRDs;
use POSIX qw(strftime);
use Exporter 'import';
our @EXPORT = qw(port_init port_update port_cgi);
sub port_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $port = $config->{port};
my $info;
my @ds;
my @tmp;
my $n;
if(-e $rrd) {
$info = RRDs::info($rrd);
for my $key (keys %$info) {
if(index($key, 'ds[') == 0) {
if(index($key, '.type') != -1) {
push(@ds, substr($key, 3, index($key, ']') - 3));
}
}
}
if(scalar(@ds) / 2 != $port->{max}) {
logger("Detected size mismatch between 'max = $port->{max}' and $rrd (" . scalar(@ds) / 2 . "). Resizing it accordingly. All historic data will be lost. Backup file created.");
rename($rrd, "$rrd.bak");
}
}
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
for($n = 0; $n < $port->{max}; $n++) {
push(@tmp, "DS:port" . $n . "_in:GAUGE:120:0:U");
push(@tmp, "DS:port" . $n . "_out:GAUGE:120:0:U");
}
eval {
RRDs::create($rrd,
"--step=60",
@tmp,
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
if($config->{os} eq "Linux") {
my $num;
my @line;
# set the iptables rules for each defined port
my @pl = split(',', $port->{list});
for($n = 0; $n < $port->{max}; $n++) {
$pl[$n] = trim($pl[$n]);
if($pl[$n]) {
my $p = lc((split(',', $port->{desc}->{$pl[$n]}))[1]) || "all";
system("iptables -N monitorix_IN_$n 2>/dev/null");
system("iptables -I INPUT -p $p --dport $pl[$n] -j monitorix_IN_$n -c 0 0");
system("iptables -N monitorix_OUT_$n 2>/dev/null");
system("iptables -I OUTPUT -p $p --sport $pl[$n] -j monitorix_OUT_$n -c 0 0");
}
}
}
if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) {
# set the ipfw rules for each defined port
my @pl = split(',', $port->{list});
for($n = 0; $n < $port->{max}; $n++) {
$pl[$n] = trim($pl[$n]);
if($pl[$n]) {
my $p = lc((split(',', $port->{desc}->{$pl[$n]}))[1]) || "all";
system("ipfw -q add $port->{rule} count $p from me $pl[$n] to any");
system("ipfw -q add $port->{rule} count $p from any to me $pl[$n]");
}
}
}
$config->{port_hist_in} = ();
$config->{port_hist_out} = ();
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub port_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $port = $config->{port};
my @in;
my @out;
my $n;
my $rrdata = "N";
if($config->{os} eq "Linux") {
open(IN, "iptables -nxvL INPUT |");
while(<IN>) {
for($n = 0; $n < $port->{max}; $n++) {
$in[$n] = 0 unless $in[$n];
if(/ monitorix_IN_$n /) {
my (undef, $bytes) = split(' ', $_);
chomp($bytes);
$in[$n] = $bytes - ($config->{port_hist_in}[$n] || 0);
$in[$n] = 0 unless $in[$n] != $bytes;
$config->{port_hist_in}[$n] = $bytes;
$in[$n] /= 60;
}
}
}
close(IN);
open(IN, "iptables -nxvL OUTPUT |");
while(<IN>) {
for($n = 0; $n < $port->{max}; $n++) {
$out[$n] = 0 unless $out[$n];
if(/ monitorix_OUT_$n /) {
my (undef, $bytes) = split(' ', $_);
chomp($bytes);
$out[$n] = $bytes - ($config->{port_hist_out}[$n] || 0);
$out[$n] = 0 unless $out[$n] != $bytes;
$config->{port_hist_out}[$n] = $bytes;
$out[$n] /= 60;
}
}
}
close(IN);
}
if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) {
my @pl = split(',', $port->{list});
open(IN, "ipfw show $port->{rule} 2>/dev/null |");
while(<IN>) {
for($n = 0; $n < $port->{max}; $n++) {
$in[$n] = 0 unless $in[$n];
$pl[$n] = trim($pl[$n]);
if(/ from any to me dst-port $pl[$n]$/) {
my (undef, undef, $bytes) = split(' ', $_);
chomp($bytes);
$in[$n] = $bytes;
}
$out[$n] = 0 unless $out[$n];
if(/ from me $pl[$n] to any$/) {
my (undef, undef, $bytes) = split(' ', $_);
chomp($bytes);
$out[$n] = $bytes;
}
}
}
close(IN);
}
for($n = 0; $n < $port->{max}; $n++) {
$rrdata .= ":$in[$n]:$out[$n]";
}
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub port_cgi {
my ($package, $config, $cgi) = @_;
my $port = $config->{port};
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @warning;
my @PNG;
my @PNGz;
my $name;
my @tmp;
my @tmpz;
my @CDEF;
my $T = "B";
my $vlabel = "bytes/s";
my $n;
my $n2;
my $str;
my $err;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
if(lc($config->{netstats_in_bps}) eq "y") {
$T = "b";
$vlabel = "bits/s";
}
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
my $line1;
my $line2;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print(" ");
for($n = 0; $n < $port->{max} && $n < scalar(my @pl = split(',', $port->{list})); $n++) {
$pl[$n] = trim($pl[$n]);
my $pn = trim((split(',', $port->{desc}->{$pl[$n]}))[0]);
printf(" %-5s %-8s", $pl[$n], $pn);
$line1 .= " K$T/s_I K$T/s_O";
$line2 .= "-----------------";
}
print("\n");
print("Time$line1\n");
print("----$line2 \n");
my $line;
my @row;
my $time;
my $n2;
my $from;
my $to;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc} ", $time);
for($n2 = 0; $n2 < $port->{max} && $n2 < scalar(my @pl = split(',', $port->{list})); $n2++) {
$from = $n2 * 2;
$to = $from + 1;
my ($kin, $kout) = @$line[$from..$to];
$kin /= 1024;
$kout /= 1024;
if(lc($config->{netstats_in_bps}) eq "y") {
$kin *= 8;
$kout *= 8;
}
@row = ($kin, $kout);
printf(" %6d %6d ", @row);
}
print("\n");
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
for($n = 0; $n < $port->{max}; $n++) {
$str = $u . $package . $n . "." . $tf->{when} . ".png";
push(@PNG, $str);
unlink("$PNG_DIR" . $str);
if(lc($config->{enable_zoom}) eq "y") {
$str = $u . $package . $n . "z." . $tf->{when} . ".png";
push(@PNGz, $str);
unlink("$PNG_DIR" . $str);
}
}
$n = 0;
while($n < $port->{max} && $n < scalar(my @pl = split(',', $port->{list}))) {
if($title) {
if($n == 0) {
main::graph_header($title, $port->{graphs_per_row});
}
print(" <tr>\n");
}
for($n2 = 0; $n2 < $port->{graphs_per_row}; $n2++) {
last unless ($n < $port->{max} && $n < scalar(@pl));
if($title) {
print(" <td bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
my $pnum;
$pl[$n] = trim($pl[$n]);
my $pn = trim((split(',', $port->{desc}->{$pl[$n]}))[0]);
my $pp = trim((split(',', $port->{desc}->{$pl[$n]}))[1]);
my $prig = trim((split(',', $port->{desc}->{$pl[$n]}))[2]);
my $plim = trim((split(',', $port->{desc}->{$pl[$n]}))[3]);
undef(@riglim);
if(trim($prig) eq 1) {
push(@riglim, "--upper-limit=" . trim($plim));
} else {
if(trim($prig) eq 2) {
push(@riglim, "--upper-limit=" . trim($plim));
push(@riglim, "--rigid");
}
}
undef(@warning);
if($config->{os} eq "Linux") {
open(IN, "netstat -nl --$pp |");
while(<IN>) {
(undef, undef, undef, $pnum) = split(' ', $_);
chomp($pnum);
$pnum =~ s/.*://;
if($pnum eq $pl[$n]) {
last;
}
}
close(IN);
}
if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD")) {
open(IN, "netstat -anl -p $pp |");
while(<IN>) {
my $stat;
(undef, undef, undef, $pnum, undef, $stat) = split(' ', $_);
chomp($stat);
if($stat eq "LISTEN") {
chomp($pnum);
($pnum) = ($pnum =~ m/^.*?(\.\d+$)/);
$pnum =~ s/\.//;
if($pnum eq $pl[$n]) {
last;
}
}
}
close(IN);
}
if($pnum ne $pl[$n]) {
push(@warning, $colors->{warning_color});
}
$name = substr($pn, 0, 15);
undef(@tmp);
undef(@tmpz);
undef(@CDEF);
push(@tmp, "AREA:B_in#44EE44:Input");
push(@tmp, "AREA:B_out#4444EE:Output");
push(@tmp, "AREA:B_out#4444EE:");
push(@tmp, "AREA:B_in#44EE44:");
push(@tmp, "LINE1:B_out#0000EE");
push(@tmp, "LINE1:B_in#00EE00");
push(@tmpz, "AREA:B_in#44EE44:Input");
push(@tmpz, "AREA:B_out#4444EE:Output");
push(@tmpz, "AREA:B_out#4444EE:");
push(@tmpz, "AREA:B_in#44EE44:");
push(@tmpz, "LINE1:B_out#0000EE");
push(@tmpz, "LINE1:B_in#00EE00");
if(lc($config->{netstats_in_bps}) eq "y") {
push(@CDEF, "CDEF:B_in=in,8,*");
push(@CDEF, "CDEF:B_out=out,8,*");
} else {
push(@CDEF, "CDEF:B_in=in");
push(@CDEF, "CDEF:B_out=out");
}
($width, $height) = split('x', $config->{graph_size}->{mini});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG[$n]",
"--title=$name traffic ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
@warning,
"DEF:in=$rrd:port" . $n . "_in:AVERAGE",
"DEF:out=$rrd:port" . $n . "_out:AVERAGE",
@CDEF,
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$n]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$n]",
"--title=$name traffic ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
@warning,
"DEF:in=$rrd:port" . $n . "_in:AVERAGE",
"DEF:out=$rrd:port" . $n . "_out:AVERAGE",
@CDEF,
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$n]: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /port$n/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$n] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$n] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$n] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$n] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$n] . "'>\n");
}
}
if($title) {
print(" </td>\n");
}
$n++;
}
if($title) {
print(" </tr>\n");
}
}
if($title) {
main::graph_footer();
}
print(" <br>\n");
return;
}
1;

658
lib/proc.pm Normal file
View File

@ -0,0 +1,658 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package proc;
use strict;
use warnings;
use Monitorix;
use RRDs;
use Exporter 'import';
our @EXPORT = qw(proc_init proc_update proc_cgi);
sub proc_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $proc = $config->{proc};
my $info;
my @ds;
my @tmp;
my $n;
if(!grep {$_ eq $config->{os}} ("Linux", "FreeBSD")) {
logger("$myself is not supported yet by your operating system ($config->{os}).");
return;
}
if(-e $rrd) {
$info = RRDs::info($rrd);
for my $key (keys %$info) {
if(index($key, 'ds[') == 0) {
if(index($key, '.type') != -1) {
push(@ds, substr($key, 3, index($key, ']') - 3));
}
}
}
if(scalar(@ds) / 9 != $proc->{max}) {
logger("Detected size mismatch between 'max = $proc->{max}' and $rrd (" . scalar(@ds) / 9 . "). Resizing it accordingly. All historic data will be lost. Backup file created.");
rename($rrd, "$rrd.bak");
}
}
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
for($n = 0; $n < $proc->{max}; $n++) {
push(@tmp, "DS:proc" . $n . "_user:GAUGE:120:0:100");
push(@tmp, "DS:proc" . $n . "_nice:GAUGE:120:0:100");
push(@tmp, "DS:proc" . $n . "_sys:GAUGE:120:0:100");
push(@tmp, "DS:proc" . $n . "_idle:GAUGE:120:0:100");
push(@tmp, "DS:proc" . $n . "_iow:GAUGE:120:0:100");
push(@tmp, "DS:proc" . $n . "_irq:GAUGE:120:0:100");
push(@tmp, "DS:proc" . $n . "_sirq:GAUGE:120:0:100");
push(@tmp, "DS:proc" . $n . "_steal:GAUGE:120:0:100");
push(@tmp, "DS:proc" . $n . "_guest:GAUGE:120:0:100");
}
eval {
RRDs::create($rrd,
"--step=60",
@tmp,
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
$config->{proc_hist} = ();
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub proc_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $proc = $config->{proc};
my @procs;
my $total;
my $n;
my @lastproc;
my @p;
my @l;
my $rrdata = "N";
# Read last processor usage data
my $str;
for($n = 0; $n < $proc->{max}; $n++) {
$str = "cpu" . $n;
if($config->{proc_hist}->{$str}) {
push(@lastproc, $config->{proc_hist}->{$str});
}
}
if($config->{os} eq "Linux") {
open(IN, "/proc/stat");
while(<IN>) {
for($n = 0; $n < $proc->{max}; $n++) {
$str = "cpu" . $n;
if(/^cpu$n /) {
$config->{proc_hist}->{$str} = $_;
chomp($config->{proc_hist}->{$str});
push(@procs, $config->{proc_hist}->{$str});
}
}
}
close(IN);
} elsif($config->{os} eq "FreeBSD") {
my $cptimes;
my @tmp;
my $from;
my $to;
my $ncpu = `sysctl -n hw.ncpu`;
open(IN, "sysctl -n kern.cp_times |");
my @data = split(' ', <IN>);
close(IN);
chomp($ncpu);
for($n = 0; $n < $proc->{max}; $n++) {
$str = "cpu" . $n;
$from = $n * 5;
$to = $from + 4;
@tmp = @data[$from..$to];
@tmp[0, 1, 2, 3, 4] = @tmp[0, 1, 2, 4, 3];
$cptimes = join(' ', @tmp);
chomp($cptimes);
$cptimes = $str . " " . $cptimes;
$config->{proc_hist}->{$str} = $cptimes;
push(@procs, $cptimes);
}
}
my @deltas;
for($n = 0; $n < $proc->{max}; $n++) {
if($procs[$n]) {
@p = split(' ', $procs[$n]);
@l = (0) x 10;
@l = split(' ', $lastproc[$n]) if $lastproc[$n];
@deltas = (
# $p[0] and $l[0] are the 'cpu' word
$p[1] - $l[1], # user
$p[2] - $l[2], # nice
$p[3] - $l[3], # sys
$p[4] - $l[4], # idle
$p[5] - $l[5], # iow
$p[6] - $l[6], # irq
$p[7] - $l[7], # sirq
$p[8] - $l[8], # steal
$p[9] - $l[9], # guest
);
$total = $deltas[0] + $deltas[1] + $deltas[2] + $deltas[3] + $deltas[4] + $deltas[5] + $deltas[6] + $deltas[7] + $deltas[8];
undef(@p);
push(@p, $deltas[0] ? ($deltas[0] * 100) / $total : 0);
push(@p, $deltas[1] ? ($deltas[1] * 100) / $total : 0);
push(@p, $deltas[2] ? ($deltas[2] * 100) / $total : 0);
push(@p, $deltas[3] ? ($deltas[3] * 100) / $total : 0);
push(@p, $deltas[4] ? ($deltas[4] * 100) / $total : 0);
push(@p, $deltas[5] ? ($deltas[5] * 100) / $total : 0);
push(@p, $deltas[6] ? ($deltas[6] * 100) / $total : 0);
push(@p, $deltas[7] ? ($deltas[7] * 100) / $total : 0);
push(@p, $deltas[8] ? ($deltas[8] * 100) / $total : 0);
$procs[$n] = join(' ', @p);
} else {
$procs[$n] = join(' ', (0, 0, 0, 0, 0, 0, 0, 0, 0));
}
}
for($n = 0; $n < $proc->{max}; $n++) {
@p = split(' ', $procs[$n]);
$rrdata .= ":$p[0]:$p[1]:$p[2]:$p[3]:$p[4]:$p[5]:$p[6]:$p[7]:$p[8]";
}
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub proc_cgi {
my ($package, $config, $cgi) = @_;
my $proc = $config->{proc};
my $kern = $config->{kern};
my @rigid = split(',', $proc->{rigid});
my @limit = split(',', $proc->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @PNG;
my @PNGz;
my @tmp;
my @tmpz;
my $vlabel;
my $ncpu;
my $n;
my $n2;
my $str;
my $err;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
if($config->{os} eq "Linux") {
$ncpu = `grep -w processor /proc/cpuinfo | tail -1 | awk '{ print \$3 }'`;
chomp($ncpu);
$ncpu++;
} elsif($config->{os} eq "FreeBSD") {
$ncpu = `/sbin/sysctl -n hw.ncpu`;
chomp($ncpu);
}
$ncpu = $ncpu > $proc->{max} ? $proc->{max} : $ncpu;
return unless $ncpu > 1;
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
for($n = 0; $n < $ncpu; $n++) {
print(" Processor " . sprintf("%3d", $n) . " ");
}
print("\nTime");
for($n = 0; $n < $ncpu; $n++) {
print(" User Nice Sys Idle I/Ow IRQ sIRQ Steal Guest");
}
print(" \n----");
for($n = 0; $n < $ncpu; $n++) {
print("-------------------------------------------------------");
}
print(" \n");
my $line;
my @row;
my $time;
my $from;
my $to;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc} ", $time);
for($n2 = 0; $n2 < $ncpu; $n2++) {
$from = $n2 * $ncpu;
$to = $from + $ncpu;
my ($usr, $nic, $sys, $idle, $iow, $irq, $sirq, $steal, $guest,) = @$line[$from..$to];
@row = ($usr, $nic, $sys, $idle, $iow, $irq, $sirq, $steal, $guest);
printf(" %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% ", @row);
}
print("\n");
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
for($n = 0; $n < $ncpu; $n++) {
$str = $u . $package . $n . "." . $tf->{when} . ".png";
push(@PNG, $str);
unlink("$PNG_DIR" . $str);
if(lc($config->{enable_zoom}) eq "y") {
$str = $u . $package . $n . "z." . $tf->{when} . ".png";
push(@PNGz, $str);
unlink("$PNG_DIR" . $str);
}
}
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
$n = 0;
while($n < $ncpu) {
if($title) {
if($n == 0) {
main::graph_header($title, $proc->{graphs_per_row});
}
print(" <tr>\n");
}
for($n2 = 0; $n2 < $proc->{graphs_per_row}; $n2++) {
last unless $n < $ncpu;
if($title) {
print(" <td bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@tmp);
undef(@tmpz);
if(lc($kern->{graph_mode}) eq "r") {
$vlabel = "Percent (%)";
if(lc($kern->{list}->{user}) eq "y") {
push(@tmp, "AREA:user#4444EE:user");
push(@tmpz, "AREA:user#4444EE:user");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:user:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:user:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:user:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:user:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{nice}) eq "y") {
push(@tmp, "AREA:nice#EEEE44:nice");
push(@tmpz, "AREA:nice#EEEE44:nice");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:nice:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{sys}) eq "y") {
push(@tmp, "AREA:sys#44EEEE:system");
push(@tmpz, "AREA:sys#44EEEE:system");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:sys:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{iow}) eq "y") {
push(@tmp, "AREA:iow#EE44EE:I/O wait");
push(@tmpz, "AREA:iow#EE44EE:I/O wait");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:iow:LAST:Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{irq}) eq "y") {
push(@tmp, "AREA:irq#888888:IRQ");
push(@tmpz, "AREA:irq#888888:IRQ");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:irq:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{sirq}) eq "y") {
push(@tmp, "AREA:sirq#E29136:softIRQ");
push(@tmpz, "AREA:sirq#E29136:softIRQ");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:sirq:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{steal}) eq "y") {
push(@tmp, "AREA:steal#44EE44:steal");
push(@tmpz, "AREA:steal#44EE44:steal");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:steal:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{guest}) eq "y") {
push(@tmp, "AREA:guest#448844:guest");
push(@tmpz, "AREA:guest#448844:guest");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:guest:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:MAX: Max\\: %4.1lf%%\\n");
}
}
push(@tmp, "LINE1:guest#1F881F") unless lc($kern->{list}->{guest}) ne "y";
push(@tmpz, "LINE1:guest#1F881F") unless lc($kern->{list}->{guest}) ne "y";
push(@tmp, "LINE1:steal#00EE00") unless lc($kern->{list}->{steal}) ne "y";
push(@tmpz, "LINE1:steal#00EE00") unless lc($kern->{list}->{steal}) ne "y";
push(@tmp, "LINE1:sirq#D86612") unless lc($kern->{list}->{sirq}) ne "y";
push(@tmpz, "LINE1:sirq#D86612") unless lc($kern->{list}->{sirq}) ne "y";
push(@tmp, "LINE1:irq#CCCCCC") unless lc($kern->{list}->{irq}) ne "y";
push(@tmpz, "LINE1:irq#CCCCCC") unless lc($kern->{list}->{irq}) ne "y";
push(@tmp, "LINE1:iow#EE00EE") unless lc($kern->{list}->{iow}) ne "y";
push(@tmpz, "LINE1:iow#EE00EE") unless lc($kern->{list}->{iow}) ne "y";
push(@tmp, "LINE1:sys#00EEEE") unless lc($kern->{list}->{sys}) ne "y";
push(@tmpz, "LINE1:sys#00EEEE") unless lc($kern->{list}->{sys}) ne "y";
push(@tmp, "LINE1:nice#EEEE00") unless lc($kern->{list}->{nice}) ne "y";
push(@tmpz, "LINE1:nice#EEEE00") unless lc($kern->{list}->{nice}) ne "y";
push(@tmp, "LINE1:user#0000EE") unless lc($kern->{list}->{user}) ne "y";
push(@tmpz, "LINE1:user#0000EE") unless lc($kern->{list}->{user}) ne "y";
} else {
$vlabel = "Stacked Percent (%)";
push(@tmp, "CDEF:s_nice=user,nice,+");
push(@tmpz, "CDEF:s_nice=user,nice,+");
push(@tmp, "CDEF:s_sys=s_nice,sys,+");
push(@tmpz, "CDEF:s_sys=s_nice,sys,+");
push(@tmp, "CDEF:s_iow=s_sys,iow,+");
push(@tmpz, "CDEF:s_iow=s_sys,iow,+");
push(@tmp, "CDEF:s_irq=s_iow,irq,+");
push(@tmpz, "CDEF:s_irq=s_iow,irq,+");
push(@tmp, "CDEF:s_sirq=s_irq,sirq,+");
push(@tmpz, "CDEF:s_sirq=s_irq,sirq,+");
push(@tmp, "CDEF:s_steal=s_sirq,steal,+");
push(@tmpz, "CDEF:s_steal=s_sirq,steal,+");
push(@tmp, "CDEF:s_guest=s_steal,guest,+");
push(@tmpz, "CDEF:s_guest=s_steal,guest,+");
if(lc($kern->{list}->{guest}) eq "y") {
push(@tmp, "AREA:s_guest#E29136:guest");
push(@tmpz, "AREA:s_guest#E29136:guest");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:guest:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:guest:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{steal}) eq "y") {
push(@tmp, "AREA:s_steal#888888:steal");
push(@tmpz, "AREA:s_steal#888888:steal");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:steal:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:steal:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{sirq}) eq "y") {
push(@tmp, "AREA:s_sirq#448844:softIRQ");
push(@tmpz, "AREA:s_sirq#448844:softIRQ");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:sirq:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:sirq:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{irq}) eq "y") {
push(@tmp, "AREA:s_irq#44EE44:IRQ");
push(@tmpz, "AREA:s_irq#44EE44:IRQ");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:irq:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:irq:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{iow}) eq "y") {
push(@tmp, "AREA:s_iow#EE44EE:I/O wait");
push(@tmpz, "AREA:s_iow#EE44EE:I/O wait");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:iow:LAST:Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:iow:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{sys}) eq "y") {
push(@tmp, "AREA:s_sys#44EEEE:system");
push(@tmpz, "AREA:s_sys#44EEEE:system");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:sys:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:sys:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{nice}) eq "y") {
push(@tmp, "AREA:s_nice#EEEE44:nice");
push(@tmpz, "AREA:s_nice#EEEE44:nice");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:nice:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:nice:MAX: Max\\: %4.1lf%%\\n");
}
}
if(lc($kern->{list}->{user}) eq "y") {
push(@tmp, "AREA:user#4444EE:user");
push(@tmpz, "AREA:user#4444EE:user");
if(lc($proc->{data}) eq "y") {
push(@tmp, "GPRINT:user:LAST: Cur\\: %4.1lf%%");
push(@tmp, "GPRINT:user:AVERAGE: Avg\\: %4.1lf%%");
push(@tmp, "GPRINT:user:MIN: Min\\: %4.1lf%%");
push(@tmp, "GPRINT:user:MAX: Max\\: %4.1lf%%\\n");
}
}
push(@tmp, "LINE1:s_guest#D86612");
push(@tmpz, "LINE1:s_guest#D86612");
push(@tmp, "LINE1:s_steal#CCCCCC");
push(@tmpz, "LINE1:s_steal#CCCCCC");
push(@tmp, "LINE1:s_sirq#1F881F");
push(@tmpz, "LINE1:s_sirq#1F881F");
push(@tmp, "LINE1:s_irq#00EE00");
push(@tmpz, "LINE1:s_irq#00EE00");
push(@tmp, "LINE1:s_iow#EE00EE");
push(@tmpz, "LINE1:s_iow#EE00EE");
push(@tmp, "LINE1:s_sys#00EEEE");
push(@tmpz, "LINE1:s_sys#00EEEE");
push(@tmp, "LINE1:s_nice#EEEE00");
push(@tmpz, "LINE1:s_nice#EEEE00");
push(@tmp, "LINE1:user#0000EE");
push(@tmpz, "LINE1:user#0000EE");
}
($width, $height) = split('x', $config->{graph_size}->{$proc->{size}});
RRDs::graph("$PNG_DIR" . "$PNG[$n]",
"--title=$config->{graphs}->{_proc} $n ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:user=$rrd:proc" . $n . "_user:AVERAGE",
"DEF:nice=$rrd:proc" . $n . "_nice:AVERAGE",
"DEF:sys=$rrd:proc" . $n . "_sys:AVERAGE",
"DEF:iow=$rrd:proc" . $n . "_iow:AVERAGE",
"DEF:irq=$rrd:proc" . $n . "_irq:AVERAGE",
"DEF:sirq=$rrd:proc" . $n . "_sirq:AVERAGE",
"DEF:steal=$rrd:proc" . $n . "_steal:AVERAGE",
"DEF:guest=$rrd:proc" . $n . "_guest:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG[$n]: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNGz[$n]",
"--title=$config->{graphs}->{_proc} $n ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:user=$rrd:proc" . $n . "_user:AVERAGE",
"DEF:nice=$rrd:proc" . $n . "_nice:AVERAGE",
"DEF:sys=$rrd:proc" . $n . "_sys:AVERAGE",
"DEF:iow=$rrd:proc" . $n . "_iow:AVERAGE",
"DEF:irq=$rrd:proc" . $n . "_irq:AVERAGE",
"DEF:sirq=$rrd:proc" . $n . "_sirq:AVERAGE",
"DEF:steal=$rrd:proc" . $n . "_steal:AVERAGE",
"DEF:guest=$rrd:proc" . $n . "_guest:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNGz[$n]: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /proc$n/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNGz[$n] . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$n] . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNGz[$n] . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$n] . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG[$n] . "'>\n");
}
}
if($title) {
print(" </td>\n");
}
$n++;
}
if($title) {
print(" </tr>\n");
}
}
if($title) {
main::graph_footer();
}
print(" <br>\n");
return;
}
1;

976
lib/serv.pm Normal file
View File

@ -0,0 +1,976 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package serv;
use strict;
use warnings;
use Monitorix;
use RRDs;
use POSIX qw(strftime);
use Exporter 'import';
our @EXPORT = qw(serv_init serv_update serv_cgi);
sub serv_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
eval {
RRDs::create($rrd,
"--step=300",
"DS:serv_i_ssh:GAUGE:600:0:U",
"DS:serv_i_ftp:GAUGE:600:0:U",
"DS:serv_i_telnet:GAUGE:600:0:U",
"DS:serv_i_imap:GAUGE:600:0:U",
"DS:serv_i_smb:GAUGE:600:0:U",
"DS:serv_i_fax:GAUGE:600:0:U",
"DS:serv_i_cups:GAUGE:600:0:U",
"DS:serv_i_pop3:GAUGE:600:0:U",
"DS:serv_i_smtp:GAUGE:600:0:U",
"DS:serv_i_spam:GAUGE:600:0:U",
"DS:serv_i_virus:GAUGE:600:0:U",
"DS:serv_i_f2b:GAUGE:600:0:U",
"DS:serv_i_val02:GAUGE:600:0:U",
"DS:serv_i_val03:GAUGE:600:0:U",
"DS:serv_i_val04:GAUGE:600:0:U",
"DS:serv_i_val05:GAUGE:600:0:U",
"DS:serv_l_ssh:GAUGE:600:0:U",
"DS:serv_l_ftp:GAUGE:600:0:U",
"DS:serv_l_telnet:GAUGE:600:0:U",
"DS:serv_l_imap:GAUGE:600:0:U",
"DS:serv_l_smb:GAUGE:600:0:U",
"DS:serv_l_fax:GAUGE:600:0:U",
"DS:serv_l_cups:GAUGE:600:0:U",
"DS:serv_l_pop3:GAUGE:600:0:U",
"DS:serv_l_smtp:GAUGE:600:0:U",
"DS:serv_l_spam:GAUGE:600:0:U",
"DS:serv_l_virus:GAUGE:600:0:U",
"DS:serv_l_f2b:GAUGE:600:0:U",
"DS:serv_l_val02:GAUGE:600:0:U",
"DS:serv_l_val03:GAUGE:600:0:U",
"DS:serv_l_val04:GAUGE:600:0:U",
"DS:serv_l_val05:GAUGE:600:0:U",
"RRA:AVERAGE:0.5:1:288",
"RRA:AVERAGE:0.5:6:336",
"RRA:AVERAGE:0.5:12:744",
"RRA:AVERAGE:0.5:288:365",
"RRA:MIN:0.5:1:288",
"RRA:MIN:0.5:6:336",
"RRA:MIN:0.5:12:744",
"RRA:MIN:0.5:288:365",
"RRA:MAX:0.5:1:288",
"RRA:MAX:0.5:6:336",
"RRA:MAX:0.5:12:744",
"RRA:MAX:0.5:288:365",
"RRA:LAST:0.5:1:288",
"RRA:LAST:0.5:6:336",
"RRA:LAST:0.5:12:744",
"RRA:LAST:0.5:288:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
$config->{serv_hist} = ();
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub serv_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $ssh = 0;
my $ftp = 0;
my $telnet = 0;
my $imap = 0;
my $smb = 0;
my $fax = 0;
my $cups = 0;
my $pop3 = 0;
my $smtp = 0;
my $spam = 0;
my $virus = 0;
my $f2b = 0;
my $val02 = 0;
my $val03 = 0;
my $val04 = 0;
my $val05 = 0;
my $date;
my $rrdata = "N";
# This graph is refreshed only every 5 minutes
my (undef, $min) = localtime(time);
return if($min % 5);
if(-r $config->{secure_log}) {
$date = strftime("%b %e", localtime);
open(IN, "$config->{secure_log}");
while(<IN>) {
if(/^$date/) {
if(/ sshd\[/ && /Accepted /) {
$ssh++;
}
if($config->{os} eq "Linux") {
if(/START: pop3/) {
$pop3++;
}
if(/START: ftp/ ||
(/ proftpd\[/ && /Login successful./)) {
$ftp++;
}
if(/START: telnet/) {
$telnet++;
}
} elsif($config->{os} eq "FreeBSD") {
if(/login:/ && /login from /) {
$telnet++;
}
}
}
}
close(IN);
}
if(-r $config->{imap_log}) {
$config->{imap_date_log_format} = $config->{imap_date_log_format} || "%b %d";
my $date_dovecot = strftime($config->{imap_date_log_format}, localtime);
my $date_uw = strftime("%b %e %T", localtime);
open(IN, "$config->{imap_log}");
while(<IN>) {
# UW-IMAP log
if(/$date_uw/) {
if(/ imapd\[/ && / Login user=/) {
$imap++;
}
}
# Dovecot log
if(/$date_dovecot /) {
if(/ imap-login: / && / Login: /) {
$imap++;
}
if(/ pop3-login: / && / Login: /) {
$pop3++;
}
}
}
close(IN);
}
my $smb_L = 0;
open(IN, "smbstatus -L 2>/dev/null |");
while(<IN>) {
if(/^----------/) {
$smb_L++;
next;
}
if($smb_L) {
$smb_L++ unless !$_;
}
}
close(IN);
$smb_L--;
my $smb_S = 0;
open(IN, "smbstatus -S 2>/dev/null |");
while(<IN>) {
if(/^----------/) {
$smb_S++;
next;
}
if($smb_S) {
$smb_S++ unless !$_;
}
}
close(IN);
$smb_S--;
$smb = $smb_L + $smb_S;
if(-r $config->{hylafax_log}) {
$date = strftime("%m/%d/%y", localtime);
open(IN, "$config->{hylafax_log}");
while(<IN>) {
if(/^$date/ && /SEND/) {
$fax++;
}
}
close(IN);
}
if(-r $config->{cups_log}) {
$date = strftime("%d/%b/%Y", localtime);
open(IN, "$config->{cups_log}");
while(<IN>) {
if(/\[$date:/) {
$cups++;
}
}
close(IN);
}
if(-r $config->{fail2ban_log}) {
$date = strftime("%Y-%m-%d", localtime);
open(IN, $config->{fail2ban_log});
while(<IN>) {
if(/^$date/ && / fail2ban/ && / WARNING / && / Ban /) {
$f2b++;
}
}
close(IN);
}
if(-r $config->{mail_log}) {
$date = strftime("%b %e", localtime);
open(IN, "$config->{mail_log}");
while(<IN>) {
if(/^$date/) {
if(/to=/ && /stat(us)?=sent/i) {
$smtp++;
}
if(/MailScanner/ && /Spam Checks:/ && /Found/ && /spam messages/) {
$spam++;
}
if(/MailScanner/ && /Virus Scanning:/ && /Found/ && /viruses/) {
$virus++;
}
}
}
close(IN);
}
$date = strftime("%Y-%m-%d", localtime);
if(-r "$config->{cg_logdir}/$date.log") {
open(IN, "$config->{cg_logdir}/$date.log");
while(<IN>) {
if(/DEQUEUER \[\d+\] (LOCAL\(.+\) delivered|SMTP.+ relayed)\:/) {
$smtp++;
}
if(/IMAP/ && / connected from /) {
$imap++;
}
if(/POP/ && / connected from /) {
$pop3++;
}
}
close(IN);
}
if(-r $config->{spamassassin_log}) {
$date = strftime("%b %e", localtime);
open(IN, $config->{spamassassin_log});
while(<IN>) {
if(/^$date/ && /spamd: identified spam/) {
$spam++;
}
}
close(IN);
}
if(-r $config->{clamav_log}) {
$date = strftime("%a %b %e", localtime);
open(IN, $config->{clamav_log});
while(<IN>) {
if(/^$date/ && / FOUND/) {
$virus++;
}
}
close(IN);
}
# I data (incremental)
$rrdata .= ":$ssh:$ftp:$telnet:$imap:$smb:$fax:$cups:$pop3:$smtp:$spam:$virus:$f2b:$val02:$val03:$val04:$val05";
# L data (load)
my $l_ssh = 0;
my $l_ftp = 0;
my $l_telnet = 0;
my $l_imap = 0;
my $l_smb = 0;
my $l_fax = 0;
my $l_cups = 0;
my $l_pop3 = 0;
my $l_smtp = 0;
my $l_spam = 0;
my $l_virus = 0;
my $l_f2b = 0;
my $l_val02 = 0;
my $l_val03 = 0;
my $l_val04 = 0;
my $l_val05 = 0;
$l_ssh = $ssh - ($config->{serv_hist}->{'ssh'} || 0);
$l_ssh = 0 unless $l_ssh != $ssh;
$l_ssh /= 300;
$config->{serv_hist}->{'ssh'} = $ssh;
$l_ftp = $ftp - ($config->{serv_hist}->{'ftp'} || 0);
$l_ftp = 0 unless $l_ftp != $ftp;
$l_ftp /= 300;
$config->{serv_hist}->{'ftp'} = $ftp;
$l_telnet = $telnet - ($config->{serv_hist}->{'telnet'} || 0);
$l_telnet = 0 unless $l_telnet != $telnet;
$l_telnet /= 300;
$config->{serv_hist}->{'telnet'} = $telnet;
$l_imap = $imap - ($config->{serv_hist}->{'imap'} || 0);
$l_imap = 0 unless $l_imap != $imap;
$l_imap /= 300;
$config->{serv_hist}->{'imap'} = $imap;
$l_smb = $smb - ($config->{serv_hist}->{'smb'} || 0);
$l_smb = 0 unless $l_smb != $smb;
$l_smb /= 300;
$config->{serv_hist}->{'smb'} = $smb;
$l_fax = $fax - ($config->{serv_hist}->{'fax'} || 0);
$l_fax = 0 unless $l_fax != $fax;
$l_fax /= 300;
$config->{serv_hist}->{'fax'} = $fax;
$l_cups = $cups - ($config->{serv_hist}->{'cups'} || 0);
$l_cups = 0 unless $l_cups != $cups;
$l_cups /= 300;
$config->{serv_hist}->{'cups'} = $cups;
$l_pop3 = $pop3 - ($config->{serv_hist}->{'pop3'} || 0);
$l_pop3 = 0 unless $l_pop3 != $pop3;
$l_pop3 /= 300;
$config->{serv_hist}->{'pop3'} = $pop3;
$l_smtp = $smtp - ($config->{serv_hist}->{'smtp'} || 0);
$l_smtp = 0 unless $l_smtp != $smtp;
$l_smtp /= 300;
$config->{serv_hist}->{'smtp'} = $smtp;
$l_spam = $spam - ($config->{serv_hist}->{'spam'} || 0);
$l_spam = 0 unless $l_spam != $spam;
$l_spam /= 300;
$config->{serv_hist}->{'spam'} = $spam;
$l_virus = $virus - ($config->{serv_hist}->{'virus'} || 0);
$l_virus = 0 unless $l_virus != $virus;
$l_virus /= 300;
$config->{serv_hist}->{'virus'} = $virus;
$l_f2b = $f2b - ($config->{serv_hist}->{'f2b'} || 0);
$l_f2b = 0 unless $l_f2b != $f2b;
$l_f2b /= 300;
$config->{serv_hist}->{'f2b'} = $f2b;
$l_val02 = $val02 - ($config->{serv_hist}->{'val02'} || 0);
$l_val02 = 0 unless $l_val02 != $val02;
$l_val02 /= 300;
$config->{serv_hist}->{'val02'} = $val02;
$l_val03 = $val03 - ($config->{serv_hist}->{'val03'} || 0);
$l_val03 = 0 unless $l_val03 != $val03;
$l_val03 /= 300;
$config->{serv_hist}->{'val03'} = $val03;
$l_val04 = $val04 - ($config->{serv_hist}->{'val04'} || 0);
$l_val04 = 0 unless $l_val04 != $val04;
$l_val04 /= 300;
$config->{serv_hist}->{'val04'} = $val04;
$l_val05 = $val05 - ($config->{serv_hist}->{'val05'} || 0);
$l_val05 = 0 unless $l_val05 != $val05;
$l_val05 /= 300;
$config->{serv_hist}->{'val05'} = $val05;
$rrdata .= ":$l_ssh:$l_ftp:$l_telnet:$l_imap:$l_smb:$l_fax:$l_cups:$l_pop3:$l_smtp:$l_spam:$l_virus:$l_f2b:$l_val02:$l_val03:$l_val04:$l_val05";
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub serv_cgi {
my ($package, $config, $cgi) = @_;
my $serv = $config->{serv};
my @rigid = split(',', $serv->{rigid});
my @limit = split(',', $serv->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my $vlabel;
my @tmp;
my @tmpz;
my $n;
my $str;
my $err;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
if(lc($serv->{mode}) eq "i") {
print "Values expressed as incremental or cumulative hits.\n";
}
print("Time SSH FTP Telnet Samba Fax CUPS F2B IMAP POP3 SMTP Spam Virus\n");
print("--------------------------------------------------------------------------------------------------- \n");
my $line;
my @row;
my $time;
my $from = 0;
my $to;
if(lc($serv->{mode}) eq "l") {
$from = 15;
}
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
$time = $time - (1 / $tf->{ts});
$to = $from + 10;
my ($ssh, $ftp, $telnet, $imap, $smb, $fax, $cups, $pop3, $smtp, $spam, $virus, $f2b) = @$line[$from..$to];
@row = ($ssh, $ftp, $telnet, $imap, $smb, $fax, $cups, $f2b, $pop3, $smtp, $spam, $virus);
if(lc($serv->{mode}) eq "i") {
printf(" %2d$tf->{tc} %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d\n", $time, @row);
} elsif(lc($serv->{mode}) eq "l") {
printf(" %2d$tf->{tc} %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n", $time, @row);
}
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
my $PNG1 = $u . $package . "1." . $tf->{when} . ".png";
my $PNG2 = $u . $package . "2." . $tf->{when} . ".png";
my $PNG3 = $u . $package . "3." . $tf->{when} . ".png";
my $PNG1z = $u . $package . "1z." . $tf->{when} . ".png";
my $PNG2z = $u . $package . "2z." . $tf->{when} . ".png";
my $PNG3z = $u . $package . "3z." . $tf->{when} . ".png";
unlink ("$PNG_DIR" . "$PNG1",
"$PNG_DIR" . "$PNG2",
"$PNG_DIR" . "$PNG3");
if(lc($config->{enable_zoom}) eq "y") {
unlink ("$PNG_DIR" . "$PNG1z",
"$PNG_DIR" . "$PNG2z",
"$PNG_DIR" . "$PNG3z");
}
if($title) {
main::graph_header($title, 2);
}
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
if(lc($serv->{mode}) eq "l") {
$vlabel = "Accesses/s";
push(@tmp, "AREA:l_ssh#4444EE:SSH");
push(@tmp, "GPRINT:l_ssh:LAST: Current\\: %3.2lf");
push(@tmp, "GPRINT:l_ssh:AVERAGE: Average\\: %3.2lf");
push(@tmp, "GPRINT:l_ssh:MIN: Min\\: %3.2lf");
push(@tmp, "GPRINT:l_ssh:MAX: Max\\: %3.2lf\\n");
push(@tmp, "AREA:l_ftp#44EE44:FTP");
push(@tmp, "GPRINT:l_ftp:LAST: Current\\: %3.2lf");
push(@tmp, "GPRINT:l_ftp:AVERAGE: Average\\: %3.2lf");
push(@tmp, "GPRINT:l_ftp:MIN: Min\\: %3.2lf");
push(@tmp, "GPRINT:l_ftp:MAX: Max\\: %3.2lf\\n");
push(@tmp, "AREA:l_telnet#EE44EE:Telnet");
push(@tmp, "GPRINT:l_telnet:LAST: Current\\: %3.2lf");
push(@tmp, "GPRINT:l_telnet:AVERAGE: Average\\: %3.2lf");
push(@tmp, "GPRINT:l_telnet:MIN: Min\\: %3.2lf");
push(@tmp, "GPRINT:l_telnet:MAX: Max\\: %3.2lf\\n");
push(@tmp, "AREA:l_smb#EEEE44:Samba");
push(@tmp, "GPRINT:l_smb:LAST: Current\\: %3.2lf");
push(@tmp, "GPRINT:l_smb:AVERAGE: Average\\: %3.2lf");
push(@tmp, "GPRINT:l_smb:MIN: Min\\: %3.2lf");
push(@tmp, "GPRINT:l_smb:MAX: Max\\: %3.2lf\\n");
push(@tmp, "AREA:l_fax#FFA500:Fax");
push(@tmp, "GPRINT:l_fax:LAST: Current\\: %3.2lf");
push(@tmp, "GPRINT:l_fax:AVERAGE: Average\\: %3.2lf");
push(@tmp, "GPRINT:l_fax:MIN: Min\\: %3.2lf");
push(@tmp, "GPRINT:l_fax:MAX: Max\\: %3.2lf\\n");
push(@tmp, "AREA:l_cups#444444:CUPS");
push(@tmp, "GPRINT:l_cups:LAST: Current\\: %3.2lf");
push(@tmp, "GPRINT:l_cups:AVERAGE: Average\\: %3.2lf");
push(@tmp, "GPRINT:l_cups:MIN: Min\\: %3.2lf");
push(@tmp, "GPRINT:l_cups:MAX: Max\\: %3.2lf\\n");
push(@tmp, "AREA:l_f2b#EE4444:Fail2ban");
push(@tmp, "GPRINT:l_f2b:LAST: Current\\: %3.2lf");
push(@tmp, "GPRINT:l_f2b:AVERAGE: Average\\: %3.2lf");
push(@tmp, "GPRINT:l_f2b:MIN: Min\\: %3.2lf");
push(@tmp, "GPRINT:l_f2b:MAX: Max\\: %3.2lf\\n");
push(@tmp, "LINE2:l_ssh#4444EE");
push(@tmp, "LINE2:l_ftp#44EE44");
push(@tmp, "LINE2:l_telnet#EE44EE");
push(@tmp, "LINE2:l_smb#EEEE44");
push(@tmp, "LINE2:l_fax#FFA500");
push(@tmp, "LINE2:l_cups#444444");
push(@tmp, "LINE2:l_f2b#EE4444");
push(@tmp, "COMMENT: \\n");
push(@tmpz, "AREA:l_ssh#4444EE:SSH");
push(@tmpz, "AREA:l_ftp#44EE44:FTP");
push(@tmpz, "AREA:l_telnet#EE44EE:Telnet");
push(@tmpz, "AREA:l_smb#EEEE44:Samba");
push(@tmpz, "AREA:l_fax#FFA500:Fax");
push(@tmpz, "AREA:l_cups#444444:CUPS");
push(@tmpz, "AREA:l_f2b#EE4444:Fail2ban");
push(@tmpz, "LINE2:l_ssh#4444EE");
push(@tmpz, "LINE2:l_ftp#44EE44");
push(@tmpz, "LINE2:l_telnet#EE44EE");
push(@tmpz, "LINE2:l_smb#EEEE44");
push(@tmpz, "LINE2:l_fax#FFA500");
push(@tmpz, "LINE2:l_cups#444444");
push(@tmpz, "LINE2:l_f2b#EE4444");
} else {
$vlabel = "Incremental hits";
push(@tmp, "AREA:i_ssh#4444EE:SSH");
push(@tmp, "GPRINT:i_ssh:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:i_ssh:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:i_ssh:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:i_ssh:MAX: Max\\: %5.0lf\\n");
push(@tmp, "AREA:i_ftp#44EE44:FTP");
push(@tmp, "GPRINT:i_ftp:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:i_ftp:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:i_ftp:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:i_ftp:MAX: Max\\: %5.0lf\\n");
push(@tmp, "AREA:i_telnet#EE44EE:Telnet");
push(@tmp, "GPRINT:i_telnet:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:i_telnet:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:i_telnet:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:i_telnet:MAX: Max\\: %5.0lf\\n");
push(@tmp, "AREA:i_smb#EEEE44:Samba");
push(@tmp, "GPRINT:i_smb:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:i_smb:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:i_smb:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:i_smb:MAX: Max\\: %5.0lf\\n");
push(@tmp, "AREA:i_fax#FFA500:Fax");
push(@tmp, "GPRINT:i_fax:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:i_fax:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:i_fax:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:i_fax:MAX: Max\\: %5.0lf\\n");
push(@tmp, "AREA:i_cups#444444:CUPS");
push(@tmp, "GPRINT:i_cups:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:i_cups:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:i_cups:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:i_cups:MAX: Max\\: %5.0lf\\n");
push(@tmp, "AREA:i_f2b#EE4444:Fail2ban");
push(@tmp, "GPRINT:i_f2b:LAST: Current\\: %5.0lf");
push(@tmp, "GPRINT:i_f2b:AVERAGE: Average\\: %5.0lf");
push(@tmp, "GPRINT:i_f2b:MIN: Min\\: %5.0lf");
push(@tmp, "GPRINT:i_f2b:MAX: Max\\: %5.0lf\\n");
push(@tmp, "LINE2:i_ssh#4444EE");
push(@tmp, "LINE2:i_ftp#44EE44");
push(@tmp, "LINE2:i_telnet#EE44EE");
push(@tmp, "LINE2:i_smb#EEEE44");
push(@tmp, "LINE2:i_fax#FFA500");
push(@tmp, "LINE2:i_cups#444444");
push(@tmp, "LINE2:i_f2b#EE4444");
push(@tmp, "COMMENT: \\n");
push(@tmpz, "AREA:i_ssh#4444EE:SSH");
push(@tmpz, "AREA:i_ftp#44EE44:FTP");
push(@tmpz, "AREA:i_telnet#EE44EE:Telnet");
push(@tmpz, "AREA:i_smb#EEEE44:Samba");
push(@tmpz, "AREA:i_fax#FFA500:Fax");
push(@tmpz, "AREA:i_cups#444444:CUPS");
push(@tmpz, "AREA:i_f2b#EE4444:Fail2ban");
push(@tmpz, "LINE2:i_ssh#4444EE");
push(@tmpz, "LINE2:i_ftp#44EE44");
push(@tmpz, "LINE2:i_telnet#EE44EE");
push(@tmpz, "LINE2:i_smb#EEEE44");
push(@tmpz, "LINE2:i_fax#FFA500");
push(@tmpz, "LINE2:i_cups#444444");
push(@tmpz, "LINE2:i_f2b#EE4444");
}
if($title) {
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG1",
"--title=$config->{graphs}->{_serv1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:i_ssh=$rrd:serv_i_ssh:AVERAGE",
"DEF:i_ftp=$rrd:serv_i_ftp:AVERAGE",
"DEF:i_telnet=$rrd:serv_i_telnet:AVERAGE",
"DEF:i_imap=$rrd:serv_i_imap:AVERAGE",
"DEF:i_smb=$rrd:serv_i_smb:AVERAGE",
"DEF:i_fax=$rrd:serv_i_fax:AVERAGE",
"DEF:i_cups=$rrd:serv_i_cups:AVERAGE",
"DEF:i_f2b=$rrd:serv_i_f2b:AVERAGE",
"DEF:l_ssh=$rrd:serv_l_ssh:AVERAGE",
"DEF:l_ftp=$rrd:serv_l_ftp:AVERAGE",
"DEF:l_telnet=$rrd:serv_l_telnet:AVERAGE",
"DEF:l_imap=$rrd:serv_l_imap:AVERAGE",
"DEF:l_smb=$rrd:serv_l_smb:AVERAGE",
"DEF:l_fax=$rrd:serv_l_fax:AVERAGE",
"DEF:l_cups=$rrd:serv_l_cups:AVERAGE",
"DEF:l_f2b=$rrd:serv_l_f2b:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG1z",
"--title=$config->{graphs}->{_serv1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:i_ssh=$rrd:serv_i_ssh:AVERAGE",
"DEF:i_ftp=$rrd:serv_i_ftp:AVERAGE",
"DEF:i_telnet=$rrd:serv_i_telnet:AVERAGE",
"DEF:i_imap=$rrd:serv_i_imap:AVERAGE",
"DEF:i_smb=$rrd:serv_i_smb:AVERAGE",
"DEF:i_fax=$rrd:serv_i_fax:AVERAGE",
"DEF:i_cups=$rrd:serv_i_cups:AVERAGE",
"DEF:i_f2b=$rrd:serv_i_f2b:AVERAGE",
"DEF:l_ssh=$rrd:serv_l_ssh:AVERAGE",
"DEF:l_ftp=$rrd:serv_l_ftp:AVERAGE",
"DEF:l_telnet=$rrd:serv_l_telnet:AVERAGE",
"DEF:l_imap=$rrd:serv_l_imap:AVERAGE",
"DEF:l_smb=$rrd:serv_l_smb:AVERAGE",
"DEF:l_fax=$rrd:serv_l_fax:AVERAGE",
"DEF:l_cups=$rrd:serv_l_cups:AVERAGE",
"DEF:l_f2b=$rrd:serv_l_f2b:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /serv1/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG1z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG1z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@riglim);
if(trim($rigid[1]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
} else {
if(trim($rigid[1]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
if(lc($serv->{mode}) eq "l") {
$vlabel = "Accesses/s";
push(@tmp, "AREA:l_imap#4444EE:IMAP");
push(@tmp, "GPRINT:l_imap:LAST: Current\\: %4.2lf\\n");
push(@tmp, "AREA:l_pop3#44EE44:POP3");
push(@tmp, "GPRINT:l_pop3:LAST: Current\\: %4.2lf\\n");
push(@tmp, "LINE1:l_imap#4444EE:");
push(@tmp, "LINE1:l_pop3#44EE44:");
push(@tmpz, "AREA:l_imap#4444EE:IMAP");
push(@tmpz, "AREA:l_pop3#44EE44:POP3");
push(@tmpz, "LINE2:l_imap#4444EE:");
push(@tmpz, "LINE2:l_pop3#44EE44:");
} else {
$vlabel = "Incremental hits";
push(@tmp, "AREA:i_imap#4444EE:IMAP");
push(@tmp, "GPRINT:i_imap:LAST: Current\\: %5.0lf\\n");
push(@tmp, "AREA:i_pop3#44EE44:POP3");
push(@tmp, "GPRINT:i_pop3:LAST: Current\\: %5.0lf\\n");
push(@tmp, "LINE1:i_imap#4444EE:");
push(@tmp, "LINE1:i_pop3#44EE44:");
push(@tmpz, "AREA:i_imap#4444EE:IMAP");
push(@tmpz, "AREA:i_pop3#44EE44:POP3");
push(@tmpz, "LINE2:i_imap#4444EE:");
push(@tmpz, "LINE2:i_pop3#44EE44:");
}
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG2",
"--title=$config->{graphs}->{_serv2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:i_imap=$rrd:serv_i_imap:AVERAGE",
"DEF:l_imap=$rrd:serv_l_imap:AVERAGE",
"DEF:i_pop3=$rrd:serv_i_pop3:AVERAGE",
"DEF:l_pop3=$rrd:serv_l_pop3:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG2z",
"--title=$config->{graphs}->{_serv2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:i_imap=$rrd:serv_i_imap:AVERAGE",
"DEF:l_imap=$rrd:serv_l_imap:AVERAGE",
"DEF:i_pop3=$rrd:serv_i_pop3:AVERAGE",
"DEF:l_pop3=$rrd:serv_l_pop3:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /serv2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG2z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG2z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "'>\n");
}
}
undef(@riglim);
if(trim($rigid[2]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
} else {
if(trim($rigid[2]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
if(lc($serv->{mode}) eq "l") {
$vlabel = "Accesses/s";
push(@tmp, "AREA:l_smtp#44EEEE:SMTP");
push(@tmp, "GPRINT:l_smtp:LAST: Current\\: %4.2lf\\n");
push(@tmp, "AREA:l_spam#EEEE44:Spam");
push(@tmp, "GPRINT:l_spam:LAST: Current\\: %4.2lf\\n");
push(@tmp, "AREA:l_virus#EE4444:Virus");
push(@tmp, "GPRINT:l_virus:LAST: Current\\: %4.2lf\\n");
push(@tmp, "LINE2:l_smtp#44EEEE");
push(@tmp, "LINE2:l_spam#EEEE44");
push(@tmp, "LINE2:l_virus#EE4444");
push(@tmpz, "AREA:l_smtp#44EEEE:SMTP");
push(@tmpz, "AREA:l_spam#EEEE44:Spam");
push(@tmpz, "AREA:l_virus#EE4444:Virus");
push(@tmpz, "LINE2:l_smtp#44EEEE");
push(@tmpz, "LINE2:l_spam#EEEE44");
push(@tmpz, "LINE2:l_virus#EE4444");
} else {
$vlabel = "Incremental hits";
push(@tmp, "AREA:i_smtp#44EEEE:SMTP");
push(@tmp, "GPRINT:i_smtp:LAST: Current\\: %5.0lf\\n");
push(@tmp, "AREA:i_spam#EEEE44:Spam");
push(@tmp, "GPRINT:i_spam:LAST: Current\\: %5.0lf\\n");
push(@tmp, "AREA:i_virus#EE4444:Virus");
push(@tmp, "GPRINT:i_virus:LAST: Current\\: %5.0lf\\n");
push(@tmp, "LINE2:i_smtp#44EEEE");
push(@tmp, "LINE2:i_spam#EEEE44");
push(@tmp, "LINE2:i_virus#EE4444");
push(@tmpz, "AREA:i_smtp#44EEEE:SMTP");
push(@tmpz, "AREA:i_spam#EEEE44:Spam");
push(@tmpz, "AREA:i_virus#EE4444:Virus");
push(@tmpz, "LINE2:i_smtp#44EEEE");
push(@tmpz, "LINE2:i_spam#EEEE44");
push(@tmpz, "LINE2:i_virus#EE4444");
}
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG3",
"--title=$config->{graphs}->{_serv3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:i_smtp=$rrd:serv_i_smtp:AVERAGE",
"DEF:i_spam=$rrd:serv_i_spam:AVERAGE",
"DEF:i_virus=$rrd:serv_i_virus:AVERAGE",
"DEF:l_smtp=$rrd:serv_l_smtp:AVERAGE",
"DEF:l_spam=$rrd:serv_l_spam:AVERAGE",
"DEF:l_virus=$rrd:serv_l_virus:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
undef(@tmp);
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG3z",
"--title=$config->{graphs}->{_serv3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=$vlabel",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:i_smtp=$rrd:serv_i_smtp:AVERAGE",
"DEF:i_spam=$rrd:serv_i_spam:AVERAGE",
"DEF:i_virus=$rrd:serv_i_virus:AVERAGE",
"DEF:l_smtp=$rrd:serv_l_smtp:AVERAGE",
"DEF:l_spam=$rrd:serv_l_spam:AVERAGE",
"DEF:l_virus=$rrd:serv_l_virus:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /serv3/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG3z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG3z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
1;

1463
lib/squid.pm Normal file

File diff suppressed because it is too large Load Diff

744
lib/system.pm Normal file
View File

@ -0,0 +1,744 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package system;
use strict;
use warnings;
use Monitorix;
use RRDs;
use Exporter 'import';
our @EXPORT = qw(system_init system_update system_cgi);
sub system_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
eval {
RRDs::create($rrd,
"--step=60",
"DS:system_load1:GAUGE:120:0:U",
"DS:system_load5:GAUGE:120:0:U",
"DS:system_load15:GAUGE:120:0:U",
"DS:system_nproc:GAUGE:120:0:U",
"DS:system_npslp:GAUGE:120:0:U",
"DS:system_nprun:GAUGE:120:0:U",
"DS:system_npwio:GAUGE:120:0:U",
"DS:system_npzom:GAUGE:120:0:U",
"DS:system_npstp:GAUGE:120:0:U",
"DS:system_npswp:GAUGE:120:0:U",
"DS:system_mtotl:GAUGE:120:0:U",
"DS:system_mbuff:GAUGE:120:0:U",
"DS:system_mcach:GAUGE:120:0:U",
"DS:system_mfree:GAUGE:120:0:U",
"DS:system_macti:GAUGE:120:0:U",
"DS:system_minac:GAUGE:120:0:U",
"DS:system_val01:GAUGE:120:0:U",
"DS:system_val02:GAUGE:120:0:U",
"DS:system_val03:GAUGE:120:0:U",
"DS:system_val04:GAUGE:120:0:U",
"DS:system_val05:GAUGE:120:0:U",
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
# check dependencies
if(lc($config->{enable_alerts}) eq "y") {
if(! -x $config->{alert_loadavg_script}) {
logger("$myself: ERROR: script '$config->{alert_loadavg_script}' doesn't exist or don't has execution permissions.");
}
}
$config->{system_hist} = 0;
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub system_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $load1;
my $load5;
my $load15;
my $nproc;
my $npslp;
my $nprun;
my $npwio;
my $npzom;
my $npstp;
my $npswp;
my $mtotl;
my $mbuff;
my $mcach;
my $mfree;
my $macti;
my $minac;
my $val01 = 0;
my $val02 = 0;
my $val03 = 0;
my $val04 = 0;
my $val05 = 0;
my $rrdata = "N";
$npwio = $npzom = $npstp = $npswp = 0;
if($config->{os} eq "Linux") {
open(IN, "/proc/loadavg");
while(<IN>) {
if(/^(\d+\.\d+) (\d+\.\d+) (\d+\.\d+) (\d+)\/(\d+)/) {
$load1 = $1;
$load5 = $2;
$load15 = $3;
$nprun = $4;
$npslp = $5;
}
}
close(IN);
$nproc = $npslp + $nprun;
open(IN, "/proc/meminfo");
while(<IN>) {
if(/^MemTotal:\s+(\d+) kB$/) {
$mtotl = $1;
next;
}
if(/^MemFree:\s+(\d+) kB$/) {
$mfree = $1;
next;
}
if(/^Buffers:\s+(\d+) kB$/) {
$mbuff = $1;
next;
}
if(/^Cached:\s+(\d+) kB$/) {
$mcach = $1;
last;
}
}
close(IN);
$macti = $minac = "";
} elsif($config->{os} eq "FreeBSD") {
my $page_size;
open(IN, "sysctl -n vm.loadavg |");
while(<IN>) {
if(/^\{ (\d+\.\d+) (\d+\.\d+) (\d+\.\d+) \}$/) {
$load1 = $1;
$load5 = $2;
$load15 = $3;
}
}
close(IN);
open(IN, "sysctl vm.vmtotal |");
while(<IN>) {
if(/^Processes:\s+\(RUNQ:\s+(\d+) Disk.*? Sleep:\s+(\d+)\)$/) {
$nprun = $1;
$npslp = $2;
}
if(/^Free Memory Pages:\s+(\d+)K$/) {
$mfree = $1;
}
}
close(IN);
$nproc = $npslp + $nprun;
$mtotl = `sysctl -n hw.realmem`;
$mbuff = `sysctl -n vfs.bufspace`;
$mcach = `sysctl -n vm.stats.vm.v_cache_count`;
chomp($mbuff);
$mbuff = $mbuff / 1024;
chomp($mtotl);
$mtotl = $mtotl / 1024;
$page_size = `sysctl -n vm.stats.vm.v_page_size`;
$macti = `sysctl -n vm.stats.vm.v_active_count`;
$minac = `sysctl -n vm.stats.vm.v_inactive_count`;
chomp($page_size, $mcach, $macti, $minac);
$mcach = ($page_size * $mcach) / 1024;
$macti = ($page_size * $macti) / 1024;
$minac = ($page_size * $minac) / 1024;
} elsif($config->{os} eq "OpenBSD" || $config->{os} eq "NetBSD") {
open(IN, "sysctl -n vm.loadavg |");
while(<IN>) {
if(/^(\d+\.\d+) (\d+\.\d+) (\d+\.\d+)$/) {
$load1 = $1;
$load5 = $2;
$load15 = $3;
}
}
close(IN);
open(IN, "top -b |");
while(<IN>) {
if(/ processes:/) {
$_ =~ s/:/,/;
my (@tmp) = split(',', $_);
foreach(@tmp) {
my ($num, $desc) = split(' ', $_);
$nproc = $num unless $desc ne "processes";
if(grep {$_ eq $desc} ("idle", "sleeping", "stopped", "zombie")) {
$npslp += $num;
}
if($desc eq "running" || $desc eq "on") {
$nprun += $num;
}
}
}
if($config->{os} eq "OpenBSD") {
if(/^Memory: Real: (\d+)\w\/\d+\w act\/tot Free: (\d+)\w /) {
$macti = $1;
$mfree = $2;
$macti = int($macti) * 1024;
$mfree = int($mfree) * 1024;
last;
}
}
if($config->{os} eq "NetBSD") {
if(/^Memory: (\d+)\w Act, .*, (\d+)\w Free/) {
$macti = $1;
$mfree = $2;
$macti = int($macti) * 1024;
$mfree = int($mfree) * 1024;
last;
}
}
}
close(IN);
$mtotl = `sysctl -n hw.physmem`;
chomp($mtotl);
$mtotl = $mtotl / 1024;
}
chomp(
$load1,
$load5,
$load15,
$nproc,
$npslp,
$nprun,
$npwio,
$npzom,
$npstp,
$npswp,
$mtotl,
$mbuff,
$mcach,
$mfree,
$macti,
$minac,
);
# SYSTEM alert
if(lc($config->{enable_alerts}) eq "y") {
if(!$config->{alert_loadavg_threshold} || $load15 < $config->{alert_loadavg_threshold}) {
$config->{system_hist} = 0;
} else {
if(!$config->{system_hist}) {
$config->{system_hist} = time;
}
if($config->{system_hist} > 0 && (time - $config->{system_hist}) > $config->{alert_loadavg_timeintvl}) {
if(-x $config->{alert_loadavg_script}) {
system($config->{alert_loadavg_script} . " " .$config->{alert_loadavg_timeintvl} . " " . $config->{alert_loadavg_threshold} . " " . $load15);
}
$config->{system_hist} = time;
}
}
}
$rrdata .= ":$load1:$load5:$load15:$nproc:$npslp:$nprun:$npwio:$npzom:$npstp:$npswp:$mtotl:$mbuff:$mcach:$mfree:$macti:$minac:$val01:$val02:$val03:$val04:$val05";
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub system_cgi {
my ($package, $config, $cgi) = @_;
my $system = $config->{system};
my @rigid = split(',', $system->{rigid});
my @limit = split(',', $system->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @tmp;
my @tmpz;
my $n;
my $err;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
my $total_mem;
if($config->{os} eq "Linux") {
$total_mem = `grep -w MemTotal: /proc/meminfo | awk '{print \$2}'`;
chomp($total_mem);
} elsif(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) {
$total_mem = `/sbin/sysctl -n hw.physmem`; # in bytes
chomp($total_mem);
$total_mem = int($total_mem / 1024); # in KB
}
$total_mem = int($total_mem / 1024); # in MB
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch($rrd,
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print(" CPU load average Memory usage in MB Processes\n");
print("Time 1min 5min 15min Used Cached Buffers Total Run\n");
print("------------------------------------------------------------- \n");
my $line;
my @row;
my $time;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
my ($load1, $load5, $load15, $nproc, $npslp, $nprun, $mtotl, $buff, $cach, $free) = @$line;
$buff /= 1024;
$cach /= 1024;
$free /= 1024;
@row = ($load1, $load5, $load15, $total_mem - $free, $cach, $buff, $nproc, $nprun);
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc} %4.1f %4.1f %4.1f %6d %6d %6d %5d %5d \n", $time, @row);
}
print("\n");
print(" system uptime: " . get_uptime($config) . "\n");
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
my $PNG1 = $u . $package . "1." . $tf->{when} . ".png";
my $PNG2 = $u . $package . "2." . $tf->{when} . ".png";
my $PNG3 = $u . $package . "3." . $tf->{when} . ".png";
my $PNG1z = $u . $package . "1z." . $tf->{when} . ".png";
my $PNG2z = $u . $package . "2z." . $tf->{when} . ".png";
my $PNG3z = $u . $package . "3z." . $tf->{when} . ".png";
unlink ("$PNG_DIR" . "$PNG1",
"$PNG_DIR" . "$PNG2",
"$PNG_DIR" . "$PNG3");
if(lc($config->{enable_zoom}) eq "y") {
unlink ("$PNG_DIR" . "$PNG1z",
"$PNG_DIR" . "$PNG2z",
"$PNG_DIR" . "$PNG3z");
}
if($title) {
main::graph_header($title, 2);
}
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
my $uptimeline;
if($RRDs::VERSION > 1.2) {
$uptimeline = "COMMENT:system uptime\\: " . get_uptime($config) . "\\c";
} else {
$uptimeline = "COMMENT:system uptime: " . get_uptime($config) . "\\c";
}
if($title) {
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
push(@tmp, "AREA:load1#4444EE: 1 min average");
push(@tmp, "GPRINT:load1:LAST: Current\\: %4.2lf");
push(@tmp, "GPRINT:load1:AVERAGE: Average\\: %4.2lf");
push(@tmp, "GPRINT:load1:MIN: Min\\: %4.2lf");
push(@tmp, "GPRINT:load1:MAX: Max\\: %4.2lf\\n");
push(@tmp, "LINE1:load1#0000EE");
push(@tmp, "LINE1:load5#EEEE00: 5 min average");
push(@tmp, "GPRINT:load5:LAST: Current\\: %4.2lf");
push(@tmp, "GPRINT:load5:AVERAGE: Average\\: %4.2lf");
push(@tmp, "GPRINT:load5:MIN: Min\\: %4.2lf");
push(@tmp, "GPRINT:load5:MAX: Max\\: %4.2lf\\n");
push(@tmp, "LINE1:load15#00EEEE:15 min average");
push(@tmp, "GPRINT:load15:LAST: Current\\: %4.2lf");
push(@tmp, "GPRINT:load15:AVERAGE: Average\\: %4.2lf");
push(@tmp, "GPRINT:load15:MIN: Min\\: %4.2lf");
push(@tmp, "GPRINT:load15:MAX: Max\\: %4.2lf\\n");
push(@tmpz, "AREA:load1#4444EE: 1 min average");
push(@tmpz, "LINE1:load1#0000EE");
push(@tmpz, "LINE1:load5#EEEE00: 5 min average");
push(@tmpz, "LINE1:load15#00EEEE:15 min average");
if($config->{os} eq "FreeBSD") {
push(@tmp, "COMMENT: \\n");
}
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG1",
"--title=$config->{graphs}->{_system1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Load average",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:load1=$rrd:system_load1:AVERAGE",
"DEF:load5=$rrd:system_load5:AVERAGE",
"DEF:load15=$rrd:system_load15:AVERAGE",
@tmp,
"COMMENT: \\n",
$uptimeline);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG1z",
"--title=$config->{graphs}->{_system1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Load average",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:load1=$rrd:system_load1:AVERAGE",
"DEF:load5=$rrd:system_load5:AVERAGE",
"DEF:load15=$rrd:system_load15:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /system1/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG1z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG1z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@riglim);
if(trim($rigid[1]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
} else {
if(trim($rigid[1]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:npslp#44AAEE:Sleeping");
push(@tmp, "AREA:nprun#EE4444:Running");
push(@tmp, "LINE1:nprun#EE0000");
push(@tmp, "LINE1:npslp#00EEEE");
push(@tmp, "LINE1:nproc#EEEE00:Processes");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG2",
"--title=$config->{graphs}->{_system2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Processes",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:nproc=$rrd:system_nproc:AVERAGE",
"DEF:npslp=$rrd:system_npslp:AVERAGE",
"DEF:nprun=$rrd:system_nprun:AVERAGE",
@tmp,
"COMMENT: \\n");
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG2z",
"--title=$config->{graphs}->{_system2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Processes",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:nproc=$rrd:system_nproc:AVERAGE",
"DEF:npslp=$rrd:system_npslp:AVERAGE",
"DEF:nprun=$rrd:system_nprun:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /system2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG2z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG2z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "'>\n");
}
}
undef(@tmp);
undef(@tmpz);
if($config->{os} eq "Linux") {
push(@tmp, "AREA:m_mused#EE4444:Used");
push(@tmp, "AREA:m_mcach#44EE44:Cached");
push(@tmp, "AREA:m_mbuff#CCCCCC:Buffers");
push(@tmp, "LINE1:m_mbuff#888888");
push(@tmp, "LINE1:m_mcach#00EE00");
push(@tmp, "LINE1:m_mused#EE0000");
} elsif($config->{os} eq "FreeBSD") {
push(@tmp, "AREA:m_mused#EE4444:Used");
push(@tmp, "AREA:m_mcach#44EE44:Cached");
push(@tmp, "AREA:m_mbuff#CCCCCC:Buffers");
push(@tmp, "AREA:m_macti#EEEE44:Active");
push(@tmp, "AREA:m_minac#4444EE:Inactive");
push(@tmp, "LINE1:m_minac#0000EE");
push(@tmp, "LINE1:m_macti#EEEE00");
push(@tmp, "LINE1:m_mbuff#888888");
push(@tmp, "LINE1:m_mcach#00EE00");
push(@tmp, "LINE1:m_mused#EE0000");
} elsif($config->{os} eq "OpenBSD" || $config->{os} eq "NetBSD") {
push(@tmp, "AREA:m_mused#EE4444:Used");
push(@tmp, "AREA:m_macti#44EE44:Active");
push(@tmp, "LINE1:m_macti#00EE00");
push(@tmp, "LINE1:m_mused#EE0000");
}
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG3",
"--title=$config->{graphs}->{_system3} (${total_mem}MB) ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Megabytes",
"--width=$width",
"--height=$height",
"--upper-limit=$total_mem",
"--lower-limit=0",
"--base=1024",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:mtotl=$rrd:system_mtotl:AVERAGE",
"DEF:mbuff=$rrd:system_mbuff:AVERAGE",
"DEF:mcach=$rrd:system_mcach:AVERAGE",
"DEF:mfree=$rrd:system_mfree:AVERAGE",
"DEF:macti=$rrd:system_macti:AVERAGE",
"DEF:minac=$rrd:system_minac:AVERAGE",
"CDEF:m_mtotl=mtotl,1024,/",
"CDEF:m_mbuff=mbuff,1024,/",
"CDEF:m_mcach=mcach,1024,/",
"CDEF:m_mused=m_mtotl,mfree,1024,/,-",
"CDEF:m_macti=macti,1024,/",
"CDEF:m_minac=minac,1024,/",
@tmp,
"COMMENT: \\n");
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG3z",
"--title=$config->{graphs}->{_system3} (${total_mem}MB) ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Megabytes",
"--width=$width",
"--height=$height",
"--upper-limit=$total_mem",
"--lower-limit=0",
"--base=1024",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:mtotl=$rrd:system_mtotl:AVERAGE",
"DEF:mbuff=$rrd:system_mbuff:AVERAGE",
"DEF:mcach=$rrd:system_mcach:AVERAGE",
"DEF:mfree=$rrd:system_mfree:AVERAGE",
"DEF:macti=$rrd:system_macti:AVERAGE",
"DEF:minac=$rrd:system_minac:AVERAGE",
"CDEF:m_mtotl=mtotl,1024,/",
"CDEF:m_mbuff=mbuff,1024,/",
"CDEF:m_mcach=mcach,1024,/",
"CDEF:m_mused=m_mtotl,mfree,1024,/,-",
"CDEF:m_macti=macti,1024,/",
"CDEF:m_minac=minac,1024,/",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /system3/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG3z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG3z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
sub get_uptime {
my $config = shift;
my $str;
my $uptime;
if($config->{os} eq "Linux") {
open(IN, "/proc/uptime");
($uptime, undef) = split(' ', <IN>);
close(IN);
} elsif($config->{os} eq "FreeBSD") {
open(IN, "/sbin/sysctl -n kern.boottime |");
(undef, undef, undef, $uptime) = split(' ', <IN>);
close(IN);
$uptime =~ s/,//;
$uptime = time - int($uptime);
} elsif($config->{os} eq "OpenBSD" || $config->{os} eq "NetBSD") {
open(IN, "/sbin/sysctl -n kern.boottime |");
$uptime = <IN>;
close(IN);
chomp($uptime);
$uptime = time - int($uptime);
}
my $d = int($uptime / (60 * 60 * 24));
my $h = int($uptime / (60 * 60)) % 24;
my $m = int($uptime / 60) % 60;
my $d_string = $d ? sprintf("%d days,", $d) : "";
my $h_string = $h ? sprintf("%d", $h) : "";
my $m_string = $h ? sprintf("%sh %dm", $h, $m) : sprintf("%d min", $m);
return "$d_string $m_string";
}
1;

460
lib/user.pm Normal file
View File

@ -0,0 +1,460 @@
#
# Monitorix - A lightweight system monitoring tool.
#
# Copyright (C) 2005-2013 by Jordi Sanfeliu <jordi@fibranet.cat>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
package user;
use strict;
use warnings;
use Monitorix;
use RRDs;
use Exporter 'import';
our @EXPORT = qw(user_init user_update user_cgi);
sub user_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
if(!(-e $rrd)) {
logger("Creating '$rrd' file.");
eval {
RRDs::create($rrd,
"--step=60",
"DS:user_sys:GAUGE:120:0:U",
"DS:user_smb:GAUGE:120:0:U",
"DS:user_mac:GAUGE:120:0:U",
"DS:user_val1:GAUGE:120:0:U",
"DS:user_val2:GAUGE:120:0:U",
"DS:user_val3:GAUGE:120:0:U",
"DS:user_val4:GAUGE:120:0:U",
"DS:user_val5:GAUGE:120:0:U",
"RRA:AVERAGE:0.5:1:1440",
"RRA:AVERAGE:0.5:30:336",
"RRA:AVERAGE:0.5:60:744",
"RRA:AVERAGE:0.5:1440:365",
"RRA:MIN:0.5:1:1440",
"RRA:MIN:0.5:30:336",
"RRA:MIN:0.5:60:744",
"RRA:MIN:0.5:1440:365",
"RRA:MAX:0.5:1:1440",
"RRA:MAX:0.5:30:336",
"RRA:MAX:0.5:60:744",
"RRA:MAX:0.5:1440:365",
"RRA:LAST:0.5:1:1440",
"RRA:LAST:0.5:30:336",
"RRA:LAST:0.5:60:744",
"RRA:LAST:0.5:1440:365",
);
};
my $err = RRDs::error;
if($@ || $err) {
logger("$@") unless !$@;
if($err) {
logger("ERROR: while creating $rrd: $err");
if($err eq "RRDs::error") {
logger("... is the RRDtool Perl package installed?");
}
}
return;
}
}
push(@{$config->{func_update}}, $package);
logger("$myself: Ok") if $debug;
}
sub user_update {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $sys;
my $smb;
my $mac;
my @data;
my $rrdata = "N";
open(IN, "who -q |");
while(<IN>) {
if(/^#\s+\S+=(\d+)/) {
$sys = $1;
last;
}
}
close(IN);
$smb = 0;
open(IN, "smbstatus -b 2>/dev/null |");
while(<IN>) {
if(/^----------/) {
$smb++;
next;
}
if($smb) {
$smb++ unless !$_;
}
}
close(IN);
$smb--;
open(IN, "macusers 2>/dev/null |");
@data = <IN>;
close(IN);
$mac = scalar(@data) - 1;
$mac = 0 unless @data;
$rrdata .= ":$sys:$smb:$mac:0:0:0:0:0";
RRDs::update($rrd, $rrdata);
logger("$myself: $rrdata") if $debug;
my $err = RRDs::error;
logger("ERROR: while updating $rrd: $err") if $err;
}
sub user_cgi {
my ($package, $config, $cgi) = @_;
my $user = $config->{user};
my @rigid = split(',', $user->{rigid});
my @limit = split(',', $user->{limit});
my $tf = $cgi->{tf};
my $colors = $cgi->{colors};
my $graph = $cgi->{graph};
my $silent = $cgi->{silent};
my $u = "";
my $width;
my $height;
my @riglim;
my @tmp;
my @tmpz;
my $n;
my $err;
my $rrd = $config->{base_lib} . $package . ".rrd";
my $title = $config->{graph_title}->{$package};
my $PNG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir};
$title = !$silent ? $title : "";
# text mode
#
if(lc($config->{iface_mode}) eq "text") {
if($title) {
main::graph_header($title, 2);
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
my (undef, undef, undef, $data) = RRDs::fetch("$rrd",
"--start=-$tf->{nwhen}$tf->{twhen}",
"AVERAGE",
"-r $tf->{res}");
$err = RRDs::error;
print("ERROR: while fetching $rrd: $err\n") if $err;
print(" <pre style='font-size: 12px; color: $colors->{fg_color}';>\n");
print("Time Logged In Samba Netatalk\n");
print("------------------------------------- \n");
my $line;
my @row;
my $time;
for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
$line = @$data[$n];
my ($sys, $smb, $mac) = @$line;
@row = ($sys, $smb, $mac);
$time = $time - (1 / $tf->{ts});
printf(" %2d$tf->{tc} %6d %6d %6d\n", $time, @row);
}
print(" </pre>\n");
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
# graph mode
#
if($silent eq "yes" || $silent eq "imagetag") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "_";
}
if($silent eq "imagetagbig") {
$colors->{fg_color} = "#000000"; # visible color for text mode
$u = "";
}
my $PNG1 = $u . $package . "1." . $tf->{when} . ".png";
my $PNG2 = $u . $package . "2." . $tf->{when} . ".png";
my $PNG3 = $u . $package . "3." . $tf->{when} . ".png";
my $PNG1z = $u . $package . "1z." . $tf->{when} . ".png";
my $PNG2z = $u . $package . "2z." . $tf->{when} . ".png";
my $PNG3z = $u . $package . "3z." . $tf->{when} . ".png";
unlink ("$PNG_DIR" . "$PNG1",
"$PNG_DIR" . "$PNG2",
"$PNG_DIR" . "$PNG3");
if(lc($config->{enable_zoom}) eq "y") {
unlink ("$PNG_DIR" . "$PNG1z",
"$PNG_DIR" . "$PNG2z",
"$PNG_DIR" . "$PNG3z");
}
if($title) {
main::graph_header($title, 2);
}
if(trim($rigid[0]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
} else {
if(trim($rigid[0]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[0]));
push(@riglim, "--rigid");
}
}
if($title) {
print(" <tr>\n");
print(" <td bgcolor='$colors->{title_bg_color}'>\n");
}
push(@tmp, "AREA:sys#44EE44:Logged In");
push(@tmp, "GPRINT:sys:LAST: Current\\: %3.0lf");
push(@tmp, "GPRINT:sys:AVERAGE: Average\\: %3.0lf");
push(@tmp, "GPRINT:sys:MIN: Min\\: %3.0lf");
push(@tmp, "GPRINT:sys:MAX: Max\\: %3.0lf\\n");
push(@tmp, "LINE1:sys#00EE00");
push(@tmpz, "AREA:sys#44EE44:Logged In");
push(@tmpz, "LINE1:sys#00EE00");
($width, $height) = split('x', $config->{graph_size}->{main});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
}
RRDs::graph("$PNG_DIR" . "$PNG1",
"--title=$config->{graphs}->{_user1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Users",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:sys=$rrd:user_sys:AVERAGE",
"COMMENT: \\n",
@tmp,
"COMMENT: \\n",
"COMMENT: \\n",
"COMMENT: \\n");
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG1z",
"--title=$config->{graphs}->{_user1} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Users",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$colors->{graph_colors}},
"DEF:sys=$rrd:user_sys:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG1z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /user1/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG1z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG1z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG1 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" <td valign='top' bgcolor='" . $colors->{title_bg_color} . "'>\n");
}
undef(@riglim);
if(trim($rigid[1]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
} else {
if(trim($rigid[1]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[1]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:smb#EEEE44:Samba");
push(@tmp, "GPRINT:smb:LAST: Current\\: %3.0lf\\n");
push(@tmp, "LINE1:smb#EEEE00");
push(@tmpz, "AREA:smb#EEEE44:Samba");
push(@tmpz, "LINE2:smb#EEEE00");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG2",
"--title=$config->{graphs}->{_user2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Users",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:smb=$rrd:user_smb:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG2z",
"--title=$config->{graphs}->{_user2} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Users",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:smb=$rrd:user_smb:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG2z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /user2/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG2z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG2z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG2 . "'>\n");
}
}
undef(@riglim);
if(trim($rigid[2]) eq 1) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
} else {
if(trim($rigid[2]) eq 2) {
push(@riglim, "--upper-limit=" . trim($limit[2]));
push(@riglim, "--rigid");
}
}
undef(@tmp);
undef(@tmpz);
push(@tmp, "AREA:mac#EE4444:Netatalk");
push(@tmp, "GPRINT:mac:LAST: Current\\: %3.0lf\\n");
push(@tmp, "LINE1:mac#EE0000");
push(@tmpz, "AREA:mac#EE4444:Netatalk");
push(@tmpz, "LINE2:mac#EE0000");
($width, $height) = split('x', $config->{graph_size}->{small});
if($silent =~ /imagetag/) {
($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag";
($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig";
@tmp = @tmpz;
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
push(@tmp, "COMMENT: \\n");
}
RRDs::graph("$PNG_DIR" . "$PNG3",
"--title=$config->{graphs}->{_user3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Users",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:mac=$rrd:user_mac:AVERAGE",
@tmp);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3: $err\n") if $err;
if(lc($config->{enable_zoom}) eq "y") {
($width, $height) = split('x', $config->{graph_size}->{zoom});
RRDs::graph("$PNG_DIR" . "$PNG3z",
"--title=$config->{graphs}->{_user3} ($tf->{nwhen}$tf->{twhen})",
"--start=-$tf->{nwhen}$tf->{twhen}",
"--imgformat=PNG",
"--vertical-label=Users",
"--width=$width",
"--height=$height",
@riglim,
"--lower-limit=0",
@{$cgi->{version12}},
@{$cgi->{version12_small}},
@{$colors->{graph_colors}},
"DEF:mac=$rrd:user_mac:AVERAGE",
@tmpz);
$err = RRDs::error;
print("ERROR: while graphing $PNG_DIR" . "$PNG3z: $err\n") if $err;
}
if($title || ($silent =~ /imagetag/ && $graph =~ /user3/)) {
if(lc($config->{enable_zoom}) eq "y") {
if(lc($config->{disable_javascript_void}) eq "y") {
print(" <a href=\"" . $config->{url} . $config->{imgs_dir} . $PNG3z . "\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
else {
print(" <a href=\"javascript:void(window.open('" . $config->{url} . $config->{imgs_dir} . $PNG3z . "','','width=" . ($width + 115) . ",height=" . ($height + 100) . ",scrollbars=0,resizable=0'))\"><img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "' border='0'></a>\n");
}
} else {
print(" <img src='" . $config->{url} . $config->{imgs_dir} . $PNG3 . "'>\n");
}
}
if($title) {
print(" </td>\n");
print(" </tr>\n");
main::graph_footer();
}
print(" <br>\n");
return;
}
1;

6843
monitorix

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff