今日写一篇关于nagios的教程吧。(本文乃初级原理教程,适合新手阅读。)
 
    早些年刚刚接触nagios的时候看过好多书籍,印象中,这些书籍内容都很多,讲解十分详细。很多时候、书籍作者干脆会把某项配置所支持的参数全都列出来,可是这样对于新手来说,可能就不知所云了,几乎就是扫一眼就翻过去了,等花了好长时间终于把一本书看完了,也就全忘的差不多了,也不知道都看了些什么,和没看过一样。这种讲解十分详细的书适合那些已掌握基础的人员去阅读、以进一步提高,但是对于刚入门的读者来说,这简直就像天方夜谭一样。
 
    所以本文将用最通俗的语言为您讲解nagios的基本监控原理。
 
    即、nagios是怎样进行监控的?nagios如何知道系统或服务挂掉了?以及挂掉时怎样发送报警信息?
 
 
    参考书籍:
      1. 《nagios网络监控中文版》(supermeng 2008年 版)
      2. 《nagios3完整配置文档》第一版 整理:守住每一天: Blog:liuyu.blog.51cto.com  
      
    感谢前辈们的辛勤付出。
 
   “如果我能看得更远,那是因为我站在巨人的肩膀上”  -----  牛顿。
 
    本文版权遵从于GNU版权第二版,禁止商业用途,转载请注明出处。
 
    
 
 
    安装过程:略。(以下所有内容都假设nagios已安装在/usr/local/nagios目录中)
 
 
##################################################################################
# 正文开始:
 
 
 
    首先,我们知道,nagios只是一个框架,其本身并“没有”真正的监控功能,实现监控的都是nagios的插件,而插件可以使用任何语言编写,这就使得nagios的扩展性极强。只要搭建好nagios环境,用任何合适的语言都可以写出适用的监控程序。
 
 
    Nagios对于其使用的插件仅有两点要求:
 
           第一、程序至少有一行输出(最好别多于1行),这一行输出将会显示在nagios的页面上。
 
例如下图:
 
监控利器Nagios原理教程(即、Nagios怎样报警?)_nagios
 
           监控使用的插件程序输出什么内容,这里就会显示什么。
           当发送报警信息(如:短信或邮件)时,发送的正文内容也会是插件程序输出的内容。
 
           如果程序没有输出,即便收到短信等,也不知什么东西挂了。
           所以输出“对服务的描述”是很有必要的。
           况且、如果程序没有输出,nrpe会报如下错误:
                    NRPE: Unable to read output
           所以一定要有输出。
 
           程序的第一行输出将会被保存在$SERVICEOUTPUT$这个宏中
           如果输出多于一行,多余的输出将被保存在$LONGSERVICEOUTPUT$这个宏中。
           建议输出不要太多,简单的能描述问题即可。毕竟没人愿意阅读像作文似的报警信息。
 
 
 
           第二,nagios要求插件程序必须有返回值,且只能是0,1,2,3中的一个。
             其中: 0表示 正常。 返回值为0的监控项会在其页面上显示一个绿色的OK。
                    1表示 警告。 返回值为1的监控项会在其页面上显示一个黄(浅黄)色的warning。 
                    2表示 紧急。 返回值为2的监控项会在其页面上显示一个红色的critical。 
                    3表示 未知。 返回值为3的监控项会在其页面上显示一个棕?(深黄?)色的unknown。 
 
 
监控利器Nagios原理教程(即、Nagios怎样报警?)_iOS_02监控利器Nagios原理教程(即、Nagios怎样报警?)_iOS_03(天呐,unknown那个是什么颜色?棕还是深黄?我眼睛肿么了?)
 
 
 
只要你的插件程序符合这两点要求,那么报警的事情就交给nagios来处理吧。
 
