类似看门狗的支持(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 中启动它,如果它由于某种原因死了,它会自行重启。
但无论如何 - 你可以有多个子程序(例如你的测试脚本)全部自动产生(为了奖励积分 - 它们将 运行 并行)。
我有一个 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 中启动它,如果它由于某种原因死了,它会自行重启。
但无论如何 - 你可以有多个子程序(例如你的测试脚本)全部自动产生(为了奖励积分 - 它们将 运行 并行)。