- Repository
- Munin (master)
- Last change
- 2018-08-07
- Graph Categories
- Family
- auto
- Capabilities
- Language
- Perl
- License
- GPL-2.0-only
- Authors
squid
Name
squid - Multigraph-capable plugin to monitor Squid
Notes
This plugin will produce multiple graphs showing:
- the number of requests (replaces squid_requests);
- the traffic (replaces squid_traffic);
- the size of the cache (replaces squid_cache);
- the traffic to the ICP peers (replaces squid_icp);
- the mean size of stored objects (replaces squid_objectsize).
Configuration
The following configuration parameters are used by this plugin
[squid]
env.host - hostname to connect to
env.port - port number to connect to
env.username - username used for authentication
env.password - password used for authentication
Default Configuration
[squid]
env.host 127.0.0.1
env.port 3128
Wildcard Configuration
It’s possible to use the plugin in a virtual-node capacity, in which case the host configuration will default to the hostname following the underscore:
[squid_someserver]
env.host someserver
env.port 3128
Author
Copyright (C) 2013 Diego Elio Pettenò
Copyright (C) 2008 Bjorn Ruberg
Copyright (C) 2004 Audun Ytterdal
Copyright (C) 2004 Jimmy Olsen
Copyright (C) 2004 Tore Anderson
License
Gnu GPLv2
Magic Markers
#%# family=auto
#%# capabilities=autoconf
#!/usr/bin/perl -w
=head1 NAME
squid - Multigraph-capable plugin to monitor Squid
=head1 NOTES
This plugin will produce multiple graphs showing:
- the number of requests (replaces squid_requests);
- the traffic (replaces squid_traffic);
- the size of the cache (replaces squid_cache);
- the traffic to the ICP peers (replaces squid_icp);
- the mean size of stored objects (replaces squid_objectsize).
=head1 CONFIGURATION
The following configuration parameters are used by this plugin
[squid]
env.host - hostname to connect to
env.port - port number to connect to
env.username - username used for authentication
env.password - password used for authentication
=head2 DEFAULT CONFIGURATION
[squid]
env.host 127.0.0.1
env.port 3128
=head2 WILDCARD CONFIGURATION
It's possible to use the plugin in a virtual-node capacity, in which
case the host configuration will default to the hostname following the
underscore:
[squid_someserver]
env.host someserver
env.port 3128
=head1 AUTHOR
Copyright (C) 2013 Diego Elio Pettenò
Copyright (C) 2008 Bjorn Ruberg
Copyright (C) 2004 Audun Ytterdal
Copyright (C) 2004 Jimmy Olsen
Copyright (C) 2004 Tore Anderson
=head1 LICENSE
Gnu GPLv2
=begin comment
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
=end comment
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=cut
use strict;
use Munin::Plugin;
use Munin::Plugin::Framework;
use IO::Socket::INET;
my $plugin = Munin::Plugin::Framework->new;
$plugin->{hostname} = $1 if $Munin::Plugin::me =~ /_([^_]+)$/;
my $peeraddr = $ENV{'host'} || $plugin->{hostname} || '127.0.0.1';
my $peerport = $ENV{'port'} || '3128';
my $username = $ENV{'username'};
my $password = $ENV{'password'};
my $requirements = undef;
if (! eval "require HTTP::Headers" or ! eval "require HTTP::Response" ) {
$requirements = "HTTP::Message not found";
}
sub getobject {
my $socket = IO::Socket::INET->new(PeerAddr => $peeraddr,
PeerPort => $peerport,
Proto => 'tcp',
Timeout => 25);
if ( ! $socket ) {
$requirements = $!;
return undef;
}
my ($object) = @_;
my $request_line = sprintf("GET cache_object://%s/%s HTTP/1.0\r\n",
$peeraddr, $object);
my $headers = HTTP::Headers->new('Accept' => '*/*',
'User-Agent' => sprintf("munin/%s (squid)",
$Munin::Common::Defaults::MUNIN_VERSION)
);
if ( $username and $password ) {
$headers->authorization_basic($username, $password);
$headers->proxy_authorization_basic($username, $password);
}
$socket->print($request_line . $headers->as_string("\r\n") . "\r\n");
my $response = HTTP::Response->parse(join('', $socket->getlines));
$socket->close();
return $response;
}
sub get_icp {
my $server_list = getobject('server_list');
if ( not defined $server_list ) {
return undef;
}
if ( $server_list->{content} =~ /There are no neighbors/ ) {
return undef;
}
my @lines = split(/\r\n/, $server_list->{content});
my $ret;
my $id = "";
for (my $i = 0; $i <= $#lines; $i++) {
chomp $lines[$i];
if ($lines[$i] =~ /Address[^:]+:\s*([\d\.]+)\s*$/) {
my $host = $1;
$id = "h" . $host;
$id =~ s/\.//g;
my $h;
if ($h = Net::hostent::gethost ($host)) {
$ret->{$id}->{host} = lc $h->name;
} else {
$ret->{$id}->{host} = $host;
}
} elsif ($lines[$i] =~ /FETCHES\s*:\s*(\d+)/) {
$ret->{$id}->{fetches} = $1;
}
}
}
my $counters = getobject('counters');
my $storedir = getobject('storedir');
my $info = getobject('info');
my $icp_data = get_icp;
if ( $requirements ) {
$plugin->{autoconf} = "no ($requirements)";
} elsif ( !$counters->is_success ) {
$plugin->{autoconf} = "no ($counters->status_line)";
$plugin->{autoconf} =~ s/[\r\n]//g;
}
if ( defined $counters && $counters->{is_success} ) {
my $hits =
($counters->content =~ /client_http\.hits = ([0-9]+)/) ? $1 : "U";
my $errors =
($counters->content =~ /client_http\.errors = ([0-9]+)/) ? $1 : "U";
my $requests =
($counters->content =~ /client_http\.requests = ([0-9]+)/) ? $1 : undef;
my $misses = $requests ? ($requests - $errors - $hits) : "U";
my $in =
($counters->content =~ /client_http\.kbytes_in = ([0-9]+)/) ? ($1 * 1024) : "U";
my $out =
($counters->content =~ /client_http\.kbytes_out = ([0-9]+)/) ? ($1 * 1024) : "U";
my $hits_out =
($counters->content =~ /client_http\.hit_kbytes_out = ([0-9]+)/) ? ($1 * 1024) : "U";
$plugin->add_graphs
(
squid_requests =>
{
title => "Squid client requests",
args => "--base 1000 -l 0",
vlabel => "requests per \${graph_period}",
order => "hits errors misses",
total => "total",
category => "network",
fields =>
{
hits =>
{
type => "DERIVE",
draw => "AREASTACK",
min => 0,
value => $hits,
},
errors =>
{
type => "DERIVE",
draw => "AREASTACK",
min => 0,
value => $errors,
},
misses =>
{
type => "DERIVE",
draw => "AREASTACK",
min => 0,
value => $misses,
},
},
},
"squid_traffic" =>
{
title => "Squid Traffic",
args => "--base 1024 -l 0",
vlabel => "bytes per \${graph_period}",
order => "in out hits_out",
fields =>
{
in =>
{
label => "received",
type => "DERIVE",
min => "0",
value => $in,
},
out =>
{
label => "sent",
type => "DERIVE",
min => "0",
value => $out,
},
hits_out =>
{
label => "sent from cache",
type => "DERIVE",
min => "0",
value => $hits_out,
},
},
},
);
}
if ( defined $storedir && $storedir->is_success ) {
my $max =
($storedir->content =~ /Maximum (?:Swap )?Size\s*:\s*([0-9]+) KB/) ? ($1 * 1024) : "U";
my $current =
($storedir->content =~ /Current (?:Store Swap )?Size\s*:\s*([0-9]+) KB/) ? ($1 * 1024) : "U";
$plugin->add_graphs
(
"squid_swap" =>
{
title => "Squid swap size",
order => "max current",
vlabel => "bytes",
args => "--base 1024 -l 0",
fields =>
{
max => { label => "Maximum Swap Size", value => $max },
current => { label => "Current Store Swap Size", value => $current }
}
},
);
}
if ( defined $info && $info->is_success ) {
my $size = 'U';
if ( $info->content =~ /Mean Object Size:\s*([0-9.]+) ([KMG])B/i ) {
$size = $1;
my $unit = $2;
if ( $unit eq 'K' ) {
$size *= 1024;
} elsif ( $unit eq 'M' ) {
$size *= (1024*1024);
} elsif ( $unit eq 'G' ) {
$size *= (1024*1024*1024);
}
}
$plugin->add_graphs
(
"squid_objectsize" =>
{
title => "Squid object size",
vlabel => "bytes",
args => "--base 1024 -l 0",
fields =>
{
size => { label => "Mean Object Size", value => $size }
},
}
);
}
if ( $icp_data ) {
$plugin->add_graphs
(
"squid_icp" =>
{
title => "Squid Relay Statistics",
vlabel => "requests per \${graph_period}",
args => "--base 1000 -l 0",
total => "total",
fields => {},
},
);
foreach my $i (sort keys %{$icp_data}) {
$plugin->{graphs}->{"squid_icp"}->{fields}->{$i} =
{
label => $icp_data->{$i}->{host},
type => "DERIVE",
min => 0,
draw => "AREASTACK",
value => $icp_data->{$i}->{fetches}
};
}
}
$plugin->run;