通过自己编写的插件来使用 Nagios

系统监视方面的优势和新的可能性

了解更多关于 Nagios 的内容,并找出使用这个软件时存在的新的系统监视可能性。Nagios 是一种开放源代码监视软件,它可以扫描主机、服务、网络方面存在的问题。Nagios 与其他类似的包之间的主要区别在于,Nagios 将所有的信息简化为“工作(working)”、“可疑的(questionable)”和“故障(failure)”状态,并且 Nagios 支持由插件组成的非常丰富的“生态系统”。这些特性使得用户能够进行有效安装,在此过程中无需过多地关心细节内容,只提供他们所需的信息即可。

Cameron Laird (claird@phaseit.net), Vice President, Phaseit, Inc.

Photo of Cameron LairdCameron Laird 是 developerWorks 长期投稿者和前专栏作家。他经常编写关于促进其公司应用程序开发的项目的文章,主要关注可靠性、安全性和最初不是为协作而设计的系统集成。



Wojciech Kocjan (wojciech@kocjan.org), 软件工程师, IBM

Wojciech Kocjan 是 IBM 的一名软件工程师。他的商业客户包括 Motorola 和 IBM。他还具有多年作为志愿者参与各种开放源代码项目的经验。您可以通过 wojciech@kocjan.org 与他联系。



2007 年 9 月 03 日

在多台主机中监视和分析大量的信息——CPU 是否超载?网络接口是否满负荷?——是一项繁重的工作。不过一个好的解决方案可能只有几步之遥!开放源代码 Nagios 项目(请参见参考资料)可以非常方便地解决复杂的监视和通知需求。

了解 Nagios 的关键在于,它并不是监视和跟踪“普通的”测量数据,如 CPU 使用率,该工具将所有的信息简化为“工作”、“可疑的”和“故障”状态。这可以帮助操作员根据预定义的和可配置的标准,重点关注最重要和最关键的问题。

Nagios 内置了报告停机时间的功能,在跟踪服务水平协议 (SLA) 的实现时,这可能是非常有用的。正如本文稍后将要说明的,Nagios 还提供了停机自动扩大功能、服务和主机依赖关系,这篇介绍性的文章将主要讨论您可以轻松地为基本的监视需求编写小的、自定义的内容。

安装

大多数 Linux® 分发版中都内置了 Nagios 安装。在这种情况下,安装工作可以很好地与 Apache Web 服务器进行集成。要激活或者更新这种配置,您需要运行下面的命令:

yum install nagios

或者 apt-get install nagios-text。可以从 NagiosExchange 免费下载用于 AIX® 平台的二进制文件(请参见参考资料)。

对于其他平台,可以从 Nagios.org 下载 Nagios 的源代码(请参见参考资料)。生成新的 Nagios 需要一些标准开发工具:

  • 工具
    • gcc
    • make
    • autoconf
    • automake
  • 可执行文件
    • libgd
    • openssl
  • 包(库和 Header)

许多与简单网络管理协议相关的(SNMP 相关的)插件还需要 Perl 和 Net::SNMP 包。

在安装和设置了 Nagios 之后,您应该可以使用缺省的 http://your.host.name/nagios URL 访问 Nagios。图 1 显示了哪些主机和服务已启动或者停止。

图 1. Tactical Monitoring Overview 屏幕
Tactical Overview

配置 Nagios

在缺省情况下,所有的 Nagios 配置文件都位于 /etc/nagios 目录。为了方便起见,可能将与 Apache 相关的配置文件符号链接到 Apache 配置目录。可以将配置分为多个文件,每个文件用于配置中不同的部分。

首先需要设置的组件是联系人和联系人组。联系人是那些接收主机或服务停止运行的通知的人员。在缺省情况下,Nagios 提供了寻呼机和电子邮件通知方式。通过扩展,允许通过 Jabber 和许多其他方式进行通知,这在某些情况下是非常方便的。

联系人存储在 contacts.cfg 文件中,并且定义如下:

清单 1. 配置 1:基本联系人信息
define contact{
        contact_name                    jdoe
        alias                           John Due
        service_notification_commands   notify-by-email
        host_notification_commands      host-notify-by-emailes
        email                           john.doe@yourcompany.com
        }

