openGauss-server/contrib/pgxc_ctl/monitor.cpp

409 lines
13 KiB
C++

/*-------------------------------------------------------------------------
*
* monitor.c
*
* Monitoring module of Postgres-XC configuration and operation tool.
*
* Portions Copyright (c) 2013 Postgres-XC Development Group
*
*-------------------------------------------------------------------------
*/
/*
* This module is imported from /contrib/pgxc_monitor, to provide monitoring
* feature of each pgstgres-xc components.
*/
#include "gtm/gtm_client.h"
#include "gtm/libpq-fe.h"
#include <stdlib.h>
#include <getopt.h>
#include "utils.h"
#include "variables.h"
/* This is an ugly hack to avoid conflict between gtm_c.h and pgxc_ctl.h */
#undef true
#undef false
#include "pgxc_ctl_log.h"
#include "varnames.h"
#include "config.h"
#include "monitor.h"
/* Define all the node types */
typedef enum {
NONE = 0,
GTM, /* GTM or GTM-proxy */
NODE /* Coordinator or Datanode */
} nodetype_t;
#define GetToken() (line = get_word(line, &token))
#define testToken(word) ((token != NULL) && (strcmp(token, word) == 0))
#define TestToken(word) ((token != NULL) && (strcasecmp(token, word) == 0))
static void printResult(int res, char* what, char* name)
{
if (res == 0) {
if (name)
elog(NOTICE, "Running: %s %s\n", what, name);
else
elog(NOTICE, "Running: %s\n", what);
} else {
if (name)
elog(NOTICE, "Not running: %s %s\n", what, name);
else
elog(NOTICE, "Not running: %s\n", what);
}
}
static void monitor_gtm_master(void)
{
return (printResult(do_gtm_ping(sval(VAR_gtmMasterServer), atoi(sval(VAR_gtmMasterPort))), "gtm master", NULL));
}
static void monitor_gtm_slave(void)
{
if (doesExist(VAR_gtmSlaveServer, 0) && doesExist(VAR_gtmSlavePort, 0))
return (printResult(do_gtm_ping(sval(VAR_gtmSlaveServer), atoi(sval(VAR_gtmSlavePort))), "gtm slave", NULL));
}
static void monitor_gtm_proxy(char** nodeList)
{
char** actualNodeList;
int ii;
int idx;
actualNodeList = makeActualNodeList(nodeList);
for (ii = 0; actualNodeList[ii]; ii++) {
if ((idx = gtmProxyIdx(actualNodeList[ii])) < 0) {
elog(ERROR, "ERROR: %s is not a gtm proxy.\n", actualNodeList[ii]);
continue;
}
printResult(do_gtm_ping(aval(VAR_gtmProxyServers)[idx], atoi(aval(VAR_gtmProxyPorts)[idx])),
"gtm proxy",
actualNodeList[ii]);
}
}
static void monitor_coordinator_master(char** nodeList)
{
char** actualNodeList;
int ii;
int idx;
actualNodeList = makeActualNodeList(nodeList);
for (ii = 0; actualNodeList[ii]; ii++) {
if ((idx = coordIdx(actualNodeList[ii])) < 0) {
elog(ERROR, "ERROR: %s is not a coordinator\n", actualNodeList[ii]);
continue;
}
printResult(pingNode(aval(VAR_coordMasterServers)[idx], aval(VAR_coordPorts)[idx]),
"coordinator master",
actualNodeList[ii]);
}
}
static void monitor_coordinator_slave(char** nodeList)
{
char** actualNodeList;
int ii;
int idx;
if (!isVarYes(VAR_coordSlave)) {
elog(ERROR, "ERROR: coordinator slave is not configured.\n");
return;
}
actualNodeList = makeActualNodeList(nodeList);
for (ii = 0; actualNodeList[ii]; ii++) {
if ((idx = coordIdx(actualNodeList[ii])) < 0) {
elog(ERROR, "ERROR: %s is not a coordinator\n", actualNodeList[ii]);
continue;
}
/* Need to check again if the slave is configured */
if (!doesExist(VAR_coordSlaveServers, idx) || is_none(aval(VAR_coordSlaveServers)[idx]))
elog(ERROR, "ERROR: coordinator slave %s is not configured\n", actualNodeList[ii]);
else
printResult(pingNode(aval(VAR_coordSlaveServers)[idx], aval(VAR_coordPorts)[idx]),
"coordinator slave",
actualNodeList[ii]);
}
}
static void monitor_coordinator(char** nodeList)
{
char** actualNodeList;
int ii;
int idx;
actualNodeList = makeActualNodeList(nodeList);
for (ii = 0; actualNodeList[ii]; ii++) {
if ((idx = coordIdx(actualNodeList[ii])) < 0) {
elog(ERROR, "ERROR: %s is not a coordinator\n", actualNodeList[ii]);
continue;
}
printResult(pingNode(aval(VAR_coordMasterServers)[idx], aval(VAR_coordPorts)[idx]),
"coordinator master",
actualNodeList[ii]);
if (doesExist(VAR_coordSlaveServers, idx) && !is_none(aval(VAR_coordSlaveServers)[idx]))
printResult(pingNode(aval(VAR_coordSlaveServers)[idx], aval(VAR_coordPorts)[idx]),
"coordinatr slave",
actualNodeList[ii]);
}
}
static void monitor_datanode_master(char** nodeList)
{
char** actualNodeList;
int ii;
int idx;
actualNodeList = makeActualNodeList(nodeList);
for (ii = 0; actualNodeList[ii]; ii++) {
if ((idx = datanodeIdx(actualNodeList[ii])) < 0) {
elog(ERROR, "ERROR: %s is not a datanode\n", actualNodeList[ii]);
continue;
}
printResult(pingNode(aval(VAR_datanodeMasterServers)[idx], aval(VAR_datanodePorts)[idx]),
"datanode master",
actualNodeList[ii]);
}
}
static void monitor_datanode_slave(char** nodeList)
{
char** actualNodeList;
int ii;
int idx;
if (!isVarYes(VAR_datanodeSlave)) {
elog(ERROR, "ERROR: datanode slave is not configured.\n");
return;
}
actualNodeList = makeActualNodeList(nodeList);
for (ii = 0; actualNodeList[ii]; ii++) {
if ((idx = datanodeIdx(actualNodeList[ii])) < 0) {
elog(ERROR, "ERROR: %s is not a datanode\n", actualNodeList[ii]);
continue;
}
if (doesExist(VAR_datanodeSlaveServers, idx) && !is_none(aval(VAR_datanodeSlaveServers)[idx]))
printResult(pingNode(aval(VAR_datanodeSlaveServers)[idx], aval(VAR_datanodePorts)[idx]),
"datanode slave",
actualNodeList[ii]);
else
elog(ERROR, "ERROR: datanode slave %s is not configured.\n", actualNodeList[ii]);
}
}
static void monitor_datanode(char** nodeList)
{
char** actualNodeList;
int ii;
int idx;
actualNodeList = makeActualNodeList(nodeList);
for (ii = 0; actualNodeList[ii]; ii++) {
if ((idx = datanodeIdx(actualNodeList[ii])) < 0) {
elog(ERROR, "ERROR: %s is not a datanode\n", actualNodeList[ii]);
continue;
}
printResult(pingNode(aval(VAR_datanodeMasterServers)[idx], aval(VAR_datanodePorts)[idx]),
"datanode master",
actualNodeList[ii]);
if (doesExist(VAR_datanodeSlaveServers, idx) && !is_none(aval(VAR_datanodeSlaveServers)[idx]))
printResult(pingNode(aval(VAR_datanodeSlaveServers)[idx], aval(VAR_datanodePorts)[idx]),
"datanode slave",
actualNodeList[ii]);
}
}
static void monitor_something(char** nodeList)
{
char** actualNodeList;
int ii;
char* wkNodeList[2];
NodeType type;
wkNodeList[1] = NULL;
actualNodeList = makeActualNodeList(nodeList);
for (ii = 0; actualNodeList[ii]; ii++) {
if ((type = getNodeType(actualNodeList[ii])) == NodeType_GTM) {
monitor_gtm_master();
if (isVarYes(VAR_gtmSlave))
monitor_gtm_slave();
continue;
} else if (type == NodeType_GTM_PROXY) {
wkNodeList[0] = actualNodeList[ii];
monitor_gtm_proxy(wkNodeList);
continue;
} else if (type == NodeType_COORDINATOR) {
wkNodeList[0] = actualNodeList[ii];
monitor_coordinator(wkNodeList);
continue;
} else if (type == NodeType_DATANODE) {
wkNodeList[0] = actualNodeList[ii];
monitor_datanode(wkNodeList);
continue;
} else {
elog(ERROR, "ERROR: %s is not found in any node.\n", actualNodeList[ii]);
continue;
}
}
}
void do_monitor_command(char* line)
{
char* token = NULL;
int rc = 0;
if (!GetToken()) {
elog(ERROR, "ERROR: no monitor command options found.\n");
return;
}
if (TestToken("gtm")) {
if (!GetToken() || TestToken("all")) {
/* Ping GTM */
monitor_gtm_master();
if (isVarYes(VAR_gtmSlave))
monitor_gtm_slave();
} else if (TestToken("master"))
monitor_gtm_master();
else if (TestToken("slave")) {
if (isVarYes(VAR_gtmSlave))
monitor_gtm_slave();
else
elog(ERROR, "ERROR: gtm slave is not configured.\n"), rc = -1;
} else
elog(ERROR, "Invalid monitor gtm command option.\n"), rc = -1;
return;
} else if (TestToken("gtm_proxy")) {
if (!GetToken() || TestToken("all"))
monitor_gtm_proxy(aval(VAR_gtmProxyNames));
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
monitor_gtm_proxy(nodeList);
CleanArray(nodeList);
}
return;
} else if (TestToken("coordinator")) {
if (!GetToken() || TestToken("all")) {
monitor_coordinator_master(aval(VAR_coordNames));
if (isVarYes(VAR_coordSlave))
monitor_coordinator_slave(aval(VAR_coordNames));
return;
} else if (TestToken("master")) {
if (!GetToken() || TestToken("all"))
monitor_coordinator_master(aval(VAR_coordNames));
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
monitor_coordinator_master(nodeList);
CleanArray(nodeList);
}
} else if (TestToken("slave")) {
if (!isVarYes(VAR_coordSlave))
elog(ERROR, "ERROR: coordinator slave is not configured.\n"), rc = -1;
else if (!GetToken() || TestToken("all"))
monitor_coordinator_slave(aval(VAR_coordNames));
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
monitor_coordinator_slave(nodeList);
CleanArray(nodeList);
}
} else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
monitor_coordinator(nodeList);
CleanArray(nodeList);
}
} else if (TestToken("datanode")) {
if (!GetToken() || TestToken("all")) {
monitor_datanode_master(aval(VAR_datanodeNames));
if (isVarYes(VAR_coordSlave))
monitor_datanode_slave(aval(VAR_datanodeNames));
} else if (TestToken("master")) {
if (!GetToken() || TestToken("all"))
monitor_datanode_master(aval(VAR_datanodeNames));
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
monitor_datanode_master(nodeList);
CleanArray(nodeList);
}
} else if (TestToken("slave")) {
if (!isVarYes(VAR_coordSlave))
elog(ERROR, "ERROR: datanode slave is not configured.\n"), rc = -1;
else if (!GetToken() || TestToken("all"))
monitor_datanode_slave(aval(VAR_coordNames));
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
monitor_datanode_slave(nodeList);
CleanArray(nodeList);
}
} else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
monitor_datanode(nodeList);
CleanArray(nodeList);
}
} else if (TestToken("all")) {
monitor_gtm_master();
if (isVarYes(VAR_gtmSlave))
monitor_gtm_slave();
if (isVarYes(VAR_gtmProxy))
monitor_gtm_proxy(aval(VAR_gtmProxyNames));
monitor_coordinator(aval(VAR_coordNames));
monitor_datanode(aval(VAR_datanodeNames));
} else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
monitor_something(nodeList);
CleanArray(nodeList);
}
return;
}
/*
* Ping a given GTM or GTM-proxy
*/
int do_gtm_ping(char* host, int port)
{
char connect_str[MAXPATH + 1];
GTM_Conn* conn = NULL;
if (host == NULL) {
elog(ERROR, "ERROR: no hostname is specified.\n");
return -1;
}
if (port <= 0) {
elog(ERROR, "ERROR: Invalid port number, %d.\n", port);
return -1;
}
sprintf(connect_str,
"host=%s port=%d node_name=%s remote_type=%d postmaster=0",
host,
port,
myName,
GTM_NODE_COORDINATOR);
if ((conn = PQconnectGTM(connect_str)) == NULL) {
elog(DEBUG3, "DEBUG3: Could not connect to %s, %d\n", host, port);
return -1;
}
GTMPQfinish(conn);
return 0;
}