ana/api/stats.hpp

Go to the documentation of this file.
00001 /* $Id: stats.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 
00003 /**
00004  * @file
00005  * @brief Implementation details for the ana project dealing with network statistics.
00006  *
00007  * ana: Asynchronous Network API.
00008  * Copyright (C) 2010 - 2012 Guillermo Biset.
00009  *
00010  * This file is part of the ana project.
00011  *
00012  * System:         ana
00013  * Language:       C++
00014  *
00015  * Author:         Guillermo Biset
00016  * E-Mail:         billybiset AT gmail DOT com
00017  *
00018  * ana is free software: you can redistribute it and/or modify
00019  * it under the terms of the GNU General Public License as published by
00020  * the Free Software Foundation, either version 2 of the License, or
00021  * (at your option) any later version.
00022  *
00023  * ana is distributed in the hope that it will be useful,
00024  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00025  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00026  * GNU General Public License for more details.
00027  *
00028  * You should have received a copy of the GNU General Public License
00029  * along with ana.  If not, see <http://www.gnu.org/licenses/>.
00030  *
00031  */
00032 
00033 #ifndef ANA_STATS_HPP
00034 #define ANA_STATS_HPP
00035 
00036 #include "timers.hpp"
00037 
00038 namespace ana
00039 {
00040     /** Type of collected network statistics. */
00041     enum stat_type
00042     {
00043         /** Statistics accumulated since creation of the network component. */
00044         ACCUMULATED,
00045 
00046         /** Network statistics for the last second. */
00047         SECONDS,
00048 
00049         /** Network statistics for the last minute. */
00050         MINUTES,
00051 
00052         /** Network statistics for the last hour. */
00053         HOURS,
00054 
00055         /** Network statistics for the last day. */
00056         DAYS
00057     };
00058 
00059     /**
00060      * A network statistics object, describes statistics for a given time period.
00061      */
00062     struct stats
00063     {
00064         virtual ~stats() {}
00065 
00066         /** Returns the amount of seconds since creation. */
00067         virtual size_t uptime()       const = 0;
00068 
00069         /** Returns the amount of received packets for a particular collected statistics object. */
00070         virtual size_t packets_in()   const = 0;
00071 
00072         /** Returns the amount of sent packets for a particular collected statistics object. */
00073         virtual size_t packets_out()  const = 0;
00074 
00075         /** Returns the amount of received bytes for a particular collected statistics object. */
00076         virtual size_t bytes_in()     const = 0;
00077 
00078         /** Returns the amount of sent bytes for a particular collected statistics object. */
00079         virtual size_t bytes_out()    const = 0;
00080     };
00081 
00082     /// @cond false
00083     namespace detail
00084     {
00085         class stats_logger : public stats
00086         {
00087             public:
00088                 stats_logger(size_t ms_to_reset, boost::asio::io_service& io_service) :
00089                     started_at_( std::time(0) ),
00090                     secs_to_reset_(ms_to_reset / 1000.0),
00091                     timer_(io_service),
00092                     start_time_( 0 ),
00093                     packets_in_( 0 ),
00094                     packets_out_( 0 ),
00095                     bytes_in_( 0 ),
00096                     bytes_out_( 0 )
00097                 {
00098                     if (secs_to_reset_ > 0 )
00099                     {
00100                         timer_.expires_from_now( secs_to_reset_ );
00101                         timer_.async_wait(boost::bind( &stats_logger::reset, this,
00102                                                        boost::asio::placeholders::error ) );
00103                     }
00104                 }
00105 
00106                 virtual ~stats_logger() {}
00107 
00108                 void log_send( detail::shared_buffer buffer )
00109                 {
00110                     ++packets_out_;
00111                     bytes_out_ += buffer->size() + HEADER_LENGTH;
00112                 }
00113 
00114                 void log_send( size_t size, bool finished_packet = false )
00115                 {
00116                     bytes_out_ += size;
00117                     if (finished_packet)
00118                         ++packets_out_;
00119                 }
00120 
00121                 void log_receive( read_buffer buffer )
00122                 {
00123                     ++packets_in_;
00124                     bytes_in_ += buffer->size();
00125                 }
00126 
00127                 void log_receive( size_t size, bool finished_packet = false )
00128                 {
00129                     bytes_in_ += size;
00130                     if (finished_packet)
00131                         ++packets_in_;
00132                 }
00133 
00134             private:
00135                 void reset(const boost::system::error_code& /*ec*/)
00136                 {
00137                     packets_in_  = 0;
00138                     packets_out_ = 0;
00139                     bytes_in_    = 0;
00140                     bytes_out_   = 0;
00141 
00142                     if (secs_to_reset_ > 0 )
00143                     {
00144                         timer_.expires_from_now( secs_to_reset_ );
00145                         timer_.async_wait(boost::bind( &stats_logger::reset, this,
00146                                                        boost::asio::placeholders::error ) );
00147                     }
00148                 }
00149 
00150                 virtual size_t uptime()       const
00151                 {
00152                     return std::time(0) - started_at_;
00153                 }
00154 
00155                 virtual size_t packets_in()   const
00156                 {
00157                     return packets_in_;
00158                 }
00159 
00160                 virtual size_t packets_out()  const
00161                 {
00162                     return packets_out_;
00163                 }
00164 
00165                 virtual size_t bytes_in()     const
00166                 {
00167                     return bytes_in_;
00168                 }
00169 
00170                 virtual size_t bytes_out()    const
00171                 {
00172                     return bytes_out_;
00173                 }
00174 
00175 
00176                 std::time_t  started_at_;
00177 
00178                 double       secs_to_reset_;
00179                 boost_timer  timer_;
00180 
00181                 std::time_t start_time_;
00182 
00183                 size_t packets_in_;
00184                 size_t packets_out_;
00185 
00186                 size_t bytes_in_;
00187                 size_t bytes_out_;
00188         };
00189     }
00190 
00191     class stats_collector
00192     {
00193         public:
00194             stats_collector() :
00195                 io_service_(),
00196                 collector_thread_( NULL ),
00197                 accumulator_( 0, io_service_),
00198                 seconds_stats_( time::seconds(1), io_service_ ),
00199                 minutes_stats_( time::minutes(1), io_service_ ),
00200                 hours_stats_( time::hours(1), io_service_ ),
00201                 days_stats_( time::days(1), io_service_ ),
00202                 current_packet_in_size_(0),
00203                 current_packet_out_size_(0),
00204                 current_packet_in_(0),
00205                 current_packet_out_(0),
00206                 current_packet_in_max_(0),
00207                 current_packet_out_max_(0),
00208                 current_packet_in_total_(0),
00209                 current_packet_out_total_(0)
00210             {
00211                 collector_thread_ = new boost::thread( boost::bind(&boost::asio::io_service::run,
00212                                                                    &io_service_) );
00213             }
00214 
00215             const stats* get_stats( stat_type type ) const
00216             {
00217                 switch (type)
00218                 {
00219                     case ACCUMULATED : return &accumulator_;
00220                     case SECONDS     : return &seconds_stats_;
00221                     case MINUTES     : return &minutes_stats_;
00222                     case HOURS       : return &hours_stats_;
00223                     case DAYS        : return &days_stats_;
00224                 }
00225                 throw std::runtime_error("Wrong stat stype requested.");
00226             }
00227 
00228             size_t current_packet_in_size()   const { return current_packet_in_size_;   }
00229             size_t current_packet_out_size()  const { return current_packet_out_size_;  }
00230 
00231             size_t current_packet_in_last()   const { return current_packet_in_;        }
00232             size_t current_packet_in_max()    const { return current_packet_in_max_;    }
00233             size_t current_packet_in_total()  const { return current_packet_in_total_;  }
00234 
00235             size_t current_packet_out_last()  const { return current_packet_out_;       }
00236             size_t current_packet_out_max()   const { return current_packet_out_max_;   }
00237             size_t current_packet_out_total() const { return current_packet_out_total_; }
00238 
00239             void log_send( detail::shared_buffer buffer )
00240             {
00241                 accumulator_.log_send  ( buffer );
00242                 seconds_stats_.log_send( buffer );
00243                 minutes_stats_.log_send( buffer );
00244                 hours_stats_.log_send  ( buffer );
00245                 days_stats_.log_send   ( buffer );
00246 
00247                 log_current_packet_out(buffer->size(), true);
00248             }
00249 
00250             void log_send( size_t size, bool finished_packet = false )
00251             {
00252                 accumulator_.log_send  ( size, finished_packet );
00253                 seconds_stats_.log_send( size, finished_packet );
00254                 minutes_stats_.log_send( size, finished_packet );
00255                 hours_stats_.log_send  ( size, finished_packet );
00256                 days_stats_.log_send   ( size, finished_packet );
00257 
00258                 log_current_packet_out(size, finished_packet);
00259             }
00260 
00261 
00262             void log_receive( read_buffer buffer )
00263             {
00264                 accumulator_.log_receive  ( buffer );
00265                 seconds_stats_.log_receive( buffer );
00266                 minutes_stats_.log_receive( buffer );
00267                 hours_stats_.log_receive  ( buffer );
00268                 days_stats_.log_receive   ( buffer );
00269 
00270                 log_current_packet_in(buffer->size(), true);
00271             }
00272 
00273             void log_receive( size_t size, bool finished_packet = false )
00274             {
00275                 accumulator_.log_receive  ( size, finished_packet );
00276                 seconds_stats_.log_receive( size, finished_packet );
00277                 minutes_stats_.log_receive( size, finished_packet );
00278                 hours_stats_.log_receive  ( size, finished_packet );
00279                 days_stats_.log_receive   ( size, finished_packet );
00280 
00281                 log_current_packet_in(size, finished_packet);
00282             }
00283 
00284             void start_send_packet( size_t size )    { current_packet_out_size_ = size; }
00285             void start_receive_packet( size_t size ) { current_packet_in_size_  = size; }
00286 
00287             ~stats_collector()
00288             {
00289                 io_service_.stop();
00290                 collector_thread_->join();
00291                 delete collector_thread_;
00292             }
00293 
00294         private:
00295             void log_current_packet_in(size_t size,bool finished_packet)
00296             {
00297                 if (finished_packet)
00298                 {
00299                     current_packet_in_       = 0;
00300                     current_packet_in_max_   = 0;
00301                     current_packet_in_total_ = 0;
00302                 }
00303                 else
00304                 {
00305                     current_packet_in_        = size;
00306                     current_packet_in_max_    = (std::max)(size, current_packet_in_max_);
00307                     current_packet_in_total_ += size;
00308                 }
00309             }
00310             void log_current_packet_out(size_t size, bool finished_packet)
00311             {
00312                 if (finished_packet)
00313                 {
00314                     current_packet_out_       = 0;
00315                     current_packet_out_max_   = 0;
00316                     current_packet_out_total_ = 0;
00317                 }
00318                 else
00319                 {
00320                     current_packet_out_        = size;
00321                     current_packet_out_max_    = (std::max)(size, current_packet_out_max_);
00322                     current_packet_out_total_ += size;
00323                 }
00324             }
00325 
00326 
00327             boost::asio::io_service io_service_;
00328 
00329             boost::thread*       collector_thread_;
00330 
00331             detail::stats_logger accumulator_;
00332             detail::stats_logger seconds_stats_;
00333             detail::stats_logger minutes_stats_;
00334             detail::stats_logger hours_stats_;
00335             detail::stats_logger days_stats_;
00336 
00337             size_t               current_packet_in_size_;
00338             size_t               current_packet_out_size_;
00339 
00340             size_t               current_packet_in_;
00341             size_t               current_packet_out_;
00342             size_t               current_packet_in_max_;
00343             size_t               current_packet_out_max_;
00344             size_t               current_packet_in_total_;
00345             size_t               current_packet_out_total_;
00346     };
00347     /// @endcond
00348 }
00349 
00350 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:45 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs