The limit-ping-fail option is available (and read) from the configuration file
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@intra2net.com>
Mon, 21 Mar 2011 14:58:20 +0000 (15:58 +0100)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@intra2net.com>
Mon, 21 Mar 2011 15:06:11 +0000 (16:06 +0100)
- this option sets the threshold of pings to a host that must fail in order to mark the host as down.

12 files changed:
Readme
conf/pingcheck.conf
src/config/configuration.cpp
src/config/configuration.h
src/config/configurationreader.cpp
src/config/configurationreader.h
src/main.cpp
src/ping/boostpinger.h
src/ping/pinganalyzer.cpp
src/ping/pinganalyzer.h
src/ping/pingscheduler.cpp
src/ping/pingscheduler.h

diff --git a/Readme b/Readme
index 70a0101..c197b94 100644 (file)
--- a/Readme
+++ b/Readme
@@ -106,6 +106,16 @@ of error detection and handling:
 - Handle Exceptions for exceptional errors.
 
 
+2.5. Assertions
+---------------------------------------
+Also, it is good to use ASSERTS to document assumptions about:
+- method's argument values. If you expect that a parameter have certain values,
+  assert it (preconditions)
+- and if you expect the method deliver a certain value, assert in the end of
+  the method (postcondition).
+This is known by programming by contract.
+
+
 
 3.   Source Code
 =======================================
@@ -157,9 +167,12 @@ configuration block.
 4.1. General
 ---------------------------------------
 This configurations are shared among and affect all the hosts.
-- limit-hosts-down: ranges from 0 to the number of hosts available. This value
-  represents the minimum number of hosts that have to fail (i.e. do not reply
-  the ping) in order to alert any external system.
+- limit-hosts-down: an absolute number, which ranges from 0 to the number of
+  hosts available. This value represents the minimum number of hosts that have
+  to fail (i.e. do not reply to the ping) in order to alert any external system.
+- limit-ping-fail: percentage of pings to a host that can fail. If the
+  percentage of failed pings to a host exceed this number, then the host is
+  considered down.
 
 
 4.2. Host
index 5e5548b..799a7c8 100644 (file)
@@ -1,4 +1,5 @@
 limit-hosts-down=5
+limit-ping-fail=40
 
 [host]
 name=www.intra2net.com
index ea6bce0..468993f 100644 (file)
@@ -11,9 +11,12 @@ using namespace std;
 Configuration::Configuration() :
     ConfigFileName( "" ),
     LimitHostsDown( 0 ),
-    Hosts(),
     MinLimitHostsDown( 0 ),
-    MaxLimitHostsDown( 50 )
+    MaxLimitHostsDown( 50 ),
+    LimitPingFail( 0 ),
+    MinLimitPingFail( 0 ),
+    MaxLimitPingFail( 100 ),
+    Hosts()
 {
 }
 
@@ -45,6 +48,16 @@ void Configuration::set_limit_hosts_down( const int limit_hosts_down )
     this->LimitHostsDown = limit_hosts_down;
 }
 
+int Configuration::get_limit_ping_fail() const
+{
+    return LimitPingFail;
+}
+
+void Configuration::set_limit_ping_fail( const int limit_ping_fail )
+{
+    LimitPingFail = limit_ping_fail;
+}
+
 vector< HostItem > Configuration::get_hosts() const
 {
     return Hosts;
index b86335e..fa8d0a7 100644 (file)
@@ -24,16 +24,21 @@ public:
     int get_limit_hosts_down() const;
     void set_limit_hosts_down( const int limit_hosts_down );
 
+    int get_limit_ping_fail() const;
+    void set_limit_ping_fail( const int limit_ping_fail );
+
     std::vector<HostItem> get_hosts() const;
     void set_hosts( const std::vector<HostItem> &hosts_list );
 
 private:
     std::string ConfigFileName;
     int LimitHostsDown;
-    std::vector<HostItem> Hosts;
-
     const int MinLimitHostsDown;
     const int MaxLimitHostsDown;
+    int LimitPingFail;
+    const int MinLimitPingFail;
+    const int MaxLimitPingFail;
+    std::vector<HostItem> Hosts;
 
 };
 
index 2df1a63..06c2d0f 100644 (file)
@@ -26,6 +26,9 @@ ConfigurationReader::ConfigurationReader() :
     DefaultLimitHostsDown( 1 ),
     LimitHostsDownCmdStr( "limit-hosts-down" ),
     LimitHostsDownCmdDesc( "Limit of host that have to be down in order to notify." ),
+    DefaultLimitPingFail( 50 ),
+    LimitPingFailCmdStr( "limit-ping-fail" ),
+    LimitPingFailCmdDesc( "Maximum percentage of pings that can fail for a given host." ),
     HostNameCmdStr( "host.name" ),
     HostNameCmdDesc( "Host address" ),
     DefaultHostInterval( 1 ),
@@ -110,6 +113,7 @@ options_description ConfigurationReader::get_configuration_options() const
     options_description options( "Configuration" );
     options.add_options()
         ( LimitHostsDownCmdStr.c_str(), value<int>()->default_value( DefaultLimitHostsDown ), LimitHostsDownCmdDesc.c_str() )
+        ( LimitPingFailCmdStr.c_str(), value<int>()->default_value( DefaultLimitPingFail ), LimitPingFailCmdDesc.c_str() )
         ( HostNameCmdStr.c_str(), value< vector<string> >(), HostNameCmdDesc.c_str() )
         ( HostIntervalCmdStr.c_str(), value< vector<int> >(), HostIntervalCmdDesc.c_str() )
     ;
@@ -119,6 +123,7 @@ options_description ConfigurationReader::get_configuration_options() const
 
 bool ConfigurationReader::parse_configuration_options( const variables_map &vm )
 {
+    // config-file
     if ( vm.count( ConfigFileCmdStr ) )
     {
         string config_file_name = vm[ ConfigFileCmdStr ].as<string> ();
@@ -127,6 +132,7 @@ bool ConfigurationReader::parse_configuration_options( const variables_map &vm )
         cout << ConfigFileCmdStr << "=" << config_file_name << endl;
     }
 
+    // limit-hosts-down
     if ( vm.count( LimitHostsDownCmdStr ) )
     {
         int limit_host_down = vm[ LimitHostsDownCmdStr ].as<int> ();
@@ -135,6 +141,16 @@ bool ConfigurationReader::parse_configuration_options( const variables_map &vm )
         cout << LimitHostsDownCmdStr << "=" << limit_host_down << endl;
     }
 
+    // limit-ping-fail
+    if ( vm.count( LimitPingFailCmdStr ) )
+    {
+        int limit_ping_fail = vm[ LimitPingFailCmdStr ].as<int> ();
+        Config.set_limit_ping_fail( limit_ping_fail );
+
+        cout << LimitPingFailCmdStr << "=" << limit_ping_fail << endl;
+    }
+
+    // [host] name
     int hosts_names_total = 0;
     if ( vm.count( HostNameCmdStr ) )
     {
@@ -154,6 +170,7 @@ bool ConfigurationReader::parse_configuration_options( const variables_map &vm )
         hosts_names_total = hosts_names.size();
     }
 
+    // [host] interval
     int hosts_interval_total = 0;
     if ( vm.count( HostIntervalCmdStr ) )
     {
@@ -174,7 +191,8 @@ bool ConfigurationReader::parse_configuration_options( const variables_map &vm )
     }
 
     // TODO deal when interval for a given host was not set. use DefaultHostInterval
-    BOOST_ASSERT(hosts_names_total == hosts_interval_total);
+
+    BOOST_ASSERT( hosts_names_total == hosts_interval_total );
 
     return true;
 }
index a6dded0..f586892 100644 (file)
@@ -64,6 +64,9 @@ private:
     const int DefaultLimitHostsDown;
     const std::string LimitHostsDownCmdStr;
     const std::string LimitHostsDownCmdDesc;
+    const int DefaultLimitPingFail;
+    const std::string LimitPingFailCmdStr;
+    const std::string LimitPingFailCmdDesc;
     const std::string HostNameCmdStr;
     const std::string HostNameCmdDesc;
     const int DefaultHostInterval;
