blob: e58a0055332945f8cf1c5bdcef0847d27037b983 [file] [log] [blame]
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
Alexander Afanasyev86287992012-12-10 16:11:50 -08004 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08005 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
Alexander Afanasyev86287992012-12-10 16:11:50 -08007 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08008 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Alexander Afanasyev86287992012-12-10 16:11:50 -080011 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080012 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyev86287992012-12-10 16:11:50 -080015 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080016 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
Alexander Afanasyev86287992012-12-10 16:11:50 -080019
Alexander Afanasyev0c395372014-12-20 15:54:02 -080020#include "ndn-cs-tracer.hpp"
Alexander Afanasyev86287992012-12-10 16:11:50 -080021#include "ns3/node.h"
22#include "ns3/packet.h"
23#include "ns3/config.h"
24#include "ns3/names.h"
25#include "ns3/callback.h"
26
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080027#include "apps/ndn-app.hpp"
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -080028#include "ns3/simulator.h"
29#include "ns3/node-list.h"
30#include "ns3/log.h"
31
32#include <boost/lexical_cast.hpp>
33
34#include <fstream>
35
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080036NS_LOG_COMPONENT_DEFINE("ndn.CsTracer");
Alexander Afanasyev86287992012-12-10 16:11:50 -080037
Alexander Afanasyev86287992012-12-10 16:11:50 -080038namespace ns3 {
39namespace ndn {
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -080040
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080041static std::list<std::tuple<shared_ptr<std::ostream>, std::list<Ptr<CsTracer>>>> g_tracers;
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -080042
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070043void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080044CsTracer::Destroy()
Alexander Afanasyevdb5f3b62013-08-09 17:42:12 -070045{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080046 g_tracers.clear();
Alexander Afanasyevdb5f3b62013-08-09 17:42:12 -070047}
48
49void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080050CsTracer::InstallAll(const std::string& file, Time averagingPeriod /* = Seconds (0.5)*/)
Alexander Afanasyev5352af32013-07-15 09:51:28 -070051{
52 using namespace boost;
53 using namespace std;
54
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080055 std::list<Ptr<CsTracer>> tracers;
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080056 shared_ptr<std::ostream> outputStream;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080057 if (file != "-") {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080058 shared_ptr<std::ofstream> os(new std::ofstream());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080059 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyev5352af32013-07-15 09:51:28 -070060
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080061 if (!os->is_open()) {
62 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
63 return;
Alexander Afanasyev5352af32013-07-15 09:51:28 -070064 }
65
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080066 outputStream = os;
67 }
68 else {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080069 outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080070 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -070071
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080072 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
73 Ptr<CsTracer> trace = Install(*node, outputStream, averagingPeriod);
74 tracers.push_back(trace);
75 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -070076
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080077 if (tracers.size() > 0) {
78 // *m_l3RateTrace << "# "; // not necessary for R's read.table
79 tracers.front()->PrintHeader(*outputStream);
80 *outputStream << "\n";
81 }
82
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080083 g_tracers.push_back(std::make_tuple(outputStream, tracers));
Alexander Afanasyev5352af32013-07-15 09:51:28 -070084}
85
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070086void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080087CsTracer::Install(const NodeContainer& nodes, const std::string& file,
88 Time averagingPeriod /* = Seconds (0.5)*/)
Alexander Afanasyev5352af32013-07-15 09:51:28 -070089{
90 using namespace boost;
91 using namespace std;
92
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080093 std::list<Ptr<CsTracer>> tracers;
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080094 shared_ptr<std::ostream> outputStream;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080095 if (file != "-") {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080096 shared_ptr<std::ofstream> os(new std::ofstream());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080097 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyev5352af32013-07-15 09:51:28 -070098
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080099 if (!os->is_open()) {
100 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
101 return;
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700102 }
103
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800104 outputStream = os;
105 }
106 else {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800107 outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800108 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700109
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800110 for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
111 Ptr<CsTracer> trace = Install(*node, outputStream, averagingPeriod);
112 tracers.push_back(trace);
113 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700114
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800115 if (tracers.size() > 0) {
116 // *m_l3RateTrace << "# "; // not necessary for R's read.table
117 tracers.front()->PrintHeader(*outputStream);
118 *outputStream << "\n";
119 }
120
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800121 g_tracers.push_back(std::make_tuple(outputStream, tracers));
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700122}
123
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800124void
125CsTracer::Install(Ptr<Node> node, const std::string& file,
126 Time averagingPeriod /* = Seconds (0.5)*/)
127{
128 using namespace boost;
129 using namespace std;
130
131 std::list<Ptr<CsTracer>> tracers;
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800132 shared_ptr<std::ostream> outputStream;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800133 if (file != "-") {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800134 shared_ptr<std::ofstream> os(new std::ofstream());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800135 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
136
137 if (!os->is_open()) {
138 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
139 return;
140 }
141
142 outputStream = os;
143 }
144 else {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800145 outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800146 }
147
148 Ptr<CsTracer> trace = Install(node, outputStream, averagingPeriod);
149 tracers.push_back(trace);
150
151 if (tracers.size() > 0) {
152 // *m_l3RateTrace << "# "; // not necessary for R's read.table
153 tracers.front()->PrintHeader(*outputStream);
154 *outputStream << "\n";
155 }
156
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800157 g_tracers.push_back(std::make_tuple(outputStream, tracers));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800158}
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700159
160Ptr<CsTracer>
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800161CsTracer::Install(Ptr<Node> node, shared_ptr<std::ostream> outputStream,
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800162 Time averagingPeriod /* = Seconds (0.5)*/)
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700163{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800164 NS_LOG_DEBUG("Node: " << node->GetId());
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700165
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800166 Ptr<CsTracer> trace = Create<CsTracer>(outputStream, node);
167 trace->SetAveragingPeriod(averagingPeriod);
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700168
169 return trace;
170}
171
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800172//////////////////////////////////////////////////////////////////////////////
173//////////////////////////////////////////////////////////////////////////////
174//////////////////////////////////////////////////////////////////////////////
175
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800176CsTracer::CsTracer(shared_ptr<std::ostream> os, Ptr<Node> node)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800177 : m_nodePtr(node)
178 , m_os(os)
Alexander Afanasyev86287992012-12-10 16:11:50 -0800179{
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800180 m_node = boost::lexical_cast<std::string>(m_nodePtr->GetId());
Alexander Afanasyev86287992012-12-10 16:11:50 -0800181
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800182 Connect();
Alexander Afanasyev86287992012-12-10 16:11:50 -0800183
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800184 std::string name = Names::FindName(node);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800185 if (!name.empty()) {
186 m_node = name;
187 }
Alexander Afanasyev86287992012-12-10 16:11:50 -0800188}
189
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800190CsTracer::CsTracer(shared_ptr<std::ostream> os, const std::string& node)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800191 : m_node(node)
192 , m_os(os)
Alexander Afanasyev86287992012-12-10 16:11:50 -0800193{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800194 Connect();
Alexander Afanasyev86287992012-12-10 16:11:50 -0800195}
196
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800197CsTracer::~CsTracer(){};
Alexander Afanasyev86287992012-12-10 16:11:50 -0800198
199void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800200CsTracer::Connect()
Alexander Afanasyev86287992012-12-10 16:11:50 -0800201{
Alexander Afanasyev8fbcc642019-07-27 16:53:37 -0400202 // // @TODO Do the same with NFD content store...
203 // Ptr<ContentStore> cs = m_nodePtr->GetObject<ContentStore>();
204 // cs->TraceConnectWithoutContext("CacheHits", MakeCallback(&CsTracer::CacheHits, this));
205 // cs->TraceConnectWithoutContext("CacheMisses", MakeCallback(&CsTracer::CacheMisses, this));
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800206
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800207 Reset();
Alexander Afanasyev86287992012-12-10 16:11:50 -0800208}
209
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800210void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800211CsTracer::SetAveragingPeriod(const Time& period)
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800212{
213 m_period = period;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800214 m_printEvent.Cancel();
215 m_printEvent = Simulator::Schedule(m_period, &CsTracer::PeriodicPrinter, this);
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800216}
217
218void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800219CsTracer::PeriodicPrinter()
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800220{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800221 Print(*m_os);
222 Reset();
223
224 m_printEvent = Simulator::Schedule(m_period, &CsTracer::PeriodicPrinter, this);
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800225}
226
227void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800228CsTracer::PrintHeader(std::ostream& os) const
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800229{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800230 os << "Time"
231 << "\t"
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800232
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800233 << "Node"
234 << "\t"
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800235
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800236 << "Type"
237 << "\t"
238 << "Packets"
239 << "\t";
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800240}
241
242void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800243CsTracer::Reset()
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800244{
245 m_stats.Reset();
246}
247
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800248#define PRINTER(printName, fieldName) \
249 os << time.ToDouble(Time::S) << "\t" << m_node << "\t" << printName << "\t" << m_stats.fieldName \
250 << "\n";
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800251
252void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800253CsTracer::Print(std::ostream& os) const
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800254{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800255 Time time = Simulator::Now();
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800256
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800257 PRINTER("CacheHits", m_cacheHits);
258 PRINTER("CacheMisses", m_cacheMisses);
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800259}
260
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800261void
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700262CsTracer::CacheHits(shared_ptr<const Interest>, shared_ptr<const Data>)
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800263{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800264 m_stats.m_cacheHits++;
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800265}
266
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800267void
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700268CsTracer::CacheMisses(shared_ptr<const Interest>)
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800269{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800270 m_stats.m_cacheMisses++;
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800271}
272
Alexander Afanasyev86287992012-12-10 16:11:50 -0800273} // namespace ndn
274} // namespace ns3