使用 Monit 和 RRDtool 进行基础监控

作者:Andy Carlson

如何在低端系统上提供强大的监控。

在运行关键系统时,必须了解系统正在消耗哪些资源,在资源利用率达到特定水平时收到警报,并对长期性能进行趋势分析。Zabbix 和 Nagios 是两个大型解决方案,可以监控、警报和分析系统性能趋势,并且它们都提供了丰富的用户界面。然而,由于这些解决方案的要求,通常需要专用的硬件/VM 资源来托管监控解决方案。对于较小的服务器部署,存在一些选项可以提供基本的监控、警报和趋势分析功能。本文展示了如何使用 Monit 完成基本和自定义的监控和警报。它还介绍了如何使用 RRDtool 监控系统性能的长期趋势。

Monit 的初始配置

在许多流行的 Linux 发行版中,您可以从相关的软件仓库安装 Monit。安装完成后,您可以使用 monitrc 配置文件处理所有配置。该文件通常位于 /etc 目录结构中,但确切位置因您的发行版而异。

配置文件有两个部分:全局 (Global) 和服务 (Services)。全局部分允许自定义 Monit 应用程序的配置。Monit 服务包含一个基于 Web 的前端,可以通过配置文件完全配置。尽管该部分默认被注释掉,但您可以有选择地取消注释项目以进行精细的自定义。Web 配置块如下所示:


set httpd port 2812 and
    use address localhost
    allow localhost
    allow admin:monit

第一行设置了您可以通过 Web 浏览器访问 Monit 的端口号。第二行设置了用于访问 Monit 的主机名(HTTP Host 标头)。第三行设置了可以访问 Monit 应用程序的主机。请注意,如果当前已部署防火墙,您也可以使用本地防火墙访问限制来实现这一点。第四行允许配置用户名/密码对,以便在访问 Monit 时使用。还有一个部分允许为与 Monit 的加密连接配置 SSL 选项。虽然在传递身份验证数据时建议启用 SSL,但您也可以通过现有的 Web 服务器(例如 nginx 或 Apache)反向代理 Monit,前提是 Web 服务器上已配置 SSL。有关通过 Apache 反向代理 Monit 的更多信息,请参阅本文末尾的“资源”部分。

您需要启用的下一个项目是配置电子邮件警报。要设置将通过其将电子邮件中继到收件人的电子邮件服务器,请添加或启用以下行:


set mailserver mailserver.company.com

请注意,如果本地正在运行 SMTP 服务器,则此示例中的服务器名称 mailserver.company.com 可以替换为 localhost

要启用的下一个块设置将发送的电子邮件警报消息的内容,它看起来与此类似:


set mail-format {
  from:    Monit <monit@$HOST>
  subject: Monit alert --  $EVENT $SERVICE
  message: $EVENT Service $SERVICE
                Date:        $DATE
                Action:      $ACTION
                Host:        $HOST
                Description: $DESCRIPTION

                Your faithful employee,
                Monit
}

在此块中,使用不同的预定义变量来提供特定于警报的信息(用 $ 符号表示)。您可以修改发件人、主题或消息字段中的文本,也可以根据需要向消息字段添加其他数据。

要完成警报功能,您可以配置一个电子邮件地址,该地址将接收来自 Monit 的所有电子邮件警报,方法是添加以下行:


set alert user@domain.com

此时,指定的电子邮件地址将接收 Monit 生成的所有警报。但是,到目前为止,尚未配置任何警报。要开始配置警报,我们首先看一下前面提到的“服务”部分。该部分为本地计算机提供了一些基本的监控功能,包括 CPU、内存、交换空间、文件系统和基本网络监控。这些配置项中的每一个都提供了阈值的定义。在满足阈值后,可以采取操作,包括发送警报。例如,CPU/内存/交换空间监控的开箱即用警报如下所示:


check system $HOST
   if loadavg (1min) > 4 then alert
   if loadavg (5min) > 2 then alert
   if cpu usage > 95% for 10 cycles then alert
   if memory usage > 75% then alert
   if swap usage > 25% then alert

再次注意使用变量来定义要监控的主机。虽然此处定义的所有触发器都会导致警报,但也可以采取其他操作。有关这些设置的更多信息,请查阅 Monit 文档(请参阅“资源”)。

Monit 的自定义配置

