diff -cr postgresql-snapshot-030321/doc/src/sgml/maintenance.sgml postgresql-win32-mha/doc/src/sgml/maintenance.sgml
*** postgresql-snapshot-030321/doc/src/sgml/maintenance.sgml	Mon Mar 15 15:21:30 2004
--- postgresql-win32-mha/doc/src/sgml/maintenance.sgml	Sat Mar 27 20:39:42 2004
***************
*** 456,462 ****
     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
     <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
--- 456,462 ----
     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>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 -cr postgresql-snapshot-030321/doc/src/sgml/runtime.sgml postgresql-win32-mha/doc/src/sgml/runtime.sgml
*** postgresql-snapshot-030321/doc/src/sgml/runtime.sgml	Mon Mar 15 18:57:51 2004
--- postgresql-win32-mha/doc/src/sgml/runtime.sgml	Sat Mar 27 20:50:13 2004
***************
*** 473,479 ****
  <programlisting>
  # This is a comment
  log_connections = yes
! syslog = 2
  search_path = '$user, public'
  </programlisting>
      One parameter is specified per line. The equal sign between name and
--- 473,479 ----
  <programlisting>
  # This is a comment
  log_connections = yes
! log_destination = 'syslog'
  search_path = '$user, public'
  </programlisting>
      One parameter is specified per line. The equal sign between name and
***************
*** 501,507 ****
      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
  </programlisting>
      Command-line options override any conflicting settings in
      <filename>postgresql.conf</filename>.
--- 501,507 ----
      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 log_destination='syslog'
  </programlisting>
      Command-line options override any conflicting settings in
      <filename>postgresql.conf</filename>.
***************
*** 1682,1708 ****
       <primary>server log</primary>
      </indexterm>
  
!     <sect3 id="runtime-config-logging-syslog">
!      <title>Syslog</title>
  
!      <indexterm zone="runtime-config-logging-syslog">
!       <primary>syslog</primary>
       </indexterm>
  
       <variablelist>
  
