Skip to content

Commit

Permalink
stats feature
Browse files Browse the repository at this point in the history
  • Loading branch information
DarienRaymond committed Mar 30, 2018
1 parent 24f393a commit 35e160a
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 5 deletions.
13 changes: 13 additions & 0 deletions app/stats/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package stats

import (
"context"

"v2ray.com/core/common"
)

func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewManager(ctx, config.(*Config))
}))
}
42 changes: 42 additions & 0 deletions app/stats/config.pb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package stats

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package

type Config struct {
}

func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }

func init() {
proto.RegisterType((*Config)(nil), "v2ray.core.app.stats.Config")
}

func init() { proto.RegisterFile("v2ray.com/core/app/stats/config.proto", fileDescriptor0) }

var fileDescriptor0 = []byte{
// 123 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x2d, 0x33, 0x2a, 0x4a,
0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0xd0, 0x2f,
0x2e, 0x49, 0x2c, 0x29, 0xd6, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x4c, 0xd7, 0x2b, 0x28, 0xca, 0x2f,
0xc9, 0x17, 0x12, 0x81, 0x29, 0x2b, 0x4a, 0xd5, 0x4b, 0x2c, 0x28, 0xd0, 0x03, 0x2b, 0x51, 0xe2,
0xe0, 0x62, 0x73, 0x06, 0xab, 0x72, 0xb2, 0xe2, 0x92, 0x48, 0xce, 0xcf, 0xd5, 0xc3, 0xa6, 0x2a,
0x80, 0x31, 0x8a, 0x15, 0xcc, 0x58, 0xc5, 0x24, 0x12, 0x66, 0x14, 0x94, 0x58, 0xa9, 0xe7, 0x0c,
0x92, 0x77, 0x2c, 0x28, 0xd0, 0x0b, 0x06, 0x09, 0x27, 0xb1, 0x81, 0xad, 0x30, 0x06, 0x04, 0x00,
0x00, 0xff, 0xff, 0x88, 0x24, 0xc6, 0x41, 0x8b, 0x00, 0x00, 0x00,
}
11 changes: 11 additions & 0 deletions app/stats/config.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto3";

package v2ray.core.app.stats;
option csharp_namespace = "V2Ray.Core.App.Stats";
option go_package = "stats";
option java_package = "com.v2ray.core.app.stats";
option java_multiple_files = true;

message Config {

}
5 changes: 5 additions & 0 deletions app/stats/errors.generated.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package stats

import "v2ray.com/core/common/errors"

func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App", "Stats") }
68 changes: 68 additions & 0 deletions app/stats/stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package stats

//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg stats -path App,Stats

import (
"context"
"sync"
"sync/atomic"

"v2ray.com/core"
)

type Counter struct {
value int64
}

func (c *Counter) Value() int64 {
return atomic.LoadInt64(&c.value)
}

func (c *Counter) Exchange(newValue int64) int64 {
return atomic.SwapInt64(&c.value, newValue)
}

func (c *Counter) Add(delta int64) int64 {
return atomic.AddInt64(&c.value, delta)
}

type Manager struct {
access sync.RWMutex
counters map[string]*Counter
}

func NewManager(ctx context.Context, config *Config) (*Manager, error) {
return &Manager{
counters: make(map[string]*Counter),
}, nil
}

func (m *Manager) RegisterCounter(name string) (core.StatCounter, error) {
m.access.Lock()
defer m.access.Unlock()

if _, found := m.counters[name]; found {
return nil, newError("Counter ", name, " already registered.")
}
c := new(Counter)
m.counters[name] = c
return c, nil
}

func (m *Manager) GetCounter(name string) core.StatCounter {
m.access.RLock()
defer m.access.RUnlock()

if c, found := m.counters[name]; found {
return c
}
return nil
}

func (m *Manager) Start() error {
return nil
}

func (m *Manager) Close() error {
return nil
}
15 changes: 15 additions & 0 deletions app/stats/stats_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package stats_test

import (
"testing"

"v2ray.com/core"
. "v2ray.com/core/app/stats"
. "v2ray.com/ext/assert"
)

