Skip to content

[supervisor/code] grpc tracing and terminal fixes #3504

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .werft/values.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ components:
env:
- name: THEIA_RATELIMIT_LOG
value: "50"
- name: SUPERVISOR_DEBUG_ENABLE
value: "true"
prebuild:
spec:
containers:
Expand Down
26 changes: 18 additions & 8 deletions components/common-go/pprof/pprof.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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]
Expand All @@ -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" {
Expand Down
6 changes: 4 additions & 2 deletions components/ide/code/leeway.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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/ \
Expand All @@ -28,7 +30,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 \
Expand Down
1 change: 1 addition & 0 deletions components/supervisor/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions components/supervisor/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
3 changes: 3 additions & 0 deletions components/supervisor/pkg/supervisor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions components/supervisor/pkg/supervisor/supervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -37,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 (
Expand Down Expand Up @@ -574,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"))
Expand All @@ -596,6 +606,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()
Expand Down