github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/app/stats/command/command.go (about)

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