From de7808e32c352f82d6b82a8554f08c2e8b2d1b31 Mon Sep 17 00:00:00 2001 From: Tobias Deiminger Date: Sat, 11 Sep 2021 13:48:11 +0200 Subject: [PATCH] Make syslog facility handling reusable The upcoming JournaldLogger will need the same syslog validation and conversion logic, so factor it out from SyslogLogger to make it reusable. Also explicitely include syslog.h, which defines the syslog() function. --- lib/base/sysloglogger.cpp | 88 +++++++++++++++++++++------------------ lib/base/sysloglogger.hpp | 19 ++++++++- 2 files changed, 64 insertions(+), 43 deletions(-) diff --git a/lib/base/sysloglogger.cpp b/lib/base/sysloglogger.cpp index 44babc31c..c21445eca 100644 --- a/lib/base/sysloglogger.cpp +++ b/lib/base/sysloglogger.cpp @@ -5,6 +5,7 @@ #include "base/sysloglogger-ti.cpp" #include "base/configtype.hpp" #include "base/statsfunction.hpp" +#include using namespace icinga; @@ -12,11 +13,11 @@ REGISTER_TYPE(SyslogLogger); REGISTER_STATSFUNCTION(SyslogLogger, &SyslogLogger::StatsFunc); -INITIALIZE_ONCE(&SyslogLogger::StaticInitialize); +INITIALIZE_ONCE(&SyslogHelper::StaticInitialize); -std::map SyslogLogger::m_FacilityMap; +std::map SyslogHelper::m_FacilityMap; -void SyslogLogger::StaticInitialize() +void SyslogHelper::StaticInitialize() { ScriptGlobal::Set("System.FacilityAuth", "LOG_AUTH", true); ScriptGlobal::Set("System.FacilityAuthPriv", "LOG_AUTHPRIV", true); @@ -61,6 +62,44 @@ void SyslogLogger::StaticInitialize() m_FacilityMap["LOG_UUCP"] = LOG_UUCP; } +bool SyslogHelper::ValidateFacility(const String& facility) +{ + if (m_FacilityMap.find(facility) == m_FacilityMap.end()) { + try { + Convert::ToLong(facility); + } catch (const std::exception&) { + return false; + } + } + return true; +} + +int SyslogHelper::SeverityToNumber(LogSeverity severity) +{ + switch (severity) { + case LogDebug: + return LOG_DEBUG; + case LogNotice: + return LOG_NOTICE; + case LogWarning: + return LOG_WARNING; + case LogCritical: + return LOG_CRIT; + case LogInformation: + default: + return LOG_INFO; + } +} + +int SyslogHelper::FacilityToNumber(const String& facility) +{ + auto it = m_FacilityMap.find(facility); + if (it != m_FacilityMap.end()) + return it->second; + else + return Convert::ToLong(facility); +} + void SyslogLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&) { DictionaryData nodes; @@ -75,28 +114,14 @@ void SyslogLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&) void SyslogLogger::OnConfigLoaded() { ObjectImpl::OnConfigLoaded(); - - String facilityString = GetFacility(); - - auto it = m_FacilityMap.find(facilityString); - - if (it != m_FacilityMap.end()) - m_Facility = it->second; - else - m_Facility = Convert::ToLong(facilityString); + m_Facility = SyslogHelper::FacilityToNumber(GetFacility()); } void SyslogLogger::ValidateFacility(const Lazy& lvalue, const ValidationUtils& utils) { ObjectImpl::ValidateFacility(lvalue, utils); - - if (m_FacilityMap.find(lvalue()) == m_FacilityMap.end()) { - try { - Convert::ToLong(lvalue()); - } catch (const std::exception&) { - BOOST_THROW_EXCEPTION(ValidationError(this, { "facility" }, "Invalid facility specified.")); - } - } + if (!SyslogHelper::ValidateFacility(lvalue())) + BOOST_THROW_EXCEPTION(ValidationError(this, { "facility" }, "Invalid facility specified.")); } /** @@ -106,27 +131,8 @@ void SyslogLogger::ValidateFacility(const Lazy& lvalue, const Validation */ void SyslogLogger::ProcessLogEntry(const LogEntry& entry) { - int severity; - switch (entry.Severity) { - case LogDebug: - severity = LOG_DEBUG; - break; - case LogNotice: - severity = LOG_NOTICE; - break; - case LogWarning: - severity = LOG_WARNING; - break; - case LogCritical: - severity = LOG_CRIT; - break; - case LogInformation: - default: - severity = LOG_INFO; - break; - } - - syslog(severity | m_Facility, "%s", entry.Message.CStr()); + syslog(SyslogHelper::SeverityToNumber(entry.Severity) | m_Facility, + "%s", entry.Message.CStr()); } void SyslogLogger::Flush() diff --git a/lib/base/sysloglogger.hpp b/lib/base/sysloglogger.hpp index 168c5d9a5..d1d685907 100644 --- a/lib/base/sysloglogger.hpp +++ b/lib/base/sysloglogger.hpp @@ -10,6 +10,23 @@ namespace icinga { +/** + * Helper class to handle syslog facility strings and numbers. + * + * @ingroup base + */ +class SyslogHelper final +{ +public: + static void StaticInitialize(); + static bool ValidateFacility(const String& facility); + static int SeverityToNumber(LogSeverity severity); + static int FacilityToNumber(const String& facility); + +private: + static std::map m_FacilityMap; +}; + /** * A logger that logs to syslog. * @@ -21,14 +38,12 @@ public: DECLARE_OBJECT(SyslogLogger); DECLARE_OBJECTNAME(SyslogLogger); - static void StaticInitialize(); static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); void OnConfigLoaded() override; void ValidateFacility(const Lazy& lvalue, const ValidationUtils& utils) override; protected: - static std::map m_FacilityMap; int m_Facility; void ProcessLogEntry(const LogEntry& entry) override;