index ae4d889..1608ffd 100644 (file)
@@ -1,12 +1,14 @@
+#include <vector>
+
 #include <boost/asio.hpp>
 #include <boost/foreach.hpp>
-#include <vector>
 
 #include "config/configurationreader.h"
 #include "config/host.h"
 #include "ping/pingscheduler.h"
 
 using namespace std;
+using namespace boost;
 using namespace boost::asio;
 
 int main( int argc, char* argv[] )
@@ -18,8 +20,11 @@ int main( int argc, char* argv[] )
     {
         io_service io_service;
 
-        // TODO init_pingers()
         Configuration config = config_reader.get_configuration();
+
+        int limit_ping_fail = config.get_limit_ping_fail();
+
+        // TODO init_pingers()
         vector< HostItem > hosts = config.get_hosts();
         vector< PingSchedulerItem > scheduler_list;
         BOOST_FOREACH( HostItem host, hosts )
@@ -28,7 +33,8 @@ int main( int argc, char* argv[] )
             int ping_interval = (*host).get_interval();
             PingSchedulerItem scheduler(
                     new PingScheduler(
-                            io_service, ping_address, ping_interval
+                            io_service, ping_address, ping_interval,
+                            limit_ping_fail
                     )
             );
             scheduler_list.push_back( scheduler );
index b8b840b..a1bbf12 100644 (file)
@@ -11,6 +11,9 @@ class IcmpPacket;
 // BoostPinger
 //-----------------------------------------------------------------------------
 
+/**
+ * @brief This class performs ping to host using Boost Asio.
+ */
 class BoostPinger : public Pinger
 {
 public:
index 72692ca..b7f4acd 100644 (file)
@@ -5,6 +5,7 @@
 #include <boost/assert.hpp>
 
 using namespace std;
+using namespace boost;
 
 //-----------------------------------------------------------------------------
 // PingAnalyzer
@@ -12,16 +13,16 @@ using namespace std;
 
 PingAnalyzer::PingAnalyzer(
         const string &host_address,
-        const int ping_fail_threshold_percentage
+        const int limit_ping_fail_percentage
 ) :
     Notifier( host_address ),
-    PingFailThresholdPercentage( ping_fail_threshold_percentage ),
+    LimitPingFailPercentage( limit_ping_fail_percentage ),
     ResolvedIpCount( 0 ),
     PingsPerformedCount( 0 ),
     PingsFailedCount( 0 )
 {
     BOOST_ASSERT( !host_address.empty() );
-    BOOST_ASSERT( ( 0 <= ping_fail_threshold_percentage ) && ( ping_fail_threshold_percentage <= 100 ) );
+    BOOST_ASSERT( ( 0 <= limit_ping_fail_percentage ) && ( limit_ping_fail_percentage <= 100 ) );
 }
 
 PingAnalyzer::~PingAnalyzer()
@@ -41,18 +42,20 @@ void PingAnalyzer::update_ping_statistics( bool ping_success )
     BOOST_ASSERT( 0 <= PingsPerformedCount );
     BOOST_ASSERT( PingsFailedCount <= PingsPerformedCount );
 
-    ++PingsPerformedCount;
+    increase_ping_performed_count();
 
     if ( !ping_success )
     {
-        ++PingsFailedCount;
+        increase_ping_failed_count();
     }
 
-    if ( PingsPerformedCount >= ResolvedIpCount )
+    // after we tried all IPs resolved for this host, we can analyze how many
+    // failed
+    if ( tried_all_resolved_ip() )
     {
         analyze();
 
-        reset_ping_counter();
+        reset_ping_counters();
     }
 
     BOOST_ASSERT( PingsFailedCount <= PingsPerformedCount );
@@ -60,13 +63,13 @@ void PingAnalyzer::update_ping_statistics( bool ping_success )
 
 void PingAnalyzer::analyze()
 {
-    BOOST_ASSERT( ( 0 <= PingFailThresholdPercentage ) && ( PingFailThresholdPercentage <= 100 ) );
-    BOOST_ASSERT( ( 0 <= PingsFailedCount ) && ( PingsFailedCount <= PingsPerformedCount ) );
     BOOST_ASSERT( PingsPerformedCount == ResolvedIpCount );
+    BOOST_ASSERT( ( 0 <= LimitPingFailPercentage ) && ( LimitPingFailPercentage <= 100 ) );
+    BOOST_ASSERT( ( 0 <= PingsFailedCount ) && ( PingsFailedCount <= PingsPerformedCount ) );
 
-    int ping_fail_threshold_absolute = PingFailThresholdPercentage / 100; // TODO possible number loss, check with care
+    int limit_ping_fail_absolute = LimitPingFailPercentage / 100; // TODO possible precision loss, check with care
 
-    if ( PingsFailedCount > ping_fail_threshold_absolute )
+    if ( PingsFailedCount > limit_ping_fail_absolute )
     {
         Notifier.alert_host_down();
     }
@@ -77,8 +80,23 @@ void PingAnalyzer::analyze()
 
 }
 
-void PingAnalyzer::reset_ping_counter()
+void PingAnalyzer::increase_ping_performed_count()
+{
+    ++PingsPerformedCount;
+}
+
+void PingAnalyzer::increase_ping_failed_count()
+{
+    ++PingsFailedCount;
+}
+
+void PingAnalyzer::reset_ping_counters()
 {
     PingsPerformedCount = 0;
     PingsFailedCount = 0;
 }
+
+bool PingAnalyzer::tried_all_resolved_ip() const
+{
+    return ( PingsPerformedCount >= ResolvedIpCount );
+}
index b97adc4..e7033cc 100644 (file)
@@ -3,12 +3,19 @@
 
 #include <string>
 
+#include <boost/shared_ptr.hpp>
+
 #include "ping/pingstatusnotifier.h"
 
 //-----------------------------------------------------------------------------
 // PingAnalyzer
 //-----------------------------------------------------------------------------
 
+/**
+ * @brief This class analyze the ping status (success or failure) and decides
+ * what to do.
+ * Scope: one object per host.
+ */
 class PingAnalyzer
 {
 public:
@@ -23,11 +30,14 @@ public:
 
 private:
     void analyze();
-    void reset_ping_counter();
+    void increase_ping_performed_count();
+    void increase_ping_failed_count();
+    void reset_ping_counters();
+    bool tried_all_resolved_ip() const;
 
 private:
     PingStatusNotifier Notifier;
-    int PingFailThresholdPercentage;
+    int LimitPingFailPercentage;
     int ResolvedIpCount;
     int PingsPerformedCount;
     int PingsFailedCount;
index 499751d..38a7ee3 100644 (file)
@@ -19,14 +19,16 @@ using namespace boost::posix_time;
 PingScheduler::PingScheduler(
         boost::asio::io_service &io_service,
         const string &ping_address,
-        const int ping_interval_in_sec
+        const int ping_interval_in_sec,
+        const int limit_ping_fail_percentage
+
 ) :
     IoService( io_service ),
     Timer( io_service ),
     TimeSentLastPing( microsec_clock::universal_time() ),
-    IpList( ping_address ),
     PingIntervalInSec( ping_interval_in_sec ),
-    Analyzer( ping_address, 50 ) // 50% max acceptable failure
+    IpList( ping_address ),
+    Analyzer( ping_address, limit_ping_fail_percentage )
 {
 }
 
index 1060477..d9b9d5a 100644 (file)
 // PingScheduler
 //-----------------------------------------------------------------------------
 
+/**
+ * @brief This class is responsible to control whether to ping a host. It
+ * schedules periodic pings to a host.
+ * Scope: one object per host.
+ */
 class PingScheduler
 {
 public:
     PingScheduler(
             boost::asio::io_service &io_service,
             const std::string &ping_address,
-            const int ping_interval_in_sec
+            const int ping_interval_in_sec,
+            const int limit_ping_fail_percentage
     );
     virtual ~PingScheduler();
 
@@ -38,8 +44,8 @@ private:
     boost::asio::io_service &IoService;
     boost::asio::deadline_timer Timer;
     boost::posix_time::ptime TimeSentLastPing;
-    DnsResolver IpList;
     const int PingIntervalInSec;
+    DnsResolver IpList;
     PingAnalyzer Analyzer;
 
 };