Skip to content

Commit

Permalink
Add WindowsEventLogLogger
Browse files Browse the repository at this point in the history
  • Loading branch information
julianbrost committed Jun 21, 2021
1 parent 5a114a6 commit 6de9f58
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 6 deletions.
17 changes: 17 additions & 0 deletions doc/09-object-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -1864,4 +1864,21 @@ Facility Constants:
FacilityUucp | LOG\_UUCP | The UUCP system.


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

Specifies Icinga 2 logging to the Windows Event Log.
This configuration object is available as `windowseventlog` [logging feature](14-features.md#logging).

Example:

```
object WindowsEventLogLogger "windowseventlog" {
severity = "warning"
}
```

Configuration Attributes:

Name | Type | Description
--------------------------|-----------------------|----------------------------------
severity | String | **Optional.** The minimum severity for this log. Can be "debug", "notice", "information", "warning" or "critical". Defaults to "warning".
11 changes: 6 additions & 5 deletions doc/14-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ Icinga 2 supports three different types of logging:
You can enable additional loggers using the `icinga2 feature enable`
and `icinga2 feature disable` commands to configure loggers:

Feature | Description
---------|------------
debuglog | Debug log (path: `/var/log/icinga2/debug.log`, severity: `debug` or higher)
mainlog | Main log (path: `/var/log/icinga2/icinga2.log`, severity: `information` or higher)
syslog | Syslog (severity: `warning` or higher)
Feature | Description
----------------|------------
debuglog | Debug log (path: `/var/log/icinga2/debug.log`, severity: `debug` or higher)
mainlog | Main log (path: `/var/log/icinga2/icinga2.log`, severity: `information` or higher)
syslog | Syslog (severity: `warning` or higher)
windowseventlog | Windows Event Log (severity: `warning` or higher)

By default file the `mainlog` feature is enabled. When running Icinga 2
on a terminal log messages with severity `information` or higher are
Expand Down
2 changes: 2 additions & 0 deletions etc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ install_if_not_exists(icinga2/features-available/debuglog.conf ${ICINGA2_CONFIGD
install_if_not_exists(icinga2/features-available/mainlog.conf ${ICINGA2_CONFIGDIR}/features-available)
if(NOT WIN32)
install_if_not_exists(icinga2/features-available/syslog.conf ${ICINGA2_CONFIGDIR}/features-available)
else()
install_if_not_exists(icinga2/features-available/windowseventlog.conf ${ICINGA2_CONFIGDIR}/features-available)
endif()
install_if_not_exists(icinga2/scripts/mail-host-notification.sh ${ICINGA2_CONFIGDIR}/scripts)
install_if_not_exists(icinga2/scripts/mail-service-notification.sh ${ICINGA2_CONFIGDIR}/scripts)
Expand Down
8 changes: 8 additions & 0 deletions etc/icinga2/features-available/windowseventlog.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* The WindowsEventLogLogger type writes log information to the Windows Event Log.
*/

object WindowsEventLogLogger "windowseventlog" {
severity = "warning"
}

14 changes: 14 additions & 0 deletions icinga-installer/icinga2.wixpatch.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@
<Custom Action="XtraUninstall" Before="RemoveExistingProducts">$CM_CP_sbin.icinga2_installer.exe=2 AND NOT SUPPRESS_XTRA</Custom>
</InstallExecuteSequence>

<!--
Write the path to eventprovider.dll to the registry so that the Event Viewer is able to find
the message definitions and properly displays our log messages.

See also: https://docs.microsoft.com/en-us/windows/win32/eventlog/reporting-an-event
-->
<FeatureRef Id="ProductFeature" IgnoreParent="yes">
<Component Id="EventProviderRegistryEntry" Guid="*" Directory="INSTALL_ROOT">
<RegistryKey Root="HKLM" Key="SYSTEM\CurrentControlSet\Services\EventLog\Application\Icinga 2" Action="createAndRemoveOnUninstall">
<RegistryValue Name="EventMessageFile" Type="string" Value="[#CM_FP_sbin.eventprovider.dll]" />
</RegistryKey>
</Component>
</FeatureRef>

<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Run Icinga 2 setup wizard" />

<Property Id="WixShellExecTarget" Value="[#CM_FP_sbin.Icinga2SetupAgent.exe]" />
Expand Down
27 changes: 27 additions & 0 deletions lib/base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,33 @@ set(base_SOURCES
workqueue.cpp workqueue.hpp
)

if(WIN32)
mkclass_target(windowseventloglogger.ti windowseventloglogger-ti.cpp windowseventloglogger-ti.hpp)
list(APPEND base_SOURCES windowseventloglogger.cpp windowseventloglogger.hpp windowseventloglogger-ti.hpp)

# Generate a DLL containing message definitions for the Windows Event Viewer.
# See also: https://docs.microsoft.com/en-us/windows/win32/eventlog/reporting-an-event
add_custom_command(
OUTPUT windowseventloglogger-provider.rc windowseventloglogger-provider.h
COMMAND mc ARGS -U ${CMAKE_CURRENT_SOURCE_DIR}/windowseventloglogger-provider.mc
DEPENDS windowseventloglogger-provider.mc
)

list(APPEND base_SOURCES windowseventloglogger-provider.h)

add_custom_command(
OUTPUT windowseventloglogger-provider.res
COMMAND rc ARGS windowseventloglogger-provider.rc
DEPENDS windowseventloglogger-provider.rc
)

add_library(eventprovider MODULE windowseventloglogger-provider.res windowseventloglogger-provider.rc)
set_target_properties(eventprovider PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(eventprovider PRIVATE -noentry)

install(TARGETS eventprovider LIBRARY DESTINATION ${CMAKE_INSTALL_SBINDIR})
endif()

set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/application-version.cpp PROPERTY EXCLUDE_UNITY_BUILD TRUE)

if(ICINGA2_UNITY_BUILD)
Expand Down
5 changes: 5 additions & 0 deletions lib/base/windowseventloglogger-provider.mc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
MessageId=0x1
SymbolicName=MSG_PLAIN_LOG_ENTRY
Language=English
%1
.
71 changes: 71 additions & 0 deletions lib/base/windowseventloglogger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* Icinga 2 | (c) 2021 Icinga GmbH | GPLv2+ */

#ifdef _WIN32
#include "base/windowseventloglogger.hpp"
#include "base/windowseventloglogger-ti.cpp"
#include "base/windowseventloglogger-provider.h"
#include "base/configtype.hpp"
#include "base/statsfunction.hpp"
#include <windows.h>

using namespace icinga;

REGISTER_TYPE(WindowsEventLogLogger);

REGISTER_STATSFUNCTION(WindowsEventLogLogger, &WindowsEventLogLogger::StatsFunc);

INITIALIZE_ONCE(&WindowsEventLogLogger::StaticInitialize);

static HANDLE l_EventLog = nullptr;

void WindowsEventLogLogger::StaticInitialize()
{
l_EventLog = RegisterEventSourceA(nullptr, "Icinga 2");
}

void WindowsEventLogLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
{
DictionaryData nodes;

for (const WindowsEventLogLogger::Ptr& logger : ConfigType::GetObjectsByType<WindowsEventLogLogger>()) {
nodes.emplace_back(logger->GetName(), 1);
}

status->Set("windowseventloglogger", new Dictionary(std::move(nodes)));
}

/**
* Processes a log entry and outputs it to the Windows Event Log.
*
* @param entry The log entry.
*/
void WindowsEventLogLogger::ProcessLogEntry(const LogEntry& entry)
{
if (l_EventLog != nullptr) {
std::string message = Logger::SeverityToString(entry.Severity) + "/" + entry.Facility + ": " + entry.Message;
std::array<const char *, 1> strings{
message.c_str()
};

WORD eventType;
switch (entry.Severity) {
case LogCritical:
eventType = EVENTLOG_ERROR_TYPE;
break;
case LogWarning:
eventType = EVENTLOG_WARNING_TYPE;
break;
default:
eventType = EVENTLOG_INFORMATION_TYPE;
}

ReportEventA(l_EventLog, eventType, 0, MSG_PLAIN_LOG_ENTRY, NULL, strings.size(), 0, strings.data(), NULL);
}
}

void WindowsEventLogLogger::Flush()
{
/* Nothing to do here. */
}

#endif /* _WIN32 */
35 changes: 35 additions & 0 deletions lib/base/windowseventloglogger.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* Icinga 2 | (c) 2021 Icinga GmbH | GPLv2+ */

#ifndef WINDOWSEVENTLOGLOGGER_H
#define WINDOWSEVENTLOGLOGGER_H

#ifdef _WIN32
#include "base/i2-base.hpp"
#include "base/windowseventloglogger-ti.hpp"

namespace icinga
{

/**
* A logger that logs to the Windows Event Log.
*
* @ingroup base
*/
class WindowsEventLogLogger final : public ObjectImpl<WindowsEventLogLogger>
{
public:
DECLARE_OBJECT(WindowsEventLogLogger);
DECLARE_OBJECTNAME(WindowsEventLogLogger);

static void StaticInitialize();
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);

protected:
void ProcessLogEntry(const LogEntry& entry) override;
void Flush() override;
};

}
#endif /* _WIN32 */

#endif /* WINDOWSEVENTLOGLOGGER_H */
15 changes: 15 additions & 0 deletions lib/base/windowseventloglogger.ti
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* Icinga 2 | (c) 2021 Icinga GmbH | GPLv2+ */

#include "base/logger.hpp"

library base;

namespace icinga
{

class WindowsEventLogLogger : Logger
{
activation_priority -100;
};

}
2 changes: 1 addition & 1 deletion tools/syntax/vim/syntax/icinga2.vim
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ syn keyword icinga2ObjType IcingaApplication IdoMysqlConnection IdoPgsqlConnec
syn keyword icinga2ObjType InfluxdbWriter LivestatusListener Notification NotificationCommand
syn keyword icinga2ObjType NotificationComponent OpenTsdbWriter PerfdataWriter
syn keyword icinga2ObjType ScheduledDowntime Service ServiceGroup SyslogLogger
syn keyword icinga2ObjType TimePeriod User UserGroup Zone
syn keyword icinga2ObjType TimePeriod User UserGroup WindowsEventLogLogger Zone

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

0 comments on commit 6de9f58

Please sign in to comment.