api: add /v1/health/ws for health bubbles on dashboard

This commit is contained in:
yusing
2025-01-19 04:34:20 +08:00
parent fe7740f1b0
commit 1adba05065
13 changed files with 89 additions and 23 deletions

View File

@@ -30,7 +30,7 @@ type (
HealthMon health.HealthMonitor `json:"health,omitempty"`
loadBalancer *loadbalancer.LoadBalancer
server *loadbalancer.Server
server loadbalancer.Server
handler http.Handler
rp *reverseproxy.ReverseProxy
@@ -180,11 +180,8 @@ 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) HealthMonitor() health.HealthMonitor {
return r.HealthMon
}
func (r *HTTPRoute) addToLoadBalancer(parent task.Parent) {

View File

@@ -26,7 +26,12 @@ type (
func (stats *RouteStats) Add(r *R.Route) {
stats.Total++
switch r.Health() {
mon := r.HealthMonitor()
if mon == nil {
stats.NumUnknown++
return
}
switch mon.Status() {
case health.StatusHealthy:
stats.NumHealthy++
case health.StatusUnhealthy:

View File

@@ -11,7 +11,6 @@ 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 (
@@ -24,12 +23,11 @@ type (
Routes = F.Map[string, *Route]
impl interface {
entry.Entry
types.Route
task.TaskStarter
task.TaskFinisher
String() string
TargetURL() url.URL
Health() health.Status
}
RawEntry = types.RawEntry
RawEntries = types.RawEntries

View File

@@ -2,6 +2,7 @@ package routes
import (
"strings"
"time"
"github.com/yusing/go-proxy/internal/homepage"
"github.com/yusing/go-proxy/internal/route/entry"
@@ -10,6 +11,33 @@ import (
"github.com/yusing/go-proxy/internal/utils/strutils"
)
func getHealthInfo(r route.Route) map[string]string {
mon := r.HealthMonitor()
if mon == nil {
return map[string]string{
"status": "unknown",
"uptime": "n/a",
"latency": "n/a",
}
}
return map[string]string{
"status": mon.Status().String(),
"uptime": mon.Uptime().Round(time.Second).String(),
"latency": mon.Latency().Round(time.Microsecond).String(),
}
}
func HealthMap() map[string]map[string]string {
healthMap := make(map[string]map[string]string)
httpRoutes.RangeAll(func(alias string, r route.HTTPRoute) {
healthMap[alias] = getHealthInfo(r)
})
streamRoutes.RangeAll(func(alias string, r route.StreamRoute) {
healthMap[alias] = getHealthInfo(r)
})
return healthMap
}
func HomepageConfig(useDefaultCategories bool) homepage.Config {
hpCfg := homepage.NewHomePageConfig()
GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
@@ -77,8 +105,8 @@ func HomepageConfig(useDefaultCategories bool) homepage.Config {
return hpCfg
}
func RoutesByAlias(typeFilter ...route.RouteType) map[string]any {
rts := make(map[string]any)
func RoutesByAlias(typeFilter ...route.RouteType) map[string]route.Route {
rts := make(map[string]route.Route)
if len(typeFilter) == 0 || typeFilter[0] == "" {
typeFilter = []route.RouteType{route.RouteTypeReverseProxy, route.RouteTypeStream}
}

View File

@@ -116,12 +116,8 @@ 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) HealthMonitor() health.HealthMonitor {
return r.HealthMon
}
func (r *StreamRoute) acceptConnections() {

View File

@@ -8,14 +8,16 @@ import (
)
type (
HTTPRoute interface {
Route interface {
Entry
HealthMonitor() health.HealthMonitor
}
HTTPRoute interface {
Route
http.Handler
Health() health.Status
}
StreamRoute interface {
Entry
Route
net.Stream
Health() health.Status
}
)