1631 lines
52 KiB
Perl
1631 lines
52 KiB
Perl
#!/usr/bin/perl -w
|
|
|
|
package MyRRD;
|
|
|
|
use strict;
|
|
use Data::Dumper;
|
|
use LWP::UserAgent;
|
|
use IO::Socket::UNIX;
|
|
use JSON;
|
|
use Digest::MD5 qw(md5_hex);
|
|
|
|
sub new
|
|
{
|
|
my $this = shift;
|
|
my $rrd = shift;
|
|
my $img = shift;
|
|
|
|
# bless object
|
|
$this = ref $this if ref $this;
|
|
# instantiate
|
|
my $obj = bless {
|
|
_rrd => $rrd,
|
|
_img => $img,
|
|
_rrdtool => '/usr/bin/rrdtool',
|
|
}, $this;
|
|
return $obj;
|
|
}
|
|
|
|
sub networkInterface
|
|
{
|
|
my $this = shift;
|
|
my $iface = shift;
|
|
my $title = shift;
|
|
|
|
my $regexpiface = $iface;
|
|
$regexpiface =~ s/\./\\\./;
|
|
my $in = 0;
|
|
my $out = 0;
|
|
open IN, "</proc/net/dev";
|
|
while (<IN>)
|
|
{
|
|
if (my @expr = m/^\s*$regexpiface:\s*(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+(\d+)/)
|
|
{
|
|
$in = $expr[0] || 0;
|
|
$out = $expr[1] || 0;
|
|
last;
|
|
}
|
|
}
|
|
close (IN);
|
|
|
|
print "$iface trafic in, out: $in, $out\n";
|
|
|
|
my $filename = "$this->{_rrd}/nic-$iface.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for $iface interface...\n";
|
|
system "$this->{_rrdtool} create \"$filename\" -s 300 \\
|
|
DS:in:DERIVE:600:0:U \\
|
|
DS:out:DERIVE:600:0:U \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t in:out N:$in:$out";
|
|
$this->networkGraph($iface, 'day', $title);
|
|
$this->networkGraph($iface, 'week', $title);
|
|
$this->networkGraph($iface, 'month', $title);
|
|
$this->networkGraph($iface, 'year', $title);
|
|
}
|
|
|
|
sub networkGraph
|
|
{
|
|
my $this = shift;
|
|
my $iface = shift;
|
|
my $type = shift;
|
|
my $title = shift;
|
|
|
|
my $rrd_filename = "$this->{_rrd}/nic-$iface.rrd";
|
|
my $graph_filename = "$this->{_img}/nic-$iface-$type.png";
|
|
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
-s -1$type \\
|
|
-t 'Trafic sur $iface :: $title' \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-h 250 -w 1100 \\
|
|
--border 0 \\
|
|
-l 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"o/s\" \\
|
|
DEF:in=$rrd_filename:in:AVERAGE \\
|
|
DEF:out=$rrd_filename:out:AVERAGE \\
|
|
CDEF:out_neg=out,-1,* \\
|
|
VDEF:inmax=in,MAXIMUM \\
|
|
VDEF:inavg=in,AVERAGE \\
|
|
VDEF:inlast=in,LAST \\
|
|
VDEF:outmax=out,MAXIMUM \\
|
|
VDEF:outavg=out,AVERAGE \\
|
|
VDEF:outlast=out,LAST \\
|
|
AREA:in#A0E59C:\"Incoming\t\t\" \\
|
|
GPRINT:inmax:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:inavg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:inlast:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
AREA:out_neg#68A5D3:\"Outgoing\t\t\" \\
|
|
GPRINT:outmax:\"Max\\: %8.2lf %S\" \\
|
|
GPRINT:outavg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:outlast:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
HRULE:0#202020 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub prioMap
|
|
{
|
|
my $this = shift;
|
|
my $in = shift;
|
|
my $out = shift;
|
|
|
|
open IN, "/sbin/tc -s qdisc show dev $in 2> /dev/null | grep \"^ Sent\" |";
|
|
my @inqueues;
|
|
while (<IN>)
|
|
{
|
|
chomp;
|
|
/^ Sent (\d+) bytes.*$/;
|
|
my $bytes = $1 || 0;
|
|
push @inqueues, $bytes;
|
|
}
|
|
close IN;
|
|
shift @inqueues;
|
|
|
|
open OUT, "/sbin/tc -s qdisc show dev $out 2> /dev/null | grep \"^ Sent\" |";
|
|
my @outqueues;
|
|
while (<OUT>)
|
|
{
|
|
chomp;
|
|
/^ Sent (\d+) bytes.*$/;
|
|
my $bytes = $1 || 0;
|
|
push @outqueues, $bytes;
|
|
}
|
|
close OUT;
|
|
shift @outqueues;
|
|
|
|
print "tc1 in/out: $inqueues[0]/$outqueues[0] bytes\n";
|
|
print "tc2 in/out: $inqueues[1]/$outqueues[1] bytes\n";
|
|
print "tc3 in/out: $inqueues[2]/$outqueues[2] bytes\n";
|
|
print "tc4 in/out: $inqueues[3]/$outqueues[3] bytes\n";
|
|
|
|
my $filename = "$this->{_rrd}/tc-$in-$out.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for client tc-ppp0...\n";
|
|
system "$this->{_rrdtool} create \"$filename\" \\
|
|
-s 300 \\
|
|
DS:intc1:DERIVE:600:0:U \\
|
|
DS:intc2:DERIVE:600:0:U \\
|
|
DS:intc3:DERIVE:600:0:U \\
|
|
DS:intc4:DERIVE:600:0:U \\
|
|
DS:outtc1:DERIVE:600:0:U \\
|
|
DS:outtc2:DERIVE:600:0:U \\
|
|
DS:outtc3:DERIVE:600:0:U \\
|
|
DS:outtc4:DERIVE:600:0:U \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t intc1:intc2:intc3:intc4:outtc1:outtc2:outtc3:outtc4 \\
|
|
N:$inqueues[0]:$inqueues[1]:$inqueues[2]:$inqueues[3]:$outqueues[0]:$outqueues[1]:$outqueues[2]:$outqueues[3]";
|
|
|
|
$this->tcGraph("tc-$in-$out", 'day');
|
|
$this->tcGraph("tc-$in-$out", 'week');
|
|
$this->tcGraph("tc-$in-$out", 'month');
|
|
$this->tcGraph("tc-$in-$out", 'year');
|
|
}
|
|
|
|
sub tcGraph
|
|
{
|
|
my $this = shift;
|
|
my $name = shift;
|
|
my $type = shift;
|
|
|
|
system "$this->{_rrdtool} graph \"$this->{_img}/$name-$type.png\" \\
|
|
-s -1$type \\
|
|
-t \"Traffic shapping ADSL (ATM rate)\" \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-h 250 -w 1100 \\
|
|
--border 0 \\
|
|
-l 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"o/s\" \\
|
|
DEF:intc1=$this->{_rrd}/$name.rrd:intc1:AVERAGE \\
|
|
DEF:intc2=$this->{_rrd}/$name.rrd:intc2:AVERAGE \\
|
|
DEF:intc3=$this->{_rrd}/$name.rrd:intc3:AVERAGE \\
|
|
DEF:intc4=$this->{_rrd}/$name.rrd:intc4:AVERAGE \\
|
|
DEF:outtc1=$this->{_rrd}/$name.rrd:outtc1:AVERAGE \\
|
|
DEF:outtc2=$this->{_rrd}/$name.rrd:outtc2:AVERAGE \\
|
|
DEF:outtc3=$this->{_rrd}/$name.rrd:outtc3:AVERAGE \\
|
|
DEF:outtc4=$this->{_rrd}/$name.rrd:outtc4:AVERAGE \\
|
|
CDEF:outtc1_neg=outtc1,-1,* \\
|
|
CDEF:outtc2_neg=outtc2,-1,* \\
|
|
CDEF:outtc3_neg=outtc3,-1,* \\
|
|
CDEF:outtc4_neg=outtc4,-1,* \\
|
|
VDEF:intc1max=intc1,MAXIMUM \\
|
|
VDEF:intc1avg=intc1,AVERAGE \\
|
|
VDEF:intc1last=intc1,LAST \\
|
|
VDEF:intc2max=intc2,MAXIMUM \\
|
|
VDEF:intc2avg=intc2,AVERAGE \\
|
|
VDEF:intc2last=intc2,LAST \\
|
|
VDEF:intc3max=intc3,MAXIMUM \\
|
|
VDEF:intc3avg=intc3,AVERAGE \\
|
|
VDEF:intc3last=intc3,LAST \\
|
|
VDEF:intc4max=intc4,MAXIMUM \\
|
|
VDEF:intc4avg=intc4,AVERAGE \\
|
|
VDEF:intc4last=intc4,LAST \\
|
|
VDEF:outtc1max=outtc1,MAXIMUM \\
|
|
VDEF:outtc1avg=outtc1,AVERAGE \\
|
|
VDEF:outtc1last=outtc1,LAST \\
|
|
VDEF:outtc2max=outtc2,MAXIMUM \\
|
|
VDEF:outtc2avg=outtc2,AVERAGE \\
|
|
VDEF:outtc2last=outtc2,LAST \\
|
|
VDEF:outtc3max=outtc3,MAXIMUM \\
|
|
VDEF:outtc3avg=outtc3,AVERAGE \\
|
|
VDEF:outtc3last=outtc3,LAST \\
|
|
VDEF:outtc4max=outtc4,MAXIMUM \\
|
|
VDEF:outtc4avg=outtc4,AVERAGE \\
|
|
VDEF:outtc4last=outtc4,LAST \\
|
|
COMMENT:\"Incomming\\n\" \\
|
|
AREA:intc4#E3D85D:\"Low+Guest\t\" \\
|
|
GPRINT:intc4max:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:intc4avg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:intc4last:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
AREA:intc3#68A5D3:\"Defaut\t\t\":STACK \\
|
|
GPRINT:intc3max:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:intc3avg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:intc3last:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
AREA:intc2#A0E59C:\"Mail\t\t\":STACK \\
|
|
GPRINT:intc2max:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:intc2avg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:intc2last:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
AREA:intc1#E36363:\"Interactif\t\":STACK \\
|
|
GPRINT:intc1max:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:intc1avg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:intc1last:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
COMMENT:\"Outgoing\\n\" \\
|
|
AREA:outtc4_neg#E3D85D:\"Low+Guest\t\" \\
|
|
GPRINT:outtc4max:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:outtc4avg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:outtc4last:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
AREA:outtc3_neg#68A5D3:\"Defaut\t\t\":STACK \\
|
|
GPRINT:outtc3max:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:outtc3avg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:outtc3last:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
AREA:outtc2_neg#A0E59C:\"Mail\t\t\":STACK \\
|
|
GPRINT:outtc2max:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:outtc2avg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:outtc2last:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
AREA:outtc1_neg#E36363:\"Interactif\t\":STACK \\
|
|
GPRINT:outtc1max:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:outtc1avg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:outtc1last:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
HRULE:0#202020 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub cpu
|
|
{
|
|
my $this = shift;
|
|
my $stat = `grep '^cpu ' /proc/stat`;
|
|
my @res = ($stat =~ m/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/);
|
|
my $user = $res[0];
|
|
my $nice = $res[1];
|
|
my $sys = $res[2];
|
|
my $iowait = $res[4];
|
|
print "CPU user : $user\n";
|
|
print "CPU nice : $nice\n";
|
|
print "CPU systeme : $sys\n";
|
|
print "CPU iowait : $iowait\n";
|
|
|
|
my $filename = "$this->{_rrd}/system-cpu.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for cpu...\n";
|
|
system "$this->{_rrdtool} create \"$filename\" \\
|
|
-s 300 \\
|
|
DS:user:DERIVE:600:0:U \\
|
|
DS:sys:DERIVE:600:0:U \\
|
|
DS:nice:DERIVE:600:0:U \\
|
|
DS:iowait:DERIVE:600:0:U \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t user:sys:nice:iowait N:$user:$sys:$nice:$iowait";
|
|
|
|
$this->cpuGraph('day');
|
|
$this->cpuGraph('week');
|
|
$this->cpuGraph('month');
|
|
$this->cpuGraph('year');
|
|
}
|
|
|
|
sub cpuGraph
|
|
{
|
|
my $this = shift;
|
|
my $type = shift;
|
|
|
|
my $rrd_filename = "$this->{_rrd}/system-cpu.rrd";
|
|
my $graph_filename = "$this->{_img}/system-cpu-$type.png";
|
|
|
|
my $ncpu=`grep -E '^cpu[0-9]+ ' /proc/stat | wc -l`;
|
|
my $max = $ncpu * 100;
|
|
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-s -1$type \\
|
|
-t \"Utilisation CPU\" \\
|
|
-h 250 -w 1100 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"%\" \\
|
|
-u $max \\
|
|
-l 0 \\
|
|
-r \\
|
|
DEF:user=$rrd_filename:user:AVERAGE \\
|
|
DEF:sys=$rrd_filename:sys:AVERAGE \\
|
|
DEF:iowait=$rrd_filename:iowait:AVERAGE \\
|
|
DEF:nice=$rrd_filename:nice:AVERAGE \\
|
|
VDEF:usermax=user,MAXIMUM \\
|
|
VDEF:useravg=user,AVERAGE \\
|
|
VDEF:userlast=user,LAST \\
|
|
VDEF:sysmax=sys,MAXIMUM \\
|
|
VDEF:sysavg=sys,AVERAGE \\
|
|
VDEF:syslast=sys,LAST \\
|
|
VDEF:iowaitmax=iowait,MAXIMUM \\
|
|
VDEF:iowaitavg=iowait,AVERAGE \\
|
|
VDEF:iowaitlast=iowait,LAST \\
|
|
VDEF:nicemax=nice,MAXIMUM \\
|
|
VDEF:niceavg=nice,AVERAGE \\
|
|
VDEF:nicelast=nice,LAST \\
|
|
AREA:user#A0E59C:\"Utilisateur\t\" \\
|
|
GPRINT:usermax:\"Max\\: %6.2lf\" \\
|
|
GPRINT:useravg:\"\tAvg\\: %6.2lf\" \\
|
|
GPRINT:userlast:\"\tCurrent\\: %6.2lf %%\\n\" \\
|
|
AREA:sys#E36363:\"Systeme\t\t\":STACK \\
|
|
GPRINT:sysmax:\"Max\\: %6.2lf\" \\
|
|
GPRINT:sysavg:\"\tAvg\\: %6.2lf\" \\
|
|
GPRINT:syslast:\"\tCurrent\\: %6.2lf %%\\n\" \\
|
|
AREA:iowait#E3D85D:\"IO wait\t\t\":STACK \\
|
|
GPRINT:iowaitmax:\"Max\\: %6.2lf\" \\
|
|
GPRINT:iowaitavg:\"\tAvg\\: %6.2lf\" \\
|
|
GPRINT:iowaitlast:\"\tCurrent\\: %6.2lf %%\\n\" \\
|
|
AREA:nice#68A5D3:\"Nice\t\t\":STACK \\
|
|
GPRINT:nicemax:\"Max\\: %6.2lf\" \\
|
|
GPRINT:niceavg:\"\tAvg\\: %6.2lf\" \\
|
|
GPRINT:nicelast:\"\tCurrent\\: %6.2lf %%\\n\" \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub memory
|
|
{
|
|
my $this = shift;
|
|
my $ramMax = shift;
|
|
my $swapMax = shift;
|
|
my $mems = ();
|
|
open IN, "</proc/meminfo";
|
|
while (<IN>)
|
|
{
|
|
if (/^(\w+):\s*(\d+)\s+kb/i)
|
|
{
|
|
$mems->{$1} = $2 / 1024;
|
|
}
|
|
}
|
|
close (IN);
|
|
|
|
my $total = ($mems->{'MemTotal'} || 0) - ($mems->{'MemFree'} || 0);
|
|
my $apps = ($mems->{'MemTotal'} || 0) - ($mems->{'MemFree'} || 0) - ($mems->{'Buffers'} || 0) - ($mems->{'Cached'} || 0) - ($mems->{'Slab'} || 0) - ($mems->{'PageTables'} || 0);
|
|
my $cache = $mems->{'Cached'} || 0;
|
|
my $buffers = $mems->{'Buffers'} || 0;
|
|
my $slab = $mems->{'Slab'} || 0;
|
|
my $swap = ($mems->{'SwapTotal'} || 0) - ($mems->{'SwapFree'} || 0);
|
|
print "Total : $total\n";
|
|
print "Apps : $apps\n";
|
|
print "Cache : $cache\n";
|
|
print "Buffers : $buffers\n";
|
|
print "Slab : $slab\n";
|
|
print "Swap : $swap\n";
|
|
|
|
my $filename = "$this->{_rrd}/system-mem.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for mem...\n";
|
|
system "$this->{_rrdtool} create \"$filename\" \\
|
|
-s 300 \\
|
|
DS:apps:GAUGE:600:0:$ramMax \\
|
|
DS:cache:GAUGE:600:0:$ramMax \\
|
|
DS:buffers:GAUGE:600:0:$ramMax \\
|
|
DS:slab:GAUGE:600:0:$ramMax \\
|
|
DS:total:GAUGE:600:0:$ramMax \\
|
|
DS:swap:GAUGE:600:0:$swapMax \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t apps:cache:buffers:slab:total:swap N:$apps:$cache:$buffers:$slab:$total:$swap";
|
|
|
|
$this->memoryGraph('day');
|
|
$this->memoryGraph('week');
|
|
$this->memoryGraph('month');
|
|
$this->memoryGraph('year');
|
|
}
|
|
|
|
sub memoryGraph
|
|
{
|
|
my $this = shift;
|
|
my $type = shift;
|
|
|
|
my $rrd_filename = "$this->{_rrd}/system-mem.rrd";
|
|
my $graph_filename = "$this->{_img}/system-mem-$type.png";
|
|
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-s -1$type \\
|
|
-t \"Utilisation Memoire\" \\
|
|
-h 250 -w 1100 \\
|
|
-l 0 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"Mo\" \\
|
|
-b 1024 \\
|
|
DEF:apps=$rrd_filename:apps:AVERAGE \\
|
|
DEF:cache=$rrd_filename:cache:AVERAGE \\
|
|
DEF:buffers=$rrd_filename:buffers:AVERAGE \\
|
|
DEF:slab=$rrd_filename:slab:AVERAGE \\
|
|
DEF:total=$rrd_filename:total:AVERAGE \\
|
|
DEF:swap=$rrd_filename:swap:AVERAGE \\
|
|
CDEF:swap_neg=swap,-1,* \\
|
|
VDEF:appsmin=apps,MINIMUM \\
|
|
VDEF:appsmax=apps,MAXIMUM \\
|
|
VDEF:appsavg=apps,AVERAGE \\
|
|
VDEF:appslast=apps,LAST \\
|
|
VDEF:cachemin=cache,MINIMUM \\
|
|
VDEF:cachemax=cache,MAXIMUM \\
|
|
VDEF:cacheavg=cache,AVERAGE \\
|
|
VDEF:cachelast=cache,LAST \\
|
|
VDEF:buffersmin=buffers,MINIMUM \\
|
|
VDEF:buffersmax=buffers,MAXIMUM \\
|
|
VDEF:buffersavg=buffers,AVERAGE \\
|
|
VDEF:bufferslast=buffers,LAST \\
|
|
VDEF:slabmin=slab,MINIMUM \\
|
|
VDEF:slabmax=slab,MAXIMUM \\
|
|
VDEF:slabavg=slab,AVERAGE \\
|
|
VDEF:slablast=slab,LAST \\
|
|
VDEF:totalmin=total,MINIMUM \\
|
|
VDEF:totalmax=total,MAXIMUM \\
|
|
VDEF:totalavg=total,AVERAGE \\
|
|
VDEF:totallast=total,LAST \\
|
|
VDEF:swapmin=swap,MINIMUM \\
|
|
VDEF:swapmax=swap,MAXIMUM \\
|
|
VDEF:swapavg=swap,AVERAGE \\
|
|
VDEF:swaplast=swap,LAST \\
|
|
AREA:total#3B743F:\"Total\t\" \\
|
|
GPRINT:totalmin:\"Min\\: %8.2lf\" \\
|
|
GPRINT:totalmax:\"\tMax\\: %8.2lf\" \\
|
|
GPRINT:totalavg:\"\tAvg\\: %8.2lf\" \\
|
|
GPRINT:totallast:\"\tCurrent\\: %8.2lf Mo\\n\" \\
|
|
AREA:apps#E36363:\"Apps\t\" \\
|
|
GPRINT:appsmin:\"Min\\: %8.2lf\" \\
|
|
GPRINT:appsmax:\"\tMax\\: %8.2lf\" \\
|
|
GPRINT:appsavg:\"\tAvg\\: %8.2lf\" \\
|
|
GPRINT:appslast:\"\tCurrent\\: %8.2lf Mo\\n\" \\
|
|
AREA:cache#68A5D3:\"Cache\t\":STACK \\
|
|
GPRINT:cachemin:\"Min\\: %8.2lf\" \\
|
|
GPRINT:cachemax:\"\tMax\\: %8.2lf\" \\
|
|
GPRINT:cacheavg:\"\tAvg\\: %8.2lf\" \\
|
|
GPRINT:cachelast:\"\tCurrent\\: %8.2lf Mo\\n\" \\
|
|
AREA:buffers#3D617C:\"Buffers\t\":STACK \\
|
|
GPRINT:buffersmin:\"Min\\: %8.2lf\" \\
|
|
GPRINT:buffersmax:\"\tMax\\: %8.2lf\" \\
|
|
GPRINT:buffersavg:\"\tAvg\\: %8.2lf\" \\
|
|
GPRINT:bufferslast:\"\tCurrent\\: %8.2lf Mo\\n\" \\
|
|
AREA:slab#A0E59C:\"Slab\t\":STACK \\
|
|
GPRINT:slabmin:\"Min\\: %8.2lf\" \\
|
|
GPRINT:slabmax:\"\tMax\\: %8.2lf\" \\
|
|
GPRINT:slabavg:\"\tAvg\\: %8.2lf\" \\
|
|
GPRINT:slablast:\"\tCurrent\\: %8.2lf Mo\\n\" \\
|
|
AREA:swap_neg#E3D85D:\"Swap\t\" \\
|
|
GPRINT:swapmin:\"Min\\: %8.2lf\" \\
|
|
GPRINT:swapmax:\"\tMax\\: %8.2lf\" \\
|
|
GPRINT:swapavg:\"\tAvg\\: %8.2lf\" \\
|
|
GPRINT:swaplast:\"\tCurrent\\: %8.2lf Mo\\n\" \\
|
|
HRULE:0#202020 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub load
|
|
{
|
|
my $this = shift;
|
|
my $charge=`cut -f2 -d' ' < /proc/loadavg`;
|
|
chomp $charge;
|
|
print "CPU Load : $charge\n";
|
|
|
|
my $filename = "$this->{_rrd}/system-load.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for load...\n";
|
|
system "$this->{_rrdtool} create \"$filename\" \\
|
|
-s 300 \\
|
|
DS:charge:GAUGE:600:0:100 \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t charge N:$charge";
|
|
|
|
$this->loadGraph('day');
|
|
$this->loadGraph('week');
|
|
$this->loadGraph('month');
|
|
$this->loadGraph('year');
|
|
}
|
|
|
|
sub loadGraph
|
|
{
|
|
my $this = shift;
|
|
my $type = shift;
|
|
|
|
my $rrd_filename = "$this->{_rrd}/system-load.rrd";
|
|
my $graph_filename = "$this->{_img}/system-load-$type.png";
|
|
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-s -1$type \\
|
|
-t \"Charge Systeme\" \\
|
|
-X 0 \\
|
|
-h 250 -w 1100 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v load \\
|
|
DEF:charge=$rrd_filename:charge:AVERAGE \\
|
|
VDEF:chargemax=charge,MAXIMUM \\
|
|
VDEF:chargeavg=charge,AVERAGE \\
|
|
VDEF:chargelast=charge,LAST \\
|
|
LINE1.5:charge#3D617C:\"Charge Systeme\t\" \\
|
|
GPRINT:chargemax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:chargeavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:chargelast:\"\tCurrent\\: %4.2lf\\n\" \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub cswitch
|
|
{
|
|
my $this = shift;
|
|
my $intr;
|
|
my $ctxt;
|
|
|
|
open IN, "</proc/stat";
|
|
while (my $line = <IN>)
|
|
{
|
|
if (my ($val) = ($line =~ m/^intr\s+(\d+)/))
|
|
{
|
|
$intr = $val;
|
|
}
|
|
if (my ($val) = ($line =~ m/^ctxt\s+(\d+)/))
|
|
{
|
|
$ctxt = $val;
|
|
}
|
|
}
|
|
close (IN);
|
|
|
|
print "Interrupts: $intr\n";
|
|
print "Context switches: $ctxt\n";
|
|
|
|
my $filename = "$this->{_rrd}/system-cswitch.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for cswitch...\n";
|
|
system "$this->{_rrdtool} create \"$filename\" -s 300 \\
|
|
DS:intr:DERIVE:600:0:100000 \\
|
|
DS:ctxt:DERIVE:600:0:100000 \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t intr:ctxt N:$intr:$ctxt";
|
|
$this->cswitchGraph('day');
|
|
$this->cswitchGraph('week');
|
|
$this->cswitchGraph('month');
|
|
$this->cswitchGraph('year');
|
|
}
|
|
|
|
sub cswitchGraph
|
|
{
|
|
my $this = shift;
|
|
my $type = shift;
|
|
|
|
my $rrd_filename = "$this->{_rrd}/system-cswitch.rrd";
|
|
my $graph_filename = "$this->{_img}/system-cswitch-$type.png";
|
|
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
-s -1$type \\
|
|
-t 'Interrupts / Context switches' \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-h 250 -w 1100 \\
|
|
-l 0 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"unit/s\" \\
|
|
DEF:ctxt=$rrd_filename:ctxt:AVERAGE \\
|
|
DEF:intr=$rrd_filename:intr:AVERAGE \\
|
|
VDEF:ctxtmax=ctxt,MAXIMUM \\
|
|
VDEF:ctxtavg=ctxt,AVERAGE \\
|
|
VDEF:ctxtlast=ctxt,LAST \\
|
|
VDEF:intrmax=intr,MAXIMUM \\
|
|
VDEF:intravg=intr,AVERAGE \\
|
|
VDEF:intrlast=intr,LAST \\
|
|
LINE1.5:ctxt#3D617C:\"Context switches\t\" \\
|
|
GPRINT:ctxtmax:\"Max\\: %8.2lf %S\" \\
|
|
GPRINT:ctxtavg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:ctxtlast:\"\tCurrent\\: %8.2lf %Sunit/s\\n\" \\
|
|
LINE1.5:intr#3B743F:\"Interrupts\t\t\" \\
|
|
GPRINT:intrmax:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:intravg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:intrlast:\"\tCurrent\\: %8.2lf %Sunit/s\\n\" \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub iostat
|
|
{
|
|
my $this = shift;
|
|
my $device = shift;
|
|
|
|
my $devstring = `grep ' $device ' /proc/diskstats`;
|
|
|
|
my ($rio, $rmerge, $rsect, $ruse, $wio, $wmerge, $wsect, $wuse) = ($devstring =~ m/$device\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/);
|
|
|
|
print "I/O read: $rsect\n";
|
|
print "I/O write: $wsect\n";
|
|
|
|
my $filename = "$this->{_rrd}/system-iostat-$device.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for cswitch...\n";
|
|
system "$this->{_rrdtool} create \"$filename\" -s 300 \\
|
|
DS:rsect:DERIVE:600:0:U \\
|
|
DS:wsect:DERIVE:600:0:U \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t rsect:wsect N:$rsect:$wsect";
|
|
$this->iostatGraph($device, 'day');
|
|
$this->iostatGraph($device, 'week');
|
|
$this->iostatGraph($device, 'month');
|
|
$this->iostatGraph($device, 'year');
|
|
}
|
|
|
|
sub iostatGraph
|
|
{
|
|
my $this = shift;
|
|
my $device = shift;
|
|
my $type = shift;
|
|
|
|
my $rrd_filename = "$this->{_rrd}/system-iostat-$device.rrd";
|
|
my $graph_filename = "$this->{_img}/system-iostat-$device-$type.png";
|
|
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
-s -1$type \\
|
|
-t 'I/O :: /dev/$device' \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-h 250 -w 1100 \\
|
|
-l 0 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"blocs/s\" \\
|
|
DEF:wsect=$rrd_filename:wsect:AVERAGE \\
|
|
DEF:rsect=$rrd_filename:rsect:AVERAGE \\
|
|
VDEF:wsectmax=wsect,MAXIMUM \\
|
|
VDEF:wsectavg=wsect,AVERAGE \\
|
|
VDEF:wsectlast=wsect,LAST \\
|
|
VDEF:rsectmax=rsect,MAXIMUM \\
|
|
VDEF:rsectavg=rsect,AVERAGE \\
|
|
VDEF:rsectlast=rsect,LAST \\
|
|
LINE1.5:wsect#3D617C:\"I/O write\t\" \\
|
|
GPRINT:wsectmax:\"Max\\: %8.2lf %S\" \\
|
|
GPRINT:wsectavg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:wsectlast:\"\tCurrent\\: %8.2lf %Sblocs/s\\n\" \\
|
|
LINE1.5:rsect#3B743F:\"I/O read\t\" \\
|
|
GPRINT:rsectmax:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:rsectavg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:rsectlast:\"\tCurrent\\: %8.2lf %Sblocs/s\\n\" \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub hddtemp
|
|
{
|
|
my $this = shift;
|
|
my $device = shift;
|
|
my $title = shift;
|
|
|
|
my $temp;
|
|
if ($device =~ /nvm/)
|
|
{
|
|
$temp = `/usr/sbin/nvme smart-log /dev/$device | awk '/temperature/ {gsub("°C", "", \$3); print \$3}'`
|
|
}
|
|
else
|
|
{
|
|
$temp = `/usr/sbin/hddtemp -n /dev/$device`;
|
|
}
|
|
$temp =~ s/[\n ]//g;
|
|
print "$title (/dev/$device) temp: $temp degrees C\n";
|
|
|
|
my $filename = "$this->{_rrd}/system-$device.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for /dev/$device...\n";
|
|
system "$this->{_rrdtool} create \"$filename\" \\
|
|
-s 300 \\
|
|
DS:temp:GAUGE:600:0:100 \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t temp N:$temp";
|
|
|
|
$this->hddtempGraph($device, 'day', $title);
|
|
$this->hddtempGraph($device, 'week', $title);
|
|
$this->hddtempGraph($device, 'month', $title);
|
|
$this->hddtempGraph($device, 'year', $title);
|
|
}
|
|
|
|
sub hddtempGraph
|
|
{
|
|
my $this = shift;
|
|
my $device = shift;
|
|
my $type = shift;
|
|
my $title = shift;
|
|
|
|
my $rrd_filename = "$this->{_rrd}/system-$device.rrd";
|
|
my $graph_filename = "$this->{_img}/system-$device-$type.png";
|
|
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-s -1$type \\
|
|
-t \"Temperature DD :: $title (/dev/$device)\" \\
|
|
-h 250 -w 1100 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"C\" \\
|
|
DEF:temp=$rrd_filename:temp:AVERAGE \\
|
|
VDEF:tempmin=temp,MINIMUM \\
|
|
VDEF:tempmax=temp,MAXIMUM \\
|
|
VDEF:tempavg=temp,AVERAGE \\
|
|
VDEF:templast=temp,LAST \\
|
|
LINE1.5:temp#3D617C:\"$title (/dev/$device)\t\" \\
|
|
GPRINT:tempmin:\"Min\\: %4.2lf\" \\
|
|
GPRINT:tempmax:\"\tMax\\: %4.2lf\" \\
|
|
GPRINT:tempavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:templast:\"\tCurrent\\: %4.2lf C\\n\" \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub sensorstemp
|
|
{
|
|
my $this = shift;
|
|
my $sets = shift;
|
|
|
|
my $valuesCollected = {};
|
|
my $sensorsData = decode_json `sensors -j 2>/dev/null`;
|
|
|
|
for my $hwmon (keys %$sets)
|
|
{
|
|
my $sensors = $sets->{$hwmon};
|
|
|
|
for my $key (keys %$sensors)
|
|
{
|
|
my $item = $sensors->{$key};
|
|
|
|
my $temp = $sensorsData->{$hwmon}->{$key}->{$item->{key}} || 0;
|
|
print $item->{name}, " : $temp degrees C\n";
|
|
|
|
# ds can only be 19 chars long [a-zA-Z0-9_] - this should not colide that much
|
|
my $ds = substr md5_hex($hwmon . '_' . $item->{key}), 0, 19;
|
|
$valuesCollected->{$ds}->{name} = $item->{name};
|
|
$valuesCollected->{$ds}->{value} = $temp;
|
|
}
|
|
}
|
|
|
|
my $filename = "$this->{_rrd}/system-sensors.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for system temperatures...\n";
|
|
my $entries = '';
|
|
for my $device (keys %$valuesCollected)
|
|
{
|
|
$entries .= "DS:$device:GAUGE:600:0:127 ";
|
|
}
|
|
system "$this->{_rrdtool} create \"$filename\" \\
|
|
-s 300 \\
|
|
$entries \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
# attention : sort pour faire coller les clés !!
|
|
my $entries = join ':', sort keys %$valuesCollected;
|
|
my $values = 'N';
|
|
for my $device (sort keys %$valuesCollected)
|
|
{
|
|
$values .= ":" . $valuesCollected->{$device}->{value};
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t $entries $values";
|
|
|
|
$this->sensorstempGraph('day', $valuesCollected);
|
|
$this->sensorstempGraph('week', $valuesCollected);
|
|
$this->sensorstempGraph('month', $valuesCollected);
|
|
$this->sensorstempGraph('year', $valuesCollected);
|
|
}
|
|
|
|
sub sensorstempGraph
|
|
{
|
|
my $this = shift;
|
|
my $type = shift;
|
|
my $sensors = shift;
|
|
|
|
my $rrd_filename = "$this->{_rrd}/system-sensors.rrd";
|
|
my $graph_filename = "$this->{_img}/system-sensors-$type.png";
|
|
|
|
my @colors = ("#3D617C", "#3B743F", "#913F3F", "#68A5D3", "#A0E59C", "#E36363", "#E3D85D", "#6e3d7c", "#bc68d3", "#7c633d", "#d3a868");
|
|
my $colorId = 0;
|
|
my $defs = '';
|
|
|
|
# lexical sort for graph
|
|
my @orderedKeys = sort { $sensors->{$a}->{name} cmp $sensors->{$b}->{name} } keys %$sensors;
|
|
for my $device (@orderedKeys)
|
|
{
|
|
$defs .= "DEF:$device=$rrd_filename:$device:AVERAGE \\
|
|
VDEF:${device}min=$device,MINIMUM \\
|
|
VDEF:${device}max=$device,MAXIMUM \\
|
|
VDEF:${device}avg=$device,AVERAGE \\
|
|
VDEF:${device}last=$device,LAST \\
|
|
LINE1.5:${device}$colors[$colorId]:\"$sensors->{$device}->{name}\t\" \\
|
|
GPRINT:${device}min:\"Min\\: %4.2lf\" \\
|
|
GPRINT:${device}max:\"\tMax\\: %4.2lf\" \\
|
|
GPRINT:${device}avg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:${device}last:\"\tCurrent\\: %4.2lf C\\n\" ";
|
|
$colorId = ($colorId + 1) % scalar @colors;
|
|
}
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
-s -1$type \\
|
|
-t 'Températures système' \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-h 250 -w 1100 \\
|
|
-l 0 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"C\" \\
|
|
$defs \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub sensorsfan
|
|
{
|
|
my $this = shift;
|
|
my $sets = shift;
|
|
|
|
my $valuesCollected = {};
|
|
my $sensorsData = decode_json `sensors -j 2>/dev/null`;
|
|
|
|
for my $hwmon (keys %$sets)
|
|
{
|
|
my $sensors = $sets->{$hwmon};
|
|
|
|
for my $key (keys %$sensors)
|
|
{
|
|
my $item = $sensors->{$key};
|
|
|
|
my $rpm = $sensorsData->{$hwmon}->{$key}->{$item->{key}} || 0;
|
|
print $item->{name}, " : $rpm RPM\n";
|
|
|
|
# ds can only be 19 chars long [a-zA-Z0-9_] - this should not colide that much
|
|
my $ds = substr md5_hex($hwmon . '_' . $item->{key}), 0, 19;
|
|
$valuesCollected->{$ds}->{name} = $item->{name};
|
|
$valuesCollected->{$ds}->{value} = $rpm;
|
|
}
|
|
}
|
|
|
|
my $filename = "$this->{_rrd}/system-fan-sensors.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for system fan speed...\n";
|
|
my $entries = '';
|
|
for my $device (keys %$valuesCollected)
|
|
{
|
|
$entries .= "DS:$device:GAUGE:600:0:3000 ";
|
|
}
|
|
system "$this->{_rrdtool} create \"$filename\" \\
|
|
-s 300 \\
|
|
$entries \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
# attention : sort pour faire coller les clés !!
|
|
my $entries = join ':', sort keys %$valuesCollected;
|
|
my $values = 'N';
|
|
for my $device (sort keys %$valuesCollected)
|
|
{
|
|
$values .= ":" . $valuesCollected->{$device}->{value};
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t $entries $values";
|
|
|
|
$this->sensorsfanGraph('day', $valuesCollected);
|
|
$this->sensorsfanGraph('week', $valuesCollected);
|
|
$this->sensorsfanGraph('month', $valuesCollected);
|
|
$this->sensorsfanGraph('year', $valuesCollected);
|
|
}
|
|
|
|
sub sensorsfanGraph
|
|
{
|
|
my $this = shift;
|
|
my $type = shift;
|
|
my $sensors = shift;
|
|
|
|
my $rrd_filename = "$this->{_rrd}/system-fan-sensors.rrd";
|
|
my $graph_filename = "$this->{_img}/system-fan-sensors-$type.png";
|
|
|
|
my @colors = ("#3D617C", "#3B743F", "#913F3F", "#68A5D3", "#A0E59C", "#E36363", "#E3D85D");
|
|
my $colorId = 0;
|
|
my $defs = '';
|
|
|
|
# lexical sort for graph
|
|
my @orderedKeys = sort { $sensors->{$a}->{name} cmp $sensors->{$b}->{name} } keys %$sensors;
|
|
for my $device (@orderedKeys)
|
|
{
|
|
$defs .= "DEF:$device=$rrd_filename:$device:AVERAGE \\
|
|
VDEF:${device}min=$device,MINIMUM \\
|
|
VDEF:${device}max=$device,MAXIMUM \\
|
|
VDEF:${device}avg=$device,AVERAGE \\
|
|
VDEF:${device}last=$device,LAST \\
|
|
LINE1.5:${device}$colors[$colorId]:\"$sensors->{$device}->{name}\t\" \\
|
|
GPRINT:${device}min:\"Min\\: %4.2lf\" \\
|
|
GPRINT:${device}max:\"\tMax\\: %4.2lf\" \\
|
|
GPRINT:${device}avg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:${device}last:\"\tCurrent\\: %4.2lf RPM\\n\" ";
|
|
$colorId = ($colorId + 1) % scalar @colors;
|
|
}
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
-s -1$type \\
|
|
-t 'Vitesse ventilation' \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-h 250 -w 1100 \\
|
|
-l 0 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"RPM\" \\
|
|
$defs \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub ups
|
|
{
|
|
my $this = shift;
|
|
my $upsname = shift;
|
|
my $multiplier = shift;
|
|
|
|
my $upsc = ();
|
|
open IN, "upsc $upsname |";
|
|
while (<IN>)
|
|
{
|
|
if (/^([\w.]+):\s*([\d.]+)/i)
|
|
{
|
|
$upsc->{$1} = $2;
|
|
}
|
|
}
|
|
close (IN);
|
|
my $load = $upsc->{'ups.load'};
|
|
my $input = $upsc->{'input.voltage'};
|
|
my $output= $upsc->{'output.voltage'};
|
|
chomp $load;
|
|
chomp $input;
|
|
chomp $output;
|
|
$load *= $multiplier;
|
|
print "UPS $upsname load: $load VA\n";
|
|
print "UPS $upsname input voltage: $input V\n";
|
|
print "UPS $upsname output voltage: $output V\n";
|
|
if (! -e "$this->{_rrd}/ups-$upsname.rrd")
|
|
{
|
|
print "creating rrd database for UPS $upsname...\n";
|
|
system "$this->{_rrdtool} create \"$this->{_rrd}/ups-$upsname.rrd\" \\
|
|
-s 300 \\
|
|
DS:load:GAUGE:600:0:500 \\
|
|
DS:input:GAUGE:600:0:500 \\
|
|
DS:output:GAUGE:600:0:500 \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$this->{_rrd}/ups-$upsname.rrd\" -t load:input:output N:$load:$input:$output";
|
|
|
|
$this->upsGraph($upsname, 'day');
|
|
$this->upsGraph($upsname, 'week');
|
|
$this->upsGraph($upsname, 'month');
|
|
$this->upsGraph($upsname, 'year');
|
|
}
|
|
|
|
sub upsGraph
|
|
{
|
|
my $this = shift;
|
|
my $upsname = shift;
|
|
my $type = shift;
|
|
|
|
system "$this->{_rrdtool} graph \"$this->{_img}/ups-load-$upsname-$type.png\" \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-s -1$type \\
|
|
-t \"Charge UPS :: $upsname\" \\
|
|
-h 250 -w 1100 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"VA\" \\
|
|
DEF:load=$this->{_rrd}/ups-$upsname.rrd:load:AVERAGE \\
|
|
VDEF:loadmin=load,MINIMUM \\
|
|
VDEF:loadmax=load,MAXIMUM \\
|
|
VDEF:loadavg=load,AVERAGE \\
|
|
VDEF:loadlast=load,LAST \\
|
|
LINE1.5:load#3D617C:\"Charge\t\" \\
|
|
GPRINT:loadmin:\"Min\\: %4.2lf\" \\
|
|
GPRINT:loadmax:\"\tMax\\: %4.2lf\" \\
|
|
GPRINT:loadavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:loadlast:\"\tCurrent\\: %4.2lf VA\\n\" \\
|
|
2>&1 > /dev/null";
|
|
|
|
system "$this->{_rrdtool} graph \"$this->{_img}/ups-voltage-$upsname-$type.png\" \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-s -1$type \\
|
|
-t \"Tension UPS :: $upsname\" \\
|
|
-h 250 -w 1100 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"V\" \\
|
|
DEF:input=$this->{_rrd}/ups-$upsname.rrd:input:AVERAGE \\
|
|
DEF:output=$this->{_rrd}/ups-$upsname.rrd:output:AVERAGE \\
|
|
VDEF:inputmin=input,MINIMUM \\
|
|
VDEF:inputmax=input,MAXIMUM \\
|
|
VDEF:inputavg=input,AVERAGE \\
|
|
VDEF:inputlast=input,LAST \\
|
|
VDEF:outputmin=output,MINIMUM \\
|
|
VDEF:outputmax=output,MAXIMUM \\
|
|
VDEF:outputavg=output,AVERAGE \\
|
|
VDEF:outputlast=output,LAST \\
|
|
LINE1.5:input#3D617C:\"Tension entrée\t\" \\
|
|
GPRINT:inputmin:\"Min\\: %4.2lf\" \\
|
|
GPRINT:inputmax:\"\tMax\\: %4.2lf\" \\
|
|
GPRINT:inputavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:inputlast:\"\tCurrent\\: %4.2lf V\\n\" \\
|
|
LINE1.5:output#3B743F:\"Tension sortie\t\" \\
|
|
GPRINT:outputmin:\"Min\\: %4.2lf\" \\
|
|
GPRINT:outputmax:\"\tMax\\: %4.2lf\" \\
|
|
GPRINT:outputavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:outputlast:\"\tCurrent\\: %4.2lf V\\n\" \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub nginx
|
|
{
|
|
my $this = shift;
|
|
my $url = shift;
|
|
my $ua = LWP::UserAgent->new (timeout => 10);
|
|
my $response = $ua->get ($url);
|
|
my $connections_accept = "U";
|
|
my $connections_handeled = "U";
|
|
my $requests = "U";
|
|
if ($response->content =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s*$/im)
|
|
{
|
|
$connections_accept = $1;
|
|
$connections_handeled = $2;
|
|
$requests = $3;
|
|
}
|
|
print "nginx requests: $connections_accept $connections_handeled $requests\n";
|
|
|
|
my $filename = "$this->{_rrd}/system-nginx.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for nginx...\n";
|
|
system "$this->{_rrdtool} create \"$filename\" \\
|
|
-s 300 \\
|
|
DS:connectionsaccept:DERIVE:600:0:U \\
|
|
DS:connectionshandeled:DERIVE:600:0:U \\
|
|
DS:requests:DERIVE:600:0:U \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t connectionsaccept:connectionshandeled:requests N:$connections_accept:$connections_handeled:$requests";
|
|
|
|
$this->nginxGraph('day');
|
|
$this->nginxGraph('week');
|
|
$this->nginxGraph('month');
|
|
$this->nginxGraph('year');
|
|
}
|
|
|
|
sub nginxGraph
|
|
{
|
|
my $this = shift;
|
|
my $type = shift;
|
|
|
|
my $rrd_filename = "$this->{_rrd}/system-nginx.rrd";
|
|
my $graph_filename = "$this->{_img}/system-nginx-$type.png";
|
|
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-s -1$type \\
|
|
-t \"Requêtes nginx\" \\
|
|
-h 250 -w 1100 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"reqs/s\" \\
|
|
DEF:connectionsaccept=$rrd_filename:connectionsaccept:AVERAGE \\
|
|
DEF:connectionshandeled=$rrd_filename:connectionshandeled:AVERAGE \\
|
|
DEF:requests=$rrd_filename:requests:AVERAGE \\
|
|
VDEF:camax=connectionsaccept,MAXIMUM \\
|
|
VDEF:caavg=connectionsaccept,AVERAGE \\
|
|
VDEF:calast=connectionsaccept,LAST \\
|
|
VDEF:chmax=connectionshandeled,MAXIMUM \\
|
|
VDEF:chavg=connectionshandeled,AVERAGE \\
|
|
VDEF:chlast=connectionshandeled,LAST \\
|
|
VDEF:requestsmax=requests,MAXIMUM \\
|
|
VDEF:requestsavg=requests,AVERAGE \\
|
|
VDEF:requestslast=requests,LAST \\
|
|
LINE1.5:connectionsaccept#3D617C:\"Connections\t\t\t\" \\
|
|
GPRINT:camax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:caavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:calast:\"\tCurrent\\: %4.2lf conns/s\\n\" \\
|
|
LINE1.5:connectionshandeled#3B743F:\"Connections handeled\t\" \\
|
|
GPRINT:chmax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:chavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:chlast:\"\tCurrent\\: %4.2lf conns/s\\n\" \\
|
|
LINE1.5:requests#913F3F:\"Requests\t\t\t\" \\
|
|
GPRINT:requestsmax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:requestsavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:requestslast:\"\tCurrent\\: %4.2lf reqs/s\\n\" \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
sub haproxy
|
|
{
|
|
my $this = shift;
|
|
my $socket = shift;
|
|
my $farms = shift;
|
|
|
|
my $sock = new IO::Socket::UNIX (Peer => $socket, Type => SOCK_STREAM, Timeout => 1);
|
|
return if not $sock;
|
|
print $sock "show stat\n";
|
|
while (<$sock>)
|
|
{
|
|
chomp;
|
|
my @csv = split /,/;
|
|
# HTTP stats
|
|
next if not defined $csv[1];
|
|
if (exists $farms->{http}->{$csv[0]})
|
|
{
|
|
if ($csv[1] eq 'FRONTEND' or $csv[1] eq 'BACKEND')
|
|
{
|
|
$farms->{http}->{$csv[0]} = \@csv;
|
|
}
|
|
}
|
|
# Socket stats
|
|
if (exists $farms->{socket}->{$csv[0]})
|
|
{
|
|
if ($csv[1] eq 'FRONTEND' or $csv[1] eq 'BACKEND')
|
|
{
|
|
$farms->{socket}->{$csv[0]}->{total} = \@csv;
|
|
}
|
|
else
|
|
{
|
|
$farms->{socket}->{$csv[0]}->{$csv[1]} = \@csv;
|
|
}
|
|
}
|
|
}
|
|
|
|
# HTTP stats
|
|
for my $farmName (keys %{$farms->{http}})
|
|
{
|
|
my @csv = @{$farms->{http}->{$farmName}};
|
|
print "haproxy requests on $farmName: $csv[39]:$csv[40]:$csv[41]:$csv[42]:$csv[43]:$csv[44]\n";
|
|
|
|
my $filename = "$this->{_rrd}/system-haproxy-http-$farmName.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for haproxy $farmName HTTP farm...\n";
|
|
system "$this->{_rrdtool} create \"$filename\" \\
|
|
-s 300 \\
|
|
DS:1XX:DERIVE:600:0:U \\
|
|
DS:2XX:DERIVE:600:0:U \\
|
|
DS:3XX:DERIVE:600:0:U \\
|
|
DS:4XX:DERIVE:600:0:U \\
|
|
DS:5XX:DERIVE:600:0:U \\
|
|
DS:other:DERIVE:600:0:U \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t 1XX:2XX:3XX:4XX:5XX:other N:$csv[39]:$csv[40]:$csv[41]:$csv[42]:$csv[43]:$csv[44]";
|
|
}
|
|
|
|
# Socket stats
|
|
for my $farmName (keys %{$farms->{socket}})
|
|
{
|
|
my $stats = $farms->{socket}->{$farmName};
|
|
my @keys = ();
|
|
my @vals = ();
|
|
for my $socket (keys %{$stats})
|
|
{
|
|
push @keys, "${socket}_in";
|
|
push @vals, $stats->{$socket}[8];
|
|
push @keys, "${socket}_out";
|
|
push @vals, $stats->{$socket}[9];
|
|
}
|
|
print "haproxy sock stats on $farmName: " . join(':', @keys) . "/" . join(':', @vals) . "\n";
|
|
|
|
my $filename = "$this->{_rrd}/system-haproxy-socket-$farmName.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for haproxy $farmName Socket farm...\n";
|
|
my $create = "$this->{_rrdtool} create \"$filename\" \\
|
|
-s 300 ";
|
|
for my $socket (@keys)
|
|
{
|
|
$create .= "DS:$socket:DERIVE:600:0:U ";
|
|
}
|
|
$create .= "RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
system $create;
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t " . join(':', @keys) . " N:" . join(':', @vals);
|
|
}
|
|
|
|
$this->haproxyGraphHttp('day', $farms->{http});
|
|
$this->haproxyGraphHttp('week', $farms->{http});
|
|
$this->haproxyGraphHttp('month', $farms->{http});
|
|
$this->haproxyGraphHttp('year', $farms->{http});
|
|
$this->haproxyGraphSocket('day', $farms->{socket});
|
|
$this->haproxyGraphSocket('week', $farms->{socket});
|
|
$this->haproxyGraphSocket('month', $farms->{socket});
|
|
$this->haproxyGraphSocket('year', $farms->{socket});
|
|
}
|
|
|
|
sub haproxyGraphHttp
|
|
{
|
|
my $this = shift;
|
|
my $type = shift;
|
|
my $farms = shift;
|
|
|
|
for my $farmName (keys %$farms)
|
|
{
|
|
my $rrd_filename = "$this->{_rrd}/system-haproxy-http-$farmName.rrd";
|
|
my $graph_filename = "$this->{_img}/system-haproxy-http-$farmName-$type.png";
|
|
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-s -1$type \\
|
|
-t \"Haproxy HTTP stats - $farmName\" \\
|
|
-h 250 -w 1100 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"reqs/s\" \\
|
|
DEF:1XX=$rrd_filename:1XX:AVERAGE \\
|
|
DEF:2XX=$rrd_filename:2XX:AVERAGE \\
|
|
DEF:3XX=$rrd_filename:3XX:AVERAGE \\
|
|
DEF:4XX=$rrd_filename:4XX:AVERAGE \\
|
|
DEF:5XX=$rrd_filename:5XX:AVERAGE \\
|
|
DEF:other=$rrd_filename:other:AVERAGE \\
|
|
VDEF:1XXmax=1XX,MAXIMUM \\
|
|
VDEF:1XXavg=1XX,AVERAGE \\
|
|
VDEF:1XXlast=1XX,LAST \\
|
|
VDEF:2XXmax=2XX,MAXIMUM \\
|
|
VDEF:2XXavg=2XX,AVERAGE \\
|
|
VDEF:2XXlast=2XX,LAST \\
|
|
VDEF:3XXmax=3XX,MAXIMUM \\
|
|
VDEF:3XXavg=3XX,AVERAGE \\
|
|
VDEF:3XXlast=3XX,LAST \\
|
|
VDEF:4XXmax=4XX,MAXIMUM \\
|
|
VDEF:4XXavg=4XX,AVERAGE \\
|
|
VDEF:4XXlast=4XX,LAST \\
|
|
VDEF:5XXmax=5XX,MAXIMUM \\
|
|
VDEF:5XXavg=5XX,AVERAGE \\
|
|
VDEF:5XXlast=5XX,LAST \\
|
|
VDEF:othermax=other,MAXIMUM \\
|
|
VDEF:otheravg=other,AVERAGE \\
|
|
VDEF:otherlast=other,LAST \\
|
|
CDEF:total=1XX,2XX,3XX,4XX,5XX,other,+,+,+,+,+ \\
|
|
VDEF:totalmax=total,MAXIMUM \\
|
|
VDEF:totalavg=total,AVERAGE \\
|
|
VDEF:totallast=total,LAST \\
|
|
AREA:total#CDCDCD:\"Total\t\" \\
|
|
GPRINT:totalmax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:totalavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:totallast:\"\tCurrent\\: %4.2lf reqs/s\\n\" \\
|
|
AREA:1XX#3D617C:\"1XX\t\t\" \\
|
|
GPRINT:1XXmax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:1XXavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:1XXlast:\"\tCurrent\\: %4.2lf reqs/s\\n\" \\
|
|
AREA:2XX#68A5D3:\"2XX\t\t\":STACK \\
|
|
GPRINT:2XXmax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:2XXavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:2XXlast:\"\tCurrent\\: %4.2lf reqs/s\\n\" \\
|
|
AREA:3XX#A0E59C:\"3XX\t\t\":STACK \\
|
|
GPRINT:3XXmax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:3XXavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:3XXlast:\"\tCurrent\\: %4.2lf reqs/s\\n\" \\
|
|
AREA:4XX#3B743F:\"4XX\t\t\":STACK \\
|
|
GPRINT:4XXmax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:4XXavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:4XXlast:\"\tCurrent\\: %4.2lf reqs/s\\n\" \\
|
|
AREA:5XX#913F3F:\"5XX\t\t\":STACK \\
|
|
GPRINT:5XXmax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:5XXavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:5XXlast:\"\tCurrent\\: %4.2lf reqs/s\\n\" \\
|
|
AREA:other#E3D85D:\"other\t\":STACK \\
|
|
GPRINT:othermax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:otheravg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:otherlast:\"\tCurrent\\: %4.2lf reqs/s\\n\" \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
}
|
|
|
|
sub haproxyGraphSocket
|
|
{
|
|
my $this = shift;
|
|
my $type = shift;
|
|
my $farms = shift;
|
|
|
|
my @colors = ("#68A5D3", "#A0E59C", "#E36363", "#E3D85D", "#3D617C", "#3B743F", "#913F3F");
|
|
|
|
for my $farmName (keys %$farms)
|
|
{
|
|
my $rrd_filename = "$this->{_rrd}/system-haproxy-socket-$farmName.rrd";
|
|
my $graph_filename = "$this->{_img}/system-haproxy-socket-$farmName-$type.png";
|
|
|
|
my @keys = ();
|
|
for my $socket (sort keys %{$farms->{$farmName}})
|
|
{
|
|
push @keys, "${socket}_in";
|
|
push @keys, "${socket}_out";
|
|
}
|
|
my $colorId = 0;
|
|
my $idIn = 0;
|
|
my $idOut = 0;
|
|
my @defs = ();
|
|
my @graphsIn = ();
|
|
my @graphsOut = ();
|
|
for my $key (@keys)
|
|
{
|
|
# data
|
|
my $graphDataKey = $key;
|
|
my $stack = "";
|
|
my $def = "DEF:${key}=${rrd_filename}:${key}:AVERAGE \\
|
|
VDEF:${key}max=${key},MAXIMUM \\
|
|
VDEF:${key}avg=${key},AVERAGE \\
|
|
VDEF:${key}last=${key},LAST ";
|
|
if ($key =~ m/_in$/)
|
|
{
|
|
$graphDataKey = "${key}_neg";
|
|
$def .= "CDEF:${graphDataKey}=${key},-1,* ";
|
|
}
|
|
push @defs, $def;
|
|
next if $key =~ m/^total_(in|out)$/;
|
|
# graphs items
|
|
if ($key =~ m/_in$/)
|
|
{
|
|
$stack = ":STACK" if $idIn++ > 0;
|
|
push @graphsIn, "AREA:${graphDataKey}$colors[$colorId]:\"${key}\t\t\"${stack} \\
|
|
GPRINT:${key}max:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:${key}avg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:${key}last:\"\tCurrent\\: %8.2lf %So/s\\n\" ";
|
|
}
|
|
else
|
|
{
|
|
$stack = ":STACK" if $idOut++ > 0;
|
|
push @graphsOut, "AREA:${graphDataKey}$colors[$colorId]:\"${key}\t\t\"${stack} \\
|
|
GPRINT:${key}max:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:${key}avg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:${key}last:\"\tCurrent\\: %8.2lf %So/s\\n\" ";
|
|
}
|
|
$colorId = ($colorId + 1) % scalar @colors if $key =~ m/_out$/;
|
|
}
|
|
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-s -1$type \\
|
|
-t \"Haproxy socket stats - $farmName\" \\
|
|
-h 250 -w 1100 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"o/s\" \\
|
|
" . join(' ', @defs) . " \\
|
|
AREA:total_out#CDCDCD:\"Total_out\t\" \\
|
|
GPRINT:total_outmax:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:total_outavg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:total_outlast:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
" . join(' ', @graphsOut) . " \\
|
|
AREA:total_in_neg#CDCDCD:\"Total_in\t\t\" \\
|
|
GPRINT:total_inmax:\"Max\\: %8.2lf %s\" \\
|
|
GPRINT:total_inavg:\"\tAvg\\: %8.2lf %S\" \\
|
|
GPRINT:total_inlast:\"\tCurrent\\: %8.2lf %So/s\\n\" \\
|
|
" . join(' ', @graphsIn) . " \\
|
|
HRULE:0#202020 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
}
|
|
|
|
sub battery
|
|
{
|
|
my $this = shift;
|
|
my $bat = shift;
|
|
|
|
open FH, "</sys/class/power_supply/$bat/charge_full_design";
|
|
my $full = <FH>;
|
|
close FH;
|
|
open FH, "</sys/class/power_supply/$bat/charge_now";
|
|
my $now = <FH>;
|
|
close FH;
|
|
chomp $full;
|
|
chomp $now;
|
|
my $level = ($now * 100) / $full;
|
|
print "Niveau batterie $bat: $level\n";
|
|
|
|
my $filename = "$this->{_rrd}/system-battery-$bat.rrd";
|
|
|
|
if (! -e $filename)
|
|
{
|
|
print "creating rrd database for system battery...\n";
|
|
system "$this->{_rrdtool} create \"$filename\" \\
|
|
-s 300 \\
|
|
DS:bat:GAUGE:600:0:100 \\
|
|
RRA:AVERAGE:0.5:1:576 \\
|
|
RRA:AVERAGE:0.5:6:672 \\
|
|
RRA:AVERAGE:0.5:24:732 \\
|
|
RRA:AVERAGE:0.5:144:1460 \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
system "$this->{_rrdtool} update \"$filename\" -t bat N:$level";
|
|
|
|
$this->batteryGraph('day', $bat);
|
|
$this->batteryGraph('week', $bat);
|
|
$this->batteryGraph('month', $bat);
|
|
$this->batteryGraph('year', $bat);
|
|
}
|
|
|
|
sub batteryGraph
|
|
{
|
|
my $this = shift;
|
|
my $type = shift;
|
|
my $bat = shift;
|
|
|
|
my $rrd_filename = "$this->{_rrd}/system-battery-$bat.rrd";
|
|
my $graph_filename = "$this->{_img}/system-battery-$bat-$type.png";
|
|
|
|
system "$this->{_rrdtool} graph \"$graph_filename\" \\
|
|
--lazy \\
|
|
--tabwidth 20 \\
|
|
-s -1$type \\
|
|
-t \"Niveau Batterie - $bat\" \\
|
|
-h 250 -w 1100 \\
|
|
--border 0 \\
|
|
-a PNG \\
|
|
-E \\
|
|
-n DEFAULT:0:monospace \\
|
|
-n TITLE:11 \\
|
|
-n AXIS:10 \\
|
|
-n LEGEND:10 \\
|
|
-n UNIT:10 \\
|
|
-v \"%\" \\
|
|
-u 100 \\
|
|
-l 0 \\
|
|
-r \\
|
|
DEF:bat=$rrd_filename:bat:AVERAGE \\
|
|
VDEF:batmax=bat,MAXIMUM \\
|
|
VDEF:batavg=bat,AVERAGE \\
|
|
VDEF:batlast=bat,LAST \\
|
|
LINE1.5:bat#3D617C:\"Batterie\t\" \\
|
|
GPRINT:batmax:\"Max\\: %4.2lf\" \\
|
|
GPRINT:batavg:\"\tAvg\\: %4.2lf\" \\
|
|
GPRINT:batlast:\"\tCurrent\\: %4.2lf %%\\n\" \\
|
|
2>&1 > /dev/null";
|
|
}
|
|
|
|
1;
|
|
|