Commit d8ea33f2 authored by Magnus Hagander's avatar Magnus Hagander

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
parent 90d8e8ff
...@@ -3037,6 +3037,14 @@ local0.* /var/log/postgresql ...@@ -3037,6 +3037,14 @@ local0.* /var/log/postgresql
to the <application>syslog</application> daemon's configuration file to the <application>syslog</application> daemon's configuration file
to make it work. to make it work.
</para> </para>
<para>
On Windows, when you use the <literal>eventlog</literal>
option for <varname>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 <xref linkend="event-log-registration"> for details.
</para>
</note> </note>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -3287,6 +3295,23 @@ local0.* /var/log/postgresql ...@@ -3287,6 +3295,23 @@ local0.* /var/log/postgresql
</listitem> </listitem>
</varlistentry> </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
the log. 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> </variablelist>
</sect2> </sect2>
<sect2 id="runtime-config-logging-when"> <sect2 id="runtime-config-logging-when">
......
...@@ -1551,19 +1551,6 @@ PostgreSQL, contrib and HTML documentation successfully made. Ready to install. ...@@ -1551,19 +1551,6 @@ PostgreSQL, contrib and HTML documentation successfully made. Ready to install.
</step> </step>
</procedure> </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> <formalpara>
<title>Uninstallation:</title> <title>Uninstallation:</title>
<para> <para>
......
...@@ -2295,4 +2295,50 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com ...@@ -2295,4 +2295,50 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com
</sect1> </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 <literal>PostgreSQL</literal>.
</para>
<para>
To specify a different event source name (see
<xref linkend="guc-event-source">), use the <literal>/n</literal>
and <literal>/i</literal> options:
<screen>
<userinput>regsvr32 /n /i:<replaceable>event_source_name</> <replaceable>pgsql_library_directory</>/pgevent.dll</>
</screen>
</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
<literal>eventlog</literal> in <filename>postgresql.conf</filename>.
</para>
</note>
</sect1>
</chapter> </chapter>
...@@ -123,6 +123,7 @@ static void write_syslog(int level, const char *line); ...@@ -123,6 +123,7 @@ static void write_syslog(int level, const char *line);
static void write_console(const char *line, int len); static void write_console(const char *line, int len);
#ifdef WIN32 #ifdef WIN32
extern char *event_source;
static void write_eventlog(int level, const char *line, int len); static void write_eventlog(int level, const char *line, int len);
#endif #endif
...@@ -1673,7 +1674,7 @@ write_eventlog(int level, const char *line, int len) ...@@ -1673,7 +1674,7 @@ write_eventlog(int level, const char *line, int len)
if (evtHandle == INVALID_HANDLE_VALUE) if (evtHandle == INVALID_HANDLE_VALUE)
{ {
evtHandle = RegisterEventSource(NULL, "PostgreSQL"); evtHandle = RegisterEventSource(NULL, event_source ? event_source : "PostgreSQL");
if (evtHandle == NULL) if (evtHandle == NULL)
{ {
evtHandle = INVALID_HANDLE_VALUE; evtHandle = INVALID_HANDLE_VALUE;
......
...@@ -412,6 +412,7 @@ bool log_executor_stats = false; ...@@ -412,6 +412,7 @@ bool log_executor_stats = false;
bool log_statement_stats = false; /* this is sort of all three bool log_statement_stats = false; /* this is sort of all three
* above together */ * above together */
bool log_btree_build_stats = false; bool log_btree_build_stats = false;
char *event_source;
bool check_function_bodies = true; bool check_function_bodies = true;
bool default_with_oids = false; bool default_with_oids = false;
...@@ -2819,6 +2820,19 @@ static struct config_string ConfigureNamesString[] = ...@@ -2819,6 +2820,19 @@ static struct config_string ConfigureNamesString[] =
NULL, assign_syslog_ident, NULL 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, {"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE,
gettext_noop("Sets the time zone for displaying and interpreting time stamps."), gettext_noop("Sets the time zone for displaying and interpreting time stamps."),
......
...@@ -322,6 +322,8 @@ ...@@ -322,6 +322,8 @@
#syslog_facility = 'LOCAL0' #syslog_facility = 'LOCAL0'
#syslog_ident = 'postgres' #syslog_ident = 'postgres'
# This is only relevant when logging to eventlog (win32):
#event_source = 'PostgreSQL'
# - When to Log - # - When to Log -
......
...@@ -15,16 +15,55 @@ ...@@ -15,16 +15,55 @@
#include <windows.h> #include <windows.h>
#include <olectl.h> #include <olectl.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* Global variables */ /* Global variables */
HANDLE g_module = NULL; /* hModule of DLL */ 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 */ /* Prototypes */
STDAPI HRESULT DllInstall(BOOL bInstall, __in_opt LPCWSTR pszCmdLine);
DllRegisterServer(void); STDAPI DllRegisterServer(void);
STDAPI DllUnregisterServer(void); STDAPI DllUnregisterServer(void);
BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved); 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 * DllRegisterServer --- Instructs DLL to create its registry entries
*/ */
...@@ -35,6 +74,7 @@ DllRegisterServer(void) ...@@ -35,6 +74,7 @@ DllRegisterServer(void)
HKEY key; HKEY key;
DWORD data; DWORD data;
char buffer[_MAX_PATH]; char buffer[_MAX_PATH];
char key_name[400];
/* Set the name of DLL full path name. */ /* Set the name of DLL full path name. */
if (!GetModuleFileName((HMODULE) g_module, buffer, sizeof(buffer))) if (!GetModuleFileName((HMODULE) g_module, buffer, sizeof(buffer)))
...@@ -47,7 +87,10 @@ DllRegisterServer(void) ...@@ -47,7 +87,10 @@ DllRegisterServer(void)
* Add PostgreSQL source name as a subkey under the Application key in the * Add PostgreSQL source name as a subkey under the Application key in the
* EventLog registry key. * 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); MessageBox(NULL, "Could not create the registry key.", "PostgreSQL error", MB_OK | MB_ICONSTOP);
return SELFREG_E_TYPELIB; return SELFREG_E_TYPELIB;
...@@ -72,7 +115,7 @@ DllRegisterServer(void) ...@@ -72,7 +115,7 @@ DllRegisterServer(void)
"TypesSupported", "TypesSupported",
0, 0,
REG_DWORD, REG_DWORD,
(LPBYTE) &data, (LPBYTE) & data,
sizeof(DWORD))) sizeof(DWORD)))
{ {
MessageBox(NULL, "Could not set the supported types.", "PostgreSQL error", MB_OK | MB_ICONSTOP); MessageBox(NULL, "Could not set the supported types.", "PostgreSQL error", MB_OK | MB_ICONSTOP);
...@@ -90,12 +133,17 @@ DllRegisterServer(void) ...@@ -90,12 +133,17 @@ DllRegisterServer(void)
STDAPI STDAPI
DllUnregisterServer(void) DllUnregisterServer(void)
{ {
char key_name[400];
/* /*
* Remove PostgreSQL source name as a subkey under the Application key in * Remove PostgreSQL source name as a subkey under the Application key in
* the EventLog registry key. * 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); MessageBox(NULL, "Could not delete the registry key.", "PostgreSQL error", MB_OK | MB_ICONSTOP);
return SELFREG_E_TYPELIB; return SELFREG_E_TYPELIB;
......
...@@ -2,3 +2,4 @@ ...@@ -2,3 +2,4 @@
EXPORTS EXPORTS
DllUnregisterServer ; DllUnregisterServer ;
DllRegisterServer ; DllRegisterServer ;
DllInstall ;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment