Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: common/runtime/profiling/profiler.go

Issue 2588643002: Enable AppEngine profiling endpoints. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package profiling 5 package profiling
6 6
7 import ( 7 import (
8 "flag" 8 "flag"
9 "fmt" 9 "fmt"
10 "net" 10 "net"
11 "net/http" 11 "net/http"
12 httpProf "net/http/pprof" 12 httpProf "net/http/pprof"
Vadim Sh. 2016/12/18 22:44:37 This import registers routes in default net/http r
13 "os" 13 "os"
14 "path/filepath" 14 "path/filepath"
15 "runtime" 15 "runtime"
16 "runtime/pprof" 16 "runtime/pprof"
17 "sync/atomic" 17 "sync/atomic"
18 18
19 » "github.com/julienschmidt/httprouter" 19 » "github.com/luci/luci-go/server/router"
20
20 "github.com/luci/luci-go/common/clock" 21 "github.com/luci/luci-go/common/clock"
21 "github.com/luci/luci-go/common/errors" 22 "github.com/luci/luci-go/common/errors"
22 "github.com/luci/luci-go/common/logging" 23 "github.com/luci/luci-go/common/logging"
23 ) 24 )
24 25
25 // Profiler helps setup and manage profiling 26 // Profiler helps setup and manage profiling
26 type Profiler struct { 27 type Profiler struct {
27 // BindHTTP, if not empty, is the HTTP address to bind to. 28 // BindHTTP, if not empty, is the HTTP address to bind to.
28 // 29 //
29 // Can also be configured with "-profile-bind-http" flag. 30 // Can also be configured with "-profile-bind-http" flag.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 // If we have an output directory, start our CPU profiling. 65 // If we have an output directory, start our CPU profiling.
65 if p.BindHTTP != "" { 66 if p.BindHTTP != "" {
66 if err := p.startHTTP(); err != nil { 67 if err := p.startHTTP(); err != nil {
67 return errors.Annotate(err).Reason("failed to start HTTP server").Err() 68 return errors.Annotate(err).Reason("failed to start HTTP server").Err()
68 } 69 }
69 } 70 }
70 return nil 71 return nil
71 } 72 }
72 73
73 func (p *Profiler) startHTTP() error { 74 func (p *Profiler) startHTTP() error {
74 » // Register paths: https://golang.org/src/net/http/pprof/pprof.go 75 » r := router.New()
75 » router := httprouter.New() 76 » InstallHandlers(r, router.MiddlewareChain{})
76 » router.HandlerFunc("GET", "/debug/pprof/", httpProf.Index)
77 » router.HandlerFunc("GET", "/debug/pprof/cmdline", httpProf.Cmdline)
78 » router.HandlerFunc("GET", "/debug/pprof/profile", httpProf.Profile)
79 » router.HandlerFunc("GET", "/debug/pprof/symbol", httpProf.Symbol)
80 » router.HandlerFunc("GET", "/debug/pprof/trace", httpProf.Trace)
81 » for _, p := range pprof.Profiles() {
82 » » name := p.Name()
83 » » router.Handler("GET", fmt.Sprintf("/debug/pprof/%s", name), http Prof.Handler(name))
84 » }
85 77
86 // Bind to our profiling port. 78 // Bind to our profiling port.
87 l, err := net.Listen("tcp4", p.BindHTTP) 79 l, err := net.Listen("tcp4", p.BindHTTP)
88 if err != nil { 80 if err != nil {
89 return errors.Annotate(err).Reason("failed to bind to TCP4 addre ss: %(addr)q"). 81 return errors.Annotate(err).Reason("failed to bind to TCP4 addre ss: %(addr)q").
90 D("addr", p.BindHTTP).Err() 82 D("addr", p.BindHTTP).Err()
91 } 83 }
92 84
93 server := http.Server{ 85 server := http.Server{
94 » » Handler: http.HandlerFunc(router.ServeHTTP), 86 » » Handler: http.HandlerFunc(r.ServeHTTP),
95 } 87 }
96 go func() { 88 go func() {
97 if err := server.Serve(l); err != nil { 89 if err := server.Serve(l); err != nil {
98 p.getLogger().Errorf("Error serving profile HTTP: %s", e rr) 90 p.getLogger().Errorf("Error serving profile HTTP: %s", e rr)
99 } 91 }
100 }() 92 }()
101 return nil 93 return nil
102 } 94 }
103 95
104 // Stop stops the Profiler's operations. 96 // Stop stops the Profiler's operations.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 counter := atomic.AddUint32(&p.pathCounter, 1) - 1 143 counter := atomic.AddUint32(&p.pathCounter, 1) - 1
152 return filepath.Join(p.Dir, fmt.Sprintf("%s_%d_%d.prof", base, now.Unix( ), counter)) 144 return filepath.Join(p.Dir, fmt.Sprintf("%s_%d_%d.prof", base, now.Unix( ), counter))
153 } 145 }
154 146
155 func (p *Profiler) getLogger() logging.Logger { 147 func (p *Profiler) getLogger() logging.Logger {
156 if p.Logger != nil { 148 if p.Logger != nil {
157 return p.Logger 149 return p.Logger
158 } 150 }
159 return logging.Null 151 return logging.Null
160 } 152 }
153
154 // InstallHandlers installs standard profiler paths into the supplied Router.
155 //
156 // See https://golang.org/src/net/http/pprof/pprof.go
157 func InstallHandlers(r *router.Router, base router.MiddlewareChain) {
158 r.GET("/debug/pprof/", base, wrapHandlerFunc(httpProf.Index))
159 r.GET("/debug/pprof/cmdline", base, wrapHandlerFunc(httpProf.Cmdline))
160 r.GET("/debug/pprof/profile", base, wrapHandlerFunc(httpProf.Profile))
161 r.GET("/debug/pprof/symbol", base, wrapHandlerFunc(httpProf.Symbol))
162 r.GET("/debug/pprof/trace", base, wrapHandlerFunc(httpProf.Trace))
163 for _, p := range pprof.Profiles() {
164 name := p.Name()
165 r.GET(fmt.Sprintf("/debug/pprof/%s", name), base, wrapHandler(ht tpProf.Handler(name)))
166 }
167 }
168
169 func wrapHandlerFunc(h http.HandlerFunc) router.Handler {
170 return func(c *router.Context) {
171 h(c.Writer, c.Request)
172 }
173 }
174
175 func wrapHandler(h http.Handler) router.Handler {
176 return func(c *router.Context) {
177 h.ServeHTTP(c.Writer, c.Request)
178 }
179 }
OLDNEW
« appengine/gaemiddleware/routes.go ('K') | « appengine/gaemiddleware/routes.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698