Skip to content
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

net/http/pprof: Index has hard-coded prefix path #14286

Closed
illicitonion opened this issue Feb 10, 2016 · 5 comments
Closed

net/http/pprof: Index has hard-coded prefix path #14286

illicitonion opened this issue Feb 10, 2016 · 5 comments

Comments

@illicitonion
Copy link

Right now, https://golang.org/src/net/http/pprof/pprof.go?s=6283:6333#L197 has a

func Index(w http.ResponseWriter, r *http.Request)

which only works if the path on which it is serving is exactly /debug/pprof/.

This is weakly documented, and also a little inconvenient, as handling other paths may be desirable. In particular, its behaviour if you do assume that it can be hosted on other paths is that every profile you try to get returns the index page.

It would be nice to fix this so that it supports arbitrary path prefixes. The ways that occur to me to implement this are:

  1. Rather than extracting the expected path suffix up-front and looking it up in the profiles map, iterating over the available profiles and checking whether they are a suffix of the requested path (possibly the longest suffix). This is a little less efficient (O(1) profile lookup becomes O(|available profiles|), but the number of profiles should be small and this handler shouldn't be hit too often or on many critical paths.

  2. Introduce a function which takes the path prefix and returns a handler suitable for that prefix. It preserves the current performance characteristics, but leaves the old slightly-broken method there for backwards compatibility, at the cost of requiring duplication of the prefix specification (both in the Handle call and in the Index-creator-func), and generally feeling slightly ugly.

I'm inclined towards implementing the first; does anyone have any strong opinions?

@ianlancetaylor ianlancetaylor changed the title net/http/pprof.Index has hard-coded prefix path net/http/pprof: Index has hard-coded prefix path Feb 10, 2016
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Feb 10, 2016
@rakyll
Copy link
Contributor

rakyll commented Feb 11, 2016

as handling other paths may be desirable

Why don't we return the index handler from pprof.Handler("index")? It doesn't solve the issue of /debug/pprof paths will be registered as a side effect when you import the package but gives flexibility to serve the index handler from a different route.

@illicitonion
Copy link
Author

Right now you can get at the handler with a call to something like http.HandleFunc("/debug/pprof", http.HandlerFunc(pprof.Index)), so I don't think the extra pprof.Handler("index") behaviour is worth the hassle of having to forbid "index" as a profile name.

The problem, really, is that if you choose to serve it from a different route, it's broken.

@rakyll
Copy link
Contributor

rakyll commented Feb 12, 2016

The problem, really, is that if you choose to serve it from a different route, it's broken.

You can serve it from a different route:

http.Handle("/custom/pprof", http.HandlerFunc(pprofhttp.Index))

init registers the routes on the DefaultServeMux, if you use a custom ServeMux, you don't also have to serve the /debug/pprof endpoints.

package main

import (
    "log"
    "net/http"
    pprofhttp "net/http/pprof"
)

func main() {
    mux := http.NewServeMux()
    mux.Handle("/custom/pprof", http.HandlerFunc(pprofhttp.Index))
    log.Println(http.ListenAndServe("localhost:6060", mux))
}

I don't quite think we can do anything else without breaking the current users.

I got confused because you have mentioned the index handler only initially, the same applies to other pprof endpoints.

@rakyll
Copy link
Contributor

rakyll commented Feb 12, 2016

if strings.HasPrefix(r.URL.Path, "/debug/pprof/")

Please ignore my previous comment. I lost the background, haven't seen the line and was replying without context.

Why don't you just write a custom index handler or register the routes manually if you don't have many custom profiles? The optimistic matching from the path is a bit magical and polluting the API surface is the last thing we should consider. The index handler is just a few lines of code and easy to replicate.

@bradfitz
Copy link
Contributor

bradfitz commented Feb 1, 2017

I'd rather not go down this road.

The package docs already say:

The handled paths all begin with /debug/pprof/

This package is quite small. If you want something different, it's easy enough to fork it. I don't want to bloat the package (in either API or implementation) by supporting too much flexibility. The nice things about conventions (like /debug/*) is that it permits simplicity elsewhere.

@bradfitz bradfitz closed this as completed Feb 1, 2017
@golang golang locked and limited conversation to collaborators Feb 1, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants