blob: 5a2d6623c1d73c7964d39990ef2307ebaa07b3c2 [file] [log] [blame]
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2011 UCLA
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
21#include "ndn-l3-aggregate-tracer.h"
22
23#include "ns3/node.h"
24#include "ns3/packet.h"
25#include "ns3/config.h"
26#include "ns3/callback.h"
27#include "ns3/ndn-app.h"
28#include "ns3/ndn-face.h"
29#include "ns3/ndn-interest.h"
Alexander Afanasyev6eba36f2013-08-07 17:42:54 -070030#include "ns3/ndn-data.h"
Alexander Afanasyev37b84c52013-04-26 13:38:52 -070031#include "ns3/ndn-pit-entry.h"
32
Alexander Afanasyev59314802012-11-26 14:56:04 -080033#include "ns3/simulator.h"
34#include "ns3/node-list.h"
35#include "ns3/log.h"
36
37#include <fstream>
38
39NS_LOG_COMPONENT_DEFINE ("ndn.L3AggregateTracer");
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -080040
41namespace ns3 {
42namespace ndn {
43
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070044static std::list< boost::tuple< boost::shared_ptr<std::ostream>, std::list<Ptr<L3AggregateTracer> > > > g_tracers;
45
Alexander Afanasyev5352af32013-07-15 09:51:28 -070046template<class T>
47static inline void
48NullDeleter (T *ptr)
49{
50}
51
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070052void
Alexander Afanasyevdb5f3b62013-08-09 17:42:12 -070053L3AggregateTracer::Destroy ()
54{
55 g_tracers.clear ();
56}
57
58void
Alexander Afanasyev59314802012-11-26 14:56:04 -080059L3AggregateTracer::InstallAll (const std::string &file, Time averagingPeriod/* = Seconds (0.5)*/)
60{
61 using namespace boost;
62 using namespace std;
Alexander Afanasyev37b84c52013-04-26 13:38:52 -070063
Alexander Afanasyev59314802012-11-26 14:56:04 -080064 std::list<Ptr<L3AggregateTracer> > tracers;
Alexander Afanasyev5352af32013-07-15 09:51:28 -070065 boost::shared_ptr<std::ostream> outputStream;
66 if (file != "-")
67 {
68 boost::shared_ptr<std::ofstream> os (new std::ofstream ());
69 os->open (file.c_str (), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyev59314802012-11-26 14:56:04 -080070
Alexander Afanasyev5352af32013-07-15 09:51:28 -070071 if (!os->is_open ())
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070072 {
73 NS_LOG_ERROR ("File " << file << " cannot be opened for writing. Tracing disabled");
74 return;
75 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -070076
77 outputStream = os;
78 }
79 else
80 {
81 outputStream = boost::shared_ptr<std::ostream> (&std::cout, NullDeleter<std::ostream>);
82 }
Alexander Afanasyev59314802012-11-26 14:56:04 -080083
84 for (NodeList::Iterator node = NodeList::Begin ();
85 node != NodeList::End ();
86 node++)
87 {
Alexander Afanasyeva68783a2013-06-27 13:39:04 -070088 Ptr<L3AggregateTracer> trace = Install (*node, outputStream, averagingPeriod);
Alexander Afanasyev59314802012-11-26 14:56:04 -080089 tracers.push_back (trace);
90 }
91
92 if (tracers.size () > 0)
93 {
94 // *m_l3RateTrace << "# "; // not necessary for R's read.table
95 tracers.front ()->PrintHeader (*outputStream);
96 *outputStream << "\n";
97 }
98
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070099 g_tracers.push_back (boost::make_tuple (outputStream, tracers));
Alexander Afanasyev59314802012-11-26 14:56:04 -0800100}
101
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -0700102void
Alexander Afanasyeva68783a2013-06-27 13:39:04 -0700103L3AggregateTracer::Install (const NodeContainer &nodes, const std::string &file, Time averagingPeriod/* = Seconds (0.5)*/)
104{
105 using namespace boost;
106 using namespace std;
Alexander Afanasyev59314802012-11-26 14:56:04 -0800107
Alexander Afanasyeva68783a2013-06-27 13:39:04 -0700108 std::list<Ptr<L3AggregateTracer> > tracers;
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700109 boost::shared_ptr<std::ostream> outputStream;
110 if (file != "-")
111 {
112 boost::shared_ptr<std::ofstream> os (new std::ofstream ());
113 os->open (file.c_str (), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyeva68783a2013-06-27 13:39:04 -0700114
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700115 if (!os->is_open ())
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -0700116 {
117 NS_LOG_ERROR ("File " << file << " cannot be opened for writing. Tracing disabled");
118 return;
119 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700120
121 outputStream = os;
122 }
123 else
124 {
125 outputStream = boost::shared_ptr<std::ostream> (&std::cout, NullDeleter<std::ostream>);
126 }
Alexander Afanasyeva68783a2013-06-27 13:39:04 -0700127
128 for (NodeContainer::Iterator node = nodes.Begin ();
129 node != nodes.End ();
130 node++)
131 {
132 Ptr<L3AggregateTracer> trace = Install (*node, outputStream, averagingPeriod);
133 tracers.push_back (trace);
134 }
135
136 if (tracers.size () > 0)
137 {
138 // *m_l3RateTrace << "# "; // not necessary for R's read.table
139 tracers.front ()->PrintHeader (*outputStream);
140 *outputStream << "\n";
141 }
142
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -0700143 g_tracers.push_back (boost::make_tuple (outputStream, tracers));
Alexander Afanasyeva68783a2013-06-27 13:39:04 -0700144}
145
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -0700146void
Alexander Afanasyeva68783a2013-06-27 13:39:04 -0700147L3AggregateTracer::Install (Ptr<Node> node, const std::string &file, Time averagingPeriod/* = Seconds (0.5)*/)
148{
149 using namespace boost;
150 using namespace std;
151
152 std::list<Ptr<L3AggregateTracer> > tracers;
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700153 boost::shared_ptr<std::ostream> outputStream;
154 if (file != "-")
155 {
156 boost::shared_ptr<std::ofstream> os (new std::ofstream ());
157 os->open (file.c_str (), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyeva68783a2013-06-27 13:39:04 -0700158
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700159 if (!os->is_open ())
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -0700160 {
161 NS_LOG_ERROR ("File " << file << " cannot be opened for writing. Tracing disabled");
162 return;
163 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700164
165 outputStream = os;
166 }
167 else
168 {
169 outputStream = boost::shared_ptr<std::ostream> (&std::cout, NullDeleter<std::ostream>);
170 }
Alexander Afanasyeva68783a2013-06-27 13:39:04 -0700171
172 Ptr<L3AggregateTracer> trace = Install (node, outputStream, averagingPeriod);
173 tracers.push_back (trace);
174
175 if (tracers.size () > 0)
176 {
177 // *m_l3RateTrace << "# "; // not necessary for R's read.table
178 tracers.front ()->PrintHeader (*outputStream);
179 *outputStream << "\n";
180 }
181
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -0700182 g_tracers.push_back (boost::make_tuple (outputStream, tracers));
Alexander Afanasyeva68783a2013-06-27 13:39:04 -0700183}
184
185
186Ptr<L3AggregateTracer>
187L3AggregateTracer::Install (Ptr<Node> node,
188 boost::shared_ptr<std::ostream> outputStream,
189 Time averagingPeriod/* = Seconds (0.5)*/)
190{
191 NS_LOG_DEBUG ("Node: " << node->GetId ());
192
193 Ptr<L3AggregateTracer> trace = Create<L3AggregateTracer> (outputStream, node);
194 trace->SetAveragingPeriod (averagingPeriod);
195
196 return trace;
197}
Alexander Afanasyev59314802012-11-26 14:56:04 -0800198
199L3AggregateTracer::L3AggregateTracer (boost::shared_ptr<std::ostream> os, Ptr<Node> node)
200 : L3Tracer (node)
201 , m_os (os)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800202{
203 Reset ();
204}
205
Alexander Afanasyev59314802012-11-26 14:56:04 -0800206L3AggregateTracer::L3AggregateTracer (boost::shared_ptr<std::ostream> os, const std::string &node)
207 : L3Tracer (node)
208 , m_os (os)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800209{
210 Reset ();
211}
212
213L3AggregateTracer::~L3AggregateTracer ()
214{
215};
216
217void
Alexander Afanasyev59314802012-11-26 14:56:04 -0800218L3AggregateTracer::SetAveragingPeriod (const Time &period)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800219{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800220 m_period = period;
221 m_printEvent.Cancel ();
222 m_printEvent = Simulator::Schedule (m_period, &L3AggregateTracer::PeriodicPrinter, this);
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800223}
224
Alexander Afanasyev59314802012-11-26 14:56:04 -0800225void
226L3AggregateTracer::PeriodicPrinter ()
227{
228 Print (*m_os);
229 Reset ();
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700230
Alexander Afanasyev59314802012-11-26 14:56:04 -0800231 m_printEvent = Simulator::Schedule (m_period, &L3AggregateTracer::PeriodicPrinter, this);
232}
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800233
234void
235L3AggregateTracer::PrintHeader (std::ostream &os) const
236{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800237 os << "Time" << "\t"
238
239 << "Node" << "\t"
240 << "FaceId" << "\t"
241 << "FaceDescr" << "\t"
242
243 << "Type" << "\t"
244 << "Packets" << "\t"
245 << "Kilobytes";
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800246}
247
248void
Alexander Afanasyev59314802012-11-26 14:56:04 -0800249L3AggregateTracer::Reset ()
250{
251 for (std::map<Ptr<const Face>, boost::tuple<Stats, Stats> >::iterator stats = m_stats.begin ();
252 stats != m_stats.end ();
253 stats++)
254 {
255 stats->second.get<0> ().Reset ();
256 stats->second.get<1> ().Reset ();
257 }
258}
259
260
261#define STATS(INDEX) stats->second.get<INDEX> ()
262
263#define PRINTER(printName, fieldName) \
264 os << time.ToDouble (Time::S) << "\t" \
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700265 << m_node << "\t"; \
266 if (stats->first) \
267 { \
268 os \
269 << stats->first->GetId () << "\t" \
270 << *stats->first << "\t"; \
271 } \
272 else \
273 { \
274 os << "-1\tall\t"; \
275 } \
276 os \
Alexander Afanasyev59314802012-11-26 14:56:04 -0800277 << printName << "\t" \
278 << STATS(0).fieldName << "\t" \
279 << STATS(1).fieldName / 1024.0 << "\n";
280
281
282void
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800283L3AggregateTracer::Print (std::ostream &os) const
284{
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700285 Time time = Simulator::Now ();
286
Alexander Afanasyev59314802012-11-26 14:56:04 -0800287 for (std::map<Ptr<const Face>, boost::tuple<Stats, Stats> >::iterator stats = m_stats.begin ();
288 stats != m_stats.end ();
289 stats++)
290 {
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700291 if (!stats->first)
292 continue;
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800293
Alexander Afanasyev59314802012-11-26 14:56:04 -0800294 PRINTER ("InInterests", m_inInterests);
295 PRINTER ("OutInterests", m_outInterests);
Alexander Afanasyevf1a4f1e2013-03-18 08:37:49 -0600296 PRINTER ("DropInterests", m_dropInterests);
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700297
Alexander Afanasyev59314802012-11-26 14:56:04 -0800298 PRINTER ("InNacks", m_inNacks);
299 PRINTER ("OutNacks", m_outNacks);
Alexander Afanasyevf1a4f1e2013-03-18 08:37:49 -0600300 PRINTER ("DropNacks", m_dropNacks);
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800301
Alexander Afanasyev59314802012-11-26 14:56:04 -0800302 PRINTER ("InData", m_inData);
303 PRINTER ("OutData", m_outData);
Alexander Afanasyevf1a4f1e2013-03-18 08:37:49 -0600304 PRINTER ("DropData", m_dropData);
Alexander Afanasyev59314802012-11-26 14:56:04 -0800305 }
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700306
307 {
308 std::map<Ptr<const Face>, boost::tuple<Stats, Stats> >::iterator stats = m_stats.find (Ptr<const Face> (0));
Alexander Afanasyev6692e0b2013-05-06 10:38:50 -0700309 if (stats != m_stats.end ())
310 {
311 PRINTER ("SatisfiedInterests", m_satisfiedInterests);
312 PRINTER ("TimedOutInterests", m_timedOutInterests);
313 }
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700314 }
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800315}
316
317void
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700318L3AggregateTracer::OutInterests (Ptr<const Interest> interest, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800319{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800320 m_stats[face].get<0> ().m_outInterests ++;
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700321 if (interest->GetWire ())
322 {
323 m_stats[face].get<1> ().m_outInterests += interest->GetWire ()->GetSize ();
324 }
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800325}
326
327void
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700328L3AggregateTracer::InInterests (Ptr<const Interest> interest, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800329{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800330 m_stats[face].get<0> ().m_inInterests ++;
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700331 if (interest->GetWire ())
332 {
333 m_stats[face].get<1> ().m_inInterests += interest->GetWire ()->GetSize ();
334 }
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800335}
336
337void
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700338L3AggregateTracer::DropInterests (Ptr<const Interest> interest, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800339{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800340 m_stats[face].get<0> ().m_dropInterests ++;
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700341 if (interest->GetWire ())
342 {
343 m_stats[face].get<1> ().m_dropInterests += interest->GetWire ()->GetSize ();
344 }
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800345}
346
347void
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700348L3AggregateTracer::OutNacks (Ptr<const Interest> nack, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800349{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800350 m_stats[face].get<0> ().m_outNacks ++;
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700351 if (nack->GetWire ())
352 {
353 m_stats[face].get<1> ().m_outNacks += nack->GetWire ()->GetSize ();
354 }
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800355}
356
357void
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700358L3AggregateTracer::InNacks (Ptr<const Interest> nack, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800359{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800360 m_stats[face].get<0> ().m_inNacks ++;
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700361 if (nack->GetWire ())
362 {
363 m_stats[face].get<1> ().m_inNacks += nack->GetWire ()->GetSize ();
364 }
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800365}
366
367void
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700368L3AggregateTracer::DropNacks (Ptr<const Interest> nack, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800369{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800370 m_stats[face].get<0> ().m_dropNacks ++;
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700371 if (nack->GetWire ())
372 {
373 m_stats[face].get<1> ().m_dropNacks += nack->GetWire ()->GetSize ();
374 }
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800375}
376
377void
Alexander Afanasyev772f51b2013-08-01 18:53:25 -0700378L3AggregateTracer::OutData (Ptr<const Data> data,
Alexander Afanasyev59314802012-11-26 14:56:04 -0800379 bool fromCache, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800380{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800381 m_stats[face].get<0> ().m_outData ++;
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700382 if (data->GetWire ())
383 {
384 m_stats[face].get<1> ().m_outData += data->GetWire ()->GetSize ();
385 }
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800386}
387
388void
Alexander Afanasyev772f51b2013-08-01 18:53:25 -0700389L3AggregateTracer::InData (Ptr<const Data> data,
Alexander Afanasyev59314802012-11-26 14:56:04 -0800390 Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800391{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800392 m_stats[face].get<0> ().m_inData ++;
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700393 if (data->GetWire ())
394 {
395 m_stats[face].get<1> ().m_inData += data->GetWire ()->GetSize ();
396 }
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800397}
398
399void
Alexander Afanasyev772f51b2013-08-01 18:53:25 -0700400L3AggregateTracer::DropData (Ptr<const Data> data,
Alexander Afanasyev59314802012-11-26 14:56:04 -0800401 Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800402{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800403 m_stats[face].get<0> ().m_dropData ++;
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700404 if (data->GetWire ())
405 {
406 m_stats[face].get<1> ().m_dropData += data->GetWire ()->GetSize ();
407 }
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800408}
409
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700410void
411L3AggregateTracer::SatisfiedInterests (Ptr<const pit::Entry>)
412{
413 m_stats[0].get<0> ().m_satisfiedInterests ++;
414 // no "size" stats
415}
416
417void
418L3AggregateTracer::TimedOutInterests (Ptr<const pit::Entry>)
419{
420 m_stats[0].get<0> ().m_timedOutInterests ++;
421 // no "size" stats
422}
423
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800424} // namespace ndn
425} // namespace ns3