Skip to content

Commit 6de9f58

Browse files
committed
Add WindowsEventLogLogger
1 parent 5a114a6 commit 6de9f58

11 files changed

+201
-6
lines changed

doc/09-object-types.md

+17
Original file line numberDiff line numberDiff line change
@@ -1864,4 +1864,21 @@ Facility Constants:
18641864
FacilityUucp | LOG\_UUCP | The UUCP system.
18651865

18661866

1867+
### WindowsEventLogLogger <a id="objecttype-windowseventloglogger"></a>
18671868

1869+
Specifies Icinga 2 logging to the Windows Event Log.
1870+
This configuration object is available as `windowseventlog` [logging feature](14-features.md#logging).
1871+
1872+
Example:
1873+
1874+
```
1875+
object WindowsEventLogLogger "windowseventlog" {
1876+
severity = "warning"
1877+
}
1878+
```
1879+
1880+
Configuration Attributes:
1881+
1882+
Name | Type | Description
1883+
--------------------------|-----------------------|----------------------------------
1884+
severity | String | **Optional.** The minimum severity for this log. Can be "debug", "notice", "information", "warning" or "critical". Defaults to "warning".

doc/14-features.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ Icinga 2 supports three different types of logging:
1111
You can enable additional loggers using the `icinga2 feature enable`
1212
and `icinga2 feature disable` commands to configure loggers:
1313

14-
Feature | Description
15-
---------|------------
16-
debuglog | Debug log (path: `/var/log/icinga2/debug.log`, severity: `debug` or higher)
17-
mainlog | Main log (path: `/var/log/icinga2/icinga2.log`, severity: `information` or higher)
18-
syslog | Syslog (severity: `warning` or higher)
14+
Feature | Description
15+
----------------|------------
16+
debuglog | Debug log (path: `/var/log/icinga2/debug.log`, severity: `debug` or higher)
17+
mainlog | Main log (path: `/var/log/icinga2/icinga2.log`, severity: `information` or higher)
18+
syslog | Syslog (severity: `warning` or higher)
19+
windowseventlog | Windows Event Log (severity: `warning` or higher)
1920

2021
By default file the `mainlog` feature is enabled. When running Icinga 2
2122
on a terminal log messages with severity `information` or higher are

etc/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ install_if_not_exists(icinga2/features-available/debuglog.conf ${ICINGA2_CONFIGD
3939
install_if_not_exists(icinga2/features-available/mainlog.conf ${ICINGA2_CONFIGDIR}/features-available)
4040
if(NOT WIN32)
4141
install_if_not_exists(icinga2/features-available/syslog.conf ${ICINGA2_CONFIGDIR}/features-available)
42+
else()
43+
install_if_not_exists(icinga2/features-available/windowseventlog.conf ${ICINGA2_CONFIGDIR}/features-available)
4244
endif()
4345
install_if_not_exists(icinga2/scripts/mail-host-notification.sh ${ICINGA2_CONFIGDIR}/scripts)
4446
install_if_not_exists(icinga2/scripts/mail-service-notification.sh ${ICINGA2_CONFIGDIR}/scripts)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* The WindowsEventLogLogger type writes log information to the Windows Event Log.
3+
*/
4+
5+
object WindowsEventLogLogger "windowseventlog" {
6+
severity = "warning"
7+
}
8+

icinga-installer/icinga2.wixpatch.cmake

+14
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,20 @@
2020
<Custom Action="XtraUninstall" Before="RemoveExistingProducts">$CM_CP_sbin.icinga2_installer.exe=2 AND NOT SUPPRESS_XTRA</Custom>
2121
</InstallExecuteSequence>
2222

23+
<!--
24+
Write the path to eventprovider.dll to the registry so that the Event Viewer is able to find
25+
the message definitions and properly displays our log messages.
26+
27+
See also: https://docs.microsoft.com/en-us/windows/win32/eventlog/reporting-an-event
28+
-->
29+
<FeatureRef Id="ProductFeature" IgnoreParent="yes">
30+
<Component Id="EventProviderRegistryEntry" Guid="*" Directory="INSTALL_ROOT">
31+
<RegistryKey Root="HKLM" Key="SYSTEM\CurrentControlSet\Services\EventLog\Application\Icinga 2" Action="createAndRemoveOnUninstall">
32+
<RegistryValue Name="EventMessageFile" Type="string" Value="[#CM_FP_sbin.eventprovider.dll]" />
33+
</RegistryKey>
34+
</Component>
35+
</FeatureRef>
36+
2337
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Run Icinga 2 setup wizard" />
2438

2539
<Property Id="WixShellExecTarget" Value="[#CM_FP_sbin.Icinga2SetupAgent.exe]" />

lib/base/CMakeLists.txt

+27
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,33 @@ set(base_SOURCES
8585
workqueue.cpp workqueue.hpp
8686
)
8787

88+
if(WIN32)
89+
mkclass_target(windowseventloglogger.ti windowseventloglogger-ti.cpp windowseventloglogger-ti.hpp)
90+
list(APPEND base_SOURCES windowseventloglogger.cpp windowseventloglogger.hpp windowseventloglogger-ti.hpp)
91+
92+
# Generate a DLL containing message definitions for the Windows Event Viewer.
93+
# See also: https://docs.microsoft.com/en-us/windows/win32/eventlog/reporting-an-event
94+
add_custom_command(
95+
OUTPUT windowseventloglogger-provider.rc windowseventloglogger-provider.h
96+
COMMAND mc ARGS -U ${CMAKE_CURRENT_SOURCE_DIR}/windowseventloglogger-provider.mc
97+
DEPENDS windowseventloglogger-provider.mc
98+
)
99+
100+
list(APPEND base_SOURCES windowseventloglogger-provider.h)
101+
102+
add_custom_command(
103+
OUTPUT windowseventloglogger-provider.res
104+
COMMAND rc ARGS windowseventloglogger-provider.rc
105+
DEPENDS windowseventloglogger-provider.rc
106+
)
107+
108+
add_library(eventprovider MODULE windowseventloglogger-provider.res windowseventloglogger-provider.rc)
109+
set_target_properties(eventprovider PROPERTIES LINKER_LANGUAGE CXX)
110+
target_link_libraries(eventprovider PRIVATE -noentry)
111+
112+
install(TARGETS eventprovider LIBRARY DESTINATION ${CMAKE_INSTALL_SBINDIR})
113+
endif()
114+
88115
set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/application-version.cpp PROPERTY EXCLUDE_UNITY_BUILD TRUE)
89116

90117
if(ICINGA2_UNITY_BUILD)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
MessageId=0x1
2+
SymbolicName=MSG_PLAIN_LOG_ENTRY
3+
Language=English
4+
%1
5+
.

lib/base/windowseventloglogger.cpp

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/* Icinga 2 | (c) 2021 Icinga GmbH | GPLv2+ */
2+
3+
#ifdef _WIN32
4+
#include "base/windowseventloglogger.hpp"
5+
#include "base/windowseventloglogger-ti.cpp"
6+
#include "base/windowseventloglogger-provider.h"
7+
#include "base/configtype.hpp"
8+
#include "base/statsfunction.hpp"
9+
#include <windows.h>
10+
11+
using namespace icinga;
12+
13+
REGISTER_TYPE(WindowsEventLogLogger);
14+
15+
REGISTER_STATSFUNCTION(WindowsEventLogLogger, &WindowsEventLogLogger::StatsFunc);
16+
17+
INITIALIZE_ONCE(&WindowsEventLogLogger::StaticInitialize);
18+
19+
static HANDLE l_EventLog = nullptr;
20+
21+
void WindowsEventLogLogger::StaticInitialize()
22+
{
23+
l_EventLog = RegisterEventSourceA(nullptr, "Icinga 2");
24+
}
25+
26+
void WindowsEventLogLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
27+
{
28+
DictionaryData nodes;
29+
30+
for (const WindowsEventLogLogger::Ptr& logger : ConfigType::GetObjectsByType<WindowsEventLogLogger>()) {
31+
nodes.emplace_back(logger->GetName(), 1);
32+
}
33+
34+
status->Set("windowseventloglogger", new Dictionary(std::move(nodes)));
35+
}
36+
37+
/**
38+
* Processes a log entry and outputs it to the Windows Event Log.
39+
*
40+
* @param entry The log entry.
41+
*/
42+
void WindowsEventLogLogger::ProcessLogEntry(const LogEntry& entry)
43+
{
44+
if (l_EventLog != nullptr) {
45+
std::string message = Logger::SeverityToString(entry.Severity) + "/" + entry.Facility + ": " + entry.Message;
46+
std::array<const char *, 1> strings{
47+
message.c_str()
48+
};
49+
50+
WORD eventType;
51+
switch (entry.Severity) {
52+
case LogCritical:
53+
eventType = EVENTLOG_ERROR_TYPE;
54+
break;
55+
case LogWarning:
56+
eventType = EVENTLOG_WARNING_TYPE;
57+
break;
58+
default:
59+
eventType = EVENTLOG_INFORMATION_TYPE;
60+
}
61+
62+
ReportEventA(l_EventLog, eventType, 0, MSG_PLAIN_LOG_ENTRY, NULL, strings.size(), 0, strings.data(), NULL);
63+
}
64+
}
65+
66+
void WindowsEventLogLogger::Flush()
67+
{
68+
/* Nothing to do here. */
69+
}
70+
71+
#endif /* _WIN32 */

lib/base/windowseventloglogger.hpp

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* Icinga 2 | (c) 2021 Icinga GmbH | GPLv2+ */
2+
3+
#ifndef WINDOWSEVENTLOGLOGGER_H
4+
#define WINDOWSEVENTLOGLOGGER_H
5+
6+
#ifdef _WIN32
7+
#include "base/i2-base.hpp"
8+
#include "base/windowseventloglogger-ti.hpp"
9+
10+
namespace icinga
11+
{
12+
13+
/**
14+
* A logger that logs to the Windows Event Log.
15+
*
16+
* @ingroup base
17+
*/
18+
class WindowsEventLogLogger final : public ObjectImpl<WindowsEventLogLogger>
19+
{
20+
public:
21+
DECLARE_OBJECT(WindowsEventLogLogger);
22+
DECLARE_OBJECTNAME(WindowsEventLogLogger);
23+
24+
static void StaticInitialize();
25+
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
26+
27+
protected:
28+
void ProcessLogEntry(const LogEntry& entry) override;
29+
void Flush() override;
30+
};
31+
32+
}
33+
#endif /* _WIN32 */
34+
35+
#endif /* WINDOWSEVENTLOGLOGGER_H */

lib/base/windowseventloglogger.ti

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* Icinga 2 | (c) 2021 Icinga GmbH | GPLv2+ */
2+
3+
#include "base/logger.hpp"
4+
5+
library base;
6+
7+
namespace icinga
8+
{
9+
10+
class WindowsEventLogLogger : Logger
11+
{
12+
activation_priority -100;
13+
};
14+
15+
}

tools/syntax/vim/syntax/icinga2.vim

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ syn keyword icinga2ObjType IcingaApplication IdoMysqlConnection IdoPgsqlConnec
6060
syn keyword icinga2ObjType InfluxdbWriter LivestatusListener Notification NotificationCommand
6161
syn keyword icinga2ObjType NotificationComponent OpenTsdbWriter PerfdataWriter
6262
syn keyword icinga2ObjType ScheduledDowntime Service ServiceGroup SyslogLogger
63-
syn keyword icinga2ObjType TimePeriod User UserGroup Zone
63+
syn keyword icinga2ObjType TimePeriod User UserGroup WindowsEventLogLogger Zone
6464

6565
" Object/Template marker (simplified)
6666
syn match icinga2ObjDef "\(object\|template\)[ \t]\+.*"

0 commit comments

Comments
 (0)