diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index afdb53f9b553c0cb558ab3463e1eb82a14f04546..841b5ec61d04c50d40a539415d737b57f093edb3 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1164,7 +1164,17 @@ PostmasterMain(int argc, char *argv[])
 	 * Log_destination permits.  We don't do this until the postmaster is
 	 * fully launched, since startup failures may as well be reported to
 	 * stderr.
+	 *
+	 * If we are in fact disabling logging to stderr, first emit a log message
+	 * saying so, to provide a breadcrumb trail for users who may not remember
+	 * that their logging is configured to go somewhere else.
 	 */
+	if (!(Log_destination & LOG_DESTINATION_STDERR))
+		ereport(LOG,
+				(errmsg("ending log output to stderr"),
+				 errhint("Future log output will go to log destination \"%s\".",
+						 Log_destination_string)));
+
 	whereToSendOutput = DestNone;
 
 	/*
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index e3b6102516285c3051412c8b7b8c3ad8b435fc75..8b00aa525b2f57e308886c35e12a8cc7f9b979b0 100644
--- a/src/backend/postmaster/syslogger.c
+++ b/src/backend/postmaster/syslogger.c
@@ -634,6 +634,20 @@ SysLogger_Start(void)
 			/* now we redirect stderr, if not done already */
 			if (!redirection_done)
 			{
+#ifdef WIN32
+				int			fd;
+#endif
+
+				/*
+				 * Leave a breadcrumb trail when redirecting, in case the user
+				 * forgets that redirection is active and looks only at the
+				 * original stderr target file.
+				 */
+				ereport(LOG,
+						(errmsg("redirecting log output to logging collector process"),
+						 errhint("Future log output will appear in directory \"%s\".",
+								 Log_directory)));
+
 #ifndef WIN32
 				fflush(stdout);
 				if (dup2(syslogPipe[1], fileno(stdout)) < 0)
@@ -649,8 +663,6 @@ SysLogger_Start(void)
 				close(syslogPipe[1]);
 				syslogPipe[1] = -1;
 #else
-				int			fd;
-
 				/*
 				 * open the pipe in binary mode and make sure stderr is binary
 				 * after it's been dup'ed into, to avoid disturbing the pipe
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index a812ccd1c29986e3f47d90ed49dec4dfce2febfa..a415b907b6af930443cc5f7eab38025da1da3f6e 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -109,6 +109,7 @@ emit_log_hook_type emit_log_hook = NULL;
 int			Log_error_verbosity = PGERROR_VERBOSE;
 char	   *Log_line_prefix = NULL;		/* format for extra log line info */
 int			Log_destination = LOG_DESTINATION_STDERR;
+char	   *Log_destination_string = NULL;
 
 #ifdef HAVE_SYSLOG
 
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 047dfd126936976bb12a70e547748a1a2050f40a..0b23c38adfad2feb8cc709f9ed7bc782e48d90a8 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -444,8 +444,6 @@ int			tcp_keepalives_count;
  * cases provide the value for SHOW to display.  The real state is elsewhere
  * and is kept in sync by assign_hooks.
  */
-static char *log_destination_string;
-
 static char *syslog_ident_str;
 static bool phony_autocommit;
 static bool session_auth_is_superuser;
@@ -2871,7 +2869,7 @@ static struct config_string ConfigureNamesString[] =
 						 "depending on the platform."),
 			GUC_LIST_INPUT
 		},
-		&log_destination_string,
+		&Log_destination_string,
 		"stderr",
 		check_log_destination, assign_log_destination, NULL
 	},
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 6df0d379f4f77973e0b42498999e99b3164bb2fd..59d6f5e813110b6523e307dc7d25c4015ea9a524 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -428,6 +428,7 @@ typedef enum
 extern int	Log_error_verbosity;
 extern char *Log_line_prefix;
 extern int	Log_destination;
+extern char *Log_destination_string;
 
 /* Log destination bitmap */
 #define LOG_DESTINATION_STDERR	 1