Back to godoc.org
github.com/maruel/panicparse/stack/webstack

package webstack

v1.5.0
Latest Go to latest
Published: May 29, 2020 | License: Apache-2.0 | Module: github.com/maruel/panicparse

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

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

Code:

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

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

Code:

// 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))
Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
f or F : Jump to identifier