Skip to content

Commit 8b76f89

Browse files
committed
Refactor fallback to stderr for csvlog to handle better WIN32 service case
send_message_to_server_log() would force a redirection of a log entry to stderr in some cases for csvlog, like the syslogger not being available yet. If this happens, csvlog would fall back to stderr to log some information rather than nothing. The code was organized so as stderr is done before csvlog, with csvlog checking that stderr did not happen yet with a reversed condition. With this code organization, it could be possible to lose some messages if running Postgres as a service on WIN32, as there is no usable stderr, and the handling of the StringInfoData holding the message for stderr was rather confusing because of that. This commit moves the csvlog handling to be before stderr, as as we are able to track down if it is necessary to log something to stderr. The reduces the handling of stderr to be in a single code path, adding a fallback to event logs for a WIN32 service. This also simplifies the way we handle the StringInfoData for stderr, making easier the integration of new file-based log destinations. I got to play with services and event logs on Windows while checking this change. Reviewed-by: Chris Bandy Discussion: https://postgr.es/m/YV0vwBovEKf1WXkl@paquier.xyz
1 parent 08e2daf commit 8b76f89

File tree

1 file changed

+24
-30
lines changed

1 file changed

+24
-30
lines changed

src/backend/utils/error/elog.c

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3008,6 +3008,7 @@ static void
30083008
send_message_to_server_log(ErrorData *edata)
30093009
{
30103010
StringInfoData buf;
3011+
bool fallback_to_stderr = false;
30113012

30123013
initStringInfo(&buf);
30133014

@@ -3159,8 +3160,27 @@ send_message_to_server_log(ErrorData *edata)
31593160
}
31603161
#endif /* WIN32 */
31613162

3162-
/* Write to stderr, if enabled */
3163-
if ((Log_destination & LOG_DESTINATION_STDERR) || whereToSendOutput == DestDebug)
3163+
/* Write to csvlog, if enabled */
3164+
if (Log_destination & LOG_DESTINATION_CSVLOG)
3165+
{
3166+
/*
3167+
* Send CSV data if it's safe to do so (syslogger doesn't need the
3168+
* pipe). If this is not possible, fallback to an entry written to
3169+
* stderr.
3170+
*/
3171+
if (redirection_done || MyBackendType == B_LOGGER)
3172+
write_csvlog(edata);
3173+
else
3174+
fallback_to_stderr = true;
3175+
}
3176+
3177+
/*
3178+
* Write to stderr, if enabled or if required because of a previous
3179+
* limitation.
3180+
*/
3181+
if ((Log_destination & LOG_DESTINATION_STDERR) ||
3182+
whereToSendOutput == DestDebug ||
3183+
fallback_to_stderr)
31643184
{
31653185
/*
31663186
* Use the chunking protocol if we know the syslogger should be
@@ -3189,34 +3209,8 @@ send_message_to_server_log(ErrorData *edata)
31893209
if (MyBackendType == B_LOGGER)
31903210
write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_STDERR);
31913211

3192-
/* Write to CSV log if enabled */
3193-
if (Log_destination & LOG_DESTINATION_CSVLOG)
3194-
{
3195-
if (redirection_done || MyBackendType == B_LOGGER)
3196-
{
3197-
/*
3198-
* send CSV data if it's safe to do so (syslogger doesn't need the
3199-
* pipe). First get back the space in the message buffer.
3200-
*/
3201-
pfree(buf.data);
3202-
write_csvlog(edata);
3203-
}
3204-
else
3205-
{
3206-
/*
3207-
* syslogger not up (yet), so just dump the message to stderr,
3208-
* unless we already did so above.
3209-
*/
3210-
if (!(Log_destination & LOG_DESTINATION_STDERR) &&
3211-
whereToSendOutput != DestDebug)
3212-
write_console(buf.data, buf.len);
3213-
pfree(buf.data);
3214-
}
3215-
}
3216-
else
3217-
{
3218-
pfree(buf.data);
3219-
}
3212+
/* No more need of the message formatted for stderr */
3213+
pfree(buf.data);
32203214
}
32213215

32223216
/*

0 commit comments

Comments
 (0)