Merge pull request #350 from pstavirs/streamrates
Add average rate per GUID in stream statistics
This commit is contained in:
commit
5e7bf77b0c
@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
#include "streamstatsmodel.h"
|
#include "streamstatsmodel.h"
|
||||||
|
|
||||||
#include "protocol.pb.h"
|
#include "protocol.pb.h"
|
||||||
|
#include "xqlocale.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QBrush>
|
#include <QBrush>
|
||||||
@ -45,12 +46,22 @@ enum {
|
|||||||
kAggrTxPkts,
|
kAggrTxPkts,
|
||||||
kAggrRxPkts,
|
kAggrRxPkts,
|
||||||
kAggrPktLoss,
|
kAggrPktLoss,
|
||||||
|
kTxDuration,
|
||||||
|
kAvgTxFrameRate,
|
||||||
|
kAvgRxFrameRate,
|
||||||
|
kAvgTxBitRate,
|
||||||
|
kAvgRxBitRate,
|
||||||
kMaxAggrStreamStats
|
kMaxAggrStreamStats
|
||||||
};
|
};
|
||||||
static QStringList aggrStatTitles = QStringList()
|
static QStringList aggrStatTitles = QStringList()
|
||||||
<< "Total\nTx Pkts"
|
<< "Total\nTx Pkts"
|
||||||
<< "Total\nRx Pkts"
|
<< "Total\nRx Pkts"
|
||||||
<< "Total\nPkt Loss";
|
<< "Total\nPkt Loss"
|
||||||
|
<< "Duration\n(secs)"
|
||||||
|
<< "Avg\nTx PktRate"
|
||||||
|
<< "Avg\nRx PktRate"
|
||||||
|
<< "Avg\nTx BitRate"
|
||||||
|
<< "Avg\nRx BitRate";
|
||||||
|
|
||||||
static const uint kAggrGuid = 0xffffffff;
|
static const uint kAggrGuid = 0xffffffff;
|
||||||
|
|
||||||
@ -149,6 +160,26 @@ QVariant StreamStatsModel::data(const QModelIndex &index, int role) const
|
|||||||
return QString("%L1").arg(aggrGuidStats_.value(guid).txPkts);
|
return QString("%L1").arg(aggrGuidStats_.value(guid).txPkts);
|
||||||
case kAggrPktLoss:
|
case kAggrPktLoss:
|
||||||
return QString("%L1").arg(aggrGuidStats_.value(guid).pktLoss);
|
return QString("%L1").arg(aggrGuidStats_.value(guid).pktLoss);
|
||||||
|
case kTxDuration:
|
||||||
|
return QString("%L1").arg(aggrGuidStats_.value(guid).txDuration);
|
||||||
|
case kAvgTxFrameRate:
|
||||||
|
return QString("%L1").arg(
|
||||||
|
aggrGuidStats_.value(guid).txPkts
|
||||||
|
/ aggrGuidStats_.value(guid).txDuration);
|
||||||
|
case kAvgRxFrameRate:
|
||||||
|
return QString("%L1").arg(
|
||||||
|
aggrGuidStats_.value(guid).rxPkts
|
||||||
|
/ aggrGuidStats_.value(guid).txDuration);
|
||||||
|
case kAvgTxBitRate:
|
||||||
|
return XLocale().toBitRateString(
|
||||||
|
(aggrGuidStats_.value(guid).txBytes
|
||||||
|
+ 24 * aggrGuidStats_.value(guid).txPkts) * 8
|
||||||
|
/ aggrGuidStats_.value(guid).txDuration);
|
||||||
|
case kAvgRxBitRate:
|
||||||
|
return XLocale().toBitRateString(
|
||||||
|
(aggrGuidStats_.value(guid).rxBytes
|
||||||
|
+ 24 * aggrGuidStats_.value(guid).rxPkts) * 8
|
||||||
|
/ aggrGuidStats_.value(guid).txDuration);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
@ -232,10 +263,18 @@ void StreamStatsModel::appendStreamStatsList(
|
|||||||
aggrGuid.rxPkts += ss.rxPkts;
|
aggrGuid.rxPkts += ss.rxPkts;
|
||||||
aggrGuid.txPkts += ss.txPkts;
|
aggrGuid.txPkts += ss.txPkts;
|
||||||
aggrGuid.pktLoss += ss.txPkts - ss.rxPkts;
|
aggrGuid.pktLoss += ss.txPkts - ss.rxPkts;
|
||||||
|
aggrGuid.rxBytes += ss.rxBytes;
|
||||||
|
aggrGuid.txBytes += ss.txBytes;
|
||||||
|
if (s.tx_duration() > aggrGuid.txDuration)
|
||||||
|
aggrGuid.txDuration = s.tx_duration(); // XXX: use largest or avg?
|
||||||
|
|
||||||
aggrAggr.rxPkts += ss.rxPkts;
|
aggrAggr.rxPkts += ss.rxPkts;
|
||||||
aggrAggr.txPkts += ss.txPkts;
|
aggrAggr.txPkts += ss.txPkts;
|
||||||
aggrAggr.pktLoss += ss.txPkts - ss.rxPkts;
|
aggrAggr.pktLoss += ss.txPkts - ss.rxPkts;
|
||||||
|
aggrAggr.rxBytes += ss.rxBytes;
|
||||||
|
aggrAggr.txBytes += ss.txBytes;
|
||||||
|
if (aggrGuid.txDuration > aggrAggr.txDuration)
|
||||||
|
aggrAggr.txDuration = aggrGuid.txDuration;
|
||||||
|
|
||||||
if (!portList_.contains(pgp))
|
if (!portList_.contains(pgp))
|
||||||
portList_.append(pgp);
|
portList_.append(pgp);
|
||||||
@ -246,6 +285,8 @@ void StreamStatsModel::appendStreamStatsList(
|
|||||||
if (guidList_.size() && !guidList_.contains(kAggrGuid))
|
if (guidList_.size() && !guidList_.contains(kAggrGuid))
|
||||||
guidList_.append(kAggrGuid);
|
guidList_.append(kAggrGuid);
|
||||||
|
|
||||||
|
std::sort(guidList_.begin(), guidList_.end());
|
||||||
|
|
||||||
#if QT_VERSION >= 0x040600
|
#if QT_VERSION >= 0x040600
|
||||||
endResetModel();
|
endResetModel();
|
||||||
#else
|
#else
|
||||||
|
@ -61,7 +61,10 @@ private:
|
|||||||
struct AggrGuidStats {
|
struct AggrGuidStats {
|
||||||
quint64 rxPkts;
|
quint64 rxPkts;
|
||||||
quint64 txPkts;
|
quint64 txPkts;
|
||||||
|
quint64 rxBytes;
|
||||||
|
quint64 txBytes;
|
||||||
qint64 pktLoss;
|
qint64 pktLoss;
|
||||||
|
double txDuration;
|
||||||
};
|
};
|
||||||
QList<Guid> guidList_;
|
QList<Guid> guidList_;
|
||||||
QList<PortGroupPort> portList_;
|
QList<PortGroupPort> portList_;
|
||||||
|
@ -31,7 +31,7 @@ StreamStatsWindow::StreamStatsWindow(QAbstractItemModel *model, QWidget *parent)
|
|||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
streamStats->addAction(actionShowByteCounters);
|
streamStats->addAction(actionShowDetails);
|
||||||
|
|
||||||
if (id)
|
if (id)
|
||||||
setWindowTitle(windowTitle() + QString("(%1)").arg(id));
|
setWindowTitle(windowTitle() + QString("(%1)").arg(id));
|
||||||
@ -39,7 +39,7 @@ StreamStatsWindow::StreamStatsWindow(QAbstractItemModel *model, QWidget *parent)
|
|||||||
count++;
|
count++;
|
||||||
|
|
||||||
filterModel_ = new StreamStatsFilterModel(this);
|
filterModel_ = new StreamStatsFilterModel(this);
|
||||||
filterModel_->setFilterRegExp(QRegExp(".*Pkt.*"));
|
filterModel_->setFilterRegExp(QRegExp(kDefaultFilter_));
|
||||||
filterModel_->setSourceModel(model);
|
filterModel_->setSourceModel(model);
|
||||||
streamStats->setModel(filterModel_);
|
streamStats->setModel(filterModel_);
|
||||||
|
|
||||||
@ -56,10 +56,10 @@ StreamStatsWindow::~StreamStatsWindow()
|
|||||||
id = 0;
|
id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamStatsWindow::on_actionShowByteCounters_triggered(bool checked)
|
void StreamStatsWindow::on_actionShowDetails_triggered(bool checked)
|
||||||
{
|
{
|
||||||
if (checked)
|
if (checked)
|
||||||
filterModel_->setFilterRegExp(QRegExp(".*"));
|
filterModel_->setFilterRegExp(QRegExp(".*"));
|
||||||
else
|
else
|
||||||
filterModel_->setFilterRegExp(QRegExp(".*Pkt.*"));
|
filterModel_->setFilterRegExp(QRegExp(kDefaultFilter_));
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,10 @@ public:
|
|||||||
~StreamStatsWindow();
|
~StreamStatsWindow();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_actionShowByteCounters_triggered(bool checked);
|
void on_actionShowDetails_triggered(bool checked);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QString kDefaultFilter_{"^(?!Port).*"};
|
||||||
QSortFilterProxyModel *filterModel_;
|
QSortFilterProxyModel *filterModel_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,12 +27,12 @@ Wait a little bit to see if they appear, otherwise verify your stream stats conf
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
<action name="actionShowByteCounters">
|
<action name="actionShowDetails">
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show Byte Counters</string>
|
<string>Show Details</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -290,6 +290,8 @@ message StreamStats {
|
|||||||
required PortId port_id = 1;
|
required PortId port_id = 1;
|
||||||
required StreamGuid stream_guid = 2;
|
required StreamGuid stream_guid = 2;
|
||||||
|
|
||||||
|
optional double tx_duration = 3; // in seconds
|
||||||
|
|
||||||
optional uint64 rx_pkts = 11;
|
optional uint64 rx_pkts = 11;
|
||||||
optional uint64 rx_bytes = 12;
|
optional uint64 rx_bytes = 12;
|
||||||
optional uint64 tx_pkts = 13;
|
optional uint64 tx_pkts = 13;
|
||||||
|
@ -714,6 +714,8 @@ void AbstractPort::streamStats(uint guid, OstProto::StreamStatsList *stats)
|
|||||||
s->mutable_stream_guid()->set_id(guid);
|
s->mutable_stream_guid()->set_id(guid);
|
||||||
s->mutable_port_id()->set_id(id());
|
s->mutable_port_id()->set_id(id());
|
||||||
|
|
||||||
|
s->set_tx_duration(lastTransmitDuration());
|
||||||
|
|
||||||
s->set_tx_pkts(sst.tx_pkts);
|
s->set_tx_pkts(sst.tx_pkts);
|
||||||
s->set_tx_bytes(sst.tx_bytes);
|
s->set_tx_bytes(sst.tx_bytes);
|
||||||
s->set_rx_pkts(sst.rx_pkts);
|
s->set_rx_pkts(sst.rx_pkts);
|
||||||
@ -725,6 +727,7 @@ void AbstractPort::streamStatsAll(OstProto::StreamStatsList *stats)
|
|||||||
{
|
{
|
||||||
// FIXME: change input param to a non-OstProto type and/or have
|
// FIXME: change input param to a non-OstProto type and/or have
|
||||||
// a getFirst/Next like API?
|
// a getFirst/Next like API?
|
||||||
|
double txDur = lastTransmitDuration();
|
||||||
StreamStatsIterator i(streamStats_);
|
StreamStatsIterator i(streamStats_);
|
||||||
while (i.hasNext())
|
while (i.hasNext())
|
||||||
{
|
{
|
||||||
@ -735,6 +738,8 @@ void AbstractPort::streamStatsAll(OstProto::StreamStatsList *stats)
|
|||||||
s->mutable_stream_guid()->set_id(i.key());
|
s->mutable_stream_guid()->set_id(i.key());
|
||||||
s->mutable_port_id()->set_id(id());
|
s->mutable_port_id()->set_id(id());
|
||||||
|
|
||||||
|
s->set_tx_duration(txDur);
|
||||||
|
|
||||||
s->set_tx_pkts(sst.tx_pkts);
|
s->set_tx_pkts(sst.tx_pkts);
|
||||||
s->set_tx_bytes(sst.tx_bytes);
|
s->set_tx_bytes(sst.tx_bytes);
|
||||||
s->set_rx_pkts(sst.rx_pkts);
|
s->set_rx_pkts(sst.rx_pkts);
|
||||||
|
@ -110,6 +110,7 @@ public:
|
|||||||
virtual void startTransmit() = 0;
|
virtual void startTransmit() = 0;
|
||||||
virtual void stopTransmit() = 0;
|
virtual void stopTransmit() = 0;
|
||||||
virtual bool isTransmitOn() = 0;
|
virtual bool isTransmitOn() = 0;
|
||||||
|
virtual double lastTransmitDuration() = 0;
|
||||||
|
|
||||||
virtual void startCapture() = 0;
|
virtual void startCapture() = 0;
|
||||||
virtual void stopCapture() = 0;
|
virtual void stopCapture() = 0;
|
||||||
|
@ -68,6 +68,9 @@ public:
|
|||||||
}
|
}
|
||||||
virtual void stopTransmit() { transmitter_->stop(); }
|
virtual void stopTransmit() { transmitter_->stop(); }
|
||||||
virtual bool isTransmitOn() { return transmitter_->isRunning(); }
|
virtual bool isTransmitOn() { return transmitter_->isRunning(); }
|
||||||
|
virtual double lastTransmitDuration() {
|
||||||
|
return transmitter_->lastTxDuration();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void startCapture() { capturer_->start(); }
|
virtual void startCapture() { capturer_->start(); }
|
||||||
virtual void stopCapture() { capturer_->stop(); }
|
virtual void stopCapture() { capturer_->stop(); }
|
||||||
|
@ -107,6 +107,10 @@ bool PcapTransmitter::isRunning()
|
|||||||
{
|
{
|
||||||
return txThread_.isRunning();
|
return txThread_.isRunning();
|
||||||
}
|
}
|
||||||
|
double PcapTransmitter::lastTxDuration()
|
||||||
|
{
|
||||||
|
return txThread_.lastTxDuration();
|
||||||
|
}
|
||||||
|
|
||||||
void PcapTransmitter::updateTxThreadStreamStats()
|
void PcapTransmitter::updateTxThreadStreamStats()
|
||||||
{
|
{
|
||||||
|
@ -49,6 +49,7 @@ public:
|
|||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
bool isRunning();
|
bool isRunning();
|
||||||
|
double lastTxDuration();
|
||||||
private slots:
|
private slots:
|
||||||
void updateTxThreadStreamStats();
|
void updateTxThreadStreamStats();
|
||||||
private:
|
private:
|
||||||
|
@ -243,6 +243,7 @@ void PcapTxThread::run()
|
|||||||
const int kSyncTransmit = 1;
|
const int kSyncTransmit = 1;
|
||||||
int i;
|
int i;
|
||||||
long overHead = 0; // overHead should be negative or zero
|
long overHead = 0; // overHead should be negative or zero
|
||||||
|
TimeStamp startTime, endTime;
|
||||||
|
|
||||||
qDebug("packetSequenceList_.size = %d", packetSequenceList_.size());
|
qDebug("packetSequenceList_.size = %d", packetSequenceList_.size());
|
||||||
if (packetSequenceList_.size() <= 0)
|
if (packetSequenceList_.size() <= 0)
|
||||||
@ -260,6 +261,7 @@ void PcapTxThread::run()
|
|||||||
|
|
||||||
lastStats_ = *stats_; // used for stream stats
|
lastStats_ = *stats_; // used for stream stats
|
||||||
|
|
||||||
|
getTimeStamp(&startTime);
|
||||||
state_ = kRunning;
|
state_ = kRunning;
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < packetSequenceList_.size())
|
while (i < packetSequenceList_.size())
|
||||||
@ -348,6 +350,10 @@ _restart:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_exit:
|
_exit:
|
||||||
|
getTimeStamp(&endTime);
|
||||||
|
lastTxDuration_ = udiffTimeStamp(&startTime, &endTime)/1e6;
|
||||||
|
qDebug("Tx duration = %fs", lastTxDuration_);
|
||||||
|
|
||||||
if (trackStreamStats_)
|
if (trackStreamStats_)
|
||||||
updateStreamStats();
|
updateStreamStats();
|
||||||
|
|
||||||
@ -388,6 +394,11 @@ bool PcapTxThread::isRunning()
|
|||||||
return (state_ == kRunning);
|
return (state_ == kRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double PcapTxThread::lastTxDuration()
|
||||||
|
{
|
||||||
|
return lastTxDuration_;
|
||||||
|
}
|
||||||
|
|
||||||
int PcapTxThread::sendQueueTransmit(pcap_t *p,
|
int PcapTxThread::sendQueueTransmit(pcap_t *p,
|
||||||
pcap_send_queue *queue, long &overHead, int sync)
|
pcap_send_queue *queue, long &overHead, int sync)
|
||||||
{
|
{
|
||||||
|
@ -55,6 +55,7 @@ public:
|
|||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
bool isRunning();
|
bool isRunning();
|
||||||
|
double lastTxDuration();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum State
|
enum State
|
||||||
@ -92,6 +93,8 @@ private:
|
|||||||
StatsTuple *stats_;
|
StatsTuple *stats_;
|
||||||
StatsTuple lastStats_;
|
StatsTuple lastStats_;
|
||||||
StreamStats streamStats_;
|
StreamStats streamStats_;
|
||||||
|
|
||||||
|
double lastTxDuration_{0.0}; // in secs
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user