41 class EMANE::Utils::CommonLayerStatistics::Implementation
46 const std::string & sInstance) :
47 sInstance_{sInstance},
49 unicastDropTableLabels_{
"NEM"},
50 broadcastDropTableLabels_{
"NEM"},
51 unicastAcceptTableLabels_{
"NEM",
"Num Pkts Tx",
"Num Bytes Tx",
"Num Pkts Rx",
"Num Bytes Rx"},
52 broadcastAcceptTableLabels_{
"NEM",
"Num Pkts Tx",
"Num Bytes Tx",
"Num Pkts Rx",
"Num Bytes Rx"},
53 pNumUpstreamPacketsUnicastTx_{},
54 pNumUpstreamBytesUnicastTx_{},
55 pNumUpstreamPacketsBroadcastTx_{},
56 pNumUpstreamBytesBroadcastTx_{},
57 pNumUpstreamPacketsUnicastRx_{},
58 pNumUpstreamBytesUnicastRx_{},
59 pNumUpstreamPacketsUnicastDrop_{},
60 pNumUpstreamPacketsBroadcastRx_{},
61 pNumUpstreamBytesBroadcastRx_{},
62 pNumUpstreamPacketsBroadcastDrop_{},
63 pNumDownstreamPacketsUnicastTx_{},
64 pNumDownstreamBytesUnicastTx_{},
65 pNumDownstreamPacketsBroadcastTx_{},
66 pNumDownstreamBytesBroadcastTx_{},
67 pNumDownstreamPacketsUnicastRx_{},
68 pNumDownstreamBytesUnicastRx_{},
69 pNumDownstreamPacketsUnicastDrop_{},
70 pNumDownstreamPacketsBroadcastRx_{},
71 pNumDownstreamBytesBroadcastRx_{},
72 pNumDownstreamPacketsBroadcastDrop_{},
73 pNumDownstreamPacketsUnicastGenerated_{},
74 pNumDownstreamBytesUnicastGenerated_{},
75 pNumDownstreamPacketsBroadcastGenerated_{},
76 pNumDownstreamBytesBroadcastGenerated_{},
77 pStatisticUnicastDropTable_{},
78 pStatisticBroadcastDropTable_{},
79 pStatisticUnicastAcceptTable_{},
80 pStatisticBroadcastAcceptTable_{}
82 if(unicastDropTableLabels.empty())
84 bHaveDropTables_ =
false;
88 bHaveDropTables_ =
true;
90 unicastDropTableLabels_.insert(unicastDropTableLabels_.end(),
91 unicastDropTableLabels.begin(),
92 unicastDropTableLabels.end());
94 if(broadcastDropTableLabels.empty())
96 broadcastDropTableLabels_ = unicastDropTableLabels_;
100 broadcastDropTableLabels_.insert(broadcastDropTableLabels_.end(),
101 broadcastDropTableLabels.begin(),
102 broadcastDropTableLabels.end());
112 avgUpstreamProcessingDelay_.registerStatistic(
113 statisticRegistrar.registerNumeric<Average>(
"avgUpstreamProcessingDelay" + sInstance_,
115 "Average upstream processing delay"));
119 pNumUpstreamPacketsUnicastTx_ =
120 statisticRegistrar.registerNumeric<Counter>(
"numUpstreamPacketsUnicastTx" + sInstance_,
122 "Number of upstream unicast packets transmitted");
124 pNumUpstreamBytesUnicastTx_ =
125 statisticRegistrar.registerNumeric<Counter>(
"numUpstreamBytesUnicastTx" + sInstance_,
127 "Number of upstream unicast bytes transmitted");
131 pNumUpstreamPacketsBroadcastTx_ =
132 statisticRegistrar.registerNumeric<Counter>(
"numUpstreamPacketsBroadcastTx" + sInstance_,
134 "Number of upstream broadcast packets transmitted");
136 pNumUpstreamBytesBroadcastTx_ =
137 statisticRegistrar.registerNumeric<Counter>(
"numUpstreamBytesBroadcastTx" + sInstance_,
139 "Number of updtream broadcast bytes transmitted");
142 pNumUpstreamPacketsUnicastRx_ =
143 statisticRegistrar.registerNumeric<Counter>(
"numUpstreamPacketsUnicastRx" + sInstance_,
145 "Number upstream unicast packets received");
147 pNumUpstreamBytesUnicastRx_ =
148 statisticRegistrar.registerNumeric<Counter>(
"numUpstreamBytesUnicastRx" + sInstance_,
150 "Number upstream unicast bytes received");
152 pNumUpstreamPacketsUnicastDrop_ =
153 statisticRegistrar.registerNumeric<Counter>(
"numUpstreamPacketsUnicastDrop" + sInstance_,
155 "Number of upstream unicast packets dropped");
158 pNumUpstreamPacketsBroadcastRx_ =
159 statisticRegistrar.registerNumeric<Counter>(
"numUpstreamPacketsBroadcastRx" + sInstance_,
161 "Number of upstream broadcast packets received");
163 pNumUpstreamBytesBroadcastRx_ =
164 statisticRegistrar.registerNumeric<Counter>(
"numUpstreamBytesBroadcastRx" + sInstance_,
166 "Number of upstream broadcast bytes received");
168 pNumUpstreamPacketsBroadcastDrop_ =
169 statisticRegistrar.registerNumeric<Counter>(
"numUpstreamPacketsBroadcastDrop" + sInstance_,
171 "Number of upstream broadcast packets dropped");
174 pNumDownstreamPacketsUnicastTx_ =
175 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamPacketsUnicastTx" + sInstance_,
177 "Number of downstream unicast packets transmitted");
179 pNumDownstreamBytesUnicastTx_ =
180 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamBytesUnicastTx" + sInstance_,
182 "Number of downstream unicast bytes transmitted");
185 pNumDownstreamPacketsBroadcastTx_ =
186 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamPacketsBroadcastTx" + sInstance_,
188 "Number of downstream broadcast packets transmitted");
190 pNumDownstreamBytesBroadcastTx_ =
191 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamBytesBroadcastTx" + sInstance_,
193 "Number of downstream broadcast bytes transmitted");
196 pNumDownstreamPacketsUnicastRx_ =
197 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamPacketsUnicastRx" + sInstance_,
199 "Number of downstream unicast packets received");
201 pNumDownstreamBytesUnicastRx_ =
202 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamBytesUnicastRx" + sInstance_,
204 "Number of downstream unicast bytes received");
206 pNumDownstreamPacketsUnicastDrop_ =
207 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamPacketsUnicastDrop" + sInstance_,
209 "Number of downstream unicast packets dropped");
212 pNumDownstreamPacketsBroadcastRx_ =
213 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamPacketsBroadcastRx" + sInstance_,
215 "Number of downstream broadcast packets received");
217 pNumDownstreamBytesBroadcastRx_ =
218 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamBytesBroadcastRx" + sInstance_,
220 "Number of downstream broadcast bytes received");
222 pNumDownstreamPacketsBroadcastDrop_ =
223 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamPacketsBroadcastDrop" + sInstance_,
225 "Number of downstream broadcast packets dropped");
228 avgDownstreamProcessingDelay_.registerStatistic(
229 statisticRegistrar.registerNumeric<Average>(
"avgDownstreamProcessingDelay" + sInstance_,
230 StatisticProperties::CLEARABLE,
231 "Average downstream processing delay"));
235 pNumDownstreamPacketsUnicastGenerated_ =
236 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamPacketsUnicastGenerated" + sInstance_,
238 "Number of layer generated downstream unicast packets");
240 pNumDownstreamBytesUnicastGenerated_ =
241 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamBytesUnicastGenerated" + sInstance_,
243 "Number of layer generated downstream unicast bytes");
246 pNumDownstreamPacketsBroadcastGenerated_ =
247 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamPacketsBroadcastGenerated" + sInstance_,
249 "Number of layer generated downstream broadcast packets");
251 pNumDownstreamBytesBroadcastGenerated_ =
252 statisticRegistrar.registerNumeric<Counter>(
"numDownstreamBytesBroadcastGenerated" + sInstance_,
254 "Number of layer generated downstream broadcast bytes");
259 pStatisticUnicastDropTable_ =
260 statisticRegistrar.registerTable<
NEMId>(
"UnicastPacketDropTable" + sInstance_,
261 unicastDropTableLabels_,
262 [
this](StatisticTablePublisher * pTable)
264 std::lock_guard<std::mutex> m(nemUnicastDropTableMutex_);
265 nemUnicastDropCodeMap_.clear();
268 "Unicast packets dropped by reason code");
270 pStatisticBroadcastDropTable_ =
271 statisticRegistrar.registerTable<
NEMId>(
"BroadcastPacketDropTable" + sInstance_,
272 broadcastDropTableLabels_,
273 [
this](StatisticTablePublisher * pTable)
275 std::lock_guard<std::mutex> m(nemBroadcastDropTableMutex_);
276 nemBroadcastDropCodeMap_.clear();
279 "Broadcast packets dropped by reason code");
282 pStatisticUnicastAcceptTable_ =
283 statisticRegistrar.registerTable<
NEMId>(
"UnicastPacketAcceptTable" + sInstance_,
284 unicastAcceptTableLabels_,
285 [
this](StatisticTablePublisher * pTable)
287 std::lock_guard<std::mutex> m(nemUnicastAcceptTableMutex_);
288 nemUnicastAcceptMap_.clear();
291 "Unicast packets accepted");
293 pStatisticBroadcastAcceptTable_ =
294 statisticRegistrar.registerTable<
NEMId>(
"BroadcastPacketAcceptTable" + sInstance_,
295 broadcastAcceptTableLabels_,
296 [
this](StatisticTablePublisher * pTable)
298 std::lock_guard<std::mutex> m(nemBroadcastAcceptTableMutex_);
299 nemBroadcastAcceptMap_.clear();
302 "Broadcast packets accepted");
310 ++*pNumUpstreamPacketsBroadcastRx_;
312 *pNumUpstreamBytesBroadcastRx_ += pkt.length();
316 ++*pNumUpstreamPacketsUnicastRx_;
318 *pNumUpstreamBytesUnicastRx_ += pkt.length();
328 updateDropTable(pkt.getPacketInfo(), dropCode, isBroadcast(pkt),
true);
332 updateAcceptTable(pkt.getPacketInfo(), pkt.length(), isBroadcast(pkt),
true,
true);
339 ++*pNumUpstreamPacketsBroadcastDrop_;
343 ++*pNumUpstreamPacketsUnicastDrop_;
349 avgUpstreamProcessingDelay_.update(delay.count());
353 ++*pNumUpstreamPacketsBroadcastTx_;
355 *pNumUpstreamBytesBroadcastTx_ += pkt.length();
359 ++*pNumUpstreamPacketsUnicastTx_;
361 *pNumUpstreamBytesUnicastTx_ += pkt.length();
371 ++*pNumDownstreamPacketsBroadcastRx_;
373 *pNumDownstreamBytesBroadcastRx_ += pkt.length();
377 ++*pNumDownstreamPacketsUnicastRx_;
379 *pNumDownstreamBytesUnicastRx_ += pkt.length();
388 updateDropTable(pkt.getPacketInfo(), dropCode, isBroadcast(pkt),
false);
392 updateAcceptTable(pkt.getPacketInfo(), pkt.length(), isBroadcast(pkt),
false,
true);
399 ++*pNumDownstreamPacketsBroadcastDrop_;
403 ++*pNumDownstreamPacketsUnicastDrop_;
409 avgDownstreamProcessingDelay_.update(delay.count());
415 ++*pNumDownstreamPacketsBroadcastGenerated_;
417 pNumDownstreamBytesBroadcastGenerated_ += pkt.length();
421 ++*pNumDownstreamPacketsUnicastGenerated_;
423 pNumDownstreamBytesUnicastGenerated_ += pkt.length();
430 ++*pNumDownstreamPacketsBroadcastTx_;
432 *pNumDownstreamBytesBroadcastTx_ += pkt.length();
436 ++*pNumDownstreamPacketsUnicastTx_;
438 *pNumDownstreamBytesUnicastTx_ += pkt.length();
445 void updateDropTable(
const PacketInfo & packetInfo,
size_t dropCode,
bool bIsBroadcast,
bool bIsUpstream)
449 NEMDropCodeMap * pThisDropCodeMap{};
451 StatisticTable<NEMId> * pThisTable{};
455 std::mutex * pThisMutex{};
461 nemId = packetInfo.getSource();
465 nemId = packetInfo.getDestination();
470 pThisDropCodeMap = &nemBroadcastDropCodeMap_;
472 pThisTable = pStatisticBroadcastDropTable_;
474 pThisMutex = &nemBroadcastDropTableMutex_;
476 numColumns = broadcastDropTableLabels_.size();
480 pThisDropCodeMap = &nemUnicastDropCodeMap_;
482 pThisTable = pStatisticUnicastDropTable_;
484 pThisMutex = &nemUnicastDropTableMutex_;
486 numColumns = unicastDropTableLabels_.size();
490 std::lock_guard<std::mutex> m(*pThisMutex);
492 auto iter = pThisDropCodeMap->find(nemId);
494 if(iter == pThisDropCodeMap->end())
497 std::vector<Any> v{
Any{nemId}};
500 v.insert(v.end(), numColumns - 1,
Any{Counter{}});
502 pThisTable->addRow(nemId, v);
505 pThisDropCodeMap->insert(std::make_pair(nemId,
506 Counters(numColumns - 1, Counter{}))).first;
509 if(dropCode > iter->second.size())
513 else if(dropCode != 0)
516 ++(iter->second[dropCode - 1]);
519 pThisTable->setCell(nemId, dropCode,
Any{iter->second[dropCode - 1]});
524 void updateAcceptTable(
const PacketInfo & packetInfo,
530 NEMAcceptMap * pThisAcceptMap{};
532 StatisticTable<NEMId> * pThisTable{};
536 std::mutex * pThisMutex{};
542 pThisAcceptMap = &nemBroadcastAcceptMap_;
544 pThisTable = pStatisticBroadcastAcceptTable_;
546 pThisMutex = &nemBroadcastAcceptTableMutex_;
548 numColumns = broadcastAcceptTableLabels_.size();
550 nemId = packetInfo.getSource();
554 pThisAcceptMap = &nemUnicastAcceptMap_;
556 pThisTable = pStatisticUnicastAcceptTable_;
558 pThisMutex = &nemUnicastAcceptTableMutex_;
560 numColumns = unicastAcceptTableLabels_.size();
562 nemId = packetInfo.getSource();
566 std::lock_guard<std::mutex> m(*pThisMutex);
568 auto iter = pThisAcceptMap->find(nemId);
570 if(iter == pThisAcceptMap->end())
573 std::vector<Any> v{
Any{nemId}};
576 v.insert(v.end(), numColumns - 1,
Any{Counter{}});
578 pThisTable->addRow(nemId, v);
581 pThisAcceptMap->insert(std::make_pair(nemId,
582 BasicCounts{})).first;
590 ++(iter->second.numRxPackets_);
591 iter->second.numRxBytes_ += sizeInBytes;
594 pThisTable->setCell(nemId, NUM_PKTS_RX,
Any{iter->second.numRxPackets_});
595 pThisTable->setCell(nemId, NUM_BYTES_RX,
Any{iter->second.numRxBytes_});
600 ++(iter->second.numTxPackets_);
601 iter->second.numTxBytes_ += sizeInBytes;
604 pThisTable->setCell(nemId, NUM_PKTS_TX,
Any{iter->second.numTxPackets_});
605 pThisTable->setCell(nemId, NUM_BYTES_TX ,
Any{iter->second.numTxBytes_});
614 enum AcceptTableLabelIndex {NUM_PKTS_TX = 1, NUM_BYTES_TX = 2, NUM_PKTS_RX = 3, NUM_BYTES_RX = 4};
616 using Counter = std::uint64_t;
619 Counter numRxPackets_;
621 Counter numTxPackets_;
632 using Average = float;
634 using Counters = std::vector<Counter>;
636 using NEMDropCodeMap = std::map<NEMId, Counters>;
638 using NEMAcceptMap = std::map<NEMId, BasicCounts>;
640 NEMDropCodeMap nemUnicastDropCodeMap_;
642 NEMDropCodeMap nemBroadcastDropCodeMap_;
644 NEMAcceptMap nemUnicastAcceptMap_;
646 NEMAcceptMap nemBroadcastAcceptMap_;
648 std::mutex nemUnicastDropTableMutex_;
650 std::mutex nemBroadcastDropTableMutex_;
652 std::mutex nemUnicastAcceptTableMutex_;
654 std::mutex nemBroadcastAcceptTableMutex_;
656 const std::string sInstance_;
658 bool bHaveDropTables_;
670 StatisticNumeric<Counter> * pNumUpstreamPacketsUnicastTx_;
671 StatisticNumeric<Counter> * pNumUpstreamBytesUnicastTx_;
674 StatisticNumeric<Counter> * pNumUpstreamPacketsBroadcastTx_;
675 StatisticNumeric<Counter> * pNumUpstreamBytesBroadcastTx_;
678 StatisticNumeric<Counter> * pNumUpstreamPacketsUnicastRx_;
679 StatisticNumeric<Counter> * pNumUpstreamBytesUnicastRx_;
680 StatisticNumeric<Counter> * pNumUpstreamPacketsUnicastDrop_;
683 StatisticNumeric<Counter> * pNumUpstreamPacketsBroadcastRx_;
684 StatisticNumeric<Counter> * pNumUpstreamBytesBroadcastRx_;
685 StatisticNumeric<Counter> * pNumUpstreamPacketsBroadcastDrop_;
688 RunningAverage<Average> avgUpstreamProcessingDelay_;
691 StatisticNumeric<Counter> * pNumDownstreamPacketsUnicastTx_;
692 StatisticNumeric<Counter> * pNumDownstreamBytesUnicastTx_;
695 StatisticNumeric<Counter> * pNumDownstreamPacketsBroadcastTx_;
696 StatisticNumeric<Counter> * pNumDownstreamBytesBroadcastTx_;
699 StatisticNumeric<Counter> * pNumDownstreamPacketsUnicastRx_;
700 StatisticNumeric<Counter> * pNumDownstreamBytesUnicastRx_;
701 StatisticNumeric<Counter> * pNumDownstreamPacketsUnicastDrop_;
704 StatisticNumeric<Counter> * pNumDownstreamPacketsBroadcastRx_;
705 StatisticNumeric<Counter> * pNumDownstreamBytesBroadcastRx_;
706 StatisticNumeric<Counter> * pNumDownstreamPacketsBroadcastDrop_;
709 RunningAverage<Average> avgDownstreamProcessingDelay_;
712 StatisticNumeric<Counter> * pNumDownstreamPacketsUnicastGenerated_;
713 StatisticNumeric<Counter> * pNumDownstreamBytesUnicastGenerated_;
716 StatisticNumeric<Counter> * pNumDownstreamPacketsBroadcastGenerated_;
717 StatisticNumeric<Counter> * pNumDownstreamBytesBroadcastGenerated_;
719 StatisticTable<NEMId> * pStatisticUnicastDropTable_;
720 StatisticTable<NEMId> * pStatisticBroadcastDropTable_;
722 StatisticTable<NEMId> * pStatisticUnicastAcceptTable_;
723 StatisticTable<NEMId> * pStatisticBroadcastAcceptTable_;
726 inline bool isBroadcast(
const DownstreamPacket & pkt)
731 inline bool isBroadcast(
const UpstreamPacket & pkt)
742 const std::string & sInstance):
743 pImpl_{
new Implementation{unicastDropTableLabels, broadcastDropTableLabels, sInstance}}
753 pImpl_->registerStatistics(statisticRegistrar);
759 pImpl_->processInbound(pkt);
767 pImpl_->processOutbound(pkt, delay, dropCode);
773 pImpl_->processInbound(pkt);
782 pImpl_->processOutbound(pkt, delay, dropCode, bSelfGenerated);
A Packet class that allows upstream processing to strip layer headers as the packet travels up the st...
void processOutbound(const UpstreamPacket &pkt, Microseconds delay, size_t dropCode={})
constexpr NEMId NEM_BROADCAST_MAC_ADDRESS
void registerStatistics(StatisticRegistrar &statisticRegistrar)
The StatisticRegistrar allows NEM layers to register statistics and statistic tables. Statistics and Statistic tables are owned by the emulator framework and a borrowed reference is returned to the registering NEM layer.
std::vector< std::string > StatisticTableLabels
Specialized packet the allows downstream processing to add layer specific headers as the packet trave...
std::chrono::microseconds Microseconds
void processInbound(const UpstreamPacket &pkt)
CommonLayerStatistics(const StatisticTableLabels &unicastDropTableLabels, const StatisticTableLabels &broadcastDropTableLabels={}, const std::string &sInstance={})