mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-05-01 01:44:15 +00:00
API: Add user online stats (#3637)
* add statsUserOnline bool to policy * add OnlineMap struct to stats * apply UserOnline functionality to dispatcher * add statsonline api command * fix comments * Update app/stats/online_map.go Co-authored-by: mmmray <142015632+mmmray@users.noreply.github.com> * improve AddIP * regenerate pb --------- Co-authored-by: mmmray <142015632+mmmray@users.noreply.github.com>
This commit is contained in:
parent
e3276df725
commit
2c72864935
15 changed files with 575 additions and 177 deletions
80
app/stats/online_map.go
Normal file
80
app/stats/online_map.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
package stats
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// OnlineMap is an implementation of stats.OnlineMap.
|
||||
type OnlineMap struct {
|
||||
value int
|
||||
ipList map[string]time.Time
|
||||
access sync.RWMutex
|
||||
lastCleanup time.Time
|
||||
cleanupPeriod time.Duration
|
||||
}
|
||||
|
||||
// NewOnlineMap creates a new instance of OnlineMap.
|
||||
func NewOnlineMap() *OnlineMap {
|
||||
return &OnlineMap{
|
||||
ipList: make(map[string]time.Time),
|
||||
lastCleanup: time.Now(),
|
||||
cleanupPeriod: 10 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
// Count implements stats.OnlineMap.
|
||||
func (c *OnlineMap) Count() int {
|
||||
return c.value
|
||||
}
|
||||
|
||||
// List implements stats.OnlineMap.
|
||||
func (c *OnlineMap) List() []string {
|
||||
return c.GetKeys()
|
||||
}
|
||||
|
||||
// AddIP implements stats.OnlineMap.
|
||||
func (c *OnlineMap) AddIP(ip string) {
|
||||
list := c.ipList
|
||||
|
||||
if ip == "127.0.0.1" {
|
||||
return
|
||||
}
|
||||
if _, ok := list[ip]; !ok {
|
||||
c.access.Lock()
|
||||
list[ip] = time.Now()
|
||||
c.access.Unlock()
|
||||
}
|
||||
if time.Since(c.lastCleanup) > c.cleanupPeriod {
|
||||
list = c.RemoveExpiredIPs(list)
|
||||
c.lastCleanup = time.Now()
|
||||
}
|
||||
|
||||
c.value = len(list)
|
||||
c.ipList = list
|
||||
}
|
||||
|
||||
func (c *OnlineMap) GetKeys() []string {
|
||||
c.access.RLock()
|
||||
defer c.access.RUnlock()
|
||||
|
||||
keys := []string{}
|
||||
for k := range c.ipList {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
func (c *OnlineMap) RemoveExpiredIPs(list map[string]time.Time) map[string]time.Time {
|
||||
c.access.Lock()
|
||||
defer c.access.Unlock()
|
||||
|
||||
now := time.Now()
|
||||
for k, t := range list {
|
||||
diff := now.Sub(t)
|
||||
if diff.Seconds() > 20 {
|
||||
delete(list, k)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue