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