烦人的通知
在2011 年 2 月刊中,我撰写了关于 screen,控制台窗口管理器,以及我如何配置其硬状态行以在我的终端窗口底部显示通知的文章。尽管有些人喜欢他们的桌面环境在收到新电子邮件或 IM 时弹出通知,但由于我大部分时间都在 screen 中度过,它集中了我的注意力,因此将重要通知放在那里是有意义的。在那篇2011 年 2 月的文章中,我介绍了如何设置硬状态行,并演示了我用来显示何时有新电子邮件的自定义脚本。
在本文中,我扩展了关于 screen 通知的主题,介绍了一个我发现非常有用新的通知脚本。自从我拥有了不止少数的服务器以来,我就依赖于像 Nagios 这样的监控程序来跟踪服务器的健康状况。尽管监控软件有其自身的通知方法,通过电子邮件或 SMS,但我发现将我当前的 Nagios 健康状况直接显示在我的 screen 会话中很有价值。它不仅为我的邮件通知提供了一个备份,而且还节省了我一直打开浏览器中的 Nagios 窗口的时间。
如果您是 screen 的新手,并且还没有设置自定义的硬状态行,请先查看我的2011 年 2 月文章,以便快速入门。我假设您已经设置了一个基本的 .screenrc 文件,而不是从头开始重新讨论如何配置 .screenrc 文件,相反,我将跳过如何将这个 Nagios 脚本添加到您现有的 screen 会话中。
Screen 抓取用于 Screen当我着手编写这个脚本时,我意识到有很多不同的方法可以捕获 Nagios 当前的健康状况。尽管我没有花太多时间研究它,但我认为我可以查询更底层的 API,但老实说,我真正想要的只是知道 Nagios 是否一切正常(绿色)或有任何警告或严重警报(黄色或红色),以及如果有,有多少。为了实现这一点,我决定最简单的方法是抓取其中一个 Nagios 状态页面以获取我需要的信息。老实说,只要它有一个 Web 界面,并且您有足够的正则表达式技巧来解析 HTML 以获取您需要的数据,这种相同的方法应该非常适用于您可能使用的任何监控程序。
我最初编写这个脚本是为了,如果 Nagios 状态正常,它将打印出来,如果有任何严重或警告警报,它将输出这些统计信息。我意识到我希望 screen 以绿色打印正常,黄色打印警告,红色打印严重警报。这样,即使我没有直接看着我的终端,我也可能会注意到问题。为了实现这一点,我实际上需要在 screen 中运行该脚本三次。
下面的脚本只接受两个参数:要轮询的 Nagios 主机(如果使用用户名和密码,则为可选)以及要报告的状态类型。我选择了颜色代码绿色、黄色和红色分别代表正常、警告和严重状态。我发现 http://nagioshostname/cgi-bin/nagios3/tac.cgi 页面是最容易抓取的,并且包含了我脚本所需的所有信息
#!/usr/bin/perl
# usage: nagios_scraper.pl [user:password@]nagios_host STATUS
# where STATUS is green, red, yellow, or all
$nagios_host=shift;
$show=shift;
open TAC, "wget --timeout=2 -q -O -
↪http://$nagios_host/cgi-bin/nagios3/tac.cgi |"; @tac = <TAC>;
close TAC;
foreach $line (@tac){
if ($line =~ /(\d+) Down/){ $hosts_down = $1; }
elsif($line =~ /(\d+) Unreachable/){ $hosts_unreachable = $1; }
elsif($line =~ /(\d+) Up/){ $hosts_up = $1; }
elsif($line =~ /(\d+) Pending/){ $hosts_pending = $1; }
elsif($line =~ /(\d+) Critical/){ $services_critical = $1; }
elsif($line =~ /(\d+) Warning/){ $services_warning = $1; }
elsif($line =~ /(\d+) Unknown/){ $services_unknown = $1; }
elsif($line =~ /(\d+) Ok/){ $services_ok = $1; }
elsif($line =~ /(\d+) Pending/){ $services_pending = $1; }
}
# remove the username and password from the output
$nagios_host =~ s/.*\@//;
if($show eq "green" && ($hosts_down == 0 && $services_critical == 0
↪&& $services_warning == 0)){
print "$nagios_host: OK";
}
elsif($show eq "red" && ($hosts_down > 0 || $services_critical > 0)){
print "$nagios_host: ${hosts_down}D ${services_critical}C ";
}
elsif($show eq "yellow" && $services_warning > 0){
print "$nagios_host: ${services_warning}W ";
}
elsif($show eq "all"){
print "${hosts_down}D ${hosts_up}U ${services_critical}C
↪${services_warning}W ${services_ok}OK";
}
正如您所看到的,我实际上收集了比我最终使用的更多的统计信息,以防万一我想稍后参考它们。这个脚本中需要注意的重要一点是,在每种绿色、红色和黄色状态中,我只在有该状态的内容要打印时才打印。这至关重要,因为我不想使我的硬状态行混乱,并且我希望只在真正需要我注意时才看到黄色或红色文本。
将此脚本命名为 nagios_scraper.pl,将其放在 /usr/local/bin 中供所有人使用,或放在您用户的 ~/bin/ 目录中,确保它是可执行的,然后针对您的 Nagios 服务器对其进行测试,以确保您的语法正确。例如,如果您没有为 Nagios 设置用户名或密码,并且您的 Nagios 服务器名为 naggyhost,您将键入以下命令来测试一切是否正常
$ /usr/local/bin/nagios_scraper.pl naggyhost green
键入以下内容以测试严重警报
$ /usr/local/bin/nagios_scraper.pl naggyhost red
或者,键入以下内容以测试查看所有状态
$ /usr/local/bin/nagios_scraper.pl naggyhost all
我建议您为您 Nagios Web 访问设置用户名和密码(如果您尚未设置)。因为您用于此脚本的用户名和密码最终将以纯文本形式出现,所以我建议为 Nagios Web 界面设置一个帐户,该帐户可以登录,但只能查看 Nagios 状态,并且不能提交任何更改(如维护模式和确认)。假设我在 naggyhost 上设置了一个名为 readonly 的帐户,密码为 n0wr1t3。我将像这样调用脚本
$ /usr/local/bin/nagios_scraper.pl readonly:n0wr1t3@naggyhost red
同样,如果脚本在其中一种模式下不提供任何输出,则可能只是意味着该状态当前不适用。如果您想确定地测试这一点,请使用 all 参数而不是 green、yellow 或 red 运行脚本,以查看完整状态。
我们将,我们将,Nag 你一旦您测试了脚本并使其工作,下一步就是将其添加到您的 ~/.screenrc 中。第一步是在 ~/.screenrc 中添加三个新的反引号配置行,这将分别使用 green、red 和 yellow 状态调用 nagios_scraper.pl。在我的例子中,我假设您可能定义了一些反引号命令,所以我从命令 110 开始
backtick 110 27 27 /usr/local/bin/nagios_scraper.pl
↪readonly:n0wr1te@naggyhost red
backtick 111 61 61 /usr/local/bin/nagios_scraper.pl
↪readonly:n0wr1te@naggyhost yellow
backtick 112 73 73 /usr/local/bin/nagios_scraper.pl
↪readonly:n0wr1te@naggyhost green
我已经将每个命令设置为以不同的时间间隔运行。我希望比警告或一切正常时更频繁地检查严重警报,所以我每 27 秒运行一次带有 red 参数的命令。然后我每 61 秒和 73 秒运行一次带有 yellow 和 green 的命令。请注意,我将这些间隔设置为奇数时间。我已经意识到错开我的 screen 通知脚本的价值,这样它们就不会冒着同时运行的风险,因此为了帮助实现这一点,我尝试选择奇数间隔。
一旦您定义了反引号行,下一步就是将它们添加到您的硬状态字符串中,以便它们以绿色、黄色和红色显示。在我的例子中,我粘贴了
%{+b r}%110`%{+b y}%111`%{= g}%112`
以便我从之前的文章修改的硬状态字符串将是
hardstatus string '%{= w}%Y-%m-%d %c | %l | %101`|
↪%{+b r}%110`%{+b y}%111`%{= g}%112`'
现在保存您对 ~/.screenrc 的更改,然后启动一个新的 screen 会话,或者键入 Ctrl-A : 并键入 source ~/.screenrc
以将这些更改加载到您现有的 screen 会话中。图 1 和图 2 显示了硬状态行在状态正常或存在严重警报时的外观。

图 1. 一切正常。

图 2. 一个主机宕机警报,带有五个严重服务。
当我深入研究 screen 通知时,最让我惊讶的是,一旦您掌握了窍门,向列表中添加新脚本是多么简单。即使您不使用 screen,修改脚本以使其输出到桌面通知也不会太困难(有关详细信息,请参阅我的2009 年 12 月专栏)。