From d8ea33f2c02721c89c2434b9fda170afb7fe4999 Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Tue, 25 Oct 2011 20:02:55 +0200 Subject: [PATCH] Support configurable eventlog application names on Windows This allows different instances to use the eventlog with different identifiers, by setting the event_source GUC, similar to how syslog_ident works. Original patch by MauMau, heavily modified by Magnus Hagander --- doc/src/sgml/config.sgml | 25 ++++++++ doc/src/sgml/installation.sgml | 13 ----- doc/src/sgml/runtime.sgml | 46 +++++++++++++++ src/backend/utils/error/elog.c | 3 +- src/backend/utils/misc/guc.c | 14 +++++ src/backend/utils/misc/postgresql.conf.sample | 2 + src/bin/pgevent/pgevent.c | 58 +++++++++++++++++-- src/bin/pgevent/pgevent.def | 1 + 8 files changed, 143 insertions(+), 19 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index fa2dcf336c..3ace7dfa93 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -3037,6 +3037,14 @@ local0.* /var/log/postgresql to the syslog daemon's configuration file to make it work. + + On Windows, when you use the eventlog + option for log_destination, you should + register an event source and its library with the operating + system so that the Windows Event Viewer can display event + log messages cleanly. + See for details. + @@ -3287,6 +3295,23 @@ local0.* /var/log/postgresql + + 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 + the 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 index 0410cff4ac..41b9009de0 100644 --- a/doc/src/sgml/installation.sgml +++ b/doc/src/sgml/installation.sgml @@ -1551,19 +1551,6 @@ PostgreSQL, contrib and HTML documentation successfully made. Ready to install. - - 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: diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 68ceff1530..86499c67ac 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -2295,4 +2295,50 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com + + 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. + + + + To specify a different event source name (see + ), use the /n + and /i options: + +regsvr32 /n /i:event_source_name pgsql_library_directory/pgevent.dll + + + + + 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 index 7122b59b96..9a99fc7402 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -123,6 +123,7 @@ static void write_syslog(int level, const char *line); static void write_console(const char *line, int len); #ifdef WIN32 +extern char *event_source; static void write_eventlog(int level, const char *line, int len); #endif @@ -1673,7 +1674,7 @@ write_eventlog(int level, const char *line, int len) if (evtHandle == INVALID_HANDLE_VALUE) { - evtHandle = RegisterEventSource(NULL, "PostgreSQL"); + 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 index 73e6001071..0b1c912fb3 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -412,6 +412,7 @@ bool log_executor_stats = false; bool log_statement_stats = false; /* this is sort of all three * above together */ bool log_btree_build_stats = false; +char *event_source; bool check_function_bodies = true; bool default_with_oids = false; @@ -2819,6 +2820,19 @@ static struct config_string ConfigureNamesString[] = NULL, assign_syslog_ident, NULL }, +#ifdef WIN32 + { + {"event_source", PGC_POSTMASTER, LOGGING_WHERE, + gettext_noop("Sets the application name used to identify" + "PostgreSQL messages in the event log."), + NULL + }, + &event_source, + "PostgreSQL", + NULL, NULL, NULL + }, +#endif + { {"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE, gettext_noop("Sets the time zone for displaying and interpreting time stamps."), diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 67b098bd6d..315db46634 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -322,6 +322,8 @@ #syslog_facility = 'LOCAL0' #syslog_ident = 'postgres' +# This is only relevant when logging to eventlog (win32): +#event_source = 'PostgreSQL' # - When to Log - diff --git a/src/bin/pgevent/pgevent.c b/src/bin/pgevent/pgevent.c index 1fcde866d6..d4d505c53f 100644 --- a/src/bin/pgevent/pgevent.c +++ b/src/bin/pgevent/pgevent.c @@ -15,16 +15,55 @@ #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 + */ +char event_source[256] = "PostgreSQL"; + /* Prototypes */ -STDAPI -DllRegisterServer(void); +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) +{ + size_t ret; + + if (pszCmdLine && *pszCmdLine != '\0') + wcstombs_s(&ret, event_source, sizeof(event_source), + pszCmdLine, sizeof(event_source)); + + /* + * This is an ugly hack 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 */ @@ -35,6 +74,7 @@ DllRegisterServer(void) HKEY key; DWORD data; char buffer[_MAX_PATH]; + char key_name[400]; /* Set the name of DLL full path name. */ if (!GetModuleFileName((HMODULE) g_module, buffer, sizeof(buffer))) @@ -47,7 +87,10 @@ DllRegisterServer(void) * 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)) + _snprintf(key_name, sizeof(key_name), + "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; @@ -72,7 +115,7 @@ DllRegisterServer(void) "TypesSupported", 0, REG_DWORD, - (LPBYTE) &data, + (LPBYTE) & data, sizeof(DWORD))) { MessageBox(NULL, "Could not set the supported types.", "PostgreSQL error", MB_OK | MB_ICONSTOP); @@ -90,12 +133,17 @@ DllRegisterServer(void) STDAPI DllUnregisterServer(void) { + char key_name[400]; + /* * 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")) + _snprintf(key_name, sizeof(key_name), + "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 index 21bab7ac75..6b4d44afa1 100644 --- a/src/bin/pgevent/pgevent.def +++ b/src/bin/pgevent/pgevent.def @@ -2,3 +2,4 @@ EXPORTS DllUnregisterServer ; DllRegisterServer ; + DllInstall ; -- 2.40.0