#pragma once #include #include #include #include #include "Address.hpp" #include "BucketMetric.hpp" #include "packets/Packet.hpp" #include "MessageRegistry.hpp" namespace tw::net { using Clock = std::chrono::steady_clock; using TimePoint = Clock::time_point; struct NetworkSendInfo { PacketType message_type; bool is_sent_by_us; Address target; TimePoint timepoint; std::span buffer; NetworkSendInfo( PacketType message_type, bool is_sent_by_us, const Address& target, const std::span buffer ) : message_type(message_type), is_sent_by_us(is_sent_by_us), target(target), timepoint(std::chrono::steady_clock::now()), buffer(buffer) { } }; class NetworkStatsLogger { private: std::vector m_backlog; std::vector m_buffer; size_t m_left, m_right; std::optional m_output; using Interval = std::chrono::seconds; BucketMetric> m_ping_metric; BucketMetric> m_outgoing; BucketMetric> m_incoming; public: NetworkStatsLogger() : m_backlog(10000, {MESSAGE_PACKET, false, Address({}, 0), {}}), m_buffer(1000000), m_left(0), m_right(0), m_ping_metric("ms", 1000), m_outgoing("b/s", 1000), m_incoming("b/s", 1000) { } void set_file_output(std::filesystem::path path); size_t get_size() { return m_right - m_left + (m_right < m_left ? m_backlog.size() : 0); } NetworkSendInfo& get_item(uint32_t idx) { return m_backlog[(m_left + idx) % m_backlog.size()]; } std::span allocate_memory_for_buffer(size_t size) { uint32_t start = m_right; if(m_buffer.size() - m_right < size) { // throw away packets from the start to make space for(; m_backlog[m_left].buffer.data() < m_buffer.data() + start + size && m_left != m_right; m_left = (m_left + 1) % m_buffer.size()) { } start = 0; } uint32_t end = start + size; return std::span(m_buffer.begin() + start, m_buffer.begin() + end); } // constexpr void log(PacketType message_type, bool is_sent, const Address& target, const ByteBuffer& content) { // std::span span = allocate_memory_for_buffer(content.size()); // memcpy(span.data(), content.data().data(), content.size()); // m_right = (m_right + 1) % m_backlog.size(); // m_backlog[m_right] = NetworkSendInfo(message_type, is_sent, target, span); // } // constexpr void log_receive( // PacketType message_type, // const Address& from // ) { // log(message_type, false, from, content); // m_incoming.push(content.size()); // } // constexpr void log_send( // PacketType message_type, // const Address& to // ) { // log(message_type, true, to, content); // m_outgoing.push(content.size()); // } void log_ping(uint32_t ping) { m_ping_metric.push(ping); } BucketMetric>& ping(){ return m_ping_metric; } BucketMetric& outgoing(){ return m_outgoing; } BucketMetric& incoming(){ return m_incoming; } }; }