Skip to content
This repository was archived by the owner on Jan 20, 2021. It is now read-only.

Commit 408c7ad

Browse files
committed
Enable pprof/debug endpoints by default
Makes sure that debug endpoints are always available, which will aid in debugging demon issues. Wraps debug endpoints in the middleware chain so the can be blocked by authz. Signed-off-by: Brian Goff <[email protected]>
1 parent 458f671 commit 408c7ad

5 files changed

Lines changed: 76 additions & 65 deletions

File tree

api/server/profiler.go

Lines changed: 0 additions & 46 deletions
This file was deleted.

api/server/router/debug/debug.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package debug
2+
3+
import (
4+
"expvar"
5+
"net/http"
6+
"net/http/pprof"
7+
8+
"github.com/docker/docker/api/server/httputils"
9+
"github.com/docker/docker/api/server/router"
10+
"golang.org/x/net/context"
11+
)
12+
13+
// NewRouter creates a new debug router
14+
// The debug router holds endpoints for debug the daemon, such as those for pprof.
15+
func NewRouter() router.Router {
16+
r := &debugRouter{}
17+
r.initRoutes()
18+
return r
19+
}
20+
21+
type debugRouter struct {
22+
routes []router.Route
23+
}
24+
25+
func (r *debugRouter) initRoutes() {
26+
r.routes = []router.Route{
27+
router.NewGetRoute("/vars", frameworkAdaptHandler(expvar.Handler())),
28+
router.NewGetRoute("/pprof/", frameworkAdaptHandlerFunc(pprof.Index)),
29+
router.NewGetRoute("/pprof/cmdline", frameworkAdaptHandlerFunc(pprof.Cmdline)),
30+
router.NewGetRoute("/pprof/profile", frameworkAdaptHandlerFunc(pprof.Profile)),
31+
router.NewGetRoute("/pprof/symbol", frameworkAdaptHandlerFunc(pprof.Symbol)),
32+
router.NewGetRoute("/pprof/trace", frameworkAdaptHandlerFunc(pprof.Trace)),
33+
router.NewGetRoute("/pprof/{name}", handlePprof),
34+
}
35+
}
36+
37+
func (r *debugRouter) Routes() []router.Route {
38+
return r.routes
39+
}
40+
41+
func frameworkAdaptHandler(handler http.Handler) httputils.APIFunc {
42+
return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
43+
handler.ServeHTTP(w, r)
44+
return nil
45+
}
46+
}
47+
48+
func frameworkAdaptHandlerFunc(handler http.HandlerFunc) httputils.APIFunc {
49+
return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
50+
handler(w, r)
51+
return nil
52+
}
53+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package debug
2+
3+
import (
4+
"net/http"
5+
"net/http/pprof"
6+
7+
"golang.org/x/net/context"
8+
)
9+
10+
func handlePprof(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
11+
pprof.Handler(vars["name"]).ServeHTTP(w, r)
12+
return nil
13+
}

api/server/server.go

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/docker/docker/api/server/httputils"
1313
"github.com/docker/docker/api/server/middleware"
1414
"github.com/docker/docker/api/server/router"
15+
"github.com/docker/docker/api/server/router/debug"
1516
"github.com/docker/docker/dockerversion"
1617
"github.com/gorilla/mux"
1718
"golang.org/x/net/context"
@@ -148,13 +149,10 @@ func (s *Server) makeHTTPHandler(handler httputils.APIFunc) http.HandlerFunc {
148149

149150
// InitRouter initializes the list of routers for the server.
150151
// This method also enables the Go profiler if enableProfiler is true.
151-
func (s *Server) InitRouter(enableProfiler bool, routers ...router.Router) {
152+
func (s *Server) InitRouter(routers ...router.Router) {
152153
s.routers = append(s.routers, routers...)
153154

154155
m := s.createMux()
155-
if enableProfiler {
156-
profilerSetup(m)
157-
}
158156
s.routerSwapper = &routerSwapper{
159157
router: m,
160158
}
@@ -175,6 +173,13 @@ func (s *Server) createMux() *mux.Router {
175173
}
176174
}
177175

176+
debugRouter := debug.NewRouter()
177+
s.routers = append(s.routers, debugRouter)
178+
for _, r := range debugRouter.Routes() {
179+
f := s.makeHTTPHandler(r.Handler())
180+
m.Path("/debug" + r.Path()).Handler(f)
181+
}
182+
178183
err := errors.NewRequestNotFoundError(fmt.Errorf("page not found"))
179184
notFoundHandler := httputils.MakeErrorHandler(err)
180185
m.HandleFunc(versionMatcher+"/{path:.*}", notFoundHandler)
@@ -194,15 +199,3 @@ func (s *Server) Wait(waitChan chan error) {
194199
}
195200
waitChan <- nil
196201
}
197-
198-
// DisableProfiler reloads the server mux without adding the profiler routes.
199-
func (s *Server) DisableProfiler() {
200-
s.routerSwapper.Swap(s.createMux())
201-
}
202-
203-
// EnableProfiler reloads the server mux adding the profiler routes.
204-
func (s *Server) EnableProfiler() {
205-
m := s.createMux()
206-
profilerSetup(m)
207-
s.routerSwapper.Swap(m)
208-
}

cmd/dockerd/daemon.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,8 @@ func (cli *DaemonCli) reloadConfig() {
383383
switch {
384384
case debugEnabled && !config.Debug: // disable debug
385385
debug.Disable()
386-
cli.api.DisableProfiler()
387386
case config.Debug && !debugEnabled: // enable debug
388387
debug.Enable()
389-
cli.api.EnableProfiler()
390388
}
391389

392390
}
@@ -536,7 +534,7 @@ func initRouter(opts routerOptions) {
536534
}
537535
}
538536

539-
opts.api.InitRouter(debug.IsEnabled(), routers...)
537+
opts.api.InitRouter(routers...)
540538
}
541539

542540
// TODO: remove this from cli and return the authzMiddleware

0 commit comments

Comments
 (0)