将联系人划分成组:在主机或服务状态发生更改时,Nagios 并不指定需要通知的人员,而是通知相关的组。有时甚至可以对某个人员进行多次定义,以指定不同的通知命令或地址,然后向用户所在的联系组添加联系该人员的所有方式(请参见清单 2)。

清单 2. 配置 2:分组的联系人
define contactgroup{
        contactgroup_name               server-admins
        alias                           Server Administrators
        members                         jdoe,albundy
        }

下一个步骤是配置需要由 Nagios 进行监视的主机。应该添加所有包含监视或检查是否正处于活动状态的服务的主机。存储主机信息的配置文件是 hosts.cfg。下面是一个主机定义的示例:

清单 3. 配置 3:添加新主机
define host{
        host_name                       ubuntu_1_2
        alias                           Ubuntu test server
        address                         192.168.1.2
        check_command                   check-host-alive
        max_check_attempts              20
        notifications_enabled           1
        event_handler_enabled           0
        flap_detection_enabled          0
        process_perf_data               1
        retain_status_information       1
        retain_nonstatus_information    1
        notification_interval           60
        notification_period             24x7
        notification_options            d,u,r
        }

Nagios 配置的最后一步是为配置的主机定义服务。这个示例使用了一个预定义的“ping”Nagios 插件,它将发送 Internet 控制信息协议(Internet Control Message Protocol,ICMP)回显请求以确定主机是否有响应。

清单 4. 配置 4:添加新服务
define service{
        use                             service-template
        host_name                       ubuntu_1_2
        service_description             PING
        check_period                    24x7
        contact_groups                  server-admins
        notification_options            c,r
        check_command                   check_ping!300.0,20%!1000.0,60%
        }

在完成了这个配置工作之后,重新启动您的 Nagios 守护进程,稍等几秒钟让 Nagios 进行初始化,然后,证实 Web 管理接口中 ping 服务的可见性。

如何编写 Nagios 插件

Nagios 的最激动人心的方面是可以轻松地编写您自己的插件,只需要了解一些简单的指导原则即可。为了管理插件,Nagios 每次在查询一个服务的状态时,产生一个子进程,并且它使用来自该命令的输出和退出代码来确定具体的状态。退出状态代码的含义如下所示:

  • OK —退出代码 0—表示服务正常地工作。
  • WARNING —退出代码 1—表示服务处于警告状态。
  • CRITICAL —退出代码 2—表示服务处于危险状态。
  • UNKNOWN —退出代码 3—表示服务处于未知状态。

最后一种状态通常表示该插件无法确定服务的状态。例如,可能出现了内部错误。

下面提供了一个 Python 示例脚本,用于检查 UNIX® 平均负载。它假定 2.0 以上的级别表示警告状态,而 5.0 以上的级别表示危险状态。这些值都采用了硬编码的方式,并且始终使用最近一分钟的平均负载。

清单 5. Python 插件—示例工作插件
#!/usr/bin/env python

import os,sys

(d1, d2, d3) = os.getloadavg()

if d1 >= 5.0:
    print "GETLOADAVG CRITICAL: Load average is %.2f" % (d1)
    sys.exit(2)
elif d1 >= 2.0:
    print "GETLOADAVG WARNING: Load average is %.2f" % (d1)
    sys.exit(1)
else:
    print "GETLOADAVG OK: Load average is %.2f" % (d1)
    sys.exit(0)

在编写了这个小的可执行插件之后,接下来是使用 Nagios 注册该插件,并创建一个检查平均负载的服务定义。

这项工作也是非常简单的:使用下面的内容创建一个名为 /etc/nagios-plugins/config/mygetloadavg.cfg 的文件,根据下面的示例,向 services.cfg 文件添加一个服务。请记住,必须在 hosts.cfg 配置文件中定义 localhost

清单 6. 示例插件—使用 Nagios 进行注册
define command{
        command_name    check_mygetloadavg
	command_line    /path/to/check_getloadavg
	}
清单 7. 创建一个使用示例插件的服务
define service{
        use                             service-template
        host_name                       localhost
        service_description             LoadAverage
        check_period                    24x7
        contact_groups                  server-admins
        notification_options            c,r
        check_command                   check_mygetloadavg
        }