那么,nagios会在何时发送报警信息呢?答案很简单:当你的插件程序返回值发生变化时。
 
 
例如:
     返回值从0变成1,表示从OK状态变成WARNING状态,此时nagios是一定会自动通知你的,你只要喝着茶等短信或邮件就行了。
    
     返回值从2变成0,表示从紧急CRITICAL状态变成OK状态,也就是故障恢复了,此时nagios也会通知你一下的,怎么样?很人性化吧。
 
     如果某监控项的状态一直是非0状态(warning,critical,unknown中的一个),那么nagios会每隔20分钟向你发送一条报警信息,当然,这个间隔的时间你也是可以自己设定的,默认是20分钟。
 
     如果监控状态一直是OK,那么什么信息也不会发送,nagios不会去打扰你的。
 
     下面,我们就开始编写第一个监控插件吧,编写插件的语言任意,但绝大多数都是用shell,这里就用BASH为大家演示一个最简单的监控插件。
 
 
     设定需求为:
        假设/opt/myproject/status这个文件会保存某程序的运行状态
        当文件的内容为computing时表示程序正在进行计算,此状态可以认为是正常的。
        当文件的内容为blocked时表示程序由于某些原因被挂起了,但是进程还在,此时发个警告即可。
        当文件的内容为killed时表示该程序由于某些原因被kill了,进程已不在,此为严重故障。
 
监控脚本为:

#!/bin/bash

logdir=/opt/myproject

logfile=$logdir/status

 

status_ok=0

status_warn=1

status_critical=2

status_unknown=3

 

[ -f $logfile ] || {

echo "logfile:$logfile not exist or type error!"

exit $status_unknown

}

 

content=$(cat $logfile)

 

if [ x"$content" = x"computing" ];then

echo "OK,process is computing"

exit $status_ok

elif [ x"$content" = x"blocked" ]then

echo "Warn.process is blocked"

exit $status_warn

elif [ x"$content" = x"killed" ];then

echo "Critical.process is killed"

exit $status_critical

else

echo "Unknown error.Can not read from logfile:$logfile"

exit $status_unknown

fi

OK ,脚本编辑结束,将此脚本保存为/tmp/check_process_status.sh,再加上可执行权限后即可执行之进行监控了。
 
那么,nagios是如何使用它进行监控呢。首先来看下监控项的配置语法吧。

define service {

use remote-service

host_name myhost.mydomain.com

service_description process_status

check_command check_process_status

}

1.每一个监控项,都需要为之定义一个“服务”,如代码第一行:define service
2.第二行中的“use remote-service”的含义是:该监控项使用“remote-service”这个默认的模板。
          模板的内容将在下一篇博文中讲解(高级内容)
3.第三行:host_name定义了该监控项是属于哪台机器的,也可以说成是你要为哪台机器添加此监控。
 这里我设置的是为“myhost.mydomain.com”这台机器添加这项监控。
4.第四行:这项监控项的描述。这里设置的值将会显示在nagios页面的"Service"字段。如下图:
 
监控利器Nagios原理教程(即、Nagios怎样报警?)_iOS_04
 
图中的监控项,配置文件中的内容是:service_description Zombie Processes
所以这里的Service字段显示的就是“Zombie Processes”,也就是说:Service_description后面写什么,nagios页面的Service字段就会显示什么。
5.第五行:check_command 定义该监控项使用哪个“nagios命令”来进行监控,此“nagios命令”的名字随便起,叫什么都行,叫abcd也行,叫xyz也行,但是通常都会使用一个“见名知意”的命令名,这里我设置的命令名字是“check_process_status",nagios在运行时就会调用名字为“check_process_status"的命令。
 
但是这个命令是什么含义呢?nagios并不知道,所以需要我们来对这个命令进行定义,定义命令的格式如下:
define command {
command_name check_process_status
command_line /tmp/check_process_status.sh
}
 
1.第一行:define command就表示我现在要定义一个命令
2.第二行:command_name定义了这个命令的名字,只有在这里定义过的命令,才可以在nagios中使用。
  本例中,我们使用了一个名为“check_process_status”的命令,但是这个命令事先并不存在,所以现在我们来定义他,之后就可以使用了。
3.第三行:command_line定义了这个nagios命令对应的“系统命令”,该“系统命令”可以是二进制可执行程序,也可以是任何可执行的脚本。所以,嗯嗯,我们刚刚编写的脚本当然也就可以使用了,so,把脚本的全路径写进去吧。
 
这样,一个nagios的命令就定义完了,这4行代码将会告诉nagiso主程序,你可以使用一个名字为“check_process_status”的命令,使用这个命令,就相当于使用如下系统命令:/tmp/check_process_status.sh
 
这样,一个监控项就添加完了。而这个监控项使用的监控程序、就是我们自己编写的shell脚本。是不是很方便呢?
 
 
 
 
 
