Perl 超时输出消息
Perl TIMEOUT output message
我正在编写 perl 脚本以使用 Nagios 监控数据库。
我正在使用 Time::HiRes 库中的警报功能来超时。
use Time::HiRes qw[ time alarm ];
alarm $timeout;
一切正常。问题是我想更改输出消息,因为它 returns "Temporizador" 如果我这样做
echo $?
Returns 142.我想更改消息以制作"exit 3"以便Nagios能够识别它。
已经试过'eval'但没有用。
您应该处理 ALRM
信号。例如:
#!/usr/bin/env perl
use strict;
use warnings;
use Time::HiRes qw[ time alarm ];
$SIG{ALRM} = sub {print "Custom message\n"; exit 3};
alarm 2;
sleep 10; # this line represents the rest of your program, don't include it
这将输出:
18:08:20-eballes@urth:~/$ ./test.pl
Custom message
18:08:23-eballes@urth:~/$ echo $?
3
有关处理信号的详细说明,请查看 this nice tutorial on perltricks。
占用时间的函数是用 C 编写的,这使您无法安全地使用自定义信号处理程序。
您似乎并不担心强行终止您的程序,因此我建议您使用 alarm
而不使用信号处理程序,以在 运行 花费的时间太长时强行终止您的程序,并使用为 Nagios 提供正确响应的包装器。
改变
/path/to/program some args
到
/path/to/timeout_wrapper 30 /path/to/program some args
以下为timeout_wrapper
:
#!/usr/bin/perl
use strict;
use warnings;
use POSIX qw( WNOHANG );
use Time::HiRes qw( sleep time );
sub wait_for_child_to_complete {
my ($pid, $timeout) = @_;
my $wait_until = time + $timeout;
while (time < $wait_until) {
waitpid($pid, WNOHANG)
and return $?;
sleep(0.5);
}
return undef;
}
{
my $timeout = shift(@ARGV);
defined( my $pid = fork() )
or exit(3);
if (!$pid) {
alarm($timeout); # Optional. The parent will handle this anyway.
exec(@ARGV)
or exit(3);
}
my $timed_out = 0;
my $rv = wait_for_child_to_complete($pid, $timeout);
if (!defined($rv)) {
$timed_out = 1;
if (kill(ALRM => $pid)) {
$rv = wait_for_child_to_complete($pid, 5);
if (!defined($rv)) {
kill(KILL => $pid)
}
}
}
exit(2) if $timed_out;
exit(3) if $rv & 0x7F; # Killed by some signal.
exit($rv >> 8); # Expect the exit code to comply with the spec.
}
使用Nagios Plugin Return Codes。超时实际上应该 return 2
.
我正在编写 perl 脚本以使用 Nagios 监控数据库。 我正在使用 Time::HiRes 库中的警报功能来超时。
use Time::HiRes qw[ time alarm ];
alarm $timeout;
一切正常。问题是我想更改输出消息,因为它 returns "Temporizador" 如果我这样做
echo $?
Returns 142.我想更改消息以制作"exit 3"以便Nagios能够识别它。
已经试过'eval'但没有用。
您应该处理 ALRM
信号。例如:
#!/usr/bin/env perl
use strict;
use warnings;
use Time::HiRes qw[ time alarm ];
$SIG{ALRM} = sub {print "Custom message\n"; exit 3};
alarm 2;
sleep 10; # this line represents the rest of your program, don't include it
这将输出:
18:08:20-eballes@urth:~/$ ./test.pl
Custom message
18:08:23-eballes@urth:~/$ echo $?
3
有关处理信号的详细说明,请查看 this nice tutorial on perltricks。
占用时间的函数是用 C 编写的,这使您无法安全地使用自定义信号处理程序。
您似乎并不担心强行终止您的程序,因此我建议您使用 alarm
而不使用信号处理程序,以在 运行 花费的时间太长时强行终止您的程序,并使用为 Nagios 提供正确响应的包装器。
改变
/path/to/program some args
到
/path/to/timeout_wrapper 30 /path/to/program some args
以下为timeout_wrapper
:
#!/usr/bin/perl
use strict;
use warnings;
use POSIX qw( WNOHANG );
use Time::HiRes qw( sleep time );
sub wait_for_child_to_complete {
my ($pid, $timeout) = @_;
my $wait_until = time + $timeout;
while (time < $wait_until) {
waitpid($pid, WNOHANG)
and return $?;
sleep(0.5);
}
return undef;
}
{
my $timeout = shift(@ARGV);
defined( my $pid = fork() )
or exit(3);
if (!$pid) {
alarm($timeout); # Optional. The parent will handle this anyway.
exec(@ARGV)
or exit(3);
}
my $timed_out = 0;
my $rv = wait_for_child_to_complete($pid, $timeout);
if (!defined($rv)) {
$timed_out = 1;
if (kill(ALRM => $pid)) {
$rv = wait_for_child_to_complete($pid, 5);
if (!defined($rv)) {
kill(KILL => $pid)
}
}
}
exit(2) if $timed_out;
exit(3) if $rv & 0x7F; # Killed by some signal.
exit($rv >> 8); # Expect the exit code to comply with the spec.
}
使用Nagios Plugin Return Codes。超时实际上应该 return 2
.