编写一个完整的插件

前面的示例说明了一个采用“硬编码”方式插件的限制,它不支持运行时配置。在实际中,通常最好的方式是创建一个可配置的插件。通过这种方式,您可以创建和维护一个插件,使用 Nagios 将其注册为单个插件,并且传递参数以便为特定的情况自定义警告和危险水平。下一个示例还包括一则使用消息;经过证实,对于由几个不同的开发人员或者管理员所使用或维护的插件,这是非常有价值的。

另一个好的实践是捕获所有的异常,并后退以报告 UNKNOWN 服务状态,以便 Nagios 能够正确地管理有关这个情况的通知。那些允许异常“失败”的插件通常会退出,并返回值 1;对于 Nagios,这表示一个 WARNING 状态。请确保您的插件能够正确地区分 WARNING 和 UNKNOWN。请注意,例如,在将其作为 UNKNOWN 结果处理可能出现错误的情况下,通常可以禁用至少某些 WARNING 通知。

用 Python 编写一个插件

上述的建议—运行时参数化、一则使用消息,以及经过改进的异常处理—将得到示例插件的源代码,这段代码要比前面的长几倍。但是您可以更安全地对错误进行处理,并且能够在更广泛的范围内重用该插件。

清单 8. Python 插件—获取平均负载的完整插件
#!/usr/bin/env python

import os
import sys
import getopt

def usage():
    print """Usage: check_getloadavg [-h|--help] [-m|--mode 1|2|3] \
    [-w|--warning level] [-c|--critical level]"

Mode: 1 - last minute ; 2 - last 5 minutes ; 3 - last 15 minutes"
Warning level defaults to 2.0
Critical level defaults to 5.0"""
    sys.exit(3)

try:
    options, args = getopt.getopt(sys.argv[1:],
        "hm:w:c:",
        "--help --mode= --warning= --critical=",
        )
except getopt.GetoptError:
    usage()
    sys.exit(3)

argMode = "1"
argWarning = 2.0
argCritical = 5.0

for name, value in options:
    if name in ("-h", "--help"):
        usage()
    if name in ("-m", "--mode"):
        if value not in ("1", "2", "3"):
            usage()
        argMode = value
    if name in ("-w", "--warning"):
        try:
            argWarning = 0.0 + value
        except Exception:
            print "Unable to convert to floating point value\n"
            usage()
    if name in ("-c", "--critical"):
        try:
            argCritical = 0.0 + value
        except Exception:
            print "Unable to convert to floating point value\n"
            usage()

try:
    (d1, d2, d3) = os.getloadavg()
except Exception:
    print "GETLOADAVG UNKNOWN: Error while getting load average"
    sys.exit(3)

if argMode == "1":
    d = d1
elif argMode == "2":
    d = d2
elif argMode == "3":
    d = d3

if d >= argCritical:
    print "GETLOADAVG CRITICAL: Load average is %.2f" % (d)
    sys.exit(2)
elif d >= argWarning:
    print "GETLOADAVG WARNING: Load average is %.2f" % (d)
    sys.exit(1)
else:
    print "GETLOADAVG OK: Load average is %.2f" % (d)
    sys.exit(0)

为了使用这个新的插件,需要使用下面的方法来注册 /etc/nagios-plugins/config/mygetloadavg2.cfg

清单 9. Python 插件—使用 Nagios 进行注册
define command{
        command_name    check_mygetloadavg2
	command_line    /path/to/check_getloadavg2 -m $ARG1$ -w $ARG2$ -c $ARG3$
	}

另外,根据下面的示例,在 services.cfg 文件中添加或者更改服务条目。请注意,使用感叹号 ! 来分隔插件参数。与前面一样,必须在 hosts.cfg 配置文件中定义 localhost

清单 10. 创建一个使用 Python 插件的服务
define service{
        use                             service-template
        host_name                       localhost
        service_description             LoadAverage2
        check_period                    24x7
        contact_groups                  server-admins
        notification_options            c,r
        check_command                   check_mygetloadavg2!1!3.0!6.0
        }

用 Tcl 编写一个插件

