2016-06-15 10 views
2

나는 Nagios로 DB를 모니터링하기 위해 펄 스크립트를 프로그래밍하고있다. 타임 아웃을 위해 Time :: HiRes 라이브러리의 알람 기능을 사용하고 있습니다.Perl TIMEOUT 출력 메시지

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

모든 것이 정상적으로 작동합니다. 문제는 나는 그것이 "Temporizador"를 반환 원인 출력 메시지를 변경할와 내가

echo $? 

반환 (142)을 할 경우 내가 될 수 있도록 "3 번 출구"를 만들기 위해 메시지를 변경할 수 있습니다 Nagios에 의해 인정.

이미 '평가'를 시도했지만 작동하지 않습니다.

+2

'Temporizador'는 자식 중 하나가 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