use dashmap::DashMap; use serde::{Deserialize, Serialize}; use std::cell::UnsafeCell; use std::fmt; use std::sync::Arc; use std::time::{Duration, Instant}; use tokio::time::interval; use tokio_util::task::AbortOnDropHandle; /// Predefined metric names for type safety #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum MetricName { /// RPC calls sent to peers PeerRpcClientTx, /// RPC calls received from peers PeerRpcClientRx, /// RPC calls sent to peers PeerRpcServerTx, /// RPC calls received from peers PeerRpcServerRx, /// RPC call duration in milliseconds PeerRpcDuration, /// RPC errors PeerRpcErrors, /// Data-plane traffic bytes sent TrafficBytesTx, /// Data-plane traffic bytes sent, grouped by destination instance TrafficBytesTxByInstance, /// Data-plane traffic bytes received TrafficBytesRx, /// Data-plane traffic bytes received, grouped by source instance TrafficBytesRxByInstance, /// Control-plane traffic bytes sent TrafficControlBytesTx, /// Control-plane traffic bytes sent, grouped by destination instance TrafficControlBytesTxByInstance, /// Control-plane traffic bytes received TrafficControlBytesRx, /// Control-plane traffic bytes received, grouped by source instance TrafficControlBytesRxByInstance, /// Traffic bytes forwarded TrafficBytesForwarded, /// Control-plane traffic bytes forwarded TrafficControlBytesForwarded, /// Traffic bytes sent to self TrafficBytesSelfTx, /// Traffic bytes received from self TrafficBytesSelfRx, /// Traffic bytes forwarded for foreign network, rx to local TrafficBytesForeignForwardRx, /// Traffic bytes forwarded for foreign network, tx from local TrafficBytesForeignForwardTx, /// Traffic bytes forwarded for foreign network, forward TrafficBytesForeignForwardForwarded, /// Data-plane traffic packets sent TrafficPacketsTx, /// Data-plane traffic packets sent, grouped by destination instance TrafficPacketsTxByInstance, /// Data-plane traffic packets received TrafficPacketsRx, /// Data-plane traffic packets received, grouped by source instance TrafficPacketsRxByInstance, /// Control-plane traffic packets sent TrafficControlPacketsTx, /// Control-plane traffic packets sent, grouped by destination instance TrafficControlPacketsTxByInstance, /// Control-plane traffic packets received TrafficControlPacketsRx, /// Control-plane traffic packets received, grouped by source instance TrafficControlPacketsRxByInstance, /// Traffic packets forwarded TrafficPacketsForwarded, /// Control-plane traffic packets forwarded TrafficControlPacketsForwarded, /// Traffic packets sent to self TrafficPacketsSelfTx, /// Traffic packets received from self TrafficPacketsSelfRx, /// Traffic packets forwarded for foreign network, rx to local TrafficPacketsForeignForwardRx, /// Traffic packets forwarded for foreign network, tx from local TrafficPacketsForeignForwardTx, /// Traffic packets forwarded for foreign network, forward TrafficPacketsForeignForwardForwarded, /// UDP broadcast relay packets captured from the raw socket UdpBroadcastRelayPacketsCaptured, /// UDP broadcast relay packets ignored before forwarding UdpBroadcastRelayPacketsIgnored, /// UDP broadcast relay packets forwarded UdpBroadcastRelayPacketsForwarded, /// UDP broadcast relay packets that failed to forward UdpBroadcastRelayPacketsForwardFailed, /// Compression bytes before compression CompressionBytesRxBefore, /// Compression bytes after compression CompressionBytesRxAfter, /// Compression bytes before compression CompressionBytesTxBefore, /// Compression bytes after compression CompressionBytesTxAfter, TcpProxyConnect, } impl fmt::Display for MetricName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { MetricName::PeerRpcClientTx => write!(f, "peer_rpc_client_tx"), MetricName::PeerRpcClientRx => write!(f, "peer_rpc_client_rx"), MetricName::PeerRpcServerTx => write!(f, "peer_rpc_server_tx"), MetricName::PeerRpcServerRx => write!(f, "peer_rpc_server_rx"), MetricName::PeerRpcDuration => write!(f, "peer_rpc_duration_ms"), MetricName::PeerRpcErrors => write!(f, "peer_rpc_errors"), MetricName::TrafficBytesTx => write!(f, "traffic_bytes_tx"), MetricName::TrafficBytesTxByInstance => write!(f, "traffic_bytes_tx_by_instance"), MetricName::TrafficBytesRx => write!(f, "traffic_bytes_rx"), MetricName::TrafficBytesRxByInstance => write!(f, "traffic_bytes_rx_by_instance"), MetricName::TrafficControlBytesTx => write!(f, "traffic_control_bytes_tx"), MetricName::TrafficControlBytesTxByInstance => { write!(f, "traffic_control_bytes_tx_by_instance") } MetricName::TrafficControlBytesRx => write!(f, "traffic_control_bytes_rx"), MetricName::TrafficControlBytesRxByInstance => { write!(f, "traffic_control_bytes_rx_by_instance") } MetricName::TrafficBytesForwarded => write!(f, "traffic_bytes_forwarded"), MetricName::TrafficControlBytesForwarded => { write!(f, "traffic_control_bytes_forwarded") } MetricName::TrafficBytesSelfTx => write!(f, "traffic_bytes_self_tx"), MetricName::TrafficBytesSelfRx => write!(f, "traffic_bytes_self_rx"), MetricName::TrafficBytesForeignForwardRx => { write!(f, "traffic_bytes_foreign_forward_rx") } MetricName::TrafficBytesForeignForwardTx => { write!(f, "traffic_bytes_foreign_forward_tx") } MetricName::TrafficBytesForeignForwardForwarded => { write!(f, "traffic_bytes_foreign_forward_forwarded") } MetricName::TrafficPacketsTx => write!(f, "traffic_packets_tx"), MetricName::TrafficPacketsTxByInstance => { write!(f, "traffic_packets_tx_by_instance") } MetricName::TrafficPacketsRx => write!(f, "traffic_packets_rx"), MetricName::TrafficPacketsRxByInstance => { write!(f, "traffic_packets_rx_by_instance") } MetricName::TrafficControlPacketsTx => write!(f, "traffic_control_packets_tx"), MetricName::TrafficControlPacketsTxByInstance => { write!(f, "traffic_control_packets_tx_by_instance") } MetricName::TrafficControlPacketsRx => write!(f, "traffic_control_packets_rx"), MetricName::TrafficControlPacketsRxByInstance => { write!(f, "traffic_control_packets_rx_by_instance") } MetricName::TrafficPacketsForwarded => write!(f, "traffic_packets_forwarded"), MetricName::TrafficControlPacketsForwarded => { write!(f, "traffic_control_packets_forwarded") } MetricName::TrafficPacketsSelfTx => write!(f, "traffic_packets_self_tx"), MetricName::TrafficPacketsSelfRx => write!(f, "traffic_packets_self_rx"), MetricName::TrafficPacketsForeignForwardRx => { write!(f, "traffic_packets_foreign_forward_rx") } MetricName::TrafficPacketsForeignForwardTx => { write!(f, "traffic_packets_foreign_forward_tx") } MetricName::TrafficPacketsForeignForwardForwarded => { write!(f, "traffic_packets_foreign_forward_forwarded") } MetricName::UdpBroadcastRelayPacketsCaptured => { write!(f, "udp_broadcast_relay_packets_captured") } MetricName::UdpBroadcastRelayPacketsIgnored => { write!(f, "udp_broadcast_relay_packets_ignored") } MetricName::UdpBroadcastRelayPacketsForwarded => { write!(f, "udp_broadcast_relay_packets_forwarded") } MetricName::UdpBroadcastRelayPacketsForwardFailed => { write!(f, "udp_broadcast_relay_packets_forward_failed") } MetricName::CompressionBytesRxBefore => write!(f, "compression_bytes_rx_before"), MetricName::CompressionBytesRxAfter => write!(f, "compression_bytes_rx_after"), MetricName::CompressionBytesTxBefore => write!(f, "compression_bytes_tx_before"), MetricName::CompressionBytesTxAfter => write!(f, "compression_bytes_tx_after"), MetricName::TcpProxyConnect => write!(f, "tcp_proxy_connect"), } } } /// Predefined label types for type safety #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum LabelType { /// Network Name NetworkName(String), /// Destination instance ID ToInstanceId(String), /// Source instance ID FromInstanceId(String), /// Source peer ID SrcPeerId(u32), /// Destination peer ID DstPeerId(u32), /// Service name ServiceName(String), /// Method name MethodName(String), /// Protocol type Protocol(String), /// Direction (tx/rx) Direction(String), /// Compression algorithm CompressionAlgo(String), /// Error type ErrorType(String), /// Status Status(String), /// Dst Ip DstIp(String), /// Mapped Dst Ip MappedDstIp(String), } impl fmt::Display for LabelType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { LabelType::NetworkName(name) => write!(f, "network_name={}", name), LabelType::ToInstanceId(id) => write!(f, "to_instance_id={}", id), LabelType::FromInstanceId(id) => write!(f, "from_instance_id={}", id), LabelType::SrcPeerId(id) => write!(f, "src_peer_id={}", id), LabelType::DstPeerId(id) => write!(f, "dst_peer_id={}", id), LabelType::ServiceName(name) => write!(f, "service_name={}", name), LabelType::MethodName(name) => write!(f, "method_name={}", name), LabelType::Protocol(proto) => write!(f, "protocol={}", proto), LabelType::Direction(dir) => write!(f, "direction={}", dir), LabelType::CompressionAlgo(algo) => write!(f, "compression_algo={}", algo), LabelType::ErrorType(err) => write!(f, "error_type={}", err), LabelType::Status(status) => write!(f, "status={}", status), LabelType::DstIp(ip) => write!(f, "dst_ip={}", ip), LabelType::MappedDstIp(ip) => write!(f, "mapped_dst_ip={}", ip), } } } impl LabelType { pub fn key(&self) -> &'static str { match self { LabelType::NetworkName(_) => "network_name", LabelType::ToInstanceId(_) => "to_instance_id", LabelType::FromInstanceId(_) => "from_instance_id", LabelType::SrcPeerId(_) => "src_peer_id", LabelType::DstPeerId(_) => "dst_peer_id", LabelType::ServiceName(_) => "service_name", LabelType::MethodName(_) => "method_name", LabelType::Protocol(_) => "protocol", LabelType::Direction(_) => "direction", LabelType::CompressionAlgo(_) => "compression_algo", LabelType::ErrorType(_) => "error_type", LabelType::Status(_) => "status", LabelType::DstIp(_) => "dst_ip", LabelType::MappedDstIp(_) => "mapped_dst_ip", } } pub fn value(&self) -> String { match self { LabelType::NetworkName(name) => name.clone(), LabelType::ToInstanceId(id) => id.clone(), LabelType::FromInstanceId(id) => id.clone(), LabelType::SrcPeerId(id) => id.to_string(), LabelType::DstPeerId(id) => id.to_string(), LabelType::ServiceName(name) => name.clone(), LabelType::MethodName(name) => name.clone(), LabelType::Protocol(proto) => proto.clone(), LabelType::Direction(dir) => dir.clone(), LabelType::CompressionAlgo(algo) => algo.clone(), LabelType::ErrorType(err) => err.clone(), LabelType::Status(status) => status.clone(), LabelType::DstIp(ip) => ip.clone(), LabelType::MappedDstIp(ip) => ip.clone(), } } } /// Label represents a key-value pair for metric identification #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Label { pub key: String, pub value: String, } impl Label { pub fn new(key: impl Into, value: impl Into) -> Self { Self { key: key.into(), value: value.into(), } } pub fn from_label_type(label_type: &LabelType) -> Self { Self { key: label_type.key().to_string(), value: label_type.value(), } } } /// LabelSet represents a collection of labels for a metric #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct LabelSet { labels: Vec