netbug

package module
v0.0.0-...-e64d308 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2015 License: MIT Imports: 8 Imported by: 8

README

netbug

GoDoc

Package netbug provides access to an http.Handler that accesses the profiling and debug tools available in the /net/http/pprof and /runtime/pprof packages.

The advantages of using netbug over the existing /net/http/pprof handlers are:

  1. You can register the handler under an arbitrary route-prefix. A use-case might be to have a secret endpoint for keeping this information hidden from prying eyes, rather than /debug/pprof;
  2. It pulls together all the handlers from /net/http/pprof and /runtime/pprof into a single index page, for when you can't quite remember the URL for the profile you want;
  3. You can register the handlers onto http.ServeMux's that aren't http.DefaultServeMux;
  4. It provides an optional handler that requires a token URL parameter. This is useful if you want that little bit of extra security (use this over HTTPS connections only).

Note: It still imports /net/http/pprof, which means the /debug/pprof routes in that package still get registered on http.DefaultServeMux. If you're using this package to avoid those routes being registered, you should use it with your own http.ServeMux.

netbug is trying to cater for the situation where you want all profiling tools available remotely on your running services, but you don't want to expose the /debug/pprof routes that net/http/pprof forces you to expose.

How do I use it?

In the simplest case give netbug the http.ServeMux you want to register the handlers on, as well as where you want to register the handler and you're away.

package main

import (
	"log"
	"net/http"

	"github.com/e-dard/netbug"
)

func main() {
	r := http.NewServeMux()
	netbug.RegisterHandler("/myroute/", r)
	if err := http.ListenAndServe(":8080", r); err != nil {
		log.Fatal(err)
	}
}

Visiting http://localhost:8080/myroute/ will then return:

netbug also provides a simple way of adding some authentication:

package main

import (
	"log"
	"net/http"

	"github.com/e-dard/netbug"
)

func main() {
	r := http.NewServeMux()
	netbug.RegisterAuthHandler("password", "/myroute/", r)
	if err := http.ListenAndServe(":8080", r); err != nil {
		log.Fatal(err)
	}
}

And visit http://localhost:8080/myroute/?token=password.

Obviously this form of authentication is pointless if you're not accessing the routes over an HTTPS connection. If you want to use a different form of authentication, e.g., HTTP Basic Authentication, then you can use the handler returned by netbug.Handler(), and wrap it with handlers provided by packages like github.com/abbot/go-http-auth.

What can you do with it?

It just wraps the behaviour of the /net/http/pprof and /runtime/pprof packages. Check out their documentation to see what's available. As an example though, if you want to run a 30-second CPU profile on your running service it's really simple:

$ go tool pprof https://example.com/myroute/profile
New in Go 1.5

You can now produce execution traces of your remotely running program using netbug.

To do this run one of the trace profiles, which will result in a file being downloaded. Then use the Go trace tool to generate a trace, which will open up in your browser.

$ go tool trace binary-being-profiled /path/to/downloaded/trace

When compiling binary-being-profiled, you will need to have targeted the same architecture as the binary that generated the profile.

## Background The net/http/pprof package is great. It let's you access profiling and debug information about your running services, via HTTP, and even plugs straight into go tool pprof. You can find out more about using the net/http/pprof package at the bottom of this blog post.

However, there are a couple of problems with the net/http/pprof package.

  1. It assumes you're cool about the relevant handlers being registered under the /debug/pprof route.
  2. It assumes you're cool about handlers being registered on http.DefaultServeMux.
  3. You can't wrap the handlers in any way, say to add authentication or other logic.

You can sort of fix (1) and (2) by digging around the net/http/pprof package and registering all all the exported handlers under different paths on your own http.ServeMux, but you still have the problem of the index page—which is useful to visit if you don't profile much—using hard-coded paths. It doesn't really work well. Also, the index page doesn't provide you with easy links to the debug information that the net/http/pprof package has handlers for.

netbug is just a small package to fix these issues.

Documentation

Overview

Package netbug provides an http.Handler for executing the various profilers and debug tools in the Go standard library.