最后的示例是使用 Tcl 编写的一个插件,它使用简单对象访问协议 (SOAP) 和 Web 服务描述语言 (WSDL) 检查 xmenthods.net 的汇率。SOAP 为该插件提供了汇率的当前值,并将这些值与配置的范围进行比较。如果该值不属于警告的范围,那么它将被认为是 OK。如果该值大于或者小于警告级别,但是并没有超过危险极限,则将状态设置为 WARNING。否则将其设置为 CRITICAL,除非出现了网络错误,在这种情况下将状态设置为 UNKNOWN。

该插件可以识别不同的可配置参数,以便能够检查不同范围的汇率。它还可以用于检查各个国家的各种汇率。

清单 11. Tcl 插件—验证当前汇率
#!/usr/bin/env tclsh

# parse arguments
package require cmdline
set options {
    {country1.arg "" "Country 1"}
    {country2.arg "" "Country 2"}
    {lowerwarning.arg "" "Lower warning limit"}
    {upperwarning.arg "" "Upper warning limit"}
    {lowercritical.arg "" "Lower critical limit"}
    {uppercritical.arg "" "Upper critical limit"}
}

array set opt [cmdline::getoptions argv $options {: [options]}]

# if the user did not supply all arguments, show help message
for each necessary [array names opt] {
    if {$opt($necessary) == ""} {
        set argv "-help"
        catch {cmdline::getoptions argv $options {: [options]}} usage
	puts stderr $usage
        exit 3
    }
}

# load TclWebServices package
package require WS::Client

if {[catch {
    # download WSDL
    WS::Client::GetAndParseWsdl \
        http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl \
	{} currency

    # create stub commands
    WS::Client::CreateStubs currency

    # download the actual exchange rate
    set result [lindex \
        [currency::getRate "England" "Japan"] 1]
} error]} {
    # if downloading the rate failed for some reason, report it
    puts "EXCHANGERATE UNKNOWN: $error"
    exit 3
}
    
if {($result < $opt(lowercritical)) || ($result > $opt(uppercritical))} {
    puts "EXCHANGERATE CRITICAL: rate is $result"
    exit 2
}
if {($result < $opt(lowerwarning)) || ($result > $opt(upperwarning))} {
    puts "EXCHANGERATE WARNING: rate is $result"
    exit 1
}
puts "EXCHANGERATE OK: rate is $result"
exit 0

现在,您需要注册这个命令,以便 Nagios 知道如何调用它。为了完成这项工作,可以使用与前面类似的配置和命令定义来创建一个名为 /etc/nagios-plugins/config/exchangerate.cfg 的文件:

command_line    /path/to/check_exchangerate
-country1 $ARG1$ -country2 $ARG2$ -lowercritical \
 $ARG3$ -lowerwarning $ARG4$ -upperwarning $ARG5$ -uppercritical $ARG6$


在下面的示例中,假定该命令的名称为 check_exchangerate

接下来,创建一个使用刚刚创建的插件来监视汇率的服务。下面是服务定义,它将该服务与 localhost 服务器关联起来。尽管这个检查并不真正地关联于任何物理主机,但是需要将它绑定到一台主机。如果这个检查涉及到调用受信任的网络中的服务器的 SOAP 方法,那么您可以添加需要进行监视的实际服务器,并且在这个示例中,应该将服务绑定到该服务器。清单 12 中的代码检查 英镑对日元的汇率,并验证汇率位于 225 到 275 之间。

清单 12. 添加 Tcl 插件作为一个新的服务
define service{
        use                             service-template
        host_name                       localhost
        service_description             EXCHANGERATE
        check_period                    24x7
        contact_groups                  other-admins
        notification_options            c,r
        check_command                   check_exchangerate!England!Japan!200!225!275!300
        }

结束语

您可以使用 Nagios 监视所有类型的硬件和软件。您可以编写自己的插件,这使得能够监视与 Nagios 服务器进行通信的各种对象。正如您可以使用管理命令行参数和退出状态的任何计算语言一样,存在各种各样的可能性。

高级系统管理员可以使用 Tcl 或者任何其他语言来扩展 SOAP 示例,以便与内部网 Web 服务进行通信,并编写插件以验证该服务行为的正确性。

