类似看门狗的支持(bash perl 或 python)

Watchdog-like support (bash perl or python)

我有一个 bash 脚本(我正在转换为 perl),该脚本 运行 处于无限循环 (while true; do) 中以轮询我们网络上的设备并记录它们对文本文件的响应。在 (while) 循环的每次迭代中,该设备的文本文件都会附加其最新信息。

我希望始终使用此脚本 运行 -- 如果它挂起、崩溃或不再写入适当的文本文件 -- 它应该重新启动。

根据 this Whosebug 问题中发布的建议,我可以编写以下 bash 脚本:

until myserver; do
  echo "Server 'myserver' crashed with exit code $?.  Respawning.." >&2
  sleep 1
done

其中 myserver 是轮询程序。这将解释脚本意外崩溃或挂起的问题,假设在这些情况下发出了非零退出代码。但是,如果脚本没有完全 fail/exit,而是以某种方式失败,只是阻止它写入文本文件——在这种情况下,我也想重新启动脚本。这就是类似看门狗的脚本的用武之地。我可以使用 Python 的 watchdog 并编写一个使用 Observer 库的脚本来监视正在生成的文本文件,like in this example.我会触发停滞的文本文件,为 python 脚本发出非零退出,然后按如下方式扩充上面的 bash 脚本:

until [myserver -o pythonMon]; do
  echo "Server 'myserver' crashed with exit code $?.  Respawning.." >&2
  sleep 1
done

其中 pythonMon 是监控文本文件是否正确更新的 python 脚本。不幸的是,这种方法需要三个脚本(主轮询脚本和两个监控脚本);有点乱。我正在寻找 optimize/simplify 这种方法。有什么建议吗?理想情况下,我有一个单一的脚本(至少一个单一的监控脚本)来保持轮询脚本 运行ning 而不是两个。有没有办法将文件监控直接添加到 bash 或 perl 代码中? 这是在 64 位 CentOS 6.5 运行ning

我正在做一些类似的事情来监控一堆设备。虽然有点取决于轮询频率 - 我通过 cron 以 3m 的间隔生成。

请记住,10 秒的样本可能非常密集,并且可能并不总是必要的 - 它确实在一定程度上取决于您的目标。

总之,工作的工具是Parallel::ForkManager。

#!/usr/bin/perl

use strict;
use warnings;

use Parallel::ForkManager;

my @targets = qw( server1 server2 );

my %test_list = { 'fetch_cpu' => \&fetch_cpu_stats, };


sub fetch_cpu_stats {
    my ($target) = @_;
    ## do something to $target;
    open( my $ssh_results, "-|", "ssh -n $target uptime" )
        or die $!;
    while (<$ssh_results>) {
        print;
    }
}

my $manager = Parallel::ForkManager->new(10);

while (1) {
    foreach my $test ( keys %test_list ) {
        foreach my $target (@targets) {
            $manager->start and next;
            print "$$ starting $test\n";
            &{$test_list{$test}}($target);
            $manager -> finish;
        }
    }
    sleep 10;
}

这将产生最多 10 个并发 'tests',并且每 10 秒重新运行。可能值得某种 'lock' 过程(使用 flock),以便使用 cron 检查您的 'daemon' 脚本是否仍然 运行ning.

那会是这样的:

open ( my $self, "<", [=11=] ) or die $!;
flock ( $self, 2 | 4 ) or die "[=11=] already running"; 

然后您可以经常在 cron 中启动它,如果它由于某种原因死了,它会自行重启。

但无论如何 - 你可以有多个子程序(例如你的测试脚本)全部自动产生(为了奖励积分 - 它们将 运行 并行)。