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

Reply via email to