还可以使用 C 插件或者将 C 嵌入到您最喜欢的动态语言中(对于 Python,使用 Pyinline;对于 Perl,使用 Inline ;或者对于 Tcl,使用 Critcl),以便将您的操作系统的 C API 与您的插件(使用高级语言编写)组合在一起。

Nagios 的另一个值得关注的特性是被动检查。到此为止,您所看到的 Nagios 监视功能可以管理短期状态的可执行文件,启动它们,然后接收结果。在被动检查过程中,Nagios 并不产生插件以检查状态,而是不同的应用程序周期性地或者当服务状态发生更改时,将状态更新发送给 Nagios。这样的应用程序可以接收来自其他源的通知,对其进行聚合,并将经过计算的汇总信息传递给 Nagios。如果经过一段时间还没有接收到来自某个服务的通知,Nagios 还可以假定该服务已经停止。我们将在后续的文章中说明 Nagios 被动检查的实现。

使得 Nagios 插件如此激动人心的原因是,它们非常容易进行编写和共享。Nagios 插件非常适合于网络和系统管理员所碰到的各种情况,并且在许多情况下,可以很简单地重用其他人已经完成的工作。正如运行良好的 Wiki 或者 Web 本身一样,可以很容易地提供一个有帮助的示例,不过所有可用的 Nagios 插件的整体价值是非常巨大的。

参考资料

学习

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文
  • Nagios:有关 Nagios 的更详细的信息,请访问 Nagios 官方网站。它包含应用程序的最新版本、RPM 包,以及用于 Linux 平台的独立版本。另外,propaganda 页面还向您介绍了哪些公司使用了 Nagios 及其原因。
  • 有几本 Nagios 方面的书籍这篇评论 Nagios:System and Network Monitoring,还提供了有关 Nagios 的主题的一般背景信息。
  • Nagios Exchange 是大量公开的 Nagios 插件的中央存储库。
  • 可以从 NagiosExchange 免费下载用于 AIX 平台的二进制文件。对于其他的平台,可以从 Nagios.org 下载 Nagios 的源代码。
  • Nagiosplug Developer guidelines:这个页面包含了有关编写您自己的 Nagios 插件的各种建议和很好的实践。
  • Passive Host and Service Checks 直接从您的应用程序向 Nagios 发送通知。
  • 要了解更多有关 Python 的内容,请访问 Python 主页。这个网站包含了所有的下载信息以及有关 Python 和如何使用它的附加帮助。请仔细浏览 David Mertz 的 developerWorks 专栏“Charming Python”。
  • 对于那些需要掌握 Tcl 最新动态的读者,可以从 www.tcl.tk/ 联机获得各种发行版的完整的 Tcl 文档。可以从其 Sourceforge 项目免费下载 Tcl/Tk 本身。
  • 在 Python 中编写 C 代码,可以使用 PyInline 模块,可以从其 Sourceforge 项目免费地下载该模块。
  • 对于那些希望在他们的插件中使用本地 OS API 的所有 Tcl 爱好者,可以使用 Critcl 将 C 引入到 Tcl。Starkit 允许在您的计算机上运行、构建和使用 Critcl,您可以从 critcl.kit 免费地下载该工具。
  • 查看 Cameron Laird 撰写的其他文章和教程:
  • 受欢迎的内容:查看您的同事所感兴趣的 AIX 和 UNIX 文章。
  • AIX and UNIX 专区:developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。
  • AIX and UNIX 新手指南:访问“New to AIX and UNIX”页面可了解更多关于 AIX 和 UNIX 的内容。
  • AIX 5L Wiki:发现 AIX 相关技术信息的协作环境。
  • 按主题搜索“AIX and UNIX”库:
  • Safari 书店:访问此电子参考资料库可查找特定的技术资源。
  • developerWorks 技术事件和网络广播:了解最新的 developerWorks 技术事件和网络广播。
  • Podcast:收听 Podcast 并与 IBM 技术专家保持同步。

获得产品和技术

  • IBM 试用软件:从 developerWorks 可直接下载这些试用软件,您可以利用它们开发您的下一个项目。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=252581
ArticleTitle=通过自己编写的插件来使用 Nagios
publish-date=09032007