From fbe548482d60f14cf1e8a425c853be915f37f0f1 Mon Sep 17 00:00:00 2001 From: Anton Kosyakov Date: Fri, 19 Mar 2021 09:14:06 +0000 Subject: [PATCH 1/4] [supervisor] allow to enable pprof --- .werft/values.dev.yaml | 2 ++ components/common-go/pprof/pprof.go | 26 +++++++++++++------ components/supervisor/go.mod | 1 + components/supervisor/go.sum | 1 + .../supervisor/pkg/supervisor/config.go | 3 +++ .../supervisor/pkg/supervisor/supervisor.go | 4 +++ 6 files changed, 29 insertions(+), 8 deletions(-) diff --git a/.werft/values.dev.yaml b/.werft/values.dev.yaml index afb7bfe152a077..5f26587a5d42c5 100644 --- a/.werft/values.dev.yaml +++ b/.werft/values.dev.yaml @@ -71,6 +71,8 @@ components: env: - name: THEIA_RATELIMIT_LOG value: "50" + - name: SUPERVISOR_DEBUG_ENABLE + value: "true" prebuild: spec: containers: diff --git a/components/common-go/pprof/pprof.go b/components/common-go/pprof/pprof.go index 884b6a51171c76..89b922b15b9b0e 100644 --- a/components/common-go/pprof/pprof.go +++ b/components/common-go/pprof/pprof.go @@ -15,14 +15,13 @@ import ( "github.com/gitpod-io/gitpod/common-go/log" ) +// http handler path which MUST be used as a prefix to route pprof endpoint +// since it is hardcoded inside pprof +const Path = "/debug/pprof/" + // Serve starts a new HTTP server serving pprof endpoints on the given addr func Serve(addr string) { - mux := http.NewServeMux() - mux.HandleFunc("/debug/pprof/", index) - mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) - mux.HandleFunc("/debug/pprof/profile", pprof.Profile) - mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) - mux.HandleFunc("/debug/pprof/trace", pprof.Trace) + mux := Handler() log.WithField("addr", addr).Info("serving pprof service") err := http.ListenAndServe(addr, mux) @@ -31,8 +30,19 @@ func Serve(addr string) { } } +// Handler produces the pprof endpoint handler +func Handler() *http.ServeMux { + mux := http.NewServeMux() + mux.HandleFunc(Path, index) + mux.HandleFunc(Path+"cmdline", pprof.Cmdline) + mux.HandleFunc(Path+"profile", pprof.Profile) + mux.HandleFunc(Path+"symbol", pprof.Symbol) + mux.HandleFunc(Path+"trace", pprof.Trace) + return mux +} + func index(w http.ResponseWriter, r *http.Request) { - if strings.HasPrefix(r.URL.Path, "/debug/pprof/") { + if strings.HasPrefix(r.URL.Path, Path) { // according to Ian Lance Taylor it's ok to turn on mutex and block profiling // when asking for the actual profile [1]. This handler implements this idea, as // discussed in [2] @@ -41,7 +51,7 @@ func index(w http.ResponseWriter, r *http.Request) { // [2] https://github.com/golang/go/issues/23401 var ( - name = strings.TrimPrefix(r.URL.Path, "/debug/pprof/") + name = strings.TrimPrefix(r.URL.Path, Path) seconds, serr = strconv.ParseInt(r.URL.Query().Get("seconds"), 10, 64) ) if name == "mutex" { diff --git a/components/supervisor/go.mod b/components/supervisor/go.mod index 2dc71680d42feb..9e9e9e923cc99f 100644 --- a/components/supervisor/go.mod +++ b/components/supervisor/go.mod @@ -20,6 +20,7 @@ require ( github.com/golang/protobuf v1.4.3 github.com/google/go-cmp v0.5.4 github.com/google/uuid v1.1.4 + github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 github.com/grpc-ecosystem/grpc-gateway/v2 v2.2.0 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/prometheus/procfs v0.0.8 // indirect diff --git a/components/supervisor/go.sum b/components/supervisor/go.sum index 542be88fed237d..81a1fb96c67217 100644 --- a/components/supervisor/go.sum +++ b/components/supervisor/go.sum @@ -193,6 +193,7 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 h1:FlFbCRLd5Jr4iYXZufAvgWN6Ao0JrI5chLINnUXDDr0= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI= diff --git a/components/supervisor/pkg/supervisor/config.go b/components/supervisor/pkg/supervisor/config.go index 0ce907553274e5..689f5558facab5 100644 --- a/components/supervisor/pkg/supervisor/config.go +++ b/components/supervisor/pkg/supervisor/config.go @@ -192,6 +192,9 @@ type WorkspaceConfig struct { // GitpodHeadless controls whether the workspace is running headless GitpodHeadless string `env:"GITPOD_HEADLESS"` + + // DebugEnabled controls whether the supervisor debugging facilities (pprof, grpc tracing) shoudl be enabled + DebugEnable bool `env:"SUPERVISOR_DEBUG_ENABLE"` } // WorkspaceGitpodToken is a list of tokens that should be added to supervisor's token service diff --git a/components/supervisor/pkg/supervisor/supervisor.go b/components/supervisor/pkg/supervisor/supervisor.go index 5f4c75060e804d..5a88f2bc8f4f1f 100644 --- a/components/supervisor/pkg/supervisor/supervisor.go +++ b/components/supervisor/pkg/supervisor/supervisor.go @@ -28,6 +28,7 @@ import ( "google.golang.org/grpc" "github.com/gitpod-io/gitpod/common-go/log" + "github.com/gitpod-io/gitpod/common-go/pprof" csapi "github.com/gitpod-io/gitpod/content-service/api" "github.com/gitpod-io/gitpod/content-service/pkg/executor" "github.com/gitpod-io/gitpod/content-service/pkg/initializer" @@ -596,6 +597,9 @@ func startAPIEndpoint(ctx context.Context, cfg *Config, wg *sync.WaitGroup, serv routes := http.NewServeMux() routes.Handle("/_supervisor/v1/", http.StripPrefix("/_supervisor", restMux)) routes.Handle("/_supervisor/frontend", http.FileServer(http.Dir(cfg.FrontendLocation))) + if cfg.DebugEnable { + routes.Handle("/_supervisor"+pprof.Path, http.StripPrefix("/_supervisor", pprof.Handler())) + } go http.Serve(httpMux, routes) go m.Serve() From 7b94d02da29f33499339d66a7448e3cec4c228db Mon Sep 17 00:00:00 2001 From: Anton Kosyakov Date: Fri, 19 Mar 2021 09:45:41 +0000 Subject: [PATCH 2/4] [supervisor] allow to enable grpc tracing --- components/supervisor/pkg/supervisor/supervisor.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/components/supervisor/pkg/supervisor/supervisor.go b/components/supervisor/pkg/supervisor/supervisor.go index 5a88f2bc8f4f1f..dc01c9aaa8047b 100644 --- a/components/supervisor/pkg/supervisor/supervisor.go +++ b/components/supervisor/pkg/supervisor/supervisor.go @@ -38,6 +38,8 @@ import ( "github.com/gitpod-io/gitpod/supervisor/pkg/ports" "github.com/gitpod-io/gitpod/supervisor/pkg/terminal" daemon "github.com/gitpod-io/gitpod/ws-daemon/api" + + grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" ) var ( @@ -575,6 +577,13 @@ func startAPIEndpoint(ctx context.Context, cfg *Config, wg *sync.WaitGroup, serv log.WithError(err).Fatal("cannot start health endpoint") } + if cfg.DebugEnable { + opts = append(opts, + grpc.UnaryInterceptor(grpc_logrus.UnaryServerInterceptor(log.Log)), + grpc.StreamInterceptor(grpc_logrus.StreamServerInterceptor(log.Log)), + ) + } + m := cmux.New(l) restMux := grpcruntime.NewServeMux() grpcMux := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc")) From 3da73ebbfcb14b32be2157265a6eb8f4cf100414 Mon Sep 17 00:00:00 2001 From: Anton Kosyakov Date: Mon, 22 Mar 2021 10:27:04 +0000 Subject: [PATCH 3/4] [code] terminal fixes --- components/ide/code/leeway.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ide/code/leeway.Dockerfile b/components/ide/code/leeway.Dockerfile index 05a44538bbdc3b..58f11108e6f83b 100644 --- a/components/ide/code/leeway.Dockerfile +++ b/components/ide/code/leeway.Dockerfile @@ -28,7 +28,7 @@ RUN sudo apt-get update \ && sudo apt-get clean -y \ && rm -rf /var/lib/apt/lists/* -ENV GP_CODE_COMMIT 17c1ebd3f58baefa67a76240bec4577d55f273e5 +ENV GP_CODE_COMMIT d1e895baec868644416b80c9ec83556a6a9a3311 RUN mkdir gp-code \ && cd gp-code \ && git init \ From da60853db5bd6a7ff66799c3df6993e86341f68f Mon Sep 17 00:00:00 2001 From: Anton Kosyakov Date: Mon, 22 Mar 2021 11:23:09 +0000 Subject: [PATCH 4/4] [code] bump up to latest node.js 12.x --- components/ide/code/leeway.Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/ide/code/leeway.Dockerfile b/components/ide/code/leeway.Dockerfile index 58f11108e6f83b..c76137df0c3d9d 100644 --- a/components/ide/code/leeway.Dockerfile +++ b/components/ide/code/leeway.Dockerfile @@ -2,7 +2,9 @@ # Licensed under the GNU Affero General Public License (AGPL). # See License-AGPL.txt in the project root for license information. -FROM node:12.18.3 AS node_installer +# we use latest major version of Node.js distributed VS Code. (see about dialog in your local VS Code) +# ideallay we should use exact version, but it has criticla bugs in regards to grpc over http2 streams +FROM node:12.21.0 AS node_installer RUN mkdir -p /ide/node/bin \ /ide/node/include/node/ \ /ide/node/lib/node_modules/npm/ \