On 25.03.26 09:25, Amit Kapila wrote:
On Wed, Mar 25, 2026 at 5:43 AM Gyan Sreejith <[email protected]> wrote:

Thank you, Kuroda-san and Chao for the suggestions and the patch. I have merged 
it with v18-0001, and I have fixed everything that Peter suggested.


Pushed after minor changes.

Instead of creating a new logging API in pg_createsubscriber locally, why not extend logging.c to support a log file. This is much simpler, doesn't require caller changes, and could be reused elsewhere. See attached patches. (The 0003 and 0004 are just some additional code simplifications.)
From 6a4ddd24b8a07f6d324e7bfcd415ca0e9295a45d Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Tue, 31 Mar 2026 14:01:15 +0200
Subject: [PATCH v20 1/4] Add log file support to logging.c

This adds the ability for users of logging.c to provide a file handle
for a log file, where log messages are also written in addition to
stderr.
---
 src/common/logging.c         | 27 +++++++++++++++++++++++++++
 src/include/common/logging.h |  2 ++
 2 files changed, 29 insertions(+)

diff --git a/src/common/logging.c b/src/common/logging.c
index 5206949e5d8..4a69d96281b 100644
--- a/src/common/logging.c
+++ b/src/common/logging.c
@@ -26,6 +26,8 @@ static int    log_flags;
 static void (*log_pre_callback) (void);
 static void (*log_locus_callback) (const char **, uint64 *);
 
+static FILE *log_logfile;
+
 static const char *sgr_error = NULL;
 static const char *sgr_warning = NULL;
 static const char *sgr_note = NULL;
@@ -204,6 +206,18 @@ pg_logging_set_locus_callback(void (*cb) (const char 
**filename, uint64 *lineno)
        log_locus_callback = cb;
 }
 
+void
+pg_logging_set_logfile(FILE *logfile)
+{
+       log_logfile = logfile;
+}
+
+void
+pg_logging_unset_logfile(void)
+{
+       log_logfile = NULL;
+}
+
 void
 pg_log_generic(enum pg_log_level level, enum pg_log_part part,
                           const char *pg_restrict fmt,...)
