nagios插件check_squid报错的问题解决方法

http://workaround.org/squid/nagios-plugin/check_squid的脚本用来检测squid很好用,但有时会报错:

Parsing of undecoded UTF-8 will give garbage when decoding entities at /usr/lib/perl5/vendor_perl/5.8.5/LWP/Protocol.pm line 114.

原因是:
HTML::HeadParser模块在使用parse()方法时,对没有编码的UTF-8会弄混,要保证在传值之前进行适当的编码。
参考:http://www.xinjiezuo.com/blog/?p=43

解决方式是加入一行:

$ua->parse_head(0);

跳过去就好了。

下面是改过后的check_squid.

#!/usr/bin/perl -w
#
# check_squid – Nagios check plugin for testing a Squid proxy
#
# Christoph Haas (email@christoph-haas.de)
# License: GPL 2
#
# V0.2
#

use LWP::UserAgent;
use HTTP::Request::Common qw(POST GET);
use HTTP::Headers;
use strict;

my ($url, $urluser, $urlpass, $proxy, $proxyport,
        $proxyuser, $proxypass, $expectstatus) = @ARGV;

unless ($url && $proxy && $expectstatus)
{
        print "Usage: url urluser urlpass proxy proxyport proxyuser proxypass expectstatusn";
                                print " url       -> The URL to check on the internet (http://www.google.com)n";
                                print " urluser   -> Username if the web site required authentication (- = none)n";
                                print " urlpass   -> Password if the web site required authentication (- = none)n";
                                print " proxy     -> Server that squid runs on (proxy.mydomain)n";
                                print " proxyport -> TCP port that Squid listens on (3128)n";
                                print " proxyuser -> Username if the web site required authentication (- = none)n";
                                print " proxypass -> Password if the web site required authentication (- = none)n";
                                print " expectstatus -> HTTP code that should be returnedn";
                                print "                  (2 = anything that begins with 2)n";
        exit -1;
}

$urluser=” if $urluser eq ‘-‘;
$urlpass=” if $urlpass eq ‘-‘;
$proxyuser=” if $proxyuser eq ‘-‘;
$proxypass=” if $proxypass eq ‘-‘;

my $ua = new LWP::UserAgent;
$ua->parse_head(0); //加入这行就好了

my $h = HTTP::Headers->new();

if ($proxy)
{
        $ua->proxy([‘http’, ‘ftp’], "http://$proxy:$proxyport");

        if ($proxyuser)
        {
                $h->proxy_authorization_basic($proxyuser,$proxypass);
        }
}

if ($urluser)
{
        $h->authorization_basic($urluser, $urlpass);
}

my $req = HTTP::Request->new(‘GET’, $url, $h);

my $res = $ua->request($req);

if ($res->status_line =~ /^$expectstatus/)
{
        print "OK – Status: ".$res->status_line."n";
        exit 0;
}
else
{
        print "WARNING – Status: ".$res->status_line." (but expected $expectstatus…)n";
        exit 1;
}

nagios配置文件的关系和理解

