[check_postgres] New action: warm_standby
david.barbion at adeoservices.com
david.barbion at adeoservices.com
Wed Jun 29 07:50:38 UTC 2011
Le 28/06/2011 19:33, Greg Sabino Mullane a écrit :
> On Tue, Jun 28, 2011 at 03:29:05PM +0200, david.barbion at adeoservices.com wrote:
>> Hello,
>>
>> I've created a small patch for check_postgres.pl that adds a new action:
>> warm_standby.
>> This action checks that the process pg_standby is running for the
>> current cluster (depending on the PGPORT env var.).
>> This patch needs the perl module Proc::ProcessTable available at CPAN.
> Thanks! Quick thoughts:
>
> Obviously we'll need a require not a 'use' for the module
> (see for example, the way we handle Date::Parse). I'm not sure about
> the name: we are really checking for a pg_standby process, so
> the "warm_standby" check is indirect.
>
> I'm wondering how this is better than the existing check that scans
> pg_controldata? Also compare with the check_standby_mode() argument...
>
Here is my new patch.
This one takes care of the database cluster state (got from
pg_controldata in check_standby_mode()).
--- a/check_postgres.pl
+++ b/check_postgres.pl
@@ -946,6 +946,7 @@ our $action_info = {
new_version_cp => [0, 'Checks if a newer version of
check_postgres.pl is available.'],
new_version_pg => [0, 'Checks if a newer version of Postgres is
available.'],
new_version_tnm => [0, 'Checks if a newer version of tail_n_mail
is available.'],
+ pg_standby => [1, 'Check that postgresql is started in warm
standby mode (pg_standby process)'],
pgb_pool_cl_active => [1, 'Check the number of active clients in
each pgbouncer pool.'],
pgb_pool_cl_waiting => [1, 'Check the number of waiting clients in
each pgbouncer pool.'],
pgb_pool_sv_active => [1, 'Check the number of active server
connections in each pgbouncer pool.'],
@@ -1573,6 +1574,9 @@ check_bloat() if $action eq 'bloat';
## Simple connection, warning or critical options
check_connection() if $action eq 'connection';
+## Check pg_standby process
+check_pg_standby() if $action eq 'pg_standby' ;
+
## Check the commitratio of one or more databases
check_commitratio() if $action eq 'commitratio';
@@ -3559,6 +3563,107 @@ sub check_connection {
} ## end of check_connection
+sub is_parent_process {
+
+ ## Check that a given PID is the child of another PID
+ ## @arg1: current process table
+ ## @arg2: pid of the parent process
+ ## @arg3: pid of the children process
+
+ my $process_table_ref = shift ;
+ my @process_table = @$process_table_ref ;
+ my $parent_pid = shift ;
+ my $child_pid = shift ;
+
+ return(0) if($child_pid == 1) ;
+
+ foreach my $p ( @process_table){
+ if ( $p->pid == $child_pid) {
+ # found !
+ if ($p->ppid == $parent_pid) {
+ return(1) ;
+ }else {
+ if (is_parent_process(\@process_table, $parent_pid,
$p->ppid) == 1) {
+ return(1) ;
+ }
+ }
+ }
+ }
+ return(0) ;
+} ## end of is_parent_process
+
+sub check_pg_standby {
+
+ ## Check that postgresql is started in warm standby mode
+ ## Look at the process table for pg_standby command
+ ## No comparisons made: warning and critical are not allowed
+ ## Suports: Nagios, MRTG
+
+ my $postmaster_pid = 0;
+ my $pg_standby_pid = 0;
+ my $found = 0 ;
+
+ if ($opt{warning} or $opt{critical}) {
+ ndie msg('range-none');
+ }
+
+ # compute $STANDBY value from pg_controldata output
+ check_standby_mode() ;
+
+ # first check that the cluster is running in standby mode
+ if (!$STANDBY) {
+ add_critical "cluster not in standby mode" ;
+ return;
+ }
+
+ # get current cluster port or default
+ my $port = $ENV{PGPORT} ;
+ $port = $opt{defaultport} if (!$port) ;
+
+ # This function needs the perl module Proc::ProcessTable
+ eval {
+ require Proc::ProcessTable;
+ import DProc::ProcessTable;
+ };
+
+ # retrieve complete process table
+ my $t = new Proc::ProcessTable;
+
+ # First, look for the postmaster process at the specified PGPORT
+ foreach my $p ( @{$t->table} ){
+ if ( $p->cmndline =~ /postmaster.*$port/) {
+ # postmaster process found!
+ $postmaster_pid = $p->pid ;
+ }
+ }
+ if ($postmaster_pid == 0) {
+ add_critical "Postmaster PID not found for port $port" ;
+ return ;
+ }
+
+ # Then, look for the pg_standby
+ foreach my $p ( @{$t->table} ){
+ if ( $p->cmndline =~ /pg_standby/) {
+ # found !
+ $pg_standby_pid = $p->pid ;
+ if (is_parent_process(\@{$t->table}, $postmaster_pid,
$pg_standby_pid) == 1) {
+ # pg_standby running
+ $found = $pg_standby_pid ;
+ }
+ }
+ }
+ if (!$found) {
+ add_critical "pg_standby not running" ;
+ }else {
+ add_ok "pg_standby($found) running" ;
+ }
+
+ return;
+
+} ## end of check_pg_standby
+
+
+
sub check_custom_query {
## Run a user-supplied query, then parse the results
Ce message et toutes les pièces jointes sont établis à l'attention exclusive de leurs destinataires et sont confidentiels. Si vous recevez ce message par erreur, merci de le détruire et d'en avertir immédiatement l'expéditeur. L'internet ne permettant pas d'assurer l'intégrité de ce message, le contenu de ce message ne représente en aucun cas un engagement de la part de Adeo Services.
More information about the Check_postgres
mailing list