github.com/eagleql/xray-core@v1.4.4/app/stats/command/command.go (about) 1 package command 2 3 //go:generate go run github.com/eagleql/xray-core/common/errors/errorgen 4 5 import ( 6 "context" 7 "runtime" 8 "time" 9 10 grpc "google.golang.org/grpc" 11 12 "github.com/eagleql/xray-core/app/stats" 13 "github.com/eagleql/xray-core/common" 14 "github.com/eagleql/xray-core/common/strmatcher" 15 "github.com/eagleql/xray-core/core" 16 feature_stats "github.com/eagleql/xray-core/features/stats" 17 ) 18 19 // statsServer is an implementation of StatsService. 20 type statsServer struct { 21 stats feature_stats.Manager 22 startTime time.Time 23 } 24 25 func NewStatsServer(manager feature_stats.Manager) StatsServiceServer { 26 return &statsServer{ 27 stats: manager, 28 startTime: time.Now(), 29 } 30 } 31 32 func (s *statsServer) GetStats(ctx context.Context, request *GetStatsRequest) (*GetStatsResponse, error) { 33 c := s.stats.GetCounter(request.Name) 34 if c == nil { 35 return nil, newError(request.Name, " not found.") 36 } 37 var value int64 38 if request.Reset_ { 39 value = c.Set(0) 40 } else { 41 value = c.Value() 42 } 43 return &GetStatsResponse{ 44 Stat: &Stat{ 45 Name: request.Name, 46 Value: value, 47 }, 48 }, nil 49 } 50 51 func (s *statsServer) QueryStats(ctx context.Context, request *QueryStatsRequest) (*QueryStatsResponse, error) { 52 matcher, err := strmatcher.Substr.New(request.Pattern) 53 if err != nil { 54 return nil, err 55 } 56 57 response := &QueryStatsResponse{} 58 59 manager, ok := s.stats.(*stats.Manager) 60 if !ok { 61 return nil, newError("QueryStats only works its own stats.Manager.") 62 } 63 64 manager.VisitCounters(func(name string, c feature_stats.Counter) bool { 65 if matcher.Match(name) { 66 var value int64 67 if request.Reset_ { 68 value = c.Set(0) 69 } else { 70 value = c.Value() 71 } 72 response.Stat = append(response.Stat, &Stat{ 73 Name: name, 74 Value: value, 75 }) 76 } 77 return true 78 }) 79 80 return response, nil 81 } 82 83 func (s *statsServer) GetSysStats(ctx context.Context, request *SysStatsRequest) (*SysStatsResponse, error) { 84 var rtm runtime.MemStats 85 runtime.ReadMemStats(&rtm) 86 87 uptime := time.Since(s.startTime) 88 89 response := &SysStatsResponse{ 90 Uptime: uint32(uptime.Seconds()), 91 NumGoroutine: uint32(runtime.NumGoroutine()), 92 Alloc: rtm.Alloc, 93 TotalAlloc: rtm.TotalAlloc, 94 Sys: rtm.Sys, 95 Mallocs: rtm.Mallocs, 96 Frees: rtm.Frees, 97 LiveObjects: rtm.Mallocs - rtm.Frees, 98 NumGC: rtm.NumGC, 99 PauseTotalNs: rtm.PauseTotalNs, 100 } 101 102 return response, nil 103 } 104 105 func (s *statsServer) mustEmbedUnimplementedStatsServiceServer() {} 106 107 type service struct { 108 statsManager feature_stats.Manager 109 } 110 111 func (s *service) Register(server *grpc.Server) { 112 ss := NewStatsServer(s.statsManager) 113 RegisterStatsServiceServer(server, ss) 114 115 // For compatibility purposes 116 vCoreDesc := StatsService_ServiceDesc 117 vCoreDesc.ServiceName = "v2ray.core.app.stats.command.StatsService" 118 server.RegisterService(&vCoreDesc, ss) 119 } 120 121 func init() { 122 common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) { 123 s := new(service) 124 125 core.RequireFeatures(ctx, func(sm feature_stats.Manager) { 126 s.statsManager = sm 127 }) 128 129 return s, nil 130 })) 131 }