add traffic reset for stats

This commit is contained in:
ginuerzh
2024-12-24 20:11:22 +08:00
parent 914a4622fd
commit 06d993023f
41 changed files with 407 additions and 143 deletions
+7 -5
View File
@@ -31,6 +31,7 @@ import (
tls_util "github.com/go-gost/x/internal/util/tls"
"github.com/go-gost/x/metadata"
mdutil "github.com/go-gost/x/metadata/util"
xstats "github.com/go-gost/x/observer/stats"
"github.com/go-gost/x/registry"
xservice "github.com/go-gost/x/service"
"github.com/vishvananda/netns"
@@ -101,8 +102,8 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
ifce := cfg.Interface
var preUp, preDown, postUp, postDown []string
var ignoreChain bool
var pStats *stats.Stats
var observePeriod time.Duration
var pStats stats.Stats
var observerPeriod time.Duration
var netnsIn, netnsOut string
var dialTimeout time.Duration
if cfg.Metadata != nil {
@@ -123,9 +124,10 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
ignoreChain = mdutil.GetBool(md, parsing.MDKeyIgnoreChain)
if mdutil.GetBool(md, parsing.MDKeyEnableStats) {
pStats = &stats.Stats{}
pStats = xstats.NewStats(mdutil.GetBool(md, "observer.resetTraffic"))
}
observePeriod = mdutil.GetDuration(md, "observePeriod")
observerPeriod = mdutil.GetDuration(md, "observePeriod", "observer.period")
netnsIn = mdutil.GetString(md, "netns")
netnsOut = mdutil.GetString(md, "netns.out")
dialTimeout = mdutil.GetDuration(md, "dialTimeout")
@@ -318,7 +320,7 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
xservice.RecordersOption(recorders...),
xservice.StatsOption(pStats),
xservice.ObserverOption(registry.ObserverRegistry().Get(cfg.Observer)),
xservice.ObservePeriodOption(observePeriod),
xservice.ObserverPeriodOption(observerPeriod),
xservice.LoggerOption(serviceLogger),
)
+1 -1
View File
@@ -70,7 +70,7 @@ func (d *http3Dialer) Dial(ctx context.Context, addr string, opts ...dialer.Dial
Host: host,
Client: &http.Client{
// Timeout: 60 * time.Second,
Transport: &http3.RoundTripper{
Transport: &http3.Transport{
TLSClientConfig: d.options.TLSConfig,
Dial: func(ctx context.Context, adr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlyConnection, error) {
// d.options.Logger.Infof("dial: %s/%s, %s", addr, network, host)
+2 -2
View File
@@ -9,7 +9,7 @@ require (
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/gin-contrib/cors v1.7.2
github.com/gin-gonic/gin v1.10.0
github.com/go-gost/core v0.1.11
github.com/go-gost/core v0.2.0
github.com/go-gost/gosocks4 v0.0.1
github.com/go-gost/gosocks5 v0.4.2
github.com/go-gost/plugin v0.1.1
@@ -45,7 +45,7 @@ require (
github.com/zalando/go-keyring v0.2.4
golang.org/x/crypto v0.31.0
golang.org/x/exp v0.0.0-20241210194714-1829a127f884
golang.org/x/net v0.32.0
golang.org/x/net v0.33.0
golang.org/x/sys v0.28.0
golang.org/x/text v0.21.0
golang.org/x/time v0.5.0
+4 -4
View File
@@ -51,8 +51,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/go-gost/core v0.1.11 h1:7zmRx0stWrClUJM/IT/ltRQJC9wUc8f6TAj1fbBiSPs=
github.com/go-gost/core v0.1.11/go.mod h1:WGI43jOka7FAsSAwi/fSMaqxdR+E339ycb4NBGlFr6A=
github.com/go-gost/core v0.2.0 h1:hZf94DAv93iwKXXzGXBmspE5bExYcBJeLl6inL9mG6Y=
github.com/go-gost/core v0.2.0/go.mod h1:WGI43jOka7FAsSAwi/fSMaqxdR+E339ycb4NBGlFr6A=
github.com/go-gost/gosocks4 v0.0.1 h1:+k1sec8HlELuQV7rWftIkmy8UijzUt2I6t+iMPlGB2s=
github.com/go-gost/gosocks4 v0.0.1/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc=
github.com/go-gost/gosocks5 v0.4.2 h1:IianxHTkACPqCwiOAT3MHoMdSUl+SEPSRu1ikawC1Pc=
@@ -305,8 +305,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+2 -1
View File
@@ -22,6 +22,7 @@ import (
xhop "github.com/go-gost/x/hop"
resolver_util "github.com/go-gost/x/internal/util/resolver"
rate_limiter "github.com/go-gost/x/limiter/rate"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -163,7 +164,7 @@ func (h *dnsHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
+2 -1
View File
@@ -21,6 +21,7 @@ import (
"github.com/go-gost/x/internal/util/sniffing"
tls_util "github.com/go-gost/x/internal/util/tls"
rate_limiter "github.com/go-gost/x/limiter/rate"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -114,7 +115,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
}
ro.Network = network
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
+2 -1
View File
@@ -24,6 +24,7 @@ import (
tls_util "github.com/go-gost/x/internal/util/tls"
rate_limiter "github.com/go-gost/x/limiter/rate"
mdutil "github.com/go-gost/x/metadata/util"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -116,7 +117,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
}
ro.Network = network
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
+21 -6
View File
@@ -26,6 +26,7 @@ import (
"github.com/go-gost/core/limiter/traffic"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/core/recorder"
xbypass "github.com/go-gost/x/bypass"
@@ -41,6 +42,7 @@ import (
ws_util "github.com/go-gost/x/internal/util/ws"
rate_limiter "github.com/go-gost/x/limiter/rate"
traffic_wrapper "github.com/go-gost/x/limiter/traffic/wrapper"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -83,7 +85,7 @@ func (h *httpHandler) Init(md md.Metadata) error {
h.cancel = cancel
if h.options.Observer != nil {
h.stats = stats_util.NewHandlerStats(h.options.Service)
h.stats = stats_util.NewHandlerStats(h.options.Service, h.md.observerResetTraffic)
go h.observeStats(ctx)
}
@@ -143,7 +145,7 @@ func (h *httpHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler
})
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
@@ -420,7 +422,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
}
func (h *httpHandler) handleProxy(ctx context.Context, conn net.Conn, req *http.Request, ro *xrecorder.HandlerRecorderObject, log logger.Logger) error {
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
ro.Time = time.Time{}
@@ -452,7 +454,7 @@ func (h *httpHandler) handleProxy(ctx context.Context, conn net.Conn, req *http.
}
}
func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriter, req *http.Request, ro *xrecorder.HandlerRecorderObject, pStats *stats.Stats, log logger.Logger) (close bool, err error) {
func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriter, req *http.Request, ro *xrecorder.HandlerRecorderObject, pStats stats.Stats, log logger.Logger) (close bool, err error) {
close = true
ro2 := &xrecorder.HandlerRecorderObject{}
@@ -949,13 +951,26 @@ func (h *httpHandler) observeStats(ctx context.Context) {
return
}
ticker := time.NewTicker(h.md.observePeriod)
var events []observer.Event
ticker := time.NewTicker(h.md.observerPeriod)
defer ticker.Stop()
for {
select {
case <-ticker.C:
h.options.Observer.Observe(ctx, h.stats.Events())
if len(events) > 0 {
if err := h.options.Observer.Observe(ctx, events); err == nil {
events = nil
}
break
}
evs := h.stats.Events()
if err := h.options.Observer.Observe(ctx, evs); err != nil {
events = evs
}
case <-ctx.Done():
return
}
+10 -6
View File
@@ -29,9 +29,11 @@ type metadata struct {
hash string
authBasicRealm string
proxyAgent string
observePeriod time.Duration
limiterRefreshInterval time.Duration
observerPeriod time.Duration
observerResetTraffic bool
sniffing bool
sniffingTimeout time.Duration
sniffingWebsocket bool
@@ -73,14 +75,16 @@ func (h *httpHandler) parseMetadata(md mdata.Metadata) error {
h.md.hash = mdutil.GetString(md, "hash")
h.md.authBasicRealm = mdutil.GetString(md, "authBasicRealm")
h.md.observePeriod = mdutil.GetDuration(md, "observePeriod", "observer.observePeriod")
if h.md.observePeriod == 0 {
h.md.observePeriod = 5 * time.Second
h.md.observerPeriod = mdutil.GetDuration(md, "observePeriod", "observer.period", "observer.observePeriod")
if h.md.observerPeriod == 0 {
h.md.observerPeriod = 5 * time.Second
}
if h.md.observePeriod < time.Second {
h.md.observePeriod = time.Second
if h.md.observerPeriod < time.Second {
h.md.observerPeriod = time.Second
}
h.md.observerResetTraffic = mdutil.GetBool(md, "observer.resetTraffic")
h.md.limiterRefreshInterval = mdutil.GetDuration(md, "limiter.refreshInterval")
if h.md.limiterRefreshInterval == 0 {
h.md.limiterRefreshInterval = 30 * time.Second
+17 -3
View File
@@ -23,6 +23,7 @@ import (
"github.com/go-gost/core/limiter/traffic"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/core/recorder"
xbypass "github.com/go-gost/x/bypass"
@@ -72,7 +73,7 @@ func (h *http2Handler) Init(md md.Metadata) error {
h.cancel = cancel
if h.options.Observer != nil {
h.stats = stats_util.NewHandlerStats(h.options.Service)
h.stats = stats_util.NewHandlerStats(h.options.Service, h.md.observerResetTraffic)
go h.observeStats(ctx)
}
@@ -483,13 +484,26 @@ func (h *http2Handler) observeStats(ctx context.Context) {
return
}
ticker := time.NewTicker(h.md.observePeriod)
var events []observer.Event
ticker := time.NewTicker(h.md.observerPeriod)
defer ticker.Stop()
for {
select {
case <-ticker.C:
h.options.Observer.Observe(ctx, h.stats.Events())
if len(events) > 0 {
if err := h.options.Observer.Observe(ctx, events); err == nil {
events = nil
}
break
}
evs := h.stats.Events()
if err := h.options.Observer.Observe(ctx, evs); err != nil {
events = evs
}
case <-ctx.Done():
return
}
+8 -6
View File
@@ -18,7 +18,8 @@ type metadata struct {
header http.Header
hash string
authBasicRealm string
observePeriod time.Duration
observerPeriod time.Duration
observerResetTraffic bool
limiterRefreshInterval time.Duration
}
@@ -43,13 +44,14 @@ func (h *http2Handler) parseMetadata(md mdata.Metadata) error {
h.md.hash = mdutil.GetString(md, "hash")
h.md.authBasicRealm = mdutil.GetString(md, "authBasicRealm")
h.md.observePeriod = mdutil.GetDuration(md, "observePeriod", "observer.observePeriod")
if h.md.observePeriod == 0 {
h.md.observePeriod = 5 * time.Second
h.md.observerPeriod = mdutil.GetDuration(md, "observePeriod", "observer.period", "observer.observePeriod")
if h.md.observerPeriod == 0 {
h.md.observerPeriod = 5 * time.Second
}
if h.md.observePeriod < time.Second {
h.md.observePeriod = time.Second
if h.md.observerPeriod < time.Second {
h.md.observerPeriod = time.Second
}
h.md.observerResetTraffic = mdutil.GetBool(md, "observer.resetTraffic")
h.md.limiterRefreshInterval = mdutil.GetDuration(md, "limiter.refreshInterval")
if h.md.limiterRefreshInterval == 0 {
+2 -1
View File
@@ -17,6 +17,7 @@ import (
xbypass "github.com/go-gost/x/bypass"
ctxvalue "github.com/go-gost/x/ctx"
xnet "github.com/go-gost/x/internal/net"
xstats "github.com/go-gost/x/observer/stats"
"github.com/go-gost/x/internal/util/sniffing"
tls_util "github.com/go-gost/x/internal/util/tls"
rate_limiter "github.com/go-gost/x/limiter/rate"
@@ -90,7 +91,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
})
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
+2 -1
View File
@@ -15,6 +15,7 @@ import (
ctxvalue "github.com/go-gost/x/ctx"
xnet "github.com/go-gost/x/internal/net"
rate_limiter "github.com/go-gost/x/limiter/rate"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -78,7 +79,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
+19 -4
View File
@@ -11,6 +11,7 @@ import (
"github.com/go-gost/core/hop"
"github.com/go-gost/core/limiter/traffic"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/core/recorder"
"github.com/go-gost/relay"
@@ -19,6 +20,7 @@ import (
stats_util "github.com/go-gost/x/internal/util/stats"
tls_util "github.com/go-gost/x/internal/util/tls"
rate_limiter "github.com/go-gost/x/limiter/rate"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -65,7 +67,7 @@ func (h *relayHandler) Init(md md.Metadata) (err error) {
h.cancel = cancel
if h.options.Observer != nil {
h.stats = stats_util.NewHandlerStats(h.options.Service)
h.stats = stats_util.NewHandlerStats(h.options.Service, h.md.observerResetTraffic)
go h.observeStats(ctx)
}
@@ -122,7 +124,7 @@ func (h *relayHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
@@ -253,13 +255,26 @@ func (h *relayHandler) observeStats(ctx context.Context) {
return
}
ticker := time.NewTicker(h.md.observePeriod)
var events []observer.Event
ticker := time.NewTicker(h.md.observerPeriod)
defer ticker.Stop()
for {
select {
case <-ticker.C:
h.options.Observer.Observe(ctx, h.stats.Events())
if len(events) > 0 {
if err := h.options.Observer.Observe(ctx, events); err == nil {
events = nil
}
break
}
evs := h.stats.Events()
if err := h.options.Observer.Observe(ctx, evs); err != nil {
events = evs
}
case <-ctx.Done():
return
}
+10 -6
View File
@@ -21,9 +21,11 @@ type metadata struct {
noDelay bool
hash string
muxCfg *mux.Config
observePeriod time.Duration
limiterRefreshInterval time.Duration
observerPeriod time.Duration
observerResetTraffic bool
sniffing bool
sniffingTimeout time.Duration
sniffingWebsocket bool
@@ -62,14 +64,16 @@ func (h *relayHandler) parseMetadata(md mdata.Metadata) (err error) {
MaxStreamBuffer: mdutil.GetInt(md, "mux.maxStreamBuffer"),
}
h.md.observePeriod = mdutil.GetDuration(md, "observePeriod", "observer.observePeriod")
if h.md.observePeriod == 0 {
h.md.observePeriod = 5 * time.Second
h.md.observerPeriod = mdutil.GetDuration(md, "observePeriod", "observer.period", "observer.observePeriod")
if h.md.observerPeriod == 0 {
h.md.observerPeriod = 5 * time.Second
}
if h.md.observePeriod < time.Second {
h.md.observePeriod = time.Second
if h.md.observerPeriod < time.Second {
h.md.observerPeriod = time.Second
}
h.md.observerResetTraffic = mdutil.GetBool(md, "observer.resetTraffic")
h.md.limiterRefreshInterval = mdutil.GetDuration(md, "limiter.refreshInterval")
if h.md.limiterRefreshInterval == 0 {
h.md.limiterRefreshInterval = 30 * time.Second
+2 -1
View File
@@ -18,6 +18,7 @@ import (
"github.com/go-gost/x/internal/util/sniffing"
tls_util "github.com/go-gost/x/internal/util/tls"
rate_limiter "github.com/go-gost/x/limiter/rate"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -96,7 +97,7 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
})
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
+19 -4
View File
@@ -14,6 +14,7 @@ import (
"github.com/go-gost/core/limiter/traffic"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/core/recorder"
"github.com/go-gost/gosocks4"
@@ -25,6 +26,7 @@ import (
tls_util "github.com/go-gost/x/internal/util/tls"
rate_limiter "github.com/go-gost/x/limiter/rate"
traffic_wrapper "github.com/go-gost/x/limiter/traffic/wrapper"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -70,7 +72,7 @@ func (h *socks4Handler) Init(md md.Metadata) (err error) {
h.cancel = cancel
if h.options.Observer != nil {
h.stats = stats_util.NewHandlerStats(h.options.Service)
h.stats = stats_util.NewHandlerStats(h.options.Service, h.md.observerResetTraffic)
go h.observeStats(ctx)
}
@@ -122,7 +124,7 @@ func (h *socks4Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl
})
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
@@ -338,13 +340,26 @@ func (h *socks4Handler) observeStats(ctx context.Context) {
return
}
ticker := time.NewTicker(h.md.observePeriod)
var events []observer.Event
ticker := time.NewTicker(h.md.observerPeriod)
defer ticker.Stop()
for {
select {
case <-ticker.C:
h.options.Observer.Observe(ctx, h.stats.Events())
if len(events) > 0 {
if err := h.options.Observer.Observe(ctx, events); err == nil {
events = nil
}
break
}
evs := h.stats.Events()
if err := h.options.Observer.Observe(ctx, evs); err != nil {
events = evs
}
case <-ctx.Done():
return
}
+10 -6
View File
@@ -15,9 +15,11 @@ import (
type metadata struct {
readTimeout time.Duration
hash string
observePeriod time.Duration
limiterRefreshInterval time.Duration
observerPeriod time.Duration
observerResetTraffic bool
sniffing bool
sniffingTimeout time.Duration
sniffingWebsocket bool
@@ -37,14 +39,16 @@ func (h *socks4Handler) parseMetadata(md mdata.Metadata) (err error) {
h.md.hash = mdutil.GetString(md, "hash")
h.md.observePeriod = mdutil.GetDuration(md, "observePeriod", "observer.observePeriod")
if h.md.observePeriod == 0 {
h.md.observePeriod = 5 * time.Second
h.md.observerPeriod = mdutil.GetDuration(md, "observePeriod", "observer.period", "observer.observePeriod")
if h.md.observerPeriod == 0 {
h.md.observerPeriod = 5 * time.Second
}
if h.md.observePeriod < time.Second {
h.md.observePeriod = time.Second
if h.md.observerPeriod < time.Second {
h.md.observerPeriod = time.Second
}
h.md.observerResetTraffic = mdutil.GetBool(md, "observer.resetTraffic")
h.md.limiterRefreshInterval = mdutil.GetDuration(md, "limiter.refreshInterval")
if h.md.limiterRefreshInterval == 0 {
h.md.limiterRefreshInterval = 30 * time.Second
+19 -4
View File
@@ -9,6 +9,7 @@ import (
"github.com/go-gost/core/handler"
"github.com/go-gost/core/limiter/traffic"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/core/recorder"
"github.com/go-gost/gosocks5"
@@ -18,6 +19,7 @@ import (
stats_util "github.com/go-gost/x/internal/util/stats"
tls_util "github.com/go-gost/x/internal/util/tls"
rate_limiter "github.com/go-gost/x/limiter/rate"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -70,7 +72,7 @@ func (h *socks5Handler) Init(md md.Metadata) (err error) {
h.cancel = cancel
if h.options.Observer != nil {
h.stats = stats_util.NewHandlerStats(h.options.Service)
h.stats = stats_util.NewHandlerStats(h.options.Service, h.md.observerResetTraffic)
go h.observeStats(ctx)
}
@@ -122,7 +124,7 @@ func (h *socks5Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl
})
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
@@ -216,13 +218,26 @@ func (h *socks5Handler) observeStats(ctx context.Context) {
return
}
ticker := time.NewTicker(h.md.observePeriod)
var events []observer.Event
ticker := time.NewTicker(h.md.observerPeriod)
defer ticker.Stop()
for {
select {
case <-ticker.C:
h.options.Observer.Observe(ctx, h.stats.Events())
if len(events) > 0 {
if err := h.options.Observer.Observe(ctx, events); err == nil {
events = nil
}
break
}
evs := h.stats.Events()
if err := h.options.Observer.Observe(ctx, evs); err != nil {
events = evs
}
case <-ctx.Done():
return
}
+9 -6
View File
@@ -23,9 +23,11 @@ type metadata struct {
compatibilityMode bool
hash string
muxCfg *mux.Config
observePeriod time.Duration
limiterRefreshInterval time.Duration
observerPeriod time.Duration
observerResetTraffic bool
sniffing bool
sniffingTimeout time.Duration
sniffingWebsocket bool
@@ -66,13 +68,14 @@ func (h *socks5Handler) parseMetadata(md mdata.Metadata) (err error) {
MaxStreamBuffer: mdutil.GetInt(md, "mux.maxStreamBuffer"),
}
h.md.observePeriod = mdutil.GetDuration(md, "observePeriod", "observer.observePeriod")
if h.md.observePeriod == 0 {
h.md.observePeriod = 5 * time.Second
h.md.observerPeriod = mdutil.GetDuration(md, "observePeriod", "observer.period", "observer.observePeriod")
if h.md.observerPeriod == 0 {
h.md.observerPeriod = 5 * time.Second
}
if h.md.observePeriod < time.Second {
h.md.observePeriod = time.Second
if h.md.observerPeriod < time.Second {
h.md.observerPeriod = time.Second
}
h.md.observerResetTraffic = mdutil.GetBool(md, "observer.resetTraffic")
h.md.limiterRefreshInterval = mdutil.GetDuration(md, "limiter.refreshInterval")
if h.md.limiterRefreshInterval == 0 {
+2 -1
View File
@@ -20,6 +20,7 @@ import (
"github.com/go-gost/x/internal/util/ss"
tls_util "github.com/go-gost/x/internal/util/tls"
rate_limiter "github.com/go-gost/x/limiter/rate"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -106,7 +107,7 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H
})
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
+2 -1
View File
@@ -24,6 +24,7 @@ import (
sshd_util "github.com/go-gost/x/internal/util/sshd"
tls_util "github.com/go-gost/x/internal/util/tls"
rate_limiter "github.com/go-gost/x/limiter/rate"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -98,7 +99,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
})
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
+1 -1
View File
@@ -65,7 +65,7 @@ func (h *tunnelHandler) handleBind(ctx context.Context, conn net.Conn, network,
return
}
var stats *stats.Stats
var stats stats.Stats
if h.stats != nil {
stats = h.stats.Stats(tunnelID.String())
}
+4 -3
View File
@@ -38,6 +38,7 @@ import (
ws_util "github.com/go-gost/x/internal/util/ws"
climiter "github.com/go-gost/x/limiter/conn/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"golang.org/x/net/http/httpguts"
@@ -86,7 +87,7 @@ func (ep *entrypoint) Handle(ctx context.Context, conn net.Conn) (err error) {
})
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
@@ -195,7 +196,7 @@ func (ep *entrypoint) dial(ctx context.Context, network, addr string) (conn net.
}
func (ep *entrypoint) handleHTTP(ctx context.Context, conn net.Conn, ro *xrecorder.HandlerRecorderObject, log logger.Logger) (err error) {
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
br := bufio.NewReader(conn)
@@ -250,7 +251,7 @@ func (ep *entrypoint) handleHTTP(ctx context.Context, conn net.Conn, ro *xrecord
}
}
func (ep *entrypoint) httpRoundTrip(ctx context.Context, rw io.ReadWriter, req *http.Request, ro *xrecorder.HandlerRecorderObject, pStats *stats.Stats, log logger.Logger) (err error) {
func (ep *entrypoint) httpRoundTrip(ctx context.Context, rw io.ReadWriter, req *http.Request, ro *xrecorder.HandlerRecorderObject, pStats stats.Stats, log logger.Logger) (err error) {
ro2 := &xrecorder.HandlerRecorderObject{}
*ro2 = *ro
ro = ro2
+17 -3
View File
@@ -14,6 +14,7 @@ import (
"github.com/go-gost/core/listener"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer"
"github.com/go-gost/core/service"
"github.com/go-gost/relay"
ctxvalue "github.com/go-gost/x/ctx"
@@ -116,7 +117,7 @@ func (h *tunnelHandler) Init(md md.Metadata) (err error) {
h.cancel = cancel
if h.options.Observer != nil {
h.stats = stats_util.NewHandlerStats(h.options.Service)
h.stats = stats_util.NewHandlerStats(h.options.Service, h.md.observerResetTraffic)
go h.observeStats(ctx)
}
@@ -321,13 +322,26 @@ func (h *tunnelHandler) observeStats(ctx context.Context) {
return
}
ticker := time.NewTicker(h.md.observePeriod)
var events []observer.Event
ticker := time.NewTicker(h.md.observerPeriod)
defer ticker.Stop()
for {
select {
case <-ticker.C:
h.options.Observer.Observe(ctx, h.stats.Events())
if len(events) > 0 {
if err := h.options.Observer.Observe(ctx, events); err == nil {
events = nil
}
break
}
evs := h.stats.Events()
if err := h.options.Observer.Observe(ctx, evs); err != nil {
events = evs
}
case <-ctx.Done():
return
}
+9 -6
View File
@@ -36,8 +36,10 @@ type metadata struct {
ingress ingress.Ingress
sd sd.SD
muxCfg *mux.Config
observePeriod time.Duration
limiterRefreshInterval time.Duration
observerPeriod time.Duration
observerResetTraffic bool
}
func (h *tunnelHandler) parseMetadata(md mdata.Metadata) (err error) {
@@ -105,13 +107,14 @@ func (h *tunnelHandler) parseMetadata(md mdata.Metadata) (err error) {
h.md.muxCfg.MaxStreamBuffer = 1048576
}
h.md.observePeriod = mdutil.GetDuration(md, "observePeriod", "observer.observePeriod")
if h.md.observePeriod == 0 {
h.md.observePeriod = 5 * time.Second
h.md.observerPeriod = mdutil.GetDuration(md, "observePeriod", "observer.period", "observer.observePeriod")
if h.md.observerPeriod == 0 {
h.md.observerPeriod = 5 * time.Second
}
if h.md.observePeriod < time.Second {
h.md.observePeriod = time.Second
if h.md.observerPeriod < time.Second {
h.md.observerPeriod = time.Second
}
h.md.observerResetTraffic = mdutil.GetBool(md, "observer.resetTraffic")
h.md.limiterRefreshInterval = mdutil.GetDuration(md, "limiter.refreshInterval")
if h.md.limiterRefreshInterval == 0 {
+1 -1
View File
@@ -27,7 +27,7 @@ const (
type ConnectorOptions struct {
service string
sd sd.SD
stats *stats.Stats
stats stats.Stats
limiter traffic.TrafficLimiter
}
+2 -1
View File
@@ -21,6 +21,7 @@ import (
xnet "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/internal/util/sniffing"
tls_util "github.com/go-gost/x/internal/util/tls"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
@@ -95,7 +96,7 @@ func (h *unixHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler
})
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
defer func() {
+3 -2
View File
@@ -34,6 +34,7 @@ import (
"github.com/go-gost/x/internal/util/sniffing"
tls_util "github.com/go-gost/x/internal/util/tls"
ws_util "github.com/go-gost/x/internal/util/ws"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"golang.org/x/net/http/httpguts"
@@ -123,7 +124,7 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
opt(&ho)
}
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
br := bufio.NewReader(conn)
@@ -349,7 +350,7 @@ func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions)
return nil
}
func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriter, node *chain.Node, req *http.Request, pStats *stats.Stats, ho *HandleOptions) (close bool, err error) {
func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriter, node *chain.Node, req *http.Request, pStats stats.Stats, ho *HandleOptions) (close bool, err error) {
close = true
log := ho.Log
+3 -2
View File
@@ -30,6 +30,7 @@ import (
xhttp "github.com/go-gost/x/internal/net/http"
tls_util "github.com/go-gost/x/internal/util/tls"
ws_util "github.com/go-gost/x/internal/util/ws"
xstats "github.com/go-gost/x/observer/stats"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
xrecorder "github.com/go-gost/x/recorder"
"golang.org/x/net/http/httpguts"
@@ -114,7 +115,7 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
opt(&ho)
}
pStats := stats.Stats{}
pStats := xstats.Stats{}
conn = stats_wrapper.WrapConn(conn, &pStats)
br := bufio.NewReader(conn)
@@ -262,7 +263,7 @@ func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions)
return nil
}
func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriter, req *http.Request, ro *xrecorder.HandlerRecorderObject, pStats *stats.Stats, log logger.Logger) (close bool, err error) {
func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriter, req *http.Request, ro *xrecorder.HandlerRecorderObject, pStats stats.Stats, log logger.Logger) (close bool, err error) {
close = true
ro2 := &xrecorder.HandlerRecorderObject{}
+12 -9
View File
@@ -5,22 +5,25 @@ import (
"github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
xstats "github.com/go-gost/x/observer/stats"
)
type HandlerStats struct {
service string
stats map[string]*stats.Stats
mu sync.RWMutex
service string
stats map[string]stats.Stats
resetTraffic bool
mu sync.RWMutex
}
func NewHandlerStats(service string) *HandlerStats {
func NewHandlerStats(service string, resetTraffic bool) *HandlerStats {
return &HandlerStats{
service: service,
stats: make(map[string]*stats.Stats),
service: service,
stats: make(map[string]stats.Stats),
resetTraffic: resetTraffic,
}
}
func (p *HandlerStats) Stats(client string) *stats.Stats {
func (p *HandlerStats) Stats(client string) stats.Stats {
p.mu.RLock()
pstats := p.stats[client]
p.mu.RUnlock()
@@ -32,7 +35,7 @@ func (p *HandlerStats) Stats(client string) *stats.Stats {
defer p.mu.Unlock()
pstats = p.stats[client]
if pstats == nil {
pstats = &stats.Stats{}
pstats = xstats.NewStats(p.resetTraffic)
}
p.stats[client] = pstats
@@ -47,7 +50,7 @@ func (p *HandlerStats) Events() (events []observer.Event) {
if !v.IsUpdated() {
continue
}
events = append(events, stats.StatsEvent{
events = append(events, xstats.StatsEvent{
Kind: "handler",
Service: p.service,
Client: k,
+7 -3
View File
@@ -2,13 +2,14 @@ package observer
import (
"context"
"errors"
"io"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/plugin/observer/proto"
"github.com/go-gost/x/internal/plugin"
xstats "github.com/go-gost/x/observer/stats"
"github.com/go-gost/x/service"
"google.golang.org/grpc"
)
@@ -67,7 +68,7 @@ func (p *grpcPlugin) Observe(ctx context.Context, events []observer.Event, opts
},
})
case observer.EventStats:
ev := event.(stats.StatsEvent)
ev := event.(xstats.StatsEvent)
req.Events = append(req.Events, &proto.Event{
Kind: ev.Kind,
Service: ev.Service,
@@ -83,11 +84,14 @@ func (p *grpcPlugin) Observe(ctx context.Context, events []observer.Event, opts
})
}
}
_, err := p.client.Observe(ctx, &req)
reply, err := p.client.Observe(ctx, &req)
if err != nil {
p.log.Error(err)
return err
}
if reply == nil || !reply.Ok {
return errors.New("observe failed")
}
return nil
}
+14 -5
View File
@@ -4,14 +4,14 @@ import (
"bytes"
"context"
"encoding/json"
"fmt"
"errors"
"net/http"
"strings"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/x/internal/plugin"
xstats "github.com/go-gost/x/observer/stats"
"github.com/go-gost/x/service"
)
@@ -41,7 +41,7 @@ type statusEvent struct {
Msg string `json:"msg"`
}
type observeResponse struct {
type httpPluginResponse struct {
OK bool `json:"ok"`
}
@@ -94,7 +94,7 @@ func (p *httpPlugin) Observe(ctx context.Context, events []observer.Event, opts
},
})
case observer.EventStats:
ev := e.(stats.StatsEvent)
ev := e.(xstats.StatsEvent)
r.Events = append(r.Events, event{
Kind: ev.Kind,
Service: ev.Service,
@@ -131,7 +131,16 @@ func (p *httpPlugin) Observe(ctx context.Context, events []observer.Event, opts
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf(resp.Status)
return errors.New(resp.Status)
}
res := httpPluginResponse{}
if err := json.NewDecoder(resp.Body).Decode(&res); err != nil {
return err
}
if !res.OK {
return errors.New("observe failed")
}
return nil
+102
View File
@@ -0,0 +1,102 @@
package stats
import (
"sync/atomic"
"github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
)
type Stats struct {
updated atomic.Bool
totalConns atomic.Uint64
currentConns atomic.Uint64
inputBytes atomic.Uint64
outputBytes atomic.Uint64
totalErrs atomic.Uint64
resetTraffic bool
}
func NewStats(resetTraffic bool) stats.Stats {
return &Stats{
resetTraffic: resetTraffic,
}
}
func (s *Stats) Add(kind stats.Kind, n int64) {
if s == nil {
return
}
switch kind {
case stats.KindTotalConns:
if n > 0 {
s.totalConns.Add(uint64(n))
}
case stats.KindCurrentConns:
s.currentConns.Add(uint64(n))
case stats.KindInputBytes:
s.inputBytes.Add(uint64(n))
case stats.KindOutputBytes:
s.outputBytes.Add(uint64(n))
case stats.KindTotalErrs:
if n > 0 {
s.totalErrs.Add(uint64(n))
}
}
s.updated.Store(true)
}
func (s *Stats) Get(kind stats.Kind) uint64 {
if s == nil {
return 0
}
switch kind {
case stats.KindTotalConns:
return s.totalConns.Load()
case stats.KindCurrentConns:
return s.currentConns.Load()
case stats.KindInputBytes:
if s.resetTraffic {
return s.inputBytes.Swap(0)
}
return s.inputBytes.Load()
case stats.KindOutputBytes:
if s.resetTraffic {
return s.outputBytes.Swap(0)
}
return s.outputBytes.Load()
case stats.KindTotalErrs:
return s.totalErrs.Load()
}
return 0
}
func (s *Stats) Reset() {
s.updated.Store(false)
s.totalConns.Store(0)
s.currentConns.Store(0)
s.inputBytes.Store(0)
s.outputBytes.Store(0)
s.totalErrs.Store(0)
}
func (s *Stats) IsUpdated() bool {
return s.updated.Swap(false)
}
type StatsEvent struct {
Kind string
Service string
Client string
TotalConns uint64
CurrentConns uint64
InputBytes uint64
OutputBytes uint64
TotalErrs uint64
}
func (StatsEvent) Type() observer.EventType {
return observer.EventStats
}
+6 -6
View File
@@ -19,12 +19,12 @@ var (
type conn struct {
net.Conn
stats *stats.Stats
stats stats.Stats
closed chan struct{}
mu sync.Mutex
}
func WrapConn(c net.Conn, pStats *stats.Stats) net.Conn {
func WrapConn(c net.Conn, pStats stats.Stats) net.Conn {
if pStats == nil {
return c
}
@@ -84,10 +84,10 @@ func (c *conn) Metadata() metadata.Metadata {
type packetConn struct {
net.PacketConn
stats *stats.Stats
stats stats.Stats
}
func WrapPacketConn(pc net.PacketConn, stats *stats.Stats) net.PacketConn {
func WrapPacketConn(pc net.PacketConn, stats stats.Stats) net.PacketConn {
if stats == nil {
return pc
}
@@ -118,10 +118,10 @@ func (c *packetConn) Metadata() metadata.Metadata {
type udpConn struct {
net.PacketConn
stats *stats.Stats
stats stats.Stats
}
func WrapUDPConn(pc net.PacketConn, stats *stats.Stats) udp.Conn {
func WrapUDPConn(pc net.PacketConn, stats stats.Stats) udp.Conn {
return &udpConn{
PacketConn: pc,
stats: stats,
+2 -2
View File
@@ -9,10 +9,10 @@ import (
// readWriter is an io.ReadWriter with Stats.
type readWriter struct {
io.ReadWriter
stats *stats.Stats
stats stats.Stats
}
func WrapReadWriter(rw io.ReadWriter, stats *stats.Stats) io.ReadWriter {
func WrapReadWriter(rw io.ReadWriter, stats stats.Stats) io.ReadWriter {
if stats == nil {
return rw
}
+2 -2
View File
@@ -7,11 +7,11 @@ import (
)
type listener struct {
stats *stats.Stats
stats stats.Stats
net.Listener
}
func WrapListener(ln net.Listener, stats *stats.Stats) net.Listener {
func WrapListener(ln net.Listener, stats stats.Stats) net.Listener {
if stats == nil {
return ln
}
+5 -1
View File
@@ -3,6 +3,7 @@ package recorder
import (
"context"
"encoding/json"
"errors"
"io"
"github.com/go-gost/core/logger"
@@ -56,7 +57,7 @@ func (p *grpcPlugin) Record(ctx context.Context, b []byte, opts ...recorder.Reco
md, _ := json.Marshal(options.Metadata)
_, err := p.client.Record(ctx,
reply, err := p.client.Record(ctx,
&proto.RecordRequest{
Data: b,
Metadata: md,
@@ -65,6 +66,9 @@ func (p *grpcPlugin) Record(ctx context.Context, b []byte, opts ...recorder.Reco
p.log.Error(err)
return err
}
if reply == nil || !reply.Ok {
return errors.New("record failed")
}
return nil
}
+1 -2
View File
@@ -5,7 +5,6 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"github.com/go-gost/core/logger"
@@ -84,7 +83,7 @@ func (p *httpPlugin) Record(ctx context.Context, b []byte, opts ...recorder.Reco
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("%s", resp.Status)
return errors.New(resp.Status)
}
res := httpPluginResponse{}
+42 -21
View File
@@ -21,20 +21,21 @@ import (
ctxvalue "github.com/go-gost/x/ctx"
xnet "github.com/go-gost/x/internal/net"
xmetrics "github.com/go-gost/x/metrics"
xstats "github.com/go-gost/x/observer/stats"
"github.com/rs/xid"
)
type options struct {
admission admission.Admission
recorders []recorder.RecorderObject
preUp []string
postUp []string
preDown []string
postDown []string
stats *stats.Stats
observer observer.Observer
observePeriod time.Duration
logger logger.Logger
admission admission.Admission
recorders []recorder.RecorderObject
preUp []string
postUp []string
preDown []string
postDown []string
stats stats.Stats
observer observer.Observer
observerPeriod time.Duration
logger logger.Logger
}
type Option func(opts *options)
@@ -75,7 +76,7 @@ func PostDownOption(cmds []string) Option {
}
}
func StatsOption(stats *stats.Stats) Option {
func StatsOption(stats stats.Stats) Option {
return func(opts *options) {
opts.stats = stats
}
@@ -87,9 +88,9 @@ func ObserverOption(observer observer.Observer) Option {
}
}
func ObservePeriodOption(period time.Duration) Option {
func ObserverPeriodOption(period time.Duration) Option {
return func(opts *options) {
opts.observePeriod = period
opts.observerPeriod = period
}
}
@@ -249,7 +250,9 @@ func (s *defaultService) Serve() error {
metrics.Labels{"service": s.name, "client": clientIP}); v != nil {
v.Inc()
}
s.status.stats.Add(stats.KindTotalErrs, 1)
if sts := s.status.stats; sts != nil {
sts.Add(stats.KindTotalErrs, 1)
}
}
}()
}
@@ -307,10 +310,15 @@ func (s *defaultService) observeStats(ctx context.Context) {
return
}
d := s.options.observePeriod
if d < time.Millisecond {
d := s.options.observerPeriod
if d == 0 {
d = 5 * time.Second
}
if d < time.Second {
d = 1 * time.Second
}
var events []observer.Event
ticker := time.NewTicker(d)
defer ticker.Stop()
@@ -318,20 +326,33 @@ func (s *defaultService) observeStats(ctx context.Context) {
for {
select {
case <-ticker.C:
st := s.status.Stats()
if !st.IsUpdated() {
if len(events) > 0 {
if err := s.options.observer.Observe(ctx, events); err == nil {
events = nil
}
break
}
s.options.observer.Observe(ctx, []observer.Event{
stats.StatsEvent{
st := s.status.Stats()
if st == nil || !st.IsUpdated() {
break
}
evs := []observer.Event{
xstats.StatsEvent{
Kind: "service",
Service: s.name,
TotalConns: st.Get(stats.KindTotalConns),
CurrentConns: st.Get(stats.KindCurrentConns),
InputBytes: st.Get(stats.KindInputBytes),
OutputBytes: st.Get(stats.KindOutputBytes),
TotalErrs: st.Get(stats.KindTotalErrs),
},
})
}
if err := s.options.observer.Observe(ctx, evs); err != nil {
events = evs
}
case <-ctx.Done():
return
}
+2 -2
View File
@@ -29,7 +29,7 @@ type Status struct {
createTime time.Time
state State
events []Event
stats *stats.Stats
stats stats.Stats
mu sync.RWMutex
}
@@ -71,7 +71,7 @@ func (p *Status) addEvent(event Event) {
p.events = append(p.events, event)
}
func (p *Status) Stats() *stats.Stats {
func (p *Status) Stats() stats.Stats {
if p == nil {
return nil
}