1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-24 18:07:20 +00:00

Changed the location of their own plug-ins

This commit is contained in:
Горлов Максим 2012-02-25 12:22:25 +04:00
parent ca363693d7
commit f14628ad35
6 changed files with 0 additions and 0 deletions

View file

@ -1,359 +0,0 @@
#!/usr/bin/perl -w
# -*- perl -*-
=head1 NAME
batteries Munin plugin to monitor the battery states through procfs and sysfs
=head1 APPLICABLE SYSTEMS
Systems with avialable /proc/acpi/battery/BATx or /sys/class/power_supply/BATx
=head1 CONFIGURATION
none
=head1 INTERPRETATION
The plugin shows:
Design capacity -> avialable if avialable /proc/acpi/battery/BATx or /sys/class/power_supply/BATx
Last full capacity -> avialable if avialable /proc/acpi/battery/BATx or /sys/class/power_supply/BATx
Design capacity low -> avialable only if avialable /proc/acpi/battery/BATx
Design capacity warning -> avialable only if avialable /proc/acpi/battery/BATx
Capacity granularity 1 -> avialable only if avialable /proc/acpi/battery/BATx
Capacity granularity 2 -> avialable only if avialable /proc/acpi/battery/BATx
Remaining capacity -> avialable if avialable /proc/acpi/battery/BATx or /sys/class/power_supply/BATx
Present rate -> avialable if avialable /proc/acpi/battery/BATx or /sys/class/power_supply/BATx
Percentage Current/design voltage -> avialable if avialable /proc/acpi/battery/BATx or /sys/class/power_supply/BATx
Percentage Current/full capacity -> avialable if avialable /proc/acpi/battery/BATx or /sys/class/power_supply/BATx
Percentage Full/design capacity -> avialable if avialable /proc/acpi/battery/BATx or /sys/class/power_supply/BATx
Design voltage -> avialable if avialable /proc/acpi/battery/BATx or /sys/class/power_supply/BATx
Present voltage -> avialable if avialable /proc/acpi/battery/BATx or /sys/class/power_supply/BATx
=head1 MAGIC MARKERS
#%# family=power
#%# capabilities=autoconf
=head1 VERSION
1.0
=head1 BUGS
None known.
=head1 AUTHOR
Gorlow Maxim aka Sheridan <sheridan@sheridan-home.ru> - email and jabber
=head1 LICENSE
GPLv2
=cut
use strict;
use warnings;
use IO::Dir;
use Munin::Plugin;
need_multigraph();
my $proc_path = '/proc/acpi/battery';
my $sys_path = '/sys/class/power_supply';
my $proc_data_exists;
my $sys_data_exists;
my $batteryes_count;
sub trim
{
my($string)=@_;
for ($string)
{
s/^\s+//;
s/\s+$//;
}
return $string;
}
sub get_batteryes_count
{
my $path = $_[0];
return 0 unless (-e $path);
my $count = 0;
my $dir = IO::Dir->new($path);
if(defined $dir)
{
my $d;
while (defined ($d = $dir->read))
{
next unless $d =~ m/BAT\d+/;
$count++;
}
}
else { return 0; }
return $count;
}
sub init
{
my $proc_batt_count = get_batteryes_count($proc_path);
my $sys_batt_count = get_batteryes_count($sys_path );
#print "$proc_batt_count $sys_batt_count\n";
$proc_data_exists = $proc_batt_count > 0;
$sys_data_exists = $sys_batt_count > 0;
if ($proc_data_exists and $sys_data_exists and ($proc_batt_count != $sys_batt_count))
{
die "Something wrong, batteryes count from $proc_path and $sys_path not equal (proc: $proc_batt_count, sys: $sys_batt_count)!"
}
if ($proc_data_exists) { $batteryes_count = $proc_batt_count; }
elsif ($sys_data_exists) { $batteryes_count = $sys_batt_count; }
unless ($batteryes_count)
{
die "Batteryes not found."
}
}
sub read_proc_data
{
my ($batt_num, $file) = @_[0..1];
my ($var, $val, $result);
open(FH, '<', "${proc_path}/BAT${batt_num}/${file}") or die $!;
foreach my $line (<FH>)
{
chomp ($line);
($var, $val) = split(':', $line);
if ($val =~ m/^\s*$/ ) { $val = "nan"; }
elsif ($val =~ m/\w\s+\w/) { $val = (split(" " ,$val))[0]; }
$result->{$var} = trim($val);
#print "var $var - val $val\n";
}
close(FH);
return $result;
}
sub read_sys_data
{
my ($batt_num, $file) = @_[0..1];
my $file_content = "nan";
open(FH, '<', "${sys_path}/BAT${batt_num}/${file}") or die $!;
$file_content = <FH>;
close(FH);
chomp ($file_content);
if($file_content =~ m/^\s*$/) { return 'nan'; }
return $file_content;
}
sub percent
{
my ($full, $current) = @_[0..1];
return $current/($full/100);
}
sub read_info
{
my $info;
for (my $i = 0; $i < $batteryes_count; $i++)
{
if($sys_data_exists)
{
$info->{$i}{'manufacturer'} = read_sys_data($i, 'manufacturer');
$info->{$i}{'battery_type'} = read_sys_data($i, 'technology' );
$info->{$i}{'model_name'} = read_sys_data($i, 'model_name' );
$info->{$i}{'serial_number'} = read_sys_data($i, 'serial_number');
}
else
{
my $proc_info = read_proc_data($i, 'info');
$info->{$i}{'manufacturer'} = $proc_info->{'OEM info' };
$info->{$i}{'battery_type'} = $proc_info->{'battery type' };
$info->{$i}{'model_name'} = $proc_info->{'model number' };
$info->{$i}{'serial_number'} = $proc_info->{'serial number'};
}
}
return $info;
}
sub read_data
{
my $data;
for (my $i = 0; $i < $batteryes_count; $i++)
{
if($sys_data_exists)
{
my $divider = 1000000; # need for equvivalent sys and proc data
$data->{$i}{'design_capacity'} = read_sys_data($i, 'charge_full_design')/$divider;
$data->{$i}{'last_full_capacity'} = read_sys_data($i, 'charge_full') /$divider;
$data->{$i}{'remaining_capacity'} = read_sys_data($i, 'charge_now') /$divider;
$data->{$i}{'design_voltage'} = read_sys_data($i, 'voltage_min_design')/$divider;
$data->{$i}{'present_voltage'} = read_sys_data($i, 'voltage_now') /$divider;
$data->{$i}{'present_rate'} = read_sys_data($i, 'current_now') /$divider;
}
if($proc_data_exists)
{
my $divider = 1000; # need for equvivalent sys and proc data
my $proc_info = read_proc_data($i, 'info');
unless($sys_data_exists)
{
my $proc_state = read_proc_data($i, 'state');
$data->{$i}{'design_capacity'} = $proc_info ->{'design capacity'} /$divider;
$data->{$i}{'last_full_capacity'} = $proc_info ->{'last full capacity'}/$divider;
$data->{$i}{'remaining_capacity'} = $proc_state->{'remaining capacity'}/$divider;
$data->{$i}{'design_voltage'} = $proc_info ->{'design voltage'} /$divider;
$data->{$i}{'present_voltage'} = $proc_state->{'present voltage'} /$divider;
$data->{$i}{'present_rate'} = $proc_state->{'present rate'} /$divider;
}
$data->{$i}{'design_capacity_low'} = $proc_info ->{'design capacity low'} /$divider;
$data->{$i}{'design_capacity_warning'} = $proc_info ->{'design capacity warning'}/$divider;
$data->{$i}{'capacity_granularity_1'} = $proc_info ->{'capacity granularity 1'} /$divider;
$data->{$i}{'capacity_granularity_2'} = $proc_info ->{'capacity granularity 2'} /$divider;
}
$data->{$i}{'current_voltage_percent'} = percent($data->{$i}{'design_voltage'} , $data->{$i}{'present_voltage'});
$data->{$i}{'current_capacity_percent'} = percent($data->{$i}{'last_full_capacity'}, $data->{$i}{'remaining_capacity'});
$data->{$i}{'full_capacity_percent'} = percent($data->{$i}{'design_capacity'} , $data->{$i}{'last_full_capacity'});
}
return $data;
}
my $graphs =
{
'batteryes_capacity' => { 'vlabel' => 'Capacity, Ah', 'title' => '%s capacity', 'args' => '--base 1000',
'fields' => [qw/design_capacity last_full_capacity design_capacity_low design_capacity_warning capacity_granularity_1 capacity_granularity_2 remaining_capacity/] },
'batteryes_voltage' => { 'vlabel' => 'Voltage, V' , 'title' => '%s voltage' , 'args' => '--base 1000',
'fields' => [qw/design_voltage present_voltage/] },
'batteryes_percents' => { 'vlabel' => '%' , 'title' => '%s percents', 'args' => '--base 1000 --upper-limit 100 -l 0',
'fields' => [qw/current_voltage_percent current_capacity_percent full_capacity_percent/] },
'batteryes_current' => { 'vlabel' => 'Current, A' , 'title' => '%s current' , 'args' => '--base 1000',
'fields' => [qw/present_rate/] }
};
my $fields =
{
'design_capacity' => { 'source' => 'both', 'draw' => 'AREA' , 'label' => 'Design capacity' , 'info' => 'Battery design capacity' },
'last_full_capacity' => { 'source' => 'both', 'draw' => 'AREA' , 'label' => 'Last full capacity' , 'info' => 'Battery full charge capacity' },
'design_capacity_low' => { 'source' => 'proc', 'draw' => 'LINE2', 'label' => 'Design capacity low' , 'info' => 'Low battery level' },
'design_capacity_warning' => { 'source' => 'proc', 'draw' => 'LINE2', 'label' => 'Design capacity warning', 'info' => 'Warning battery level' },
'capacity_granularity_1' => { 'source' => 'proc', 'draw' => 'LINE2', 'label' => 'Capacity granularity 1' , 'info' => 'Capacity granularity 1' },
'capacity_granularity_2' => { 'source' => 'proc', 'draw' => 'LINE2', 'label' => 'Capacity granularity 2' , 'info' => 'Capacity granularity 2' },
'remaining_capacity' => { 'source' => 'both', 'draw' => 'LINE2', 'label' => 'Remaining capacity' , 'info' => 'Current battery charge' },
'present_rate' => { 'source' => 'both', 'draw' => 'LINE2', 'label' => 'Present rate' , 'info' => 'Current battery rate' },
'design_voltage' => { 'source' => 'both', 'draw' => 'AREA' , 'label' => 'Design voltage' , 'info' => 'Battery design voltage' },
'present_voltage' => { 'source' => 'both', 'draw' => 'AREA' , 'label' => 'Present voltage' , 'info' => 'Current battery voltage' },
'current_voltage_percent' => { 'source' => 'both', 'draw' => 'LINE2', 'label' => 'Current/design voltage' , 'info' => 'Current battery voltage / ( Battery design voltage / 100 )' },
'current_capacity_percent' => { 'source' => 'both', 'draw' => 'LINE2', 'label' => 'Current/full capacity' , 'info' => 'Current battery charge / ( Battery full charge capacity / 100 )' },
'full_capacity_percent' => { 'source' => 'both', 'draw' => 'LINE2', 'label' => 'Full/design capacity' , 'info' => 'Battery full charge capacity / ( Battery design capacity / 100 )' },
};
# ------------------------------------ start here -----------------------------------
if (defined($ARGV[0]) and ($ARGV[0] eq 'autoconf'))
{
printf("%s\n", (-e $proc_path or -e $sys_path) ? "yes" : "no ($proc_path and $sys_path not exists)");
exit (0);
}
init();
if ($ARGV[0] and $ARGV[0] eq "config")
{
my %config;
my $info = read_info();
foreach my $graph (keys %{$graphs})
{
my @order;
$config{$graph}{'graph'}{'title'} = sprintf($graphs->{$graph}{'title'}, 'Mean batteryes');
$config{$graph}{'graph'}{'args'} = $graphs->{$graph}{'args'};
$config{$graph}{'graph'}{'vlabel'} = $graphs->{$graph}{'vlabel'};
$config{$graph}{'graph'}{'category'} = 'power';
foreach my $field (@{$graphs->{$graph}{'fields'}})
{
if(($proc_data_exists and $fields->{$field}{'source'} eq 'proc') or $fields->{$field}{'source'} eq 'both')
{
$config{$graph}{'fields'}{$field}{'label'} = $fields->{$field}{'label'};
$config{$graph}{'fields'}{$field}{'info'} = $fields->{$field}{'info'};
$config{$graph}{'fields'}{$field}{'draw'} = $fields->{$field}{'draw'};
$config{$graph}{'fields'}{$field}{'type'} = 'GAUGE';
push(@order, $field);
}
}
$config{$graph}{'graph'}{'order'} = join(' ', @order);
for (my $i = 0; $i < $batteryes_count; $i++)
{
my @b_order;
my $battery_name = sprintf("BAT%s", $i);
my $graph_name = sprintf("%s.%s", $graph, $battery_name);
$config{$graph_name}{'graph'}{'title'} = sprintf($graphs->{$graph}{'title'}, $battery_name);
$config{$graph_name}{'graph'}{'info'} = sprintf("%s battery %s %s (sn: %s)", $info->{$i}{'battery_type'}, $info->{$i}{'manufacturer'}, $info->{$i}{'model_name'}, $info->{$i}{'serial_number'});
$config{$graph_name}{'graph'}{'args'} = '--base 1000';
$config{$graph_name}{'graph'}{'vlabel'} = $graphs->{$graph}{'vlabel'};
$config{$graph_name}{'graph'}{'category'} = 'power';
foreach my $field (@{$graphs->{$graph}{'fields'}})
{
if(($proc_data_exists and $fields->{$field}{'source'} eq 'proc') or $fields->{$field}{'source'} eq 'both')
{
$config{$graph_name}{'fields'}{$field}{'label'} = $fields->{$field}{'label'};
$config{$graph_name}{'fields'}{$field}{'info'} = $fields->{$field}{'info'};
$config{$graph_name}{'fields'}{$field}{'draw'} = $fields->{$field}{'draw'};
$config{$graph_name}{'fields'}{$field}{'type'} = 'GAUGE';
push(@b_order, $field);
}
}
$config{$graph_name}{'graph'}{'order'} = join(' ', @b_order);
}
}
# ---------------- print ------------------
foreach my $graph (sort keys %config)
{
printf("multigraph %s\n", $graph);
foreach my $g_option(sort keys %{$config{$graph}{'graph'}})
{
printf("graph_%s %s\n", $g_option, $config{$graph}{'graph'}{$g_option});
}
foreach my $field (sort keys %{$config{$graph}{'fields'}})
{
foreach my $f_option (sort keys %{$config{$graph}{'fields'}{$field}})
{
printf("%s.%s %s\n", $field, $f_option, $config{$graph}{'fields'}{$field}{$f_option});
}
}
print "\n";
}
exit (0);
}
# ----------------------------- values ---------------------------------------------
my $data = read_data();
foreach my $graph (sort keys %{$graphs})
{
printf ("multigraph %s\n", $graph);
foreach my $field (sort @{$graphs->{$graph}{'fields'}})
{
my $field_summ = 0;
if(($proc_data_exists and $fields->{$field}{'source'} eq 'proc') or $fields->{$field}{'source'} eq 'both')
{
for (my $i = 0; $i < $batteryes_count; $i++)
{
$field_summ += $data->{$i}{$field};
}
printf("%s.value %s\n", $field, $field_summ/$batteryes_count);
}
}
print "\n";
for (my $i = 0; $i < $batteryes_count; $i++)
{
my $graph_name = sprintf("%s.BAT%s", $graph, $i);
printf ("multigraph %s\n", $graph_name);
foreach my $field (sort @{$graphs->{$graph}{'fields'}})
{
if(($proc_data_exists and $fields->{$field}{'source'} eq 'proc') or $fields->{$field}{'source'} eq 'both')
{
printf("%s.value %s\n", $field, $data->{$i}{$field});
}
}
print "\n";
}
}

