1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-22 10:08:15 -05:00

Merge pull request #1794 from v2fly/sysstat

add StatsService.GetSysStats
This commit is contained in:
Xiaokang Wang 2019-07-14 13:17:58 +08:00 committed by GitHub
commit 54c7483964
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 303 additions and 38 deletions

View File

@ -6,6 +6,8 @@ package command
import ( import (
"context" "context"
"runtime"
"time"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
@ -18,11 +20,15 @@ import (
// statsServer is an implementation of StatsService. // statsServer is an implementation of StatsService.
type statsServer struct { type statsServer struct {
stats feature_stats.Manager stats feature_stats.Manager
startTime time.Time
} }
func NewStatsServer(manager feature_stats.Manager) StatsServiceServer { func NewStatsServer(manager feature_stats.Manager) StatsServiceServer {
return &statsServer{stats: manager} return &statsServer{
stats: manager,
startTime: time.Now(),
}
} }
func (s *statsServer) GetStats(ctx context.Context, request *GetStatsRequest) (*GetStatsResponse, error) { func (s *statsServer) GetStats(ctx context.Context, request *GetStatsRequest) (*GetStatsResponse, error) {
@ -76,6 +82,28 @@ func (s *statsServer) QueryStats(ctx context.Context, request *QueryStatsRequest
return response, nil return response, nil
} }
func (s *statsServer) GetSysStats(ctx context.Context, request *SysStatsRequest) (*SysStatsResponse, error) {
var rtm runtime.MemStats
runtime.ReadMemStats(&rtm)
uptime := time.Since(s.startTime)
response := &SysStatsResponse{
Uptime: uint32(uptime.Seconds()),
NumGoroutine: uint32(runtime.NumGoroutine()),
Alloc: rtm.Alloc,
TotalAlloc: rtm.TotalAlloc,
Sys: rtm.Sys,
Mallocs: rtm.Mallocs,
Frees: rtm.Frees,
LiveObjects: rtm.Mallocs - rtm.Frees,
NumGC: rtm.NumGC,
PauseTotalNs: rtm.PauseTotalNs,
}
return response, nil
}
type service struct { type service struct {
statsManager feature_stats.Manager statsManager feature_stats.Manager
} }

View File

@ -1,3 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: v2ray.com/core/app/stats/command/command.proto
package command package command
import ( import (
@ -5,6 +8,8 @@ import (
fmt "fmt" fmt "fmt"
proto "github.com/golang/protobuf/proto" proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
math "math" math "math"
) )
@ -240,6 +245,148 @@ func (m *QueryStatsResponse) GetStat() []*Stat {
return nil return nil
} }
type SysStatsRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SysStatsRequest) Reset() { *m = SysStatsRequest{} }
func (m *SysStatsRequest) String() string { return proto.CompactTextString(m) }
func (*SysStatsRequest) ProtoMessage() {}
func (*SysStatsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_c902411c4948f26b, []int{5}
}
func (m *SysStatsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SysStatsRequest.Unmarshal(m, b)
}
func (m *SysStatsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SysStatsRequest.Marshal(b, m, deterministic)
}
func (m *SysStatsRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_SysStatsRequest.Merge(m, src)
}
func (m *SysStatsRequest) XXX_Size() int {
return xxx_messageInfo_SysStatsRequest.Size(m)
}
func (m *SysStatsRequest) XXX_DiscardUnknown() {
xxx_messageInfo_SysStatsRequest.DiscardUnknown(m)
}
var xxx_messageInfo_SysStatsRequest proto.InternalMessageInfo
type SysStatsResponse struct {
NumGoroutine uint32 `protobuf:"varint,1,opt,name=NumGoroutine,proto3" json:"NumGoroutine,omitempty"`
NumGC uint32 `protobuf:"varint,2,opt,name=NumGC,proto3" json:"NumGC,omitempty"`
Alloc uint64 `protobuf:"varint,3,opt,name=Alloc,proto3" json:"Alloc,omitempty"`
TotalAlloc uint64 `protobuf:"varint,4,opt,name=TotalAlloc,proto3" json:"TotalAlloc,omitempty"`
Sys uint64 `protobuf:"varint,5,opt,name=Sys,proto3" json:"Sys,omitempty"`
Mallocs uint64 `protobuf:"varint,6,opt,name=Mallocs,proto3" json:"Mallocs,omitempty"`
Frees uint64 `protobuf:"varint,7,opt,name=Frees,proto3" json:"Frees,omitempty"`
LiveObjects uint64 `protobuf:"varint,8,opt,name=LiveObjects,proto3" json:"LiveObjects,omitempty"`
PauseTotalNs uint64 `protobuf:"varint,9,opt,name=PauseTotalNs,proto3" json:"PauseTotalNs,omitempty"`
Uptime uint32 `protobuf:"varint,10,opt,name=Uptime,proto3" json:"Uptime,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SysStatsResponse) Reset() { *m = SysStatsResponse{} }
func (m *SysStatsResponse) String() string { return proto.CompactTextString(m) }
func (*SysStatsResponse) ProtoMessage() {}
func (*SysStatsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_c902411c4948f26b, []int{6}
}
func (m *SysStatsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SysStatsResponse.Unmarshal(m, b)
}
func (m *SysStatsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SysStatsResponse.Marshal(b, m, deterministic)
}
func (m *SysStatsResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_SysStatsResponse.Merge(m, src)
}
func (m *SysStatsResponse) XXX_Size() int {
return xxx_messageInfo_SysStatsResponse.Size(m)
}
func (m *SysStatsResponse) XXX_DiscardUnknown() {
xxx_messageInfo_SysStatsResponse.DiscardUnknown(m)
}
var xxx_messageInfo_SysStatsResponse proto.InternalMessageInfo
func (m *SysStatsResponse) GetNumGoroutine() uint32 {
if m != nil {
return m.NumGoroutine
}
return 0
}
func (m *SysStatsResponse) GetNumGC() uint32 {
if m != nil {
return m.NumGC
}
return 0
}
func (m *SysStatsResponse) GetAlloc() uint64 {
if m != nil {
return m.Alloc
}
return 0
}
func (m *SysStatsResponse) GetTotalAlloc() uint64 {
if m != nil {
return m.TotalAlloc
}
return 0
}
func (m *SysStatsResponse) GetSys() uint64 {
if m != nil {
return m.Sys
}
return 0
}
func (m *SysStatsResponse) GetMallocs() uint64 {
if m != nil {
return m.Mallocs
}
return 0
}
func (m *SysStatsResponse) GetFrees() uint64 {
if m != nil {
return m.Frees
}
return 0
}
func (m *SysStatsResponse) GetLiveObjects() uint64 {
if m != nil {
return m.LiveObjects
}
return 0
}
func (m *SysStatsResponse) GetPauseTotalNs() uint64 {
if m != nil {
return m.PauseTotalNs
}
return 0
}
func (m *SysStatsResponse) GetUptime() uint32 {
if m != nil {
return m.Uptime
}
return 0
}
type Config struct { type Config struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
@ -250,7 +397,7 @@ func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) } func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {} func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { func (*Config) Descriptor() ([]byte, []int) {
return fileDescriptor_c902411c4948f26b, []int{5} return fileDescriptor_c902411c4948f26b, []int{7}
} }
func (m *Config) XXX_Unmarshal(b []byte) error { func (m *Config) XXX_Unmarshal(b []byte) error {
@ -277,6 +424,8 @@ func init() {
proto.RegisterType((*GetStatsResponse)(nil), "v2ray.core.app.stats.command.GetStatsResponse") proto.RegisterType((*GetStatsResponse)(nil), "v2ray.core.app.stats.command.GetStatsResponse")
proto.RegisterType((*QueryStatsRequest)(nil), "v2ray.core.app.stats.command.QueryStatsRequest") proto.RegisterType((*QueryStatsRequest)(nil), "v2ray.core.app.stats.command.QueryStatsRequest")
proto.RegisterType((*QueryStatsResponse)(nil), "v2ray.core.app.stats.command.QueryStatsResponse") proto.RegisterType((*QueryStatsResponse)(nil), "v2ray.core.app.stats.command.QueryStatsResponse")
proto.RegisterType((*SysStatsRequest)(nil), "v2ray.core.app.stats.command.SysStatsRequest")
proto.RegisterType((*SysStatsResponse)(nil), "v2ray.core.app.stats.command.SysStatsResponse")
proto.RegisterType((*Config)(nil), "v2ray.core.app.stats.command.Config") proto.RegisterType((*Config)(nil), "v2ray.core.app.stats.command.Config")
} }
@ -285,28 +434,38 @@ func init() {
} }
var fileDescriptor_c902411c4948f26b = []byte{ var fileDescriptor_c902411c4948f26b = []byte{
// 321 bytes of a gzipped FileDescriptorProto // 488 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xb1, 0x4e, 0xc3, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x5d, 0x6f, 0xd3, 0x30,
0x10, 0x86, 0x49, 0x5b, 0xda, 0x72, 0x20, 0x01, 0x16, 0x43, 0x55, 0x75, 0x88, 0x3c, 0x75, 0xc1, 0x14, 0x5d, 0xdb, 0xac, 0xed, 0x6e, 0x37, 0xad, 0xb3, 0x10, 0xb2, 0xa6, 0x09, 0x45, 0x7e, 0xea,
0xa9, 0x82, 0xc4, 0xc2, 0x04, 0x19, 0x90, 0x50, 0x07, 0x70, 0x25, 0x06, 0x36, 0x13, 0x0e, 0x54, 0x0b, 0xce, 0x54, 0x24, 0x5e, 0x78, 0x1a, 0x91, 0x98, 0x84, 0xca, 0x18, 0x29, 0xf0, 0xc0, 0x9b,
0x41, 0x62, 0xd7, 0x76, 0x22, 0xe5, 0x95, 0x78, 0x38, 0x9e, 0x01, 0xc5, 0x49, 0x54, 0xa0, 0x6a, 0x17, 0x2e, 0x28, 0xd0, 0xc4, 0x9e, 0xed, 0x54, 0xca, 0xdf, 0xe1, 0x91, 0x1f, 0xc5, 0x6f, 0x41,
0x54, 0xa6, 0xdc, 0xc5, 0xff, 0x77, 0xf7, 0xdf, 0xd9, 0xc0, 0xf2, 0x50, 0x8b, 0x82, 0xc5, 0x32, 0x76, 0x12, 0xfa, 0x31, 0xad, 0x1b, 0x4f, 0xf5, 0x39, 0xf7, 0x9e, 0xdc, 0x73, 0xed, 0xa3, 0x02,
0x09, 0x62, 0xa9, 0x31, 0x10, 0x4a, 0x05, 0xc6, 0x0a, 0x6b, 0x82, 0x58, 0x26, 0x89, 0x48, 0x5f, 0x5f, 0x4e, 0xb5, 0xa8, 0x78, 0x2a, 0xf3, 0x28, 0x95, 0x1a, 0x23, 0xa1, 0x54, 0x64, 0xac, 0xb0,
0x9a, 0x2f, 0x53, 0x5a, 0x5a, 0x49, 0x26, 0x8d, 0x5e, 0x23, 0x13, 0x4a, 0x31, 0xa7, 0x65, 0xb5, 0x26, 0x4a, 0x65, 0x9e, 0x8b, 0xe2, 0x6b, 0xfb, 0xcb, 0x95, 0x96, 0x56, 0x92, 0xb3, 0xb6, 0x5f,
0x86, 0x5e, 0xc1, 0xf1, 0x2d, 0xda, 0x45, 0xf9, 0x8f, 0xe3, 0x2a, 0x43, 0x63, 0x09, 0x81, 0x5e, 0x23, 0x17, 0x4a, 0x71, 0xdf, 0xcb, 0x9b, 0x1e, 0xf6, 0x0a, 0x8e, 0x2f, 0xd1, 0xce, 0x1d, 0x97,
0x2a, 0x12, 0x1c, 0x79, 0xbe, 0x37, 0x3d, 0xe0, 0x2e, 0x26, 0x67, 0xb0, 0xaf, 0xd1, 0xa0, 0x1d, 0xe0, 0x6d, 0x89, 0xc6, 0x12, 0x02, 0x41, 0x21, 0x72, 0xa4, 0x9d, 0xb0, 0x33, 0x39, 0x48, 0xfc,
0x75, 0x7c, 0x6f, 0x3a, 0xe4, 0x55, 0x42, 0x67, 0xd0, 0x2b, 0xc9, 0x6d, 0x44, 0x2e, 0x3e, 0x32, 0x99, 0x3c, 0x81, 0x7d, 0x8d, 0x06, 0x2d, 0xed, 0x86, 0x9d, 0xc9, 0x30, 0xa9, 0x01, 0x3b, 0x87,
0x74, 0x44, 0x97, 0x57, 0x09, 0xbd, 0x83, 0x93, 0x75, 0x3b, 0xa3, 0x64, 0x6a, 0x90, 0x5c, 0x42, 0xc0, 0x29, 0xef, 0x53, 0x2c, 0xc5, 0xa2, 0x44, 0xaf, 0xe8, 0x25, 0x35, 0x60, 0x6f, 0x61, 0xbc,
0xaf, 0xf4, 0xe4, 0xe8, 0xc3, 0x90, 0xb2, 0x36, 0xbf, 0xac, 0x44, 0xb9, 0xd3, 0xd3, 0x08, 0x4e, 0x1a, 0x67, 0x94, 0x2c, 0x0c, 0x92, 0x97, 0x10, 0x38, 0x4f, 0x5e, 0x3d, 0x9a, 0x32, 0xbe, 0xcb,
0x1f, 0x32, 0xd4, 0xc5, 0x2f, 0xf3, 0x23, 0x18, 0x28, 0x61, 0x2d, 0xea, 0xb4, 0x76, 0xd3, 0xa4, 0x2f, 0x77, 0xd2, 0xc4, 0xf7, 0xb3, 0x18, 0x4e, 0x3e, 0x94, 0xa8, 0xab, 0x0d, 0xf3, 0x14, 0x06,
0x5b, 0x46, 0x98, 0x03, 0xf9, 0x59, 0x64, 0xc3, 0x52, 0xf7, 0x5f, 0x96, 0x86, 0xd0, 0x8f, 0x64, 0x4a, 0x58, 0x8b, 0xba, 0x68, 0xdc, 0xb4, 0xf0, 0x9e, 0x15, 0x66, 0x40, 0xd6, 0x3f, 0x72, 0xc7,
0xfa, 0xba, 0x7c, 0x0b, 0xbf, 0x3c, 0x38, 0x72, 0x35, 0x17, 0xa8, 0xf3, 0x65, 0x8c, 0xe4, 0x1d, 0x52, 0xef, 0xbf, 0x2c, 0x9d, 0xc0, 0xf1, 0xbc, 0x32, 0xeb, 0x86, 0xd8, 0xaf, 0x2e, 0x8c, 0x57,
0x86, 0xcd, 0xe4, 0xe4, 0xbc, 0xbd, 0xe0, 0x9f, 0x0b, 0x19, 0xb3, 0x5d, 0xe5, 0x95, 0x7b, 0xba, 0x5c, 0xf3, 0x7d, 0x06, 0x87, 0x57, 0x65, 0x7e, 0x29, 0xb5, 0x2c, 0x6d, 0x56, 0xd4, 0x17, 0x77,
0x47, 0x56, 0x00, 0xeb, 0xa9, 0x48, 0xd0, 0xce, 0x6f, 0x2c, 0x71, 0x3c, 0xdb, 0x1d, 0x68, 0x5a, 0x94, 0x6c, 0x70, 0xce, 0xaf, 0xc3, 0xb1, 0xf7, 0x7b, 0x94, 0xd4, 0xc0, 0xb1, 0x17, 0x8b, 0x85,
0xde, 0xcc, 0xc1, 0x8f, 0x65, 0xd2, 0x0a, 0xde, 0x7b, 0x4f, 0x83, 0x3a, 0xfc, 0xec, 0x4c, 0x1e, 0x4c, 0x69, 0x2f, 0xec, 0x4c, 0x82, 0xa4, 0x06, 0xe4, 0x19, 0xc0, 0x47, 0x69, 0xc5, 0xa2, 0x2e,
0x43, 0x2e, 0x0a, 0x16, 0x95, 0xca, 0x6b, 0xa5, 0xdc, 0x16, 0x0d, 0x8b, 0xaa, 0xe3, 0xe7, 0xbe, 0x05, 0xbe, 0xb4, 0xc6, 0x90, 0x31, 0xf4, 0xe6, 0x95, 0xa1, 0xfb, 0xbe, 0xe0, 0x8e, 0xee, 0x9e,
0x7b, 0xbb, 0x17, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x9e, 0xb8, 0xeb, 0xed, 0x02, 0x00, 0xde, 0x09, 0x57, 0x33, 0xb4, 0xef, 0xd9, 0x16, 0xba, 0x09, 0x6f, 0x34, 0xa2, 0xa1, 0x83, 0x7a,
0x00, 0x82, 0x07, 0x24, 0x84, 0xd1, 0x2c, 0x5b, 0xe2, 0xfb, 0x9b, 0x1f, 0x98, 0x5a, 0x43, 0x87, 0xbe,
0xb6, 0x4e, 0xb9, 0x9d, 0xae, 0x45, 0x69, 0xd0, 0x8f, 0xbd, 0x32, 0xf4, 0xc0, 0xb7, 0x6c, 0x70,
0xe4, 0x29, 0xf4, 0x3f, 0x29, 0x9b, 0xe5, 0x48, 0xc1, 0x2f, 0xd5, 0x20, 0x36, 0x84, 0x7e, 0x2c,
0x8b, 0x6f, 0xd9, 0xf7, 0xe9, 0x9f, 0x2e, 0x1c, 0xfa, 0xbb, 0x9a, 0xa3, 0x5e, 0x66, 0x29, 0x92,
0x9f, 0x30, 0x6c, 0x13, 0x43, 0x9e, 0xef, 0x7e, 0x88, 0xad, 0x20, 0x9f, 0xf2, 0xc7, 0xb6, 0xd7,
0xaf, 0xc2, 0xf6, 0xc8, 0x2d, 0xc0, 0x2a, 0x0d, 0x24, 0xda, 0xad, 0xbf, 0x13, 0xbe, 0xd3, 0xf3,
0xc7, 0x0b, 0xfe, 0x8d, 0x2c, 0x60, 0xe4, 0x8c, 0x34, 0x09, 0x79, 0x68, 0xc5, 0xad, 0x74, 0x3d,
0xb4, 0xe2, 0x76, 0xf0, 0xd8, 0xde, 0xeb, 0x19, 0x84, 0xa9, 0xcc, 0x77, 0xca, 0xae, 0x3b, 0x5f,
0x06, 0xcd, 0xf1, 0x77, 0xf7, 0xec, 0xf3, 0x34, 0x11, 0x15, 0x8f, 0x5d, 0xe7, 0x85, 0x52, 0x3e,
0xed, 0x86, 0xc7, 0x75, 0xf9, 0xa6, 0xef, 0xff, 0x63, 0x5e, 0xfc, 0x0d, 0x00, 0x00, 0xff, 0xff,
0x25, 0xa8, 0x5c, 0x1b, 0x95, 0x04, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -323,6 +482,7 @@ const _ = grpc.SupportPackageIsVersion4
type StatsServiceClient interface { type StatsServiceClient interface {
GetStats(ctx context.Context, in *GetStatsRequest, opts ...grpc.CallOption) (*GetStatsResponse, error) GetStats(ctx context.Context, in *GetStatsRequest, opts ...grpc.CallOption) (*GetStatsResponse, error)
QueryStats(ctx context.Context, in *QueryStatsRequest, opts ...grpc.CallOption) (*QueryStatsResponse, error) QueryStats(ctx context.Context, in *QueryStatsRequest, opts ...grpc.CallOption) (*QueryStatsResponse, error)
GetSysStats(ctx context.Context, in *SysStatsRequest, opts ...grpc.CallOption) (*SysStatsResponse, error)
} }
type statsServiceClient struct { type statsServiceClient struct {
@ -351,10 +511,34 @@ func (c *statsServiceClient) QueryStats(ctx context.Context, in *QueryStatsReque
return out, nil return out, nil
} }
func (c *statsServiceClient) GetSysStats(ctx context.Context, in *SysStatsRequest, opts ...grpc.CallOption) (*SysStatsResponse, error) {
out := new(SysStatsResponse)
err := c.cc.Invoke(ctx, "/v2ray.core.app.stats.command.StatsService/GetSysStats", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// StatsServiceServer is the server API for StatsService service. // StatsServiceServer is the server API for StatsService service.
type StatsServiceServer interface { type StatsServiceServer interface {
GetStats(context.Context, *GetStatsRequest) (*GetStatsResponse, error) GetStats(context.Context, *GetStatsRequest) (*GetStatsResponse, error)
QueryStats(context.Context, *QueryStatsRequest) (*QueryStatsResponse, error) QueryStats(context.Context, *QueryStatsRequest) (*QueryStatsResponse, error)
GetSysStats(context.Context, *SysStatsRequest) (*SysStatsResponse, error)
}
// UnimplementedStatsServiceServer can be embedded to have forward compatible implementations.
type UnimplementedStatsServiceServer struct {
}
func (*UnimplementedStatsServiceServer) GetStats(ctx context.Context, req *GetStatsRequest) (*GetStatsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetStats not implemented")
}
func (*UnimplementedStatsServiceServer) QueryStats(ctx context.Context, req *QueryStatsRequest) (*QueryStatsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method QueryStats not implemented")
}
func (*UnimplementedStatsServiceServer) GetSysStats(ctx context.Context, req *SysStatsRequest) (*SysStatsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetSysStats not implemented")
} }
func RegisterStatsServiceServer(s *grpc.Server, srv StatsServiceServer) { func RegisterStatsServiceServer(s *grpc.Server, srv StatsServiceServer) {
@ -397,6 +581,24 @@ func _StatsService_QueryStats_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _StatsService_GetSysStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SysStatsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(StatsServiceServer).GetSysStats(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/v2ray.core.app.stats.command.StatsService/GetSysStats",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(StatsServiceServer).GetSysStats(ctx, req.(*SysStatsRequest))
}
return interceptor(ctx, in, info, handler)
}
var _StatsService_serviceDesc = grpc.ServiceDesc{ var _StatsService_serviceDesc = grpc.ServiceDesc{
ServiceName: "v2ray.core.app.stats.command.StatsService", ServiceName: "v2ray.core.app.stats.command.StatsService",
HandlerType: (*StatsServiceServer)(nil), HandlerType: (*StatsServiceServer)(nil),
@ -409,6 +611,10 @@ var _StatsService_serviceDesc = grpc.ServiceDesc{
MethodName: "QueryStats", MethodName: "QueryStats",
Handler: _StatsService_QueryStats_Handler, Handler: _StatsService_QueryStats_Handler,
}, },
{
MethodName: "GetSysStats",
Handler: _StatsService_GetSysStats_Handler,
},
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{},
Metadata: "v2ray.com/core/app/stats/command/command.proto", Metadata: "v2ray.com/core/app/stats/command/command.proto",

View File

@ -31,9 +31,26 @@ message QueryStatsResponse {
repeated Stat stat = 1; repeated Stat stat = 1;
} }
message SysStatsRequest {
}
message SysStatsResponse {
uint32 NumGoroutine = 1;
uint32 NumGC = 2;
uint64 Alloc = 3;
uint64 TotalAlloc = 4;
uint64 Sys = 5;
uint64 Mallocs = 6;
uint64 Frees = 7;
uint64 LiveObjects = 8;
uint64 PauseTotalNs = 9;
uint32 Uptime = 10;
}
service StatsService { service StatsService {
rpc GetStats(GetStatsRequest) returns (GetStatsResponse) {} rpc GetStats(GetStatsRequest) returns (GetStatsResponse) {}
rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse) {} rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse) {}
rpc GetSysStats(SysStatsRequest) returns (SysStatsResponse) {}
} }
message Config {} message Config {}

View File

@ -6,6 +6,7 @@ import (
"flag" "flag"
"fmt" "fmt"
"strings" "strings"
"time"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -31,10 +32,12 @@ func (c *ApiCommand) Description() Description {
"\tLoggerService.RestartLogger", "\tLoggerService.RestartLogger",
"\tStatsService.GetStats", "\tStatsService.GetStats",
"\tStatsService.QueryStats", "\tStatsService.QueryStats",
"API calls in this command have a timeout to the server of 3 seconds.",
"Examples:", "Examples:",
"v2ctl api --server=127.0.0.1:8080 LoggerService.RestartLogger '' ", "v2ctl api --server=127.0.0.1:8080 LoggerService.RestartLogger '' ",
"v2ctl api --server=127.0.0.1:8080 StatsService.QueryStats 'pattern: \"\" reset: false'", "v2ctl api --server=127.0.0.1:8080 StatsService.QueryStats 'pattern: \"\" reset: false'",
"v2ctl api --server=127.0.0.1:8080 StatsService.GetStats 'name: \"inbound>>>statin>>>traffic>>>downlink\" reset: false'", "v2ctl api --server=127.0.0.1:8080 StatsService.GetStats 'name: \"inbound>>>statin>>>traffic>>>downlink\" reset: false'",
"v2ctl api --server=127.0.0.1:8080 StatsService.GetSysStats ''",
}, },
} }
} }
@ -48,12 +51,6 @@ func (c *ApiCommand) Execute(args []string) error {
return err return err
} }
conn, err := grpc.Dial(*serverAddrPtr, grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
return newError("failed to dial ", *serverAddrPtr).Base(err)
}
defer conn.Close()
unnamedArgs := fs.Args() unnamedArgs := fs.Args()
if len(unnamedArgs) < 2 { if len(unnamedArgs) < 2 {
return newError("service name or request not specified.") return newError("service name or request not specified.")
@ -65,7 +62,16 @@ func (c *ApiCommand) Execute(args []string) error {
return newError("unknown service: ", service) return newError("unknown service: ", service)
} }
response, err := handler(conn, method, unnamedArgs[1]) ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
conn, err := grpc.DialContext(ctx, *serverAddrPtr, grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
return newError("failed to dial ", *serverAddrPtr).Base(err)
}
defer conn.Close()
response, err := handler(ctx, conn, method, unnamedArgs[1])
if err != nil { if err != nil {
return newError("failed to call service ", unnamedArgs[0]).Base(err) return newError("failed to call service ", unnamedArgs[0]).Base(err)
} }
@ -84,14 +90,14 @@ func getServiceMethod(s string) (string, string) {
return service, method return service, method
} }
type serviceHandler func(conn *grpc.ClientConn, method string, request string) (string, error) type serviceHandler func(ctx context.Context, conn *grpc.ClientConn, method string, request string) (string, error)
var serivceHandlerMap = map[string]serviceHandler{ var serivceHandlerMap = map[string]serviceHandler{
"statsservice": callStatsService, "statsservice": callStatsService,
"loggerservice": callLogService, "loggerservice": callLogService,
} }
func callLogService(conn *grpc.ClientConn, method string, request string) (string, error) { func callLogService(ctx context.Context, conn *grpc.ClientConn, method string, request string) (string, error) {
client := logService.NewLoggerServiceClient(conn) client := logService.NewLoggerServiceClient(conn)
switch strings.ToLower(method) { switch strings.ToLower(method) {
@ -100,7 +106,7 @@ func callLogService(conn *grpc.ClientConn, method string, request string) (strin
if err := proto.UnmarshalText(request, r); err != nil { if err := proto.UnmarshalText(request, r); err != nil {
return "", err return "", err
} }
resp, err := client.RestartLogger(context.Background(), r) resp, err := client.RestartLogger(ctx, r)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -110,7 +116,7 @@ func callLogService(conn *grpc.ClientConn, method string, request string) (strin
} }
} }
func callStatsService(conn *grpc.ClientConn, method string, request string) (string, error) { func callStatsService(ctx context.Context, conn *grpc.ClientConn, method string, request string) (string, error) {
client := statsService.NewStatsServiceClient(conn) client := statsService.NewStatsServiceClient(conn)
switch strings.ToLower(method) { switch strings.ToLower(method) {
@ -119,7 +125,7 @@ func callStatsService(conn *grpc.ClientConn, method string, request string) (str
if err := proto.UnmarshalText(request, r); err != nil { if err := proto.UnmarshalText(request, r); err != nil {
return "", err return "", err
} }
resp, err := client.GetStats(context.Background(), r) resp, err := client.GetStats(ctx, r)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -129,7 +135,15 @@ func callStatsService(conn *grpc.ClientConn, method string, request string) (str
if err := proto.UnmarshalText(request, r); err != nil { if err := proto.UnmarshalText(request, r); err != nil {
return "", err return "", err
} }
resp, err := client.QueryStats(context.Background(), r) resp, err := client.QueryStats(ctx, r)
if err != nil {
return "", err
}
return proto.MarshalTextString(resp), nil
case "getsysstats":
// SysStatsRequest is an empty message
r := &statsService.SysStatsRequest{}
resp, err := client.GetSysStats(ctx, r)
if err != nil { if err != nil {
return "", err return "", err
} }