func TestInternface(t *testing.T) {
assert := With(t)

assert((*Manager)(nil), Implements, (*core.StatManager)(nil))
}
10 changes: 6 additions & 4 deletions config.pb.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Config struct {
Inbound []*InboundHandlerConfig `protobuf:"bytes,1,rep,name=inbound" json:"inbound,omitempty"`
// Outbound handler configurations. Must have at least one item. The first item is used as default for routing.
Outbound []*OutboundHandlerConfig `protobuf:"bytes,2,rep,name=outbound" json:"outbound,omitempty"`
// App configuration. Must be one in the app directory.
// App is for configurations of all features in V2Ray. A feature must implement the Feature interface, and its config type must be registered through common.RegisterConfig.
App []*v2ray_core_common_serial.TypedMessage `protobuf:"bytes,4,rep,name=app" json:"app,omitempty"`
// Transport settings.
Transport *v2ray_core_transport.Config `protobuf:"bytes,5,opt,name=transport" json:"transport,omitempty"`
Expand Down Expand Up @@ -72,10 +72,11 @@ func (m *Config) GetExtension() []*v2ray_core_common_serial.TypedMessage {
return nil
}

// InboundHandlerConfig is the configuration for inbound handler.
type InboundHandlerConfig struct {
// Tag of the inbound handler.
// Tag of the inbound handler. The tag must be unique among all inbound handlers
Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"`
// Settings for how this inbound proxy is handled. Must be ReceiverConfig above.
// Settings for how this inbound proxy is handled.
ReceiverSettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=receiver_settings,json=receiverSettings" json:"receiver_settings,omitempty"`
// Settings for inbound proxy. Must be one of the inbound proxies.
ProxySettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings" json:"proxy_settings,omitempty"`
Expand Down Expand Up @@ -107,10 +108,11 @@ func (m *InboundHandlerConfig) GetProxySettings() *v2ray_core_common_serial.Type
return nil
}

// OutboundHandlerConfig is the configuration for outbound handler.
type OutboundHandlerConfig struct {
// Tag of this outbound handler.
Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"`
// Settings for how to dial connection for this outbound handler. Must be SenderConfig above.
// Settings for how to dial connection for this outbound handler.
SenderSettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=sender_settings,json=senderSettings" json:"sender_settings,omitempty"`
// Settings for this outbound proxy. Must be one of the outbound proxies.
ProxySettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings" json:"proxy_settings,omitempty"`
Expand Down
71 changes: 71 additions & 0 deletions stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package core

import (
"sync"
)

type StatCounter interface {
Value() int64
Exchange(int64) int64
Add(int64) int64
}

type StatManager interface {
Feature

RegisterCounter(string) (StatCounter, error)
GetCounter(string) StatCounter
}

type syncStatManager struct {
sync.RWMutex
StatManager
}

func (s *syncStatManager) Start() error {
s.RLock()
defer s.RUnlock()

if s.StatManager == nil {
return newError("StatManager not set.")
}

return s.StatManager.Start()
}

func (s *syncStatManager) Close() error {
s.RLock()
defer s.RUnlock()

if s.StatManager == nil {
return newError("StatManager not set.")
}
return s.StatManager.Close()
}

func (s *syncStatManager) RegisterCounter(name string) (StatCounter, error) {
s.RLock()
defer s.RUnlock()

if s.StatManager == nil {
return nil, newError("StatManager not set.")
}
return s.StatManager.RegisterCounter(name)
}

func (s *syncStatManager) GetCounter(name string) StatCounter {
s.RLock()
defer s.RUnlock()

if s.StatManager == nil {
return nil
}
return s.StatManager.GetCounter(name)
}

func (s *syncStatManager) Set(m StatManager) {
s.Lock()
defer s.Unlock()

s.StatManager = m
}
9 changes: 8 additions & 1 deletion v2ray.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Instance struct {
router syncRouter
ihm syncInboundHandlerManager
ohm syncOutboundHandlerManager
stats syncStatManager

access sync.Mutex
features []Feature
Expand Down Expand Up @@ -148,6 +149,8 @@ func (s *Instance) RegisterFeature(feature interface{}, instance Feature) error
s.ihm.Set(instance.(InboundHandlerManager))
case OutboundHandlerManager, *OutboundHandlerManager:
s.ohm.Set(instance.(OutboundHandlerManager))
case StatManager, *StatManager:
s.stats.Set(instance.(StatManager))
default:
s.access.Lock()
s.features = append(s.features, instance)
Expand All @@ -162,7 +165,7 @@ func (s *Instance) RegisterFeature(feature interface{}, instance Feature) error
}

func (s *Instance) allFeatures() []Feature {
return append([]Feature{s.DNSClient(), s.PolicyManager(), s.Dispatcher(), s.Router(), s.InboundHandlerManager(), s.OutboundHandlerManager()}, s.features...)
return append([]Feature{s.DNSClient(), s.PolicyManager(), s.Dispatcher(), s.Router(), s.InboundHandlerManager(), s.OutboundHandlerManager(), s.Stats()}, s.features...)
}

// GetFeature returns a feature that was registered in this Instance. Nil if not found.
Expand Down Expand Up @@ -207,3 +210,7 @@ func (s *Instance) InboundHandlerManager() InboundHandlerManager {
func (s *Instance) OutboundHandlerManager() OutboundHandlerManager {
return &(s.ohm)
}

func (s *Instance) Stats() StatManager {
return &(s.stats)
}

0 comments on commit 35e160a

Please sign in to comment.