IBR-DTNSuite  0.8
daemon/src/StatisticLogger.cpp
Go to the documentation of this file.
00001 /*
00002  * StatisticLogger.cpp
00003  *
00004  *  Created on: 05.05.2010
00005  *      Author: morgenro
00006  */
00007 
00008 #include "StatisticLogger.h"
00009 #include "core/NodeEvent.h"
00010 #include "core/BundleEvent.h"
00011 #include <ibrdtn/utils/Clock.h>
00012 #include <ibrcommon/Logger.h>
00013 #include <sstream>
00014 #include <typeinfo>
00015 #include <ctime>
00016 
00017 namespace dtn
00018 {
00019         namespace daemon
00020         {
00021                 StatisticLogger::StatisticLogger(LoggerType type, unsigned int interval, std::string address, unsigned int port)
00022                  : _timer(*this), _type(type), _interval(interval), _sentbundles(0), _recvbundles(0),
00023                    _core(dtn::core::BundleCore::getInstance()), _sock(NULL), _address(address), _port(port)
00024                 {
00025                         IBRCOMMON_LOGGER(info) << "Logging module initialized. mode = " << _type << ", interval = " << interval << IBRCOMMON_LOGGER_ENDL;
00026                 }
00027 
00028                 StatisticLogger::StatisticLogger(LoggerType type, unsigned int interval, ibrcommon::File file)
00029                  : _timer(*this), _file(file), _type(type), _interval(interval), _sentbundles(0), _recvbundles(0),
00030                    _core(dtn::core::BundleCore::getInstance()), _sock(NULL), _address("127.0.0.1"), _port(1234)
00031                 {
00032                 }
00033 
00034                 StatisticLogger::~StatisticLogger()
00035                 {
00036 
00037                 }
00038 
00039                 void StatisticLogger::componentUp()
00040                 {
00041                         if ((_type == LOGGER_FILE_PLAIN) || (_type == LOGGER_FILE_CSV))
00042                         {
00043                                 // open statistic file
00044                                 if (_file.exists())
00045                                 {
00046                                         _fileout.open(_file.getPath().c_str(), ios_base::app);
00047                                 }
00048                                 else
00049                                 {
00050                                         _fileout.open(_file.getPath().c_str(), ios_base::trunc);
00051                                 }
00052                         }
00053 
00054                         // start the timer
00055                         _timer.set(1);
00056 
00057                         try {
00058                                 _timer.start();
00059                         } catch (const ibrcommon::ThreadException &ex) {
00060                                 IBRCOMMON_LOGGER(error) << "failed to start StatisticLogger\n" << ex.what() << IBRCOMMON_LOGGER_ENDL;
00061                         }
00062 
00063                         // register at the events
00064                         bindEvent(dtn::core::NodeEvent::className);
00065                         bindEvent(dtn::core::BundleEvent::className);
00066 
00067                         if (_type == LOGGER_UDP)
00068                         {
00069                                 _sock = new ibrcommon::UnicastSocket();
00070                                 _sock->bind();
00071                         }
00072                 }
00073 
00074                 size_t StatisticLogger::timeout(ibrcommon::Timer*)
00075                 {
00076                         switch (_type)
00077                         {
00078                         case LOGGER_STDOUT:
00079                                 writeStdLog(std::cout);
00080                                 break;
00081 
00082                         case LOGGER_SYSLOG:
00083                                 writeSyslog(std::cout);
00084                                 break;
00085 
00086                         case LOGGER_FILE_PLAIN:
00087                                 writePlainLog(_fileout);
00088                                 break;
00089 
00090                         case LOGGER_FILE_CSV:
00091                                 writeCsvLog(_fileout);
00092                                 break;
00093 
00094                         case LOGGER_FILE_STAT:
00095                                 writeStatLog();
00096                                 break;
00097 
00098                         case LOGGER_UDP:
00099                                 writeUDPLog(*_sock);
00100                                 break;
00101                         }
00102 
00103                         return _interval;
00104                 }
00105 
00106                 void StatisticLogger::componentDown()
00107                 {
00108                         unbindEvent(dtn::core::NodeEvent::className);
00109                         unbindEvent(dtn::core::BundleEvent::className);
00110 
00111                         _timer.pause();
00112 
00113                         if (_type >= LOGGER_FILE_PLAIN)
00114                         {
00115                                 // close the statistic file
00116                                 _fileout.close();
00117                         }
00118 
00119                         if (_type == LOGGER_UDP)
00120                         {
00121                                 delete _sock;
00122                         }
00123                 }
00124 
00125                 void StatisticLogger::raiseEvent(const dtn::core::Event *evt)
00126                 {
00127                         try {
00128                                 const dtn::core::NodeEvent &node = dynamic_cast<const dtn::core::NodeEvent&>(*evt);
00129 
00130                                 // do not announce on node info updated
00131                                 if (node.getAction() == dtn::core::NODE_INFO_UPDATED) return;
00132                         } catch (const std::bad_cast&) {
00133                         }
00134 
00135                         try {
00136                                 const dtn::core::BundleEvent &bundle = dynamic_cast<const dtn::core::BundleEvent&>(*evt);
00137 
00138                                 switch (bundle.getAction())
00139                                 {
00140                                         case dtn::core::BUNDLE_RECEIVED:
00141                                                 _recvbundles++;
00142                                                 break;
00143 
00144                                         case dtn::core::BUNDLE_FORWARDED:
00145                                                 _sentbundles++;
00146                                                 break;
00147 
00148                                         case dtn::core::BUNDLE_DELIVERED:
00149                                                 _sentbundles++;
00150                                                 break;
00151 
00152                                         default:
00153                                                 return;
00154                                                 break;
00155                                 }
00156                         } catch (const std::bad_cast&) {
00157                         }
00158 
00159                         if ((_type == LOGGER_UDP) && (_sock != NULL))
00160                         {
00161                                 writeUDPLog(*_sock);
00162                         }
00163                 }
00164 
00165                 void StatisticLogger::writeSyslog(std::ostream &stream)
00166                 {
00167                         const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00168                         dtn::storage::BundleStorage &storage = _core.getStorage();
00169 
00170                         stream  << "DTN-Stats: CurNeighbors " << neighbors.size()
00171                                         << "; RecvBundles " << _recvbundles
00172                                         << "; SentBundles " << _sentbundles
00173                                         << "; StoredBundles " << storage.count()
00174                                         << ";" << std::endl;
00175                 }
00176 
00177                 void StatisticLogger::writeStdLog(std::ostream &stream)
00178                 {
00179                         const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00180                         size_t timestamp = dtn::utils::Clock::getTime();
00181                         dtn::storage::BundleStorage &storage = _core.getStorage();
00182 
00183                         stream  << "Timestamp " << timestamp
00184                                         << "; CurNeighbors " << neighbors.size()
00185                                         << "; RecvBundles " << _recvbundles
00186                                         << "; SentBundles " << _sentbundles
00187                                         << "; StoredBundles " << storage.count()
00188                                         << ";" << std::endl;
00189                 }
00190 
00191                 void StatisticLogger::writePlainLog(std::ostream &stream)
00192                 {
00193                         const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00194                         size_t timestamp = dtn::utils::Clock::getTime();
00195                         dtn::storage::BundleStorage &storage = _core.getStorage();
00196 
00197                         stream  << timestamp << " "
00198                                         << neighbors.size() << " "
00199                                         << _recvbundles << " "
00200                                         << _sentbundles << " "
00201                                         << storage.count() << std::endl;
00202                 }
00203 
00204                 void StatisticLogger::writeCsvLog(std::ostream &stream)
00205                 {
00206                         const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00207                         size_t timestamp = dtn::utils::Clock::getTime();
00208                         dtn::storage::BundleStorage &storage = _core.getStorage();
00209 
00210                         stream  << timestamp << ","
00211                                         << neighbors.size() << ","
00212                                         << _recvbundles << ","
00213                                         << _sentbundles << ","
00214                                         << storage.count() << std::endl;
00215                 }
00216 
00217                 void StatisticLogger::writeStatLog()
00218                 {
00219                         // open statistic file
00220                         _fileout.open(_file.getPath().c_str(), ios_base::trunc);
00221 
00222                         const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00223                         size_t timestamp = dtn::utils::Clock::getTime();
00224                         dtn::storage::BundleStorage &storage = _core.getStorage();
00225 
00226                         time_t time_now = time(NULL);
00227                         struct tm * timeinfo;
00228                         timeinfo = localtime (&time_now);
00229                         std::string datetime = asctime(timeinfo);
00230                         datetime = datetime.substr(0, datetime.length() -1);
00231 
00232                         _fileout << "IBR-DTN statistics" << std::endl;
00233                         _fileout << std::endl;
00234                         _fileout << "dtn timestamp: " << timestamp << " (" << datetime << ")" << std::endl;
00235                         _fileout << "bundles sent: " << _sentbundles << std::endl;
00236                         _fileout << "bundles received: " << _recvbundles << std::endl;
00237                         _fileout << std::endl;
00238                         _fileout << "bundles in storage: " << storage.count() << std::endl;
00239                         _fileout << std::endl;
00240                         _fileout << "neighbors (" << neighbors.size() << "):" << std::endl;
00241 
00242                         for (std::set<dtn::core::Node>::const_iterator iter = neighbors.begin(); iter != neighbors.end(); iter++)
00243                         {
00244                                 _fileout << "\t" << (*iter).toString() << std::endl;
00245                         }
00246 
00247                         _fileout << std::endl;
00248 
00249                         // close the file
00250                         _fileout.close();
00251                 }
00252 
00253                 void StatisticLogger::writeUDPLog(ibrcommon::UnicastSocket &socket)
00254                 {
00255                         std::stringstream ss;
00256 
00257                         ss << dtn::core::BundleCore::local.getString() << "\n";
00258 
00259                         writeCsvLog(ss);
00260 
00261                         const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00262                         for (std::set<dtn::core::Node>::const_iterator iter = neighbors.begin(); iter != neighbors.end(); iter++)
00263                         {
00264                                 ss << (*iter).toString() << "\n";
00265                         }
00266 
00267                         ss << std::flush;
00268 
00269                         std::string data = ss.str();
00270                         ibrcommon::vaddress addr(_address);
00271                         socket.send(addr, _port, data.c_str(), data.length());
00272                 }
00273 
00274                 const std::string StatisticLogger::getName() const
00275                 {
00276                         return "StatisticLogger";
00277                 }
00278         }
00279 }