From 0eace966e961d0a8a589c162c4ecb02c4117f1fd Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 11 Nov 2013 17:20:31 -0800 Subject: [PATCH] added support to also show inbound packet stats per sender --- .../voxel-server-library/src/VoxelServer.cpp | 40 +++++++++++++++++++ .../src/VoxelServerPacketProcessor.cpp | 33 +++++++++++++++ .../src/VoxelServerPacketProcessor.h | 30 ++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index 320e2c7de0..11d7d3ff1c 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -287,6 +287,46 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { mg_printf(connection, " Average Wait Lock Time/Voxel: %s usecs\r\n", locale.toString((uint)averageLockWaitTimePerVoxel).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData()); + + int senderNumber = 0; + NodeToSenderStatsMap& allSenderStats = GetInstance()->_voxelServerPacketProcessor->getSingleSenderStats(); + for (NodeToSenderStatsMapIterator i = allSenderStats.begin(); i != allSenderStats.end(); i++) { + senderNumber++; + // iterator->first = key + // iterator->second = value + QUuid senderID = i->first; + SingleSenderStats& senderStats = i->second; + + mg_printf(connection, "\r\n Stats for sender %d uuid: %s\r\n", senderNumber, + senderID.toString().toLocal8Bit().constData()); + + averageTransitTimePerPacket = senderStats.getAverateTransitTimePerPacket(); + averageProcessTimePerPacket = senderStats.getAverageProcessTimePerPacket(); + averageLockWaitTimePerPacket = senderStats.getAverageLockWaitTimePerPacket(); + averageProcessTimePerVoxel = senderStats.getAverageProcessTimePerVoxel(); + averageLockWaitTimePerVoxel = senderStats.getAverageLockWaitTimePerVoxel(); + totalVoxelsProcessed = senderStats.getTotalVoxelsProcessed(); + totalPacketsProcessed = senderStats.getTotalPacketsProcessed(); + + mg_printf(connection, " Total Inbound Packets: %s packets\r\n", + locale.toString((uint)totalPacketsProcessed).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData()); + mg_printf(connection, " Total Inbound Voxels: %s voxels\r\n", + locale.toString((uint)totalVoxelsProcessed).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData()); + mg_printf(connection, " Average Inbound Voxels/Packet: %f voxels/packet\r\n", averageVoxelsPerPacket); + mg_printf(connection, " Average Transit Time/Packet: %s usecs\r\n", + locale.toString((uint)averageTransitTimePerPacket).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData()); + mg_printf(connection, " Average Process Time/Packet: %s usecs\r\n", + locale.toString((uint)averageProcessTimePerPacket).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData()); + mg_printf(connection, " Average Wait Lock Time/Packet: %s usecs\r\n", + locale.toString((uint)averageLockWaitTimePerPacket).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData()); + mg_printf(connection, " Average Process Time/Voxel: %s usecs\r\n", + locale.toString((uint)averageProcessTimePerVoxel).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData()); + mg_printf(connection, " Average Wait Lock Time/Voxel: %s usecs\r\n", + locale.toString((uint)averageLockWaitTimePerVoxel).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData()); + + } + + mg_printf(connection, "%s", "\r\n"); mg_printf(connection, "%s", "\r\n"); diff --git a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp index 9d3ffcdc51..66c0d13397 100644 --- a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp +++ b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp @@ -34,6 +34,8 @@ void VoxelServerPacketProcessor::resetStats() { _totalLockWaitTime = 0; _totalVoxelsInPacket = 0; _totalPackets = 0; + + _singleSenderStats.clear(); } @@ -214,5 +216,36 @@ void VoxelServerPacketProcessor::trackInboudPackets(const QUuid& nodeUUID, int s _totalLockWaitTime += lockWaitTime; _totalVoxelsInPacket += voxelsInPacket; _totalPackets++; + + // find the individual senders stats and track them there too... + // see if this is the first we've heard of this node... + if (_singleSenderStats.find(nodeUUID) == _singleSenderStats.end()) { + SingleSenderStats stats; + + stats._totalTransitTime += transitTime; + stats._totalProcessTime += processTime; + stats._totalLockWaitTime += lockWaitTime; + stats._totalVoxelsInPacket += voxelsInPacket; + stats._totalPackets++; + + _singleSenderStats[nodeUUID] = stats; + } else { + SingleSenderStats& stats = _singleSenderStats[nodeUUID]; + stats._totalTransitTime += transitTime; + stats._totalProcessTime += processTime; + stats._totalLockWaitTime += lockWaitTime; + stats._totalVoxelsInPacket += voxelsInPacket; + stats._totalPackets++; + } } + +SingleSenderStats::SingleSenderStats() { + _totalTransitTime = 0; + _totalProcessTime = 0; + _totalLockWaitTime = 0; + _totalVoxelsInPacket = 0; + _totalPackets = 0; +} + + diff --git a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h index b461c5a664..8c7dc4837f 100644 --- a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h +++ b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h @@ -11,9 +11,36 @@ #ifndef __voxel_server__VoxelServerPacketProcessor__ #define __voxel_server__VoxelServerPacketProcessor__ +#include + #include class VoxelServer; +class SingleSenderStats { +public: + SingleSenderStats(); + + uint64_t getAverateTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; } + uint64_t getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; } + uint64_t getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; } + uint64_t getTotalVoxelsProcessed() const { return _totalVoxelsInPacket; } + uint64_t getTotalPacketsProcessed() const { return _totalPackets; } + uint64_t getAverageProcessTimePerVoxel() const + { return _totalVoxelsInPacket == 0 ? 0 : _totalProcessTime / _totalVoxelsInPacket; } + uint64_t getAverageLockWaitTimePerVoxel() const + { return _totalVoxelsInPacket == 0 ? 0 : _totalLockWaitTime / _totalVoxelsInPacket; } + + uint64_t _totalTransitTime; + uint64_t _totalProcessTime; + uint64_t _totalLockWaitTime; + uint64_t _totalVoxelsInPacket; + uint64_t _totalPackets; +}; + +typedef std::map NodeToSenderStatsMap; +typedef std::map::iterator NodeToSenderStatsMapIterator; + + /// Handles processing of incoming network packets for the voxel-server. As with other ReceivedPacketProcessor classes /// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket() class VoxelServerPacketProcessor : public ReceivedPacketProcessor { @@ -33,6 +60,8 @@ public: void resetStats(); + NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; } + protected: virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); @@ -49,5 +78,6 @@ private: uint64_t _totalVoxelsInPacket; uint64_t _totalPackets; + NodeToSenderStatsMap _singleSenderStats; }; #endif // __voxel_server__VoxelServerPacketProcessor__