Невозможно использовать инструмент go pprof с существующим сервером
У меня есть существующий http-сервер, который я хотел бы профиль. Я включил _ "net/http/pprof"
в свой импорт, и у меня уже есть HTTP-сервер:
router := createRouter()
server := &http.Server {
Addr: ":8080",
Handler: router,
ReadTimeout: 15*time.Second,
WriteTimeout: 15*time.Second,
// MaxHeaderBytes: 4096,
}
log.Fatal(server.ListenAndServe())
Когда я пытаюсь получить доступ к http://localhost:8080/debug/pprof/, я получаю 404 page not found
.
Что я получаю при использовании go tool pprof
на локальной машине:
[email protected]:~/Desktop/gotest$ go tool pprof http://192.168.0.27:8080/
Use of uninitialized value $prefix in concatenation (.) or string at /usr/lib/go/pkg/tool/linux_amd64/pprof line 3019.
Read http://192.168.0.27:8080/pprof/symbol
Failed to get the number of symbols from http://192.168.0.27:8080/pprof/symbol
[email protected]:~/Desktop/gotest$ go tool pprof http://localhost:8080/debug/pprof/profile
Read http://localhost:8080/debug/pprof/symbol
Failed to get the number of symbols from http://localhost:8080/debug/pprof/symbol
То же самое для удаленного клиента:
MacBookAir:~ apple$ go tool pprof http://192.168.0.27:8080/
Use of uninitialized value $prefix in concatenation (.) or string at /usr/local/Cellar/go/1.3.2/libexec/pkg/tool/darwin_amd64/pprof line 3027.
Read http://192.168.0.27:8080/pprof/symbol
Failed to get the number of symbols from http://192.168.0.27:8080/pprof/symbol
Ответы
Ответ 1
Это явно не указано в документации, но net/http/pprof
регистрирует свои обработчики только с помощью http.DefaultServeMux
.
Из источника:
func init() {
http.Handle("/debug/pprof/", http.HandlerFunc(Index))
http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
http.Handle("/debug/pprof/trace", http.HandlerFunc(Trace))
}
Если вы не используете мультиплексирование по умолчанию, вам просто нужно зарегистрировать любые/все те, которые вы хотите, в любом мультиплексоре, который вы используете, например что-то вроде mymux.HandleFunc("…", pprof.Index)
и т.д.
В качестве альтернативы вы можете прослушивать отдельный порт (также, возможно, связанный только с localhost, если это необходимо) с мультиплексированием по умолчанию, как вы показали.
Ответ 2
Похоже, проблема была в *mux.Router
, используемой из github.com/gorilla/mux
, которую я использовал как Handler
в моем экземпляре http.Server
.
Решение: просто запустите еще один сервер только для pprof
:
server := &http.Server {
Addr: ":8080",
Handler: router,
ReadTimeout: 15*time.Second,
WriteTimeout: 15*time.Second,
}
go func() {
log.Println(http.ListenAndServe(":6060", nil))
}()
log.Fatal(server.ListenAndServe())
Ответ 3
Если вы используете github.com/gorilla/mux.Router
вы можете просто передать любой запрос с префиксом /debug/
на http.DefaultServeMux
.
import _ "net/http/debug"
router := mux.NewRouter()
router.PathPrefix("/debug/").Handler(http.DefaultServeMux)