From b06cbc0fee1d0730d603e190944b13eac26ab23f Mon Sep 17 00:00:00 2001 From: yusing Date: Fri, 4 Oct 2024 18:52:31 +0800 Subject: [PATCH] fixed dashboard stats update --- Dockerfile | 1 - compose.example.yml | 8 +++---- go.mod | 1 + go.sum | 4 ++++ internal/api/handler.go | 1 + internal/api/v1/stats.go | 48 ++++++++++++++++++++++++++++++++++++---- 6 files changed, 54 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 02e6eb6..41c92ea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,6 @@ RUN --mount=type=cache,target="/go/pkg/mod" \ FROM scratch LABEL maintainer="yusing@6uo.me" -LABEL proxy.exclude=1 # copy timezone data COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo diff --git a/compose.example.yml b/compose.example.yml index a32deb7..7097eee 100755 --- a/compose.example.yml +++ b/compose.example.yml @@ -4,17 +4,17 @@ services: container_name: go-proxy-frontend restart: unless-stopped network_mode: host + depends_on: + - app # if you also want to proxy the WebUI and access it via gp.y.z # labels: # - proxy.aliases=gp # - proxy.gp.port=3000 - # Uncomment and change this if you have changed below + # Make sure the value is same as `GOPROXY_API_ADDR` below (if you have changed it) # # environment: - # GOPROXY_API_ADDR: 127.0.0.1:8888 - depends_on: - - app + # NEXT_PUBLIC_GOPROXY_API_ADDR: 127.0.0.1:8888 app: image: ghcr.io/yusing/go-proxy:latest container_name: go-proxy diff --git a/go.mod b/go.mod index 983bbb5..5174ba7 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cloudflare/cloudflare-go v0.106.0 // indirect + github.com/coder/websocket v1.8.12 // indirect github.com/containerd/log v0.1.0 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/go-connections v0.5.0 // indirect diff --git a/go.sum b/go.sum index 70805ac..37022c9 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3 github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cloudflare/cloudflare-go v0.106.0 h1:q41gC5Wc1nfi0D1ZhSHokWcd9mGMbqC7RE7qiP+qE00= github.com/cloudflare/cloudflare-go v0.106.0/go.mod h1:pfUQ4PIG4ISI0/Mmc21Bp86UnFU0ktmPf3iTgbSL+cM= +github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= +github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -46,6 +48,8 @@ github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= diff --git a/internal/api/handler.go b/internal/api/handler.go index 271c40d..5ed6803 100644 --- a/internal/api/handler.go +++ b/internal/api/handler.go @@ -34,6 +34,7 @@ func NewHandler(cfg *config.Config) http.Handler { mux.HandleFunc("POST", "/v1/file/{filename...}", v1.SetFileContent) mux.HandleFunc("PUT", "/v1/file/{filename...}", v1.SetFileContent) mux.HandleFunc("GET", "/v1/stats", wrap(cfg, v1.Stats)) + mux.HandleFunc("GET", "/v1/stats/ws", wrap(cfg, v1.StatsWS)) mux.HandleFunc("GET", "/v1/error_page", error_page.GetHandleFunc()) return mux } diff --git a/internal/api/v1/stats.go b/internal/api/v1/stats.go index 1d6bf35..e0f4c75 100644 --- a/internal/api/v1/stats.go +++ b/internal/api/v1/stats.go @@ -1,20 +1,60 @@ package v1 import ( + "context" "net/http" + "time" U "github.com/yusing/go-proxy/internal/api/v1/utils" + "github.com/yusing/go-proxy/internal/common" "github.com/yusing/go-proxy/internal/config" "github.com/yusing/go-proxy/internal/server" "github.com/yusing/go-proxy/internal/utils" + + "github.com/coder/websocket" + "github.com/coder/websocket/wsjson" ) func Stats(cfg *config.Config, w http.ResponseWriter, r *http.Request) { - stats := map[string]any{ + U.HandleErr(w, r, U.RespondJson(w, getStats(cfg))) +} + +func StatsWS(cfg *config.Config, w http.ResponseWriter, r *http.Request) { + originPats := cfg.Value().MatchDomains + if len(originPats) == 0 { + U.Logger.Warnf("no match domains configured, accepting websocket request from all origins") + originPats = []string{"*"} + } + if common.IsDebug { + originPats = []string{"*"} + } + conn, err := websocket.Accept(w, r, &websocket.AcceptOptions{ + OriginPatterns: originPats, + }) + if err != nil { + U.Logger.Errorf("/stats/ws failed to upgrade websocket: %s", err) + return + } + defer conn.CloseNow() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + + for range ticker.C { + stats := getStats(cfg) + if err := wsjson.Write(ctx, conn, stats); err != nil { + U.Logger.Errorf("/stats/ws failed to write JSON: %s", err) + return + } + } +} + +func getStats(cfg *config.Config) map[string]any { + return map[string]any{ "proxies": cfg.Statistics(), "uptime": utils.FormatDuration(server.GetProxyServer().Uptime()), } - if err := U.RespondJson(w, stats); err != nil { - U.HandleErr(w, r, err) - } }