From ea24af659091a51f887c3df5b17844a008049605 Mon Sep 17 00:00:00 2001 From: Noah Hilverling Date: Tue, 19 Sep 2017 16:42:32 +0200 Subject: [PATCH] SyslogLogger: Implement option to set syslog facility fixes #3964 --- doc/09-object-types.md | 25 +++++++++++++ lib/base/sysloglogger.cpp | 78 ++++++++++++++++++++++++++++++++++++++- lib/base/sysloglogger.hpp | 7 ++++ lib/base/sysloglogger.ti | 3 ++ 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/doc/09-object-types.md b/doc/09-object-types.md index 70d0eaaee..6915aa323 100644 --- a/doc/09-object-types.md +++ b/doc/09-object-types.md @@ -1510,7 +1510,32 @@ Configuration Attributes: Name |Description ----------------|---------------- severity |**Optional.** The minimum severity for this log. Can be "debug", "notice", "information", "warning" or "critical". Defaults to "warning". + facility |**Optional.** Defines the facility to use for syslog entries. This can be a facility constant like `FacilityDaemon`. Defaults to `FacilityUser`. +Facility Constants: + + Name | Facility | Description + ---------------------|---------------|---------------- + FacilityAuth | LOG\_AUTH | The authorization system. + FacilityAuthPriv | LOG\_AUTHPRIV | The same as `FacilityAuth`, but logged to a file readable only by selected individuals. + FacilityCron | LOG\_CRON | The cron daemon. + FacilityDaemon | LOG\_DAEMON | System daemons that are not provided for explicitly by other facilities. + FacilityFtp | LOG\_FTP | The file transfer protocol daemons. + FacilityKern | LOG\_KERN | Messages generated by the kernel. These cannot be generated by any user processes. + FacilityLocal0 | LOG\_LOCAL0 | Reserved for local use. + FacilityLocal1 | LOG\_LOCAL1 | Reserved for local use. + FacilityLocal2 | LOG\_LOCAL2 | Reserved for local use. + FacilityLocal3 | LOG\_LOCAL3 | Reserved for local use. + FacilityLocal4 | LOG\_LOCAL4 | Reserved for local use. + FacilityLocal5 | LOG\_LOCAL5 | Reserved for local use. + FacilityLocal6 | LOG\_LOCAL6 | Reserved for local use. + FacilityLocal7 | LOG\_LOCAL7 | Reserved for local use. + FacilityLpr | LOG\_LPR | The line printer spooling system. + FacilityMail | LOG\_MAIL | The mail system. + FacilityNews | LOG\_NEWS | The network news system. + FacilitySyslog | LOG\_SYSLOG | Messages generated internally by syslogd. + FacilityUser | LOG\_USER | Messages generated by user processes. This is the default facility identifier if none is specified. + FacilityUucp | LOG\_UUCP | The UUCP system. ## TimePeriod diff --git a/lib/base/sysloglogger.cpp b/lib/base/sysloglogger.cpp index c068053d2..cbd4d5701 100644 --- a/lib/base/sysloglogger.cpp +++ b/lib/base/sysloglogger.cpp @@ -29,6 +29,55 @@ REGISTER_TYPE(SyslogLogger); REGISTER_STATSFUNCTION(SyslogLogger, &SyslogLogger::StatsFunc); +INITIALIZE_ONCE(&SyslogLogger::StaticInitialize); + +std::map SyslogLogger::m_FacilityMap; + +void SyslogLogger::StaticInitialize(void) +{ + ScriptGlobal::Set("FacilityAuth", "LOG_AUTH"); + ScriptGlobal::Set("FacilityAuthPriv", "LOG_AUTHPRIV"); + ScriptGlobal::Set("FacilityCron", "LOG_CRON"); + ScriptGlobal::Set("FacilityDaemon", "LOG_DAEMON"); + ScriptGlobal::Set("FacilityFtp", "LOG_FTP"); + ScriptGlobal::Set("FacilityKern", "LOG_KERN"); + ScriptGlobal::Set("FacilityLocal0", "LOG_LOCAL0"); + ScriptGlobal::Set("FacilityLocal1", "LOG_LOCAL1"); + ScriptGlobal::Set("FacilityLocal2", "LOG_LOCAL2"); + ScriptGlobal::Set("FacilityLocal3", "LOG_LOCAL3"); + ScriptGlobal::Set("FacilityLocal4", "LOG_LOCAL4"); + ScriptGlobal::Set("FacilityLocal5", "LOG_LOCAL5"); + ScriptGlobal::Set("FacilityLocal6", "LOG_LOCAL6"); + ScriptGlobal::Set("FacilityLocal7", "LOG_LOCAL7"); + ScriptGlobal::Set("FacilityLpr", "LOG_LPR"); + ScriptGlobal::Set("FacilityMail", "LOG_MAIL"); + ScriptGlobal::Set("FacilityNews", "LOG_NEWS"); + ScriptGlobal::Set("FacilitySyslog", "LOG_SYSLOG"); + ScriptGlobal::Set("FacilityUser", "LOG_USER"); + ScriptGlobal::Set("FacilityUucp", "LOG_UUCP"); + + m_FacilityMap["LOG_AUTH"] = LOG_AUTH; + m_FacilityMap["LOG_AUTHPRIV"] = LOG_AUTHPRIV; + m_FacilityMap["LOG_CRON"] = LOG_CRON; + m_FacilityMap["LOG_DAEMON"] = LOG_DAEMON; + m_FacilityMap["LOG_FTP"] = LOG_FTP; + m_FacilityMap["LOG_KERN"] = LOG_KERN; + m_FacilityMap["LOG_LOCAL0"] = LOG_LOCAL0; + m_FacilityMap["LOG_LOCAL1"] = LOG_LOCAL1; + m_FacilityMap["LOG_LOCAL2"] = LOG_LOCAL2; + m_FacilityMap["LOG_LOCAL3"] = LOG_LOCAL3; + m_FacilityMap["LOG_LOCAL4"] = LOG_LOCAL4; + m_FacilityMap["LOG_LOCAL5"] = LOG_LOCAL5; + m_FacilityMap["LOG_LOCAL6"] = LOG_LOCAL6; + m_FacilityMap["LOG_LOCAL7"] = LOG_LOCAL7; + m_FacilityMap["LOG_LPR"] = LOG_LPR; + m_FacilityMap["LOG_MAIL"] = LOG_MAIL; + m_FacilityMap["LOG_NEWS"] = LOG_NEWS; + m_FacilityMap["LOG_SYSLOG"] = LOG_SYSLOG; + m_FacilityMap["LOG_USER"] = LOG_USER; + m_FacilityMap["LOG_UUCP"] = LOG_UUCP; +} + void SyslogLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&) { Dictionary::Ptr nodes = new Dictionary(); @@ -40,6 +89,33 @@ void SyslogLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&) status->Set("sysloglogger", nodes); } +void SyslogLogger::OnConfigLoaded(void) +{ + 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); +} + +void SyslogLogger::ValidateFacility(const String& value, const ValidationUtils& utils) +{ + ObjectImpl::ValidateFacility(value, utils); + + if (m_FacilityMap.find(value) == m_FacilityMap.end()) { + try { + Convert::ToLong(value); + } catch (const std::exception&) { + BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("facility"), "Invalid facility specified.")); + } + } +} + /** * Processes a log entry and outputs it to syslog. * @@ -67,7 +143,7 @@ void SyslogLogger::ProcessLogEntry(const LogEntry& entry) break; } - syslog(severity | LOG_USER, "%s", entry.Message.CStr()); + syslog(severity | m_Facility, "%s", entry.Message.CStr()); } void SyslogLogger::Flush(void) diff --git a/lib/base/sysloglogger.hpp b/lib/base/sysloglogger.hpp index 3f041ba5f..c5cfd0050 100644 --- a/lib/base/sysloglogger.hpp +++ b/lib/base/sysloglogger.hpp @@ -38,9 +38,16 @@ public: DECLARE_OBJECT(SyslogLogger); DECLARE_OBJECTNAME(SyslogLogger); + static void StaticInitialize(void); static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); + virtual void OnConfigLoaded(void) override; + virtual void ValidateFacility(const String& value, const ValidationUtils& utils) override; + protected: + static std::map m_FacilityMap; + int m_Facility; + virtual void ProcessLogEntry(const LogEntry& entry) override; virtual void Flush(void) override; }; diff --git a/lib/base/sysloglogger.ti b/lib/base/sysloglogger.ti index 63651e68a..3b375f894 100644 --- a/lib/base/sysloglogger.ti +++ b/lib/base/sysloglogger.ti @@ -26,6 +26,9 @@ namespace icinga class SyslogLogger : Logger { + [config] String facility { + default {{{ return "LOG_USER"; }}} + }; }; }