Feature: Add new PCP command to trigger log rotation
authorBo Peng <pengbo@sraoss.co.jp>
Mon, 5 Aug 2024 06:34:33 +0000 (15:34 +0900)
committerBo Peng <pengbo@sraoss.co.jp>
Mon, 5 Aug 2024 06:34:33 +0000 (15:34 +0900)
Currently the only way to trigger log rotation in logging collector process
is to send SIGUSR1 signal directly to logging collector process.
However, I think it would be nice to have a better way to do it with an external
tool (e.g. logrotate) without requiring knowledge of the logging collector's PID.

This commit adds a new PCP command "pcp_log_rotate" for triggering log rotation.

18 files changed:
doc.ja/src/sgml/ref/allfiles.sgml
doc.ja/src/sgml/ref/pcp_log_rotate.sgml [new file with mode: 0644]
doc.ja/src/sgml/reference.sgml
doc/src/sgml/ref/allfiles.sgml
doc/src/sgml/ref/pcp_log_rotate.sgml [new file with mode: 0644]
doc/src/sgml/reference.sgml
src/include/pcp/libpcp_ext.h
src/include/pool.h
src/include/watchdog/wd_ipc_defines.h
src/libs/pcp/pcp.c
src/main/pgpool_logger.c
src/main/pgpool_main.c
src/pcp_con/pcp_worker.c
src/test/regression/tests/038.pcp_commands/test.sh [new file with mode: 0755]
src/tools/pcp/.gitignore
src/tools/pcp/Makefile.am
src/tools/pcp/pcp_frontend_client.c
src/watchdog/watchdog.c

index 1af1c380dae1fe4b3d05f35989c0ff53b5ebb38b..69fbe1efe1f20ca1fcd794191e5caea88e1825a5 100644 (file)
@@ -18,6 +18,7 @@ Complete list of usable sgml source files in this directory.
 <!ENTITY pcpStopPgpool       SYSTEM "pcp_stop_pgpool.sgml">
 <!ENTITY pcpRecoveryNode     SYSTEM "pcp_recovery_node.sgml">
 <!ENTITY pcpReloadConfig     SYSTEM "pcp_reload_config.sgml">
+<!ENTITY pcpLogRotate        SYSTEM "pcp_log_rotate.sgml">
 <!ENTITY pgMd5               SYSTEM "pg_md5.sgml">
 <!ENTITY pgEnc               SYSTEM "pg_enc.sgml">
 <!ENTITY wdCli               SYSTEM "wd_cli.sgml">
diff --git a/doc.ja/src/sgml/ref/pcp_log_rotate.sgml b/doc.ja/src/sgml/ref/pcp_log_rotate.sgml
new file mode 100644 (file)
index 0000000..f49c922
--- /dev/null
@@ -0,0 +1,74 @@
+<!--
+doc/src/sgml/ref/pcp_reload_config.sgml
+Pgpool-II documentation
+-->
+
+<refentry id="PCP-LOG-ROTATE">
+ <indexterm zone="pcp-log-rotate">
+  <primary>pcp_log_rotate</primary>
+ </indexterm>
+
+ <refmeta>
+  <refentrytitle>pcp_log_rotate</refentrytitle>
+  <manvolnum>1</manvolnum>
+  <refmiscinfo>PCP Command</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+  <refname>pcp_log_rotate</refname>
+  <refpurpose>
+   Pgpool-IIのログファイルをローテーションします</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+  <cmdsynopsis>
+   <command>pcp_log_rotate</command>
+   <arg rep="repeat"><replaceable>options</replaceable></arg>
+  </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="R1-PCP-LOG-ROTATE-1">
+  <title>説明</title>
+  <para>
+   <command>pcp_log_rotate</command>
+   Pgpool-IIのログファイルをローテーションします。
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>オプション</title>
+  <para>
+   <variablelist>
+
+    <varlistentry>
+     <term><option>-s <replaceable class="parameter">scope</replaceable></option></term>
+     <term><option>--scope=<replaceable class="parameter">scope</replaceable></option></term>
+     <listitem>
+      <para>
+       コマンドの与える影響範囲を指定します。
+      </para>
+      <para>
+    サポートされているコマンドスコープは以下です。
+       デフォルトは"local"です。
+       <itemizedlist>
+       <listitem><para>c, cluster : クラスタを構成するすべてのPgpool-IIのログファイルをローテーションします。</para></listitem>
+       <listitem><para>l, local : ローカルPgpool-IIのログファイルをローテーションします。</para></listitem>
+       </itemizedlist>
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
+     <term><option>その他のオプション</option></term>
+     <listitem>
+      <para>
+       <xref linkend="pcp-common-options"> を参照してください。
+      </para>
+     </listitem>
+    </varlistentry>
+
+   </variablelist>
+  </para>
+ </refsect1>
+
+</refentry>
index 33c48db6c07556a91a09cf722898119b2deb4208..05e4d87b5ca72322763992cd18d67a4c8c7eff12 100644 (file)
   &pcpStopPgpool;
   &pcpReloadConfig;
   &pcpRecoveryNode;
