Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/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 AUTHORS
- Copyright (C) 2013 Diego Elio Pettenò
- Copyright (C) 2004 Jimmy Olsen, Audun Ytterdal, Tore Anderson
- Copyright (C) 2008 Bjorn Ruberg
- =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 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 $q = 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 ( $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 ( $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 ( $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 ( $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;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement