2016-06-15 4 views
2

NagiosでDBを監視するためのperlスクリプトをプログラミングしています。 タイムアウトのためにTime :: HiResライブラリからアラーム機能を使用しています。Perl TIMEOUT出力メッセージ

use Time::HiRes qw[ time alarm ]; 
alarm $timeout; 

すべて正常です。事は、私はそれが「Temporizador」を返す原因出力メッセージを変更したいと私は

echo $? 

戻り値142を行う場合、私はそれができるように「3番出口」を作るために、メッセージを変更したいですNagiosによって認められた。

既に「eval」を試しましたが、動作しません。

+2

'Temporizador'は、その子の1つがARLMシグナルによって殺されたときにシェルによって出力されます。 '$?'はここで子供の終了コードではありません。それは子供を殺した信号の番号です(14)ORと128。 – ikegami

答えて

3

時間を費やしている関数は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を使用します。タイムアウトは実際には2を返します。

3

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:[email protected]:~/$ ./test.pl 
Custom message 
18:08:[email protected]:~/$ echo $? 
3 

取り扱いに関する拡張説明のために信号がthis nice tutorial on perltricksを確認してください。

+0

これは働いています。質問があります。なぜ寝るの?私は睡眠を入れたかどうかを確認しました10アラーム値は10を超えることはできませんなぜですか? –

+0

これは単なる例です。 「スリープ」は「アラーム」よりも大きくなければなりません。そうでなければ、プログラムは終了し、「ALRM」信号は受信されない。 – eballes

+4

@Adrian Blanco、 'sleep'はあなたのプログラムの残りの部分を表します。実際には 'sleep'を使わないでください。 – ikegami

関連する問題