21 #include "l2-rate-tracer.h"
23 #include "ns3/packet.h"
24 #include "ns3/config.h"
25 #include "ns3/callback.h"
26 #include "ns3/simulator.h"
27 #include "ns3/node-list.h"
31 #include <boost/lexical_cast.hpp>
34 using namespace boost;
37 NS_LOG_COMPONENT_DEFINE (
"L2RateTracer");
41 static std::list< boost::tuple< boost::shared_ptr<std::ostream>, std::list<Ptr<L2RateTracer> > > > g_tracers;
50 L2RateTracer::Destroy ()
56 L2RateTracer::InstallAll (
const std::string &file, Time averagingPeriod)
58 std::list<Ptr<L2RateTracer> > tracers;
59 boost::shared_ptr<std::ostream> outputStream;
62 boost::shared_ptr<std::ofstream> os (
new std::ofstream ());
63 os->open (file.c_str (), std::ios_base::out | std::ios_base::trunc);
67 NS_LOG_ERROR (
"File " << file <<
" cannot be opened for writing. Tracing disabled");
75 outputStream = boost::shared_ptr<std::ostream> (&std::cout, NullDeleter<std::ostream>);
78 for (NodeList::Iterator node = NodeList::Begin ();
79 node != NodeList::End ();
82 NS_LOG_DEBUG (
"Node: " << lexical_cast<string> ((*node)->GetId ()));
84 Ptr<L2RateTracer> trace = Create<L2RateTracer> (outputStream, *node);
85 trace->SetAveragingPeriod (averagingPeriod);
86 tracers.push_back (trace);
89 if (tracers.size () > 0)
92 tracers.front ()->PrintHeader (*outputStream);
93 *outputStream <<
"\n";
96 g_tracers.push_back (boost::make_tuple (outputStream, tracers));
100 L2RateTracer::L2RateTracer (boost::shared_ptr<std::ostream> os, Ptr<Node> node)
104 SetAveragingPeriod (Seconds (1.0));
107 L2RateTracer::~L2RateTracer ()
109 m_printEvent.Cancel ();
113 L2RateTracer::SetAveragingPeriod (
const Time &period)
116 m_printEvent.Cancel ();
117 m_printEvent = Simulator::Schedule (m_period, &L2RateTracer::PeriodicPrinter,
this);
121 L2RateTracer::PeriodicPrinter ()
126 m_printEvent = Simulator::Schedule (m_period, &L2RateTracer::PeriodicPrinter,
this);
130 L2RateTracer::PrintHeader (std::ostream &os)
const
135 <<
"Interface" <<
"\t"
139 <<
"Kilobytes" <<
"\t"
140 <<
"PacketsRaw" <<
"\t"
145 L2RateTracer::Reset ()
147 m_stats.get<0> ().Reset ();
148 m_stats.get<1> ().Reset ();
151 const double alpha = 0.8;
153 #define STATS(INDEX) m_stats.get<INDEX> ()
154 #define RATE(INDEX, fieldName) STATS(INDEX).fieldName / m_period.ToDouble (Time::S)
156 #define PRINTER(printName, fieldName, interface) \
157 STATS(2).fieldName = alpha * RATE(0, fieldName) + (1-alpha) * STATS(2).fieldName; \
158 STATS(3).fieldName = alpha * RATE(1, fieldName) / 1024.0 + (1-alpha) * STATS(3).fieldName; \
160 os << time.ToDouble (Time::S) << "\t" \
162 << interface << "\t" \
163 << printName << "\t" \
164 << STATS(2).fieldName << "\t" \
165 << STATS(3).fieldName << "\t" \
166 << STATS(0).fieldName << "\t" \
167 << STATS(1).fieldName / 1024.0 << "\n";
170 L2RateTracer::Print (std::ostream &os)
const
172 Time time = Simulator::Now ();
174 PRINTER (
"Drop", m_drop,
"combined");
178 L2RateTracer::Drop (Ptr<const Packet> packet)
182 m_stats.get<0> ().m_drop ++;
183 m_stats.get<1> ().m_drop += packet->GetSize ();