mirror of https://github.com/Icinga/icinga2.git
Write early log messages to the Windows Event Log
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.
This commit is contained in:
parent
6de9f58810
commit
05ca30a6a0
|
@ -9,6 +9,9 @@
|
||||||
#include "base/objectlock.hpp"
|
#include "base/objectlock.hpp"
|
||||||
#include "base/context.hpp"
|
#include "base/context.hpp"
|
||||||
#include "base/scriptglobal.hpp"
|
#include "base/scriptglobal.hpp"
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "base/windowseventloglogger.hpp"
|
||||||
|
#endif /* _WIN32 */
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -29,6 +32,7 @@ REGISTER_TYPE(Logger);
|
||||||
std::set<Logger::Ptr> Logger::m_Loggers;
|
std::set<Logger::Ptr> Logger::m_Loggers;
|
||||||
std::mutex Logger::m_Mutex;
|
std::mutex Logger::m_Mutex;
|
||||||
bool Logger::m_ConsoleLogEnabled = true;
|
bool Logger::m_ConsoleLogEnabled = true;
|
||||||
|
std::atomic<bool> Logger::m_EarlyLoggingEnabled (true);
|
||||||
bool Logger::m_TimestampEnabled = true;
|
bool Logger::m_TimestampEnabled = true;
|
||||||
LogSeverity Logger::m_ConsoleLogSeverity = LogInformation;
|
LogSeverity Logger::m_ConsoleLogSeverity = LogInformation;
|
||||||
|
|
||||||
|
@ -157,6 +161,14 @@ LogSeverity Logger::GetConsoleLogSeverity()
|
||||||
return m_ConsoleLogSeverity;
|
return m_ConsoleLogSeverity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Logger::DisableEarlyLogging() {
|
||||||
|
m_EarlyLoggingEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Logger::IsEarlyLoggingEnabled() {
|
||||||
|
return m_EarlyLoggingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
void Logger::DisableTimestamp()
|
void Logger::DisableTimestamp()
|
||||||
{
|
{
|
||||||
m_TimestampEnabled = false;
|
m_TimestampEnabled = false;
|
||||||
|
@ -242,6 +254,12 @@ Log::~Log()
|
||||||
* then cout will not flush lines automatically. */
|
* then cout will not flush lines automatically. */
|
||||||
std::cout << std::flush;
|
std::cout << std::flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (Logger::IsEarlyLoggingEnabled() && entry.Severity >= Logger::GetConsoleLogSeverity()) {
|
||||||
|
WindowsEventLogLogger::WriteToWindowsEventLog(entry);
|
||||||
|
}
|
||||||
|
#endif /* _WIN32 */
|
||||||
}
|
}
|
||||||
|
|
||||||
Log& Log::operator<<(const char *val)
|
Log& Log::operator<<(const char *val)
|
||||||
|
|
|
@ -67,6 +67,8 @@ public:
|
||||||
static void DisableConsoleLog();
|
static void DisableConsoleLog();
|
||||||
static void EnableConsoleLog();
|
static void EnableConsoleLog();
|
||||||
static bool IsConsoleLogEnabled();
|
static bool IsConsoleLogEnabled();
|
||||||
|
static void DisableEarlyLogging();
|
||||||
|
static bool IsEarlyLoggingEnabled();
|
||||||
static void DisableTimestamp();
|
static void DisableTimestamp();
|
||||||
static void EnableTimestamp();
|
static void EnableTimestamp();
|
||||||
static bool IsTimestampEnabled();
|
static bool IsTimestampEnabled();
|
||||||
|
@ -84,6 +86,7 @@ private:
|
||||||
static std::mutex m_Mutex;
|
static std::mutex m_Mutex;
|
||||||
static std::set<Logger::Ptr> m_Loggers;
|
static std::set<Logger::Ptr> m_Loggers;
|
||||||
static bool m_ConsoleLogEnabled;
|
static bool m_ConsoleLogEnabled;
|
||||||
|
static std::atomic<bool> m_EarlyLoggingEnabled;
|
||||||
static bool m_TimestampEnabled;
|
static bool m_TimestampEnabled;
|
||||||
static LogSeverity m_ConsoleLogSeverity;
|
static LogSeverity m_ConsoleLogSeverity;
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,9 +37,21 @@ void WindowsEventLogLogger::StatsFunc(const Dictionary::Ptr& status, const Array
|
||||||
/**
|
/**
|
||||||
* Processes a log entry and outputs it to the Windows Event Log.
|
* 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.
|
* @param entry The log entry.
|
||||||
*/
|
*/
|
||||||
void WindowsEventLogLogger::ProcessLogEntry(const LogEntry& 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) {
|
if (l_EventLog != nullptr) {
|
||||||
std::string message = Logger::SeverityToString(entry.Severity) + "/" + entry.Facility + ": " + entry.Message;
|
std::string message = Logger::SeverityToString(entry.Severity) + "/" + entry.Facility + ": " + entry.Message;
|
||||||
|
|
|
@ -24,6 +24,8 @@ public:
|
||||||
static void StaticInitialize();
|
static void StaticInitialize();
|
||||||
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
|
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
|
||||||
|
|
||||||
|
static void WriteToWindowsEventLog(const LogEntry& entry);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ProcessLogEntry(const LogEntry& entry) override;
|
void ProcessLogEntry(const LogEntry& entry) override;
|
||||||
void Flush() override;
|
void Flush() override;
|
||||||
|
|
|
@ -675,6 +675,14 @@ bool ConfigItem::ActivateItems(const std::vector<ConfigItem::Ptr>& newItems, boo
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* Find the last logger type to be activated. */
|
||||||
|
Type::Ptr lastLoggerType = nullptr;
|
||||||
|
for (const Type::Ptr& type : types) {
|
||||||
|
if (Logger::TypeInstance->IsAssignableFrom(type)) {
|
||||||
|
lastLoggerType = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const Type::Ptr& type : types) {
|
for (const Type::Ptr& type : types) {
|
||||||
for (const ConfigItem::Ptr& item : newItems) {
|
for (const ConfigItem::Ptr& item : newItems) {
|
||||||
if (!item->m_Object)
|
if (!item->m_Object)
|
||||||
|
@ -695,6 +703,12 @@ bool ConfigItem::ActivateItems(const std::vector<ConfigItem::Ptr>& newItems, boo
|
||||||
|
|
||||||
object->Activate(runtimeCreated, cookie);
|
object->Activate(runtimeCreated, cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: find a better name for silent
|
||||||
|
if (!silent && type == lastLoggerType) {
|
||||||
|
/* Disable early logging configuration once the last logger type was activated. */
|
||||||
|
Logger::DisableEarlyLogging();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
|
|
Loading…
Reference in New Issue