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