Advertisement
Guest User

Untitled

a guest
Sep 12th, 2016
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 8.00 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2.  
  3. =head1 NAME
  4.  
  5. squid - Multigraph-capable plugin to monitor Squid
  6.  
  7. =head1 NOTES
  8.  
  9. This plugin will produce multiple graphs showing:
  10.  
  11.  - the number of requests (replaces squid_requests);
  12.  - the traffic (replaces squid_traffic);
  13.  - the size of the cache (replaces squid_cache);
  14.  - the traffic to the ICP peers (replaces squid_icp);
  15.  - the mean size of stored objects (replaces squid_objectsize).
  16.  
  17. =head1 CONFIGURATION
  18.  
  19. The following configuration parameters are used by this plugin
  20.  
  21.  [squid]
  22.   env.host     - hostname to connect to
  23.   env.port     - port number to connect to
  24.   env.username - username used for authentication
  25.   env.password - password used for authentication
  26.  
  27.  
  28. =head2 DEFAULT CONFIGURATION
  29.  
  30.  [squid]
  31.   env.host 127.0.0.1
  32.   env.port 3128
  33.  
  34. =head2 WILDCARD CONFIGURATION
  35.  
  36. It's possible to use the plugin in a virtual-node capacity, in which
  37. case the host configuration will default to the hostname following the
  38. underscore:
  39.  
  40.  [squid_someserver]
  41.   env.host someserver
  42.   env.port 3128
  43.  
  44. =head1 AUTHORS
  45.  
  46. Copyright (C) 2013 Diego Elio Pettenò
  47. Copyright (C) 2004 Jimmy Olsen, Audun Ytterdal, Tore Anderson
  48. Copyright (C) 2008 Bjorn Ruberg
  49.  
  50. =head1 LICENSE
  51.  
  52. Gnu GPLv2
  53.  
  54. =begin comment
  55.  
  56. This program is free software; you can redistribute it and/or modify
  57. it under the terms of the GNU General Public License as published by
  58. the Free Software Foundation; version 2 dated June, 1991.
  59.  
  60. This program is distributed in the hope that it will be useful, but
  61. WITHOUT ANY WARRANTY; without even the implied warranty of
  62. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  63. General Public License for more details.
  64.  
  65. You should have received a copy of the GNU General Public License
  66. along with this program; if not, write to the Free Software
  67. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  68. 02110-1301 USA.
  69.  
  70. =end comment
  71.  
  72. =head1 MAGIC MARKERS
  73.  
  74.  #%# family=auto
  75.  #%# capabilities=autoconf
  76.  
  77. =cut
  78.  
  79. use strict;
  80. use Munin::Plugin;
  81. use IO::Socket::INET;
  82.  
  83.  
  84. my $plugin = Munin::Plugin::Framework->new;
  85.  
  86. $plugin->hostname = $1 if $Munin::Plugin::me =~ /_([^_]+)$/;
  87.  
  88. my $peeraddr = $ENV{'host'} || $plugin->hostname || '127.0.0.1';
  89. my $peerport = $ENV{'port'} || '3128';
  90.  
  91. my $username = $ENV{'username'};
  92. my $password = $ENV{'password'};
  93.  
  94. my $requirements = undef;
  95. if (! eval "require HTTP::Headers" or ! eval "require HTTP::Response" ) {
  96.   $requirements = "HTTP::Message not found";
  97. }
  98.  
  99. sub getobject {
  100.   my $socket = IO::Socket::INET->new(PeerAddr => $peeraddr,
  101.                      PeerPort => $peerport,
  102.                      Proto => 'tcp',
  103.                      Timeout => 25);
  104.   if ( ! $socket ) {
  105.     $requirements = $!;
  106.     return undef;
  107.   }
  108.  
  109.   my ($object) = @_;
  110.  
  111.   my $q = sprintf("GET cache_object://%s/%s HTTP/1.0\r\n",
  112.                  $peeraddr, $object);
  113.   my $headers = HTTP::Headers->new('Accept' => '*/*',
  114.                    'User-Agent' => sprintf("munin/%s (squid)",
  115.                                $Munin::Common::Defaults::MUNIN_VERSION)
  116.                   );
  117.   if ( $username and $password ) {
  118.     $headers->authorization_basic($username, $password);
  119.     $headers->proxy_authorization_basic($username, $password);
  120.   }
  121.  
  122.   $socket->print($request_line . $headers->as_string("\r\n") . "\r\n");
  123.   my $response = HTTP::Response->parse(join('', $socket->getlines));
  124.  
  125.   $socket->close();
  126.  
  127.   return $response;
  128. }
  129.  
  130. sub get_icp {
  131.   my $server_list = getobject('server_list');
  132.   if ( $server_list->content =~ /There are no neighbors/ ) {
  133.     return undef;
  134.   }
  135.  
  136.   my @lines = split(/\r\n/, $server_list->content);
  137.  
  138.   my $ret;
  139.   my $id = "";
  140.   for (my $i = 0; $i <= $#lines; $i++) {
  141.     chomp $lines[$i];
  142.     if ($lines[$i] =~ /Address[^:]+:\s*([\d\.]+)\s*$/) {
  143.       my $host = $1;
  144.       $id = "h" . $host;
  145.       $id =~ s/\.//g;
  146.  
  147.       my $h;
  148.       if ($h = Net::hostent::gethost ($host)) {
  149.     $ret->{$id}->{host} = lc $h->name;
  150.       } else {
  151.     $ret->{$id}->{host} = $host;
  152.       }
  153.     } elsif ($lines[$i] =~ /FETCHES\s*:\s*(\d+)/) {
  154.       $ret->{$id}->{fetches} = $1;
  155.     }
  156.   }
  157. }
  158.  
  159. my $counters = getobject('counters');
  160. my $storedir = getobject('storedir');
  161. my $info     = getobject('info');
  162. my $icp_data = get_icp;
  163.  
  164. if ( $requirements ) {
  165.   $plugin->autoconf = "no ($requirements)";
  166. } elsif ( !$counters->is_success ) {
  167.   $plugin->autoconf = "no ($counters->status_line)";
  168.   $plugin->autoconf =~ s/[\r\n]//g;
  169. }
  170.  
  171. if ( $counters->is_success ) {
  172.   my $hits =
  173.     ($counters->content =~ /client_http\.hits = ([0-9]+)/) ? $1 : "U";
  174.   my $errors =
  175.     ($counters->content =~ /client_http\.errors = ([0-9]+)/) ? $1 : "U";
  176.   my $requests =
  177.     ($counters->content =~ /client_http\.requests = ([0-9]+)/) ? $1 : undef;
  178.   my $misses = $requests ? ($requests - $errors - $hits) : "U";
  179.  
  180.   my $in =
  181.     ($counters->content =~ /client_http\.kbytes_in = ([0-9]+)/) ? ($1 * 1024) : "U";
  182.   my $out =
  183.     ($counters->content =~ /client_http\.kbytes_out = ([0-9]+)/) ? ($1 * 1024) : "U";
  184.   my $hits_out =
  185.     ($counters->content =~ /client_http\.hit_kbytes_out = ([0-9]+)/) ? ($1 * 1024) : "U";
  186.  
  187.   $plugin->add_graphs
  188.     (
  189.      squid_requests =>
  190.      {
  191.       title => "Squid client requests",
  192.       args => "--base 1000 -l 0",
  193.       vlabel => "requests per \${graph_period}",
  194.       order => "hits errors misses",
  195.       total => "total",
  196.       category => "network",
  197.       fields =>
  198.       {
  199.        hits =>
  200.        {
  201.     type => "DERIVE",
  202.     draw => "AREASTACK",
  203.     min => 0,
  204.     value => $hits,
  205.        },
  206.        errors =>
  207.        {
  208.     type => "DERIVE",
  209.     draw => "AREASTACK",
  210.     min => 0,
  211.     value => $errors,
  212.        },
  213.        misses =>
  214.        {
  215.     type => "DERIVE",
  216.     draw => "AREASTACK",
  217.     min => 0,
  218.     value => $misses,
  219.        },
  220.       },
  221.      },
  222.      "squid_traffic" =>
  223.      {
  224.       title => "Squid Traffic",
  225.       args => "--base 1024 -l 0",
  226.       vlabel => "bytes per \${graph_period}",
  227.       order => "in out hits_out",
  228.       fields =>
  229.       {
  230.        in =>
  231.        {
  232.     label => "received",
  233.     type => "DERIVE",
  234.     min => "0",
  235.     value => $in,
  236.        },
  237.        out =>
  238.        {
  239.     label => "sent",
  240.     type => "DERIVE",
  241.     min => "0",
  242.     value => $out,
  243.        },
  244.        hits_out =>
  245.        {
  246.     label => "sent from cache",
  247.     type => "DERIVE",
  248.     min => "0",
  249.     value => $hits_out,
  250.        },
  251.       },
  252.      },
  253.     );
  254. }
  255.  
  256. if ( $storedir->is_success ) {
  257.   my $max =
  258.     ($storedir->content =~ /Maximum (?:Swap )?Size\s*:\s*([0-9]+) KB/) ? ($1 * 1024) : "U";
  259.   my $current =
  260.     ($storedir->content =~ /Current (?:Store Swap )?Size\s*:\s*([0-9]+) KB/) ? ($1 * 1024) : "U";
  261.  
  262.   $plugin->add_graphs
  263.     (
  264.      "squid_swap" =>
  265.      {
  266.       title => "Squid swap size",
  267.       order => "max current",
  268.       vlabel => "bytes",
  269.       args => "--base 1024 -l 0",
  270.       fields =>
  271.       {
  272.        max => { label => "Maximum Swap Size", value => $max },
  273.        current => { label => "Current Store Swap Size", value => $current }
  274.       }
  275.      },
  276.     );
  277. }
  278.  
  279. if ( $info->is_success ) {
  280.   my $size = 'U';
  281.   if ( $info->content =~ /Mean Object Size:\s*([0-9.]+) ([KMG])B/i ) {
  282.     $size = $1;
  283.     my $unit = $2;
  284.     if ( $unit eq 'K' ) {
  285.       $size *= 1024;
  286.     } elsif ( $unit eq 'M' ) {
  287.       $size *= (1024*1024);
  288.     } elsif ( $unit eq 'G' ) {
  289.       $size *= (1024*1024*1024);
  290.     }
  291.   }
  292.  
  293.   $plugin->add_graphs
  294.     (
  295.      "squid_objectsize" =>
  296.      {
  297.       title => "Squid object size",
  298.       vlabel => "bytes",
  299.       args => "--base 1024 -l 0",
  300.       fields =>
  301.       {
  302.        size => { label => "Mean Object Size", value => $size }
  303.       },
  304.      }
  305.     );
  306. }
  307.  
  308. if ( $icp_data ) {
  309.   $plugin->add_graphs
  310.     (
  311.      "squid_icp" =>
  312.      {
  313.       title => "Squid Relay Statistics",
  314.       vlabel => "requests per \${graph_period}",
  315.       args => "--base 1000 -l 0",
  316.       total => "total",
  317.       fields => {},
  318.      },
  319.     );
  320.  
  321.   foreach my $i (sort keys %{$icp_data}) {
  322.     $plugin->{graphs}->{"squid_icp"}->{fields}->{$i} =
  323.       {
  324.        label => $icp_data->{$i}->{host},
  325.        type => "DERIVE",
  326.        min => 0,
  327.        draw => "AREASTACK",
  328.        value => $icp_data->{$i}->{fetches}
  329.       };
  330.   }
  331. }
  332.  
  333. $plugin->run;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement