webstack

package
v1.6.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 9, 2022 License: Apache-2.0 Imports: 7 Imported by: 0

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL