IBR-DTNSuite
0.8
|
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 }