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 }
00071 }
00072
00073 size_t StatisticLogger::timeout(size_t)
00074 {
00075 switch (_type)
00076 {
00077 case LOGGER_STDOUT:
00078 writeStdLog(std::cout);
00079 break;
00080
00081 case LOGGER_SYSLOG:
00082 writeSyslog(std::cout);
00083 break;
00084
00085 case LOGGER_FILE_PLAIN:
00086 writePlainLog(_fileout);
00087 break;
00088
00089 case LOGGER_FILE_CSV:
00090 writeCsvLog(_fileout);
00091 break;
00092
00093 case LOGGER_FILE_STAT:
00094 writeStatLog();
00095 break;
00096
00097 case LOGGER_UDP:
00098 writeUDPLog(*_sock);
00099 break;
00100 }
00101
00102 return _interval;
00103 }
00104
00105 void StatisticLogger::componentDown()
00106 {
00107 unbindEvent(dtn::core::NodeEvent::className);
00108 unbindEvent(dtn::core::BundleEvent::className);
00109
00110 _timer.remove();
00111
00112 if (_type >= LOGGER_FILE_PLAIN)
00113 {
00114
00115 _fileout.close();
00116 }
00117
00118 if (_type == LOGGER_UDP)
00119 {
00120 delete _sock;
00121 }
00122 }
00123
00124 void StatisticLogger::raiseEvent(const dtn::core::Event *evt)
00125 {
00126 try {
00127 const dtn::core::NodeEvent &node = dynamic_cast<const dtn::core::NodeEvent&>(*evt);
00128
00129
00130 if (node.getAction() == dtn::core::NODE_INFO_UPDATED) return;
00131 } catch (std::bad_cast& bc) {
00132 }
00133
00134 try {
00135 const dtn::core::BundleEvent &bundle = dynamic_cast<const dtn::core::BundleEvent&>(*evt);
00136
00137 switch (bundle.getAction())
00138 {
00139 case dtn::core::BUNDLE_RECEIVED:
00140 _recvbundles++;
00141 break;
00142
00143 case dtn::core::BUNDLE_FORWARDED:
00144 _sentbundles++;
00145 break;
00146
00147 case dtn::core::BUNDLE_DELIVERED:
00148 _sentbundles++;
00149 break;
00150
00151 default:
00152 return;
00153 break;
00154 }
00155 } catch (std::bad_cast& bc) {
00156 }
00157
00158 if ((_type == LOGGER_UDP) && (_sock != NULL))
00159 {
00160 writeUDPLog(*_sock);
00161 }
00162 }
00163
00164 void StatisticLogger::writeSyslog(std::ostream &stream)
00165 {
00166 const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00167 dtn::core::BundleStorage &storage = _core.getStorage();
00168
00169 stream << "DTN-Stats: CurNeighbors " << neighbors.size()
00170 << "; RecvBundles " << _recvbundles
00171 << "; SentBundles " << _sentbundles
00172 << "; StoredBundles " << storage.count()
00173 << ";" << std::endl;
00174 }
00175
00176 void StatisticLogger::writeStdLog(std::ostream &stream)
00177 {
00178 const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00179 size_t timestamp = dtn::utils::Clock::getTime();
00180 dtn::core::BundleStorage &storage = _core.getStorage();
00181
00182 stream << "Timestamp " << timestamp
00183 << "; CurNeighbors " << neighbors.size()
00184 << "; RecvBundles " << _recvbundles
00185 << "; SentBundles " << _sentbundles
00186 << "; StoredBundles " << storage.count()
00187 << ";" << std::endl;
00188 }
00189
00190 void StatisticLogger::writePlainLog(std::ostream &stream)
00191 {
00192 const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00193 size_t timestamp = dtn::utils::Clock::getTime();
00194 dtn::core::BundleStorage &storage = _core.getStorage();
00195
00196 stream << timestamp << " "
00197 << neighbors.size() << " "
00198 << _recvbundles << " "
00199 << _sentbundles << " "
00200 << storage.count() << std::endl;
00201 }
00202
00203 void StatisticLogger::writeCsvLog(std::ostream &stream)
00204 {
00205 const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00206 size_t timestamp = dtn::utils::Clock::getTime();
00207 dtn::core::BundleStorage &storage = _core.getStorage();
00208
00209 stream << timestamp << ","
00210 << neighbors.size() << ","
00211 << _recvbundles << ","
00212 << _sentbundles << ","
00213 << storage.count() << std::endl;
00214 }
00215
00216 void StatisticLogger::writeStatLog()
00217 {
00218
00219 _fileout.open(_file.getPath().c_str(), ios_base::trunc);
00220
00221 const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00222 size_t timestamp = dtn::utils::Clock::getTime();
00223 dtn::core::BundleStorage &storage = _core.getStorage();
00224
00225 time_t time_now = time(NULL);
00226 struct tm * timeinfo;
00227 timeinfo = localtime (&time_now);
00228 std::string datetime = asctime(timeinfo);
00229 datetime = datetime.substr(0, datetime.length() -1);
00230
00231 _fileout << "IBR-DTN statistics" << std::endl;
00232 _fileout << std::endl;
00233 _fileout << "dtn timestamp: " << timestamp << " (" << datetime << ")" << std::endl;
00234 _fileout << "bundles sent: " << _sentbundles << std::endl;
00235 _fileout << "bundles received: " << _recvbundles << std::endl;
00236 _fileout << std::endl;
00237 _fileout << "bundles in storage: " << storage.count() << std::endl;
00238 _fileout << std::endl;
00239 _fileout << "neighbors (" << neighbors.size() << "):" << std::endl;
00240
00241 for (std::set<dtn::core::Node>::const_iterator iter = neighbors.begin(); iter != neighbors.end(); iter++)
00242 {
00243 _fileout << "\t" << (*iter).getURI() << std::endl;
00244 }
00245
00246 _fileout << std::endl;
00247
00248
00249 _fileout.close();
00250 }
00251
00252 void StatisticLogger::writeUDPLog(ibrcommon::UnicastSocket &socket)
00253 {
00254 std::stringstream ss;
00255
00256 ss << dtn::core::BundleCore::local.getString() << "\n";
00257
00258 writeCsvLog(ss);
00259
00260 const std::set<dtn::core::Node> neighbors = _core.getNeighbors();
00261 for (std::set<dtn::core::Node>::const_iterator iter = neighbors.begin(); iter != neighbors.end(); iter++)
00262 {
00263 ss << (*iter).getURI() << "\n";
00264 }
00265
00266 ss << std::flush;
00267
00268 std::string data = ss.str();
00269 ibrcommon::udpsocket::peer p = socket.getPeer(_address, _port);
00270 p.send(data.c_str(), data.length());
00271 }
00272
00273 const std::string StatisticLogger::getName() const
00274 {
00275 return "StatisticLogger";
00276 }
00277 }
00278 }