Support configurable eventlog application names on Windows
authorMagnus Hagander
Tue, 25 Oct 2011 18:02:55 +0000 (20:02 +0200)
committerMagnus Hagander
Tue, 25 Oct 2011 18:02:55 +0000 (20:02 +0200)
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
doc/src/sgml/installation.sgml
doc/src/sgml/runtime.sgml
src/backend/utils/error/elog.c
src/backend/utils/misc/guc.c
src/backend/utils/misc/postgresql.conf.sample
src/bin/pgevent/pgevent.c
src/bin/pgevent/pgevent.def

index fa2dcf336c4c4b6c85c6d5ae8b363bde473d55a7..3ace7dfa9309bdecef44e8573f54ec6367d99bbe 100644 (file)
@@ -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.
+       
+      
+     
+
       
     
      
index 0410cff4aca686dfd5e4d44e26e355df52ed5575..41b9009de05cc82b7b02b80f36bcf168e409349a 100644 (file)
@@ -1551,19 +1551,6 @@ PostgreSQL, contrib and HTML documentation successfully made. Ready to install.
   
   
 
-  
-   Registering <application>eventlog</> on <systemitem</div> <div class="diff rem">-   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:
    
index 68ceff15303c41429a10cdf5e995ee01001fffbb..86499c67ac58459261e22616083eaba0cb3984f9 100644 (file)
@@ -2295,4 +2295,50 @@ ssh -L 63333:db.foo.com:5432 [email protected]
 
  
 
+  Registering <application>Event Log</> on <systemitem</div> <div class="diff add">+  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.
+   
+  
+
 
index 7122b59b96a8a113eb85e2f23f9055058ec495f8..9a99fc7402bd4ca1ae0fc61661342451ef933373 100644 (file)
@@ -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;
index 73e600107110c28520913da3ec32189c22219fbb..0b1c912fb3ab41f68cecb6144159626cc3ca8bd2 100644 (file)
@@ -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."),
index 67b098bd6d741848a5ed70028abc6466357d91ca..315db4663416a06259b03060db88d097fa276f2a 100644 (file)
 #syslog_facility = 'LOCAL0'
 #syslog_ident = 'postgres'
 
+# This is only relevant when logging to eventlog (win32):
+#event_source = 'PostgreSQL'
 
 # - When to Log -
 
index 1fcde866d6cb3a204a3d6c02c877bbc3f385495d..d4d505c53f663ef502fa7f7f91726f0a90ca9b37 100644 (file)
 #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;
index 21bab7ac75f6091cab2cab54b0c9b681e054ced6..6b4d44afa16654150788aa246df5dc15a8934493 100644 (file)
@@ -2,3 +2,4 @@
 EXPORTS
    DllUnregisterServer ;
    DllRegisterServer ;
+   DllInstall ;