From 8364a2425f8c64a343be0c0da9a369e4f3d805a7 Mon Sep 17 00:00:00 2001 From: SpyCheese Date: Fri, 4 Oct 2024 12:19:42 +0300 Subject: [PATCH] Improve overlay stats (#1242) --- overlay/overlay-manager.cpp | 23 +++- overlay/overlay-peers.cpp | 28 +++-- overlay/overlay.cpp | 85 +++++++++------ overlay/overlay.h | 6 +- overlay/overlay.hpp | 33 +++--- tl/generate/scheme/ton_api.tl | 10 +- tl/generate/scheme/ton_api.tlo | Bin 97396 -> 97708 bytes .../validator-engine-console-query.cpp | 98 ++++++++++-------- 8 files changed, 179 insertions(+), 104 deletions(-) diff --git a/overlay/overlay-manager.cpp b/overlay/overlay-manager.cpp index 878f6637a..f062cc33b 100644 --- a/overlay/overlay-manager.cpp +++ b/overlay/overlay-manager.cpp @@ -188,7 +188,7 @@ void OverlayManager::receive_message(adnl::AdnlNodeIdShort src, adnl::AdnlNodeId return; } - td::actor::send_closure(it2->second.overlay, &Overlay::update_throughput_in_ctr, src, (td::uint32)data.size(), false); + td::actor::send_closure(it2->second.overlay, &Overlay::update_throughput_in_ctr, src, data.size(), false, false); td::actor::send_closure(it2->second.overlay, &Overlay::receive_message, src, std::move(extra), std::move(data)); } @@ -225,7 +225,14 @@ void OverlayManager::receive_query(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdSh return; } - td::actor::send_closure(it2->second.overlay, &Overlay::update_throughput_in_ctr, src, (td::uint32)data.size(), true); + td::actor::send_closure(it2->second.overlay, &Overlay::update_throughput_in_ctr, src, data.size(), true, false); + promise = [overlay = it2->second.overlay.get(), promise = std::move(promise), + src](td::Result R) mutable { + if (R.is_ok()) { + td::actor::send_closure(overlay, &Overlay::update_throughput_out_ctr, src, R.ok().size(), false, true); + } + promise.set_result(std::move(R)); + }; td::actor::send_closure(it2->second.overlay, &Overlay::receive_query, src, std::move(extra), std::move(data), std::move(promise)); } @@ -243,8 +250,14 @@ void OverlayManager::send_query_via(adnl::AdnlNodeIdShort dst, adnl::AdnlNodeIdS if (it != overlays_.end()) { auto it2 = it->second.find(overlay_id); if (it2 != it->second.end()) { - td::actor::send_closure(it2->second.overlay, &Overlay::update_throughput_out_ctr, dst, (td::uint32)query.size(), - true); + td::actor::send_closure(it2->second.overlay, &Overlay::update_throughput_out_ctr, dst, query.size(), true, false); + promise = [overlay = it2->second.overlay.get(), promise = std::move(promise), + dst](td::Result R) mutable { + if (R.is_ok()) { + td::actor::send_closure(overlay, &Overlay::update_throughput_in_ctr, dst, R.ok().size(), false, true); + } + promise.set_result(std::move(R)); + }; if (!it2->second.member_certificate.empty()) { extra->flags_ |= 1; extra->certificate_ = it2->second.member_certificate.tl(); @@ -273,7 +286,7 @@ void OverlayManager::send_message_via(adnl::AdnlNodeIdShort dst, adnl::AdnlNodeI if (it != overlays_.end()) { auto it2 = it->second.find(overlay_id); if (it2 != it->second.end()) { - td::actor::send_closure(it2->second.overlay, &Overlay::update_throughput_out_ctr, dst, (td::uint32)object.size(), + td::actor::send_closure(it2->second.overlay, &Overlay::update_throughput_out_ctr, dst, object.size(), false, false); if (!it2->second.member_certificate.empty()) { // do not send certificate here, we hope that all our neighbours already know of out certificate diff --git a/overlay/overlay-peers.cpp b/overlay/overlay-peers.cpp index 532ac882c..aba62eb15 100644 --- a/overlay/overlay-peers.cpp +++ b/overlay/overlay-peers.cpp @@ -574,28 +574,40 @@ void OverlayImpl::update_peer_err_ctr(adnl::AdnlNodeIdShort peer_id, bool is_fec } } -void OverlayImpl::update_throughput_out_ctr(adnl::AdnlNodeIdShort peer_id, td::uint32 msg_size, bool is_query) { +void OverlayImpl::update_throughput_out_ctr(adnl::AdnlNodeIdShort peer_id, td::uint64 msg_size, bool is_query, + bool is_response) { auto out_peer = peer_list_.peers_.get(peer_id); if (out_peer) { - out_peer->throughput_out_bytes_ctr += msg_size; - out_peer->throughput_out_packets_ctr++; - + out_peer->traffic_ctr.add_packet(msg_size, false); + if (is_response) { + out_peer->traffic_responses_ctr.add_packet(msg_size, false); + } if (is_query) { out_peer->last_out_query_at = td::Timestamp::now(); } } + total_traffic_ctr.add_packet(msg_size, false); + if (is_response) { + total_traffic_responses_ctr.add_packet(msg_size, false); + } } -void OverlayImpl::update_throughput_in_ctr(adnl::AdnlNodeIdShort peer_id, td::uint32 msg_size, bool is_query) { +void OverlayImpl::update_throughput_in_ctr(adnl::AdnlNodeIdShort peer_id, td::uint64 msg_size, bool is_query, + bool is_response) { auto in_peer = peer_list_.peers_.get(peer_id); if (in_peer) { - in_peer->throughput_in_bytes_ctr += msg_size; - in_peer->throughput_in_packets_ctr++; - + in_peer->traffic_ctr.add_packet(msg_size, true); + if (is_response) { + in_peer->traffic_responses_ctr.add_packet(msg_size, true); + } if (is_query) { in_peer->last_in_query_at = td::Timestamp::now(); } } + total_traffic_ctr.add_packet(msg_size, true); + if (is_response) { + total_traffic_responses_ctr.add_packet(msg_size, true); + } } void OverlayImpl::update_peer_ip_str(adnl::AdnlNodeIdShort peer_id, td::string ip_str) { diff --git a/overlay/overlay.cpp b/overlay/overlay.cpp index 96e1610b2..93ae801c9 100644 --- a/overlay/overlay.cpp +++ b/overlay/overlay.cpp @@ -38,6 +38,10 @@ namespace overlay { const OverlayMemberCertificate OverlayNode::empty_certificate_{}; +static std::string overlay_actor_name(const OverlayIdFull &overlay_id) { + return PSTRING() << "overlay." << overlay_id.compute_short_id().bits256_value().to_hex().substr(0, 4); +} + td::actor::ActorOwn Overlay::create_public(td::actor::ActorId keyring, td::actor::ActorId adnl, td::actor::ActorId manager, @@ -45,11 +49,10 @@ td::actor::ActorOwn Overlay::create_public(td::actor::ActorId callback, OverlayPrivacyRules rules, td::string scope, OverlayOptions opts) { - auto R = td::actor::create_actor( - "overlay", keyring, adnl, manager, dht_node, local_id, std::move(overlay_id), OverlayType::Public, - std::vector(), std::vector(), OverlayMemberCertificate{}, std::move(callback), - std::move(rules), std::move(scope), std::move(opts)); - return td::actor::ActorOwn(std::move(R)); + return td::actor::create_actor( + overlay_actor_name(overlay_id), keyring, adnl, manager, dht_node, local_id, std::move(overlay_id), + OverlayType::Public, std::vector(), std::vector(), + OverlayMemberCertificate{}, std::move(callback), std::move(rules), std::move(scope), std::move(opts)); } td::actor::ActorOwn Overlay::create_private( @@ -57,11 +60,10 @@ td::actor::ActorOwn Overlay::create_private( td::actor::ActorId manager, td::actor::ActorId dht_node, adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, std::vector nodes, std::unique_ptr callback, OverlayPrivacyRules rules, std::string scope, OverlayOptions opts) { - auto R = td::actor::create_actor("overlay", keyring, adnl, manager, dht_node, local_id, - std::move(overlay_id), OverlayType::FixedMemberList, std::move(nodes), - std::vector(), OverlayMemberCertificate{}, - std::move(callback), std::move(rules), std::move(scope)); - return td::actor::ActorOwn(std::move(R)); + return td::actor::create_actor( + overlay_actor_name(overlay_id), keyring, adnl, manager, dht_node, local_id, std::move(overlay_id), + OverlayType::FixedMemberList, std::move(nodes), std::vector(), OverlayMemberCertificate{}, + std::move(callback), std::move(rules), std::move(scope)); } td::actor::ActorOwn Overlay::create_semiprivate( @@ -70,11 +72,10 @@ td::actor::ActorOwn Overlay::create_semiprivate( OverlayIdFull overlay_id, std::vector nodes, std::vector root_public_keys, OverlayMemberCertificate cert, std::unique_ptr callback, OverlayPrivacyRules rules, std::string scope, OverlayOptions opts) { - auto R = td::actor::create_actor( - "overlay", keyring, adnl, manager, dht_node, local_id, std::move(overlay_id), OverlayType::CertificatedMembers, - std::move(nodes), std::move(root_public_keys), std::move(cert), std::move(callback), std::move(rules), - std::move(scope), std::move(opts)); - return td::actor::ActorOwn(std::move(R)); + return td::actor::create_actor(overlay_actor_name(overlay_id), keyring, adnl, manager, dht_node, + local_id, std::move(overlay_id), OverlayType::CertificatedMembers, + std::move(nodes), std::move(root_public_keys), std::move(cert), + std::move(callback), std::move(rules), std::move(scope), std::move(opts)); } OverlayImpl::OverlayImpl(td::actor::ActorId keyring, td::actor::ActorId adnl, @@ -281,17 +282,12 @@ void OverlayImpl::alarm() { auto SelfId = actor_id(this); iterate_all_peers([&](const adnl::AdnlNodeIdShort &key, OverlayPeer &peer) { - peer.throughput_out_bytes = static_cast(peer.throughput_out_bytes_ctr / t_elapsed); - peer.throughput_in_bytes = static_cast(peer.throughput_in_bytes_ctr / t_elapsed); - - peer.throughput_out_packets = static_cast(peer.throughput_out_packets_ctr / t_elapsed); - peer.throughput_in_packets = static_cast(peer.throughput_in_packets_ctr / t_elapsed); - - peer.throughput_out_bytes_ctr = 0; - peer.throughput_in_bytes_ctr = 0; - - peer.throughput_out_packets_ctr = 0; - peer.throughput_in_packets_ctr = 0; + peer.traffic = peer.traffic_ctr; + peer.traffic.normalize(t_elapsed); + peer.traffic_ctr = {}; + peer.traffic_responses = peer.traffic_responses_ctr; + peer.traffic_responses.normalize(t_elapsed); + peer.traffic_responses_ctr = {}; auto P = td::PromiseCreator::lambda([SelfId, peer_id = key](td::Result result) { result.ensure(); @@ -300,6 +296,12 @@ void OverlayImpl::alarm() { td::actor::send_closure(adnl_, &adnl::AdnlSenderInterface::get_conn_ip_str, local_id_, key, std::move(P)); }); + total_traffic = total_traffic_ctr; + total_traffic.normalize(t_elapsed); + total_traffic_ctr = {}; + total_traffic_responses = total_traffic_responses_ctr; + total_traffic_responses.normalize(t_elapsed); + total_traffic_responses_ctr = {}; update_throughput_at_ = td::Timestamp::in(50.0); last_throughput_update_ = td::Timestamp::now(); @@ -691,12 +693,8 @@ void OverlayImpl::get_stats(td::Promise(); node_obj->adnl_id_ = key.bits256_value(); - node_obj->t_out_bytes_ = peer.throughput_out_bytes; - node_obj->t_in_bytes_ = peer.throughput_in_bytes; - - node_obj->t_out_pckts_ = peer.throughput_out_packets; - node_obj->t_in_pckts_ = peer.throughput_in_packets; - + node_obj->traffic_ = peer.traffic.tl(); + node_obj->traffic_responses_ = peer.traffic_responses.tl(); node_obj->ip_addr_ = peer.ip_addr_str; node_obj->last_in_query_ = static_cast(peer.last_in_query_at.at_unix()); @@ -712,6 +710,8 @@ void OverlayImpl::get_stats(td::Promisenodes_.push_back(std::move(node_obj)); }); + res->total_traffic_ = total_traffic.tl(); + res->total_traffic_responses_ = total_traffic_responses.tl(); res->stats_.push_back( create_tl_object("neighbours_cnt", PSTRING() << neighbours_cnt())); @@ -732,6 +732,27 @@ bool OverlayImpl::has_valid_broadcast_certificate(const PublicKeyHash &source, s BroadcastCheckResult::Forbidden; } +void TrafficStats::add_packet(td::uint64 size, bool in) { + if (in) { + ++in_packets; + in_bytes += size; + } else { + ++out_packets; + out_bytes += size; + } +} + +void TrafficStats::normalize(double elapsed) { + out_bytes = static_cast(out_bytes / elapsed); + in_bytes = static_cast(in_bytes / elapsed); + out_packets = static_cast(out_packets / elapsed); + in_packets = static_cast(in_packets / elapsed); +} + +tl_object_ptr TrafficStats::tl() const { + return create_tl_object(out_bytes, in_bytes, out_packets, in_packets); +} + } // namespace overlay } // namespace ton diff --git a/overlay/overlay.h b/overlay/overlay.h index f25db206a..ce9f40d3f 100644 --- a/overlay/overlay.h +++ b/overlay/overlay.h @@ -72,8 +72,10 @@ class Overlay : public td::actor::Actor { virtual void receive_nodes_from_db(tl_object_ptr nodes) = 0; virtual void receive_nodes_from_db_v2(tl_object_ptr nodes) = 0; virtual void get_stats(td::Promise> promise) = 0; - virtual void update_throughput_out_ctr(adnl::AdnlNodeIdShort peer_id, td::uint32 msg_size, bool is_query) = 0; - virtual void update_throughput_in_ctr(adnl::AdnlNodeIdShort peer_id, td::uint32 msg_size, bool is_query) = 0; + virtual void update_throughput_out_ctr(adnl::AdnlNodeIdShort peer_id, td::uint64 msg_size, bool is_query, + bool is_response) = 0; + virtual void update_throughput_in_ctr(adnl::AdnlNodeIdShort peer_id, td::uint64 msg_size, bool is_query, + bool is_response) = 0; virtual void update_peer_ip_str(adnl::AdnlNodeIdShort peer_id, td::string ip_str) = 0; virtual void update_member_certificate(OverlayMemberCertificate cert) = 0; virtual void update_root_member_list(std::vector nodes, diff --git a/overlay/overlay.hpp b/overlay/overlay.hpp index 05eaf1c40..43822c5a1 100644 --- a/overlay/overlay.hpp +++ b/overlay/overlay.hpp @@ -59,6 +59,18 @@ namespace overlay { class OverlayImpl; +struct TrafficStats { + td::uint64 out_bytes = 0; + td::uint64 in_bytes = 0; + + td::uint32 out_packets = 0; + td::uint32 in_packets = 0; + + void add_packet(td::uint64 size, bool in); + void normalize(double elapsed); + tl_object_ptr tl() const; +}; + class OverlayPeer { public: adnl::AdnlNodeIdShort get_id() const { @@ -126,17 +138,8 @@ class OverlayPeer { return node_.has_full_id(); } - td::uint32 throughput_out_bytes = 0; - td::uint32 throughput_in_bytes = 0; - - td::uint32 throughput_out_packets = 0; - td::uint32 throughput_in_packets = 0; - - td::uint32 throughput_out_bytes_ctr = 0; - td::uint32 throughput_in_bytes_ctr = 0; - - td::uint32 throughput_out_packets_ctr = 0; - td::uint32 throughput_in_packets_ctr = 0; + TrafficStats traffic, traffic_ctr; + TrafficStats traffic_responses, traffic_responses_ctr; td::uint32 broadcast_errors = 0; td::uint32 fec_broadcast_errors = 0; @@ -269,9 +272,11 @@ class OverlayImpl : public Overlay { void get_stats(td::Promise> promise) override; - void update_throughput_out_ctr(adnl::AdnlNodeIdShort peer_id, td::uint32 msg_size, bool is_query) override; + void update_throughput_out_ctr(adnl::AdnlNodeIdShort peer_id, td::uint64 msg_size, bool is_query, + bool is_response) override; - void update_throughput_in_ctr(adnl::AdnlNodeIdShort peer_id, td::uint32 msg_size, bool is_query) override; + void update_throughput_in_ctr(adnl::AdnlNodeIdShort peer_id, td::uint64 msg_size, bool is_query, + bool is_response) override; void update_peer_ip_str(adnl::AdnlNodeIdShort peer_id, td::string ip_str) override; @@ -457,6 +462,8 @@ class OverlayImpl : public Overlay { td::Timestamp local_cert_is_valid_until_; td::uint32 local_member_flags_{0}; } peer_list_; + TrafficStats total_traffic, total_traffic_ctr; + TrafficStats total_traffic_responses, total_traffic_responses_ctr; OverlayOptions opts_; }; diff --git a/tl/generate/scheme/ton_api.tl b/tl/generate/scheme/ton_api.tl index 65bdf71a8..4172bc39d 100644 --- a/tl/generate/scheme/ton_api.tl +++ b/tl/generate/scheme/ton_api.tl @@ -683,10 +683,16 @@ engine.validator.proposalVote perm_key:int256 to_send:bytes = engine.validator.P engine.validator.dhtServerStatus id:int256 status:int = engine.validator.DhtServerStatus; engine.validator.dhtServersStatus servers:(vector engine.validator.dhtServerStatus) = engine.validator.DhtServersStatus; +engine.validator.overlayStatsTraffic t_out_bytes:long t_in_bytes:long t_out_pckts:int t_in_pckts:int = engine.validator.OverlayStatsTraffic; + engine.validator.overlayStatsNode adnl_id:int256 ip_addr:string is_neighbour:Bool is_alive:Bool node_flags:int - bdcst_errors:int fec_bdcst_errors:int last_in_query:int last_out_query:int t_out_bytes:int t_in_bytes:int t_out_pckts:int t_in_pckts:int = engine.validator.OverlayStatsNode; + bdcst_errors:int fec_bdcst_errors:int last_in_query:int last_out_query:int + traffic:engine.validator.overlayStatsTraffic traffic_responses:engine.validator.overlayStatsTraffic = engine.validator.OverlayStatsNode; -engine.validator.overlayStats overlay_id:int256 overlay_id_full:PublicKey adnl_id:int256 scope:string nodes:(vector engine.validator.overlayStatsNode) stats:(vector engine.validator.oneStat) extra:string = engine.validator.OverlayStats; +engine.validator.overlayStats overlay_id:int256 overlay_id_full:PublicKey adnl_id:int256 scope:string + nodes:(vector engine.validator.overlayStatsNode) stats:(vector engine.validator.oneStat) + total_traffic:engine.validator.overlayStatsTraffic total_traffic_responses:engine.validator.overlayStatsTraffic + extra:string = engine.validator.OverlayStats; engine.validator.overlaysStats overlays:(vector engine.validator.overlayStats) = engine.validator.OverlaysStats; engine.validator.onePerfTimerStat time:int min:double avg:double max:double = engine.validator.OnePerfTimerStat; diff --git a/tl/generate/scheme/ton_api.tlo b/tl/generate/scheme/ton_api.tlo index 790d2df2f9fa64cc57cb03a0521502ec99dcedbc..70a993632c8ecbe04072d787eb979e1dc479d569 100644 GIT binary patch delta 427 zcmezJgLTbsR^CUm^{p77Kw=~BZV49euUqmbpOLU&z2tKIqT=MU60(!kB;{D2u}MU# zfOza7MTu!?naPtA8KpP7NPduIT(H^HJii#Cam6YHPLK&Vj|us3PQJKmI}6B|$vvwb ze0WRpOA>S9OCZ`Ic5>LZ9R!)o2z7$=v-_IjDC**iQi}`n^NLf8K}uliCm&dCAPTYv zs*mBS99Im)!7EqE^84kdq%tso_#k(1Z#G;L&6vuLWHZbhWP1gn@~Acoverlay_id_ << " adnl_id: " << s->adnl_id_ << " scope: " << s->scope_ << "\n"; sb << " nodes:\n"; - - td::uint32 overlay_t_out_bytes = 0; - td::uint32 overlay_t_out_pckts = 0; - td::uint32 overlay_t_in_bytes = 0; - td::uint32 overlay_t_in_pckts = 0; - + + auto print_traffic = [&](const char *name, const char *indent, + ton::tl_object_ptr &t) { + sb << indent << name << ":\n" + << indent << " out: " << t->t_out_bytes_ << " bytes/sec, " << t->t_out_pckts_ << " pckts/sec\n" + << indent << " in: " << t->t_in_bytes_ << " bytes/sec, " << t->t_in_pckts_ << " pckts/sec\n"; + }; for (auto &n : s->nodes_) { - sb << " adnl_id: " << n->adnl_id_ << " ip_addr: " << n->ip_addr_ << " broadcast_errors: " << n->bdcst_errors_ << " fec_broadcast_errors: " << n->fec_bdcst_errors_ << " last_in_query: " << n->last_in_query_ << " (" << time_to_human(n->last_in_query_) << ")" << " last_out_query: " << n->last_out_query_ << " (" << time_to_human(n->last_out_query_) << ")" << "\n throughput:\n out: " << n->t_out_bytes_ << " bytes/sec, " << n->t_out_pckts_ << " pckts/sec\n in: " << n->t_in_bytes_ << " bytes/sec, " << n->t_in_pckts_ << " pckts/sec\n"; - - overlay_t_out_bytes += n->t_out_bytes_; - overlay_t_out_pckts += n->t_out_pckts_; - - overlay_t_in_bytes += n->t_in_bytes_; - overlay_t_in_pckts += n->t_in_pckts_; + sb << " adnl_id: " << n->adnl_id_ << " ip_addr: " << n->ip_addr_ << " broadcast_errors: " << n->bdcst_errors_ + << " fec_broadcast_errors: " << n->fec_bdcst_errors_ << " last_in_query: " << n->last_in_query_ << " (" + << time_to_human(n->last_in_query_) << ")" + << " last_out_query: " << n->last_out_query_ << " (" << time_to_human(n->last_out_query_) << ")" + << "\n"; + sb << " is_neighbour: " << n->is_neighbour_ << " is_alive: " << n->is_alive_ + << " node_flags: " << n->node_flags_ << "\n"; + print_traffic("throughput", " ", n->traffic_); + print_traffic("throughput (responses only)", " ", n->traffic_responses_); } - sb << " total_throughput:\n out: " << overlay_t_out_bytes << " bytes/sec, " << overlay_t_out_pckts << " pckts/sec\n in: " << overlay_t_in_bytes << " bytes/sec, " << overlay_t_in_pckts << " pckts/sec\n"; - + print_traffic("total_throughput", " ", s->total_traffic_); + print_traffic("total_throughput (responses only)", " ", s->total_traffic_responses_); + sb << " stats:\n"; for (auto &t : s->stats_) { sb << " " << t->key_ << "\t" << t->value_ << "\n"; @@ -884,54 +888,64 @@ td::Status GetOverlaysStatsJsonQuery::receive(td::BufferSlice data) { TRY_RESULT_PREFIX(f, ton::fetch_tl_object(data.as_slice(), true), "received incorrect answer: "); std::ofstream sb(file_name_); - + sb << "[\n"; bool rtail = false; for (auto &s : f->overlays_) { - if(rtail) { + if (rtail) { sb << ",\n"; } else { rtail = true; } - - sb << "{\n \"overlay_id\": \"" << s->overlay_id_ << "\",\n \"adnl_id\": \"" << s->adnl_id_ << "\",\n \"scope\": " << s->scope_ << ",\n"; + + sb << "{\n \"overlay_id\": \"" << s->overlay_id_ << "\",\n \"adnl_id\": \"" << s->adnl_id_ + << "\",\n \"scope\": " << s->scope_ << ",\n"; sb << " \"nodes\": [\n"; - - td::uint32 overlay_t_out_bytes = 0; - td::uint32 overlay_t_out_pckts = 0; - td::uint32 overlay_t_in_bytes = 0; - td::uint32 overlay_t_in_pckts = 0; - + + auto print_traffic = [&](const char *name, + ton::tl_object_ptr &t) { + sb << "\"" << name << "\": { \"out_bytes_sec\": " << t->t_out_bytes_ << ", \"out_pckts_sec\": " << t->t_out_pckts_ + << ", \"in_bytes_sec\": " << t->t_in_bytes_ << ", \"in_pckts_sec\": " << t->t_in_pckts_ << " }"; + }; + bool tail = false; for (auto &n : s->nodes_) { - if(tail) { + if (tail) { sb << ",\n"; } else { tail = true; } - - sb << " {\n \"adnl_id\": \"" << n->adnl_id_ << "\",\n \"ip_addr\": \"" << n->ip_addr_ << "\",\n \"broadcast_errors\": " << n->bdcst_errors_ << ",\n \"fec_broadcast_errors\": " << n->fec_bdcst_errors_ << ",\n \"last_in_query_unix\": " << n->last_in_query_ << ",\n \"last_in_query_human\": \"" << time_to_human(n->last_in_query_) << "\",\n" << " \"last_out_query_unix\": " << n->last_out_query_ << ",\n \"last_out_query_human\": \"" << time_to_human(n->last_out_query_) << "\",\n" << "\n \"throughput\": { \"out_bytes_sec\": " << n->t_out_bytes_ << ", \"out_pckts_sec\": " << n->t_out_pckts_ << ", \"in_bytes_sec\": " << n->t_in_bytes_ << ", \"in_pckts_sec\": " << n->t_in_pckts_ << " }\n }"; - - overlay_t_out_bytes += n->t_out_bytes_; - overlay_t_out_pckts += n->t_out_pckts_; - - overlay_t_in_bytes += n->t_in_bytes_; - overlay_t_in_pckts += n->t_in_pckts_; + + sb << " {\n \"adnl_id\": \"" << n->adnl_id_ << "\",\n \"ip_addr\": \"" << n->ip_addr_ + << "\",\n \"broadcast_errors\": " << n->bdcst_errors_ + << ",\n \"fec_broadcast_errors\": " << n->fec_bdcst_errors_ + << ",\n \"last_in_query_unix\": " << n->last_in_query_ << ",\n \"last_in_query_human\": \"" + << time_to_human(n->last_in_query_) << "\",\n" + << " \"last_out_query_unix\": " << n->last_out_query_ << ",\n \"last_out_query_human\": \"" + << time_to_human(n->last_out_query_) << "\",\n" + << "\n "; + print_traffic("throughput", n->traffic_); + sb << ",\n "; + print_traffic("throughput_responses", n->traffic_responses_); + sb << "\n }"; } - sb << " ],\n"; - - sb << " \"total_throughput\": { \"out_bytes_sec\": " << overlay_t_out_bytes << ", \"out_pckts_sec\": " << overlay_t_out_pckts << ", \"in_bytes_sec\": " << overlay_t_in_bytes << ", \"in_pckts_sec\": " << overlay_t_in_pckts << " },\n"; - + sb << " ],\n "; + + print_traffic("total_throughput", s->total_traffic_); + sb << ",\n "; + print_traffic("total_throughput_responses", s->total_traffic_responses_); + sb << ",\n"; + sb << " \"stats\": {\n"; - + tail = false; for (auto &t : s->stats_) { - if(tail) { + if (tail) { sb << ",\n"; } else { tail = true; } - + sb << " \"" << t->key_ << "\": \"" << t->value_ << "\""; } sb << "\n }\n"; @@ -939,7 +953,7 @@ td::Status GetOverlaysStatsJsonQuery::receive(td::BufferSlice data) { } sb << "]\n"; sb << std::flush; - + td::TerminalIO::output(std::string("wrote stats to " + file_name_ + "\n")); return td::Status::OK(); }