github.com/geph-official/geph2@v0.22.6-0.20210211030601-f527cb59b0df/libs/kcp-go/snmp.go (about) 1 package kcp 2 3 import ( 4 "fmt" 5 "sync/atomic" 6 ) 7 8 // Snmp defines network statistics indicator 9 type Snmp struct { 10 BytesSent uint64 // bytes sent from upper level 11 BytesReceived uint64 // bytes received to upper level 12 MaxConn uint64 // max number of connections ever reached 13 ActiveOpens uint64 // accumulated active open connections 14 PassiveOpens uint64 // accumulated passive open connections 15 CurrEstab uint64 // current number of established connections 16 InErrs uint64 // UDP read errors reported from net.PacketConn 17 InCsumErrors uint64 // checksum errors from CRC32 18 KCPInErrors uint64 // packet iput errors reported from KCP 19 InPkts uint64 // incoming packets count 20 OutPkts uint64 // outgoing packets count 21 InSegs uint64 // incoming KCP segments 22 OutSegs uint64 // outgoing KCP segments 23 InBytes uint64 // UDP bytes received 24 OutBytes uint64 // UDP bytes sent 25 RetransSegs uint64 // accmulated retransmited segments 26 FastRetransSegs uint64 // accmulated fast retransmitted segments 27 EarlyRetransSegs uint64 // accmulated early retransmitted segments 28 LostSegs uint64 // number of segs infered as lost 29 RepeatSegs uint64 // number of segs duplicated 30 FECRecovered uint64 // correct packets recovered from FEC 31 FECErrs uint64 // incorrect packets recovered from FEC 32 FECParityShards uint64 // FEC segments received 33 FECShortShards uint64 // number of data shards that's not enough for recovery 34 } 35 36 func newSnmp() *Snmp { 37 return new(Snmp) 38 } 39 40 // Header returns all field names 41 func (s *Snmp) Header() []string { 42 return []string{ 43 "BytesSent", 44 "BytesReceived", 45 "MaxConn", 46 "ActiveOpens", 47 "PassiveOpens", 48 "CurrEstab", 49 "InErrs", 50 "InCsumErrors", 51 "KCPInErrors", 52 "InPkts", 53 "OutPkts", 54 "InSegs", 55 "OutSegs", 56 "InBytes", 57 "OutBytes", 58 "RetransSegs", 59 "FastRetransSegs", 60 "EarlyRetransSegs", 61 "LostSegs", 62 "RepeatSegs", 63 "FECParityShards", 64 "FECErrs", 65 "FECRecovered", 66 "FECShortShards", 67 } 68 } 69 70 // RecentLoss computes the recent pkt loss. 71 func (s *Snmp) RecentLoss() float64 { 72 retrans := atomic.LoadUint64(&s.RetransSegs) 73 total := atomic.LoadUint64(&s.OutSegs) 74 if retrans+total == 0 { 75 return 0 76 } 77 if total > 1000 { 78 atomic.StoreUint64(&s.RetransSegs, uint64(float64(retrans)*0.9)) 79 atomic.StoreUint64(&s.OutSegs, uint64(float64(total)*0.9)) 80 } 81 return 1 - float64(total)/(float64(retrans)+float64(total)) 82 } 83 84 // ToSlice returns current snmp info as slice 85 func (s *Snmp) ToSlice() []string { 86 snmp := s.Copy() 87 return []string{ 88 fmt.Sprint(snmp.BytesSent), 89 fmt.Sprint(snmp.BytesReceived), 90 fmt.Sprint(snmp.MaxConn), 91 fmt.Sprint(snmp.ActiveOpens), 92 fmt.Sprint(snmp.PassiveOpens), 93 fmt.Sprint(snmp.CurrEstab), 94 fmt.Sprint(snmp.InErrs), 95 fmt.Sprint(snmp.InCsumErrors), 96 fmt.Sprint(snmp.KCPInErrors), 97 fmt.Sprint(snmp.InPkts), 98 fmt.Sprint(snmp.OutPkts), 99 fmt.Sprint(snmp.InSegs), 100 fmt.Sprint(snmp.OutSegs), 101 fmt.Sprint(snmp.InBytes), 102 fmt.Sprint(snmp.OutBytes), 103 fmt.Sprint(snmp.RetransSegs), 104 fmt.Sprint(snmp.FastRetransSegs), 105 fmt.Sprint(snmp.EarlyRetransSegs), 106 fmt.Sprint(snmp.LostSegs), 107 fmt.Sprint(snmp.RepeatSegs), 108 fmt.Sprint(snmp.FECParityShards), 109 fmt.Sprint(snmp.FECErrs), 110 fmt.Sprint(snmp.FECRecovered), 111 fmt.Sprint(snmp.FECShortShards), 112 } 113 } 114 115 // Copy make a copy of current snmp snapshot 116 func (s *Snmp) Copy() *Snmp { 117 d := newSnmp() 118 d.BytesSent = atomic.LoadUint64(&s.BytesSent) 119 d.BytesReceived = atomic.LoadUint64(&s.BytesReceived) 120 d.MaxConn = atomic.LoadUint64(&s.MaxConn) 121 d.ActiveOpens = atomic.LoadUint64(&s.ActiveOpens) 122 d.PassiveOpens = atomic.LoadUint64(&s.PassiveOpens) 123 d.CurrEstab = atomic.LoadUint64(&s.CurrEstab) 124 d.InErrs = atomic.LoadUint64(&s.InErrs) 125 d.InCsumErrors = atomic.LoadUint64(&s.InCsumErrors) 126 d.KCPInErrors = atomic.LoadUint64(&s.KCPInErrors) 127 d.InPkts = atomic.LoadUint64(&s.InPkts) 128 d.OutPkts = atomic.LoadUint64(&s.OutPkts) 129 d.InSegs = atomic.LoadUint64(&s.InSegs) 130 d.OutSegs = atomic.LoadUint64(&s.OutSegs) 131 d.InBytes = atomic.LoadUint64(&s.InBytes) 132 d.OutBytes = atomic.LoadUint64(&s.OutBytes) 133 d.RetransSegs = atomic.LoadUint64(&s.RetransSegs) 134 d.FastRetransSegs = atomic.LoadUint64(&s.FastRetransSegs) 135 d.EarlyRetransSegs = atomic.LoadUint64(&s.EarlyRetransSegs) 136 d.LostSegs = atomic.LoadUint64(&s.LostSegs) 137 d.RepeatSegs = atomic.LoadUint64(&s.RepeatSegs) 138 d.FECParityShards = atomic.LoadUint64(&s.FECParityShards) 139 d.FECErrs = atomic.LoadUint64(&s.FECErrs) 140 d.FECRecovered = atomic.LoadUint64(&s.FECRecovered) 141 d.FECShortShards = atomic.LoadUint64(&s.FECShortShards) 142 return d 143 } 144 145 // Reset values to zero 146 func (s *Snmp) Reset() { 147 atomic.StoreUint64(&s.BytesSent, 0) 148 atomic.StoreUint64(&s.BytesReceived, 0) 149 atomic.StoreUint64(&s.MaxConn, 0) 150 atomic.StoreUint64(&s.ActiveOpens, 0) 151 atomic.StoreUint64(&s.PassiveOpens, 0) 152 atomic.StoreUint64(&s.CurrEstab, 0) 153 atomic.StoreUint64(&s.InErrs, 0) 154 atomic.StoreUint64(&s.InCsumErrors, 0) 155 atomic.StoreUint64(&s.KCPInErrors, 0) 156 atomic.StoreUint64(&s.InPkts, 0) 157 atomic.StoreUint64(&s.OutPkts, 0) 158 atomic.StoreUint64(&s.InSegs, 0) 159 atomic.StoreUint64(&s.OutSegs, 0) 160 atomic.StoreUint64(&s.InBytes, 0) 161 atomic.StoreUint64(&s.OutBytes, 0) 162 atomic.StoreUint64(&s.RetransSegs, 0) 163 atomic.StoreUint64(&s.FastRetransSegs, 0) 164 atomic.StoreUint64(&s.EarlyRetransSegs, 0) 165 atomic.StoreUint64(&s.LostSegs, 0) 166 atomic.StoreUint64(&s.RepeatSegs, 0) 167 atomic.StoreUint64(&s.FECParityShards, 0) 168 atomic.StoreUint64(&s.FECErrs, 0) 169 atomic.StoreUint64(&s.FECRecovered, 0) 170 atomic.StoreUint64(&s.FECShortShards, 0) 171 } 172 173 // DefaultSnmp is the global KCP connection statistics collector 174 var DefaultSnmp *Snmp 175 176 func init() { 177 DefaultSnmp = newSnmp() 178 }