初始配置完成后,您可以定义自定义警报。最好在 monitrc 文件之外定义自定义警报。您可以通过在 monitrc 文件中定义一个包含目录来完成此操作,如下所示:


include /opt/monit-custom/*

此行包含 /opt/monit-custom 文件夹中的所有配置文件。

接下来,让我们看一下两种类型的监控:主机检查和程序检查。主机检查允许监控远程主机上运行的基于 TCP 的服务。虽然您可以为更简单的服务执行基本的 TCP 端口连接测试,但 Monit 还提供了对特定 URL 执行基于 HTTP 的内容检查的功能。考虑以下示例:


check host linuxjournal-website with address www.linuxjournal.com
    if failed
        port 443 protocol https
        with request / with content = "Become a Patron"
    then alert

主机检查的第一行定义了此主机在 Monit 中的标识符 (linuxjournal-website) 以及将用于访问该主机的地址 (www.linuxjournal.com)。在此示例中,主机定义中的触发器包含多个条件:必须通过端口 443 使用 https 协议进行访问,并且在根 URL 处访问时,响应正文中会出现文本“Become a Patron”。可以将此检查重新配置为使用端口 80 和 http 协议。

除了主机监控之外,Monit 还允许定义基于脚本的监控器,这称为程序检查。一旦在 Monit 中配置了脚本,脚本将定期执行,并且根据脚本的退出代码,可以采取操作。

这是一个脚本示例,当 SSL 证书到期日期在指定的天数内时发出警报:


#!/bin/bash

domainexpiredate() {
    openssl x509 -text -in <(echo -n | \
    openssl s_client -connect $1:$2 2>/dev/null | \
    sed -n '/-*BEGIN/,/-*END/p') 2>/dev/null | sed -n 's/
 ↪*Not After : *//p'
}

daysleft() {
    echo "((($(date -d "$(domainexpiredate $1 $2)" +%s)-$(date
 ↪+%s))/24)/60)/60" | bc
}

defaultport() {
    if [ -z "$1" ]; then
        echo "443"
    else
        echo "$1"
    fi
}

[[ $(daysleft $2 $(defaultport $3)) -le $1 ]] && exit 1 ||
 ↪exit 0

此脚本使用两个参数执行:到期前的最少天数和服务器的主机名,以及可选的第三个参数,即端口号。这是一个脚本执行示例:


$ checkcertexpire.sh 31 www.linuxjournal.com
$ echo $?
0

当使用两个必需的参数执行脚本时,没有控制台输出。执行后,如果回显返回代码(标识为 $?),则值为 0,这表示域不会在 31 天内过期。在 Monit 中配置此项需要以下操作:


check program linuxjournal-ssl with path
 ↪"/etc/monit/scripts/checkcertexpire.sh 31 www.linuxjournal.com"
    if status != 0 then alert

与主机检查相同,程序检查在 Monit 中也有一个标识符(在本例中为 linuxjournal-ssl)。在程序检查的第一行中,以及标识符一起,是要执行的脚本以及命令行参数。请注意,触发器指示如果退出代码不是 0,则应发送警报。

使用 RRDtool 收集数据

RRDtool 是一个非常强大的工具,可让您长期收集数据。RRDtool 以其数据库格式(循环数据库)命名,将基于时间的数据保存到其数据库中,然后让您检索和绘制数据图表。RRDtool 可以绘制您可以通过命令呈现给 shell 脚本的任何数据图表。

在捕获数据之前,您必须初始化数据库。对于此示例,让我们创建一个数据库来捕获五分钟的平均负载。以下是初始化此特定数据库的命令:


rrdtool create loadavg_db.rrd --step 60
 ↪DS:loadavg:GAUGE:120:0:10000 RRA:MAX:0.5:1:1500

前两个参数指示正在创建名为 loadavg_db.rrd 的数据库。--step 参数定义了数据采样之间预期的时间间隔。在本例中,采样之间预期为 60 秒。