@@ -277,6 +291,8 @@ pg_log_generic_v(enum pg_log_level level, enum pg_log_part 
part,
                                                if (sgr_error)
                                                        fprintf(stderr, 
ANSI_ESCAPE_FMT, sgr_error);
                                                fprintf(stderr, _("error: "));
+                                               if (log_logfile)
+                                                       fprintf(log_logfile, 
_("error: "));
                                                if (sgr_error)
                                                        fprintf(stderr, 
ANSI_ESCAPE_RESET);
                                                break;
@@ -284,6 +300,8 @@ pg_log_generic_v(enum pg_log_level level, enum pg_log_part 
part,
                                                if (sgr_warning)
                                                        fprintf(stderr, 
ANSI_ESCAPE_FMT, sgr_warning);
                                                fprintf(stderr, _("warning: "));
+                                               if (log_logfile)
+                                                       fprintf(log_logfile, 
_("warning: "));
                                                if (sgr_warning)
                                                        fprintf(stderr, 
ANSI_ESCAPE_RESET);
                                                break;
@@ -295,6 +313,8 @@ pg_log_generic_v(enum pg_log_level level, enum pg_log_part 
part,
                                if (sgr_note)
                                        fprintf(stderr, ANSI_ESCAPE_FMT, 
sgr_note);
                                fprintf(stderr, _("detail: "));
+                               if (log_logfile)
+                                       fprintf(log_logfile, _("detail: "));
                                if (sgr_note)
                                        fprintf(stderr, ANSI_ESCAPE_RESET);
                                break;
@@ -302,6 +322,8 @@ pg_log_generic_v(enum pg_log_level level, enum pg_log_part 
part,
                                if (sgr_note)
                                        fprintf(stderr, ANSI_ESCAPE_FMT, 
sgr_note);
                                fprintf(stderr, _("hint: "));
+                               if (log_logfile)
+                                       fprintf(log_logfile, _("hint: "));
                                if (sgr_note)
                                        fprintf(stderr, ANSI_ESCAPE_RESET);
                                break;
@@ -332,6 +354,11 @@ pg_log_generic_v(enum pg_log_level level, enum pg_log_part 
part,
                buf[required_len - 2] = '\0';
 
        fprintf(stderr, "%s\n", buf);
+       if (log_logfile)
+       {
+               fprintf(log_logfile, "%s\n", buf);
+               fflush(log_logfile);
+       }
 
        free(buf);
 }
diff --git a/src/include/common/logging.h b/src/include/common/logging.h
index bccba4ac07b..06c202dbe2d 100644
--- a/src/include/common/logging.h
+++ b/src/include/common/logging.h
@@ -91,6 +91,8 @@ void          pg_logging_set_level(enum pg_log_level 
new_level);
 void           pg_logging_increase_verbosity(void);
 void           pg_logging_set_pre_callback(void (*cb) (void));
 void           pg_logging_set_locus_callback(void (*cb) (const char 
**filename, uint64 *lineno));
+void           pg_logging_set_logfile(FILE *logfile);
+void           pg_logging_unset_logfile(void);
 
 void           pg_log_generic(enum pg_log_level level, enum pg_log_part part,
                                                   const char *pg_restrict 
fmt,...)
-- 
2.53.0

From 8e47dcc5fc8fafa5110db7d15c853d71c123a346 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Tue, 31 Mar 2026 14:01:32 +0200
Subject: [PATCH v20 2/4] pg_createsubscriber: Use logging.c log file callback

This reverts commit 6b5b7eae3ae, where a new logging API layer was
introduced locally in pg_createsubscriber.  Instead, use the log file
callback introduced in logging.c.  This new approach is simpler and
doesn't require any caller changes.

Discussion: 
https://postgr.es/m/caeqnbauthoqarv1dscgvb_esqc-yfxim6rwkvdhc+g+f4os...@mail.gmail.com
---
 src/bin/pg_basebackup/pg_createsubscriber.c | 832 +++++++-------------
 1 file changed, 279 insertions(+), 553 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c 
b/src/bin/pg_basebackup/pg_createsubscriber.c
index 37631f700af..5c5fa2a7633 100644
--- a/src/bin/pg_basebackup/pg_createsubscriber.c
+++ b/src/bin/pg_basebackup/pg_createsubscriber.c
@@ -151,18 +151,6 @@ static void drop_existing_subscription(PGconn *conn, const 
char *subname,
                                                                           
const char *dbname);
 static void get_publisher_databases(struct CreateSubscriberOptions *opt,
                                                                        bool 
dbnamespecified);
-static void report_createsub_log(enum pg_log_level, enum pg_log_part,
-                                                                const char 
*pg_restrict fmt,...)
-                       pg_attribute_printf(3, 4);
-static void report_createsub_log_v(enum pg_log_level level, enum pg_log_part 
part,
-                                                                  const char 
*pg_restrict fmt, va_list args)
-                       pg_attribute_printf(3, 0);
-pg_noreturn static void report_createsub_fatal(const char *pg_restrict fmt,...)
-                       pg_attribute_printf(1, 2);
-static void internal_log_file_write(enum pg_log_level level,
-                                                                       enum 
pg_log_part part,
-                                                                       const 
char *pg_restrict fmt, va_list args)
-                       pg_attribute_printf(3, 0);
 
 #define        WAIT_INTERVAL   1               /* 1 second */
 
@@ -184,7 +172,6 @@ static pg_prng_state prng_state;
 static char *pg_ctl_path = NULL;
 static char *pg_resetwal_path = NULL;
 
-static FILE *internal_log_file_fp = NULL;      /* File ptr to log all messages 
to */
 static char logdir[MAXPGPATH]; /* Subdirectory of the user specified logdir
                                                                 * where the 
log files are written (if
                                                                 * specified) */
@@ -196,61 +183,6 @@ static bool recovery_ended = false;
 static bool standby_running = false;
 static bool recovery_params_set = false;
 
-/*
- * Report a message with a given log level.
- *
- * Writes to stderr, and also to the log file, if --logdir option was
- * specified.
- */
-static void
-report_createsub_log_v(enum pg_log_level level, enum pg_log_part part,
-                                          const char *pg_restrict fmt, va_list 
args)
-{
-       int                     save_errno = errno;
-
-       if (internal_log_file_fp != NULL)
-       {
-               /* Output to both stderr and the log file */
-               va_list         arg_cpy;
-
-               va_copy(arg_cpy, args);
-               internal_log_file_write(level, part, fmt, arg_cpy);
-               va_end(arg_cpy);
-               /* Restore errno in case internal_log_file_write changed it */
-               errno = save_errno;
-       }
-       pg_log_generic_v(level, part, fmt, args);
-}
-
-static void
-report_createsub_log(enum pg_log_level level, enum pg_log_part part,
-                                        const char *pg_restrict fmt,...)
-{
-       va_list         args;
-
-       va_start(args, fmt);
-
-       report_createsub_log_v(level, part, fmt, args);
-
-       va_end(args);
-}
-
-/*
- * Report a fatal error and exit
- */
-static void
-report_createsub_fatal(const char *pg_restrict fmt,...)
-{
-       va_list         args;
-
-       va_start(args, fmt);
-
-       report_createsub_log_v(PG_LOG_ERROR, PG_LOG_PRIMARY, fmt, args);
-
-       va_end(args);
-
-       exit(1);
-}
 
 /*
  * Clean up objects created by pg_createsubscriber.
@@ -282,8 +214,7 @@ cleanup_objects_atexit(void)
                if (durable_rename(conf_filename, conf_filename_disabled) != 0)
                {
                        /* durable_rename() has already logged something. */
-                       report_createsub_log(PG_LOG_WARNING, PG_LOG_HINT,
-                                                                "A manual 
removal of the recovery parameters may be required.");
+                       pg_log_warning_hint("A manual removal of the recovery 
parameters may be required.");
                }
        }
 
@@ -297,11 +228,9 @@ cleanup_objects_atexit(void)
         */
        if (recovery_ended)
        {
-               report_createsub_log(PG_LOG_WARNING, PG_LOG_PRIMARY,
-                                                        "failed after the end 
of recovery");
-               report_createsub_log(PG_LOG_WARNING, PG_LOG_HINT,
-                                                        "The target server 
cannot be used as a physical replica anymore.  "
-                                                        "You must recreate the 
physical replica before continuing.");
+               pg_log_warning("failed after the end of recovery");
+               pg_log_warning_hint("The target server cannot be used as a 
physical replica anymore.  "
+                                                       "You must recreate the 
physical replica before continuing.");
        }
 
        for (int i = 0; i < num_dbs; i++)
@@ -331,21 +260,17 @@ cleanup_objects_atexit(void)
                                 */
                                if (dbinfo->made_publication)
                                {
-                                       report_createsub_log(PG_LOG_WARNING, 
PG_LOG_PRIMARY,
-                                                                               
 "publication \"%s\" created in database \"%s\" on primary was left behind",
-                                                                               
 dbinfo->pubname,
-                                                                               
 dbinfo->dbname);
-                                       report_createsub_log(PG_LOG_WARNING, 
PG_LOG_HINT,
-                                                                               
 "Drop this publication before trying again.");
+                                       pg_log_warning("publication \"%s\" 
created in database \"%s\" on primary was left behind",
+                                                                  
dbinfo->pubname,
+                                                                  
dbinfo->dbname);
+                                       pg_log_warning_hint("Drop this 
publication before trying again.");
                                }
                                if (dbinfo->made_replslot)
                                {
-                                       report_createsub_log(PG_LOG_WARNING, 
PG_LOG_PRIMARY,
-                                                                               
 "replication slot \"%s\" created in database \"%s\" on primary was left 
behind",
-                                                                               
 dbinfo->replslotname,
-                                                                               
 dbinfo->dbname);
-                                       report_createsub_log(PG_LOG_WARNING, 
PG_LOG_HINT,
-                                                                               
 "Drop this replication slot soon to avoid retention of WAL files.");
+                                       pg_log_warning("replication slot \"%s\" 
created in database \"%s\" on primary was left behind",
+                                                                  
dbinfo->replslotname,
+                                                                  
dbinfo->dbname);
+                                       pg_log_warning_hint("Drop this 
replication slot soon to avoid retention of WAL files.");
                                }
                        }
                }
@@ -427,8 +352,7 @@ get_base_conninfo(const char *conninfo, char **dbname)
        conn_opts = PQconninfoParse(conninfo, &errmsg);
        if (conn_opts == NULL)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not parse 
connection string: %s", errmsg);
+               pg_log_error("could not parse connection string: %s", errmsg);
                PQfreemem(errmsg);
                return NULL;
        }
@@ -505,15 +429,14 @@ get_exec_path(const char *argv0, const char *progname)
                        strlcpy(full_path, progname, sizeof(full_path));
 
                if (ret == -1)
-                       report_createsub_fatal("program \"%s\" is needed by %s 
but was not found in the same directory as \"%s\"",
-                                                                  progname, 
"pg_createsubscriber", full_path);
+                       pg_fatal("program \"%s\" is needed by %s but was not 
found in the same directory as \"%s\"",
+                                        progname, "pg_createsubscriber", 
full_path);
                else
-                       report_createsub_fatal("program \"%s\" was found by 
\"%s\" but was not the same version as %s",
-                                                                  progname, 
full_path, "pg_createsubscriber");
+                       pg_fatal("program \"%s\" was found by \"%s\" but was 
not the same version as %s",
+                                        progname, full_path, 
"pg_createsubscriber");
        }
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "%s path is:  %s", progname, 
exec_path);
+       pg_log_debug("%s path is:  %s", progname, exec_path);
 
        return exec_path;
 }
@@ -530,16 +453,15 @@ check_data_directory(const char *datadir)
        uint32          major_version;
        char       *version_str;
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "checking if directory \"%s\" 
is a cluster data directory",
-                                                datadir);
+       pg_log_info("checking if directory \"%s\" is a cluster data directory",
+                               datadir);
 
        if (stat(datadir, &statbuf) != 0)
        {
                if (errno == ENOENT)
-                       report_createsub_fatal("data directory \"%s\" does not 
exist", datadir);
+                       pg_fatal("data directory \"%s\" does not exist", 
datadir);
                else
-                       report_createsub_fatal("could not access directory 
\"%s\": %m", datadir);
+                       pg_fatal("could not access directory \"%s\": %m", 
datadir);
        }
 
        /*
@@ -550,11 +472,9 @@ check_data_directory(const char *datadir)
        major_version = GET_PG_MAJORVERSION_NUM(get_pg_version(datadir, 
&version_str));
        if (major_version != PG_MAJORVERSION_NUM)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "data directory is of 
wrong version");
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_DETAIL,
-                                                        "File \"%s\" contains 
\"%s\", which is not compatible with this program's version \"%s\".",
-                                                        "PG_VERSION", 
version_str, PG_MAJORVERSION);
+               pg_log_error("data directory is of wrong version");
+               pg_log_error_detail("File \"%s\" contains \"%s\", which is not 
compatible with this program's version \"%s\".",
+                                                       "PG_VERSION", 
version_str, PG_MAJORVERSION);
                exit(1);
        }
 }
@@ -637,16 +557,14 @@ store_pub_sub_info(const struct CreateSubscriberOptions 
*opt,
                        dbinfo[i].subname = NULL;
                /* Other fields will be filled later */
 
-               report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                        "publisher(%d): 
publication: %s ; replication slot: %s ; connection string: %s", i,
-                                                        dbinfo[i].pubname ? 
dbinfo[i].pubname : "(auto)",
-                                                        dbinfo[i].replslotname 
? dbinfo[i].replslotname : "(auto)",
-                                                        dbinfo[i].pubconninfo);
-               report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                        "subscriber(%d): 
subscription: %s ; connection string: %s, two_phase: %s", i,
-                                                        dbinfo[i].subname ? 
dbinfo[i].subname : "(auto)",
-                                                        dbinfo[i].subconninfo,
-                                                        dbinfos.two_phase ? 
"true" : "false");
+               pg_log_debug("publisher(%d): publication: %s ; replication 
slot: %s ; connection string: %s", i,
+                                        dbinfo[i].pubname ? dbinfo[i].pubname 
: "(auto)",
+                                        dbinfo[i].replslotname ? 
dbinfo[i].replslotname : "(auto)",
+                                        dbinfo[i].pubconninfo);
+               pg_log_debug("subscriber(%d): subscription: %s ; connection 
string: %s, two_phase: %s", i,
+                                        dbinfo[i].subname ? dbinfo[i].subname 
: "(auto)",
+                                        dbinfo[i].subconninfo,
+                                        dbinfos.two_phase ? "true" : "false");
 
                if (num_pubs > 0)
                        pubcell = pubcell->next;
@@ -674,9 +592,8 @@ connect_database(const char *conninfo, bool exit_on_error)
        conn = PQconnectdb(conninfo);
        if (PQstatus(conn) != CONNECTION_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "connection to 
database failed: %s",
-                                                        PQerrorMessage(conn));
+               pg_log_error("connection to database failed: %s",
+                                        PQerrorMessage(conn));
                PQfinish(conn);
 
                if (exit_on_error)
@@ -688,9 +605,8 @@ connect_database(const char *conninfo, bool exit_on_error)
        res = PQexec(conn, ALWAYS_SECURE_SEARCH_PATH_SQL);
        if (PQresultStatus(res) != PGRES_TUPLES_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not clear 
\"search_path\": %s",
-                                                        
PQresultErrorMessage(res));
+               pg_log_error("could not clear \"search_path\": %s",
+                                        PQresultErrorMessage(res));
                PQclear(res);
                PQfinish(conn);
 
@@ -729,31 +645,27 @@ get_primary_sysid(const char *conninfo)
        PGresult   *res;
        uint64          sysid;
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "getting system identifier 
from publisher");
+       pg_log_info("getting system identifier from publisher");
 
        conn = connect_database(conninfo, true);
 
        res = PQexec(conn, "SELECT system_identifier FROM 
pg_catalog.pg_control_system()");
        if (PQresultStatus(res) != PGRES_TUPLES_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not get system 
identifier: %s",
-                                                        
PQresultErrorMessage(res));
+               pg_log_error("could not get system identifier: %s",
+                                        PQresultErrorMessage(res));
                disconnect_database(conn, true);
        }
        if (PQntuples(res) != 1)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not get system 
identifier: got %d rows, expected %d row",
-                                                        PQntuples(res), 1);
+               pg_log_error("could not get system identifier: got %d rows, 
expected %d row",
+                                        PQntuples(res), 1);
                disconnect_database(conn, true);
        }
 
        sysid = strtou64(PQgetvalue(res, 0, 0), NULL, 10);
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "system identifier is %" 
PRIu64 " on publisher", sysid);
+       pg_log_info("system identifier is %" PRIu64 " on publisher", sysid);
 
        PQclear(res);
        disconnect_database(conn, false);
@@ -773,17 +685,15 @@ get_standby_sysid(const char *datadir)
        bool            crc_ok;
        uint64          sysid;
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "getting system identifier 
from subscriber");
+       pg_log_info("getting system identifier from subscriber");
 
        cf = get_controlfile(datadir, &crc_ok);
        if (!crc_ok)
