From 04e118c081ef84a987906e38eef6b8cd3179dce3 Mon Sep 17 00:00:00 2001 From: yusing Date: Wed, 15 Jan 2025 09:06:54 +0800 Subject: [PATCH] api: enrich provider statistifcs --- internal/config/query.go | 17 ++++---- internal/route/http.go | 7 +++ internal/route/provider/provider.go | 24 ---------- internal/route/provider/stats.go | 68 +++++++++++++++++++++++++++++ internal/route/route.go | 2 + internal/route/stream.go | 8 ++++ internal/route/types/route.go | 3 ++ 7 files changed, 97 insertions(+), 32 deletions(-) create mode 100644 internal/route/provider/stats.go diff --git a/internal/config/query.go b/internal/config/query.go index fe2755c..9d68ca0 100644 --- a/internal/config/query.go +++ b/internal/config/query.go @@ -25,21 +25,22 @@ func (cfg *Config) DumpProviders() map[string]*provider.Provider { } func (cfg *Config) Statistics() map[string]any { - nTotalStreams := 0 - nTotalRPs := 0 + var rps, streams provider.RouteStats + var total uint16 providerStats := make(map[string]provider.ProviderStats) cfg.providers.RangeAll(func(_ string, p *provider.Provider) { stats := p.Statistics() providerStats[p.ShortName()] = stats - - nTotalRPs += stats.NumRPs - nTotalStreams += stats.NumStreams + rps.AddOther(stats.RPs) + streams.AddOther(stats.Streams) + total += stats.RPs.Total + stats.Streams.Total }) return map[string]any{ - "num_total_streams": nTotalStreams, - "num_total_reverse_proxies": nTotalRPs, - "providers": providerStats, + "total": total, + "reverse_proxies": rps, + "streams": streams, + "providers": providerStats, } } diff --git a/internal/route/http.go b/internal/route/http.go index 054421f..d47a207 100755 --- a/internal/route/http.go +++ b/internal/route/http.go @@ -180,6 +180,13 @@ func (r *HTTPRoute) ServeHTTP(w http.ResponseWriter, req *http.Request) { r.handler.ServeHTTP(w, req) } +func (r *HTTPRoute) Health() health.Status { + if r.HealthMon != nil { + return r.HealthMon.Status() + } + return health.StatusUnknown +} + func (r *HTTPRoute) addToLoadBalancer(parent task.Parent) { var lb *loadbalancer.LoadBalancer cfg := r.Raw.LoadBalance diff --git a/internal/route/provider/provider.go b/internal/route/provider/provider.go index d7702a4..f473d12 100644 --- a/internal/route/provider/provider.go +++ b/internal/route/provider/provider.go @@ -10,7 +10,6 @@ import ( E "github.com/yusing/go-proxy/internal/error" R "github.com/yusing/go-proxy/internal/route" "github.com/yusing/go-proxy/internal/route/provider/types" - route "github.com/yusing/go-proxy/internal/route/types" "github.com/yusing/go-proxy/internal/task" W "github.com/yusing/go-proxy/internal/watcher" "github.com/yusing/go-proxy/internal/watcher/events" @@ -33,11 +32,6 @@ type ( NewWatcher() W.Watcher Logger() *zerolog.Logger } - ProviderStats struct { - NumRPs int `json:"num_reverse_proxies"` - NumStreams int `json:"num_streams"` - Type types.ProviderType `json:"type"` - } ) const ( @@ -154,21 +148,3 @@ func (p *Provider) LoadRoutes() E.Error { func (p *Provider) NumRoutes() int { return p.routes.Size() } - -func (p *Provider) Statistics() ProviderStats { - numRPs := 0 - numStreams := 0 - p.routes.RangeAll(func(_ string, r *R.Route) { - switch r.Type { - case route.RouteTypeReverseProxy: - numRPs++ - case route.RouteTypeStream: - numStreams++ - } - }) - return ProviderStats{ - NumRPs: numRPs, - NumStreams: numStreams, - Type: p.t, - } -} diff --git a/internal/route/provider/stats.go b/internal/route/provider/stats.go new file mode 100644 index 0000000..276a140 --- /dev/null +++ b/internal/route/provider/stats.go @@ -0,0 +1,68 @@ +package provider + +import ( + R "github.com/yusing/go-proxy/internal/route" + "github.com/yusing/go-proxy/internal/route/provider/types" + route "github.com/yusing/go-proxy/internal/route/types" + "github.com/yusing/go-proxy/internal/watcher/health" +) + +type ( + RouteStats struct { + Total uint16 `json:"total"` + NumHealthy uint16 `json:"healthy"` + NumUnhealthy uint16 `json:"unhealthy"` + NumNapping uint16 `json:"napping"` + NumError uint16 `json:"error"` + NumUnknown uint16 `json:"unknown"` + } + ProviderStats struct { + Total uint16 `json:"total"` + RPs RouteStats `json:"reverse_proxies"` + Streams RouteStats `json:"streams"` + Type types.ProviderType `json:"type"` + } +) + +func (stats *RouteStats) Add(r *R.Route) { + stats.Total++ + switch r.Health() { + case health.StatusHealthy: + stats.NumHealthy++ + case health.StatusUnhealthy: + stats.NumUnhealthy++ + case health.StatusNapping: + stats.NumNapping++ + case health.StatusError: + stats.NumError++ + default: + stats.NumUnknown++ + } +} + +func (stats *RouteStats) AddOther(other RouteStats) { + stats.Total += other.Total + stats.NumHealthy += other.NumHealthy + stats.NumUnhealthy += other.NumUnhealthy + stats.NumNapping += other.NumNapping + stats.NumError += other.NumError + stats.NumUnknown += other.NumUnknown +} + +func (p *Provider) Statistics() ProviderStats { + var rps, streams RouteStats + p.routes.RangeAll(func(_ string, r *R.Route) { + switch r.Type { + case route.RouteTypeReverseProxy: + rps.Add(r) + case route.RouteTypeStream: + streams.Add(r) + } + }) + return ProviderStats{ + Total: rps.Total + streams.Total, + RPs: rps, + Streams: streams, + Type: p.t, + } +} diff --git a/internal/route/route.go b/internal/route/route.go index 003b912..569d727 100755 --- a/internal/route/route.go +++ b/internal/route/route.go @@ -11,6 +11,7 @@ import ( "github.com/yusing/go-proxy/internal/task" U "github.com/yusing/go-proxy/internal/utils" F "github.com/yusing/go-proxy/internal/utils/functional" + "github.com/yusing/go-proxy/internal/watcher/health" ) type ( @@ -28,6 +29,7 @@ type ( task.TaskFinisher String() string TargetURL() url.URL + Health() health.Status } RawEntry = types.RawEntry RawEntries = types.RawEntries diff --git a/internal/route/stream.go b/internal/route/stream.go index 1713fb5..3fc2bdf 100755 --- a/internal/route/stream.go +++ b/internal/route/stream.go @@ -116,6 +116,14 @@ func (r *StreamRoute) Finish(reason any) { r.task.Finish(reason) } + +func (r *StreamRoute) Health() health.Status { + if r.HealthMon != nil { + return r.HealthMon.Status() + } + return health.StatusUnknown +} + func (r *StreamRoute) acceptConnections() { defer r.task.Finish("listener closed") diff --git a/internal/route/types/route.go b/internal/route/types/route.go index d44a812..4b56b30 100644 --- a/internal/route/types/route.go +++ b/internal/route/types/route.go @@ -4,15 +4,18 @@ import ( "net/http" net "github.com/yusing/go-proxy/internal/net/types" + "github.com/yusing/go-proxy/internal/watcher/health" ) type ( HTTPRoute interface { Entry http.Handler + Health() health.Status } StreamRoute interface { Entry net.Stream + Health() health.Status } )