让我们分别查看另外两个参数。两个参数中的第一个参数以 DS 开头,并定义了一个名为 loadavg 的数据集。请注意,此数据集的选项用冒号分隔。GAUGE 关键字表示读取数据时,数据将按原样(未修改)写入数据库。120 是等待数据写入数据库的超时时间(以秒为单位)。如果在该时间窗口内数据未写入数据库,则会将零写入数据库以指示数据馈送中的错误。010000 是可以写入数据库的最小值和最大值。以 RRA 开头的参数定义了循环存档值。这定义了可以在数据库中存储多少个值以及它们将存储多长时间。MAX 表示变量包含一个值,不应以任何方式修改。0.5 表示初始分辨率值。这是一个标准值,不应更改。1 标识在存储最终值时应平均多少个步骤。在本例中,每个存储在数据库中的值都有一个步骤值。最后一个参数 1440 是将在数据库中存储多少个步骤。由于步长为 60 秒,因此此配置将提供 25 小时的数据存储在数据库中。

现在数据库已初始化,您可以捕获数据并将其存储在数据库中。为了保持准确的周期性数据收集,最好创建一个 crontab 条目,并在所需的时间间隔收集数据。对于此示例,您将让 cron 作业每分钟运行一次。要收集数据并将其放入数据库中,请使用以下命令:


rrdtool update loadavg_db.rrd --template loadavg N:$(cat
 ↪/proc/loadavg | sed 's/^\([0-9\.]\+\) .*$/\1/g')

为了执行数据收集,使用了 update 参数以及数据库名称。--template 参数允许您指定要用数据填充的变量名称。这与初始化数据库时定义的 loadavg 变量相同。N 参数定义要放入 loadavg 变量中的数据。在本例中,命令替换的结果将放入数据库中,这将是五分钟的平均负载。可以将此命令放在 crontab 中以每分钟执行一次。crotab 条目将如下所示:


* * * * * /path/to/rrdtool-script.sh

由于所有时间字段都包含星号,因此指定的脚本将每分钟运行一次。在数据库填充后,您可以使用以下命令渲染图表:


rrdtool graph loadavg_graph-$(date +"%m-%d-%Y").png \
-w 785 -h 120 -a PNG \
--slope-mode \
--start -86400 --end now \
--font DEFAULT:7: \
--title "5-minute load average" \
--watermark "`date`" \
--vertical-label "load average" \
--lower-limit 0 \
--right-axis 1:0 \
--x-grid MINUTE:10:HOUR:1:MINUTE:120:0:%R \
--alt-y-grid --rigid \
DEF:loadaverage=loadavg_db.rrd:loadavg:MAX \
LINE1:loadaverage#0000FF:"load" \
GPRINT:loadaverage:LAST:"Cur\: %5.2lf" \
GPRINT:loadaverage:AVERAGE:"Avg\: %5.2lf" \
GPRINT:loadaverage:MAX:"Max\: %5.2lf" \
GPRINT:loadaverage:MIN:"Min\: %5.2lf\t\t\t"

第一行调用 RRDtool graph 函数以及要创建的图像的文件名。在此实例中,图像文件名将包含当前日期。所有以 -- 开头的参数都设置了图表的外观和风格,包括标签、轴配置、图像格式以及从中提取数据的时间范围。有关这些参数的详细信息,请参阅 RRDtool 文档。

DEF:loadaverage 开头的行定义了一个名为 loadaverage 的图表变量,它将具有您在数据库中创建的 loadavg 变量中的值。以 LINE 开头的行指定图表线的颜色和要在图例中使用的标签。GPRINT 行指示要在图表底部打印的各种统计详细信息。在本例中,将显示最后记录的值以及时间范围内的平均值、最小值和最大值。请注意,%5.2lf 指定要打印的值为浮点数,小数点左侧最多 5 位数字,小数点右侧最多 2 位数字。

为了便于捕获每日图表,您还可以将此命令添加到 crontab 以每天午夜运行,条目如下:


0 0 * * * /path/to/rrdtool-graph.sh

这将使图形脚本每天午夜运行。现在可以将图像放置在可通过浏览器访问的文件夹中,以便于查看。

尽管存在许多提供强大图形用户界面的监控解决方案,但这些解决方案提供了基本的监控和趋势分析功能,同时使用了最少的系统资源,并为传播收集的数据提供了基本框架。

资源

Andy Carlson 在 IT 行业工作了 15 年,从事网络和服务器管理以及偶尔的编码工作。他很庆幸选择了自己热爱、成长和学习的职业。他目前与妻子、三个女儿和一个儿子住在俄亥俄州辛辛那提市。他的家人目前正在办理国际收养两个孩子的过程中。他喜欢弹吉他、编码以及与家人和朋友共度时光。

加载 Disqus 评论