-               report_createsub_fatal("control file appears to be corrupt");
+               pg_fatal("control file appears to be corrupt");
 
        sysid = cf->system_identifier;
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "system identifier is %" 
PRIu64 " on subscriber", sysid);
+       pg_log_info("system identifier is %" PRIu64 " on subscriber", sysid);
 
        pg_free(cf);
 
@@ -805,12 +715,11 @@ modify_subscriber_sysid(const struct 
CreateSubscriberOptions *opt)
        char       *out_file;
        char       *cmd_str;
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "modifying system identifier 
of subscriber");
+       pg_log_info("modifying system identifier of subscriber");
 
        cf = get_controlfile(subscriber_dir, &crc_ok);
        if (!crc_ok)
-               report_createsub_fatal("control file appears to be corrupt");
+               pg_fatal("control file appears to be corrupt");
 
        /*
         * Select a new system identifier.
@@ -823,23 +732,19 @@ modify_subscriber_sysid(const struct 
CreateSubscriberOptions *opt)
        cf->system_identifier |= getpid() & 0xFFF;
 
        if (dry_run)
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dry-run: would set 
system identifier to %" PRIu64 " on subscriber",
-                                                        cf->system_identifier);
+               pg_log_info("dry-run: would set system identifier to %" PRIu64 
" on subscriber",
+                                       cf->system_identifier);
        else
        {
                update_controlfile(subscriber_dir, cf, true);
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "system identifier is 
%" PRIu64 " on subscriber",
-                                                        cf->system_identifier);
+               pg_log_info("system identifier is %" PRIu64 " on subscriber",
+                                       cf->system_identifier);
        }
 
        if (dry_run)
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dry-run: would run 
pg_resetwal on the subscriber");
+               pg_log_info("dry-run: would run pg_resetwal on the subscriber");
        else
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "running pg_resetwal 
on the subscriber");
+               pg_log_info("running pg_resetwal on the subscriber");
 
        /*
         * Redirecting the output to the logfile if specified. Since the output
@@ -856,18 +761,16 @@ modify_subscriber_sysid(const struct 
CreateSubscriberOptions *opt)
        if (opt->log_dir)
                pg_free(out_file);
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "pg_resetwal command is: %s", 
cmd_str);
+       pg_log_debug("pg_resetwal command is: %s", cmd_str);
 
        if (!dry_run)
        {
                int                     rc = system(cmd_str);
 
                if (rc == 0)
-                       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                                "successfully 
reset WAL on the subscriber");
+                       pg_log_info("successfully reset WAL on the subscriber");
                else
-                       report_createsub_fatal("could not reset WAL on 
subscriber: %s", wait_result_to_str(rc));
+                       pg_fatal("could not reset WAL on subscriber: %s", 
wait_result_to_str(rc));
        }
 
        pg_free(cf);
@@ -892,17 +795,15 @@ generate_object_name(PGconn *conn)
                                 "WHERE datname = 
pg_catalog.current_database()");
        if (PQresultStatus(res) != PGRES_TUPLES_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not obtain 
database OID: %s",
-                                                        
PQresultErrorMessage(res));
+               pg_log_error("could not obtain database OID: %s",
+                                        PQresultErrorMessage(res));
                disconnect_database(conn, true);
        }
 
        if (PQntuples(res) != 1)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not obtain 
database OID: got %d rows, expected %d row",
-                                                        PQntuples(res), 1);
+               pg_log_error("could not obtain database OID: got %d rows, 
expected %d row",
+                                        PQntuples(res), 1);
                disconnect_database(conn, true);
        }
 
@@ -942,9 +843,8 @@ find_publication(PGconn *conn, const char *pubname, const 
char *dbname)
        res = PQexec(conn, str->data);
        if (PQresultStatus(res) != PGRES_TUPLES_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not find 
publication \"%s\" in database \"%s\": %s",
-                                                        pubname, dbname, 
PQerrorMessage(conn));
+               pg_log_error("could not find publication \"%s\" in database 
\"%s\": %s",
+                                        pubname, dbname, PQerrorMessage(conn));
                disconnect_database(conn, true);
        }
 
@@ -997,9 +897,8 @@ setup_publisher(struct LogicalRepInfo *dbinfo)
                if (find_publication(conn, dbinfo[i].pubname, dbinfo[i].dbname))
                {
                        /* Reuse existing publication on publisher. */
-                       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                                "use existing 
publication \"%s\" in database \"%s\"",
-                                                                
dbinfo[i].pubname, dbinfo[i].dbname);
+                       pg_log_info("use existing publication \"%s\" in 
database \"%s\"",
+                                               dbinfo[i].pubname, 
dbinfo[i].dbname);
                        /* Don't remove pre-existing publication if an error 
occurs. */
                        dbinfo[i].made_publication = false;
                }
@@ -1037,9 +936,8 @@ setup_publisher(struct LogicalRepInfo *dbinfo)
                        res = PQexec(conn, "SELECT pg_log_standby_snapshot()");
                        if (PQresultStatus(res) != PGRES_TUPLES_OK)
                        {
-                               report_createsub_log(PG_LOG_ERROR, 
PG_LOG_PRIMARY,
-                                                                        "could 
not write an additional WAL record: %s",
-                                                                        
PQresultErrorMessage(res));
+                               pg_log_error("could not write an additional WAL 
record: %s",
+                                                        
PQresultErrorMessage(res));
                                disconnect_database(conn, true);
                        }
                        PQclear(res);
@@ -1064,9 +962,8 @@ server_is_in_recovery(PGconn *conn)
 
        if (PQresultStatus(res) != PGRES_TUPLES_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not obtain 
recovery progress: %s",
-                                                        
PQresultErrorMessage(res));
+               pg_log_error("could not obtain recovery progress: %s",
+                                        PQresultErrorMessage(res));
                disconnect_database(conn, true);
        }
 
@@ -1078,46 +975,6 @@ server_is_in_recovery(PGconn *conn)
        return ret == 0;
 }
 
-static void
-internal_log_file_write(enum pg_log_level level, enum pg_log_part part,
-                                               const char *pg_restrict fmt, 
va_list args)
-{
-       Assert(internal_log_file_fp);
-
-       /* Do nothing if log level is too low. */
-       if (level < __pg_log_level)
-               return;
-
-       /* Add prefix based on the log part and log level */
-       switch (part)
-       {
-               case PG_LOG_PRIMARY:
-                       switch (level)
-                       {
-                               case PG_LOG_ERROR:
-                                       fprintf(internal_log_file_fp, _("error: 
"));
-                                       break;
-                               case PG_LOG_WARNING:
-                                       fprintf(internal_log_file_fp, 
_("warning: "));
-                                       break;
-                               default:
-                                       break;
-                       }
-                       break;
-               case PG_LOG_DETAIL:
-                       fprintf(internal_log_file_fp, _("detail: "));
-                       break;
-               case PG_LOG_HINT:
-                       fprintf(internal_log_file_fp, _("hint: "));
-                       break;
-       }
-
-       vfprintf(internal_log_file_fp, _(fmt), args);
-
-       fprintf(internal_log_file_fp, "\n");
-       fflush(internal_log_file_fp);
-}
-
 /*
  * Open a new logfile with proper permissions.
  */
@@ -1129,8 +986,7 @@ logfile_open(const char *filename, const char *mode)
        fh = fopen(filename, mode);
 
        if (!fh)
-               report_createsub_fatal("could not open log file \"%s\": %m",
-                                                          filename);
+               pg_fatal("could not open log file \"%s\": %m", filename);
 
        return fh;
 }
@@ -1160,15 +1016,15 @@ make_output_dirs(const char *log_basedir)
        len = snprintf(logdir, MAXPGPATH, "%s/%s", log_basedir, timestamp);
 
        if (len >= MAXPGPATH)
-               report_createsub_fatal("directory path for log files is too 
long");
+               pg_fatal("directory path for log files is too long");
 
        /* Create base directory (ignore if exists) */
        if (mkdir(log_basedir, pg_dir_create_mode) < 0 && errno != EEXIST)
-               report_createsub_fatal("could not create directory \"%s\": %m", 
log_basedir);
+               pg_fatal("could not create directory \"%s\": %m", log_basedir);
 
        /* Create a timestamp-named subdirectory under the base directory */
        if (mkdir(logdir, pg_dir_create_mode) < 0)
-               report_createsub_fatal("could not create directory \"%s\": %m", 
logdir);
+               pg_fatal("could not create directory \"%s\": %m", logdir);
 }
 
 /*
@@ -1191,8 +1047,7 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
        int                     max_prepared_transactions;
        char       *max_slot_wal_keep_size;
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "checking settings on 
publisher");
+       pg_log_info("checking settings on publisher");
 
        conn = connect_database(dbinfo[0].pubconninfo, true);
 
@@ -1202,8 +1057,7 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
         */
        if (server_is_in_recovery(conn))
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "primary server cannot 
be in recovery");
+               pg_log_error("primary server cannot be in recovery");
                disconnect_database(conn, true);
        }
 
@@ -1229,9 +1083,8 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 
        if (PQresultStatus(res) != PGRES_TUPLES_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not obtain 
publisher settings: %s",
-                                                        
PQresultErrorMessage(res));
+               pg_log_error("could not obtain publisher settings: %s",
+                                        PQresultErrorMessage(res));
                disconnect_database(conn, true);
        }
 
