使用 Monit 和 RRDtool 进行基础监控
如何在低端系统上提供强大的监控。
在运行关键系统时,必须了解系统正在消耗哪些资源,在资源利用率达到特定水平时收到警报,并对长期性能进行趋势分析。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 可以绘制您可以通过命令呈现给 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
是等待数据写入数据库的超时时间(以秒为单位)。如果在该时间窗口内数据未写入数据库,则会将零写入数据库以指示数据馈送中的错误。0
和 10000
是可以写入数据库的最小值和最大值。以 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
这将使图形脚本每天午夜运行。现在可以将图像放置在可通过浏览器访问的文件夹中,以便于查看。
尽管存在许多提供强大图形用户界面的监控解决方案,但这些解决方案提供了基本的监控和趋势分析功能,同时使用了最少的系统资源,并为传播收集的数据提供了基本框架。
资源