!      <varlistentry id="guc-syslog" xreflabel="syslog">
!       <term><varname>syslog</varname> (<type>integer</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.
         </para>
        </listitem>
       </varlistentry>
--- 1682,1707 ----
       <primary>server log</primary>
      </indexterm>
  
!     <sect3 id="runtime-config-logging-where">
!      <title>Where to log</title>
  
!      <indexterm zone="runtime-config-logging-where">
!       <primary>where to log</primary>
       </indexterm>
  
       <variablelist>
  
!      <varlistentry id="guc-log-destination" xreflabel="log_destination">
!       <term><varname>log_destination</varname> (<type>string</type>)</term>
        <listitem>
         <para>
! 	<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 -cr postgresql-snapshot-030321/src/backend/utils/error/elog.c postgresql-win32-mha/src/backend/utils/error/elog.c
*** postgresql-snapshot-030321/src/backend/utils/error/elog.c	Tue Mar 23 22:51:53 2004
--- postgresql-win32-mha/src/backend/utils/error/elog.c	Tue Mar 23 22:31:32 2004
***************
*** 70,94 ****
  /* GUC parameters */
  PGErrorVerbosity Log_error_verbosity = PGERROR_VERBOSE;
  char       *Log_line_prefix = NULL; /* format for extra log line info */
  
  #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 */
! 
  
  /*
   * ErrorData holds the data accumulated during any one ereport() cycle.
--- 70,86 ----
  /* 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
  char	   *Syslog_facility;	/* openlog() parameters */
  char	   *Syslog_ident;
  
  static void write_syslog(int level, const char *line);
! #endif
! #ifdef WIN32
! static void write_eventlog(int level, const char *line);
! #endif
  
  /*
   * ErrorData holds the data accumulated during any one ereport() cycle.
***************
*** 924,932 ****
  
  	int			len = strlen(line);
  
- 	if (Use_syslog == 0)
- 		return;
- 
  	if (!openlog_done)
  	{
  		if (strcasecmp(Syslog_facility, "LOCAL0") == 0)
--- 916,921 ----
***************
*** 1018,1023 ****
--- 1007,1040 ----
  	}
  }
  #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.
***************
*** 1252,1258 ****
  
  #ifdef HAVE_SYSLOG
  	/* Write to syslog, if enabled */
! 	if (Use_syslog >= 1)
  	{
  		int			syslog_level;
  
--- 1269,1275 ----
  
  #ifdef HAVE_SYSLOG
  	/* Write to syslog, if enabled */
! 	if (Log_destination & LOG_DESTINATION_SYSLOG)
  	{
  		int			syslog_level;
  
***************
*** 1289,1297 ****
  		write_syslog(syslog_level, buf.data);
  	}
  #endif   /* HAVE_SYSLOG */
! 
  	/* Write to stderr, if enabled */
! 	if (Use_syslog <= 1 || whereToSendOutput == Debug)
  	{
  		fprintf(stderr, "%s", buf.data);
  	}
--- 1306,1343 ----
  		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 ((Log_destination & LOG_DESTINATION_STDERR) || whereToSendOutput == Debug)
  	{
  		fprintf(stderr, "%s", buf.data);
  	}
diff -cr postgresql-snapshot-030321/src/backend/utils/misc/guc.c postgresql-win32-mha/src/backend/utils/misc/guc.c
*** postgresql-snapshot-030321/src/backend/utils/misc/guc.c	Tue Mar 23 22:51:53 2004
--- postgresql-win32-mha/src/backend/utils/misc/guc.c	Tue Mar 23 22:47:49 2004
***************
*** 75,80 ****
--- 75,83 ----
  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,148 ****
--- 146,152 ----
  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,286 ****
  	gettext_noop("Query Tuning / Other Planner Options"),
  	/* LOGGING */
  	gettext_noop("Reporting and Logging"),
! 	/* LOGGING_SYSLOG */
! 	gettext_noop("Reporting and Logging / Syslog"),
  	/* LOGGING_WHEN */
  	gettext_noop("Reporting and Logging / When to Log"),
  	/* LOGGING_WHAT */
--- 283,290 ----
  	gettext_noop("Query Tuning / Other Planner Options"),
  	/* LOGGING */
  	gettext_noop("Reporting and Logging"),
! 	/* LOGGING_WHERE */
! 	gettext_noop("Reporting and Logging / Where to Log"),
  	/* LOGGING_WHEN */
  	gettext_noop("Reporting and Logging / When to Log"),
  	/* LOGGING_WHAT */
***************
*** 941,960 ****
  		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
--- 945,950 ----
***************
*** 1651,1659 ****
  		NULL, assign_session_authorization, show_session_authorization
  	},
  
  #ifdef HAVE_SYSLOG
  	{
! 		{"syslog_facility", PGC_POSTMASTER, LOGGING_SYSLOG,
  			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.")
--- 1641,1660 ----
  		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_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.")
***************
*** 1662,1668 ****
  		"LOCAL0", assign_facility, NULL
  	},
  	{
! 		{"syslog_ident", PGC_POSTMASTER, LOGGING_SYSLOG,
  			gettext_noop("Sets the program name used to identify PostgreSQL messages "
  						 "in syslog."),
  			NULL
--- 1663,1669 ----
  		"LOCAL0", assign_facility, NULL
  	},
  	{
! 		{"syslog_ident", PGC_POSTMASTER, LOGGING_WHERE,
  			gettext_noop("Sets the program name used to identify PostgreSQL messages "
  						 "in syslog."),
  			NULL
***************
*** 4415,4420 ****
--- 4416,4483 ----
  /*
   * 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
  
diff -cr postgresql-snapshot-030321/src/backend/utils/misc/postgresql.conf.sample postgresql-win32-mha/src/backend/utils/misc/postgresql.conf.sample
*** postgresql-snapshot-030321/src/backend/utils/misc/postgresql.conf.sample	Tue Mar 23 22:51:53 2004
--- postgresql-win32-mha/src/backend/utils/misc/postgresql.conf.sample	Tue Mar 23 22:39:44 2004
***************
*** 145,153 ****
  # ERROR REPORTING AND LOGGING
  #---------------------------------------------------------------------------
  
! # - Syslog -
  
! #syslog = 0			# range 0-2; 0=stdout; 1=both; 2=syslog
  #syslog_facility = 'LOCAL0'
  #syslog_ident = 'postgres'
  
--- 145,155 ----
  # ERROR REPORTING AND LOGGING
  #---------------------------------------------------------------------------
  
! # - Where to Log -
  
! #log_destination = 'stderr'	# Valid values are combinations of stderr,
!                                 # syslog and eventlog, depending on
!                                 # platform.
  #syslog_facility = 'LOCAL0'
  #syslog_ident = 'postgres'
  
diff -cr postgresql-snapshot-030321/src/bin/psql/tab-complete.c postgresql-win32-mha/src/bin/psql/tab-complete.c
*** postgresql-snapshot-030321/src/bin/psql/tab-complete.c	Tue Feb  3 18:34:03 2004
--- postgresql-win32-mha/src/bin/psql/tab-complete.c	Sat Mar 27 20:34:40 2004
***************
*** 523,528 ****
--- 523,529 ----
  		"lc_monetary",
  		"lc_numeric",
  		"lc_time",
+ 		"log_destination",
  		"log_duration",
  		"log_error_verbosity",
  		"log_executor_stats",
***************
*** 557,563 ****
  		"stats_row_level",
  		"stats_start_collector",
  		"superuser_reserved_connections",
- 		"syslog",
  		"syslog_facility",
  		"syslog_ident",
  		"tcpip_socket",
--- 558,563 ----
diff -cr postgresql-snapshot-030321/src/include/utils/elog.h postgresql-win32-mha/src/include/utils/elog.h
*** postgresql-snapshot-030321/src/include/utils/elog.h	Tue Mar 23 22:51:53 2004
--- postgresql-win32-mha/src/include/utils/elog.h	Tue Mar 23 22:26:23 2004
***************
*** 170,180 ****
  
  extern PGErrorVerbosity Log_error_verbosity;
  extern char *Log_line_prefix;
  
! #ifdef HAVE_SYSLOG
! extern int	Use_syslog;
! #endif
! 
  
  /* Other exported functions */
  extern void DebugFileOpen(void);
--- 170,181 ----
  
  extern PGErrorVerbosity Log_error_verbosity;
  extern char *Log_line_prefix;
+ extern unsigned int Log_destination;
  
! /* 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 -cr postgresql-snapshot-030321/src/include/utils/guc_tables.h postgresql-win32-mha/src/include/utils/guc_tables.h
*** postgresql-snapshot-030321/src/include/utils/guc_tables.h	Tue Mar 23 22:51:53 2004
--- postgresql-win32-mha/src/include/utils/guc_tables.h	Tue Mar 23 22:09:29 2004
***************
*** 36,42 ****
  	QUERY_TUNING_GEQO,
  	QUERY_TUNING_OTHER,
  	LOGGING,
! 	LOGGING_SYSLOG,
  	LOGGING_WHEN,
  	LOGGING_WHAT,
  	STATS,
--- 36,42 ----
  	QUERY_TUNING_GEQO,
  	QUERY_TUNING_OTHER,
  	LOGGING,
! 	LOGGING_WHERE,
  	LOGGING_WHEN,
  	LOGGING_WHAT,
  	STATS,