+  &pcpLogRotate;
 
  </reference>
 
index aa55db096bd50c797bf99eda3943e129f434d8e7..69fbe1efe1f20ca1fcd794191e5caea88e1825a5 100644 (file)
@@ -17,7 +17,8 @@ Complete list of usable sgml source files in this directory.
 <!ENTITY pcpPromoteNode      SYSTEM "pcp_promote_node.sgml">
 <!ENTITY pcpStopPgpool       SYSTEM "pcp_stop_pgpool.sgml">
 <!ENTITY pcpRecoveryNode     SYSTEM "pcp_recovery_node.sgml">
-<!ENTITY pcpReloadConfig      SYSTEM "pcp_reload_config.sgml">
+<!ENTITY pcpReloadConfig     SYSTEM "pcp_reload_config.sgml">
+<!ENTITY pcpLogRotate        SYSTEM "pcp_log_rotate.sgml">
 <!ENTITY pgMd5               SYSTEM "pg_md5.sgml">
 <!ENTITY pgEnc               SYSTEM "pg_enc.sgml">
 <!ENTITY wdCli               SYSTEM "wd_cli.sgml">
diff --git a/doc/src/sgml/ref/pcp_log_rotate.sgml b/doc/src/sgml/ref/pcp_log_rotate.sgml
new file mode 100644 (file)
index 0000000..be1ecbe
--- /dev/null
@@ -0,0 +1,73 @@
+<!--
+doc/src/sgml/ref/pcp_logrotate_pgpool.sgml
+Pgpool-II documentation
+-->
+
+<refentry id="PCP-LOG-ROTATE">
+ <indexterm zone="pcp-log-rotate">
+  <primary>pcp_log_rotate</primary>
+ </indexterm>
+
+ <refmeta>
+  <refentrytitle>pcp_log_rotate</refentrytitle>
+  <manvolnum>1</manvolnum>
+  <refmiscinfo>PCP Command</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+  <refname>pcp_log_rotate</refname>
+  <refpurpose>
+   rotates the Pgpool-II's log file</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+  <cmdsynopsis>
+   <command>pcp_log_rotate</command>
+   <arg rep="repeat"><replaceable>options</replaceable></arg>
+  </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="R1-PCP-LOG-ROTATE-1">
+  <title>Description</title>
+  <para>
+   <command>pcp_log_rotate</command>
+   rotates the Pgpool-II's log file.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Options</title>
+  <para>
+   <variablelist>
+
+    <varlistentry>
+     <term><option>-s <replaceable class="parameter">scope</replaceable></option></term>
+     <term><option>--scope=<replaceable class="parameter">scope</replaceable></option></term>
+     <listitem>
+      <para>
+       Specifies the breadth of a command's impact.
+      </para>
+      <para>
+       The supported command scopes are as follows (The default is "local"):
+       <itemizedlist>
+       <listitem><para>c, cluster : rotates the Pgpool-II's log files of all Pgpool-II nodes part of the cluster </para></listitem>
+       <listitem><para>l, local : rotates the Pgpool-II's log file of local Pgpool-II node only </para></listitem>
+       </itemizedlist>
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
+     <term><option>Other options </option></term>
+     <listitem>
+      <para>
+       See <xref linkend="pcp-common-options">.
+      </para>
+     </listitem>
+    </varlistentry>
+
+   </variablelist>
+  </para>
+ </refsect1>
+
+</refentry>
index 51f2d893dc4e6bc08b4c56f09f74e76779cdd272..30be90bc5522446bb01a8993857f36f30b28b6a3 100644 (file)
   &pcpStopPgpool;
   &pcpReloadConfig;
   &pcpRecoveryNode;
+  &pcpLogRotate;
 
  </reference>
 
index 3c9d1d6bb9b247e7e643430a7194675699024dc8..32dfcb0033790f3ab521efd0bf0936b45e752cff 100644 (file)
@@ -381,6 +381,7 @@ extern PCPResultInfo * pcp_health_check_stats(PCPConnInfo * pcpCon, int nid);
 extern PCPResultInfo * pcp_process_count(PCPConnInfo * pcpConn);
 extern PCPResultInfo * pcp_process_info(PCPConnInfo * pcpConn, int pid);
 extern PCPResultInfo * pcp_reload_config(PCPConnInfo * pcpConn,char command_scope);
+extern PCPResultInfo * pcp_log_rotate(PCPConnInfo * pcpConn,char command_scope);
 
 extern PCPResultInfo * pcp_detach_node(PCPConnInfo * pcpConn, int nid);
 extern PCPResultInfo * pcp_detach_node_gracefully(PCPConnInfo * pcpConn, int nid);
index 21513f1d33a9ab3cc5b46d4f82cfc3ed9491fabd..8fa429fa70bf1eb6ec81c0e536df2b901e187863 100644 (file)
@@ -619,7 +619,7 @@ extern void initialize_shared_memory_main_segment(size_t size);
 extern void * pool_shared_memory_segment_get_chunk(size_t size);
 
 
-/* pool_main.c*/
+/* pgpool_main.c*/
 extern BackendInfo * pool_get_node_info(int node_number);
 extern int     pool_get_node_count(void);
 extern int *pool_get_process_list(int *array_size);
@@ -636,6 +636,7 @@ extern void pool_set_backend_status_changed_time(int backend_id);
 extern int     get_next_main_node(void);
 extern bool pool_acquire_follow_primary_lock(bool block, bool remote_reques);
 extern void pool_release_follow_primary_lock(bool remote_reques);
+extern void pool_signal_logrotate(void);
 
 /* strlcpy.c */
 #ifndef HAVE_STRLCPY
index 16ff5a4158ec9722958e05b47744201ce867fbc0..654f48715c013eb8d9ba9953c299c9b99e91ce9a 100644 (file)
@@ -75,6 +75,7 @@ typedef enum WDValueDataType
 #define WD_COMMAND_REELECT_LEADER              "REELECT_LEADER"
 #define WD_COMMAND_SHUTDOWN_CLUSTER    "SHUTDOWN_CLUSTER"
 #define WD_COMMAND_RELOAD_CONFIG_CLUSTER               "RELOAD_CONFIG_CLUSTER"
+#define WD_COMMAND_LOGROTATE_CLUSTER           "LOGROTATE_CLUSTER"
 #define WD_COMMAND_LOCK_ON_STANDBY             "APPLY_LOCK_ON_STANDBY"
 
 
index 0a2b74a881b9266fb3892aca1997fa7ef1cac299..8b4b569d46c6e1944e44f6fbb791ed83e9f425da 100644 (file)
@@ -476,6 +476,13 @@ static PCPResultInfo * process_pcp_response(PCPConnInfo * pcpConn, char sentMsg)
                                        process_command_complete_response(pcpConn, buf, rsize);
                                break;
 
+                       case 'v':                       /* pcp_log_rotate */
+                               if (sentMsg != 'V')
+                                       setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
+                               else
+                                       process_command_complete_response(pcpConn, buf, rsize);
+                               break;
+
                        case 'w':
                                if (sentMsg != 'W')
                                        setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
@@ -926,6 +933,31 @@ pcp_reload_config(PCPConnInfo * pcpConn,char command_scope)
        return process_pcp_response(pcpConn, 'Z');
 }
 
