123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2023 Nomadic Labs, <contact@nomadic-labs.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)letnamespace=Tezos_version.Node_version.namespaceletsubsystem="p2p"letmetric~help~component~namecollector=letinfo={Prometheus.MetricInfo.name=Prometheus.MetricName.v(String.concat"_"[namespace;subsystem;component;name]);help;metric_type=Gauge;label_names=[];}inletcollect()=Prometheus.LabelSetMap.singleton[][Prometheus.Sample_set.sample(collector())]in(info,collect)letadd_metric(info,collector)=Prometheus.CollectorRegistry.(registerdefault)infocollectormoduleConnections=structletcomponent="connections"moduleStats=structletactive=ref0.letincoming=ref0.letoutgoing=ref0.letprivate_=ref0.letzero()=active:=0.;incoming:=0.;outgoing:=0.;private_:=0.endletactive_connections=metric~help:"Number of active connections"~component~name:"active"(fun()->!Stats.active)letincoming_connections=metric~help:"Number of incoming connections"~component~name:"incoming"(fun()->!Stats.incoming)letoutgoing_connections=metric~help:"Number of outgoing connections"~component~name:"outgoing"(fun()->!Stats.outgoing)letprivate_connections=metric~help:"Number of private connections"~component~name:"private"(fun()->!Stats.private_)letmetrics=[active_connections;incoming_connections;outgoing_connections;private_connections;]let()=List.iteradd_metricmetricsletcollectpool=Stats.zero();P2p_pool.Connection.iter(fun_connection->ifP2p_conn.private_nodeconnectionthenStats.private_:=!Stats.private_+.1.;Stats.active:=!Stats.active+.1.;matchP2p_conn.infoconnectionwith|{incoming=true;_}->Stats.incoming:=!Stats.incoming+.1.|{incoming=false;_}->Stats.outgoing:=!Stats.outgoing+.1.)poolendmodulePeers=structletcomponent="peers"moduleStats=structletaccepted=ref0.letrunning=ref0.letdisconnected=ref0.letzero()=accepted:=0.;running:=0.;disconnected:=0.endletaccepted_peers=metric~help:"Number of accepted connections"~component~name:"accepted"(fun()->!Stats.accepted)letrunning_peers=metric~help:"Number of running peers"~component~name:"running"(fun()->!Stats.running)letdisconnected_peers=metric~help:"Number of disconnected peers"~component~name:"disconnected"(fun()->!Stats.disconnected)letmetrics=[accepted_peers;running_peers;disconnected_peers]let()=List.iteradd_metricmetricsletcollectpool=Stats.zero();P2p_pool.Peers.iter_known(fun_info->matchinfowith|infowhenP2p_peer_state.is_acceptedinfo->Stats.accepted:=!Stats.accepted+.1.|infowhenP2p_peer_state.is_disconnectedinfo->Stats.disconnected:=!Stats.disconnected+.1.|infowhenP2p_peer_state.is_runninginfo->Stats.running:=!Stats.running+.1.|_->())poolendmodulePoints=structletcomponent="points"moduleStats=structlettrusted=ref0.letgreylisted=ref0.letaccepted=ref0.letrunning=ref0.letdisconnected=ref0.letzero()=trusted:=0.;greylisted:=0.;accepted:=0.;running:=0.;disconnected:=0.endlettrusted_points=metric~help:"Number of trusted points"~component~name:"trusted"(fun()->!Stats.trusted)letgreylisted_points=metric~help:"Number of greylisted points"~component~name:"greylisted"(fun()->!Stats.greylisted)letaccepted_points=metric~help:"Number of accepted points"~component~name:"accepted"(fun()->!Stats.accepted)letrunning_points=metric~help:"Number of running points"~component~name:"running"(fun()->!Stats.running)letdisconnected_points=metric~help:"Number of disconnected points"~component~name:"disconnected"(fun()->!Stats.disconnected)letmetrics=[trusted_points;greylisted_points;accepted_points;running_points;disconnected_points;]let()=List.iteradd_metricmetricsletcollectpool=Stats.zero();P2p_pool.Points.iter_known(fun_info->ifP2p_point_state.is_acceptedinfothenStats.accepted:=!Stats.accepted+.1.elseifP2p_point_state.is_disconnectedinfothenStats.disconnected:=!Stats.disconnected+.1.elseifP2p_point_state.is_runninginfothenStats.running:=!Stats.running+.1.;matchP2p_point_state.Info.reconnection_timeinfowith|Some_->Stats.greylisted:=!Stats.greylisted+.1.|_->())poolendmoduleNet_stats=structletcomponent="io_scheduler"letp2p_stats=refP2p_stat.emptylettotal_sent=metric~help:"Total amount of sent data (in bytes)"~component~name:"total_sent"(fun()->Int64.to_float!p2p_stats.total_sent)lettotal_recv=metric~help:"Total amount of received data"~component~name:"total_recv"(fun()->Int64.to_float!p2p_stats.total_recv)letcurrent_inflow=metric~help:"Current ingoing data rate"~component~name:"current_inflow"(fun()->float!p2p_stats.current_inflow)letcurrent_outflow=metric~help:"Current outgoing data rate"~component~name:"current_outflow"(fun()->float!p2p_stats.current_outflow)letmetrics=[total_sent;total_recv;current_inflow;current_outflow]let()=List.iteradd_metricmetricsletcollectio_scheduler=p2p_stats:=P2p_io_scheduler.global_statio_schedulerendletcollectpoolio_scheduler=Prometheus.CollectorRegistry.(register_pre_collectdefault)(fun()->Connections.collectpool;Peers.collectpool;Points.collectpool;Net_stats.collectio_scheduler)