Back to

Package webstack

Latest Go to latest

The latest major version is v2.

Published: Aug 10, 2020 | License: Apache-2.0 | Module:


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.



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.

For best results, compile the executable with inlining disabled with -gcflags '-l'.

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: 1) 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".



package main

import (

func main() {
	http.HandleFunc("/debug/panicparse", webstack.SnapshotHandler)

	// Access as http://localhost:6060/debug/panicparse
	log.Println(http.ListenAndServe("localhost:6060", nil))
Example (Complex)


package main

import (

func main() {
	// This example does a few things:
	// - Diables "augment" by default, can be enabled manually with "?augment=1".
	// - 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", "", "[::1]", "::1":
				ok = true
				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)

		// Serialize the handler.
		defer mu.Unlock()

		// Throttle requests.
		if time.Since(last) < delay {
			http.Error(w, "retry later", http.StatusTooManyRequests)

		// Must be called before touching req.Form.
		// Disables source scanning by default since it's heavy.
		if req.FormValue("augment") == "" {
			req.Form.Set("augment", "0")
		// 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))
Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier