manager.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package statistic
  2. import (
  3. "os"
  4. "time"
  5. "github.com/metacubex/mihomo/common/atomic"
  6. "github.com/puzpuzpuz/xsync/v3"
  7. "github.com/shirou/gopsutil/v3/process"
  8. )
  9. var DefaultManager *Manager
  10. func init() {
  11. DefaultManager = &Manager{
  12. connections: xsync.NewMapOf[string, Tracker](),
  13. uploadTemp: atomic.NewInt64(0),
  14. downloadTemp: atomic.NewInt64(0),
  15. uploadBlip: atomic.NewInt64(0),
  16. downloadBlip: atomic.NewInt64(0),
  17. uploadTotal: atomic.NewInt64(0),
  18. downloadTotal: atomic.NewInt64(0),
  19. process: &process.Process{Pid: int32(os.Getpid())},
  20. }
  21. go DefaultManager.handle()
  22. }
  23. type Manager struct {
  24. connections *xsync.MapOf[string, Tracker]
  25. uploadTemp atomic.Int64
  26. downloadTemp atomic.Int64
  27. uploadBlip atomic.Int64
  28. downloadBlip atomic.Int64
  29. uploadTotal atomic.Int64
  30. downloadTotal atomic.Int64
  31. proxyUploadTemp atomic.Int64
  32. proxyDownloadTemp atomic.Int64
  33. proxyUploadBlip atomic.Int64
  34. proxyDownloadBlip atomic.Int64
  35. proxyUploadTotal atomic.Int64
  36. proxyDownloadTotal atomic.Int64
  37. process *process.Process
  38. memory uint64
  39. }
  40. func (m *Manager) Join(c Tracker) {
  41. if DefaultRequestNotify != nil {
  42. DefaultRequestNotify(c)
  43. }
  44. m.connections.Store(c.ID(), c)
  45. }
  46. func (m *Manager) Leave(c Tracker) {
  47. m.connections.Delete(c.ID())
  48. }
  49. func (m *Manager) Get(id string) (c Tracker) {
  50. if value, ok := m.connections.Load(id); ok {
  51. c = value
  52. }
  53. return
  54. }
  55. func (m *Manager) Range(f func(c Tracker) bool) {
  56. m.connections.Range(func(key string, value Tracker) bool {
  57. return f(value)
  58. })
  59. }
  60. func (m *Manager) PushUploaded(lastChain string, size int64) {
  61. if lastChain != "DIRECT" {
  62. m.proxyUploadTemp.Add(size)
  63. m.proxyUploadTotal.Add(size)
  64. }
  65. m.uploadTemp.Add(size)
  66. m.uploadTotal.Add(size)
  67. }
  68. func (m *Manager) PushDownloaded(lastChain string, size int64) {
  69. if lastChain != "DIRECT" {
  70. m.proxyDownloadTemp.Add(size)
  71. m.proxyDownloadTotal.Add(size)
  72. }
  73. m.downloadTemp.Add(size)
  74. m.downloadTotal.Add(size)
  75. }
  76. func (m *Manager) Now() (up int64, down int64) {
  77. return m.uploadBlip.Load(), m.downloadBlip.Load()
  78. }
  79. func (m *Manager) Memory() uint64 {
  80. m.updateMemory()
  81. return m.memory
  82. }
  83. func (m *Manager) Snapshot() *Snapshot {
  84. var connections []*TrackerInfo
  85. m.Range(func(c Tracker) bool {
  86. connections = append(connections, c.Info())
  87. return true
  88. })
  89. return &Snapshot{
  90. UploadTotal: m.uploadTotal.Load(),
  91. DownloadTotal: m.downloadTotal.Load(),
  92. Connections: connections,
  93. Memory: m.memory,
  94. }
  95. }
  96. func (m *Manager) updateMemory() {
  97. stat, err := m.process.MemoryInfo()
  98. if err != nil {
  99. return
  100. }
  101. m.memory = stat.RSS
  102. }
  103. func (m *Manager) ResetStatistic() {
  104. m.uploadTemp.Store(0)
  105. m.uploadBlip.Store(0)
  106. m.uploadTotal.Store(0)
  107. m.downloadTemp.Store(0)
  108. m.downloadBlip.Store(0)
  109. m.downloadTotal.Store(0)
  110. m.proxyUploadTemp.Store(0)
  111. m.proxyUploadBlip.Store(0)
  112. m.proxyUploadTotal.Store(0)
  113. m.proxyDownloadTemp.Store(0)
  114. m.proxyDownloadBlip.Store(0)
  115. m.proxyDownloadTotal.Store(0)
  116. }
  117. func (m *Manager) handle() {
  118. ticker := time.NewTicker(time.Second)
  119. for range ticker.C {
  120. m.uploadBlip.Store(m.uploadTemp.Load())
  121. m.uploadTemp.Store(0)
  122. m.downloadBlip.Store(m.downloadTemp.Load())
  123. m.downloadTemp.Store(0)
  124. m.proxyUploadBlip.Store(m.proxyUploadTemp.Load())
  125. m.proxyUploadTemp.Store(0)
  126. m.proxyDownloadBlip.Store(m.proxyDownloadTemp.Load())
  127. m.proxyDownloadTemp.Store(0)
  128. }
  129. }
  130. type Snapshot struct {
  131. DownloadTotal int64 `json:"downloadTotal"`
  132. UploadTotal int64 `json:"uploadTotal"`
  133. Connections []*TrackerInfo `json:"connections"`
  134. Memory uint64 `json:"memory"`
  135. }