Skip to content

Commit d8ea33f

Browse files
committed
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
1 parent 90d8e8f commit d8ea33f

File tree

8 files changed

+143
-19
lines changed

8 files changed

+143
-19
lines changed

doc/src/sgml/config.sgml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3037,6 +3037,14 @@ local0.* /var/log/postgresql
30373037
to the <application>syslog</application> daemon's configuration file
30383038
to make it work.
30393039
</para>
3040+
<para>
3041+
On Windows, when you use the <literal>eventlog</literal>
3042+
option for <varname>log_destination</>, you should
3043+
register an event source and its library with the operating
3044+
system so that the Windows Event Viewer can display event
3045+
log messages cleanly.
3046+
See <xref linkend="event-log-registration"> for details.
3047+
</para>
30403048
</note>
30413049
</listitem>
30423050
</varlistentry>
@@ -3287,6 +3295,23 @@ local0.* /var/log/postgresql
32873295
</listitem>
32883296
</varlistentry>
32893297

3298+
<varlistentry id="guc-event-source" xreflabel="event_source">
3299+
<term><varname>event_source</varname> (<type>string</type>)</term>
3300+
<indexterm>
3301+
<primary><varname>event_source</> configuration parameter</primary>
3302+
</indexterm>
3303+
<listitem>
3304+
<para>
3305+
When logging to <application>event log</> is enabled, this parameter
3306+
determines the program name used to identify
3307+
<productname>PostgreSQL</productname> messages in
3308+
the log. The default is <literal>PostgreSQL</literal>.
3309+
This parameter can only be set in the <filename>postgresql.conf</>
3310+
file or on the server command line.
3311+
</para>
3312+
</listitem>
3313+
</varlistentry>
3314+
32903315
</variablelist>
32913316
</sect2>
32923317
<sect2 id="runtime-config-logging-when">

doc/src/sgml/installation.sgml

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,19 +1551,6 @@ PostgreSQL, contrib and HTML documentation successfully made. Ready to install.
15511551
</step>
15521552
</procedure>
15531553

1554-
<formalpara>
1555-
<title>Registering <application>eventlog</> on <systemitem
1556-
class="osname">Windows</>:</title>
1557-
<para>
1558-
To register a <systemitem class="osname">Windows</> <application>eventlog</>
1559-
library with the operating system, issue this command after installation:
1560-
<screen>
1561-
<userinput>regsvr32 <replaceable>pgsql_library_directory</>/pgevent.dll</>
1562-
</screen>
1563-
This creates registry entries used by the event viewer.
1564-
</para>
1565-
</formalpara>
1566-
15671554
<formalpara>
15681555
<title>Uninstallation:</title>
15691556
<para>

doc/src/sgml/runtime.sgml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,4 +2295,50 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com
22952295

22962296
</sect1>
22972297

2298+
<sect1 id="event-log-registration">
2299+
<title>Registering <application>Event Log</> on <systemitem
2300+
class="osname">Windows</></title>
2301+
2302+
<indexterm zone="event-log-registration">
2303+
<primary>event log</primary>
2304+
<secondary>event log</secondary>
2305+
</indexterm>
2306+
2307+
<para>
2308+
To register a <systemitem class="osname">Windows</>
2309+
<application>event log</> library with the operating system,
2310+
issue this command:
2311+
<screen>
2312+
<userinput>regsvr32 <replaceable>pgsql_library_directory</>/pgevent.dll</>
2313+
</screen>
2314+
This creates registry entries used by the event viewer, under the default
2315+
event source named <literal>PostgreSQL</literal>.
2316+
</para>
2317+
2318+
<para>
2319+
To specify a different event source name (see
2320+
<xref linkend="guc-event-source">), use the <literal>/n</literal>
2321+
and <literal>/i</literal> options:
2322+
<screen>
2323+
<userinput>regsvr32 /n /i:<replaceable>event_source_name</> <replaceable>pgsql_library_directory</>/pgevent.dll</>
2324+
</screen>
2325+
</para>
2326+
2327+
<para>
2328+
To unregister the <application>event log</> library from
2329+
the operating system, issue this command:
2330+
<screen>
2331+
<userinput>regsvr32 /u [/i:<replaceable>event_source_name</>] <replaceable>pgsql_library_directory</>/pgevent.dll</>
2332+
</screen>
2333+
</para>
2334+
2335+
<note>
2336+
<para>
2337+
To enable event logging in the database server, modify
2338+
<xref linkend="guc-log-destination"> to include
2339+
<literal>eventlog</literal> in <filename>postgresql.conf</filename>.
2340+
</para>
2341+
</note>
2342+
</sect1>
2343+
22982344
</chapter>

src/backend/utils/error/elog.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ static void write_syslog(int level, const char *line);
123123
static void write_console(const char *line, int len);
124124

125125
#ifdef WIN32
126+
extern char *event_source;
126127
static void write_eventlog(int level, const char *line, int len);
127128
#endif
128129

@@ -1673,7 +1674,7 @@ write_eventlog(int level, const char *line, int len)
16731674