@@ -1245,63 +1098,48 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 
        PQclear(res);
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "publisher: wal_level: %s", 
wal_level);
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "publisher: 
max_replication_slots: %d", max_repslots);
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "publisher: current 
replication slots: %d", cur_repslots);
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "publisher: max_wal_senders: 
%d", max_walsenders);
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "publisher: current wal 
senders: %d", cur_walsenders);
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "publisher: 
max_prepared_transactions: %d",
-                                                max_prepared_transactions);
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "publisher: 
max_slot_wal_keep_size: %s",
-                                                max_slot_wal_keep_size);
+       pg_log_debug("publisher: wal_level: %s", wal_level);
+       pg_log_debug("publisher: max_replication_slots: %d", max_repslots);
+       pg_log_debug("publisher: current replication slots: %d", cur_repslots);
+       pg_log_debug("publisher: max_wal_senders: %d", max_walsenders);
+       pg_log_debug("publisher: current wal senders: %d", cur_walsenders);
+       pg_log_debug("publisher: max_prepared_transactions: %d",
+                                max_prepared_transactions);
+       pg_log_debug("publisher: max_slot_wal_keep_size: %s",
+                                max_slot_wal_keep_size);
 
        disconnect_database(conn, false);
 
        if (strcmp(wal_level, "minimal") == 0)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "publisher requires 
\"wal_level\" >= \"replica\"");
+               pg_log_error("publisher requires \"wal_level\" >= \"replica\"");
                failed = true;
        }
 
        if (max_repslots - cur_repslots < num_dbs)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "publisher requires %d 
replication slots, but only %d remain",
-                                                        num_dbs, max_repslots 
- cur_repslots);
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                        "Increase the 
configuration parameter \"%s\" to at least %d.",
-                                                        
"max_replication_slots", cur_repslots + num_dbs);
+               pg_log_error("publisher requires %d replication slots, but only 
%d remain",
+                                        num_dbs, max_repslots - cur_repslots);
+               pg_log_error_hint("Increase the configuration parameter \"%s\" 
to at least %d.",
+                                                 "max_replication_slots", 
cur_repslots + num_dbs);
                failed = true;
        }
 
        if (max_walsenders - cur_walsenders < num_dbs)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "publisher requires %d 
WAL sender processes, but only %d remain",
-                                                        num_dbs, 
max_walsenders - cur_walsenders);
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                        "Increase the 
configuration parameter \"%s\" to at least %d.",
-                                                        "max_wal_senders", 
cur_walsenders + num_dbs);
+               pg_log_error("publisher requires %d WAL sender processes, but 
only %d remain",
+                                        num_dbs, max_walsenders - 
cur_walsenders);
+               pg_log_error_hint("Increase the configuration parameter \"%s\" 
to at least %d.",
+                                                 "max_wal_senders", 
cur_walsenders + num_dbs);
                failed = true;
        }
 
        if (max_prepared_transactions != 0 && !dbinfos.two_phase)
        {
-               report_createsub_log(PG_LOG_WARNING, PG_LOG_PRIMARY,
-                                                        "two_phase option will 
not be enabled for replication slots");
-               report_createsub_log(PG_LOG_WARNING, PG_LOG_DETAIL,
-                                                        "Subscriptions will be 
created with the two_phase option disabled.  "
-                                                        "Prepared transactions 
will be replicated at COMMIT PREPARED.");
-               report_createsub_log(PG_LOG_WARNING, PG_LOG_HINT,
-                                                        "You can use the 
command-line option --enable-two-phase to enable two_phase.");
+               pg_log_warning("two_phase option will not be enabled for 
replication slots");
+               pg_log_warning_detail("Subscriptions will be created with the 
two_phase option disabled.  "
+                                                         "Prepared 
transactions will be replicated at COMMIT PREPARED.");
+               pg_log_warning_hint("You can use the command-line option 
--enable-two-phase to enable two_phase.");
        }
 
        /*
@@ -1311,11 +1149,9 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
         */
        if (dry_run && (strcmp(max_slot_wal_keep_size, "-1") != 0))
        {
-               report_createsub_log(PG_LOG_WARNING, PG_LOG_PRIMARY,
-                                                        "required WAL could be 
removed from the publisher");
-               report_createsub_log(PG_LOG_WARNING, PG_LOG_HINT,
-                                                        "Set the configuration 
parameter \"%s\" to -1 to ensure that required WAL files are not prematurely 
removed.",
-                                                        
"max_slot_wal_keep_size");
+               pg_log_warning("required WAL could be removed from the 
publisher");
+               pg_log_warning_hint("Set the configuration parameter \"%s\" to 
-1 to ensure that required WAL files are not prematurely removed.",
+                                                       
"max_slot_wal_keep_size");
        }
 
        pg_free(wal_level);
@@ -1346,16 +1182,14 @@ check_subscriber(const struct LogicalRepInfo *dbinfo)
        int                     max_replorigins;
        int                     max_wprocs;
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "checking settings on 
subscriber");
+       pg_log_info("checking settings on subscriber");
 
        conn = connect_database(dbinfo[0].subconninfo, true);
 
        /* The target server must be a standby */
        if (!server_is_in_recovery(conn))
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "target server must be 
a standby");
+               pg_log_error("target server must be a standby");
                disconnect_database(conn, true);
        }
 
@@ -1379,9 +1213,8 @@ check_subscriber(const struct LogicalRepInfo *dbinfo)
 
        if (PQresultStatus(res) != PGRES_TUPLES_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not obtain 
subscriber settings: %s",
-                                                        
PQresultErrorMessage(res));
+               pg_log_error("could not obtain subscriber settings: %s",
+                                        PQresultErrorMessage(res));
                disconnect_database(conn, true);
        }
 
@@ -1391,16 +1224,12 @@ check_subscriber(const struct LogicalRepInfo *dbinfo)
        if (strcmp(PQgetvalue(res, 3, 0), "") != 0)
                primary_slot_name = pg_strdup(PQgetvalue(res, 3, 0));
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "subscriber: 
max_logical_replication_workers: %d",
-                                                max_lrworkers);
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "subscriber: 
max_active_replication_origins: %d", max_replorigins);
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "subscriber: 
max_worker_processes: %d", max_wprocs);
+       pg_log_debug("subscriber: max_logical_replication_workers: %d",
+                                max_lrworkers);
+       pg_log_debug("subscriber: max_active_replication_origins: %d", 
max_replorigins);
+       pg_log_debug("subscriber: max_worker_processes: %d", max_wprocs);
        if (primary_slot_name)
-               report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                        "subscriber: 
primary_slot_name: %s", primary_slot_name);
+               pg_log_debug("subscriber: primary_slot_name: %s", 
primary_slot_name);
 
        PQclear(res);
 
@@ -1408,34 +1237,28 @@ check_subscriber(const struct LogicalRepInfo *dbinfo)
 
        if (max_replorigins < num_dbs)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "subscriber requires 
%d active replication origins, but only %d remain",
-                                                        num_dbs, 
max_replorigins);
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                        "Increase the 
configuration parameter \"%s\" to at least %d.",
-                                                        
"max_active_replication_origins", num_dbs);
+               pg_log_error("subscriber requires %d active replication 
origins, but only %d remain",
+                                        num_dbs, max_replorigins);
+               pg_log_error_hint("Increase the configuration parameter \"%s\" 
to at least %d.",
+                                                 
"max_active_replication_origins", num_dbs);
                failed = true;
        }
 
        if (max_lrworkers < num_dbs)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "subscriber requires 
%d logical replication workers, but only %d remain",
-                                                        num_dbs, 
max_lrworkers);
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                        "Increase the 
configuration parameter \"%s\" to at least %d.",
-                                                        
"max_logical_replication_workers", num_dbs);
+               pg_log_error("subscriber requires %d logical replication 
workers, but only %d remain",
+                                        num_dbs, max_lrworkers);
+               pg_log_error_hint("Increase the configuration parameter \"%s\" 
to at least %d.",
+                                                 
"max_logical_replication_workers", num_dbs);
                failed = true;
        }
 
        if (max_wprocs < num_dbs + 1)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "subscriber requires 
%d worker processes, but only %d remain",
-                                                        num_dbs + 1, 
max_wprocs);
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                        "Increase the 
configuration parameter \"%s\" to at least %d.",
-                                                        
"max_worker_processes", num_dbs + 1);
+               pg_log_error("subscriber requires %d worker processes, but only 
%d remain",
+                                        num_dbs + 1, max_wprocs);
+               pg_log_error_hint("Increase the configuration parameter \"%s\" 
to at least %d.",
+                                                 "max_worker_processes", 
num_dbs + 1);
                failed = true;
        }
 
@@ -1468,22 +1291,19 @@ drop_existing_subscription(PGconn *conn, const char 
*subname, const char *dbname
        appendPQExpBuffer(query, " DROP SUBSCRIPTION %s;", subname);
 
        if (dry_run)
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dry-run: would drop 
subscription \"%s\" in database \"%s\"",
-                                                        subname, dbname);
+               pg_log_info("dry-run: would drop subscription \"%s\" in 
database \"%s\"",
+                                       subname, dbname);
        else
        {
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dropping subscription 
\"%s\" in database \"%s\"",
-                                                        subname, dbname);
+               pg_log_info("dropping subscription \"%s\" in database \"%s\"",
+                                       subname, dbname);
 
                res = PQexec(conn, query->data);
 
                if (PQresultStatus(res) != PGRES_COMMAND_OK)
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "could not 
drop subscription \"%s\": %s",
-                                                                subname, 
PQresultErrorMessage(res));
+                       pg_log_error("could not drop subscription \"%s\": %s",
+                                                subname, 
PQresultErrorMessage(res));
                        disconnect_database(conn, true);
                }
 
@@ -1517,9 +1337,8 @@ check_and_drop_existing_subscriptions(PGconn *conn,
 
        if (PQresultStatus(res) != PGRES_TUPLES_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not obtain 
pre-existing subscriptions: %s",
-                                                        
PQresultErrorMessage(res));
+               pg_log_error("could not obtain pre-existing subscriptions: %s",
+                                        PQresultErrorMessage(res));
                disconnect_database(conn, true);
        }
 
