Documentation ¶
Overview ¶
Package webstack provides a http.HandlerFunc that serves a snapshot similar to net/http/pprof.Index().
Contrary to net/http/pprof, the handler is not automatically registered.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SnapshotHandler ¶
func SnapshotHandler(w http.ResponseWriter, req *http.Request)
SnapshotHandler implements http.HandlerFunc to returns a panicparse HTML format for a snapshot of the current goroutines.
Arguments are passed as form values. If you want to change the default, override the form values in a wrapper as shown in the example.
The implementation is designed to be reasonably fast, it currently does a small amount of disk I/O only for file presence.
It is a direct replacement for "/debug/pprof/goroutine?debug=2" handler in net/http/pprof.
augment: (default: 0) When set to 1, panicparse tries to find the sources on disk to improve the display of arguments based on type information. This is slower and should be avoided on high utilization server.
maxmem: (default: 67108864) maximum amount of temporary memory to use to generate a snapshot. In practice at least the double of this is used. Minimum is 1048576.
similarity: (default: "anypointer") Can be one of stack.Similarity value in lowercase: "exactflags", "exactlines", "anypointer" or "anyvalue".
Example ¶
package main import ( "log" "net/http" "github.com/maruel/panicparse/stack/webstack" ) func main() { http.HandleFunc("/debug/panicparse", webstack.SnapshotHandler) // Access as http://localhost:6060/debug/panicparse log.Println(http.ListenAndServe("localhost:6060", nil)) }
Output:
Example (Complex) ¶
package main import ( "log" "net" "net/http" "strings" "sync" "time" "github.com/maruel/panicparse/stack/webstack" ) func main() { // This example does a few things: // - Enables "augment" by default, can be disabled manually with "?augment=0". // - Forces the "maxmem" value to reduce memory pressure in worst case. // - Serializes handler to one at a time. // - Throttles requests to once per second. // - Limit request source IP to localhost and 100.64.x.x/10. (e.g. // Tailscale). const delay = time.Second mu := sync.Mutex{} var last time.Time http.HandleFunc("/debug/panicparse", func(w http.ResponseWriter, req *http.Request) { // Only allow requests from localhost or in the 100.64.x.x/10 IPv4 range. ok := false if i := strings.LastIndexByte(req.RemoteAddr, ':'); i != -1 { switch ip := req.RemoteAddr[:i]; ip { case "localhost", "127.0.0.1", "[::1]", "::1": ok = true default: p := net.ParseIP(ip).To4() ok = p != nil && p[0] == 100 && p[1] >= 64 && p[1] < 128 } } if !ok { http.Error(w, "forbidden", http.StatusForbidden) return } // Serialize the handler. mu.Lock() defer mu.Unlock() // Throttle requests. if time.Since(last) < delay { http.Error(w, "retry later", http.StatusTooManyRequests) return } // Must be called before touching req.Form. req.ParseForm() // Enable source scanning by default. if req.FormValue("augment") == "" { req.Form.Set("augment", "1") } // Reduces maximum memory usage to 32MiB (from 64MiB) for the goroutines // snapshot. req.Form.Set("maxmem", "33554432") webstack.SnapshotHandler(w, req) last = time.Now() }) // Access as http://localhost:6060/debug/panicparse log.Println(http.ListenAndServe("localhost:6060", nil)) }
Output:
Types ¶
This section is empty.