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-cs-tracer.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
20 #include "ndn-cs-tracer.hpp"
21 #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 
27 #include "apps/ndn-app.hpp"
29 #include "ns3/simulator.h"
30 #include "ns3/node-list.h"
31 #include "ns3/log.h"
32 
33 #include <boost/lexical_cast.hpp>
34 
35 #include <fstream>
36 
37 NS_LOG_COMPONENT_DEFINE("ndn.CsTracer");
38 
39 namespace ns3 {
40 namespace ndn {
41 
42 static std::list<std::tuple<shared_ptr<std::ostream>, std::list<Ptr<CsTracer>>>> g_tracers;
43 
44 void
46 {
47  g_tracers.clear();
48 }
49 
50 void
51 CsTracer::InstallAll(const std::string& file, Time averagingPeriod /* = Seconds (0.5)*/)
52 {
53  using namespace boost;
54  using namespace std;
55 
56  std::list<Ptr<CsTracer>> tracers;
57  shared_ptr<std::ostream> outputStream;
58  if (file != "-") {
59  shared_ptr<std::ofstream> os(new std::ofstream());
60  os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
61 
62  if (!os->is_open()) {
63  NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
64  return;
65  }
66 
67  outputStream = os;
68  }
69  else {
70  outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
71  }
72 
73  for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
74  Ptr<CsTracer> trace = Install(*node, outputStream, averagingPeriod);
75  tracers.push_back(trace);
76  }
77 
78  if (tracers.size() > 0) {
79  // *m_l3RateTrace << "# "; // not necessary for R's read.table
80  tracers.front()->PrintHeader(*outputStream);
81  *outputStream << "\n";
82  }
83 
84  g_tracers.push_back(std::make_tuple(outputStream, tracers));
85 }
86 
87 void
88 CsTracer::Install(const NodeContainer& nodes, const std::string& file,
89  Time averagingPeriod /* = Seconds (0.5)*/)
90 {
91  using namespace boost;
92  using namespace std;
93 
94  std::list<Ptr<CsTracer>> tracers;
95  shared_ptr<std::ostream> outputStream;
96  if (file != "-") {
97  shared_ptr<std::ofstream> os(new std::ofstream());
98  os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
99 
100  if (!os->is_open()) {
101  NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
102  return;
103  }
104 
105  outputStream = os;
106  }
107  else {
108  outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
109  }
110 
111  for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
112  Ptr<CsTracer> trace = Install(*node, outputStream, averagingPeriod);
113  tracers.push_back(trace);
114  }
115 
116  if (tracers.size() > 0) {
117  // *m_l3RateTrace << "# "; // not necessary for R's read.table
118  tracers.front()->PrintHeader(*outputStream);
119  *outputStream << "\n";
120  }
121 
122  g_tracers.push_back(std::make_tuple(outputStream, tracers));
123 }
124 
125 void
126 CsTracer::Install(Ptr<Node> node, const std::string& file,
127  Time averagingPeriod /* = Seconds (0.5)*/)
128 {
129  using namespace boost;
130  using namespace std;
131 
132  std::list<Ptr<CsTracer>> tracers;
133  shared_ptr<std::ostream> outputStream;
134  if (file != "-") {
135  shared_ptr<std::ofstream> os(new std::ofstream());
136  os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
137 
138  if (!os->is_open()) {
139  NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
140  return;
141  }
142 
143  outputStream = os;
144  }
145  else {
146  outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
147  }
148 
149  Ptr<CsTracer> trace = Install(node, outputStream, averagingPeriod);
150  tracers.push_back(trace);
151 
152  if (tracers.size() > 0) {
153  // *m_l3RateTrace << "# "; // not necessary for R's read.table
154  tracers.front()->PrintHeader(*outputStream);
155  *outputStream << "\n";
156  }
157 
158  g_tracers.push_back(std::make_tuple(outputStream, tracers));
159 }
160 
161 Ptr<CsTracer>
162 CsTracer::Install(Ptr<Node> node, shared_ptr<std::ostream> outputStream,
163  Time averagingPeriod /* = Seconds (0.5)*/)
164 {
165  NS_LOG_DEBUG("Node: " << node->GetId());
166 
167  Ptr<CsTracer> trace = Create<CsTracer>(outputStream, node);
168  trace->SetAveragingPeriod(averagingPeriod);
169 
170  return trace;
171 }
172 
176 
177 CsTracer::CsTracer(shared_ptr<std::ostream> os, Ptr<Node> node)
178  : m_nodePtr(node)
179  , m_os(os)
180 {
181  m_node = boost::lexical_cast<std::string>(m_nodePtr->GetId());
182 
183  Connect();
184 
185  std::string name = Names::FindName(node);
186  if (!name.empty()) {
187  m_node = name;
188  }
189 }
190 
191 CsTracer::CsTracer(shared_ptr<std::ostream> os, const std::string& node)
192  : m_node(node)
193  , m_os(os)
194 {
195  Connect();
196 }
197 
199 
200 void
201 CsTracer::Connect()
202 {
203  Ptr<ContentStore> cs = m_nodePtr->GetObject<ContentStore>();
204  cs->TraceConnectWithoutContext("CacheHits", MakeCallback(&CsTracer::CacheHits, this));
205  cs->TraceConnectWithoutContext("CacheMisses", MakeCallback(&CsTracer::CacheMisses, this));
206 
207  Reset();
208 }
209 
210 void
211 CsTracer::SetAveragingPeriod(const Time& period)
212 {
213  m_period = period;
214  m_printEvent.Cancel();
215  m_printEvent = Simulator::Schedule(m_period, &CsTracer::PeriodicPrinter, this);
216 }
217 
218 void
219 CsTracer::PeriodicPrinter()
220 {
221  Print(*m_os);
222  Reset();
223 
224  m_printEvent = Simulator::Schedule(m_period, &CsTracer::PeriodicPrinter, this);
225 }
226 
227 void
228 CsTracer::PrintHeader(std::ostream& os) const
229 {
230  os << "Time"
231  << "\t"
232 
233  << "Node"
234  << "\t"
235 
236  << "Type"
237  << "\t"
238  << "Packets"
239  << "\t";
240 }
241 
242 void
243 CsTracer::Reset()
244 {
245  m_stats.Reset();
246 }
247 
248 #define PRINTER(printName, fieldName) \
249  os << time.ToDouble(Time::S) << "\t" << m_node << "\t" << printName << "\t" << m_stats.fieldName \
250  << "\n";
251 
252 void
253 CsTracer::Print(std::ostream& os) const
254 {
255  Time time = Simulator::Now();
256 
257  PRINTER("CacheHits", m_cacheHits);
258  PRINTER("CacheMisses", m_cacheMisses);
259 }
260 
261 void
262 CsTracer::CacheHits(shared_ptr<const Interest>, shared_ptr<const Data>)
263 {
264  m_stats.m_cacheHits++;
265 }
266 
267 void
268 CsTracer::CacheMisses(shared_ptr<const Interest>)
269 {
270  m_stats.m_cacheMisses++;
271 }
272 
273 } // namespace ndn
274 } // namespace ns3
static void InstallAll(const std::string &file, Time averagingPeriod=Seconds(0.5))
Helper method to install tracers on all simulation nodes.
void Print(std::ostream &os) const
Print current trace data.
#define PRINTER(printName, fieldName)
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.
static void Destroy()
Explicit request to remove all statically created tracers.
static std::list< std::tuple< shared_ptr< std::ostream >, std::list< Ptr< AppDelayTracer > > > > g_tracers
void PrintHeader(std::ostream &os) const
Print head of the trace (e.g., for post-processing)
CsTracer(shared_ptr< std::ostream > os, Ptr< Node > node)
Trace constructor that attaches to the node using node pointer.
~CsTracer()
Destructor.
Base class for NDN content store.