@@ -1630,8 +1449,7 @@ setup_recovery(const struct LogicalRepInfo *dbinfo, const 
char *datadir, const c
                                                  lsn);
        }
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "recovery parameters:\n%s", 
recoveryconfcontents->data);
+       pg_log_debug("recovery parameters:\n%s", recoveryconfcontents->data);
 
        if (!dry_run)
        {
@@ -1643,10 +1461,10 @@ setup_recovery(const struct LogicalRepInfo *dbinfo, 
const char *datadir, const c
                                 INCLUDED_CONF_FILE);
                fd = fopen(conf_filename, "w");
                if (fd == NULL)
-                       report_createsub_fatal("could not open file \"%s\": 
%m", conf_filename);
+                       pg_fatal("could not open file \"%s\": %m", 
conf_filename);
 
                if (fwrite(recoveryconfcontents->data, 
recoveryconfcontents->len, 1, fd) != 1)
-                       report_createsub_fatal("could not write to file \"%s\": 
%m", conf_filename);
+                       pg_fatal("could not write to file \"%s\": %m", 
conf_filename);
 
                fclose(fd);
                recovery_params_set = true;
@@ -1685,11 +1503,9 @@ drop_primary_replication_slot(struct LogicalRepInfo 
*dbinfo, const char *slotnam
        }
        else
        {
-               report_createsub_log(PG_LOG_WARNING, PG_LOG_PRIMARY,
-                                                        "could not drop 
replication slot \"%s\" on primary",
-                                                        slotname);
-               report_createsub_log(PG_LOG_WARNING, PG_LOG_HINT,
-                                                        "Drop this replication 
slot soon to avoid retention of WAL files.");
+               pg_log_warning("could not drop replication slot \"%s\" on 
primary",
+                                          slotname);
+               pg_log_warning_hint("Drop this replication slot soon to avoid 
retention of WAL files.");
        }
 }
 
@@ -1721,11 +1537,9 @@ drop_failover_replication_slots(struct LogicalRepInfo 
*dbinfo)
                }
                else
                {
-                       report_createsub_log(PG_LOG_WARNING, PG_LOG_PRIMARY,
-                                                                "could not 
obtain failover replication slot information: %s",
-                                                                
PQresultErrorMessage(res));
-                       report_createsub_log(PG_LOG_WARNING, PG_LOG_HINT,
-                                                                "Drop the 
failover replication slots on subscriber soon to avoid retention of WAL 
files.");
+                       pg_log_warning("could not obtain failover replication 
slot information: %s",
+                                                  PQresultErrorMessage(res));
+                       pg_log_warning_hint("Drop the failover replication 
slots on subscriber soon to avoid retention of WAL files.");
                }
 
                PQclear(res);
@@ -1733,10 +1547,8 @@ drop_failover_replication_slots(struct LogicalRepInfo 
*dbinfo)
        }
        else
        {
-               report_createsub_log(PG_LOG_WARNING, PG_LOG_PRIMARY,
-                                                        "could not drop 
failover replication slot");
-               report_createsub_log(PG_LOG_WARNING, PG_LOG_HINT,
-                                                        "Drop the failover 
replication slots on subscriber soon to avoid retention of WAL files.");
+               pg_log_warning("could not drop failover replication slot");
+               pg_log_warning_hint("Drop the failover replication slots on 
subscriber soon to avoid retention of WAL files.");
        }
 }
 
@@ -1758,13 +1570,11 @@ create_logical_replication_slot(PGconn *conn, struct 
LogicalRepInfo *dbinfo)
        Assert(conn != NULL);
 
        if (dry_run)
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dry-run: would create 
the replication slot \"%s\" in database \"%s\" on publisher",
-                                                        slot_name, 
dbinfo->dbname);
+               pg_log_info("dry-run: would create the replication slot \"%s\" 
in database \"%s\" on publisher",
+                                       slot_name, dbinfo->dbname);
        else
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "creating the 
replication slot \"%s\" in database \"%s\" on publisher",
-                                                        slot_name, 
dbinfo->dbname);
+               pg_log_info("creating the replication slot \"%s\" in database 
\"%s\" on publisher",
+                                       slot_name, dbinfo->dbname);
 
        slot_name_esc = PQescapeLiteral(conn, slot_name, strlen(slot_name));
 
@@ -1775,18 +1585,16 @@ create_logical_replication_slot(PGconn *conn, struct 
LogicalRepInfo *dbinfo)
 
        PQfreemem(slot_name_esc);
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "command is: %s", str->data);
+       pg_log_debug("command is: %s", str->data);
 
        if (!dry_run)
        {
                res = PQexec(conn, str->data);
                if (PQresultStatus(res) != PGRES_TUPLES_OK)
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "could not 
create replication slot \"%s\" in database \"%s\": %s",
-                                                                slot_name, 
dbinfo->dbname,
-                                                                
PQresultErrorMessage(res));
+                       pg_log_error("could not create replication slot \"%s\" 
in database \"%s\": %s",
+                                                slot_name, dbinfo->dbname,
+                                                PQresultErrorMessage(res));
                        PQclear(res);
                        destroyPQExpBuffer(str);
                        return NULL;
@@ -1815,13 +1623,11 @@ drop_replication_slot(PGconn *conn, struct 
LogicalRepInfo *dbinfo,
        Assert(conn != NULL);
 
        if (dry_run)
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dry-run: would drop 
the replication slot \"%s\" in database \"%s\"",
-                                                        slot_name, 
dbinfo->dbname);
+               pg_log_info("dry-run: would drop the replication slot \"%s\" in 
database \"%s\"",
+                                       slot_name, dbinfo->dbname);
        else
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dropping the 
replication slot \"%s\" in database \"%s\"",
-                                                        slot_name, 
dbinfo->dbname);
+               pg_log_info("dropping the replication slot \"%s\" in database 
\"%s\"",
+                                       slot_name, dbinfo->dbname);
 
        slot_name_esc = PQescapeLiteral(conn, slot_name, strlen(slot_name));
 
@@ -1829,17 +1635,15 @@ drop_replication_slot(PGconn *conn, struct 
LogicalRepInfo *dbinfo,
 
        PQfreemem(slot_name_esc);
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "command is: %s", str->data);
+       pg_log_debug("command is: %s", str->data);
 
        if (!dry_run)
        {
                res = PQexec(conn, str->data);
                if (PQresultStatus(res) != PGRES_TUPLES_OK)
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "could not 
drop replication slot \"%s\" in database \"%s\": %s",
-                                                                slot_name, 
dbinfo->dbname, PQresultErrorMessage(res));
+                       pg_log_error("could not drop replication slot \"%s\" in 
database \"%s\": %s",
+                                                slot_name, dbinfo->dbname, 
PQresultErrorMessage(res));
                        dbinfo->made_replslot = false;  /* don't try again. */
                }
 
@@ -1859,32 +1663,25 @@ pg_ctl_status(const char *pg_ctl_cmd, int rc)
        {
                if (WIFEXITED(rc))
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "pg_ctl failed 
with exit code %d",
-                                                                
WEXITSTATUS(rc));
+                       pg_log_error("pg_ctl failed with exit code %d", 
WEXITSTATUS(rc));
                }
                else if (WIFSIGNALED(rc))
                {
 #if defined(WIN32)
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "pg_ctl was 
terminated by exception 0x%X",
-                                                                WTERMSIG(rc));
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_DETAIL,
-                                                                "See C include 
file \"ntstatus.h\" for a description of the hexadecimal value.");
+                       pg_log_error("pg_ctl was terminated by exception 0x%X",
+                                                WTERMSIG(rc));
+                       pg_log_error_detail("See C include file \"ntstatus.h\" 
for a description of the hexadecimal value.");
 #else
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "pg_ctl was 
terminated by signal %d: %s",
-                                                                WTERMSIG(rc), 
pg_strsignal(WTERMSIG(rc)));
+                       pg_log_error("pg_ctl was terminated by signal %d: %s",
+                                                WTERMSIG(rc), 
pg_strsignal(WTERMSIG(rc)));
 #endif
                }
                else
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "pg_ctl exited 
with unrecognized status %d", rc);
+                       pg_log_error("pg_ctl exited with unrecognized status 
%d", rc);
                }
 
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_DETAIL,
-                                                        "The failed command 
was: %s", pg_ctl_cmd);
+               pg_log_error_detail("The failed command was: %s", pg_ctl_cmd);
                exit(1);
        }
 }
@@ -1932,14 +1729,12 @@ start_standby_server(const struct 
CreateSubscriberOptions *opt, bool restricted_
        if (opt->log_dir)
                appendPQExpBuffer(pg_ctl_cmd, " -l \"%s/%s\"", logdir, 
SERVER_LOG_FILE_NAME);
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "pg_ctl command is: %s", 
pg_ctl_cmd->data);
+       pg_log_debug("pg_ctl command is: %s", pg_ctl_cmd->data);
        rc = system(pg_ctl_cmd->data);
        pg_ctl_status(pg_ctl_cmd->data, rc);
        standby_running = true;
        destroyPQExpBuffer(pg_ctl_cmd);
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "server was started");
+       pg_log_info("server was started");
 }
 
 static void
