check_postgres.pl 的缺陷

Nagios 系统监控pg 数据库的组件 check_postgres.pl



对数据库的监控的返回值中,存在一个缺陷。分析如下

如果 pg 数据库已经宕掉,监控代码无法连接到数据库时,应用代码不会发出critical 的告警

check_postgres.pl  返回的代码为3 对应于nagios 告警系统的 UNKNOW ,这个时候就有可能导致数据库管理人员的误判。

具体的函数为run_command()  中对数据库返回的错误信息的判断有问题。

对于设置的检查脚本中连接pg 的连接用户,如果权限不够,或者不能登录pg数据库,返回的代码为 FATAL

代码对此返回的值为3 这个时候其实从侧面是可以确认数据库应该还是ok 的,

对于检查的sql 代码超时 , 返回的结果状态也为3  , 这个时候应该是数据库忙了,这种情况,dba是需要检查系统的。

而对于 PG 数据库损坏,或者已经关机 检查代码连接不到数据库,监控代码并没有做专门的处理而是仅仅返回了状态3  UNKONW 这个时候dba 是需要优先检查数据库的,数据库可能已经处于故障状态了。

我们的修改:

在run_command 函数中增加一个错误判断:

  if ($db->{error} =~ /FATAL/) {
                                if (exists $arg->{fatalregex} and $db->{error} =~ /$arg->{fatalregex}/) {
                                        $info->{fatalregex} = $db->{error};
                                        next;
                                }
                                else {
                                        ndie "$db->{error}";
                                }
                        }

                        elsif ($db->{error} =~ /statement timeout/) {
                                ndie msg('runcommand-timeout', $timeout);
                        }
                        #### lsl
                        ##  if  run check_postgres.pl  on local host
                        ##  when  pg is down  we can recieve  MSG: psql: could not connect to server: No such file or directory
                        ##  AND  check_postgres.pl  return code = 3  Nagios  means Uknow 
                        ##  We  need this  return  Critical  Status
                        ##  So  we modified  this here  and add  sub fide 
                        ##  lsliang  
                        elsif ($db->{error} =~ /could not connect to server/) {
                                fdie  "$db->{error}"

                        }
                        if (!$db->{ok} and !$arg->{failok} and !$arg->{noverify}) {

                                ## Check if problem is due to backend being too old for this check
                                verify_version();

                                if (exists $db->{error}) {
                                        ndie $db->{error};
                                                           

同事配套的 定义了一个fdie 函数 返回状态码为2  对应于Nagios 的critical 告警,要求dba 立即处理。

fdie 函数的定义跟ndie 函数的定义是一致的,只是返回值为2 。

##### some times  we want  ndie return 2  and raise  Nagios 's  CRITICAL 
## lsl
sub fdie  {
        eval { FILE::Temp::cleanup();};
        my $msg= shift;
        chomp $msg;
        print "FATAL!!: $msg\n";
        exit 2 ;
}

经过测试可以很好的处理,pg挂掉时的告警。



请使用浏览器的分享功能分享到微信等