2011/5/26 MauMau <maumau...@gmail.com>: > Hello, > > I wrote and attached a patch for the TODO item below (which I proposed). > > Allow multiple Postgres clusters running on the same machine to distinguish > themselves in the event log > http://archives.postgresql.org/pgsql-hackers/2011-03/msg01297.php > http://archives.postgresql.org/pgsql-hackers/2011-05/msg00574.php > > I changed two things from the original proposal. > > 1. regsvr32.exe needs /n when you specify event source > I described the reason in src/bin/pgevent/pgevent.c. > > 2. I moved the article for event log registration to more suitable place > The traditional place and what I originally proposed were not best, because > those who don't build from source won't read those places. > > I successfully tested event log registration/unregistration, event logging > with/without event_source parameter, and SHOWing event_source parameter with > psql on Windows Vista (32-bit). I would appreciate if someone could test it > on 64-bit Windows who has the 64-bit environment. > > I'll add this patch to the first CommitFest of 9.2. Thank you in advance for > reviewing it.
+ <para> + On Windows, you need to register an event source + and its library with the operating system in order + to make use of the <systemitem>eventlog</systemitem> option for + <varname>log_destination</>. + See <xref linkend="event-log-registration"> for details. + </para> * This part is not strictly correct - you don't *need* to do that, it just makes things look nicer, no? * Also, what is the use for set_eventlog_parameters()? It's just a string variable, it shuold work without it. * We these days avoid #ifdef'ing gucs just because they are not on that platform - so the list is consistent. The guc should be available on non-windows platforms as well. * The guc also needs to go in postgresql.conf.sample * We never build in unicode mode, so all those checks are unnecessary. * Are we really allowed to call MessageBox in DlLRegisterService? Won't that break badly in cases like silent installs? Attached is an updated patch, which doesn't work yet. I believe the changes to the backend are correct, but probably some of the cleanups and changes in the dll are incorrect, because I seem to be unable to register either the default or a custom handler so far. -- Magnus Hagander Me: http://www.hagander.net/ Work: http://www.redpill-linpro.com/
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 842558d..583a5c9 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -2975,6 +2975,13 @@ local0.* /var/log/postgresql to the <application>syslog</application> daemon's configuration file to make it work. </para> + <para> + On Windows, you need to register an event source + and its library with the operating system in order + to make use of the <systemitem>eventlog</systemitem> option for + <varname>log_destination</>. + See <xref linkend="event-log-registration"> for details. + </para> </note> </listitem> </varlistentry> @@ -3221,6 +3228,24 @@ local0.* /var/log/postgresql </listitem> </varlistentry> + <varlistentry id="guc-event-source" xreflabel="event_source"> + <term><varname>event_source</varname> (<type>string</type>)</term> + <indexterm> + <primary><varname>event_source</> configuration parameter</primary> + </indexterm> + <listitem> + <para> + When logging to <application>event log</> is enabled, this parameter + determines the program name used to identify + <productname>PostgreSQL</productname> messages in + <application>event log</application>. The default is + <literal>PostgreSQL</literal>. + This parameter can only be set in the <filename>postgresql.conf</> + file or on the server command line. + </para> + </listitem> + </varlistentry> + </variablelist> </sect2> <sect2 id="runtime-config-logging-when"> diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml index 0410cff..41b9009 100644 --- a/doc/src/sgml/installation.sgml +++ b/doc/src/sgml/installation.sgml @@ -1552,19 +1552,6 @@ PostgreSQL, contrib and HTML documentation successfully made. Ready to install. </procedure> <formalpara> - <title>Registering <application>eventlog</> on <systemitem - class="osname">Windows</>:</title> - <para> - To register a <systemitem class="osname">Windows</> <application>eventlog</> - library with the operating system, issue this command after installation: -<screen> -<userinput>regsvr32 <replaceable>pgsql_library_directory</>/pgevent.dll</> -</screen> - This creates registry entries used by the event viewer. - </para> - </formalpara> - - <formalpara> <title>Uninstallation:</title> <para> To undo the installation use the command <command>gmake diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index ef83206..bfbb641 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -2294,4 +2294,54 @@ ssh -L 63333:db.foo.com:5432 j...@shell.foo.com </sect1> + <sect1 id="event-log-registration"> + <title>Registering <application>Event Log</> on <systemitem + class="osname">Windows</></title> + + <indexterm zone="event-log-registration"> + <primary>event log</primary> + <secondary>event log</secondary> + </indexterm> + + <para> + To register a <systemitem class="osname">Windows</> <application>event log</> + library with the operating system, issue this command: +<screen> +<userinput>regsvr32 <replaceable>pgsql_library_directory</>/pgevent.dll</> +</screen> + This creates registry entries used by the event viewer, under the default event + source named "PostgreSQL". + </para> + + <para> + You can specify the event source name with /i option. In this case, -n option + is necessary, too: +<screen> +<userinput>regsvr32 /n /i:<replaceable>event_source_name</> + <replaceable>pgsql_library_directory</>/pgevent.dll</> +</screen> + You also need to set <xref linkend="guc-event-source"> in + <filename>postgresql.conf</filename>. Note that the event source specification + only takes effect for the database server. Other applications like + <command>pg_ctl</command> always use "PostgreSQL" event source. + </para> + + <para> + To unregister the <application>event log</> library from + the operating system, issue this command: +<screen> +<userinput>regsvr32 /u [/i:<replaceable>event_source_name</>] + <replaceable>pgsql_library_directory</>/pgevent.dll</> +</screen> + </para> + + <note> + <para> + To enable event logging in the database server, modify + <xref linkend="guc-log-destination"> to include + <systemitem>eventlog</systemitem> in <filename>postgresql.conf</filename>. + </para> + </note> + </sect1> + </chapter> diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 337b875..1708869 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -122,6 +122,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; /* guc */ static void write_eventlog(int level, const char *line, int len); #endif @@ -1633,6 +1634,7 @@ write_syslog(int level, const char *line) #endif /* HAVE_SYSLOG */ #ifdef WIN32 + /* * Write a message line to the windows event log */ @@ -1645,7 +1647,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 5841631..b6ab341 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -411,6 +411,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; @@ -2815,6 +2816,17 @@ static struct config_string ConfigureNamesString[] = }, { + {"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 + }, + + { {"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE, gettext_noop("Sets the time zone for displaying and interpreting time stamps."), NULL, @@ -8214,7 +8226,6 @@ assign_syslog_ident(const char *newval, void *extra) /* Without syslog support, it will always be set to "none", so ignore */ } - static void assign_session_replication_role(int newval, void *extra) { diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 9403293..f161435 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -309,6 +309,8 @@ #syslog_facility = 'LOCAL0' #syslog_ident = 'postgres' +# This is relevant only when logging to eventlog: +#event_source = 'PostgreSQL' # - When to Log - diff --git a/src/bin/pgevent/pgevent.c b/src/bin/pgevent/pgevent.c index 1fcde86..d186e16 100644 --- a/src/bin/pgevent/pgevent.c +++ b/src/bin/pgevent/pgevent.c @@ -15,17 +15,52 @@ #include <windows.h> #include <olectl.h> #include <string.h> +#include <stdio.h> +#include <stdlib.h> /* 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]; + /* 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) +{ + if (pszCmdLine && *pszCmdLine != '\0') + strncpy(event_source, sizeof(event_source), pszCmdLine); + else + strcpy(event_source, "PostgreSQL"); + + /* + * 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 */ @@ -35,6 +70,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 +83,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; @@ -90,12 +129,16 @@ 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; @@ -113,6 +156,8 @@ DllMain(HANDLE hModule, LPVOID lpReserved ) { + memset(event_source, 0, sizeof(event_source)); + if (ul_reason_for_call == DLL_PROCESS_ATTACH) g_module = hModule; return TRUE; diff --git a/src/bin/pgevent/pgevent.def b/src/bin/pgevent/pgevent.def index 21bab7a..6b4d44a 100644 --- a/src/bin/pgevent/pgevent.def +++ b/src/bin/pgevent/pgevent.def @@ -2,3 +2,4 @@ EXPORTS DllUnregisterServer ; DllRegisterServer ; + DllInstall ;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers