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	Mon Mar 22 23:40:13 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	Mon Mar 22 23:40:13 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	Mon Mar 15 16:56:26 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/include/utils/elog.h postgresql-win32-mha/src/include/utils/elog.h
*** postgresql-snapshot-030321/src/include/utils/elog.h	Mon Mar 22 23:40:13 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	Mon Jan 19 20:04:40 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,
