diff --git a/include/ftl/protocol/self.hpp b/include/ftl/protocol/self.hpp index ad3ba198f5f4b41d8206314c61527a4171c6bf0a..b857418c3d7e9655b4b479efaba5786d92926e39 100644 --- a/include/ftl/protocol/self.hpp +++ b/include/ftl/protocol/self.hpp @@ -188,6 +188,11 @@ class Self { // Used for testing ftl::net::Universe *getUniverse() const { return universe_.get(); } + // === Statistics methods === + + float getKBitsPerSecondTX() const; + float getKBitsPerSecondRX() const; + // === The RPC methods === /** diff --git a/src/peer.cpp b/src/peer.cpp index cc955545b8610b1b16f6f18186305c48b5601447..5dca8e14638e22f077dd6f1c18a65d7df2fecc14 100644 --- a/src/peer.cpp +++ b/src/peer.cpp @@ -338,6 +338,8 @@ void Peer::data() { return; } + net_->rxBytes_ += rc; + // May possibly need locking recv_buf_.buffer_consumed(rc); @@ -576,6 +578,7 @@ int Peer::_send() { _close(reconnect_on_socket_error_); } + net_->txBytes_ += c; return c; } diff --git a/src/self.cpp b/src/self.cpp index 7331266f47551fef4cf639324cda99b95799879d..b0bcc6392aede0dd8739dcac28a67ca4049e4707 100644 --- a/src/self.cpp +++ b/src/self.cpp @@ -81,6 +81,14 @@ bool Self::isConnected(const std::string &s) { return universe_->isConnected(s); } +float Self::getKBitsPerSecondTX() const { + return universe_->getKBitsPerSecondTX(); +} + +float Self::getKBitsPerSecondRX() const { + return universe_->getKBitsPerSecondRX(); +} + size_t Self::numberOfNodes() const { return universe_->numberOfPeers(); } diff --git a/src/universe.cpp b/src/universe.cpp index 1b98f7bafb2cd209db20473cbe163b6699264508..50591f1e2fb04da7830ff797acdf784b1b6f1fd1 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -16,6 +16,8 @@ #define LOGURU_REPLACE_GLOG 1 #include <ftl/lib/loguru.hpp> +#include <ftl/time.hpp> + #include <nlohmann/json.hpp> #include "protocol/connection.hpp" @@ -425,6 +427,15 @@ std::list<PeerPtr> Universe::getPeers() const { } void Universe::_periodic() { + // Update stats + int64_t now = ftl::time::get_time(); + float seconds = static_cast<float>(now - stats_lastTS_) / 1000.0f; + stats_rxkbps_ = static_cast<float>(rxBytes_) / seconds / 1024.0f; + rxBytes_ = 0; + stats_txkbps_ = static_cast<float>(txBytes_) / seconds / 1024.0f; + txBytes_ = 0; + stats_lastTS_ = now; + auto i = reconnects_.begin(); while (i != reconnects_.end()) { std::string addr = i->peer->getURI(); diff --git a/src/universe.hpp b/src/universe.hpp index 1b0cc090bf6338d55add0cafd88f2282b447ca19..3e5ebeccdb5f3bd2f0a2b408555293eae6bfbeec 100644 --- a/src/universe.hpp +++ b/src/universe.hpp @@ -170,6 +170,9 @@ class Universe { void setSendBufferSize(ftl::URI::scheme_t s, size_t size); void setRecvBufferSize(ftl::URI::scheme_t s, size_t size); + float getKBitsPerSecondTX() const { return stats_txkbps_ * 8.0f; } + float getKBitsPerSecondRX() const { return stats_rxkbps_ * 8.0f; } + static inline std::shared_ptr<Universe> getInstance() { return instance_; } void setMaxConnections(size_t m); @@ -203,6 +206,13 @@ class Universe { std::unique_ptr<NetImplDetail> impl_; + // Statistics data. + float stats_txkbps_ = 0.0f; + float stats_rxkbps_ = 0.0f; + std::atomic_size_t txBytes_ = 0; + std::atomic_size_t rxBytes_ = 0; + int64_t stats_lastTS_ = 0; + std::vector<std::unique_ptr<ftl::net::internal::SocketServer>> listeners_; std::vector<ftl::net::PeerPtr> peers_; std::unordered_map<std::string, size_t> peer_by_uri_;