监控已经添加完了,那么,当服务故障时,nagios又是怎样进行报警的呢?
 
我看过很多书籍和文档都是从低往高那么讲,这样读起来仍然会迷糊,所以本人将反过来说,这样思路就会更清晰。
 
 
如果某监控项挂掉了,nagios主程序会自动发送报警信息给:默认的联系人组,既然是个组,里面一定有多个联系人,但也可以是1个,>=1。所以我们首先要定义这个联系人组都包含哪些联系人,语法如下:
 

点击(此处)折叠或打开

  1. define contactgroup {
  2. contactgroup_name admin
  3. members zhangsan,lisi
  4. }
这里定义了一个名为“admin”的联系人组,这个组包含“zhangsan”和“lisi”这两个联系人。
nagios默认使用的联系人组就是admin组,所以我们为admin组添加zhangsan和lisi这两个人以后,
nagios主程序就会自动发送报警信息给这两个人了。
 
但是怎样发信息给某个人呢,那么就需要设置这个人的联系方式,定义单个联系人的语法为:
 

点击(此处)折叠或打开

  1. define contact{
  2. contact_name zhangsan # 联系人名字为:zhangsan
  3. use generic-contact # 该联系人使用generic-contact这个联系人模板
  4. service_notification_commands notify-to-zhangsan
  5. # 当服务挂掉时,使用“notify-to-zhangsan"这个命令向zhangsan发送报警信息
  6. host_notification_commands notify-to-zhangsan
  7. # 当主机挂掉时,使用“notify-to-zhangsan"这个命令向zhangsan发送报警信息
  8. }
 
OK,联系人也定义完了,当nagiso要向zhangsan发送报警信息时,就会调用“notify-to-zhangsan”这个nagios命令来进行报警了。
 
那么这个命令是什么呢?原理和上面讲过的check_process_status命令相同,只要为这个命令指定要使用的系统命令的全路径就行了。比如想用邮件报警,那么可按如下方式来定义:
 
 

点击(此处)折叠或打开

  1. define command {
  2. command_name notify-to-zhangsan
  3. command_line echo " ** $NOTIFICATIONTYPE$ Service Alert: $HOSTNAME$/$HOSTADDRESS$ $SERVICEDESC$ is $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$ Additional Info:$SERVICEOUTPUT$ "| formail -I "Subject: $HOSTADDRESS$*$SERVICEOU
  4. TPUT$*$LONGDATETIME$"| sendmail -oi $CONTACTEMAIL$
  5. }
 
command_line中很长,但是仔细看,我们设置的是echo一大段字符,之后通过管道传递给sendmail命令来进行发送,而echo的那一大串字符,就是nagios的内置宏了,如:
$NOTIFICATIONTYPE$表示通知的类型,他是“Problem”和“Recovery”中的一个。
$HOSTNAME$是该监控项所属主机,即定义服务时、写在host_name后面的字符串
$SERVICEOUTPUT$是插件的第一行输出,也就是你脚本echo或print的内容了。你输出什么,这个变量就是什么值。
等等等等,不一一列举。
 
这样就完成了报警。
 
 
 
 
最后再从头描述一遍报警过程和添加监控项的过程吧。
 
 
报警过程:
 
当nagios主程序发现插件的返回值为非0时,将会发送报警信息给默认联系人组,联系人组包含了至少1个联系人,nagios会发送给所有的联系人。每个联系人都可以单独设置发送报警使用的命令。而这个命令,使用define command来定义的,可以定义成任何系统命令(包括脚本)
 
 
添加监控项过程:
 
1.define service定义一个监控项,并为其指定所属主机,描述,监控使用的命令
2.define command定义上一步中使用的那个命令
 
完成。
 
 
以上所有需要定义的监控项、命令、联系人、联系人组等,都可以在任意文件中编写,只要在主配置文件中指定该文件的全路径即可。但是通常我们都写到一个约定俗成的文件里,如:定义命令通常是在commands.cfg里面,而定义联系人和联系人组是在contact.cfg这个文件里,等等。所以你只要在相应文件里添加响应的定义即可。
 
 
 
本文2012-04-12就开始写了,但是最近一直有事,直到今天(2012-04-25)才写完,写得比较快,有很多事情都没交代,今后会不断完善修改。