115 lines
4.7 KiB
C++
115 lines
4.7 KiB
C++
#pragma once
|
|
|
|
#include <Properties.h>
|
|
#include <protocol/Packet.h>
|
|
#include <chrono>
|
|
#include "Definitions.h"
|
|
|
|
namespace ts {
|
|
namespace server {
|
|
class TSServer;
|
|
}
|
|
|
|
namespace stats {
|
|
struct StatisticEntry {
|
|
std::atomic<int8_t> use_count{0};
|
|
std::chrono::time_point<std::chrono::system_clock> timestamp;
|
|
uint16_t size = 0;
|
|
};
|
|
|
|
struct DataSummery {
|
|
uint32_t send_minute;
|
|
uint32_t send_second;
|
|
|
|
uint32_t recv_minute;
|
|
uint32_t recv_second;
|
|
|
|
uint32_t file_recv;
|
|
uint32_t file_send;
|
|
};
|
|
|
|
struct FullReport {
|
|
uint64_t connection_packets_sent[4]{0, 0, 0, 0};
|
|
uint64_t connection_bytes_sent[4]{0, 0, 0, 0};
|
|
uint64_t connection_packets_received[4]{0, 0, 0, 0};
|
|
uint64_t connection_bytes_received[4]{0, 0, 0, 0};
|
|
|
|
uint64_t file_bytes_sent = 0;
|
|
uint64_t file_bytes_received = 0;
|
|
};
|
|
|
|
class ConnectionStatistics {
|
|
public:
|
|
struct category {
|
|
enum value {
|
|
COMMAND,
|
|
ACK,
|
|
VOICE,
|
|
UNKNOWN
|
|
};
|
|
|
|
inline static category::value from_type(const protocol::PacketTypeInfo& type){
|
|
if(type == protocol::PacketTypeInfo::Command || type == protocol::PacketTypeInfo::CommandLow)
|
|
return value::COMMAND;
|
|
else if(type == protocol::PacketTypeInfo::Ack || type == protocol::PacketTypeInfo::AckLow)
|
|
return value::ACK;
|
|
else if(type == protocol::PacketTypeInfo::Voice || type == protocol::PacketTypeInfo::VoiceWhisper)
|
|
return value::VOICE;
|
|
return value::UNKNOWN;
|
|
}
|
|
};
|
|
explicit ConnectionStatistics(const std::shared_ptr<ConnectionStatistics>& /* root */, bool /* spawn properties */);
|
|
~ConnectionStatistics();
|
|
|
|
std::shared_ptr<Properties> statistics();
|
|
|
|
inline void logIncomingPacket(const protocol::ClientPacket& packet) { this->logIncomingPacket(category::from_type(packet.type()), packet.length()); }
|
|
void logIncomingPacket(const category::value& /* category */, size_t /* length */);
|
|
inline void logOutgoingPacket(const protocol::ServerPacket& packet) { this->logOutgoingPacket(category::from_type(packet.type()), packet.length()); }
|
|
void logOutgoingPacket(const category::value& /* category */, size_t /* length */);
|
|
void logFileTransferIn(uint64_t);
|
|
void logFileTransferOut(uint64_t);
|
|
|
|
void tick();
|
|
|
|
DataSummery dataReport();
|
|
FullReport full_report();
|
|
|
|
std::pair<uint64_t, uint64_t> mark_file_bytes();
|
|
|
|
inline bool measure_bandwidths() { return this->_measure_bandwidths; }
|
|
void measure_bandwidths(bool flag) { this->_measure_bandwidths = flag; }
|
|
|
|
inline bool has_properties() { return !!this->properties; }
|
|
private:
|
|
bool _measure_bandwidths = true;
|
|
std::shared_ptr<ConnectionStatistics> handle;
|
|
std::shared_ptr<Properties> properties;
|
|
|
|
|
|
std::atomic<uint64_t> connection_packets_sent[4]{0, 0, 0, 0};
|
|
std::atomic<uint64_t> connection_bytes_sent[4]{0, 0, 0, 0};
|
|
std::atomic<uint64_t> connection_packets_received[4]{0, 0, 0, 0};
|
|
std::atomic<uint64_t> connection_bytes_received[4]{0, 0, 0, 0};
|
|
|
|
std::atomic<uint64_t> file_bytes_sent = 0;
|
|
std::atomic<uint64_t> file_bytes_received = 0;
|
|
|
|
std::atomic<uint64_t> mark_file_bytes_sent = 0;
|
|
std::atomic<uint64_t> mark_file_bytes_received = 0;
|
|
|
|
spin_lock history_lock_outgoing;
|
|
spin_lock history_lock_incoming;
|
|
std::deque<StatisticEntry*> history_file_incoming{};
|
|
std::deque<StatisticEntry*> history_file_outgoing{};
|
|
std::deque<StatisticEntry*> history_incoming{};
|
|
std::deque<StatisticEntry*> history_outgoing{};
|
|
|
|
void _log_incoming_packet(StatisticEntry */* statistics */, int8_t /* type index */);
|
|
void _log_outgoing_packet(StatisticEntry* /* statistics */, int8_t /* type index */);
|
|
|
|
void _log_incoming_file_packet(StatisticEntry */* statistics */);
|
|
void _log_outgoing_file_packet(StatisticEntry* /* statistics */);
|
|
};
|
|
}
|
|
} |