14 #include <boost/noncopyable.hpp>
15 #include <boost/shared_ptr.hpp>
16 #include <boost/multi_index_container.hpp>
17 #include <boost/multi_index/ordered_index.hpp>
18 #include <boost/multi_index/sequenced_index.hpp>
19 #include <boost/multi_index/global_fun.hpp>
20 #include <boost/multi_index/mem_fun.hpp>
21 #include <boost/date_time/posix_time/posix_time.hpp>
87 return (this_counter);
107 const std::string&
getName()
const {
return(name_); }
154 return(packet->getTransid() & 1023);
228 typedef boost::multi_index_container<
232 boost::multi_index::indexed_by<
235 boost::multi_index::sequenced<>,
240 boost::multi_index::ordered_non_unique<
244 boost::multi_index::global_fun<
259 typedef typename PktList::template nth_index<1>::type
262 typedef typename PktListTransidHashIndex::const_iterator
265 typedef typename std::queue<PktListTransidHashIterator>
277 const double drop_time,
278 const bool archive_enabled,
279 const boost::posix_time::ptime boot_time);
291 static_cast<void>(sent_packets_.template get<0>().push_back(packet));
305 static_cast<void>(rcvd_packets_.push_back(packet));
318 const dhcp::PktPtr& rcvd_packet);
335 dhcp::PktPtr
matchPackets(
const dhcp::PktPtr& rcvd_packet);
361 if (rcvd_packets_num_ == 0) {
364 return(sum_delay_ / rcvd_packets_num_);
378 if (rcvd_packets_num_ == 0) {
381 return(sqrt(sum_delay_squared_ / rcvd_packets_num_ -
415 if (unordered_lookups_ == 0) {
418 return(static_cast<double>(unordered_lookup_size_sum_) /
419 static_cast<double>(unordered_lookups_));
511 double drops_ratio = 100.0 *
static_cast<double>(drops) / static_cast<double>(sent);
513 cout <<
"sent packets: " << sent << endl
515 <<
"drops: " << drops << endl
516 <<
"drops ratio: " << drops_ratio <<
" %" << endl
532 cout << fixed << setprecision(3)
533 <<
"min delay: " <<
getMinDelay() * 1e3 <<
" ms" << endl
534 <<
"avg delay: " <<
getAvgDelay() * 1e3 <<
" ms" << endl
535 <<
"max delay: " <<
getMaxDelay() * 1e3 <<
" ms" << endl
541 cout <<
"min delay: n/a" << endl
542 <<
"avg delay: n/a" << endl
543 <<
"max delay: n/a" << endl
544 <<
"std deviation: n/a" << endl
545 <<
"collected packets: 0" << endl;
562 return(std::make_tuple(sent_packets_.begin(), sent_packets_.end()));
596 PktListIterator eraseSent(
const PktListIterator it) {
597 if (archive_enabled_) {
604 static_cast<void>(archived_packets_.push_back(*it));
608 return(sent_packets_.template get<0>().erase(it));
617 PktListIterator next_sent_;
637 bool archive_enabled_;
648 double sum_delay_squared_;
661 uint64_t unordered_lookup_size_sum_;
663 uint64_t unordered_lookups_;
664 uint64_t ordered_lookups_;
668 uint64_t sent_packets_num_;
669 uint64_t rcvd_packets_num_;
671 uint64_t non_unique_addr_num_;
672 uint64_t rejected_leases_num_;
674 boost::posix_time::ptime boot_time_;
682 typedef typename std::map<ExchangeType, ExchangeStatsPtr>
ExchangesMap;
728 const double drop_time = -1) {
729 if (exchanges_.find(xchg_type) != exchanges_.end()) {
732 exchanges_[xchg_type] =
750 return (exchanges_.find(xchg_type) != exchanges_.end());
761 const std::string& long_name) {
762 if (custom_counters_.find(short_name) != custom_counters_.end()) {
764 "Custom counter " << short_name <<
" already added.");
766 custom_counters_[short_name] =
774 for (ExchangesMapIterator it = exchanges_.begin();
775 it != exchanges_.end();
777 if (it->second->getDroppedPacketsNum() > 0) {
791 CustomCounterPtr
getCounter(
const std::string& counter_key) {
792 CustomCountersMapIterator it = custom_counters_.find(counter_key);
793 if (it == custom_counters_.end()) {
795 "Custom counter " << counter_key <<
"does not exist");
808 const uint64_t value = 1) {
809 CustomCounterPtr counter = getCounter(counter_key);
825 const dhcp::PktPtr& packet) {
826 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
827 xchg_stats->appendSent(packet);
845 const dhcp::PktPtr& packet) {
846 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
847 dhcp::PktPtr sent_packet = xchg_stats->matchPackets(packet);
850 xchg_stats->updateDelays(sent_packet, packet);
851 if (archive_enabled_) {
852 xchg_stats->appendRcvd(packet);
867 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
868 return(xchg_stats->getMinDelay());
880 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
881 return(xchg_stats->getMaxDelay());
891 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
892 return(xchg_stats->getAvgDelay());
902 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
903 return(xchg_stats->getStdDevDelay());
915 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
916 return(xchg_stats->getOrphans());
929 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
930 return(xchg_stats->getAvgUnorderedLookupSetSize());
944 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
945 return(xchg_stats->getUnorderedLookups());
960 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
961 return(xchg_stats->getOrderedLookups());
973 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
974 return(xchg_stats->getSentPacketsNum());
986 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
987 return(xchg_stats->getRcvdPacketsNum());
999 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
1000 return(xchg_stats->getDroppedPacketsNum());
1014 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
1015 return(xchg_stats->getCollectedNum());
1027 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
1028 return(xchg_stats->getRejLeasesNum());
1036 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
1037 xchg_stats->updateRejLeases();
1045 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
1046 xchg_stats->updateNonUniqueAddr();
1058 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
1059 return(xchg_stats->getNonUniqueAddrNum());
1071 time_period test_period(boot_time_,
1072 microsec_clock::universal_time());
1090 if (exchanges_.empty()) {
1092 "no exchange type added for tracking");
1094 for (ExchangesMapIterator it = exchanges_.begin();
1095 it != exchanges_.end();
1097 ExchangeStatsPtr xchg_stats = it->second;
1098 std::cout <<
"***Statistics for: " << it->first
1099 <<
"***" << std::endl;
1100 xchg_stats->printMainStats();
1101 std::cout << std::endl;
1102 xchg_stats->printRTTStats();
1103 std::cout << std::endl;
1117 std::ostringstream stream_sent;
1118 std::ostringstream stream_rcvd;
1119 std::ostringstream stream_drops;
1120 std::ostringstream stream_reject;
1121 std::string sep(
"");
1122 for (ExchangesMapIterator it = exchanges_.begin();
1123 it != exchanges_.end(); ++it) {
1125 if (it != exchanges_.begin()) {
1132 stream_sent << sep << it->second->getSentPacketsNum();
1133 stream_rcvd << sep << it->second->getRcvdPacketsNum();
1134 stream_drops << sep << it->second->getDroppedPacketsNum();
1135 stream_reject << sep << it->second->getRejLeasesNum();
1139 std::cout << stream_sent.str()
1140 << clean_sep << stream_rcvd.str()
1141 << clean_sep << stream_drops.str()
1142 << clean_sep << stream_reject.str()
1146 std::cout <<
"sent: " << stream_sent.str()
1147 <<
"; received: " << stream_rcvd.str()
1148 <<
"; drops: " << stream_drops.str()
1149 <<
"; rejected: " << stream_reject.str()
1166 if (exchanges_.empty()) {
1168 "no exchange type added for tracking");
1170 for (ExchangesMapIterator it = exchanges_.begin();
1171 it != exchanges_.end();
1173 ExchangeStatsPtr xchg_stats = it->second;
1174 std::cout <<
"***Timestamps for packets: "
1176 <<
"***" << std::endl;
1177 xchg_stats->printTimestamps();
1178 std::cout << std::endl;
1192 if (custom_counters_.empty()) {
1195 for (CustomCountersMapIterator it = custom_counters_.begin();
1196 it != custom_counters_.end();
1198 CustomCounterPtr counter = it->second;
1199 std::cout << counter->getName() <<
": " << counter->getValue()
1204 std::tuple<typename ExchangeStats::PktListIterator, typename ExchangeStats::PktListIterator>
getSentPackets(
const ExchangeType xchg_type)
const {
1205 ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
1206 std::tuple<typename ExchangeStats::PktListIterator, typename ExchangeStats::PktListIterator> sent_packets_its = xchg_stats->getSentPackets();
1207 return(sent_packets_its);
1219 ExchangeStatsPtr getExchangeStats(
const ExchangeType xchg_type)
const {
1220 ExchangesMapIterator it = exchanges_.find(xchg_type);
1221 if (it == exchanges_.end()) {
1224 ExchangeStatsPtr xchg_stats = it->second;
1228 ExchangesMap exchanges_;
1229 CustomCountersMap custom_counters_;
1239 bool archive_enabled_;
1241 boost::posix_time::ptime boot_time_;
1251 #endif // STATS_MGR_H
uint64_t getRcvdPacketsNum(const ExchangeType xchg_type) const
Return total number of received packets.
const CustomCounter & incrementCounter(const std::string &counter_key, const uint64_t value=1)
Increment specified counter.
uint64_t getOrphans() const
Return number of orphan packets.
bool droppedPackets() const
Check if any packet drops occurred.
uint64_t getSentPacketsNum(const ExchangeType xchg_type) const
Return total number of sent packets.
double getAvgUnorderedLookupSetSize(const ExchangeType xchg_type) const
Return average unordered lookup set size.
DHCPv6 SOLICIT-ADVERTISE.
ExchangeType
DHCP packet exchange types.
bool hasExchangeStats(const ExchangeType xchg_type) const
Check if the exchange type has been specified.
uint64_t getRejLeasesNum(const ExchangeType xchg_type) const
Return total number of rejected leases.
ExchangesMap::const_iterator ExchangesMapIterator
Iterator pointing to ExchangesMap.
CustomCounter(const std::string &name)
Constructor.
uint64_t getCollectedNum(const ExchangeType xchg_type) const
Return number of garbage collected packets.
double getMaxDelay() const
Return maximum delay between sent and received packet.
static uint32_t hashTransid(const dhcp::PktPtr &packet)
Hash transaction id of the packet.
uint64_t getValue() const
Return counter value.
std::tuple< typename ExchangeStats::PktListIterator, typename ExchangeStats::PktListIterator > getSentPackets(const ExchangeType xchg_type) const
uint64_t getOrderedLookups(const ExchangeType xchg_type) const
Return number of ordered sent packets lookups.
CustomCountersMap::const_iterator CustomCountersMapIterator
Iterator for CustomCountersMap.
std::queue< PktListTransidHashIterator > PktListRemovalQueue
Packet list iterator queue for removal.
double getAvgUnorderedLookupSetSize() const
Return average unordered lookup set size.
uint64_t getRcvdPacketsNum() const
Return total number of received packets.
void updateRejLeases()
Increase number of rejected leases.
uint64_t getNonUniqueAddrNum(const ExchangeType xchg_type) const
Return total number of non unique addresses.
void appendSent(const dhcp::PktPtr &packet)
Add new packet to list of sent packets.
void updateDelays(const dhcp::PktPtr &sent_packet, const dhcp::PktPtr &rcvd_packet)
Update delay counters.
void printMainStats() const
Print main statistics for packet exchange.
void printCustomCounters() const
Print names and values of custom counters.
double getMinDelay() const
Return minimum delay between sent and received packet.
boost::multi_index_container< dhcp::PktPtr, boost::multi_index::indexed_by< boost::multi_index::sequenced<>, boost::multi_index::ordered_non_unique< boost::multi_index::global_fun< const dhcp::PktPtr &, uint32_t,&ExchangeStats::hashTransid > > > > PktList
List of packets (sent or received).
void printRTTStats() const
Print round trip time packets statistics.
double getAvgDelay() const
Return average packet delay.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
double getMaxDelay(const ExchangeType xchg_type) const
Return maximum delay between sent and received packet.
uint64_t getUnorderedLookups() const
Return number of unordered sent packets lookups.
uint64_t getCollectedNum() const
Return number of garbage collected packets.
DHCPv4 REQUEST-ACK (renewal)
std::map< std::string, CustomCounterPtr > CustomCountersMap
Map containing custom counters.
boost::shared_ptr< StatsMgr > StatsMgrPtr
Pointer to Statistics Manager;.
void printLeases() const
Print the list of received leases.
int dhcpVersion(ExchangeType const exchange_type)
Get the DHCP version that fits the exchange type.
void updateRejLeases(const ExchangeType xchg_type)
Increase total number of rejected leases.
std::ostream & operator<<(std::ostream &os, ExchangeType xchg_type)
Return name of the exchange.
CustomCounterPtr getCounter(const std::string &counter_key)
Return specified counter.
static int malformed_pkts_
const std::string & getName() const
Return counter name.
uint64_t getOrderedLookups() const
Return number of ordered sent packets lookups.
uint64_t getNonUniqueAddrNum() const
Return total number of non unique addresses.
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
dhcp::PktPtr passRcvdPacket(const ExchangeType xchg_type, const dhcp::PktPtr &packet)
Add new received packet and match with sent packet.
const CustomCounter & operator+=(int val)
void updateNonUniqueAddr()
Increase number of non unique addresses.
void printStats() const
Print statistics counters for all exchange types.
double getAvgDelay(const ExchangeType xchg_type) const
Return average packet delay.
dhcp::PktPtr matchPackets(const dhcp::PktPtr &rcvd_packet)
Match received packet with the corresponding sent packet.
const CustomCounter & operator++()
Increment operator.
This is a base class for exceptions thrown from the DNS library module.
uint64_t getDroppedPacketsNum(const ExchangeType xchg_type) const
Return total number of dropped packets.
Defines the logger used by the top-level component of kea-dhcp-ddns.
PktList::iterator PktListIterator
Packet list iterator for sequential access to elements.
PktList::template nth_index< 1 >::type PktListTransidHashIndex
Packet list index to search packets using transaction id hash.
void appendRcvd(const dhcp::PktPtr &packet)
Add new packet to list of received packets.
void printIntermediateStats(bool clean_report, std::string clean_sep) const
Print intermediate statistics.
void addExchangeStats(const ExchangeType xchg_type, const double drop_time=-1)
Specify new exchange type.
PktListTransidHashIndex::const_iterator PktListTransidHashIterator
Packet list iterator to access packets using transaction id hash.
uint64_t getUnorderedLookups(const ExchangeType xchg_type) const
Return number of unordered sent packets lookups.
uint64_t getOrphans(const ExchangeType xchg_type) const
Return number of orphan packets.
uint64_t getSentPacketsNum() const
Return total number of sent packets.
A generic exception that is thrown if a function is called in a prohibited way.
double getStdDevDelay() const
Return standard deviation of packet delay.
double getMinDelay(const ExchangeType xchg_type) const
Return minimum delay between sent and received packet.
double getStdDevDelay(const ExchangeType xchg_type) const
Return standard deviation of packet delay.
void addCustomCounter(const std::string &short_name, const std::string &long_name)
Add named custom uint64 counter.
std::tuple< PktListIterator, PktListIterator > getSentPackets()
boost::shared_ptr< ExchangeStats > ExchangeStatsPtr
Pointer to ExchangeStats.
boost::shared_ptr< CustomCounter > CustomCounterPtr
uint64_t getDroppedPacketsNum() const
Return number of dropped packets.
boost::posix_time::time_period getTestPeriod() const
Get time period since the start of test.
std::map< ExchangeType, ExchangeStatsPtr > ExchangesMap
Map containing all specified exchange types.
void updateNonUniqueAddrNum(const ExchangeType xchg_type)
Increase total number of non unique addresses.
uint64_t getRejLeasesNum() const
Return total number of rejected leases.
void printTimestamps()
Print timestamps for sent and received packets.
void printTimestamps() const
Print timestamps of all packets.
void passSentPacket(const ExchangeType xchg_type, const dhcp::PktPtr &packet)
Adds new packet to the sent packets list.
std::string receivedLeases() const
Return the list of received leases in CSV format as string.
const CustomCounter & operator++(int)
Increment operator.