View file

@ -1,974 +0,0 @@
#!/usr/bin/perl -w
# -*- perl -*-
=head1 NAME
cpu - Plugin to monitor CPU usage and frequencies.
=head1 APPLICABLE SYSTEMS
All Linux systems, but read below section
=head1 CONFIGURATION
The plugin automatically selects which graphics drawing.
Charts related to the frequencies of processors depends on the settings of the kernel:
Power management and ACPI options -> CPU Frequency scaling -> CPU frequency translation statistics -> Advanced statistics
=head2 WARNING AND CRITICAL SETTINGS
You can set warning and critical levels for each of the data
series the plugin reports. The following environment variables are
used as default for all fields:
env.warning
env.critical
But each field (system user nice etc...) can be controlled separately:
For example:
env.system_warning 70
env.user_warning 70
env.idle_critical 1
Also each field of each cpu can be controlled separately
For example:
env.cpu1_system_warning 70
env.cpu0_user_warning 70
env.cpu0_idle_critical 1
Algoritm is easy: for example current graph limit is env.cpu0_idle_critical if defined env.cpu0_idle_critical or env.idle_critical if defined env.idle_critical
or env.critical if defined env.critical. Or no limit
=head1 INTERPRETATION
The plugin shows each cpu usage in percent, shows the CPU frequency,
frequency shift frequencies, the percentage of use of frequencies
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=head1 VERSION
2.0
=head1 BUGS
none known
=head1 AUTHOR
Gorlow Maxim aka Sheridan <sheridan@sheridan-home.ru> (email and jabber)
=head1 LICENSE
GPLv2
=cut
use strict;
use warnings;
use Munin::Plugin;
use Data::Dumper;
my @cnames = qw(user nice system idle iowait irq softirq steal guest);
my $stat_file = "/proc/stat";
my $freq_path = "/sys/devices/system/cpu";
my $limits = {};
my $cpuinfo = {}; $cpuinfo->{'cpu_count'} = 0;
my @stat_file_content = ();
my $freq_mul = 1000; # CPU frequency multiplier from kHz to Hz
my $graphs =
{
'cpu_utilisation' => # multigraph
{
'title' => 'CPU:t: utilisation',
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100',
'vlabel' => '%',
'scale' => 'no',
'info' => 'This graph shows how CPU:t: time is spent :i:'
},
'cpu_all' => # single
{
'title' => 'All CPU utilisation',
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100',
'vlabel' => '%',
'scale' => 'no',
'info' => 'This graph shows how CPU time is spent on each processor',
'category' => 'cpu'
},
'cpu_freq_trans' => # multi
{
'title' => 'CPU frequency transitions',
'args' => '--base 1000',
'vlabel' => 'count',
'scale' => 'no',
'info' => 'This graph shows CPU transitions of each processor',
},
'cpu_freq' => # child of cpu_freq_trans
{
'title' => 'CPU:t: frequency (total)',
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100',
'vlabel' => '% of total',
'info' => 'This graph shows CPU:t: frequency :i:',
'category' => 'cpu'
},
'cpu_freq_ps' => # child of cpu_freq_trans
{
'title' => 'CPU:t: frequency (per secund)',
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100',
'vlabel' => '% per secund',
'info' => 'This graph shows CPU:t: frequency per secund from last update :i:',
'category' => 'cpu'
},
'cpu_freq_trans_table' => # child of cpu_freq_trans
{
'title' => 'CPU:t: frequency switches (total)',
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100',
'vlabel' => '% of total',
'scale' => 'no',
'info' => 'This graph shows CPU:t: frequency switches :i:',
},
'cpu_freq_trans_table_ps' => # child of cpu_freq_trans
{
'title' => 'CPU:t: frequency switches (per secund)',
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100',
'vlabel' => '% per secund',
'scale' => 'no',
'info' => 'This graph shows CPU:t: frequency switches per secund from last update :i:',
}
};
my $transparent = 'CC';
my $fields =
{
'user' =>
{
'label' => 'User',
'info' => 'Normal processes executing in user mode',
'type' => 'GAUGE',
'draw' => 'AREASTACK',
'min' => 0,
'max' => 100
},
'nice' =>
{
'label' => 'Nice',
'info' => 'Niced processes executing in user mode',
'type' => 'GAUGE',
'draw' => 'AREASTACK',
'min' => 0,
'max' => 100
},
'system' =>
{
'label' => 'System',
'info' => 'Processes executing in kernel mode',
'type' => 'GAUGE',
'draw' => 'AREASTACK',
'min' => 0,
'max' => 100
},
'idle' =>
{
'label' => 'Idle',
'info' => 'Twiddling thumbs',
'type' => 'GAUGE',
'draw' => 'AREASTACK',
'colour'=> 'FFFFDD'.$transparent,
'min' => 0,
'max' => 100
},
'iowait' =>
{
'label' => 'I/O wait',
'info' => 'Waiting for I/O to complete',
'type' => 'GAUGE',
'draw' => 'AREASTACK',
'min' => 0,
'max' => 100
},
'irq' =>
{
'label' => 'IRQ',
'info' => 'Servicing interrupts',
'type' => 'GAUGE',
'draw' => 'AREASTACK',
'min' => 0,
'max' => 100
},
'softirq' =>
{
'label' => 'Software IRQ',
'info' => 'Servicing software interrupts',
'type' => 'GAUGE',
'draw' => 'AREASTACK',
'min' => 0,
'max' => 100
},
'steal' =>
{
'label' => 'Steal',
'info' => 'Involuntary wait',
'type' => 'GAUGE',
'draw' => 'AREASTACK',
'min' => 0,
'max' => 100
},
'guest' =>
{
'label' => 'Guest',
'info' => 'Running a guest',
'type' => 'GAUGE',
'draw' => 'AREASTACK',
'min' => 0,
'max' => 100
},
'cpu_util' =>
{
'label' => ':t:',
'info' => ':t: utilisation',
'type' => 'GAUGE',
'draw' => 'LINE0.5',
'min' => 0,
'max' => 100
},
'freq_percent' =>
{
'label' => 'CPU:t: frequency',
'info' => 'CPU:t: frequency percent',
'type' => 'GAUGE',
'draw' => 'LINE0.5',
'min' => 0,
'max' => 100
},
'freq_hz' =>
{
'label' => ':t:',
'info' => 'CPU :t: frequency',
'type' => 'GAUGE',
'draw' => 'AREASTACK',
'min' => 0,
'max' => 100
},
'freq_trans' =>
{
'label' => ':t:',
'info' => ':t: frequency transitions',
'type' => 'GAUGE',
'draw' => 'LINE0.5',
'min' => 0
},
'freq_trans_table' =>
{
'label' => ':t:',
'info' => ':t: frequency switch',
'type' => 'GAUGE',
'draw' => 'AREASTACK',
'min' => 0,
'max' => 100
}
};
# ----------------- main ----------------
load_cpuinfo();
need_multigraph();
remove_unavialabled_counters();
if (defined($ARGV[0]) and ($ARGV[0] eq 'autoconf'))
{
printf("%s\n", -e $stat_file ? "yes" : "no (stats not exists)");
exit (0);
}
if (defined($ARGV[0]) and ($ARGV[0] eq 'config'))
{
print_config();
exit (0);
}
print_values();
#print Dumper prepare_graphs_fields();
exit(0);
# ----------------- sub's ----------------
# ----------------------- trim whitespace at begin and end of string ------------
sub trim
{
my($string)=@_;
for ($string) { s/^\s+//; s/\s+$//; }
return $string;
}
my $items_exists = {};
sub check_exists
{
my ($t, $cpu_num) = @_[0..1];
if (defined($cpu_num))
{
unless (exists($items_exists->{$t}{$cpu_num}))
{
if ($t eq 'freq_hz') { $items_exists->{$t}{$cpu_num} = ( -e sprintf("%s/cpu%s/cpufreq/scaling_min_freq" , $freq_path, $cpu_num) and
-e sprintf("%s/cpu%s/cpufreq/scaling_cur_freq" , $freq_path, $cpu_num) and
-e sprintf("%s/cpu%s/cpufreq/scaling_max_freq" , $freq_path, $cpu_num)); }
elsif ($t eq 'freq_trans') { $items_exists->{$t}{$cpu_num} = -e sprintf("%s/cpu%s/cpufreq/stats/time_in_state", $freq_path, $cpu_num); }
elsif ($t eq 'freq_times') { $items_exists->{$t}{$cpu_num} = -e sprintf("%s/cpu%s/cpufreq/stats/total_trans" , $freq_path, $cpu_num); }
elsif ($t eq 'freq_ttable') { $items_exists->{$t}{$cpu_num} = -e sprintf("%s/cpu%s/cpufreq/stats/trans_table" , $freq_path, $cpu_num); }
}
return $items_exists->{$t}{$cpu_num};
}
else
{
unless(exists($items_exists->{$t}{'total'}))
{
my $c = 0;
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++) { $c++ if (check_exists($t, $i)); }
$items_exists->{$t}{'total'} = $c > 0;
}
return $items_exists->{$t}{'total'};
}
}
# ------------------------- remove unavialable fields from graph --------------------------
sub remove_unavialabled_counters
{
my @cpu = split(/\s+/, (grep(/cpu\s/, get_stat_file_content()))[0]);
my $counters_count = scalar(@cpu) - 3;
@cnames = @cnames[0..$counters_count];
}
# ----------------------- get sysfs file content ----------------
my $fcontents = {};
sub get_sys_file_content
{
my $file = $_[0];
return 'nan' if (-z $file);
unless (exists($fcontents->{$file}))
{
open (FH, '<', $file) or die "$! $file \n";
$fcontents->{$file} = <FH>;
close (FH);
chomp $fcontents->{$file};
}
return $fcontents->{$file};
}
# -------------------------- loading cpu info ---------------------------------
sub load_cpuinfo
{
my $file = "/proc/cpuinfo";
open (FH, '<', $file) or die "$! $file \n";
my $cpu_num = -1;
for my $line (<FH>)
{
chomp $line;
$cpu_num++ if $line =~ m/^processor\s+:/;
$cpuinfo->{$cpu_num}{'name'} = trim((split(/:/,$line))[1]) if $line =~ m/^model name\s+:/;
$cpuinfo->{$cpu_num}{'bogomips'} = trim((split(/:/,$line))[1]) if $line =~ m/^bogomips\s+:/;
if (not exists($cpuinfo->{$cpu_num}{'info'}) and exists($cpuinfo->{$cpu_num}{'name'}) and exists($cpuinfo->{$cpu_num}{'bogomips'}))
{
$cpuinfo->{$cpu_num}{'info'} = sprintf("[%s (%s bogomips)]", $cpuinfo->{$cpu_num}{'name'}, $cpuinfo->{$cpu_num}{'bogomips'}) ;
}
}
close (FH);
$cpuinfo->{'cpu_count'} = $cpu_num+1;
}
# -------------------------- loading stat file lines ---------------------------------
sub get_stat_file_content
{
if(scalar(@stat_file_content) == 0)
{
open (FH, '<', $stat_file) or die "$! $stat_file \n";
for (<FH>)
{
next unless $_ =~ m/cpu/;
chomp $_;
push(@stat_file_content, $_);
}
close (FH);
}
return @stat_file_content;
}
# -------------------------------- replacing strings ------------------------
sub replace_template
{
my ($string, $needle, $replacement) = @_[0..2];
$string =~ s/$needle/$replacement/g;
return $string;
}
sub replace_templates
{
my ($src, $replacement_t, $replacement_i) = @_[0..2];
my $dst = {};
for my $key ( keys %{$src} )
{
$dst->{$key} = $src->{$key};
if($key =~ m/label|info|title/) { $dst->{$key} = replace_template($dst->{$key}, ':t:', $replacement_t); }
if($key =~ m/info|title/) { $dst->{$key} = replace_template($dst->{$key}, ':i:', $replacement_i); }
}
return $dst;
}
sub append_order
{
my ($pg, $graph_name, $field_name) = @_[0..2];
$pg->{$graph_name}{'graph'}{'order'} = exists($pg->{$graph_name}{'graph'}{'order'}) ? sprintf("%s %s", $pg->{$graph_name}{'graph'}{'order'}, $field_name) : $field_name;
}
sub append_field
{
my ($pg, $graph_name, $field_name, $field_src, $replacement_t, $replacement_i) = @_[0..5];
$pg->{$graph_name}{'fields'}{$field_name} = replace_templates($fields->{$field_src}, $replacement_t, $replacement_i);
append_order($pg, $graph_name, $field_name);
}
sub append_graph
{
my ($pg, $graph_name, $category, $graph_src, $replacement_t, $replacement_i) = @_[0..5];
$pg->{$graph_name}{'graph'} = replace_templates($graphs->{$graph_src}, $replacement_t, $replacement_i);
$pg->{$graph_name}{'graph'}{'category'} = $category;
}
# ---------------------------------------- preparing data for graphs ------------------------------------
sub prepare_graphs_fields
{
my $pg = {};
# ------------------ cpu_utilisation -----------------------------------
# ---------- general ----------------------
append_graph($pg, 'cpu_utilisation', 'cpu', 'cpu_utilisation', '', '');
for my $cname (@cnames) { append_field($pg, 'cpu_utilisation', $cname, $cname, '', ''); append_utilisation_limits($pg, 'cpu_utilisation', $cname, undef); }
if(check_exists('freq_hz')) { for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { append_field($pg, 'cpu_utilisation', sprintf("fp_%s", $i), 'freq_percent', $i, ''); } }
# ---------------- childs -------------------
if ($cpuinfo->{'cpu_count'} > 1)
{
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
my $graph_name = sprintf("cpu_utilisation.cpu%s", $i);
append_graph($pg, $graph_name, sprintf("CPU %s", $i), 'cpu_utilisation', $i, $cpuinfo->{$i}{'info'});
for my $cname (@cnames) { append_field($pg, $graph_name, $cname, $cname, '', ''); append_utilisation_limits($pg, $graph_name, $cname, $i); }
if(check_exists('freq_hz', $i)) { append_field($pg, $graph_name, 'fp', 'freq_percent', '', ''); }
}
}
# --------------- cpu_frequency --------------------------------------------
if(check_exists('freq_trans'))
{
# ------------ general --------------------
# - cpu frequency transitions -
append_graph($pg, 'cpu_frequency', 'cpu', 'cpu_freq_trans', '', '');
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { if (check_exists('freq_trans', $i)) { append_field($pg, 'cpu_frequency', sprintf("cpu_%s", $i), 'freq_trans', sprintf("CPU%s", $i), ''); } }
append_field($pg, 'cpu_frequency', 'total', 'freq_trans', 'Total', '');
# ---------------- childs -------------------
if(check_exists('freq_times'))
{
my $frequences = get_frequency_times();
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
if(check_exists('freq_times', $i))
{
# - cpu frequencyes -
my $graph_name = sprintf("cpu_frequency.percent_cpu%s", $i);
append_graph($pg, $graph_name, sprintf("CPU %s", $i), 'cpu_freq', $i, $cpuinfo->{$i}{'info'});
for my $freq (@{$frequences->{'names'}{$i}}) { append_field($pg, $graph_name, sprintf("hz_%s", $freq), 'freq_hz', scaleNumber($freq, 'Hz'), ''); }
# - cpu frequencyes per secund -
$graph_name = sprintf("cpu_frequency.percent_ps_cpu%s", $i);
append_graph($pg, $graph_name, sprintf("CPU %s", $i), 'cpu_freq_ps', $i, $cpuinfo->{$i}{'info'});
for my $freq (@{$frequences->{'names'}{$i}}) { append_field($pg, $graph_name, sprintf("hz_%s", $freq), 'freq_hz', scaleNumber($freq, 'Hz'), ''); }
}
}
}
if(check_exists('freq_ttable'))
{
my $f_table = get_frequency_trans_table();
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
if(check_exists('freq_ttable', $i))
{
# - cpu frequencyes table -
my $graph_name = sprintf("cpu_frequency.trans_table_cpu%s", $i);
append_graph($pg, $graph_name, sprintf("CPU %s", $i), 'cpu_freq_trans_table', $i, $cpuinfo->{$i}{'info'});
for my $from (sort keys %{$f_table->{'values'}{$i}})
{
for my $to (sort keys %{$f_table->{'values'}{$i}{$from}})
{
next if ($from eq $to);
append_field($pg, $graph_name, sprintf("f_%s_t_%s", $from, $to), 'freq_trans_table', sprintf(". %9s -> %s", scaleNumber($from, 'Hz'), scaleNumber($to, 'Hz')), '');
}
}
# - cpu frequencyes table per secund -
$graph_name = sprintf("cpu_frequency.trans_table_ps_cpu%s", $i);
append_graph($pg, $graph_name, sprintf("CPU %s", $i), 'cpu_freq_trans_table_ps', $i, $cpuinfo->{$i}{'info'});
for my $from (sort keys %{$f_table->{'values'}{$i}})
{
for my $to (sort keys %{$f_table->{'values'}{$i}{$from}})
{
next if ($from eq $to);
append_field($pg, $graph_name, sprintf("f_%s_t_%s", $from, $to), 'freq_trans_table', sprintf(". %9s -> %s", scaleNumber($from, 'Hz'), scaleNumber($to, 'Hz')), '');
}
}
}
}
}
}
# --------------- cpu_all -----------------------------------------
if ($cpuinfo->{'cpu_count'} > 1)
{
append_graph($pg, 'cpu_all', 'cpu', 'cpu_all', '', '');
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { append_field($pg, 'cpu_all', sprintf("cpu_%s", $i), 'cpu_util', sprintf("CPU%s", $i)); }
append_field($pg, 'cpu_all', 'total', 'cpu_util', 'Combined');
}
return $pg;
}
# ------------------------------------ printing limits (for utilisation graphs) ----------------
sub append_utilisation_limits
{
my ($pg, $graph_name, $cname, $i) = @_[0..3];
for my $type (qw(warning critical))
{
my $field = sprintf("%s_%s", $cname, $type);
my $cpu_field = defined($i) ? sprintf("cpu%s_%s_%s", $i, $cname, $type) : undef;
my $limit = (defined($i) and defined($limits->{'utilisation'}{$cpu_field})) ?
$limits->{'utilisation'}{$cpu_field} :
(
defined($limits->{'utilisation'}{$field}) ?
$limits->{'utilisation'}{$field} :
(
defined($limits->{'utilisation'}{$type}) ?
$limits->{'utilisation'}{$type} :
undef
)
);
if(defined($limit)) { $pg->{$graph_name}{'fields'}{$cname}{$type} = $limit; }
}
}
# ---------------- loading limits -------------
sub load_limits
{
$limits->{'utilisation'}{'warning'} = $ENV{warning} || undef;
$limits->{'utilisation'}{'critical'} = $ENV{critical} || undef;
for my $cname (@cnames)
{
for my $t (qw(warning critical))
{
my $name = sprintf("%s_%s", $cname, $t);
$limits->{'utilisation'}{$name} = $ENV{$name} || undef;
for (my $i = 0; $i <= $cpuinfo->{'cpu_count'}; $i++)
{
$name = sprintf("cpu%s_%s_%s",$i, $cname, $t);
$limits->{'utilisation'}{$name} = $ENV{$name} || undef;
}
}
}
}
# --------------------------------- graph configs ----------------------------
sub print_config
{
load_limits();
my $config = prepare_graphs_fields();
for my $g (sort keys %{$config})
{
printf("multigraph %s\n", $g);
for my $go (sort keys %{$config->{$g}{'graph'}}) { printf("graph_%s %s\n", $go, $config->{$g}{'graph'}{$go}); }
for my $f (sort keys %{$config->{$g}{'fields'}}) { for my $fo (sort keys %{$config->{$g}{'fields'}{$f}}) { printf("%s.%s %s\n", $f, $fo, $config->{$g}{'fields'}{$f}{$fo}); } }
print "\n";
}
}
# ----------------------------------- saving state data using munin --------------------
sub save_state_data
{
my $data = $_[0];
my $d = Data::Dumper->new([$data]);
$d->Indent(0);
save_state($d->Dump);
}
# -------------------------------- loading previous state data using munin -------------------
sub restore_state_data
{
my $VAR1;
my $states = (restore_state())[0];
eval $states if defined $states;
return $VAR1;
}
sub load_stats
{
my $stats = {};
# need to store --------------------
$stats->{'timestamp'} = time();
$stats->{'cpu_util'} = get_cpu_utilisation_stats() ;
$stats->{'f_trans'} = get_frequency_transitions() if check_exists('freq_trans') ;
$stats->{'f_times'} = get_frequency_times() if check_exists('freq_times') ;
$stats->{'f_ttable'} = get_frequency_trans_table() if check_exists('freq_ttable');
save_state_data($stats);
# no need to store --------------------
$stats->{'f_minmax'} = get_cpu_curr_max_freqences() if check_exists('freq_hz') ;
#print Dumper $stats;
return $stats;
}
# ---------------------------------- loading cpu stats from loaded lines ------------------------
sub get_cpu_utilisation_stats
{
my $stats = {};
for (my $i = 0; $i <= $cpuinfo->{'cpu_count'}; $i++)
{
my $rx = $i == $cpuinfo->{'cpu_count'} ? 'cpu' : sprintf ("cpu%s", $i);
my $cn = $i == $cpuinfo->{'cpu_count'} ? 'total' : $i;
my @tmp = split(/\s+/, (grep(/$rx\s/, get_stat_file_content()))[0]);
my $j = 1;
for my $cname (@cnames)
{
$stats->{$cn}{$cname} = $tmp[$j];
$j++;
}
}
return $stats;
}
# ------------------ loading frequency transitions for each cpu ----------------------------
sub get_frequency_transitions
{
my $stats = {};
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
next unless (check_exists('freq_trans', $i));
$stats->{$i} = get_sys_file_content(sprintf("%s/cpu%s/cpufreq/stats/total_trans", $freq_path, $i));
}
return $stats;
}
# ------------------ loading frequency times for each cpu ----------------------------
sub get_frequency_times
{
my $stat = {};
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
next unless (check_exists('freq_times', $i));
my $total = 0;
my $file = sprintf("%s/cpu%s/cpufreq/stats/time_in_state", $freq_path, $i);
open (FH, '<', $file) or die "$! $file \n";
for my $line (<FH>)
{
chomp $line;
my ($hz, $count) = split(/\s+/, $line);
$hz = $hz*$freq_mul;
$stat->{'values'}{$i}{$hz} = $count;
push(@{$stat->{'names'}{$i}}, $hz);
$total += $count;
}
close (FH);
$stat->{'total'}{$i} = $total;
}
return $stat;
}
# ------------------ loading current and max frequency for each cpu ----------------------------
sub get_cpu_curr_max_freqences
{
my $freq = {};
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
next unless (check_exists('freq_hz', $i));
my $cpu_path = sprintf("%s/cpu%s/cpufreq", $freq_path, $i);
$freq->{'cur'}{$i} = get_sys_file_content(sprintf("%s/scaling_cur_freq", $cpu_path))*$freq_mul;
$freq->{'max'}{$i} = get_sys_file_content(sprintf("%s/scaling_max_freq", $cpu_path))*$freq_mul;
$freq->{'min'}{$i} = get_sys_file_content(sprintf("%s/scaling_min_freq", $cpu_path))*$freq_mul;
}
return $freq;
}
sub get_frequency_trans_table
{
my $tbl = {};
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
next unless (check_exists('freq_ttable', $i));
my @frequences;
my $fcount = 0;
my $total = 0;
my $file = sprintf("%s/cpu%s/cpufreq/stats/trans_table", $freq_path, $i);
open (FH, '<', $file) or die "$! $file \n";
for my $line (<FH>)
{
chomp $line;
my ($left, $right) = split(/:/, $line);
next if($left =~ m/From/);
if($left =~ m/\d+/)
{
my $frequence = trim($left)*$freq_mul;
my @counters = split(/\s+/, trim($right));
for (my $j = 0; $j<$fcount; $j++)
{
$tbl->{'values'}{$i}{$frequence}{$frequences[$j]*$freq_mul} = $counters[$j];
$total += $counters[$j];
}
}
else
{
@frequences = split(/\s+/, trim($right));
$fcount = scalar(@frequences);
}
}
$tbl->{'total'}{$i} = $total;
close (FH);
}
return $tbl;
}
sub one_second_part
{
my ($curr, $prev, $timediff) = @_[0..2];
#print "$prev, $curr, $timediff\n";
return 'NaN' if ($curr < $prev or $timediff < 0);
return $curr - $prev if $timediff == 0;
return ($curr - $prev)/$timediff;
}
sub divide
{
my ($divider, $divident) = @_[0..1];
return 'NaN' if $divident == 0;
return $divider/$divident;
}
# -------------------------------- calculating fields values ------------------------------
sub calculate
{
my ($pstats, $cstats) = @_[0..1];
my $result = {};
my $timediff = $cstats->{'timestamp'} - $pstats->{'timestamp'};
# --- cpu utilisation ----
for my $cpu (keys %{$cstats->{'cpu_util'}})
{
# ------ calculating 1%
$result->{'cpu_util'}{'1%'}{$cpu} = 0;
for my $cname (@cnames)
{
$result->{'cpu_util'}{'diff'}{$cpu}{$cname} = one_second_part($cstats->{'cpu_util'}{$cpu}{$cname}, $pstats->{'cpu_util'}{$cpu}{$cname}, $timediff);
$result->{'cpu_util'}{'1%'}{$cpu} += $result->{'cpu_util'}{'diff'}{$cpu}{$cname} if $result->{'cpu_util'}{'diff'}{$cpu}{$cname} ne 'NaN';
}
$result->{'cpu_util'}{'1%'}{$cpu} = $result->{'cpu_util'}{'1%'}{$cpu}/100;
# ------ calculating used percents
$result->{'cpu_util'}{'used'}{$cpu} = 0;
for my $cname (@cnames)
{
$result->{'cpu_util'}{'%'}{$cpu}{$cname} = divide($result->{'cpu_util'}{'diff'}{$cpu}{$cname}, $result->{'cpu_util'}{'1%'}{$cpu});
next if $cname eq 'idle';
$result->{'cpu_util'}{'used'}{$cpu} += $result->{'cpu_util'}{'%'}{$cpu}{$cname} if $result->{'cpu_util'}{'%'}{$cpu}{$cname} ne 'NaN';
}
}
# ------ freq min max ----
if (check_exists('freq_hz'))
{
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
$result->{'f_minmax'}{'%'}{$i} = divide($cstats->{'f_minmax'}{'cur'}{$i} - $cstats->{'f_minmax'}{'min'}{$i},
(($cstats->{'f_minmax'}{'max'}{$i} - $cstats->{'f_minmax'}{'min'}{$i}) / 100 )) if (check_exists('freq_hz', $i));
}
}
# ---- freq trans ----
if (check_exists('freq_trans'))
{
$result->{'f_trans'}{'total'} = 0;
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
if(check_exists('freq_trans', $i))
{
$result->{'f_trans'}{$i} = one_second_part($cstats->{'f_trans'}{$i}, $pstats->{'f_trans'}{$i}, $timediff);
$result->{'f_trans'}{'total'} += $result->{'f_trans'}{$i} if $result->{'f_trans'}{$i} ne 'NaN';
}
}
}
# -- freq times ---
if (check_exists('freq_times'))
{
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
if (check_exists('freq_times', $i))
{
my $oneprc = $cstats->{'f_times'}{'total'}{$i}/100;
my $ps_total = 0;
for my $hz (@{$cstats->{'f_times'}{'names'}{$i}})
{
$result->{'f_times'}{$i}{$hz} = divide($cstats->{'f_times'}{'values'}{$i}{$hz}, $oneprc);
$cstats->{'f_times'}{'%_ps'}{$i}{$hz} = one_second_part($cstats->{'f_times'}{'values'}{$i}{$hz}, $pstats->{'f_times'}{'values'}{$i}{$hz}, $timediff);
$ps_total += $cstats->{'f_times'}{'%_ps'}{$i}{$hz};
}
$ps_total = $ps_total/100;
for my $hz (@{$cstats->{'f_times'}{'names'}{$i}})
{
$result->{'f_times_ps'}{$i}{$hz} = divide($cstats->{'f_times'}{'%_ps'}{$i}{$hz}, $ps_total);
}
}
}
}
# ------- freq trans table ---
if (check_exists('freq_ttable'))
{
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
if (check_exists('freq_ttable', $i))
{
my $oneprc = $cstats->{'f_ttable'}{'total'}{$i}/100;
my $ps_total = 0;
for my $from (keys %{$cstats->{'f_ttable'}{'values'}{$i}})
{
for my $to (keys %{$cstats->{'f_ttable'}{'values'}{$i}{$from}})
{
next if ($from eq $to);
$result->{'f_ttable'}{$i}{$from}{$to} = divide($cstats->{'f_ttable'}{'values'}{$i}{$from}{$to}, $oneprc);
$cstats->{'f_ttable'}{'%_ps'}{$i}{$from}{$to} = one_second_part($cstats->{'f_ttable'}{'values'}{$i}{$from}{$to}, $pstats->{'f_ttable'}{'values'}{$i}{$from}{$to}, $timediff);
$ps_total += $cstats->{'f_ttable'}{'%_ps'}{$i}{$from}{$to};
}
}
$ps_total = $ps_total/100;
for my $from (keys %{$cstats->{'f_ttable'}{'values'}{$i}})
{
for my $to (keys %{$cstats->{'f_ttable'}{'values'}{$i}{$from}})
{
next if ($from eq $to);
$result->{'f_ttable_ps'}{$i}{$from}{$to} = divide($cstats->{'f_ttable'}{'%_ps'}{$i}{$from}{$to}, $ps_total);
}
}
}
}
}
#print Dumper $result;
return $result;
}
# ---------------------------------------- preparing values ------------------------------------
sub prepare_graphs_values
{
my ($data) = $_[0];
my $pg = {};
# ------------------ cpu_utilisation -----------------------------------
# ---------- general ----------------------
for my $cname (@cnames) { $pg->{'cpu_utilisation'}{$cname} = $data->{'cpu_util'}{'%'}{'total'}{$cname}; }
if(check_exists('freq_hz')) { for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { $pg->{'cpu_utilisation'}{sprintf("fp_%s", $i)} = $data->{'f_minmax'}{'%'}{$i}; } }
# ---------------- childs -------------------
if ($cpuinfo->{'cpu_count'} > 1)
{
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
my $graph_name = sprintf("cpu_utilisation.cpu%s", $i);
for my $cname (@cnames) { $pg->{$graph_name}{$cname} = $data->{'cpu_util'}{'%'}{$i}{$cname}; }
if(check_exists('freq_hz', $i)) { $pg->{$graph_name}{'fp'} = $data->{'f_minmax'}{'%'}{$i}; }
}
}
# --------------- cpu_frequency --------------------------------------------
if(check_exists('freq_trans'))
{
# ------------ general --------------------
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { $pg->{'cpu_frequency'}{sprintf("cpu_%s", $i)} = $data->{'f_trans'}{$i} if (check_exists('freq_trans', $i)); }
$pg->{'cpu_frequency'}{'total'} = $data->{'f_trans'}{'total'};
# ---------------- childs -------------------
if(check_exists('freq_times'))
{
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
if(check_exists('freq_times', $i))
{
my $graph_name = sprintf("cpu_frequency.percent_cpu%s", $i);
for my $freq (keys %{$data->{'f_times'}{$i}}) { $pg->{$graph_name}{sprintf("hz_%s", $freq)} = $data->{'f_times'}{$i}{$freq}; }
$graph_name = sprintf("cpu_frequency.percent_ps_cpu%s", $i);
for my $freq (keys %{$data->{'f_times_ps'}{$i}}) { $pg->{$graph_name}{sprintf("hz_%s", $freq)} = $data->{'f_times_ps'}{$i}{$freq}; }
}
}
}
if(check_exists('freq_ttable'))
{
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
{
if(check_exists('freq_ttable', $i))
{
my $graph_name = sprintf("cpu_frequency.trans_table_cpu%s", $i);
for my $from (keys %{$data->{'f_ttable'}{$i}})
{
for my $to (keys %{$data->{'f_ttable'}{$i}{$from}})
{
$pg->{$graph_name}{sprintf("f_%s_t_%s", $from, $to)} = $data->{'f_ttable'}{$i}{$from}{$to};
}
}
$graph_name = sprintf("cpu_frequency.trans_table_ps_cpu%s", $i);
for my $from (keys %{$data->{'f_ttable_ps'}{$i}})
{
for my $to (keys %{$data->{'f_ttable_ps'}{$i}{$from}})
{
$pg->{$graph_name}{sprintf("f_%s_t_%s", $from, $to)} = $data->{'f_ttable_ps'}{$i}{$from}{$to};
}
}
}
}
}
}
# --------------- cpu_all --------------------------------------------
if ($cpuinfo->{'cpu_count'} > 1)
{
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { $pg->{'cpu_all'}{sprintf("cpu_%s", $i)} = $data->{'cpu_util'}{'used'}{$i}; }
$pg->{'cpu_all'}{'total'} = $data->{'cpu_util'}{'used'}{'total'};
}
return $pg;
}
# -------------------------------- printing values -----------------------------------
sub print_values
{
my $pstats = restore_state_data();
my $cstats = load_stats();
if (exists ($pstats->{'timestamp'}))
{
my $values = prepare_graphs_values(calculate($pstats, $cstats));
#print Dumper $values;
for my $g (sort keys %{$values})
{
printf("multigraph %s\n", $g);
for my $f (sort keys %{$values->{$g}}) { printf("%s.value %s\n", $f, $values->{$g}{$f}); }
print "\n";
}
}
}
__END__
- user: normal processes executing in user mode
- nice: niced processes executing in user mode
- system: processes executing in kernel mode
- idle: twiddling thumbs
- iowait: waiting for I/O to complete
- irq: servicing interrupts
- softirq: servicing softirqs
- steal: involuntary wait
- guest: running a guest

