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  }