Nagios能实现的具体的功能正是通过配置文件来表现的。而这些配置文件之间有着千丝万缕的关系。比如services依赖于host,timeperiod和contactgroup等。       Nagios.cfg这是nagios的主配置文件,它主要负责管理其他所有跟nagios有关的文件。他定义了nagios的日志文件,缓冲文件,状态信息存放文件等。还有其他所有的配置文件等。这些主要的配置文件如下:1.        hosts.cfgdefine host{host_name                                 #这一项是用来定义标识主机的名字。我们用这个名字在host group和service里标识这个主机。一个主机能定义多个服务。使用适当时,宏$HOSTNAME$里存放了这一项的值。alias                                          #这一项用来定义主机的一个完整名字或描述。主要是和使你能理容易的标识一个主机。使用适当时,宏$HOSTALIAS$里存放了这一项的值。address                                    #这一项是用来定义主机的地址。一般而言是主机的IP。当然,你也能够使用一个FQDN来标识你的主机,在没有可访问DNS服务器服务的情况下这种方法会引起问题。使用适当时,宏$ HOSTADDRESS $里存放了这一项的值。max_check_attempts                  #这一项用来定义在检测返回结果不是OK时,nagios重试检测命令的次数。设置这个值为1会导致nagios一次也不重试就报警。check_period                            #这一项用一个time period项的名字来定义在哪段时间内激活对这台主机的主动检测。time period是定义在别的文件里的配置项,我们可以在这里用名字来引用她。contact_groups                          #这是一个联系组列表。我们用联系组的名字来引用她们。多个联系组间用“,”来分隔。notification_interval                     #这一项用来定义当一个服务仍然down或unreachable时,我们间隔多久重发一次通知给联系组。notification_period                      #这一项用一个time period定义来标识什么时间段内给联系组送通知。这里我们用time period定义的名字来引用她。notification_options                   #这一项用来决定发送通知的时机。选项有:d = 当有down状态时发送通知,u = 当有unreachable状态时发送通知, r = 当有服务recoveries时发送通知,f = 当主机启动或停机时发送通知。如果你给一个n选项,那么永远不会发送通知。            }2.        hostgroups.cfgdefine hostgroup{               hostgroup_name                          #主机组名称,通常定义得较短                alias                                          #主机组别名,通常定义得较长               members                                    #主机组成员              }3.        services.cfgdefine service{               host_name                                  #主机名称               service_description                      #服务描述               check_command                         #执行命令       max_check_attempts                   #最大失败尝试次数,值为1时只报警不重新检测                            normal_check_interval                 #常规检测间隔时间,默认为60分钟                                                                             (常规检测是指无论服务状态是否正常,检测次数达到“最大次数”时)                            retry_check_interval                    #失败尝试间隔时间,默认为60分钟                                                                             (失败尝试是指服务状态不正常,检查次数达到“最大次数”时)               check_period                              #检测时间段               notification_interval                     #当服务状态不正常时通知联系人的间隔时间,值为0时不通知联系人notification_period                       #通知联系人时间段               notification_options                     #通知联系人选项,w警告,u未知,c危急,f启动和停止,n不发送通知               contact_groups                           #联系人组              }4.        servicegroups.cfgdefine servicegroup{               servicegroup_name                      #服务组名称,通常定义得较短                       alias                                #服务组别名,通常定义得较长               members                          #服务组成员              }5.        contacts.cfgdefine contact{contact_name                             #这个指令用来定义一个联系人的简称。他会在定义contactgroup时被引用到。在相应的环境中,宏定义$CONTACTNAME$会包含这个值。alias                                           #这个指令是为了定义一个联系人的具体的描述。在相应的环境中,宏定义$CONTACTALIAS$会包含这个值。host_notification_period               #这个指令是为了定义,能够通知Contact中定义的那个简称联系人,关于主机有问题或者恢复正常状态的时间段。你可以把他想象成能够通知Contact关于主机的在线时间。service_notification_period                  #这个指令是为了定义,能够通知Contact中定义的那个简称联系人,关于服务的问题或恢复正常的时间段。host_notification_options                     #这个指令为了定义主机在什么状态下会给联系人发通知。各个参数的描述如下:d=当主机的状态处于down时,发送通知;f=当主机状态处于stop时发送通知。r=当主机恢复up状态时发送通知。n=什么状态下都不发送通知。service_notification_options                 #这个指令为了定义服务在什么状态下会给联系人发通知。各个参数的描述如下:w=当服务处于警告状态时发送通知 u=当服务的状态处于unknown时,发送通知;f=当服务状态处于启动和停止时发送通知。c=当服务处于Critical状态时发送通知。n=什么状态下都不发送通知。host_notification_commands               #这个指令是为了定义一个通知联系人关于主机问题或恢复正常的联系手段的一个列表。多个手段之间用逗号隔开。service_notification_commands    #这个指令是为了定义一个通知联系人关于服务问题或恢复正常的联系手段的一个列表。多个手段之间用逗号隔开。email                                                 #这个指令是为了定义联系人的email地址。这个将取决于你是如何定义你的notification commands.它可以用来给联系人发送紧急邮件。在相应的环境中。宏定义$CONTACTEMAIL$将会包含它的值。}6.        contactgroups.cfgdefine contactgroup{               contactgroup_name                            #联系组名称,通常定义得较短               alias                                #联系组别名,通常定义得较长               members                          #联系组成员              } 7.        timeperiods.cfgdefine timeperiod{               timeperiod_name                         #时间段名称,通常定义得较短               alias                                           #时间段别名,通常定义得较长               sunday                                       #星期日时间段               monday                                      #星期一时间段               tuesday                                      #星期二时间段               wednesday                                 #星期三时间段               thursday                                     #星期四时间段               friday                                         #星期五时间段               saturday                                     #星期六时间段            }8.        commands.cfg        define command{           command_name       #定义命令的简称           command_line       #定义当服务进行时Nagios要执行的动作。在命令执行以前,所有合法的宏都要被他们的值代替。           }