From 5ba17410c6eafc643509f132b5b8b0cff9bac0c1 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Mon, 2 Jul 2012 22:53:47 -0300 Subject: [PATCH] Feature: allow to choose among two log destinations, console or syslog. --- Readme | 2 + src/CMakeLists.txt | 2 + src/config/configuration.cpp | 13 ++++++ src/config/configuration.h | 8 +++- src/config/configurationoptions.cpp | 4 ++ src/config/option/logoutputoption.cpp | 74 +++++++++++++++++++++++++++++++++ src/config/option/logoutputoption.h | 48 +++++++++++++++++++++ src/host/logoutput.cpp | 61 +++++++++++++++++++++++++++ src/host/logoutput.h | 40 ++++++++++++++++++ src/main.cpp | 24 ++++++++++- 10 files changed, 274 insertions(+), 2 deletions(-) create mode 100644 src/config/option/logoutputoption.cpp create mode 100644 src/config/option/logoutputoption.h create mode 100644 src/host/logoutput.cpp create mode 100644 src/host/logoutput.h diff --git a/Readme b/Readme index 374c87b..349b8ff 100644 --- a/Readme +++ b/Readme @@ -101,6 +101,8 @@ following: - daemon: run the application as a daemon. - log-level: apply a filter of which log messages will be printed. The available options are the default Unix levels (e.g. debug, info, etc.). +- log-output: select the place where the log messages will be printed. The available + options are CONSOLE, TERMINAL and SYSLOG. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a1c112c..4ecf48e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,6 +51,7 @@ set(SOURCES config/option/linkdownintervaloption.cpp config/option/linkupintervaloption.cpp config/option/logleveloption.cpp + config/option/logoutputoption.cpp config/option/nameserveroption.cpp config/option/pingfaillimitoption.cpp config/option/sourcenetworkinterfaceoption.cpp @@ -62,6 +63,7 @@ set(SOURCES dns/timetolive.cpp host/hoststatus.cpp host/loglevel.cpp + host/logoutput.cpp host/messagepayload.cpp host/networkinterfacelist.cpp host/pinger.cpp diff --git a/src/config/configuration.cpp b/src/config/configuration.cpp index d3a1bf9..fb5a12a 100644 --- a/src/config/configuration.cpp +++ b/src/config/configuration.cpp @@ -31,6 +31,7 @@ using I2n::Logger::LogLevel; Configuration::Configuration() : Daemon( false ), LoggingLevel( LogLevel::Error ), + LoggingOutput( LogOutput_SYSLOG ), ConfigFileName( "" ), SourceNetworkInterface( "" ), NameServer( "" ), @@ -75,6 +76,18 @@ void Configuration::set_log_level( const LogLevel &log_level ) this->LoggingLevel = log_level; } +LogOutput Configuration::get_log_output() const +{ + return LoggingOutput; +} + +void Configuration::set_log_output( const LogOutput &log_output ) +{ + BOOST_ASSERT( (LogOutput_First <= log_output) && (log_output <= LogOutput_Last) ); + + this->LoggingOutput = log_output; +} + string Configuration::get_config_file_name() const { return ConfigFileName; diff --git a/src/config/configuration.h b/src/config/configuration.h index 13ddc15..bc837c6 100644 --- a/src/config/configuration.h +++ b/src/config/configuration.h @@ -25,11 +25,13 @@ on this file might be covered by the GNU General Public License. #include #include +#include + #include -#include "logfunc.hpp" #include "config/host.h" #include "host/loglevel.h" +#include "host/logoutput.h" //----------------------------------------------------------------------------- // Configuration @@ -53,6 +55,9 @@ public: I2n::Logger::LogLevel get_log_level() const; void set_log_level( const I2n::Logger::LogLevel &log_level ); + LogOutput get_log_output() const; + void set_log_output( const LogOutput &log_output ); + std::string get_nameserver() const; void set_nameserver( const std::string &nameserver ); @@ -82,6 +87,7 @@ public: private: bool Daemon; I2n::Logger::LogLevel LoggingLevel; + LogOutput LoggingOutput; std::string ConfigFileName; std::string SourceNetworkInterface; std::string NameServer; diff --git a/src/config/configurationoptions.cpp b/src/config/configurationoptions.cpp index c994bba..ee4bccc 100644 --- a/src/config/configurationoptions.cpp +++ b/src/config/configurationoptions.cpp @@ -38,6 +38,7 @@ #include "config/option/linkdownintervaloption.h" #include "config/option/linkupintervaloption.h" #include "config/option/logleveloption.h" +#include "config/option/logoutputoption.h" #include "config/option/nameserveroption.h" #include "config/option/pingfaillimitoption.h" #include "config/option/sourcenetworkinterfaceoption.h" @@ -78,6 +79,9 @@ ConfigurationOptions::ConfigurationOptions() : ConfigurationOptionItem log_level( new LogLevelOption ); GenericOptions.push_back( log_level ); + ConfigurationOptionItem log_output( new LogOutputOption ); + GenericOptions.push_back( log_output ); + ConfigurationOptionItem hosts_down_limit( new HostsDownLimitOption ); ConfigOptions.push_back( hosts_down_limit ); diff --git a/src/config/option/logoutputoption.cpp b/src/config/option/logoutputoption.cpp new file mode 100644 index 0000000..2a6f253 --- /dev/null +++ b/src/config/option/logoutputoption.cpp @@ -0,0 +1,74 @@ +/* + The software in this package is distributed under the GNU General + Public License version 2 (with a special exception described below). + + A copy of GNU General Public License (GPL) is included in this distribution, + in the file COPYING.GPL. + + As a special exception, if other files instantiate templates or use macros + or inline functions from this file, or you compile this file and link it + with other works to produce a work based on this file, this file + does not by itself cause the resulting work to be covered + by the GNU General Public License. + + However the source code for this file must still be made available + in accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work based + on this file might be covered by the GNU General Public License. + */ + +#include "config/option/logoutputoption.h" + +#include + +#include + +#include "host/logoutput.h" + +using namespace std; +using boost::program_options::value; +using boost::program_options::variables_map; +using I2n::Logger::GlobalLogger; + +//----------------------------------------------------------------------------- +// LogOutputOption +//----------------------------------------------------------------------------- + +/** + * @brief Default constructor. + */ +LogOutputOption::LogOutputOption() : + ConfigurationOption( + "log-output", + value()->default_value( "syslog" ), + "The place where to log the messages." + ) +{ +} + +/** + * @brief Destructor. + */ +LogOutputOption::~LogOutputOption() +{ +} + +bool LogOutputOption::parse( + const variables_map& vm, + Configuration *configuration +) +{ + // log-output + if ( 1 <= vm.count( get_command_string() ) ) + { + string output_string = vm[ get_command_string() ].as (); + LogOutput output = get_log_output_from_string( output_string ); + configuration->set_log_output( output ); + + GlobalLogger.info() << get_command_string() << "=" << output_string << endl; + return true; + } + + return false; +} diff --git a/src/config/option/logoutputoption.h b/src/config/option/logoutputoption.h new file mode 100644 index 0000000..34878de --- /dev/null +++ b/src/config/option/logoutputoption.h @@ -0,0 +1,48 @@ +/* + The software in this package is distributed under the GNU General + Public License version 2 (with a special exception described below). + + A copy of GNU General Public License (GPL) is included in this distribution, + in the file COPYING.GPL. + + As a special exception, if other files instantiate templates or use macros + or inline functions from this file, or you compile this file and link it + with other works to produce a work based on this file, this file + does not by itself cause the resulting work to be covered + by the GNU General Public License. + + However the source code for this file must still be made available + in accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work based + on this file might be covered by the GNU General Public License. + */ + +#ifndef LOG_OUTPUT_OPTION_H +#define LOG_OUTPUT_OPTION_H + +#include + +#include "config/option/configurationoption.h" + +//----------------------------------------------------------------------------- +// LogOutputOption +//----------------------------------------------------------------------------- + +/** + * @brief The log output option. + */ +class LogOutputOption : public ConfigurationOption +{ +public: + LogOutputOption(); + virtual ~LogOutputOption(); + + virtual bool parse( + const boost::program_options::variables_map &vm, + Configuration *configuration + ); + +}; + +#endif // LOG_OUTPUT_OPTION_H diff --git a/src/host/logoutput.cpp b/src/host/logoutput.cpp new file mode 100644 index 0000000..cbc4970 --- /dev/null +++ b/src/host/logoutput.cpp @@ -0,0 +1,61 @@ +/* +The software in this package is distributed under the GNU General +Public License version 2 (with a special exception described below). + +A copy of GNU General Public License (GPL) is included in this distribution, +in the file COPYING.GPL. + +As a special exception, if other files instantiate templates or use macros +or inline functions from this file, or you compile this file and link it +with other works to produce a work based on this file, this file +does not by itself cause the resulting work to be covered +by the GNU General Public License. + +However the source code for this file must still be made available +in accordance with section (3) of the GNU General Public License. + +This exception does not invalidate any other reasons why a work based +on this file might be covered by the GNU General Public License. +*/ + +#include "host/logoutput.h" + +#include +#include + +#include + +using namespace std; + +//----------------------------------------------------------------------------- +// LogOutput +//----------------------------------------------------------------------------- + +static map log_output_string_map; + +/** + * @brief Transform the @a log_output_string into a @c LogOutput. + * + * @param log_output_string The string to be parsed. + * + * @return The @c LogOutput corresponding to the @a log_output_string. + */ +LogOutput get_log_output_from_string( const string &log_output_string ) +{ + BOOST_ASSERT( !log_output_string.empty() ); + + // convert to uppercase to allow the protocol to be case insensitive + string log_output_uppercase_string( log_output_string ); + transform( log_output_string.begin(), log_output_string.end(), + log_output_uppercase_string.begin(), + ::toupper ); //lint !e534 + + // TODO move to an init method + log_output_string_map[ "SYSLOG" ] = LogOutput_SYSLOG; + log_output_string_map[ "TERMINAL" ] = LogOutput_TERMINAL; + log_output_string_map[ "CONSOLE" ] = LogOutput_TERMINAL; + + LogOutput protocol = log_output_string_map[ log_output_uppercase_string ]; + + return protocol; +} diff --git a/src/host/logoutput.h b/src/host/logoutput.h new file mode 100644 index 0000000..991e421 --- /dev/null +++ b/src/host/logoutput.h @@ -0,0 +1,40 @@ +/* + The software in this package is distributed under the GNU General + Public License version 2 (with a special exception described below). + + A copy of GNU General Public License (GPL) is included in this distribution, + in the file COPYING.GPL. + + As a special exception, if other files instantiate templates or use macros + or inline functions from this file, or you compile this file and link it + with other works to produce a work based on this file, this file + does not by itself cause the resulting work to be covered + by the GNU General Public License. + + However the source code for this file must still be made available + in accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work based + on this file might be covered by the GNU General Public License. + */ + +#ifndef LOG_OUTPUT_H +#define LOG_OUTPUT_H + +#include + +//----------------------------------------------------------------------------- +// LogOutput +//----------------------------------------------------------------------------- + +enum LogOutput +{ + LogOutput_First = 0, + LogOutput_SYSLOG = LogOutput_First, + LogOutput_TERMINAL, + LogOutput_Last = LogOutput_TERMINAL +}; + +LogOutput get_log_output_from_string( const std::string &output_string ); + +#endif // LOG_OUTPUT_H diff --git a/src/main.cpp b/src/main.cpp index 6f0b9e5..586c76b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,7 +43,6 @@ using boost::asio::io_service; using boost::shared_ptr; using I2n::Logger::GlobalLogger; - //----------------------------------------------------------------------------- // Declarations //----------------------------------------------------------------------------- @@ -51,6 +50,7 @@ using I2n::Logger::GlobalLogger; ConfigurationItem get_configuration(int, const char**); LinkStatusItem get_status_notifier(const ConfigurationItem&); void init_logger(); +void set_log_output(const ConfigurationItem &); void init_pingers(const ConfigurationItem&, const LinkStatusItem&, PingSchedulerList*); void start_pingers(const PingSchedulerList&); void stop_pingers(const PingSchedulerList&); @@ -107,6 +107,26 @@ void init_logger() I2n::Logger::set_log_level( default_log_level ); //lint !e534 } +void set_log_output( + const ConfigurationItem &configuration +) +{ + LogOutput log_output = configuration->get_log_output(); + switch (log_output) + { + case LogOutput_SYSLOG: + I2n::Logger::enable_syslog(true); + I2n::Logger::enable_stderr_log(false); + I2n::Logger::enable_log_file(false); + break; + case LogOutput_TERMINAL: + I2n::Logger::enable_syslog(false); + I2n::Logger::enable_stderr_log(true); + I2n::Logger::enable_log_file(false); + break; + } +} + void init_pingers( const ConfigurationItem &configuration, const LinkStatusItem &status_notifier, @@ -259,6 +279,8 @@ int main( int argc, const char *argv[] ) int log_level = configuration->get_log_level(); I2n::Logger::set_log_level( log_level ); //lint !e534 + set_log_output( configuration ); + bool daemon_mode = configuration->get_daemon(); if ( daemon_mode ) { -- 1.7.1