gfcp_snsi.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. // Copyright © 2015 Daniel Fu <daniel820313@gmail.com>.
  2. // Copyright © 2019 Loki 'l0k18' Verloren <stalker.loki@protonmail.ch>.
  3. // Copyright © 2021 Gridfinity, LLC. <admin@gridfinity.com>.
  4. //
  5. // All rights reserved.
  6. //
  7. // All use of this code is governed by the MIT license.
  8. // The complete license is available in the LICENSE file.
  9. package gfcp // import "go.gridfinity.dev/gfcp"
  10. import (
  11. "fmt"
  12. "sync/atomic"
  13. )
  14. // Snsi == Simple Network Statistics Indicators
  15. type Snsi struct {
  16. GFcpBytesSent uint64 // Bytes sent from upper level
  17. GFcpBytesReceived uint64 // Bytes received to upper level
  18. GFcpMaxConn uint64 // Max number of connections ever reached
  19. GFcpActiveOpen uint64 // Accumulated active open connections
  20. GFcpPassiveOpen uint64 // Accumulated passive open connections
  21. GFcpNowEstablished uint64 // Current number of established connections
  22. GFcpPreInputErrors uint64 // UDP read errors reported from net.PacketConn
  23. GFcpChecksumFailures uint64 // Checksum errors from CRC32
  24. GFcpInputErrors uint64 // Packet input errors reported from GFCP
  25. GFcpInputPackets uint64 // Incoming packets count
  26. GFcpOutputPackets uint64 // Outgoing packets count
  27. GFcpInputSegments uint64 // Incoming GFCP KSegments
  28. GFcpOutputSegments uint64 // Outgoing GFCP KSegments
  29. GFcpInputBytes uint64 // UDP bytes received
  30. GFcpOutputBytes uint64 // UDP bytes sent
  31. GFcpRestransmittedSegments uint64 // Accmulated retransmited KSegments
  32. FastGFcpRestransmittedSegments uint64 // Accmulated fast retransmitted KSegments
  33. EarlyGFcpRestransmittedSegments uint64 // Accmulated early retransmitted KSegments
  34. GFcpLostSegments uint64 // Number of segs inferred as lost
  35. GFcpDupSegments uint64 // Number of segs duplicated
  36. GFcpFECRecovered uint64 // Correct packets recovered from FEC
  37. GFcpFailures uint64 // Incorrect packets recovered from FEC
  38. GFcpFECParityShards uint64 // FEC KSegments received
  39. GFcpFECRuntShards uint64 // Number of data shards insufficient for recovery
  40. }
  41. func newSnsi() *Snsi {
  42. return new(
  43. Snsi,
  44. )
  45. }
  46. // Header returns all field names
  47. func (
  48. s *Snsi,
  49. ) Header() []string {
  50. return []string{
  51. "GFcpBytesSent",
  52. "GFcpBytesReceived",
  53. "GFcpMaxConn",
  54. "GFcpActiveOpen",
  55. "GFcpPassiveOpen",
  56. "GFcpNowEstablished",
  57. "GFcpInputErrors",
  58. "GFcpChecksumFailures",
  59. "GFcpInputErrors",
  60. "GFcpInputPackets",
  61. "GFcpOutputPackets",
  62. "GFcpInputSegments",
  63. "GFcpOutputSegments",
  64. "GFcpInputBytes",
  65. "GFcpOutputBytes",
  66. "GFcpRestransmittedSegments",
  67. "FastGFcpRestransmittedSegments",
  68. "EarlyGFcpRestransmittedSegments",
  69. "GFcpLostSegments",
  70. "GFcpDupSegments",
  71. "GFcpFECParityShards",
  72. "GFcpFailures",
  73. "GFcpFECRecovered",
  74. "GFcpFECRuntShards",
  75. }
  76. }
  77. // ToSlice returns current Snsi info as a slice
  78. func (
  79. s *Snsi,
  80. ) ToSlice() []string {
  81. snsi := s.Copy()
  82. return []string{
  83. fmt.Sprint(
  84. snsi.GFcpBytesSent,
  85. ),
  86. fmt.Sprint(
  87. snsi.GFcpBytesReceived,
  88. ),
  89. fmt.Sprint(
  90. snsi.GFcpMaxConn,
  91. ),
  92. fmt.Sprint(
  93. snsi.GFcpActiveOpen,
  94. ),
  95. fmt.Sprint(
  96. snsi.GFcpPassiveOpen,
  97. ),
  98. fmt.Sprint(
  99. snsi.GFcpNowEstablished,
  100. ),
  101. fmt.Sprint(
  102. snsi.GFcpInputErrors,
  103. ),
  104. fmt.Sprint(
  105. snsi.GFcpChecksumFailures,
  106. ),
  107. fmt.Sprint(
  108. snsi.GFcpInputErrors,
  109. ),
  110. fmt.Sprint(
  111. snsi.GFcpInputPackets,
  112. ),
  113. fmt.Sprint(
  114. snsi.GFcpOutputPackets,
  115. ),
  116. fmt.Sprint(
  117. snsi.GFcpInputSegments,
  118. ),
  119. fmt.Sprint(
  120. snsi.GFcpOutputSegments,
  121. ),
  122. fmt.Sprint(
  123. snsi.GFcpInputBytes,
  124. ),
  125. fmt.Sprint(
  126. snsi.GFcpOutputBytes,
  127. ),
  128. fmt.Sprint(
  129. snsi.GFcpRestransmittedSegments,
  130. ),
  131. fmt.Sprint(
  132. snsi.FastGFcpRestransmittedSegments,
  133. ),
  134. fmt.Sprint(
  135. snsi.EarlyGFcpRestransmittedSegments,
  136. ),
  137. fmt.Sprint(
  138. snsi.GFcpLostSegments,
  139. ),
  140. fmt.Sprint(
  141. snsi.GFcpDupSegments,
  142. ),
  143. fmt.Sprint(
  144. snsi.GFcpFECParityShards,
  145. ),
  146. fmt.Sprint(
  147. snsi.GFcpFailures,
  148. ),
  149. fmt.Sprint(
  150. snsi.GFcpFECRecovered,
  151. ),
  152. fmt.Sprint(
  153. snsi.GFcpFECRuntShards,
  154. ),
  155. }
  156. }
  157. // Copy makes a copy of current Snsi snapshot
  158. func (
  159. s *Snsi,
  160. ) Copy() *Snsi {
  161. d := newSnsi()
  162. d.GFcpBytesSent = atomic.LoadUint64(
  163. &s.GFcpBytesSent,
  164. )
  165. d.GFcpBytesReceived = atomic.LoadUint64(
  166. &s.GFcpBytesReceived,
  167. )
  168. d.GFcpMaxConn = atomic.LoadUint64(
  169. &s.GFcpMaxConn,
  170. )
  171. d.GFcpActiveOpen = atomic.LoadUint64(
  172. &s.GFcpActiveOpen,
  173. )
  174. d.GFcpPassiveOpen = atomic.LoadUint64(
  175. &s.GFcpPassiveOpen,
  176. )
  177. d.GFcpNowEstablished = atomic.LoadUint64(
  178. &s.GFcpNowEstablished,
  179. )
  180. d.GFcpInputErrors = atomic.LoadUint64(
  181. &s.GFcpInputErrors,
  182. )
  183. d.GFcpChecksumFailures = atomic.LoadUint64(
  184. &s.GFcpChecksumFailures,
  185. )
  186. d.GFcpInputErrors = atomic.LoadUint64(
  187. &s.GFcpInputErrors,
  188. )
  189. d.GFcpInputPackets = atomic.LoadUint64(
  190. &s.GFcpInputPackets,
  191. )
  192. d.GFcpOutputPackets = atomic.LoadUint64(
  193. &s.GFcpOutputPackets,
  194. )
  195. d.GFcpInputSegments = atomic.LoadUint64(
  196. &s.GFcpInputSegments,
  197. )
  198. d.GFcpOutputSegments = atomic.LoadUint64(
  199. &s.GFcpOutputSegments,
  200. )
  201. d.GFcpInputBytes = atomic.LoadUint64(
  202. &s.GFcpInputBytes,
  203. )
  204. d.GFcpOutputBytes = atomic.LoadUint64(
  205. &s.GFcpOutputBytes,
  206. )
  207. d.GFcpRestransmittedSegments = atomic.LoadUint64(
  208. &s.GFcpRestransmittedSegments,
  209. )
  210. d.FastGFcpRestransmittedSegments = atomic.LoadUint64(
  211. &s.FastGFcpRestransmittedSegments,
  212. )
  213. d.EarlyGFcpRestransmittedSegments = atomic.LoadUint64(
  214. &s.EarlyGFcpRestransmittedSegments,
  215. )
  216. d.GFcpLostSegments = atomic.LoadUint64(
  217. &s.GFcpLostSegments,
  218. )
  219. d.GFcpDupSegments = atomic.LoadUint64(
  220. &s.GFcpDupSegments,
  221. )
  222. d.GFcpFECParityShards = atomic.LoadUint64(
  223. &s.GFcpFECParityShards,
  224. )
  225. d.GFcpFailures = atomic.LoadUint64(
  226. &s.GFcpFailures,
  227. )
  228. d.GFcpFECRecovered = atomic.LoadUint64(
  229. &s.GFcpFECRecovered,
  230. )
  231. d.GFcpFECRuntShards = atomic.LoadUint64(
  232. &s.GFcpFECRuntShards,
  233. )
  234. return d
  235. }
  236. // Reset sets all Snsi values to zero
  237. func (s *Snsi) Reset() {
  238. atomic.StoreUint64(
  239. &s.GFcpBytesSent,
  240. 0,
  241. )
  242. atomic.StoreUint64(
  243. &s.GFcpBytesReceived,
  244. 0,
  245. )
  246. atomic.StoreUint64(
  247. &s.GFcpMaxConn,
  248. 0,
  249. )
  250. atomic.StoreUint64(
  251. &s.GFcpActiveOpen,
  252. 0,
  253. )
  254. atomic.StoreUint64(
  255. &s.GFcpPassiveOpen,
  256. 0,
  257. )
  258. atomic.StoreUint64(
  259. &s.GFcpNowEstablished,
  260. 0,
  261. )
  262. atomic.StoreUint64(
  263. &s.GFcpInputErrors,
  264. 0,
  265. )
  266. atomic.StoreUint64(
  267. &s.GFcpChecksumFailures,
  268. 0,
  269. )
  270. atomic.StoreUint64(
  271. &s.GFcpInputErrors,
  272. 0,
  273. )
  274. atomic.StoreUint64(
  275. &s.GFcpInputPackets,
  276. 0,
  277. )
  278. atomic.StoreUint64(
  279. &s.GFcpOutputPackets,
  280. 0,
  281. )
  282. atomic.StoreUint64(
  283. &s.GFcpInputSegments,
  284. 0,
  285. )
  286. atomic.StoreUint64(
  287. &s.GFcpOutputSegments,
  288. 0,
  289. )
  290. atomic.StoreUint64(
  291. &s.GFcpInputBytes,
  292. 0,
  293. )
  294. atomic.StoreUint64(
  295. &s.GFcpOutputBytes,
  296. 0,
  297. )
  298. atomic.StoreUint64(
  299. &s.GFcpRestransmittedSegments,
  300. 0,
  301. )
  302. atomic.StoreUint64(
  303. &s.FastGFcpRestransmittedSegments,
  304. 0,
  305. )
  306. atomic.StoreUint64(
  307. &s.EarlyGFcpRestransmittedSegments,
  308. 0,
  309. )
  310. atomic.StoreUint64(
  311. &s.GFcpLostSegments,
  312. 0,
  313. )
  314. atomic.StoreUint64(
  315. &s.GFcpDupSegments,
  316. 0,
  317. )
  318. atomic.StoreUint64(
  319. &s.GFcpFECParityShards,
  320. 0,
  321. )
  322. atomic.StoreUint64(
  323. &s.GFcpFailures,
  324. 0,
  325. )
  326. atomic.StoreUint64(
  327. &s.GFcpFECRecovered,
  328. 0,
  329. )
  330. atomic.StoreUint64(
  331. &s.GFcpFECRuntShards,
  332. 0,
  333. )
  334. }
  335. // DefaultSnsi is the GFCP default statistics collector
  336. var (
  337. DefaultSnsi *Snsi
  338. )
  339. func init() {
  340. DefaultSnsi = newSnsi()
  341. }