mirror of
				https://github.com/Icinga/icinga2.git
				synced 2025-11-04 13:45:04 +01:00 
			
		
		
		
	When Icinga 2 is started as a service, the early log messages generated until the FileLogger object is activated are lost and make it really hard to debug issues that (only) occur when Icinga 2 reloads. With this commit, these early log messages are written to the Windows Event Log.
		
			
				
	
	
		
			84 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* 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.
 | 
						|
 *
 | 
						|
 * This function implements the interface expected by the Logger base class and passes
 | 
						|
 * the log entry to WindowsEventLogLogger::WriteToWindowsEventLog().
 | 
						|
 *
 | 
						|
 * @param entry The log entry.
 | 
						|
 */
 | 
						|
void WindowsEventLogLogger::ProcessLogEntry(const LogEntry& entry) {
 | 
						|
	WindowsEventLogLogger::WriteToWindowsEventLog(entry);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Writes a LogEntry object to the Windows Event Log.
 | 
						|
 *
 | 
						|
 * @param entry The log entry.
 | 
						|
 */
 | 
						|
void WindowsEventLogLogger::WriteToWindowsEventLog(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 */
 |