gfcp_snsi.go 7.3 KB

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