From 6165bbab8cb3518269e24bf9ced0be443f05e66c Mon Sep 17 00:00:00 2001 From: Bruce Momjian <bruce@momjian.us> Date: Mon, 5 Apr 2004 03:02:11 +0000 Subject: [PATCH] Remove 'syslog' GUC variable, and add more logical 'log_destination' variable to control logoutput location on Unix and Win32. Magnus Hagander --- doc/src/sgml/maintenance.sgml | 4 +- doc/src/sgml/runtime.sgml | 33 +++--- src/backend/utils/error/elog.c | 86 +++++++++++---- src/backend/utils/misc/guc.c | 101 ++++++++++++++---- src/backend/utils/misc/postgresql.conf.sample | 6 +- src/bin/psql/tab-complete.c | 4 +- src/include/utils/elog.h | 11 +- src/include/utils/guc_tables.h | 4 +- 8 files changed, 180 insertions(+), 69 deletions(-) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 8318160c3f6..9dc89b1c5b8 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.32 2004/03/15 14:21:30 momjian Exp $ +$PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.33 2004/04/05 03:02:03 momjian Exp $ --> <chapter id="maintenance"> @@ -456,7 +456,7 @@ VACUUM The simplest production-grade approach to managing log output is to send it all to <application>syslog</> and let <application>syslog</> deal with file rotation. To do this, set the - configurations parameter <literal>syslog</> to 2 (to log to + configurations parameter <literal>log_destination</> to 'syslog' (to log to <application>syslog</> only) in <filename>postgresql.conf</>. Then you can send a <literal>SIGHUP</literal> signal to the <application>syslog</> daemon whenever you want to force it to diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 33684e6201e..f23772b8da7 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.256 2004/03/31 19:59:22 momjian Exp $ +$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.257 2004/04/05 03:02:03 momjian Exp $ --> <Chapter Id="runtime"> @@ -469,7 +469,7 @@ psql: could not connect to server: No such file or directory <programlisting> # This is a comment log_connections = yes -syslog = 2 +log_destination = 'syslog' search_path = '$user, public' </programlisting> One parameter is specified per line. The equal sign between name and @@ -497,7 +497,7 @@ search_path = '$user, public' A second way to set these configuration parameters is to give them as a command line option to the <command>postmaster</command>, such as: <programlisting> -postmaster -c log_connections=yes -c syslog=2 +postmaster -c log_connections=yes -c log_destination='syslog' </programlisting> Command-line options override any conflicting settings in <filename>postgresql.conf</filename>. @@ -1705,27 +1705,26 @@ SET ENABLE_SEQSCAN TO OFF; <primary>server log</primary> </indexterm> - <sect3 id="runtime-config-logging-syslog"> - <title>Syslog</title> + <sect3 id="runtime-config-logging-where"> + <title>Where to log</title> - <indexterm zone="runtime-config-logging-syslog"> - <primary>syslog</primary> + <indexterm zone="runtime-config-logging-where"> + <primary>where to log</primary> </indexterm> <variablelist> - <varlistentry id="guc-syslog" xreflabel="syslog"> - <term><varname>syslog</varname> (<type>integer</type>)</term> + <varlistentry id="guc-log-destination" xreflabel="log_destination"> + <term><varname>log_destination</varname> (<type>string</type>)</term> <listitem> <para> - <productname>PostgreSQL</productname> allows the use of - <systemitem>syslog</systemitem> for logging. If this option is - set to 1, messages go both to <systemitem>syslog</> and the - standard output. A setting of 2 sends output only to - <systemitem>syslog</>. (Some messages will still go to the - standard output/error.) The default is 0, which means - <systemitem>syslog</> is off. This option must be set at server - start. + <productname>PostgreSQL</productname> supports several methods + for loggning, including <systemitem>stderr</systemitem> and + <systemitem>syslog</systemitem>. On Windows, + <systemitem>eventlog</systemitem> is also supported. Set this + option to a list of desired log destinations separated by a + comma. The default is to log to <systemitem>stderr</systemitem> + only. This option must be set at server start. </para> </listitem> </varlistentry> diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 37c5b36e09d..96366333f06 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.131 2004/03/22 15:34:22 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.132 2004/04/05 03:02:06 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -70,25 +70,17 @@ ErrorContextCallback *error_context_stack = NULL; /* GUC parameters */ PGErrorVerbosity Log_error_verbosity = PGERROR_VERBOSE; char *Log_line_prefix = NULL; /* format for extra log line info */ +unsigned int Log_destination; #ifdef HAVE_SYSLOG -/* - * 0 = only stdout/stderr - * 1 = stdout+stderr and syslog - * 2 = syslog only - * ... in theory anyway - */ -int Use_syslog = 0; char *Syslog_facility; /* openlog() parameters */ char *Syslog_ident; static void write_syslog(int level, const char *line); - -#else - -#define Use_syslog 0 -#endif /* HAVE_SYSLOG */ - +#endif +#ifdef WIN32 +static void write_eventlog(int level, const char *line); +#endif /* * ErrorData holds the data accumulated during any one ereport() cycle. @@ -1005,9 +997,6 @@ write_syslog(int level, const char *line) int len = strlen(line); - if (Use_syslog == 0) - return; - if (!openlog_done) { if (strcasecmp(Syslog_facility, "LOCAL0") == 0) @@ -1099,6 +1088,34 @@ write_syslog(int level, const char *line) } } #endif /* HAVE_SYSLOG */ +#ifdef WIN32 +/* + * Write a message line to the windows event log + */ +static void +write_eventlog(int level, const char *line) +{ + static HANDLE evtHandle = INVALID_HANDLE_VALUE; + + if (evtHandle == INVALID_HANDLE_VALUE) { + evtHandle = RegisterEventSource(NULL,"PostgreSQL"); + if (evtHandle == NULL) { + evtHandle = INVALID_HANDLE_VALUE; + return; + } + } + + ReportEvent(evtHandle, + level, + 0, + 0, /* All events are Id 0 */ + NULL, + 1, + 0, + &line, + NULL); +} +#endif /* WIN32*/ /* * Format tag info for log lines; append to the provided buffer. @@ -1344,7 +1361,7 @@ send_message_to_server_log(ErrorData *edata) #ifdef HAVE_SYSLOG /* Write to syslog, if enabled */ - if (Use_syslog >= 1) + if (Log_destination & LOG_DESTINATION_SYSLOG) { int syslog_level; @@ -1381,9 +1398,38 @@ send_message_to_server_log(ErrorData *edata) write_syslog(syslog_level, buf.data); } #endif /* HAVE_SYSLOG */ - +#ifdef WIN32 + if (Log_destination & LOG_DESTINATION_EVENTLOG) + { + int eventlog_level; + switch (edata->elevel) + { + case DEBUG5: + case DEBUG4: + case DEBUG3: + case DEBUG2: + case DEBUG1: + case LOG: + case COMMERROR: + case INFO: + case NOTICE: + eventlog_level = EVENTLOG_INFORMATION_TYPE; + break; + case WARNING: + eventlog_level = EVENTLOG_WARNING_TYPE; + break; + case ERROR: + case FATAL: + case PANIC: + default: + eventlog_level = EVENTLOG_ERROR_TYPE; + break; + } + write_eventlog(eventlog_level, buf.data); + } +#endif /* WIN32 */ /* Write to stderr, if enabled */ - if (Use_syslog <= 1 || whereToSendOutput == Debug) + if ((Log_destination & LOG_DESTINATION_STDERR) || whereToSendOutput == Debug) { fprintf(stderr, "%s", buf.data); } diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index b58bba82e1b..215378749b6 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut <peter_e@gmx.net>. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.196 2004/04/05 02:48:09 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.197 2004/04/05 03:02:07 momjian Exp $ * *-------------------------------------------------------------------- */ @@ -75,6 +75,9 @@ extern int CommitSiblings; extern char *preload_libraries_string; extern int DebugSharedBuffers; +static const char *assign_log_destination(const char *value, + bool doit, GucSource source); + #ifdef HAVE_SYSLOG extern char *Syslog_facility; extern char *Syslog_ident; @@ -143,6 +146,7 @@ static char *client_min_messages_str; static char *log_min_messages_str; static char *log_error_verbosity_str; static char *log_min_error_statement_str; +static char *log_destination_string; static bool phony_autocommit; static bool session_auth_is_superuser; static double phony_random_seed; @@ -279,8 +283,8 @@ const char *const config_group_names[] = gettext_noop("Query Tuning / Other Planner Options"), /* LOGGING */ gettext_noop("Reporting and Logging"), - /* LOGGING_SYSLOG */ - gettext_noop("Reporting and Logging / Syslog"), + /* LOGGING_WHERE */ + gettext_noop("Reporting and Logging / Where to Log"), /* LOGGING_WHEN */ gettext_noop("Reporting and Logging / When to Log"), /* LOGGING_WHAT */ @@ -933,20 +937,6 @@ static struct config_int ConfigureNamesInt[] = 1000, 0, INT_MAX, NULL, NULL }, -#ifdef HAVE_SYSLOG - { - {"syslog", PGC_SIGHUP, LOGGING_SYSLOG, - gettext_noop("Uses syslog for logging."), - gettext_noop("If this parameter is 1, messages go both to syslog " - "and the standard output. A value of 2 sends output only to syslog. " - "(Some messages will still go to the standard output/error.) The " - "default is 0, which means syslog is off.") - }, - &Use_syslog, - 0, 0, 2, NULL, NULL - }, -#endif - /* * Note: There is some postprocessing done in PostmasterMain() to make * sure the buffers are at least twice the number of backends, so the @@ -1644,9 +1634,20 @@ static struct config_string ConfigureNamesString[] = NULL, assign_session_authorization, show_session_authorization }, + { + {"log_destination", PGC_POSTMASTER, LOGGING_WHERE, + gettext_noop("Sets the target for log output."), + gettext_noop("Valid values are combinations of stderr, syslog " + "and eventlog, depending on platform."), + GUC_LIST_INPUT | GUC_REPORT + }, + &log_destination_string, + "stderr", assign_log_destination, NULL + }, + #ifdef HAVE_SYSLOG { - {"syslog_facility", PGC_POSTMASTER, LOGGING_SYSLOG, + {"syslog_facility", PGC_POSTMASTER, LOGGING_WHERE, gettext_noop("Sets the syslog \"facility\" to be used when syslog enabled."), gettext_noop("Valid values are LOCAL0, LOCAL1, LOCAL2, LOCAL3, " "LOCAL4, LOCAL5, LOCAL6, LOCAL7.") @@ -1655,7 +1656,7 @@ static struct config_string ConfigureNamesString[] = "LOCAL0", assign_facility, NULL }, { - {"syslog_ident", PGC_POSTMASTER, LOGGING_SYSLOG, + {"syslog_ident", PGC_POSTMASTER, LOGGING_WHERE, gettext_noop("Sets the program name used to identify PostgreSQL messages " "in syslog."), NULL @@ -4418,6 +4419,68 @@ GUCArrayDelete(ArrayType *array, const char *name) * assign_hook subroutines */ +static const char * +assign_log_destination(const char *value, bool doit, GucSource source) +{ + char *rawstring; + List *elemlist; + List *l; + unsigned int newlogdest = 0; + + /* Need a modifiable copy of string */ + rawstring = pstrdup(value); + + /* Parse string into list of identifiers */ + if (!SplitIdentifierString(rawstring, ',', &elemlist)) + { + /* syntax error in list */ + pfree(rawstring); + freeList(elemlist); + if (source >= PGC_S_INTERACTIVE) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid list syntax for parameter \"log_destination\""))); + return NULL; + } + + foreach(l, elemlist) + { + char *tok = (char *) lfirst(l); + + if (strcasecmp(tok,"stderr") == 0) + newlogdest |= LOG_DESTINATION_STDERR; +#ifdef HAVE_SYSLOG + else if (strcasecmp(tok,"syslog") == 0) + newlogdest |= LOG_DESTINATION_SYSLOG; +#endif +#ifdef WIN32 + else if (strcasecmp(tok,"eventlog") == 0) + newlogdest |= LOG_DESTINATION_EVENTLOG; +#endif + else { + if (source >= PGC_S_INTERACTIVE) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("unrecognised \"log_destination\" key word: \"%s\"", + tok))); + pfree(rawstring); + freeList(elemlist); + return NULL; + } + } + + pfree(rawstring); + freeList(elemlist); + + /* If we aren't going to do the assignment, just return OK indicator. */ + if (!doit) + return value; + + Log_destination = newlogdest; + + return value; +} + #ifdef HAVE_SYSLOG static const char * diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 0001a9ffbb3..536e3de0c06 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -145,9 +145,11 @@ # ERROR REPORTING AND LOGGING #--------------------------------------------------------------------------- -# - Syslog - +# - Where to Log - -#syslog = 0 # range 0-2; 0=stdout; 1=both; 2=syslog +#log_destination = 'stderr' # Valid values are combinations of stderr, + # syslog and eventlog, depending on + # platform. #syslog_facility = 'LOCAL0' #syslog_ident = 'postgres' diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index ff9e8c499dc..ba3039d9930 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2003, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.103 2004/03/24 22:40:29 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.104 2004/04/05 03:02:09 momjian Exp $ */ /*---------------------------------------------------------------------- @@ -523,6 +523,7 @@ psql_completion(char *text, int start, int end) "lc_monetary", "lc_numeric", "lc_time", + "log_destination", "log_duration", "log_error_verbosity", "log_executor_stats", @@ -557,7 +558,6 @@ psql_completion(char *text, int start, int end) "stats_row_level", "stats_start_collector", "superuser_reserved_connections", - "syslog", "syslog_facility", "syslog_ident", "TimeZone", diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 24db6696e66..e3c8f9152ab 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.67 2004/03/21 22:29:11 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.68 2004/04/05 03:02:10 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -176,11 +176,12 @@ typedef enum extern PGErrorVerbosity Log_error_verbosity; extern char *Log_line_prefix; +extern unsigned int Log_destination; -#ifdef HAVE_SYSLOG -extern int Use_syslog; -#endif - +/* Log destination bitmap */ +#define LOG_DESTINATION_STDERR 1 +#define LOG_DESTINATION_SYSLOG 2 +#define LOG_DESTINATION_EVENTLOG 4 /* Other exported functions */ extern void DebugFileOpen(void); diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h index 47e0339dafa..1b99bf8159d 100644 --- a/src/include/utils/guc_tables.h +++ b/src/include/utils/guc_tables.h @@ -7,7 +7,7 @@ * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/include/utils/guc_tables.h,v 1.9 2004/01/19 19:04:40 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/guc_tables.h,v 1.10 2004/04/05 03:02:11 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -36,7 +36,7 @@ enum config_group QUERY_TUNING_GEQO, QUERY_TUNING_OTHER, LOGGING, - LOGGING_SYSLOG, + LOGGING_WHERE, LOGGING_WHEN, LOGGING_WHAT, STATS, -- GitLab