+PCPResultInfo *
+pcp_log_rotate(PCPConnInfo * pcpConn,char command_scope)
+{
+       int                     wsize;
+/*
+ * pcp packet format for pcp_log_rotate
+ * v[size][command_scope]
+ */
+       if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK)
+       {
+          pcp_internal_error(pcpConn, "invalid PCP connection");
+          return NULL;
+       }
+
+       pcp_write(pcpConn->pcpConn, "V", 1);
+       wsize = htonl(sizeof(int) + sizeof(char));
+       pcp_write(pcpConn->pcpConn, &wsize, sizeof(int));
+       pcp_write(pcpConn->pcpConn, &command_scope, sizeof(char));
+       if (PCPFlush(pcpConn) < 0)
+          return NULL;
+       if (pcpConn->Pfdebug)
+          fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"Z\", len=%d\n", ntohl(wsize));
+
+       return process_pcp_response(pcpConn, 'V');
+}
 
 /*
  * Process health check response from PCP server.
index 68621b30aaddaef027169caa9108877c38514ae7..2060867322a0105103161e72c71d98e8886a4961 100644 (file)
@@ -345,7 +345,7 @@ SysLoggerMain(int argc, char *argv[])
                {
                        /*
                         * Force rotation when both values are zero. It means the request
-                        * was sent by pg_rotate_logfile() or "pg_ctl logrotate".
+                        * was sent by pcp_log_rotate.
                         */
                        if (!time_based_rotation && size_rotation_for == 0)
                                size_rotation_for = LOG_DESTINATION_STDERR | LOG_DESTINATION_CSVLOG;
index 02086372735b13db92d029b2729473bfe6aea6fb..20b89b150aaa19601c55036fcbbcd8f3dd8b23a8 100644 (file)
@@ -4097,6 +4097,37 @@ pool_release_follow_primary_lock(bool remote_request)
 
 }
 
+/*
+ * Sending log rotation signal to logger process.
+ */
+void
+pool_signal_logrotate(void)
+{
+       if (!pool_config->logging_collector)
+       {
+               ereport(ERROR,
+                               (errmsg("process log rotation request failed"),
+                                errdetail("logging_collector is disabled")));
+       }
+
+       if (pgpool_logger_pid != 0)
+       {
+               ereport(DEBUG1,
+                               (errmsg("sending SIGUSR1 to logger process with PID:%d to rotate log file", pgpool_logger_pid)));
+
+               if (kill(pgpool_logger_pid, SIGUSR1) != 0)
+                       ereport(ERROR,
+                                       (errmsg("process log rotation request failed"),
+                                        errdetail("failed to send SIGUSR1 to logger process with PID:%d", pgpool_logger_pid)));
+       }
+       else
+       {
+               ereport(ERROR,
+                               (errmsg("process log rotation request failed"),
+                                errdetail("logger process PID:%d is not valid", pgpool_logger_pid)));
+       }
+}
+
 /*
  * -------------------------------------------------------------------------
  * Subroutines for failover() begin
index 482941215a9b57e62098d299d2e2ad9782dfadf9..02f76eecb60ad62363ee3a220a99e5f3b2357654 100644 (file)
@@ -84,6 +84,7 @@ static void inform_watchdog_info(PCP_CONNECTION * frontend, char *buf);
 static void inform_node_info(PCP_CONNECTION * frontend, char *buf);
 static void inform_node_count(PCP_CONNECTION * frontend);
 static void process_reload_config(PCP_CONNECTION * frontend,char scope);
+static void process_log_rotate(PCP_CONNECTION * frontend,char scope);
 static void inform_health_check_stats(PCP_CONNECTION *frontend, char *buf);
 static void process_detach_node(PCP_CONNECTION * frontend, char *buf, char tos);
 static void process_attach_node(PCP_CONNECTION * frontend, char *buf);
@@ -329,6 +330,11 @@ pcp_process_command(char tos, char *buf, int buf_len)
                        process_reload_config(pcp_frontend, buf[0]);
                        break;
 
+               case 'V':                               /* log rotate */
+                       set_ps_display("PCP: processing log rotation request", false);
+                       process_log_rotate(pcp_frontend, buf[0]);
+                       break;
+
                case 'J':                               /* promote node */
                case 'j':                               /* promote node gracefully */
                        set_ps_display("PCP: processing promote node request", false);
@@ -1074,6 +1080,7 @@ inform_node_count(PCP_CONNECTION * frontend)
                        (errmsg("PCP: informing node count"),
                         errdetail("%d node(s) found", node_count)));
 }
+
 static void
 process_reload_config(PCP_CONNECTION * frontend, char scope)
 {
@@ -1105,6 +1112,32 @@ process_reload_config(PCP_CONNECTION * frontend, char scope)
        do_pcp_flush(frontend);
 }
 
+static void
+process_log_rotate(PCP_CONNECTION * frontend, char scope)
+{
+       char            code[] = "CommandComplete";
+       int wsize;
+
+       if (scope == 'c' && pool_config->use_watchdog)
+       {
+               ereport(LOG,
+                               (errmsg("PCP: sending command to watchdog to logrotate cluster")));
+
+               if (wd_execute_cluster_command(WD_COMMAND_LOGROTATE_CLUSTER, NULL) != COMMAND_OK)
+                       ereport(ERROR,
+                                       (errmsg("PCP: error while processing log rotation request for cluster"),
+                                        errdetail("failed to propagate log rotation command through watchdog")));
+       }
+
+       pool_signal_logrotate();
+
+       pcp_write(frontend, "v", 1);
+       wsize = htonl(sizeof(code) + sizeof(int));
+       pcp_write(frontend, &wsize, sizeof(int));
+       pcp_write(frontend, code, sizeof(code));
+       do_pcp_flush(frontend);
+}
+
 static void
 process_detach_node(PCP_CONNECTION * frontend, char *buf, char tos)
 {
diff --git a/src/test/regression/tests/038.pcp_commands/test.sh b/src/test/regression/tests/038.pcp_commands/test.sh
new file mode 100755 (executable)
index 0000000..5b6e7b1
--- /dev/null
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+#-------------------------------------------------------------------
+# Test script for pcp commands.
+#
+source $TESTLIBS
+TESTDIR=testdir
+PSQL=$PGBIN/psql
+
+rm -fr $TESTDIR
+mkdir $TESTDIR
+cd $TESTDIR
+
+# create test environment.
+echo -n "creating test environment..."
+$PGPOOL_SETUP -m s -n 2 || exit 1
+echo "done."
+
+source ./bashrc.ports
+export PGPORT=$PGPOOL_PORT
+
+echo "=== test1: pcp_log_rotate"
+
+BASEDIR=`pwd`
+echo "logging_collector = on" >> etc/pgpool.conf
+echo "log_directory = '$BASEDIR/log'" >> etc/pgpool.conf
+echo "log_filename = 'pgpool.log'" >> etc/pgpool.conf
+
+./startall
+wait_for_pgpool_startup
+
+mv log/pgpool.log log/pgpool.log.1
+
+sleep 1
+$PSQL -h localhost -c "SELECT 1" test > /dev/null 2>&1
+
+grep "SELECT 1" log/pgpool.log.1 > /dev/null 2>&1
+if [ $? != 0 ];then
+    r1=fail
+    echo "test1 failed before running pcp_log_rotate."
+else
+    $PGPOOL_INSTALL_DIR/bin/pcp_log_rotate -h localhost -w -p $PCP_PORT
+    $PSQL -h localhost -c "SELECT 1" test > /dev/null 2>&1
+
+    sleep 1
+    grep "SELECT 1" log/pgpool.log > /dev/null 2>&1
+    if [ $? = 0 ];then
+        r1=ok
+        echo "test1 ok"
+    else
+        echo "test1 failed."
+    fi
+fi
+
+./shutdownall
+
+if [ $r1 = ok ]; then
+    echo "all test succeeded"
+    exit 0
+else
+    echo "some tests failed"
+    echo "test1: $r1"
+    exit 1
+fi
index ec13595f3f4b226fcb81ef8744ef6d22d753fb43..ff2c7cce44b809da71236f619bd4877f3e4e589c 100644 (file)
@@ -1,6 +1,7 @@
 pcp_attach_node
 pcp_detach_node
 pcp_health_check_stats
+pcp_log_rotate
 pcp_node_count
 pcp_node_info
 pcp_pool_status
index a0942f4898ba5c5a059cc5257283f62810547e3f..53152f34c0446e6fa0f24776bf1616aace0c7927 100644 (file)
@@ -12,8 +12,9 @@ bin_PROGRAMS =  pcp_stop_pgpool \
                                pcp_recovery_node \
                                pcp_promote_node \
                                pcp_pool_status \
-                               pcp_watchdog_info\
-                               pcp_reload_config
+                               pcp_watchdog_info \
+                               pcp_reload_config \
+                               pcp_log_rotate
 
 client_sources = pcp_frontend_client.c ../fe_memutils.c ../../utils/sprompt.c ../../utils/pool_path.c
 
@@ -43,4 +44,5 @@ pcp_watchdog_info_SOURCES = $(client_sources)
 pcp_watchdog_info_LDADD = $(libs_dir)/pcp/libpcp.la
 pcp_reload_config_SOURCES = $(client_sources)
 pcp_reload_config_LDADD = $(libs_dir)/pcp/libpcp.la
-
+pcp_log_rotate_SOURCES = $(client_sources)
+pcp_log_rotate_LDADD = $(libs_dir)/pcp/libpcp.la
index 576bd8ce13aae180a2bba94d90dee62d9420de1e..930e2a811f02d013f980f26b2d708f7255f47c9d 100644 (file)
@@ -69,6 +69,7 @@ typedef enum
        PCP_STOP_PGPOOL,
        PCP_WATCHDOG_INFO,
        PCP_RELOAD_CONFIG,
+       PCP_LOG_ROTATE,
        UNKNOWN,
 }                      PCP_UTILITIES;
 