@@ -1950,13 +1745,11 @@ stop_standby_server(const char *datadir)
 
        pg_ctl_cmd = psprintf("\"%s\" stop -D \"%s\" -s", pg_ctl_path,
                                                  datadir);
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "pg_ctl command is: %s", 
pg_ctl_cmd);
+       pg_log_debug("pg_ctl command is: %s", pg_ctl_cmd);
        rc = system(pg_ctl_cmd);
        pg_ctl_status(pg_ctl_cmd, rc);
        standby_running = false;
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "server was stopped");
+       pg_log_info("server was stopped");
 }
 
 /*
@@ -1975,8 +1768,7 @@ wait_for_end_recovery(const char *conninfo, const struct 
CreateSubscriberOptions
        bool            ready = false;
        int                     timer = 0;
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "waiting for the target server 
to reach the consistent state");
+       pg_log_info("waiting for the target server to reach the consistent 
state");
 
        conn = connect_database(conninfo, true);
 
@@ -1994,8 +1786,7 @@ wait_for_end_recovery(const char *conninfo, const struct 
CreateSubscriberOptions
                if (opt->recovery_timeout > 0 && timer >= opt->recovery_timeout)
                {
                        stop_standby_server(subscriber_dir);
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "recovery 
timed out");
+                       pg_log_error("recovery timed out");
                        disconnect_database(conn, true);
                }
 
@@ -2007,12 +1798,10 @@ wait_for_end_recovery(const char *conninfo, const 
struct CreateSubscriberOptions
        disconnect_database(conn, false);
 
        if (!ready)
-               report_createsub_fatal("server did not end recovery");
+               pg_fatal("server did not end recovery");
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "target server reached the 
consistent state");
-       report_createsub_log(PG_LOG_INFO, PG_LOG_HINT,
-                                                "If pg_createsubscriber fails 
after this point, you must recreate the physical replica before continuing.");
+       pg_log_info("target server reached the consistent state");
+       pg_log_info_hint("If pg_createsubscriber fails after this point, you 
must recreate the physical replica before continuing.");
 }
 
 /*
@@ -2039,9 +1828,8 @@ create_publication(PGconn *conn, struct LogicalRepInfo 
*dbinfo)
        res = PQexec(conn, str->data);
        if (PQresultStatus(res) != PGRES_TUPLES_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not obtain 
publication information: %s",
-                                                        
PQresultErrorMessage(res));
+               pg_log_error("could not obtain publication information: %s",
+                                        PQresultErrorMessage(res));
                disconnect_database(conn, true);
        }
 
@@ -2054,10 +1842,8 @@ create_publication(PGconn *conn, struct LogicalRepInfo 
*dbinfo)
                 * pg_createsubscriber_ prefix followed by the exact database 
oid and
                 * a random number.
                 */
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "publication \"%s\" 
already exists", dbinfo->pubname);
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                        "Consider renaming 
this publication before continuing.");
+               pg_log_error("publication \"%s\" already exists", 
dbinfo->pubname);
+               pg_log_error_hint("Consider renaming this publication before 
continuing.");
                disconnect_database(conn, true);
        }
 
@@ -2065,28 +1851,24 @@ create_publication(PGconn *conn, struct LogicalRepInfo 
*dbinfo)
        resetPQExpBuffer(str);
 
        if (dry_run)
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dry-run: would create 
publication \"%s\" in database \"%s\"",
-                                                        dbinfo->pubname, 
dbinfo->dbname);
+               pg_log_info("dry-run: would create publication \"%s\" in 
database \"%s\"",
+                                       dbinfo->pubname, dbinfo->dbname);
        else
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "creating publication 
\"%s\" in database \"%s\"",
-                                                        dbinfo->pubname, 
dbinfo->dbname);
+               pg_log_info("creating publication \"%s\" in database \"%s\"",
+                                       dbinfo->pubname, dbinfo->dbname);
 
        appendPQExpBuffer(str, "CREATE PUBLICATION %s FOR ALL TABLES",
                                          ipubname_esc);
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "command is: %s", str->data);
+       pg_log_debug("command is: %s", str->data);
 
        if (!dry_run)
        {
                res = PQexec(conn, str->data);
                if (PQresultStatus(res) != PGRES_COMMAND_OK)
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "could not 
create publication \"%s\" in database \"%s\": %s",
-                                                                
dbinfo->pubname, dbinfo->dbname, PQresultErrorMessage(res));
+                       pg_log_error("could not create publication \"%s\" in 
database \"%s\": %s",
+                                                dbinfo->pubname, 
dbinfo->dbname, PQresultErrorMessage(res));
                        disconnect_database(conn, true);
                }
                PQclear(res);
@@ -2116,29 +1898,25 @@ drop_publication(PGconn *conn, const char *pubname, 
const char *dbname,
        pubname_esc = PQescapeIdentifier(conn, pubname, strlen(pubname));
 
        if (dry_run)
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dry-run: would drop 
publication \"%s\" in database \"%s\"",
-                                                        pubname, dbname);
+               pg_log_info("dry-run: would drop publication \"%s\" in database 
\"%s\"",
+                                       pubname, dbname);
        else
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dropping publication 
\"%s\" in database \"%s\"",
-                                                        pubname, dbname);
+               pg_log_info("dropping publication \"%s\" in database \"%s\"",
+                                       pubname, dbname);
 
        appendPQExpBuffer(str, "DROP PUBLICATION %s", pubname_esc);
 
        PQfreemem(pubname_esc);
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "command is: %s", str->data);
+       pg_log_debug("command is: %s", str->data);
 
        if (!dry_run)
        {
                res = PQexec(conn, str->data);
                if (PQresultStatus(res) != PGRES_COMMAND_OK)
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "could not 
drop publication \"%s\" in database \"%s\": %s",
-                                                                pubname, 
dbname, PQresultErrorMessage(res));
+                       pg_log_error("could not drop publication \"%s\" in 
database \"%s\": %s",
+                                                pubname, dbname, 
PQresultErrorMessage(res));
                        *made_publication = false;      /* don't try again. */
 
                        /*
@@ -2173,17 +1951,15 @@ check_and_drop_publications(PGconn *conn, struct 
LogicalRepInfo *dbinfo)
 
        if (drop_all_pubs)
        {
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dropping all existing 
publications in database \"%s\"",
-                                                        dbinfo->dbname);
+               pg_log_info("dropping all existing publications in database 
\"%s\"",
+                                       dbinfo->dbname);
 
                /* Fetch all publication names */
                res = PQexec(conn, "SELECT pubname FROM 
pg_catalog.pg_publication;");
                if (PQresultStatus(res) != PGRES_TUPLES_OK)
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "could not 
obtain publication information: %s",
-                                                                
PQresultErrorMessage(res));
+                       pg_log_error("could not obtain publication information: 
%s",
+                                                PQresultErrorMessage(res));
                        PQclear(res);
                        disconnect_database(conn, true);
                }
@@ -2206,13 +1982,11 @@ check_and_drop_publications(PGconn *conn, struct 
LogicalRepInfo *dbinfo)
                else
                {
                        if (dry_run)
-                               report_createsub_log(PG_LOG_INFO, 
PG_LOG_PRIMARY,
-                                                                        
"dry-run: would preserve existing publication \"%s\" in database \"%s\"",
-                                                                        
dbinfo->pubname, dbinfo->dbname);
+                               pg_log_info("dry-run: would preserve existing 
publication \"%s\" in database \"%s\"",
+                                                       dbinfo->pubname, 
dbinfo->dbname);
                        else
-                               report_createsub_log(PG_LOG_INFO, 
PG_LOG_PRIMARY,
-                                                                        
"preserve existing publication \"%s\" in database \"%s\"",
-                                                                        
dbinfo->pubname, dbinfo->dbname);
+                               pg_log_info("preserve existing publication 
\"%s\" in database \"%s\"",
+                                                       dbinfo->pubname, 
dbinfo->dbname);
                }
        }
 }
@@ -2246,13 +2020,11 @@ create_subscription(PGconn *conn, const struct 
LogicalRepInfo *dbinfo)
        replslotname_esc = PQescapeLiteral(conn, dbinfo->replslotname, 
strlen(dbinfo->replslotname));
 
        if (dry_run)
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dry-run: would create 
subscription \"%s\" in database \"%s\"",
-                                                        dbinfo->subname, 
dbinfo->dbname);
+               pg_log_info("dry-run: would create subscription \"%s\" in 
database \"%s\"",
+                                       dbinfo->subname, dbinfo->dbname);
        else
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "creating subscription 
\"%s\" in database \"%s\"",
-                                                        dbinfo->subname, 
dbinfo->dbname);
+               pg_log_info("creating subscription \"%s\" in database \"%s\"",
+                                       dbinfo->subname, dbinfo->dbname);
 
        appendPQExpBuffer(str,
                                          "CREATE SUBSCRIPTION %s CONNECTION %s 
PUBLICATION %s "
@@ -2266,17 +2038,15 @@ create_subscription(PGconn *conn, const struct 
LogicalRepInfo *dbinfo)
        PQfreemem(pubconninfo_esc);
        PQfreemem(replslotname_esc);
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "command is: %s", str->data);
+       pg_log_debug("command is: %s", str->data);
 
        if (!dry_run)
        {
                res = PQexec(conn, str->data);
                if (PQresultStatus(res) != PGRES_COMMAND_OK)
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "could not 
create subscription \"%s\" in database \"%s\": %s",
-                                                                
dbinfo->subname, dbinfo->dbname, PQresultErrorMessage(res));
+                       pg_log_error("could not create subscription \"%s\" in 
database \"%s\": %s",
+                                                dbinfo->subname, 
dbinfo->dbname, PQresultErrorMessage(res));
                        disconnect_database(conn, true);
                }
                PQclear(res);
@@ -2320,17 +2090,15 @@ set_replication_progress(PGconn *conn, const struct 
LogicalRepInfo *dbinfo, cons
        res = PQexec(conn, str->data);
        if (PQresultStatus(res) != PGRES_TUPLES_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not obtain 
subscription OID: %s",
-                                                        
PQresultErrorMessage(res));
+               pg_log_error("could not obtain subscription OID: %s",
+                                        PQresultErrorMessage(res));
                disconnect_database(conn, true);
        }
 
        if (PQntuples(res) != 1 && !dry_run)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not obtain 
subscription OID: got %d rows, expected %d row",
-                                                        PQntuples(res), 1);
+               pg_log_error("could not obtain subscription OID: got %d rows, 
expected %d row",
+                                        PQntuples(res), 1);
                disconnect_database(conn, true);
        }
 
