123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- package statistic
- import (
- "os"
- "time"
- "github.com/metacubex/mihomo/common/atomic"
- "github.com/puzpuzpuz/xsync/v3"
- "github.com/shirou/gopsutil/v3/process"
- )
- var DefaultManager *Manager
- func init() {
- DefaultManager = &Manager{
- connections: xsync.NewMapOf[string, Tracker](),
- uploadTemp: atomic.NewInt64(0),
- downloadTemp: atomic.NewInt64(0),
- uploadBlip: atomic.NewInt64(0),
- downloadBlip: atomic.NewInt64(0),
- uploadTotal: atomic.NewInt64(0),
- downloadTotal: atomic.NewInt64(0),
- process: &process.Process{Pid: int32(os.Getpid())},
- }
- go DefaultManager.handle()
- }
- type Manager struct {
- connections *xsync.MapOf[string, Tracker]
- uploadTemp atomic.Int64
- downloadTemp atomic.Int64
- uploadBlip atomic.Int64
- downloadBlip atomic.Int64
- uploadTotal atomic.Int64
- downloadTotal atomic.Int64
- proxyUploadTemp atomic.Int64
- proxyDownloadTemp atomic.Int64
- proxyUploadBlip atomic.Int64
- proxyDownloadBlip atomic.Int64
- proxyUploadTotal atomic.Int64
- proxyDownloadTotal atomic.Int64
- process *process.Process
- memory uint64
- }
- func (m *Manager) Join(c Tracker) {
- if DefaultRequestNotify != nil {
- DefaultRequestNotify(c)
- }
- m.connections.Store(c.ID(), c)
- }
- func (m *Manager) Leave(c Tracker) {
- m.connections.Delete(c.ID())
- }
- func (m *Manager) Get(id string) (c Tracker) {
- if value, ok := m.connections.Load(id); ok {
- c = value
- }
- return
- }
- func (m *Manager) Range(f func(c Tracker) bool) {
- m.connections.Range(func(key string, value Tracker) bool {
- return f(value)
- })
- }
- func (m *Manager) PushUploaded(lastChain string, size int64) {
- if lastChain != "DIRECT" {
- m.proxyUploadTemp.Add(size)
- m.proxyUploadTotal.Add(size)
- }
- m.uploadTemp.Add(size)
- m.uploadTotal.Add(size)
- }
- func (m *Manager) PushDownloaded(lastChain string, size int64) {
- if lastChain != "DIRECT" {
- m.proxyDownloadTemp.Add(size)
- m.proxyDownloadTotal.Add(size)
- }
- m.downloadTemp.Add(size)
- m.downloadTotal.Add(size)
- }
- func (m *Manager) Now() (up int64, down int64) {
- return m.uploadBlip.Load(), m.downloadBlip.Load()
- }
- func (m *Manager) Memory() uint64 {
- m.updateMemory()
- return m.memory
- }
- func (m *Manager) Snapshot() *Snapshot {
- var connections []*TrackerInfo
- m.Range(func(c Tracker) bool {
- connections = append(connections, c.Info())
- return true
- })
- return &Snapshot{
- UploadTotal: m.uploadTotal.Load(),
- DownloadTotal: m.downloadTotal.Load(),
- Connections: connections,
- Memory: m.memory,
- }
- }
- func (m *Manager) updateMemory() {
- stat, err := m.process.MemoryInfo()
- if err != nil {
- return
- }
- m.memory = stat.RSS
- }
- func (m *Manager) ResetStatistic() {
- m.uploadTemp.Store(0)
- m.uploadBlip.Store(0)
- m.uploadTotal.Store(0)
- m.downloadTemp.Store(0)
- m.downloadBlip.Store(0)
- m.downloadTotal.Store(0)
- m.proxyUploadTemp.Store(0)
- m.proxyUploadBlip.Store(0)
- m.proxyUploadTotal.Store(0)
- m.proxyDownloadTemp.Store(0)
- m.proxyDownloadBlip.Store(0)
- m.proxyDownloadTotal.Store(0)
- }
- func (m *Manager) handle() {
- ticker := time.NewTicker(time.Second)
- for range ticker.C {
- m.uploadBlip.Store(m.uploadTemp.Load())
- m.uploadTemp.Store(0)
- m.downloadBlip.Store(m.downloadTemp.Load())
- m.downloadTemp.Store(0)
- m.proxyUploadBlip.Store(m.proxyUploadTemp.Load())
- m.proxyUploadTemp.Store(0)
- m.proxyDownloadBlip.Store(m.proxyDownloadTemp.Load())
- m.proxyDownloadTemp.Store(0)
- }
- }
- type Snapshot struct {
- DownloadTotal int64 `json:"downloadTotal"`
- UploadTotal int64 `json:"uploadTotal"`
- Connections []*TrackerInfo `json:"connections"`
- Memory uint64 `json:"memory"`
- }
|