NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ndn-l3-rate-tracer.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
20 #include "ndn-l3-rate-tracer.hpp"
21 #include "ns3/node.h"
22 #include "ns3/packet.h"
23 #include "ns3/config.h"
24 #include "ns3/callback.h"
25 #include "ns3/simulator.h"
26 #include "ns3/log.h"
27 #include "ns3/node-list.h"
28 
30 
31 #include <fstream>
32 #include <boost/lexical_cast.hpp>
33 
34 NS_LOG_COMPONENT_DEFINE("ndn.L3RateTracer");
35 
36 namespace ns3 {
37 namespace ndn {
38 
39 static std::list<std::tuple<shared_ptr<std::ostream>, std::list<Ptr<L3RateTracer>>>>
41 
42 void
44 {
45  g_tracers.clear();
46 }
47 
48 void
49 L3RateTracer::InstallAll(const std::string& file, Time averagingPeriod /* = Seconds (0.5)*/)
50 {
51  std::list<Ptr<L3RateTracer>> tracers;
52  shared_ptr<std::ostream> outputStream;
53  if (file != "-") {
54  shared_ptr<std::ofstream> os(new std::ofstream());
55  os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
56 
57  if (!os->is_open()) {
58  NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
59  return;
60  }
61 
62  outputStream = os;
63  }
64  else {
65  outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
66  }
67 
68  for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
69  Ptr<L3RateTracer> trace = Install(*node, outputStream, averagingPeriod);
70  tracers.push_back(trace);
71  }
72 
73  if (tracers.size() > 0) {
74  // *m_l3RateTrace << "# "; // not necessary for R's read.table
75  tracers.front()->PrintHeader(*outputStream);
76  *outputStream << "\n";
77  }
78 
79  g_tracers.push_back(std::make_tuple(outputStream, tracers));
80 }
81 
82 void
83 L3RateTracer::Install(const NodeContainer& nodes, const std::string& file,
84  Time averagingPeriod /* = Seconds (0.5)*/)
85 {
86  using namespace boost;
87  using namespace std;
88 
89  std::list<Ptr<L3RateTracer>> tracers;
90  shared_ptr<std::ostream> outputStream;
91  if (file != "-") {
92  shared_ptr<std::ofstream> os(new std::ofstream());
93  os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
94 
95  if (!os->is_open()) {
96  NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
97  return;
98  }
99 
100  outputStream = os;
101  }
102  else {
103  outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
104  }
105 
106  for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
107  Ptr<L3RateTracer> trace = Install(*node, outputStream, averagingPeriod);
108  tracers.push_back(trace);
109  }
110 
111  if (tracers.size() > 0) {
112  // *m_l3RateTrace << "# "; // not necessary for R's read.table
113  tracers.front()->PrintHeader(*outputStream);
114  *outputStream << "\n";
115  }
116 
117  g_tracers.push_back(std::make_tuple(outputStream, tracers));
118 }
119 
120 void
121 L3RateTracer::Install(Ptr<Node> node, const std::string& file,
122  Time averagingPeriod /* = Seconds (0.5)*/)
123 {
124  using namespace boost;
125  using namespace std;
126 
127  std::list<Ptr<L3RateTracer>> tracers;
128  shared_ptr<std::ostream> outputStream;
129  if (file != "-") {
130  shared_ptr<std::ofstream> os(new std::ofstream());
131  os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
132 
133  if (!os->is_open()) {
134  NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
135  return;
136  }
137 
138  outputStream = os;
139  }
140  else {
141  outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
142  }
143 
144  Ptr<L3RateTracer> trace = Install(node, outputStream, averagingPeriod);
145  tracers.push_back(trace);
146 
147  if (tracers.size() > 0) {
148  // *m_l3RateTrace << "# "; // not necessary for R's read.table
149  tracers.front()->PrintHeader(*outputStream);
150  *outputStream << "\n";
151  }
152 
153  g_tracers.push_back(std::make_tuple(outputStream, tracers));
154 }
155 
156 Ptr<L3RateTracer>
157 L3RateTracer::Install(Ptr<Node> node, shared_ptr<std::ostream> outputStream,
158  Time averagingPeriod /* = Seconds (0.5)*/)
159 {
160  NS_LOG_DEBUG("Node: " << node->GetId());
161 
162  Ptr<L3RateTracer> trace = Create<L3RateTracer>(outputStream, node);
163  trace->SetAveragingPeriod(averagingPeriod);
164 
165  return trace;
166 }
167 
168 L3RateTracer::L3RateTracer(shared_ptr<std::ostream> os, Ptr<Node> node)
169  : L3Tracer(node)
170  , m_os(os)
171 {
172  SetAveragingPeriod(Seconds(1.0));
173 }
174 
175 L3RateTracer::L3RateTracer(shared_ptr<std::ostream> os, const std::string& node)
176  : L3Tracer(node)
177  , m_os(os)
178 {
179  SetAveragingPeriod(Seconds(1.0));
180 }
181 
183 {
184  m_printEvent.Cancel();
185 }
186 
187 void
188 L3RateTracer::SetAveragingPeriod(const Time& period)
189 {
190  m_period = period;
191  m_printEvent.Cancel();
192  m_printEvent = Simulator::Schedule(m_period, &L3RateTracer::PeriodicPrinter, this);
193 }
194 
195 void
196 L3RateTracer::PeriodicPrinter()
197 {
198  Print(*m_os);
199  Reset();
200 
201  m_printEvent = Simulator::Schedule(m_period, &L3RateTracer::PeriodicPrinter, this);
202 }
203 
204 void
205 L3RateTracer::PrintHeader(std::ostream& os) const
206 {
207  os << "Time"
208  << "\t"
209 
210  << "Node"
211  << "\t"
212  << "FaceId"
213  << "\t"
214  << "FaceDescr"
215  << "\t"
216 
217  << "Type"
218  << "\t"
219  << "Packets"
220  << "\t"
221  << "Kilobytes"
222  << "\t"
223  << "PacketRaw"
224  << "\t"
225  << "KilobytesRaw";
226 }
227 
228 void
229 L3RateTracer::Reset()
230 {
231  for (auto& stats : m_stats) {
232  std::get<0>(stats.second).Reset();
233  std::get<1>(stats.second).Reset();
234  }
235 }
236 
237 const double alpha = 0.8;
238 
239 #define STATS(INDEX) std::get<INDEX>(stats.second)
240 #define RATE(INDEX, fieldName) STATS(INDEX).fieldName / m_period.ToDouble(Time::S)
241 
242 #define PRINTER(printName, fieldName) \
243  STATS(2).fieldName = \
244  /*new value*/ alpha * RATE(0, fieldName) + /*old value*/ (1 - alpha) * STATS(2).fieldName; \
245  STATS(3).fieldName = /*new value*/ alpha * RATE(1, fieldName) / 1024.0 \
246  + /*old value*/ (1 - alpha) * STATS(3).fieldName; \
247  \
248  os << time.ToDouble(Time::S) << "\t" << m_node << "\t"; \
249  if (stats.first != nullptr) { \
250  os << stats.first->getId() << "\t" << stats.first->getLocalUri() << "\t"; \
251  } \
252  else { \
253  os << "-1\tall\t"; \
254  } \
255  os << printName << "\t" << STATS(2).fieldName << "\t" << STATS(3).fieldName << "\t" \
256  << STATS(0).fieldName << "\t" << STATS(1).fieldName / 1024.0 << "\n";
257 
258 void
259 L3RateTracer::Print(std::ostream& os) const
260 {
261  Time time = Simulator::Now();
262 
263  for (auto& stats : m_stats) {
264  if (stats.first == nullptr)
265  continue;
266 
267  PRINTER("InInterests", m_inInterests);
268  PRINTER("OutInterests", m_outInterests);
269 
270  PRINTER("InData", m_inData);
271  PRINTER("OutData", m_outData);
272 
273  PRINTER("InSatisfiedInterests", m_satisfiedInterests);
274  PRINTER("InTimedOutInterests", m_timedOutInterests);
275 
276  PRINTER("OutSatisfiedInterests", m_outSatisfiedInterests);
277  PRINTER("OutTimedOutInterests", m_outTimedOutInterests);
278  }
279 
280  {
281  auto i = m_stats.find(nullptr);
282  if (i != m_stats.end()) {
283  auto& stats = *i;
284  PRINTER("SatisfiedInterests", m_satisfiedInterests);
285  PRINTER("TimedOutInterests", m_timedOutInterests);
286  }
287  }
288 }
289 
290 void
291 L3RateTracer::OutInterests(const Interest& interest, const Face& face)
292 {
293  std::get<0>(m_stats[face.shared_from_this()]).m_outInterests++;
294  if (interest.hasWire()) {
295  std::get<1>(m_stats[face.shared_from_this()]).m_outInterests +=
296  interest.wireEncode().size();
297  }
298 }
299 
300 void
301 L3RateTracer::InInterests(const Interest& interest, const Face& face)
302 {
303  std::get<0>(m_stats[face.shared_from_this()]).m_inInterests++;
304  if (interest.hasWire()) {
305  std::get<1>(m_stats[face.shared_from_this()]).m_inInterests +=
306  interest.wireEncode().size();
307  }
308 }
309 
310 void
311 L3RateTracer::OutData(const Data& data, const Face& face)
312 {
313  std::get<0>(m_stats[face.shared_from_this()]).m_outData++;
314  if (data.hasWire()) {
315  std::get<1>(m_stats[face.shared_from_this()]).m_outData +=
316  data.wireEncode().size();
317  }
318 }
319 
320 void
321 L3RateTracer::InData(const Data& data, const Face& face)
322 {
323  std::get<0>(m_stats[face.shared_from_this()]).m_inData++;
324  if (data.hasWire()) {
325  std::get<1>(m_stats[face.shared_from_this()]).m_inData +=
326  data.wireEncode().size();
327  }
328 }
329 
330 void
332 {
333  std::get<0>(m_stats[nullptr]).m_satisfiedInterests++;
334  // no "size" stats
335 
336  for (const auto& in : entry.getInRecords()) {
337  std::get<0>(m_stats[in.getFace()]).m_satisfiedInterests ++;
338  }
339 
340  for (const auto& out : entry.getOutRecords()) {
341  std::get<0>(m_stats[out.getFace()]).m_outSatisfiedInterests ++;
342  }
343 }
344 
345 void
347 {
348  std::get<0>(m_stats[nullptr]).m_timedOutInterests++;
349  // no "size" stats
350 
351  for (const auto& in : entry.getInRecords()) {
352  std::get<0>(m_stats[in.getFace()]).m_timedOutInterests++;
353  }
354 
355  for (const auto& out : entry.getOutRecords()) {
356  std::get<0>(m_stats[out.getFace()]).m_outTimedOutInterests++;
357  }
358 }
359 
360 } // namespace ndn
361 } // namespace ns3
virtual ~L3RateTracer()
Destructor.
static void Destroy()
Explicit request to remove all statically created tracers.
virtual void Print(std::ostream &os) const
Print current trace data.
virtual void SatisfiedInterests(const nfd::pit::Entry &, const Face &, const Data &)
represents a face
Definition: face.hpp:59
Base class for network-layer (incoming/outgoing Interests and Data) tracing of NDN stack...
represents a PIT entry
Definition: pit-entry.hpp:67
static std::list< std::tuple< shared_ptr< std::ostream >, std::list< Ptr< AppDelayTracer > > > > g_tracers
const double alpha
const InRecordCollection & getInRecords() const
Definition: pit-entry.hpp:191
static void Install(const NodeContainer &nodes, const std::string &file, Time averagingPeriod=Seconds(0.5))
Helper method to install tracers on the selected simulation nodes.
const OutRecordCollection & getOutRecords() const
Definition: pit-entry.hpp:197
virtual void InInterests(const Interest &interest, const Face &face)
virtual void OutData(const Data &data, const Face &face)
virtual void TimedOutInterests(const nfd::pit::Entry &)
#define PRINTER(printName, fieldName)
virtual void PrintHeader(std::ostream &os) const
Print head of the trace (e.g., for post-processing)
L3RateTracer(shared_ptr< std::ostream > os, Ptr< Node > node)
Trace constructor that attaches to the node using node pointer.
static void InstallAll(const std::string &file, Time averagingPeriod=Seconds(0.5))
Helper method to install tracers on all simulation nodes.
virtual void OutInterests(const Interest &interest, const Face &face)
virtual void InData(const Data &data, const Face &face)