Browse Source

Improve platform status

世界 2 years ago
parent
commit
6e6998dab7

+ 9 - 0
experimental/clashapi/compatible/map.go

@@ -7,6 +7,15 @@ type Map[K comparable, V any] struct {
 	m sync.Map
 }
 
+func (m *Map[K, V]) Len() int {
+	var count int
+	m.m.Range(func(key, value any) bool {
+		count++
+		return true
+	})
+	return count
+}
+
 func (m *Map[K, V]) Load(key K) (V, bool) {
 	v, ok := m.m.Load(key)
 	if !ok {

+ 4 - 0
experimental/clashapi/server.go

@@ -189,6 +189,10 @@ func (s *Server) HistoryStorage() *urltest.HistoryStorage {
 	return s.urlTestHistory
 }
 
+func (s *Server) TrafficManager() *trafficontrol.Manager {
+	return s.trafficManager
+}
+
 func (s *Server) RoutedConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, matchedRule adapter.Rule) (net.Conn, adapter.Tracker) {
 	tracker := trafficontrol.NewTCPTracker(conn, s.trafficManager, castMetadata(metadata), s.router, matchedRule)
 	return tracker, tracker

+ 8 - 0
experimental/clashapi/trafficontrol/manager.go

@@ -55,6 +55,14 @@ func (m *Manager) Now() (up int64, down int64) {
 	return m.uploadBlip.Load(), m.downloadBlip.Load()
 }
 
+func (m *Manager) Total() (up int64, down int64) {
+	return m.uploadTotal.Load(), m.downloadTotal.Load()
+}
+
+func (m *Manager) Connections() int {
+	return m.connections.Len()
+}
+
 func (m *Manager) Snapshot() *Snapshot {
 	var connections []tracker
 	m.connections.Range(func(_ string, value tracker) bool {

+ 24 - 6
experimental/libbox/command_status.go

@@ -7,22 +7,40 @@ import (
 	"time"
 
 	"github.com/sagernet/sing-box/common/dialer/conntrack"
+	"github.com/sagernet/sing-box/experimental/clashapi"
 	E "github.com/sagernet/sing/common/exceptions"
 )
 
 type StatusMessage struct {
-	Memory      int64
-	Goroutines  int32
-	Connections int32
+	Memory           int64
+	Goroutines       int32
+	ConnectionsIn    int32
+	ConnectionsOut   int32
+	TrafficAvailable bool
+	Uplink           int64
+	Downlink         int64
+	UplinkTotal      int64
+	DownlinkTotal    int64
 }
 
-func readStatus() StatusMessage {
+func (s *CommandServer) readStatus() StatusMessage {
 	var memStats runtime.MemStats
 	runtime.ReadMemStats(&memStats)
 	var message StatusMessage
 	message.Memory = int64(memStats.StackInuse + memStats.HeapInuse + memStats.HeapIdle - memStats.HeapReleased)
 	message.Goroutines = int32(runtime.NumGoroutine())
-	message.Connections = int32(conntrack.Count())
+	message.ConnectionsOut = int32(conntrack.Count())
+
+	if s.service != nil {
+		if clashServer := s.service.instance.Router().ClashServer(); clashServer != nil {
+			message.TrafficAvailable = true
+			trafficManager := clashServer.(*clashapi.Server).TrafficManager()
+			message.Uplink, message.Downlink = trafficManager.Now()
+			message.UplinkTotal, message.DownlinkTotal = trafficManager.Total()
+			message.ConnectionsIn = int32(trafficManager.Connections())
+		}
+	}
+
 	return message
 }
 
@@ -36,7 +54,7 @@ func (s *CommandServer) handleStatusConn(conn net.Conn) error {
 	defer ticker.Stop()
 	ctx := connKeepAlive(conn)
 	for {
-		err = binary.Write(conn, binary.BigEndian, readStatus())
+		err = binary.Write(conn, binary.BigEndian, s.readStatus())
 		if err != nil {
 			return err
 		}