Go to the documentation of this file.00001
00002
00003
00004
00005
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, 0), _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, 0), _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
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
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
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(size_t)
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.remove();
00112
00113 if (_type >= LOGGER_FILE_PLAIN)
00114 {
00115
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
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::core::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::core::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::core::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::core::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
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::core::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).getURI() << std::endl;
00245 }
00246
00247 _fileout << std::endl;
00248
00249
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).getURI() << "\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 }