@@ -2354,30 +2122,26 @@ set_replication_progress(PGconn *conn, const struct 
LogicalRepInfo *dbinfo, cons
        originname = psprintf("pg_%u", suboid);
 
        if (dry_run)
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dry-run: would set 
the replication progress (node name \"%s\", LSN %s) in database \"%s\"",
-                                                        originname, lsnstr, 
dbinfo->dbname);
+               pg_log_info("dry-run: would set the replication progress (node 
name \"%s\", LSN %s) in database \"%s\"",
+                                       originname, lsnstr, dbinfo->dbname);
        else
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "setting the 
replication progress (node name \"%s\", LSN %s) in database \"%s\"",
-                                                        originname, lsnstr, 
dbinfo->dbname);
+               pg_log_info("setting the replication progress (node name 
\"%s\", LSN %s) in database \"%s\"",
+                                       originname, lsnstr, dbinfo->dbname);
 
        resetPQExpBuffer(str);
        appendPQExpBuffer(str,
                                          "SELECT 
pg_catalog.pg_replication_origin_advance('%s', '%s')",
                                          originname, lsnstr);
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "command is: %s", str->data);
+       pg_log_debug("command is: %s", str->data);
 
        if (!dry_run)
        {
                res = PQexec(conn, str->data);
                if (PQresultStatus(res) != PGRES_TUPLES_OK)
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "could not set 
replication progress for subscription \"%s\": %s",
-                                                                
dbinfo->subname, PQresultErrorMessage(res));
+                       pg_log_error("could not set replication progress for 
subscription \"%s\": %s",
+                                                dbinfo->subname, 
PQresultErrorMessage(res));
                        disconnect_database(conn, true);
                }
                PQclear(res);
@@ -2408,27 +2172,23 @@ enable_subscription(PGconn *conn, const struct 
LogicalRepInfo *dbinfo)
        subname = PQescapeIdentifier(conn, dbinfo->subname, 
strlen(dbinfo->subname));
 
        if (dry_run)
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "dry-run: would enable 
subscription \"%s\" in database \"%s\"",
-                                                        dbinfo->subname, 
dbinfo->dbname);
+               pg_log_info("dry-run: would enable subscription \"%s\" in 
database \"%s\"",
+                                       dbinfo->subname, dbinfo->dbname);
        else
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "enabling subscription 
\"%s\" in database \"%s\"",
-                                                        dbinfo->subname, 
dbinfo->dbname);
+               pg_log_info("enabling subscription \"%s\" in database \"%s\"",
+                                       dbinfo->subname, dbinfo->dbname);
 
        appendPQExpBuffer(str, "ALTER SUBSCRIPTION %s ENABLE", subname);
 
-       report_createsub_log(PG_LOG_DEBUG, PG_LOG_PRIMARY,
-                                                "command is: %s", str->data);
+       pg_log_debug("command is: %s", str->data);
 
        if (!dry_run)
        {
                res = PQexec(conn, str->data);
                if (PQresultStatus(res) != PGRES_COMMAND_OK)
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "could not 
enable subscription \"%s\": %s",
-                                                                
dbinfo->subname, PQresultErrorMessage(res));
+                       pg_log_error("could not enable subscription \"%s\": %s",
+                                                dbinfo->subname, 
PQresultErrorMessage(res));
                        disconnect_database(conn, true);
                }
 
@@ -2473,9 +2233,7 @@ get_publisher_databases(struct CreateSubscriberOptions 
*opt,
        res = PQexec(conn, "SELECT datname FROM pg_database WHERE datistemplate 
= false AND datallowconn AND datconnlimit <> -2 ORDER BY 1");
        if (PQresultStatus(res) != PGRES_TUPLES_OK)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "could not obtain a 
list of databases: %s",
-                                                        
PQresultErrorMessage(res));
+               pg_log_error("could not obtain a list of databases: %s", 
PQresultErrorMessage(res));
                PQclear(res);
                disconnect_database(conn, true);
        }
@@ -2581,11 +2339,9 @@ main(int argc, char **argv)
 #ifndef WIN32
        if (geteuid() == 0)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "cannot be executed by 
\"root\"");
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                        "You must run %s as 
the PostgreSQL superuser.",
-                                                        progname);
+               pg_log_error("cannot be executed by \"root\"");
+               pg_log_error_hint("You must run %s as the PostgreSQL 
superuser.",
+                                                 progname);
                exit(1);
        }
 #endif
@@ -2607,7 +2363,7 @@ main(int argc, char **argv)
                                        num_dbs++;
                                }
                                else
-                                       report_createsub_fatal("database \"%s\" 
specified more than once for -d/--database", optarg);
+                                       pg_fatal("database \"%s\" specified 
more than once for -d/--database", optarg);
                                break;
                        case 'D':
                                subscriber_dir = pg_strdup(optarg);
@@ -2652,7 +2408,7 @@ main(int argc, char **argv)
                                        num_pubs++;
                                }
                                else
-                                       report_createsub_fatal("publication 
\"%s\" specified more than once for --publication", optarg);
+                                       pg_fatal("publication \"%s\" specified 
more than once for --publication", optarg);
                                break;
                        case 3:
                                if 
(!simple_string_list_member(&opt.replslot_names, optarg))
@@ -2661,7 +2417,7 @@ main(int argc, char **argv)
                                        num_replslots++;
                                }
                                else
-                                       report_createsub_fatal("replication 
slot \"%s\" specified more than once for --replication-slot", optarg);
+                                       pg_fatal("replication slot \"%s\" 
specified more than once for --replication-slot", optarg);
                                break;
                        case 4:
                                if (!simple_string_list_member(&opt.sub_names, 
optarg))
@@ -2670,19 +2426,17 @@ main(int argc, char **argv)
                                        num_subs++;
                                }
                                else
-                                       report_createsub_fatal("subscription 
\"%s\" specified more than once for --subscription", optarg);
+                                       pg_fatal("subscription \"%s\" specified 
more than once for --subscription", optarg);
                                break;
                        case 5:
                                if 
(!simple_string_list_member(&opt.objecttypes_to_clean, optarg))
                                        
simple_string_list_append(&opt.objecttypes_to_clean, optarg);
                                else
-                                       report_createsub_fatal("object type 
\"%s\" specified more than once for --clean", optarg);
+                                       pg_fatal("object type \"%s\" specified 
more than once for --clean", optarg);
                                break;
                        default:
                                /* getopt_long already emitted a complaint */
-                               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                                        "Try 
\"%s --help\" for more information.",
-                                                                        
progname);
+                               pg_log_error_hint("Try \"%s --help\" for more 
information.", progname);
                                exit(1);
                }
        }
@@ -2703,12 +2457,9 @@ main(int argc, char **argv)
 
                if (bad_switch)
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "options %s 
and %s cannot be used together",
-                                                                bad_switch, 
"-a/--all");
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                                "Try \"%s 
--help\" for more information.",
-                                                                progname);
+                       pg_log_error("options %s and %s cannot be used 
together",
+                                                bad_switch, "-a/--all");
+                       pg_log_error_hint("Try \"%s --help\" for more 
information.", progname);
                        exit(1);
                }
        }
@@ -2716,21 +2467,17 @@ main(int argc, char **argv)
        /* Any non-option arguments? */
        if (optind < argc)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "too many command-line 
arguments (first is \"%s\")",
-                                                        argv[optind]);
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                        "Try \"%s --help\" for 
more information.", progname);
+               pg_log_error("too many command-line arguments (first is 
\"%s\")",
+                                        argv[optind]);
+               pg_log_error_hint("Try \"%s --help\" for more information.", 
progname);
                exit(1);
        }
 
        /* Required arguments */
        if (subscriber_dir == NULL)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "no subscriber data 
directory specified");
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                        "Try \"%s --help\" for 
more information.", progname);
+               pg_log_error("no subscriber data directory specified");
+               pg_log_error_hint("Try \"%s --help\" for more information.", 
progname);
                exit(1);
        }
 
@@ -2740,7 +2487,7 @@ main(int argc, char **argv)
                char            cwd[MAXPGPATH];
 
                if (!getcwd(cwd, MAXPGPATH))
-                       report_createsub_fatal("could not determine current 
directory");
+                       pg_fatal("could not determine current directory");
                opt.socket_dir = pg_strdup(cwd);
                canonicalize_path(opt.socket_dir);
        }
@@ -2757,16 +2504,15 @@ main(int argc, char **argv)
                 * identical entries for physical and logical replication. If 