@@ -95,6 +96,7 @@ struct AppTypes AllAppTypes[] =
        {"pcp_stop_pgpool", PCP_STOP_PGPOOL, "m:h:p:U:s:wWvda", "terminate pgpool-II"},
        {"pcp_watchdog_info", PCP_WATCHDOG_INFO, "n:h:p:U:wWvd", "display a pgpool-II watchdog's information"},
        {"pcp_reload_config",PCP_RELOAD_CONFIG,"h:p:U:s:wWvd", "reload a pgpool-II config file"},
+       {"pcp_log_rotate",PCP_LOG_ROTATE,"h:p:U:s:wWvd", "rotate the Pgpool-II's log file"},
        {NULL, UNKNOWN, NULL, NULL},
 };
 struct AppTypes *current_app_type;
@@ -451,6 +453,11 @@ main(int argc, char **argv)
                pcpResInfo = pcp_reload_config(pcpConn,command_scope);
        }
 
+       else if (current_app_type->app_type == PCP_LOG_ROTATE)
+       {
+               pcpResInfo = pcp_log_rotate(pcpConn,command_scope);
+       }
+
        else
        {
                /* should never happen */
@@ -861,7 +868,8 @@ static inline bool
 app_support_cluster_mode(void)
 {
        return (current_app_type->app_type == PCP_STOP_PGPOOL ||
-                       current_app_type->app_type == PCP_RELOAD_CONFIG);
+                       current_app_type->app_type == PCP_RELOAD_CONFIG ||
+                       current_app_type->app_type == PCP_LOG_ROTATE);
 }
 
 static void
index 561d9a60fdd3331ab79773906dd62ffb3b2f2789..41b53d26da5346190d3948609e82ec80196e23d6 100644 (file)
@@ -2111,6 +2111,11 @@ process_IPC_execute_cluster_command(WDCommandData * ipcCommand)
                ereport(LOG,
                                (errmsg("Watchdog has received reload config cluster command from IPC channel")));
        }
+       else if (strcasecmp(WD_COMMAND_LOGROTATE_CLUSTER, clusterCommand) == 0)
+       {
+               ereport(LOG,
+                               (errmsg("Watchdog has received log rotation cluster command from IPC channel")));
+       }
        else if (strcasecmp(WD_COMMAND_LOCK_ON_STANDBY, clusterCommand) == 0)
        {
                ereport(LOG,
@@ -4115,6 +4120,12 @@ wd_execute_cluster_command_processor(WatchdogNode * wdNode, WDPacketData * pkt)
                                (errmsg("processing reload config command from remote node \"%s\"", wdNode->nodeName)));
                pool_signal_parent(SIGHUP);
        }
+       else if (strcasecmp(WD_COMMAND_LOGROTATE_CLUSTER, clusterCommand) == 0)
+       {
+               ereport(LOG,
+                               (errmsg("processing log rotation command from remote node \"%s\"", wdNode->nodeName)));
+               pool_signal_logrotate();
+       }
        else if (strcasecmp(WD_COMMAND_LOCK_ON_STANDBY, clusterCommand) == 0)
        {
                int lock_type = -1;