16741675
if (evtHandle == INVALID_HANDLE_VALUE)
16751676
{
1676-
evtHandle = RegisterEventSource(NULL, "PostgreSQL");
1677+
evtHandle = RegisterEventSource(NULL, event_source ? event_source : "PostgreSQL");
16771678
if (evtHandle == NULL)
16781679
{
16791680
evtHandle = INVALID_HANDLE_VALUE;

src/backend/utils/misc/guc.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ bool log_executor_stats = false;
412412
bool log_statement_stats = false; /* this is sort of all three
413413
* above together */
414414
bool log_btree_build_stats = false;
415+
char *event_source;
415416

416417
bool check_function_bodies = true;
417418
bool default_with_oids = false;
@@ -2819,6 +2820,19 @@ static struct config_string ConfigureNamesString[] =
28192820
NULL, assign_syslog_ident, NULL
28202821
},
28212822

2823+
#ifdef WIN32
2824+
{
2825+
{"event_source", PGC_POSTMASTER, LOGGING_WHERE,
2826+
gettext_noop("Sets the application name used to identify"
2827+
"PostgreSQL messages in the event log."),
2828+
NULL
2829+
},
2830+
&event_source,
2831+
"PostgreSQL",
2832+
NULL, NULL, NULL
2833+
},
2834+
#endif
2835+
28222836
{
28232837
{"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE,
28242838
gettext_noop("Sets the time zone for displaying and interpreting time stamps."),

src/backend/utils/misc/postgresql.conf.sample

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@
322322
#syslog_facility = 'LOCAL0'
323323
#syslog_ident = 'postgres'
324324

325+
# This is only relevant when logging to eventlog (win32):
326+
#event_source = 'PostgreSQL'
325327

326328
# - When to Log -
327329

src/bin/pgevent/pgevent.c

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,55 @@
1515
#include <windows.h>
1616
#include <olectl.h>
1717
#include <string.h>
18+
#include <stdio.h>
19+
#include <stdlib.h>
1820

1921
/* Global variables */
2022
HANDLE g_module = NULL; /* hModule of DLL */
2123

24+
/*
25+
* The event source is stored as a registry key.
26+
* The maximum length of a registry key is 255 characters.
27+
* http://msdn.microsoft.com/en-us/library/ms724872(v=vs.85).aspx
28+
*/
29+
char event_source[256] = "PostgreSQL";
30+
2231
/* Prototypes */
23-
STDAPI
24-
DllRegisterServer(void);
32+
HRESULT DllInstall(BOOL bInstall, __in_opt LPCWSTR pszCmdLine);
33+
STDAPI DllRegisterServer(void);
2534
STDAPI DllUnregisterServer(void);
2635
BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved);
2736

37+
/*
38+
* DllInstall --- Passes the command line argument to DLL
39+
*/
40+
41+
HRESULT
42+
DllInstall(BOOL bInstall,
43+
__in_opt LPCWSTR pszCmdLine)
44+
{
45+
size_t ret;
46+
47+
if (pszCmdLine && *pszCmdLine != '\0')
48+
wcstombs_s(&ret, event_source, sizeof(event_source),
49+
pszCmdLine, sizeof(event_source));
50+
51+
/*
52+
* This is an ugly hack due to the strange behavior of "regsvr32 /i".
53+
*
54+
* When installing, regsvr32 calls DllRegisterServer before DllInstall.
55+
* When uninstalling (i.e. "regsvr32 /u /i"), on the other hand, regsvr32
56+
* calls DllInstall and then DllUnregisterServer as expected.
57+
*
58+
* This strange behavior forces us to specify -n (i.e. "regsvr32 /n /i").
59+
* Without -n, DllRegisterServer called before DllInstall would mistakenly
60+
* overwrite the default "PostgreSQL" event source registration.
61+
*/
62+
if (bInstall)
63+
DllRegisterServer();
64+
return S_OK;
65+
}
66+
2867
/*
2968
* DllRegisterServer --- Instructs DLL to create its registry entries
3069
*/
@@ -35,6 +74,7 @@ DllRegisterServer(void)
3574
HKEY key;
3675
DWORD data;
3776
char buffer[_MAX_PATH];
77+
char key_name[400];
3878

3979
/* Set the name of DLL full path name. */
4080
if (!GetModuleFileName((HMODULE) g_module, buffer, sizeof(buffer)))
@@ -47,7 +87,10 @@ DllRegisterServer(void)
4787
* Add PostgreSQL source name as a subkey under the Application key in the
4888
* EventLog registry key.
4989
*/
50-
if (RegCreateKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\PostgreSQL", &key))
90+
_snprintf(key_name, sizeof(key_name),
91+
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s",
92+
event_source);
93+
if (RegCreateKey(HKEY_LOCAL_MACHINE, key_name, &key))
5194
{
5295
MessageBox(NULL, "Could not create the registry key.", "PostgreSQL error", MB_OK | MB_ICONSTOP);
5396
return SELFREG_E_TYPELIB;
@@ -72,7 +115,7 @@ DllRegisterServer(void)
72115
"TypesSupported",
73116
0,
74117
REG_DWORD,
75-
(LPBYTE) &data,
118+
(LPBYTE) & data,
76119
sizeof(DWORD)))
77120
{
78121
MessageBox(NULL, "Could not set the supported types.", "PostgreSQL error", MB_OK | MB_ICONSTOP);
@@ -90,12 +133,17 @@ DllRegisterServer(void)
90133
STDAPI
91134
DllUnregisterServer(void)
92135
{
136+
char key_name[400];
137+
93138
/*
94139
* Remove PostgreSQL source name as a subkey under the Application key in
95140
* the EventLog registry key.
96141
*/
97142

98-
if (RegDeleteKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\PostgreSQL"))
143+
_snprintf(key_name, sizeof(key_name),
144+
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s",
145+
event_source);
146+
if (RegDeleteKey(HKEY_LOCAL_MACHINE, key_name))
99147
{
100148
MessageBox(NULL, "Could not delete the registry key.", "PostgreSQL error", MB_OK | MB_ICONSTOP);
101149
return SELFREG_E_TYPELIB;

src/bin/pgevent/pgevent.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
EXPORTS
33
DllUnregisterServer ;
44
DllRegisterServer ;
5+
DllInstall ;

0 commit comments

Comments
 (0)