there is
                 * not, we would fail anyway.
                 */
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "no publisher 
connection string specified");
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                        "Try \"%s --help\" for 
more information.", progname);
+               pg_log_error("no publisher connection string specified");
+               pg_log_error_hint("Try \"%s --help\" for more information.", 
progname);
                exit(1);
        }
 
        if (opt.log_dir != NULL)
        {
                char       *internal_log_file;
+               FILE       *internal_log_file_fp;
 
                umask(PG_MODE_MASK_OWNER);
 
@@ -2787,22 +2533,21 @@ main(int argc, char **argv)
                /* logfile_open() will exit if there is an error */
                internal_log_file_fp = logfile_open(internal_log_file, "a");
                pg_free(internal_log_file);
+
+               pg_logging_set_logfile(internal_log_file_fp);
        }
 
        if (dry_run)
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "Executing in dry-run 
mode.\n"
-                                                        "The target directory 
will not be modified.");
+               pg_log_info("Executing in dry-run mode.\n"
+                                       "The target directory will not be 
modified.");
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "validating publisher 
connection string");
+       pg_log_info("validating publisher connection string");
        pub_base_conninfo = get_base_conninfo(opt.pub_conninfo_str,
                                                                                
  &dbname_conninfo);
        if (pub_base_conninfo == NULL)
                exit(1);
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "validating subscriber 
connection string");
+       pg_log_info("validating subscriber connection string");
        sub_base_conninfo = get_sub_conninfo(&opt);
 
        /*
@@ -2819,8 +2564,7 @@ main(int argc, char **argv)
 
        if (opt.database_names.head == NULL)
        {
-               report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                        "no database was 
specified");
+               pg_log_info("no database was specified");
 
                /*
                 * Try to obtain the dbname from the publisher conninfo. If 
dbname
@@ -2831,17 +2575,14 @@ main(int argc, char **argv)
                        simple_string_list_append(&opt.database_names, 
dbname_conninfo);
                        num_dbs++;
 
-                       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                                "database name 
\"%s\" was extracted from the publisher connection string",
-                                                                
dbname_conninfo);
+                       pg_log_info("database name \"%s\" was extracted from 
the publisher connection string",
+                                               dbname_conninfo);
                }
                else
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "no database 
name specified");
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                                "Try \"%s 
--help\" for more information.",
-                                                                progname);
+                       pg_log_error("no database name specified");
+                       pg_log_error_hint("Try \"%s --help\" for more 
information.",
+                                                         progname);
                        exit(1);
                }
        }
@@ -2849,29 +2590,23 @@ main(int argc, char **argv)
        /* Number of object names must match number of databases */
        if (num_pubs > 0 && num_pubs != num_dbs)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "wrong number of 
publication names specified");
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_DETAIL,
-                                                        "The number of 
specified publication names (%d) must match the number of specified database 
names (%d).",
-                                                        num_pubs, num_dbs);
+               pg_log_error("wrong number of publication names specified");
+               pg_log_error_detail("The number of specified publication names 
(%d) must match the number of specified database names (%d).",
+                                                       num_pubs, num_dbs);
                exit(1);
        }
        if (num_subs > 0 && num_subs != num_dbs)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "wrong number of 
subscription names specified");
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_DETAIL,
-                                                        "The number of 
specified subscription names (%d) must match the number of specified database 
names (%d).",
-                                                        num_subs, num_dbs);
+               pg_log_error("wrong number of subscription names specified");
+               pg_log_error_detail("The number of specified subscription names 
(%d) must match the number of specified database names (%d).",
+                                                       num_subs, num_dbs);
                exit(1);
        }
        if (num_replslots > 0 && num_replslots != num_dbs)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "wrong number of 
replication slot names specified");
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_DETAIL,
-                                                        "The number of 
specified replication slot names (%d) must match the number of specified 
database names (%d).",
-                                                        num_replslots, 
num_dbs);
+               pg_log_error("wrong number of replication slot names 
specified");
+               pg_log_error_detail("The number of specified replication slot 
names (%d) must match the number of specified database names (%d).",
+                                                       num_replslots, num_dbs);
                exit(1);
        }
 
@@ -2882,11 +2617,9 @@ main(int argc, char **argv)
                        dbinfos.objecttypes_to_clean |= OBJECTTYPE_PUBLICATIONS;
                else
                {
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                                "invalid 
object type \"%s\" specified for %s",
-                                                                cell->val, 
"--clean");
-                       report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                                "The valid 
value is: \"%s\"", "publications");
+                       pg_log_error("invalid object type \"%s\" specified for 
%s",
+                                                cell->val, "--clean");
+                       pg_log_error_hint("The valid value is: \"%s\"", 
"publications");
                        exit(1);
                }
        }
@@ -2917,7 +2650,7 @@ main(int argc, char **argv)
        pub_sysid = get_primary_sysid(dbinfos.dbinfo[0].pubconninfo);
        sub_sysid = get_standby_sysid(subscriber_dir);
        if (pub_sysid != sub_sysid)
-               report_createsub_fatal("subscriber data directory is not a copy 
of the source database cluster");
+               pg_fatal("subscriber data directory is not a copy of the source 
database cluster");
 
        /* Subscriber PID file */
        snprintf(pidfile, MAXPGPATH, "%s/postmaster.pid", subscriber_dir);
@@ -2930,10 +2663,8 @@ main(int argc, char **argv)
         */
        if (stat(pidfile, &statbuf) == 0)
        {
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_PRIMARY,
-                                                        "standby server is 
running");
-               report_createsub_log(PG_LOG_ERROR, PG_LOG_HINT,
-                                                        "Stop the standby 
server and try again.");
+               pg_log_error("standby server is running");
+               pg_log_error_hint("Stop the standby server and try again.");
                exit(1);
        }
 
@@ -2942,8 +2673,7 @@ main(int argc, char **argv)
         * by command-line options). The goal is to avoid connections during the
         * transformation steps.
         */
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "starting the standby server 
with command-line options");
+       pg_log_info("starting the standby server with command-line options");
        start_standby_server(&opt, true, false);
 
        /* Check if the standby server is ready for logical replication */
@@ -2959,8 +2689,7 @@ main(int argc, char **argv)
         * guarantees it) *before* creating the replication slots in
         * setup_publisher().
         */
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "stopping the subscriber");
+       pg_log_info("stopping the subscriber");
        stop_standby_server(subscriber_dir);
 
        /* Create the required objects for each database on publisher */
@@ -2974,8 +2703,7 @@ main(int argc, char **argv)
         * until accepting connections. We don't want to start logical 
replication
         * during setup.
         */
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "starting the subscriber");
+       pg_log_info("starting the subscriber");
        start_standby_server(&opt, true, true);
 
        /* Waiting the subscriber to be promoted */
@@ -2996,8 +2724,7 @@ main(int argc, char **argv)
        drop_failover_replication_slots(dbinfos.dbinfo);
 
        /* Stop the subscriber */
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "stopping the subscriber");
+       pg_log_info("stopping the subscriber");
        stop_standby_server(subscriber_dir);
 
        /* Change system identifier from subscriber */
@@ -3005,8 +2732,7 @@ main(int argc, char **argv)
 
        success = true;
 
-       report_createsub_log(PG_LOG_INFO, PG_LOG_PRIMARY,
-                                                "Done!");
+       pg_log_info("Done!");
 
        return 0;
 }
-- 
2.53.0

From 55729429cbfe85e737312995cb7548a62a222405 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Tue, 31 Mar 2026 13:57:16 +0200
Subject: [PATCH v20 3/4] pg_createsubscriber: Remove separate logfile_open()
 function

---
 src/bin/pg_basebackup/pg_createsubscriber.c | 22 ++++-----------------
 1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c 
b/src/bin/pg_basebackup/pg_createsubscriber.c
index 5c5fa2a7633..e90fce0302e 100644
--- a/src/bin/pg_basebackup/pg_createsubscriber.c
+++ b/src/bin/pg_basebackup/pg_createsubscriber.c
@@ -975,22 +975,6 @@ server_is_in_recovery(PGconn *conn)
        return ret == 0;
 }
 
-/*
- * Open a new logfile with proper permissions.
- */
-static FILE *
-logfile_open(const char *filename, const char *mode)
-{
-       FILE       *fh;
-
-       fh = fopen(filename, mode);
-
-       if (!fh)
-               pg_fatal("could not open log file \"%s\": %m", filename);
-
-       return fh;
-}
-
 static void
 make_output_dirs(const char *log_basedir)
 {
@@ -2530,8 +2514,10 @@ main(int argc, char **argv)
                make_output_dirs(opt.log_dir);
                internal_log_file = psprintf("%s/%s", logdir, 
INTERNAL_LOG_FILE_NAME);
 
-               /* logfile_open() will exit if there is an error */
-               internal_log_file_fp = logfile_open(internal_log_file, "a");
+               internal_log_file_fp = fopen(internal_log_file, "a");
+               if (!internal_log_file_fp)
+                       pg_fatal("could not open log file \"%s\": %m", 
internal_log_file);
+
                pg_free(internal_log_file);
 
                pg_logging_set_logfile(internal_log_file_fp);
-- 
2.53.0

From e9ccc54a4cd2f73bf027b069efa637683bfbcc09 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Tue, 31 Mar 2026 13:57:52 +0200
Subject: [PATCH v20 4/4] pg_createsubscriber: Don't use MAXPGPATH

---
 src/bin/pg_basebackup/pg_createsubscriber.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c 
b/src/bin/pg_basebackup/pg_createsubscriber.c
index e90fce0302e..15e06e5686e 100644
--- a/src/bin/pg_basebackup/pg_createsubscriber.c
+++ b/src/bin/pg_basebackup/pg_createsubscriber.c
@@ -172,7 +172,7 @@ static pg_prng_state prng_state;
 static char *pg_ctl_path = NULL;
 static char *pg_resetwal_path = NULL;
 
-static char logdir[MAXPGPATH]; /* Subdirectory of the user specified logdir
+static char *logdir = NULL;            /* Subdirectory of the user specified 
logdir
                                                                 * where the 
log files are written (if
                                                                 * specified) */
 
@@ -982,7 +982,6 @@ make_output_dirs(const char *log_basedir)
        struct timeval tval;
        time_t          now;
        struct tm       tmbuf;
-       int                     len;
 
        /* Generate timestamp */
        gettimeofday(&tval, NULL);
@@ -997,10 +996,7 @@ make_output_dirs(const char *log_basedir)
                         (unsigned int) (tval.tv_usec / 1000));
 
        /* Build timestamp directory path */
-       len = snprintf(logdir, MAXPGPATH, "%s/%s", log_basedir, timestamp);
-
-       if (len >= MAXPGPATH)
-               pg_fatal("directory path for log files is too long");
+       logdir = psprintf("%s/%s", log_basedir, timestamp);
 
        /* Create base directory (ignore if exists) */
        if (mkdir(log_basedir, pg_dir_create_mode) < 0 && errno != EEXIST)
-- 
2.53.0

Reply via email to