From 8a50a72dc5b74b7cb518cf875b1e12debde6aacd Mon Sep 17 00:00:00 2001 From: Ian Barwick Date: Thu, 10 Aug 2017 17:18:08 +0900 Subject: [PATCH] Additional "node status" output --- dbutils.h | 6 +-- repmgr-action-node.c | 108 +++++++++++++++++++++++++++++++++++++++-- repmgr-client-global.h | 7 --- repmgr.h | 1 - strutil.c | 14 ++++++ strutil.h | 12 +++++ 6 files changed, 132 insertions(+), 16 deletions(-) diff --git a/dbutils.h b/dbutils.h index 31447a4f..2bd2123a 100644 --- a/dbutils.h +++ b/dbutils.h @@ -331,10 +331,8 @@ bool get_cluster_size(PGconn *conn, char *size); int get_server_version(PGconn *conn, char *server_version); RecoveryType get_recovery_type(PGconn *conn); int get_primary_node_id(PGconn *conn); -bool get_replication_info(PGconn *conn, ReplInfo *replication_info); bool can_use_pg_rewind(PGconn *conn, const char *data_directory, PQExpBufferData *reason); int get_ready_archive_files(PGconn *conn, const char *data_directory); -int get_replication_lag_seconds(PGconn *conn); /* extension functions */ ExtensionStatus get_repmgr_extension_status(PGconn *conn); @@ -413,7 +411,9 @@ bool get_new_primary(PGconn *conn, int *primary_node_id); void reset_voting_status(PGconn *conn); /* replication status functions */ -XLogRecPtr get_last_wal_receive_location(PGconn *conn); +XLogRecPtr get_last_wal_receive_location(PGconn *conn); +bool get_replication_info(PGconn *conn, ReplInfo *replication_info); +int get_replication_lag_seconds(PGconn *conn); /* BDR functions */ void get_all_bdr_node_records(PGconn *conn, BdrNodeInfoList *node_list); diff --git a/repmgr-action-node.c b/repmgr-action-node.c index 419133f0..fd034538 100644 --- a/repmgr-action-node.c +++ b/repmgr-action-node.c @@ -125,6 +125,89 @@ do_node_status(void) break; } + if (guc_set(conn, "archive_mode", "=", "off")) + { + key_value_list_set( + &node_status, + "WAL archiving", + "off"); + + key_value_list_set( + &node_status, + "Archive command", + "(none)"); + } + else + { + bool enabled = true; + PQExpBufferData archiving_status; + char archive_command[MAXLEN] = ""; + + initPQExpBuffer(&archiving_status); + if (recovery_type == RECTYPE_STANDBY) + { + if (guc_set(conn, "archive_mode", "=", "on")) + enabled = false; + } + + if (enabled == true) + { + appendPQExpBuffer(&archiving_status, "enabled"); + } + else + { + appendPQExpBuffer(&archiving_status, "disabled"); + } + + if (enabled == false && recovery_type == RECTYPE_STANDBY) + { + appendPQExpBuffer(&archiving_status, " (on standbys \"archive_mode\" must be set to \"always\" to be effective)"); + } + + key_value_list_set( + &node_status, + "WAL archiving", + archiving_status.data); + + termPQExpBuffer(&archiving_status); + + get_pg_setting(conn, "archive_command", archive_command); + + key_value_list_set( + &node_status, + "Archive command", + archive_command); + } + + { + char data_dir[MAXPGPATH] = ""; + int ready_files; + + if (config_file_options.data_directory[0] != '\0') + { + strncpy(data_dir, config_file_options.data_directory, MAXPGPATH); + } + else + { + /* requires superuser */ + get_pg_setting(conn, "data_directory", data_dir); + } + + ready_files = get_ready_archive_files(conn, data_dir); + + key_value_list_set_format( + &node_status, + "WALs pending archiving", + "%i pending files", + ready_files); + + if (guc_set(conn, "archive_mode", "=", "off")) + { + key_value_list_set_output_mode(&node_status, "WALs pending archiving", OM_CSV); + } + + } + if (node_info.max_wal_senders >= 0) { @@ -183,7 +266,6 @@ do_node_status(void) "disabled"); } - // if standby (and in recovery), show: // upstream // -> check if matches expected; parse recovery.conf for < 9.6 (must be superuser), @@ -195,6 +277,13 @@ do_node_status(void) if (node_info.type == STANDBY) { + key_value_list_set_format( + &node_status, + "Upstream node", + "%s (ID: %i)", + node_info.node_name, + node_info.node_id); + get_replication_info(conn, &replication_info); key_value_list_set_format( @@ -209,15 +298,23 @@ do_node_status(void) } else { + key_value_list_set( + &node_status, + "Upstream node", + "(none)"); + key_value_list_set_output_mode(&node_status, "Upstream node", OM_CSV); + key_value_list_set( &node_status, "Last received LSN", "(none)"); + key_value_list_set_output_mode(&node_status, "Last received LSN", OM_CSV); + key_value_list_set( &node_status, "Last replayed LSN", "(none)"); - + key_value_list_set_output_mode(&node_status, "Last replayed LSN", OM_CSV); } initPQExpBuffer(&output); @@ -273,9 +370,10 @@ do_node_status(void) for (cell = node_status.head; cell; cell = cell->next) { - appendPQExpBuffer( - &output, - "\t%s: %s\n", cell->key, cell->value); + if (cell->output_mode == OM_NOT_SET) + appendPQExpBuffer( + &output, + "\t%s: %s\n", cell->key, cell->value); } } diff --git a/repmgr-client-global.h b/repmgr-client-global.h index 48cfef85..93697499 100644 --- a/repmgr-client-global.h +++ b/repmgr-client-global.h @@ -15,13 +15,6 @@ /* default value for "cluster event --limit"*/ #define CLUSTER_EVENT_LIMIT 20 -typedef enum { - OM_TEXT, - OM_CSV, - OM_NAGIOS, - OM_OPTFORMAT -} OutputMode; - typedef struct { /* configuration metadata */ diff --git a/repmgr.h b/repmgr.h index 41337be2..9aa17356 100644 --- a/repmgr.h +++ b/repmgr.h @@ -68,5 +68,4 @@ - #endif /* _REPMGR_H_ */ diff --git a/strutil.c b/strutil.c index 230d1d97..ea024040 100644 --- a/strutil.c +++ b/strutil.c @@ -8,6 +8,7 @@ #include #include +#include "repmgr.h" #include "log.h" #include "strutil.h" @@ -152,6 +153,7 @@ key_value_list_set_format(KeyValueList *item_list, const char *key, const char * cell->key = pg_malloc0(keylen + 1); cell->value = pg_malloc0(MAXLEN); + cell->output_mode = OM_NOT_SET; strncpy(cell->key, key, keylen); @@ -171,6 +173,18 @@ key_value_list_set_format(KeyValueList *item_list, const char *key, const char * } +void +key_value_list_set_output_mode (KeyValueList *item_list, const char *key, OutputMode mode) +{ + KeyValueListCell *cell; + + for (cell = item_list->head; cell; cell = cell->next) + { + if (strncmp(key, cell->key, MAXLEN) == 0) + cell->output_mode = mode; + } +} + const char * key_value_list_get(KeyValueList *item_list, const char *key) { diff --git a/strutil.h b/strutil.h index ecd3a4a7..ac437e3c 100644 --- a/strutil.h +++ b/strutil.h @@ -19,6 +19,14 @@ #define MAXLEN_STR STR(MAXLEN) +typedef enum { + OM_NOT_SET = -1, + OM_TEXT, + OM_CSV, + OM_NAGIOS, + OM_OPTFORMAT +} OutputMode; + typedef struct ItemListCell { struct ItemListCell *next; @@ -36,6 +44,7 @@ typedef struct KeyValueListCell struct KeyValueListCell *next; char *key; char *value; + OutputMode output_mode; } KeyValueListCell; typedef struct KeyValueList @@ -67,6 +76,9 @@ extern void key_value_list_set_format(KeyValueList *item_list, const char *key, const char *value, ...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4))); +extern void +key_value_list_set_output_mode(KeyValueList *item_list, const char *key, OutputMode mode); + extern const char * key_value_list_get(KeyValueList *item_list, const char *key);