diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml new file mode 100644 index 5d37065..46260d0 *** a/doc/src/sgml/config.sgml --- b/doc/src/sgml/config.sgml *************** local0.* /var/log/postgresql *** 2949,2954 **** --- 2949,2961 ---- to the syslog daemon's configuration file to make it work. + + On Windows, you need to register an event source + and its library with the operating system in order + to make use of the eventlog option for + log_destination. + See for details. + *************** local0.* /var/log/postgresql *** 3189,3194 **** --- 3196,3219 ---- PostgreSQL messages in syslog logs. The default is postgres. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + event_source (string) + + event_source configuration parameter + + + + When logging to event log is enabled, this parameter + determines the program name used to identify + PostgreSQL messages in + event log. The default is + PostgreSQL. This parameter can only be set in the postgresql.conf file or on the server command line. diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml new file mode 100644 index 96387bd..262b91a *** a/doc/src/sgml/installation.sgml --- b/doc/src/sgml/installation.sgml *************** PostgreSQL, contrib and HTML documentati *** 1551,1569 **** - Registering <application>eventlog</> on <systemitem - class="osname">Windows</>: - - To register a Windows eventlog - library with the operating system, issue this command after installation: - - regsvr32 pgsql_library_directory/pgevent.dll - - This creates registry entries used by the event viewer. - - - - Uninstallation: To undo the installation use the command gmake --- 1551,1556 ---- diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml new file mode 100644 index d18ba79..9a8a22d *** a/doc/src/sgml/runtime.sgml --- b/doc/src/sgml/runtime.sgml *************** ssh -L 63333:db.foo.com:5432 joe@shell.f *** 2294,2297 **** --- 2294,2347 ---- + + Registering <application>Event Log</> on <systemitem + class="osname">Windows</> + + + event log + event log + + + + To register a Windows event log + library with the operating system, issue this command: + + regsvr32 pgsql_library_directory/pgevent.dll + + This creates registry entries used by the event viewer, under the default event + source named "PostgreSQL". + + + + You can specify the event source name with /i option. In this case, -n option + is necessary, too: + + regsvr32 /n /i:event_source_name + pgsql_library_directory/pgevent.dll + + You also need to set in + postgresql.conf. Note that the event source specification + only takes effect for the database server. Other applications like + pg_ctl always use "PostgreSQL" event source. + + + + To unregister the event log library from + the operating system, issue this command: + + regsvr32 /u [/i:event_source_name] + pgsql_library_directory/pgevent.dll + + + + + + To enable event logging in the database server, modify + to include + eventlog in postgresql.conf. + + + + diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c new file mode 100644 index 337b875..0744987 *** a/src/backend/utils/error/elog.c --- b/src/backend/utils/error/elog.c *************** static void write_syslog(int level, cons *** 122,127 **** --- 122,129 ---- static void write_console(const char *line, int len); #ifdef WIN32 + static char *event_source = NULL; + static void write_eventlog(int level, const char *line, int len); #endif *************** write_syslog(int level, const char *line *** 1633,1638 **** --- 1635,1655 ---- #endif /* HAVE_SYSLOG */ #ifdef WIN32 + + /* + * Set or update the parameters for event log logging + */ + void + set_eventlog_parameters(const char *source) + { + if (event_source == NULL || strcmp(event_source, source) != 0) + { + if (event_source) + free(event_source); + event_source = strdup(source); + } + } + /* * Write a message line to the windows event log */ *************** write_eventlog(int level, const char *li *** 1645,1651 **** if (evtHandle == INVALID_HANDLE_VALUE) { ! evtHandle = RegisterEventSource(NULL, "PostgreSQL"); if (evtHandle == NULL) { evtHandle = INVALID_HANDLE_VALUE; --- 1662,1668 ---- if (evtHandle == INVALID_HANDLE_VALUE) { ! evtHandle = RegisterEventSource(NULL, event_source ? event_source : "PostgreSQL"); if (evtHandle == NULL) { evtHandle = INVALID_HANDLE_VALUE; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c new file mode 100644 index 92391ed..07ce52d *** a/src/backend/utils/misc/guc.c --- b/src/backend/utils/misc/guc.c *************** static int syslog_facility = 0; *** 175,180 **** --- 175,183 ---- static void assign_syslog_facility(int newval, void *extra); static void assign_syslog_ident(const char *newval, void *extra); + #ifdef WIN32 + static void assign_event_source(const char *newval, void *extra); + #endif static void assign_session_replication_role(int newval, void *extra); static bool check_temp_buffers(int *newval, void **extra, GucSource source); static bool check_phony_autocommit(bool *newval, void **extra, GucSource source); *************** int tcp_keepalives_count; *** 449,454 **** --- 452,460 ---- static char *log_destination_string; static char *syslog_ident_str; + #ifdef WIN32 + static char *event_source_str; + #endif static bool phony_autocommit; static bool session_auth_is_superuser; static double phony_random_seed; *************** static struct config_string ConfigureNam *** 2822,2827 **** --- 2828,2846 ---- NULL, assign_syslog_ident, NULL }, + #ifdef WIN32 + { + {"event_source", PGC_POSTMASTER, LOGGING_WHERE, + gettext_noop("Sets the program name used to identify PostgreSQL " + "messages in event log."), + NULL + }, + &event_source_str, + "PostgreSQL", + NULL, assign_event_source, NULL + }, + #endif + { {"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE, gettext_noop("Sets the time zone for displaying and interpreting time stamps."), *************** assign_syslog_ident(const char *newval, *** 8213,8218 **** --- 8232,8245 ---- #endif /* Without syslog support, it will always be set to "none", so ignore */ } + + #ifdef WIN32 + static void + assign_event_source(const char *newval, void *extra) + { + set_eventlog_parameters(newval); + } + #endif static void diff --git a/src/bin/pgevent/pgevent.c b/src/bin/pgevent/pgevent.c new file mode 100644 index 1fcde86..402d00a *** a/src/bin/pgevent/pgevent.c --- b/src/bin/pgevent/pgevent.c *************** *** 15,31 **** --- 15,75 ---- #include #include #include + #include + #include + #include /* Global variables */ HANDLE g_module = NULL; /* hModule of DLL */ + /* + * The event source is stored as a registry key. + * The maximum length of a registry key is 255 characters. + * http://msdn.microsoft.com/en-us/library/ms724872(v=vs.85).aspx + */ + _TCHAR event_source[256] = _T("PostgreSQL"); /* Prototypes */ + HRESULT DllInstall(BOOL bInstall, __in_opt LPCWSTR pszCmdLine); STDAPI DllRegisterServer(void); STDAPI DllUnregisterServer(void); BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved); /* + * DllInstall --- Passes the command line argument to DLL + */ + + HRESULT + DllInstall(BOOL bInstall, + __in_opt LPCWSTR pszCmdLine) + { + #ifndef _UNICODE + size_t ret; + #endif + + if (pszCmdLine && *pszCmdLine != '\0') + #ifdef _UNICODE + _tcsncpy(event_source, pszCmdLine, sizeof(event_source)); + #else + wcstombs_s(&ret, event_source, sizeof(event_source), + pszCmdLine, sizeof(event_source)); + #endif + + /* + * This is an ugry part due to the strange behavior of "regsvr32 /i". + * When installing, regsvr32 calls DllRegisterServer before DllInstall. + * When uninstalling (i.e. "regsvr32 /u /i"), on the other hand, + * regsvr32 calls DllInstall and then DllUnregisterServer as expected. + * This strange behavior forces us to specify -n (i.e. "regsvr32 /n /i"). + * Without -n, DllRegisterServer called before DllInstall would + * mistakenly overwrite the default "PostgreSQL" event source registration. + */ + if (bInstall) + DllRegisterServer(); + return S_OK; + } + + /* * DllRegisterServer --- Instructs DLL to create its registry entries */ *************** DllRegisterServer(void) *** 35,40 **** --- 79,85 ---- HKEY key; DWORD data; char buffer[_MAX_PATH]; + _TCHAR key_name[400]; /* Set the name of DLL full path name. */ if (!GetModuleFileName((HMODULE) g_module, buffer, sizeof(buffer))) *************** DllRegisterServer(void) *** 47,53 **** * Add PostgreSQL source name as a subkey under the Application key in the * EventLog registry key. */ ! if (RegCreateKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\PostgreSQL", &key)) { MessageBox(NULL, "Could not create the registry key.", "PostgreSQL error", MB_OK | MB_ICONSTOP); return SELFREG_E_TYPELIB; --- 92,101 ---- * Add PostgreSQL source name as a subkey under the Application key in the * EventLog registry key. */ ! _sntprintf(key_name, sizeof(key_name), ! _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s"), ! event_source); ! if (RegCreateKey(HKEY_LOCAL_MACHINE, key_name, &key)) { MessageBox(NULL, "Could not create the registry key.", "PostgreSQL error", MB_OK | MB_ICONSTOP); return SELFREG_E_TYPELIB; *************** DllRegisterServer(void) *** 90,101 **** STDAPI DllUnregisterServer(void) { /* * Remove PostgreSQL source name as a subkey under the Application key in * the EventLog registry key. */ ! if (RegDeleteKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\PostgreSQL")) { MessageBox(NULL, "Could not delete the registry key.", "PostgreSQL error", MB_OK | MB_ICONSTOP); return SELFREG_E_TYPELIB; --- 138,154 ---- STDAPI DllUnregisterServer(void) { + _TCHAR key_name[400]; + /* * Remove PostgreSQL source name as a subkey under the Application key in * the EventLog registry key. */ ! _sntprintf(key_name, sizeof(key_name), ! _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s"), ! event_source); ! if (RegDeleteKey(HKEY_LOCAL_MACHINE, key_name)) { MessageBox(NULL, "Could not delete the registry key.", "PostgreSQL error", MB_OK | MB_ICONSTOP); return SELFREG_E_TYPELIB; diff --git a/src/bin/pgevent/pgevent.def b/src/bin/pgevent/pgevent.def new file mode 100644 index 21bab7a..6b4d44a *** a/src/bin/pgevent/pgevent.def --- b/src/bin/pgevent/pgevent.def *************** *** 2,4 **** --- 2,5 ---- EXPORTS DllUnregisterServer ; DllRegisterServer ; + DllInstall ; diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h new file mode 100644 index 4a3bd02..48bc784 *** a/src/include/utils/elog.h --- b/src/include/utils/elog.h *************** extern void DebugFileOpen(void); *** 353,358 **** --- 353,362 ---- extern char *unpack_sql_state(int sql_state); extern bool in_error_recursion_trouble(void); + #ifdef WIN32 + extern void set_eventlog_parameters(const char *source); + #endif + #ifdef HAVE_SYSLOG extern void set_syslog_parameters(const char *ident, int facility); #endif