File diff suppressed because it is too large Load diff

View file

@ -1,469 +0,0 @@
#!/usr/bin/perl -w
# -*- perl -*-
=head1 NAME
irq - Plugin to monitor inerrupts.
=head1 APPLICABLE SYSTEMS
All Linux systems
=head1 CONFIGURATION
None need
=head2 WARNING AND CRITICAL SETTINGS
You can set warning and critical levels for each of the data
series the plugin reports.
'General' graph support cpu-irqtype limits and irqtype limits
Examples:
[irq]
env.warning_cpu1_sirq_total 550
env.critical_cpu0_irq_total 600
env.warning_irq_total 700
env.critical_sirq_total 700
'Child' graphs support cpu-irqtype-irqname and irqtype-irqname limits
Examples:
[irq]
env.warning_cpu0_irq_7 100
env.critical_cpu1_sirq_HI 100
env.warning_irq_LOC 100
env.critical_irq_12 200
env.warning_sirq_BLOCK 1000
Note: irqtype: sirq, irq; sirq - Software IRQ; irq name you can see in [] on graph
=head1 INTERPRETATION
The plugin shows each cpu interrupts: summary and IRQ/Software IRQ per CPU
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=head1 VERSION
1.0
=head1 BUGS
I can not understand, how set limit to mirrored fields, so they may not display correctly
=head1 AUTHOR
Gorlow Maxim aka Sheridan <sheridan@sheridan-home.ru> (email and jabber)
=head1 LICENSE
GPLv2
=cut
use strict;
use warnings;
use Munin::Plugin;
use Data::Dumper;
my $IRQi = {};
my $graphs =
{
'irq_total' =>
{
'title' => 'Interrupts per cpu',
'args' => '--base 1000',
'vlabel' => 'count of IRQ (+) / sIRQ (-) per secund',
'info' => 'This graph shows interrupts per secund from last update',
'category' => 'system'
},
'irq_cpu' =>
{
'title' => 'CPU:cpu: :irq_type:',
'args' => '--base 1000',
'vlabel' => 'count per secund',
'info' => 'This graph shows :irq_type: for CPU:cpu: per secund from last update',
'category' => 'cpu :cpu:'
}
};
my $fields =
{
'irq' =>
{
'label' => '[:irq:] :irqinfo:',
'info' => ':irq:: :irqinfo:',
'type' => 'GAUGE',
'draw' => 'LINE1'
},
'irq_sirq' =>
{
'label' => 'CPU:cpu: sIRQ/IRQ',
'info' => 'Total sIRQ/IRQ for CPU:cpu:',
'type' => 'GAUGE',
'draw' => 'LINE1'
}
};
my $irq_types =
{
'irq' => 'Interrupts',
'sirq' => 'Software interrupts'
};
my $irq_descriptions =
{
'HI' => 'High priority tasklets',
'TIMER' => 'Timer bottom half',
'NET_TX' => 'Transmit network packets',
'NET_RX' => 'Receive network packets',
'SCSI' => 'SCSI bottom half',
'TASKLET' => 'Handles regular tasklets'
};
# ----------------- main ----------------
need_multigraph();
# -- autoconf --
if (defined($ARGV[0]) and ($ARGV[0] eq 'autoconf'))
{
printf("%s\n", (-e "/proc/interrupts" and -e "/proc/softirqs") ? "yes" : "no (stats not exists)");
exit (0);
}
# -- config --
load_irq_info();
if (defined($ARGV[0]) and ($ARGV[0] eq 'config')) { print_config(); exit (0); }
# -- values --
print_values(); exit(0);
# ----------------- sub's ----------------
# ----------------------- trim whitespace at begin and end of string ------------
sub trim
{
my ($string) = @_;
for ($string) { s/^\s+//; s/\s+$//; }
return $string;
}
# -------------------------- loading irq stats ---------------------------------
sub load_irq_info_file
{
my $file = $_[0];
my $info = {};
my $cpu_count = 0;
my $summ = 0;
open (FH, '<', $file) or die "$! $file \n";
for my $line (<FH>)
{
chomp $line;
if($line =~ m/:/)
{
my ($name, $stat) = split(/:/, trim($line));
my @data = split(/\s+/, trim($stat));
for (my $i=0; $i<$cpu_count; $i++)
{
if (defined $data[$i])
{
$info->{'info'}{$i}{$name} = $data[$i];
$info->{'summ'}{$i} += $data[$i];
}
}
if(scalar(@data) > $cpu_count)
{
my $iname = '';
($iname = $line) =~ s/^.*:(\s+\d+)+\s+(.*)$/$2/;
if ($iname ne '')
{
if ($iname =~ m/.*-.*-.*/)
{
my @parts = ($iname =~ /^((\w+-)*\w+)\s+(.*)\s*$/g);
$iname = sprintf("%s (%s)", $parts[0], $parts[2]);
}
$info->{'description'}{$name} = $iname;
}
}
elsif(exists ($irq_descriptions->{$name}))
{
$info->{'description'}{$name} = $irq_descriptions->{$name};
}
}
else
{
my @cpus = split(/\s+/, trim($line));
$cpu_count = scalar(@cpus);
for (my $i=0; $i<$cpu_count; $i++)
{
$info->{'summ'}{$i} = 0;
}
}
}
close (FH);
$info->{'cpu_count'} = $cpu_count;
return $info;
}
# -------------- loading all IRQ statistics ---------------------------
sub load_irq_info
{
my ($irq, $sirq) = (load_irq_info_file("/proc/interrupts"), load_irq_info_file("/proc/softirqs"));
$IRQi->{'stat'}{'irq' } = $irq ->{'info'};
$IRQi->{'stat'}{'sirq'} = $sirq->{'info'};
$IRQi->{'summ'}{'irq' } = $irq ->{'summ'};
$IRQi->{'summ'}{'sirq'} = $sirq->{'summ'};
$IRQi->{'description'}{'irq' } = $irq ->{'description'} if exists($irq ->{'description'});
$IRQi->{'description'}{'sirq'} = $sirq->{'description'} if exists($sirq->{'description'});
$IRQi->{'cpu_count'} = $irq ->{'cpu_count'};
}
# ------------------ loading limits ---------------------
sub load_limits
{
my $flags = {};
my $limits = {};
my $name = '';
for my $irq_type (qw(irq sirq))
{
for my $t (qw(warning critical))
{
$name = sprintf("%s_%s_total", $t, $irq_type); # env.warning_irq_total 22
$limits->{'irq_total'}{$irq_type}{$t} = $ENV{$name} || undef;
for (my $i=0; $i < $IRQi->{'cpu_count'}; $i++)
{
$name = sprintf("%s_cpu%s_%s_total", $t, $i, $irq_type); # env.warning_cpu1_sirq_total 1112
$limits->{'irq_total_percpu'}{$irq_type}{$t}{$i} = $ENV{$name} || undef;
for my $irq_name (keys %{$IRQi->{'stat'}{$irq_type}{$i}})
{
$name = sprintf("%s_cpu%s_%s_%s", $t, $i, $irq_type, $irq_name); # env.warning_cpu0_irq_7 25
$limits->{'percpu_perirq'}{$irq_type}{$t}{$i}{$irq_name} = $ENV{$name} || undef;
$name = sprintf("%s_%s_%s", $t, $irq_type, $irq_name);
unless (exists($flags->{$name}))
{
$limits->{'perirq'}{$irq_type}{$t}{$irq_name} = $ENV{$name} || undef; # env.critical_sirq_RCU 14
$flags->{$name} = 1;
}
}
}
}
}
return $limits;
}
# -------------------------------- replacing strings ------------------------
sub replace
{
my ($string, $needle, $replacement) = @_[0..2];
$string =~ s/$needle/$replacement/g;
return $string;
}
# ----------------- append limit values to general graph fields-----------------------------
sub append_total_limit
{
my ($limits, $gr, $irq_type, $field_name, $cpu_num) = @_[0..4];
for my $t (qw(warning critical))
{
my $limit = defined($limits->{'irq_total_percpu'}{$irq_type}{$t}{$cpu_num}) ? $limits->{'irq_total_percpu'}{$irq_type}{$t}{$cpu_num} :
($limits->{'irq_total'}{$irq_type}{$t} || undef);
if (defined($limit))
{
$gr->{'irq'}{'fields'}{$field_name}{$t} = $limit;
}
}
}
# ----------------- append limit values to chields graphs fields-----------------------------
sub append_cpu_limit
{
my ($limits, $gr, $irq_type, $field_name, $graph_name, $cpu_num, $irq_name) = @_[0..6];
for my $t (qw(warning critical))
{
my $limit = defined($limits->{'percpu_perirq'}{$irq_type}{$t}{$cpu_num}{$irq_name}) ? $limits->{'percpu_perirq'}{$irq_type}{$t}{$cpu_num}{$irq_name} :
($limits->{'perirq'}{$irq_type}{$t}{$irq_name} || undef);
if (defined($limit))
{
$gr->{$graph_name}{'fields'}{$field_name}{$t} = $limit;
}
}
}
# ------------------------------ preparing graphs configurations ------------------------------
sub prepare_graphs
{
my $gr = {};
my $limits = load_limits();
# --- general graph ---
$gr->{'irq'}{'graph'} = $graphs->{'irq_total'};
$gr->{'irq'}{'graph'}{'order'} = "";
for (my $i=0; $i < $IRQi->{'cpu_count'}; $i++)
{
# --- general fields ---
my ($up_field_name, $down_field_name) = (sprintf("i%s", $i), sprintf("si%s", $i));
append_total_limit($limits, $gr, 'irq', $up_field_name, $i);
append_total_limit($limits, $gr, 'sirq', $down_field_name, $i);
$gr->{'irq'}{'graph'}{'order'} .= sprintf(" %s %s", $down_field_name, $up_field_name);
$gr->{'irq'}{'fields'}{$up_field_name}{'type'} = $fields->{'irq_sirq'}{'type'};
$gr->{'irq'}{'fields'}{$down_field_name}{'type'} = $fields->{'irq_sirq'}{'type'};
$gr->{'irq'}{'fields'}{$up_field_name}{'draw'} = $fields->{'irq_sirq'}{'draw'};
$gr->{'irq'}{'fields'}{$down_field_name}{'draw'} = $fields->{'irq_sirq'}{'draw'};
$gr->{'irq'}{'fields'}{$up_field_name}{'label'} = replace($fields->{'irq_sirq'}{'label'}, ':cpu:', $i);
$gr->{'irq'}{'fields'}{$up_field_name}{'info'} = replace($fields->{'irq_sirq'}{'info'} , ':cpu:', $i);
$gr->{'irq'}{'fields'}{$down_field_name}{'label'} = 'NaN';
$gr->{'irq'}{'fields'}{$down_field_name}{'info'} = 'NaN';
$gr->{'irq'}{'fields'}{$up_field_name}{'negative'} = $down_field_name;
$gr->{'irq'}{'fields'}{$down_field_name}{'graph'} = 'no';
# --- child graphs ---
for my $irq_type (qw(irq sirq))
{
my $graph_name = sprintf("irq.%s_cpu%s", $irq_type, $i);
$gr->{$graph_name}{'graph'}{'order'} = "";
$gr->{$graph_name}{'graph'}{'args'} = $graphs->{'irq_cpu'}{'args'};
$gr->{$graph_name}{'graph'}{'vlabel'} = $graphs->{'irq_cpu'}{'vlabel'};
for my $go (qw(title info))
{
$gr->{$graph_name}{'graph'}{$go} = replace($graphs->{'irq_cpu'}{$go}, ':irq_type:', $irq_types->{$irq_type});
$gr->{$graph_name}{'graph'}{$go} = replace($gr->{$graph_name}{'graph'}{$go}, ':cpu:', $i);
}
$gr->{$graph_name}{'graph'}{'category'} = replace($graphs->{'irq_cpu'}{'category'}, ':cpu:', $i);
# -- child fields --
my @irq_names = keys %{$IRQi->{'stat'}{$irq_type}{$i}};
# names splitted for better sorting
for my $irq_name ((
(sort {int $a <=> int $b} grep{/^\d/} @irq_names),
(sort grep{!/(^\d|ERR|MIS)/} @irq_names),
(sort grep{/(ERR|MIS)/ } @irq_names)
))
{
my $field_name = clean_fieldname(sprintf("irq_%s", $irq_name));
append_cpu_limit($limits, $gr, $irq_type, $field_name, $graph_name, $i, $irq_name);
$gr->{$graph_name}{'graph'}{'order'} .= ' '.$field_name;
for my $fo (qw(label info))
{
$gr->{$graph_name}{'fields'}{$field_name}{$fo} = replace($fields->{'irq'}{$fo}, ':irq:', $irq_name);
$gr->{$graph_name}{'fields'}{$field_name}{$fo} = replace($gr->{$graph_name}{'fields'}{$field_name}{$fo},
':irqinfo:',
exists($IRQi->{'description'}{$irq_type}{$irq_name}) ?
$IRQi->{'description'}{$irq_type}{$irq_name} :
'');
}
$gr->{$graph_name}{'fields'}{$field_name}{'type'} = $fields->{'irq'}{'type'};
$gr->{$graph_name}{'fields'}{$field_name}{'draw'} = $fields->{'irq'}{'draw'};
}
}
}
return $gr;
}
# --------------------------------- graph configs ----------------------------
sub print_config
{
my $config = prepare_graphs();
for my $g (sort keys %{$config})
{
printf("multigraph %s\n", $g);
for my $go (sort keys %{$config->{$g}{'graph'}}) { printf("graph_%s %s\n", $go, $config->{$g}{'graph'}{$go}); }
for my $f (sort keys %{$config->{$g}{'fields'}}) { for my $fo (sort keys %{$config->{$g}{'fields'}{$f}}) { printf("%s.%s %s\n", $f, $fo, $config->{$g}{'fields'}{$f}{$fo}); } }
print "\n";
}
}
# ----------------------------------- saving state data using munin --------------------
sub save_state_data
{
my $data = $_[0];
my $d = Data::Dumper->new([$data]);
$d->Indent(0);
save_state($d->Dump);
}
# -------------------------------- loading previous state data using munin -------------------
sub restore_state_data
{
my $VAR1;
my $states = (restore_state())[0];
eval $states if defined $states;
return $VAR1;
}
# ----------------------------- loading statistic and save it for feature use--------------
sub load_stats
{
delete ($IRQi->{'description'});
$IRQi->{'timestamp'} = time();
save_state_data($IRQi);
return $IRQi;
}
# ----------- calculate current and previous values difference -----------------------
sub diff_value
{
my ($pvalue, $cvalue, $timediff) = @_[0..2];
return 'NaN' if $timediff <= 0 or $pvalue > $cvalue;
return ($cvalue - $pvalue)/$timediff;
}
# ----------------- calculating values ---------------------
sub calculate
{
my ($pstats, $cstats) = @_[0..1];
my $data = {};
my $timediff = $cstats->{'timestamp'} - $pstats->{'timestamp'};
for my $irq_type (qw(irq sirq))
{
for (my $i=0; $i < $IRQi->{'cpu_count'}; $i++)
{
$data->{'summ'}{$irq_type}{$i} = diff_value($pstats->{'summ'}{$irq_type}{$i}, $cstats->{'summ'}{$irq_type}{$i}, $timediff);
for my $irq_name (keys %{$cstats->{'stat'}{$irq_type}{$i}})
{
$data->{'stat'}{$irq_type}{$i}{$irq_name} = diff_value($pstats->{'stat'}{$irq_type}{$i}{$irq_name}, $cstats->{'stat'}{$irq_type}{$i}{$irq_name}, $timediff);
}
}
}
return $data;
}
# --------------------- preparing graphs values config ------------------------
sub prepare_graphs_values
{
my $data = $_[0];
my $values = {};
for (my $i=0; $i < $IRQi->{'cpu_count'}; $i++)
{
$values->{'irq'}{sprintf("i%s", $i)} = $data->{'summ'}{'irq'} {$i};
$values->{'irq'}{sprintf("si%s", $i)} = $data->{'summ'}{'sirq'}{$i};
for my $irq_type (qw(irq sirq))
{
my $graph_name = sprintf("irq.%s_cpu%s", $irq_type, $i);
for my $irq_name (keys %{$data->{'stat'}{$irq_type}{$i}})
{
my $field_name = clean_fieldname(sprintf("irq_%s", $irq_name));
$values->{$graph_name}{$field_name} = $data->{'stat'}{$irq_type}{$i}{$irq_name};
}
}
}
return $values;
}
# -------------------------------- printing values -----------------------------------
sub print_values
{
my $pstats = restore_state_data();
my $cstats = load_stats();
if (exists ($pstats->{'timestamp'}))
{
my $values = prepare_graphs_values(calculate($pstats, $cstats));
for my $g (sort keys %{$values})
{
printf("multigraph %s\n", $g);
for my $f (sort keys %{$values->{$g}}) { printf("%s.value %s\n", $f, $values->{$g}{$f}); }
print "\n";
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,462 +0,0 @@
#!/usr/bin/perl
# -*- perl -*-
=head1 NAME
squid - Plugin to monitor squid statistics
=head1 APPLICABLE SYSTEMS
Any system running squid and avialable cache_object://
=head1 CONFIGURATION
The following environment settings are the default configuration.
[squid]
env.squidhost localhost
env.squidport 3128
env.squiduser [empty]
env.squidpasswd [empty]
env.squidreqtimeout 5
=head1 INTERPRETATION
The plugin shows various statistics, current it:
- efficiency per 5 and 60 min
- traffic
- IP cache
- requests and errors
- storedir max and current size
- memory
- mean object size
- cpu
- median service times per 5 and 60 min
- internal data structures
=head1 MAGIC MARKERS
#%# family=squid
#%# capabilities=autoconf
=head1 VERSION
1.0
=head1 BUGS
=head1 AUTHOR
Gorlow Maxim aka Sheridan <sheridan@sheridan-home.ru> <- jabber and mail
=head1 LICENSE
GPLv2
=cut
use strict;
use warnings;
use IO::Socket;
use MIME::Base64;
use Munin::Plugin;
need_multigraph();
my $squid_host = $ENV{squidhost} || "localhost";
my $squid_port = $ENV{squidport} || 3128;
my $squid_user = $ENV{squiduser} || "";
my $squid_passwd = $ENV{squidpasswd} || "";
my $squid_request_timeout = $ENV{squidreqtimeout} || "5";
sub make_request
{
my $what = $_[0];
my $r_text = <<_;
GET cache_object://%s/%s HTTP/1.0
Accept: */*
%s
_
return sprintf($r_text, $squid_host, $what, &make_auth_header());
}
sub make_auth_header
{
if(defined $squid_passwd && $squid_passwd ne "")
{
my $h_text = <<_;
Authorization: Basic %s
Proxy-Authorization: Basic %s
_
my $auth = MIME::Base64::encode_base64(($squid_user ? $squid_user : "") . ":$squid_passwd", "");
return sprintf($h_text, $auth, $auth);
}
return "";
}
sub squid_requst
{
my $what = $_[0];
die "Could not connect: $!\n" unless my $cachemgr = IO::Socket::INET->new(PeerAddr => $squid_host,
PeerPort => $squid_port,
Proto => 'tcp',
Timeout => $squid_request_timeout);
my $request = &make_request($what);
$cachemgr->syswrite($request, length($request));
return $cachemgr;
}
if($ARGV[0] and $ARGV[0] eq "autoconf")
{
if (squid_requst('menu')->getline ne "") { print "yes\n"; }
exit 0;
}
if($ARGV[0] and $ARGV[0] eq "config")
{
my %config;
# ------------------------------------------------- squid_efficiency_ -----------------------------------------
foreach my $time (qw(5 60))
{
my $name = sprintf("squid_efficiency_%s", $time);
$config{$name}{'graph'}{'title'} = "Cache efficiency in ${time}min";
$config{$name}{'graph'}{'vlabel'} = '%';
$config{$name}{'graph'}{'args'} = '--lower-limit 0 --upper-limit 100';
$config{$name}{'graph'}{'scale'} = 'no';
$config{$name}{'graph'}{'category'} = 'squid';
$config{$name}{'graph'}{'order'} = 'all bytes memory disk';
$config{$name}{'field'}{'all'}{'draw'} = 'AREA';
$config{$name}{'field'}{'all'}{'label'} = 'Hits of all requests';
$config{$name}{'field'}{'bytes'}{'draw'} = 'LINE1';
$config{$name}{'field'}{'bytes'}{'label'} = 'Hits of bytes sent';
$config{$name}{'field'}{'memory'}{'draw'} = 'LINE1';
$config{$name}{'field'}{'memory'}{'label'} = 'Memory hits of hit requests';
$config{$name}{'field'}{'disk'}{'draw'} = 'LINE1';
$config{$name}{'field'}{'disk'}{'label'} = 'Disk hits of hit requests';
foreach my $fld (qw(all bytes memory disk))
{
$config{$name}{'field'}{$fld}{'max'} = 100;
$config{$name}{'field'}{$fld}{'min'} = 0;
}
}
# ------------------------------------------------- squid_traffic -----------------------------------------
$config{'squid_traffic'}{'graph'}{'title'} = 'Traffic statistics';
$config{'squid_traffic'}{'graph'}{'vlabel'} = 'bytes in (-) / out (+) per second';
$config{'squid_traffic'}{'graph'}{'args'} = '--base 1000';
$config{'squid_traffic'}{'graph'}{'category'} = 'squid';
$config{'squid_traffic'}{'graph'}{'order'} = 'client_http_in server_all_in server_http_in server_ftp_in ' .
'server_other_in icp_in icp_q_in icp_r_in cd_in client_http_hit_out ' .
'client_http_out server_all_out server_http_out server_ftp_out ' .
'server_other_out icp_out icp_q_out icp_r_out cd_out';
$config{'squid_traffic'}{'field'}{'client_http_hit_out'}{'type'} = 'COUNTER';
$config{'squid_traffic'}{'field'}{'client_http_hit_out'}{'draw'} = 'AREA';
$config{'squid_traffic'}{'field'}{'client_http_hit_out'}{'cdef'} = 'client_http_hit_out,1024,*';
$config{'squid_traffic'}{'field'}{'client_http_hit_out'}{'label'} = 'Client HTTP hit (out)';
$config{'squid_traffic'}{'field'}{'client_http_out'}{'label'} = 'Client HTTP';
$config{'squid_traffic'}{'field'}{'server_all_out'}{'label'} = 'Server all';
$config{'squid_traffic'}{'field'}{'server_http_out'}{'label'} = 'Server HTTP';
$config{'squid_traffic'}{'field'}{'server_ftp_out'}{'label'} = 'Server FTP';
$config{'squid_traffic'}{'field'}{'server_other_out'}{'label'} = 'Server other';
$config{'squid_traffic'}{'field'}{'icp_out'}{'label'} = 'ICP all';
$config{'squid_traffic'}{'field'}{'icp_q_out'}{'label'} = 'ICP queryes';
$config{'squid_traffic'}{'field'}{'icp_r_out'}{'label'} = 'ICP replies';
$config{'squid_traffic'}{'field'}{'cd_out'}{'label'} = 'Cache digest';
foreach my $fld (qw(client_http server_all server_http server_ftp server_other icp icp_q icp_r cd))
{
my ($namein, $nameout) = (sprintf("%s_in", $fld), sprintf("%s_out", $fld));
$config{'squid_traffic'}{'field'}{$namein}{'type'} = 'COUNTER';
$config{'squid_traffic'}{'field'}{$namein}{'cdef'} = sprintf("%s,1024,*", $namein);
$config{'squid_traffic'}{'field'}{$namein}{'label'} = 'none';
$config{'squid_traffic'}{'field'}{$namein}{'graph'} = 'no';
$config{'squid_traffic'}{'field'}{$nameout}{'type'} = 'COUNTER';
$config{'squid_traffic'}{'field'}{$nameout}{'draw'} = 'LINE1';
$config{'squid_traffic'}{'field'}{$nameout}{'cdef'} = sprintf("%s,1024,*", $nameout);
$config{'squid_traffic'}{'field'}{$nameout}{'negative'} = $namein;
}
# ------------------------------------------------- squid_ipcache -----------------------------------------
$config{'squid_ipcache'}{'graph'}{'title'} = 'IP cache statistics';
$config{'squid_ipcache'}{'graph'}{'vlabel'} = 'Count';
$config{'squid_ipcache'}{'graph'}{'args'} = '--base 1000';# --logarithmic';
$config{'squid_ipcache'}{'graph'}{'category'} = 'squid';
$config{'squid_ipcache'}{'graph'}{'order'} = 'request hits misses numhits neghits invdreqests entries';
$config{'squid_ipcache'}{'field'}{'entries'}{'label'} = 'Entries';
$config{'squid_ipcache'}{'field'}{'request'}{'label'} = 'Requests';
$config{'squid_ipcache'}{'field'}{'hits'}{'label'} = 'Hits';
$config{'squid_ipcache'}{'field'}{'neghits'}{'label'} = 'Negative Hits';
$config{'squid_ipcache'}{'field'}{'numhits'}{'label'} = 'Numeric Hits';
$config{'squid_ipcache'}{'field'}{'misses'}{'label'} = 'Misses';
$config{'squid_ipcache'}{'field'}{'invdreqests'}{'label'} = 'Invalid Request';
$config{'squid_ipcache'}{'field'}{'request'}{'draw'} = 'AREA';
$config{'squid_ipcache'}{'field'}{'misses'}{'draw'} = 'AREA';
$config{'squid_ipcache'}{'field'}{'hits'}{'draw'} = 'AREA';
# ------------------------------------------------- squid_requests -----------------------------------------
$config{'squid_requests'}{'graph'}{'title'} = 'Requests statistics';
$config{'squid_requests'}{'graph'}{'vlabel'} = 'errors (-) / requests (+) per second';
$config{'squid_requests'}{'graph'}{'args'} = '--base 1000';
$config{'squid_requests'}{'graph'}{'category'} = 'squid';
$config{'squid_requests'}{'graph'}{'order'} = 'client_http_errors server_all_errors server_http_errors ' .
'server_ftp_errors server_other_errors ' .
'client_http_hits aborted_requests client_http_requests ' .
'server_all_requests server_http_requests server_ftp_requests server_other_requests';
$config{'squid_requests'}{'field'}{'client_http_hits'}{'label'} = 'Client HTTP hits';
$config{'squid_requests'}{'field'}{'client_http_hits'}{'type'} = 'COUNTER';
$config{'squid_requests'}{'field'}{'client_http_hits'}{'draw'} = 'AREA';
$config{'squid_requests'}{'field'}{'aborted_requests'}{'label'} = 'Aborted requests';
$config{'squid_requests'}{'field'}{'aborted_requests'}{'type'} = 'COUNTER';
$config{'squid_requests'}{'field'}{'aborted_requests'}{'draw'} = 'LINE1';
$config{'squid_requests'}{'field'}{'client_http_requests'}{'label'} = 'Client HTTP';
$config{'squid_requests'}{'field'}{'server_all_requests'}{'label'} = 'Server all';
$config{'squid_requests'}{'field'}{'server_http_requests'}{'label'} = 'Server HTTP';
$config{'squid_requests'}{'field'}{'server_ftp_requests'}{'label'} = 'Server FTP';
$config{'squid_requests'}{'field'}{'server_other_requests'}{'label'} = 'Server other';
foreach my $fld (qw(client_http server_all server_http server_ftp server_other))
{
my ($errf, $reqf) = (sprintf("%s_errors", $fld), sprintf("%s_requests", $fld));
$config{'squid_requests'}{'field'}{$errf}{'type'} = 'COUNTER';
$config{'squid_requests'}{'field'}{$errf}{'label'} = 'none';
$config{'squid_requests'}{'field'}{$errf}{'graph'} = 'no';
$config{'squid_requests'}{'field'}{$reqf}{'type'} = 'COUNTER';
$config{'squid_requests'}{'field'}{$reqf}{'draw'} = 'LINE1';
$config{'squid_requests'}{'field'}{$reqf}{'negative'} = $errf;
}
# ------------------------------------------------- squid_storedir -----------------------------------------
$config{'squid_storedir'}{'graph'}{'title'} = 'Store directory statistics';
$config{'squid_storedir'}{'graph'}{'vlabel'} = 'bytes';
$config{'squid_storedir'}{'graph'}{'args'} = '--base 1000';
$config{'squid_storedir'}{'graph'}{'category'} = 'squid';
$config{'squid_storedir'}{'graph'}{'order'} = 'maximum current';
$config{'squid_storedir'}{'field'}{'maximum'}{'label'} = 'Maximum';
$config{'squid_storedir'}{'field'}{'maximum'}{'draw'} = 'AREA';
$config{'squid_storedir'}{'field'}{'maximum'}{'cdef'} = 'maximum,1024,*';
$config{'squid_storedir'}{'field'}{'current'}{'label'} = 'Current';
$config{'squid_storedir'}{'field'}{'current'}{'draw'} = 'AREA';
$config{'squid_storedir'}{'field'}{'current'}{'cdef'} = 'current,1024,*';
# ------------------------------------------------- squid_memory -----------------------------------------
$config{'squid_memory'}{'graph'}{'title'} = 'Store memory statistics';
$config{'squid_memory'}{'graph'}{'vlabel'} = 'bytes';
$config{'squid_memory'}{'graph'}{'args'} = '--base 1000';
$config{'squid_memory'}{'graph'}{'category'} = 'squid';
$config{'squid_memory'}{'graph'}{'order'} = 'mi_tsia mi_ob mi_sb mi_hb mi_fsb mi_fob mi_tiu mi_tf mi_ts ta ma mu';
$config{'squid_memory'}{'field'}{'mi_tsia'}{'label'} = '[mallinfo()] Total space in arena';
$config{'squid_memory'}{'field'}{'mi_ob'}{'label'} = '[mallinfo()] Ordinary blocks';
$config{'squid_memory'}{'field'}{'mi_sb'}{'label'} = '[mallinfo()] Small blocks';
$config{'squid_memory'}{'field'}{'mi_hb'}{'label'} = '[mallinfo()] Holding blocks';
$config{'squid_memory'}{'field'}{'mi_fsb'}{'label'} = '[mallinfo()] Free small blocks';
$config{'squid_memory'}{'field'}{'mi_fob'}{'label'} = '[mallinfo()] Free ordinary blocks';
$config{'squid_memory'}{'field'}{'mi_tiu'}{'label'} = '[mallinfo()] Total in use';
$config{'squid_memory'}{'field'}{'mi_tf'}{'label'} = '[mallinfo()] Total free';
$config{'squid_memory'}{'field'}{'mi_ts'}{'label'} = '[mallinfo()] Total size';
$config{'squid_memory'}{'field'}{'ta'}{'label'} = 'Total accounted';
$config{'squid_memory'}{'field'}{'ma'}{'label'} = 'memPool accounted';
$config{'squid_memory'}{'field'}{'mu'}{'label'} = 'memPool unaccounted';
foreach my $fld (qw(mi_tsia mi_ob mi_sb mi_hb mi_fsb mi_fob mi_tiu mi_tf mi_ts ta ma mu))
{
$config{'squid_memory'}{'field'}{$fld}{'draw'} = 'LINE1';
$config{'squid_memory'}{'field'}{$fld}{'cdef'} = sprintf("%s,1024,*", $fld);
}
# ------------------------------------------------- squid_meanobject -----------------------------------------
$config{'squid_meanobject'}{'graph'}{'title'} = 'Mean object size';
$config{'squid_meanobject'}{'graph'}{'vlabel'} = 'bytes';
$config{'squid_meanobject'}{'graph'}{'args'} = '--base 1000';
$config{'squid_meanobject'}{'graph'}{'category'} = 'squid';
$config{'squid_meanobject'}{'graph'}{'order'} = 'mos';
$config{'squid_meanobject'}{'field'}{'mos'}{'label'} = 'Mean object size';
$config{'squid_meanobject'}{'field'}{'mos'}{'draw'} = 'LINE1';
$config{'squid_meanobject'}{'field'}{'mos'}{'cdef'} = 'mos,1024,*';
# ------------------------------------------------- squid_cpu -----------------------------------------
$config{'squid_cpu'}{'graph'}{'title'} = 'CPU usage';
$config{'squid_cpu'}{'graph'}{'vlabel'} = '%';
$config{'squid_cpu'}{'graph'}{'args'} = '--base 1000 --lower-limit 0';
$config{'squid_cpu'}{'graph'}{'category'} = 'squid';
$config{'squid_cpu'}{'graph'}{'scale'} = 'no';
$config{'squid_cpu'}{'graph'}{'order'} = 'cur av5 av60';
$config{'squid_cpu'}{'field'}{'cur'}{'label'} = 'Current';
$config{'squid_cpu'}{'field'}{'cur'}{'draw'} = 'LINE1';
$config{'squid_cpu'}{'field'}{'av5'}{'label'} = '5 minute average';
$config{'squid_cpu'}{'field'}{'av5'}{'draw'} = 'LINE1';
$config{'squid_cpu'}{'field'}{'av60'}{'label'} = '60 minute average';
$config{'squid_cpu'}{'field'}{'av60'}{'draw'} = 'LINE1';
foreach my $fld (qw(cur av5 av60))
{
$config{'squid_cpu'}{'field'}{$fld}{'max'} = 100;
$config{'squid_cpu'}{'field'}{$fld}{'min'} = 0;
}
# ------------------------------------------------- squid_ids -----------------------------------------
$config{'squid_ids'}{'graph'}{'title'} = 'Internal data structures';
$config{'squid_ids'}{'graph'}{'vlabel'} = 'Count';
$config{'squid_ids'}{'graph'}{'args'} = '--lower-limit 0';
$config{'squid_ids'}{'graph'}{'category'} = 'squid';
$config{'squid_ids'}{'graph'}{'order'} = 'se sewmo hoci odo';
$config{'squid_ids'}{'field'}{'se'}{'label'} = 'StoreEntries';
$config{'squid_ids'}{'field'}{'se'}{'draw'} = 'LINE1';
$config{'squid_ids'}{'field'}{'sewmo'}{'label'} = 'StoreEntries with MemObjects';
$config{'squid_ids'}{'field'}{'sewmo'}{'draw'} = 'LINE1';
$config{'squid_ids'}{'field'}{'hoci'}{'label'} = 'Hot object cache items';
$config{'squid_ids'}{'field'}{'hoci'}{'draw'} = 'LINE1';
$config{'squid_ids'}{'field'}{'odo'}{'label'} = 'On-disk objects';
$config{'squid_ids'}{'field'}{'odo'}{'draw'} = 'LINE1';
# ------------------------------------------------- squid_mst -----------------------------------------
foreach my $time (qw(5 60))
{
my $name = sprintf("squid_mst_%s", $time);
$config{$name}{'graph'}{'title'} = "Median service times in ${time} minuts";
$config{$name}{'graph'}{'vlabel'} = 'seconds';
$config{$name}{'graph'}{'args'} = '--base 1000';
$config{$name}{'graph'}{'category'} = 'squid';
$config{$name}{'graph'}{'order'} = 'hra cm ch nh nmr dl iq';
$config{$name}{'field'}{'hra'}{'label'} = 'HTTP Requests (All)';
$config{$name}{'field'}{'hra'}{'draw'} = 'LINE1';
$config{$name}{'field'}{'cm'}{'label'} = 'Cache Misses';
$config{$name}{'field'}{'cm'}{'draw'} = 'LINE1';
$config{$name}{'field'}{'ch'}{'label'} = 'Cache Hits';
$config{$name}{'field'}{'ch'}{'draw'} = 'LINE1';
$config{$name}{'field'}{'nh'}{'label'} = 'Near Hits';
$config{$name}{'field'}{'nh'}{'draw'} = 'LINE1';
$config{$name}{'field'}{'nmr'}{'label'} = 'Not-Modified Replies';
$config{$name}{'field'}{'nmr'}{'draw'} = 'LINE1';
$config{$name}{'field'}{'dl'}{'label'} = 'DNS Lookups';
$config{$name}{'field'}{'dl'}{'draw'} = 'LINE1';
$config{$name}{'field'}{'iq'}{'label'} = 'ICP Queries';
$config{$name}{'field'}{'iq'}{'draw'} = 'LINE1';
}
# ------------------------------------------------- out -----------------------------------------
foreach my $graph (sort keys(%config))
{
printf ("multigraph %s\n", $graph);
foreach my $graph_option (sort keys %{$config{$graph}{'graph'}})
{
printf ("graph_%s %s\n", $graph_option, $config{$graph}{'graph'}{$graph_option});
}
foreach my $field_option (qw(label type draw graph cdef negative max min))
{
foreach my $graph_field (sort keys %{$config{$graph}{'field'}})
{
if(exists($config{$graph}{'field'}{$graph_field}{$field_option}))
{
printf("%s.%s %s\n",$graph_field , $field_option, $config{$graph}{'field'}{$graph_field}{$field_option});
}
}
}
print "\n";
}
exit 0;
}
my $cm;
my %data;
# ----------------- squid_efficiency_ and squid_memory --------------------
$cm = squid_requst('info');
while (my $line = $cm->getline)
{
# ----------------- squid_efficiency_ --------------------
if($line =~ /Hits as % of all requests:.*/) { ($data{'squid_efficiency_5'}{'all'}, $data{'squid_efficiency_60'}{'all'}) = $line =~ /([\d.]+)%/g; next; }
if($line =~ /Hits as % of bytes sent:.*/) { ($data{'squid_efficiency_5'}{'bytes'}, $data{'squid_efficiency_60'}{'bytes'}) = $line =~ /([\d.]+)%/g; next; }
if($line =~ /Memory hits as % of hit requests:.*/) { ($data{'squid_efficiency_5'}{'memory'}, $data{'squid_efficiency_60'}{'memory'}) = $line =~ /([\d.]+)%/g; next; }
if($line =~ /Disk hits as % of hit requests:.*/) { ($data{'squid_efficiency_5'}{'disk'}, $data{'squid_efficiency_60'}{'disk'}) = $line =~ /([\d.]+)%/g; next; }
# ----------------- squid_memory --------------------
if($line =~ /Total space in arena:.*/) { $data{'squid_memory'}{'mi_tsia'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /^\s+Ordinary blocks:.*/) { $data{'squid_memory'}{'mi_ob'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /^\s+Small blocks:.*/) { $data{'squid_memory'}{'mi_sb'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /Holding blocks:.*/) { $data{'squid_memory'}{'mi_hb'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /^\s+Free Small blocks:.*/) { $data{'squid_memory'}{'mi_fsb'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /^\s+Free Ordinary blocks:.*/) { $data{'squid_memory'}{'mi_fob'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /Total in use:.*/) { $data{'squid_memory'}{'mi_tiu'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /Total free:.*/) { $data{'squid_memory'}{'mi_tf'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /Total size:.*/) { $data{'squid_memory'}{'mi_ts'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /Total accounted.*/) { $data{'squid_memory'}{'ta'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /memPool accounted.*/) { $data{'squid_memory'}{'ma'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /memPool unaccounted.*/) { $data{'squid_memory'}{'mu'} = ($line =~ /(\d+)/g)[0]; next; }
# ----------------- squid_meanobject --------------------
if($line =~ /Mean Object Size.*/) { $data{'squid_meanobject'}{'mos'} = ($line =~ /([\d\.]+)/g)[0]; next; }
# ----------------- squid_cpu --------------------
if($line =~ /^\s+CPU Usage:.*/) { $data{'squid_cpu'}{'cur'} = ($line =~ /([\d\.]+)%/g)[0]; next; }
if($line =~ /^\s+CPU Usage, 5 minute avg:.*/) { $data{'squid_cpu'}{'av5'} = ($line =~ /([\d\.]+)%/g)[0]; next; }
if($line =~ /^\s+CPU Usage, 60 minute avg:.*/) { $data{'squid_cpu'}{'av60'} = ($line =~ /([\d\.]+)%/g)[0]; next; }
# ----------------- squid_mst --------------------
if($line =~ /^\s+HTTP Requests \(All\):.*/) { ($data{'squid_mst_5'}{'hra'}, $data{'squid_mst_60'}{'hra'}) = $line =~ /([\d.]+)/g; next; }
if($line =~ /^\s+Cache Misses:.*/) { ($data{'squid_mst_5'}{'cm'}, $data{'squid_mst_60'}{'cm'}) = $line =~ /([\d.]+)/g; next; }
if($line =~ /^\s+Cache Hits:.*/) { ($data{'squid_mst_5'}{'ch'}, $data{'squid_mst_60'}{'ch'}) = $line =~ /([\d.]+)/g; next; }
if($line =~ /^\s+Near Hits:.*/) { ($data{'squid_mst_5'}{'nh'}, $data{'squid_mst_60'}{'nh'}) = $line =~ /([\d.]+)/g; next; }
if($line =~ /^\s+Not-Modified Replies:.*/) { ($data{'squid_mst_5'}{'nmr'}, $data{'squid_mst_60'}{'nmr'}) = $line =~ /([\d.]+)/g; next; }
if($line =~ /^\s+DNS Lookups:.*/) { ($data{'squid_mst_5'}{'dl'}, $data{'squid_mst_60'}{'dl'}) = $line =~ /([\d.]+)/g; next; }
if($line =~ /^\s+ICP Queries:.*/) { ($data{'squid_mst_5'}{'iq'}, $data{'squid_mst_60'}{'iq'}) = $line =~ /([\d.]+)/g; next; }
# ----------------- squid_ids --------------------
if($line =~ /^\s+\d+\s+StoreEntries\s+$/) { $data{'squid_ids'}{'se'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /^\s+\d+\s+StoreEntries with MemObjects.*/) { $data{'squid_ids'}{'sewmo'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /^\s+\d+\s+Hot Object Cache Items.*/) { $data{'squid_ids'}{'hoci'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /^\s+\d+\s+on-disk objects.*/) { $data{'squid_ids'}{'odo'} = ($line =~ /(\d+)/g)[0]; next; }
}
# ----------------- squid_ipcache --------------------
$cm = squid_requst('ipcache');
while (my $line = $cm->getline)
{
if($line =~ /IPcache Entries:.*/) { $data{'squid_ipcache'}{'entries'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /IPcache Requests:.*/) { $data{'squid_ipcache'}{'request'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /IPcache Hits:.*/) { $data{'squid_ipcache'}{'hits'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /IPcache Negative Hits:.*/) { $data{'squid_ipcache'}{'neghits'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /IPcache Numeric Hits:.*/) { $data{'squid_ipcache'}{'numhits'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /IPcache Misses:.*/) { $data{'squid_ipcache'}{'misses'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /IPcache Invalid Request:.*/) { $data{'squid_ipcache'}{'invdreqests'} = ($line =~ /(\d+)/g)[0]; next; }
}
# ----------------- squid_traffic and squid_requests --------------------
$cm = squid_requst('counters');
while (my $line = $cm->getline)
{
# squid_traffic
if($line =~ /client_http.hit_kbytes_out =.*/) { $data{'squid_traffic'}{'client_http_hit_out'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /client_http.kbytes_in =.*/) { $data{'squid_traffic'}{'client_http_in'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /client_http.kbytes_out =.*/) { $data{'squid_traffic'}{'client_http_out'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.all.kbytes_in =.*/) { $data{'squid_traffic'}{'server_all_in'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.all.kbytes_out =.*/) { $data{'squid_traffic'}{'server_all_out'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.http.kbytes_in =.*/) { $data{'squid_traffic'}{'server_http_in'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.http.kbytes_out =.*/) { $data{'squid_traffic'}{'server_http_out'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.ftp.kbytes_in =.*/) { $data{'squid_traffic'}{'server_ftp_in'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.ftp.kbytes_out =.*/) { $data{'squid_traffic'}{'server_ftp_out'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.other.kbytes_in =.*/) { $data{'squid_traffic'}{'server_other_in'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.other.kbytes_out =.*/) { $data{'squid_traffic'}{'server_other_out'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /icp.kbytes_sent =.*/) { $data{'squid_traffic'}{'icp_out'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /icp.kbytes_recv =.*/) { $data{'squid_traffic'}{'icp_in'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /icp.q_kbytes_sent =.*/) { $data{'squid_traffic'}{'icp_q_out'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /icp.r_kbytes_sent =.*/) { $data{'squid_traffic'}{'icp_r_out'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /icp.q_kbytes_recv =.*/) { $data{'squid_traffic'}{'icp_q_in'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /icp.r_kbytes_recv =.*/) { $data{'squid_traffic'}{'icp_r_in'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /cd.kbytes_sent =.*/) { $data{'squid_traffic'}{'cd_in'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /cd.kbytes_recv =.*/) { $data{'squid_traffic'}{'cd_out'} = ($line =~ /(\d+)/g)[0]; next; }
# squid_requests
if($line =~ /client_http.requests =.*/) { $data{'squid_requests'}{'client_http_requests'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /client_http.hits =.*/) { $data{'squid_requests'}{'client_http_hits'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /client_http.errors =.*/) { $data{'squid_requests'}{'client_http_errors'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.all.requests =.*/) { $data{'squid_requests'}{'server_all_requests'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.all.errors =.*/) { $data{'squid_requests'}{'server_all_errors'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.http.requests =.*/) { $data{'squid_requests'}{'server_http_requests'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.http.errors =.*/) { $data{'squid_requests'}{'server_http_errors'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.ftp.requests =.*/) { $data{'squid_requests'}{'server_ftp_requests'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.ftp.errors =.*/) { $data{'squid_requests'}{'server_ftp_errors'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.other.requests =.*/) { $data{'squid_requests'}{'server_other_requests'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /server.other.errors =.*/) { $data{'squid_requests'}{'server_other_errors'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /aborted_requests =.*/) { $data{'squid_requests'}{'aborted_requests'} = ($line =~ /(\d+)/g)[0]; next; }
}
# ----------------- squid_storedir --------------------
$cm = squid_requst('storedir');
while (my $line = $cm->getline)
{
if($line =~ /Maximum Swap Size.*:*/) { $data{'squid_storedir'}{'maximum'} = ($line =~ /(\d+)/g)[0]; next; }
if($line =~ /Current Store Swap Size.*:*/) { $data{'squid_storedir'}{'current'} = ($line =~ /(\d+)/g)[0]; next; }
}
# --------------------- print ----------------
foreach my $mgraph (sort keys(%data))
{
printf ("multigraph %s\n", $mgraph);
foreach my $fld (sort keys %{$data{$mgraph}})
{
printf ("%s.value %s\n", $fld, $data{$mgraph}{$fld});
}
print "\n";
}