netbug provides some advantages over the /net/http/pprof and /runtime/pprof packages:

  1. You can register the handler under an arbitrary route or with some authentication on the handler, making it easier to to keep the profilers and debug information away from prying eyes;
  2. It pulls together all the handlers from /net/http/pprof and runtime/pprof into a single index page, for when you can't quite remember the URL for the profile you want; and
  3. You can register the handler onto an `http.ServeMux` that isn't `http.DefaultServeMux`.

The simplest integration of netbug looks like:

package main

import (
	"log"
	"net/http"

	"github.com/e-dard/netbug"
)

func main() {
	r := http.NewServeMux()
	netbug.Register("/myroute/", r)

	if err := http.ListenAndServe(":8080", r); err != nil {
		log.Fatal(err)
	}
}

You can then access the index page via GET /myroute/

The netbug.RegisterAuthHandler function lets you register the handler on your http.ServeMux and add some simple authentication, in the form of a URL parameter:

package main

import (
	"log"
	"net/http"

	"github.com/e-dard/netbug"
)

func main() {
	r := http.NewServeMux()
	netbug.RegisterAuthHandler("open sesame", "/myroute/", r)

	if err := http.ListenAndServe(":8080", r); err != nil {
		log.Fatal(err)
	}
}

You can then access the index page via:

GET /myroute/?token=open%20sesame

The package also provides access to the handlers directly, for when you want to, say, wrap them in your own logic. Just be sure that when you use the handlers that netbug provides, you take care to use `http.StripPrefix` to strip the route you registered the handler on. This is because the handlers' logic expect them to be registered on "/".

package main

import (
	"log"
	"net/http"

	"github.com/e-dard/netbug"
)

// h is a handler that you wish to wrap around netbug's handler,
// allowing you to add your own logic (other types of
// authentication for example).
func h(h http.Handler) http.Handler {
	mh := func(w http.ResponseWriter, r *http.Request) {
		// Some logic here.
		h.ServeHTTP(w, r)
	}
	return http.HandlerFunc(mh)
}

func main() {
	r := http.NewServeMux()

	// netbug's handler assumes it's registered on "/", so you need
	// to strip any prefix you actually want to register it on, if
	// you're not using the netbug.RegisterX functions.
	nbH := http.StripPrefix("/myroute/", netbug.Handler())

	// Wrap the netbug handler in your own, and register the result.
	r.Handle("/myroute/", h(nbH))

	if err := http.ListenAndServe(":8080", r); err != nil {
		log.Fatal(err)
	}
}

As you would expect, netbug works the same way with the go profiler tool as /net/http/pprof does. To run a 30 second CPU profile on your service for example:

$ go tool pprof https://example.com/myroute/profile

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AuthHandler

func AuthHandler(token string) http.Handler

AuthHandler returns an http.Handler that provides authenticated access to the various profiler and debug tools in the /net/http/pprof and /runtime/pprof packages.

The token provided is required as a URL parameter called token for all requests. The netbug package takes care of injecting the token into links in the index page.

The returned handler assumed it is registered on "/" so if you wish to register on any other route, you should strip the route prefix before passing a request on to the handler.

This is best done with:

h := http.StripPrefix("/myroute/", netbug.AuthHandler("secret"))

Unless you need to wrap or chain the handler you probably want to use netbug.RegisterAuthHandler.

func Handler

func Handler() http.Handler

Handler returns an http.Handler that provides access to the various profiler and debug tools in the /net/http/pprof and /runtime/pprof packages.

The returned handler assumed it is registered on "/" so if you wish to register on any other route, you should strip the route prefix before passing a request on to the handler.

This is best done with:

h := http.StripPrefix("/myroute/", netbug.Handler())

Unless you need to wrap or chain the handler you probably want to use netbug.RegisterHandler.

func RegisterAuthHandler

func RegisterAuthHandler(token, prefix string, mux *http.ServeMux)

RegisterAuthHandler registers a handler requiring authentication on the provided http.ServeMux, using the provided prefix to form the route.

The provided prefix needs to have a trailing slash. The full list of routes registered can be examined by visiting the root page.

func RegisterHandler

func RegisterHandler(prefix string, mux *http.ServeMux)

RegisterHandler registers the netbug handler on the provided http.ServeMux, using the provided prefix to form the route.

The provided prefix needs to have a trailing slash. The full list of routes registered for available profiles and debug information can be examined by visiting prefix.

Types

This section is empty.

Jump to

Keyboard shortcuts

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