Monitoring Errors and Panics in Go

Every error, exception or crash in production application can directly affect customer experience. To improve application quality errors and crashes should be continuously detected and eliminated. To efficiently do so, the following insights are necessary:

  • The stack traces of the errors and crashes. Without this information localizing the root cause may be extremely difficult.
  • Number of errors over time in order to estimate the impact of each type of error and prioritize work accordingly.

In Go errors are normally returned by functions or raised by a panic() call. In the latter case they can be recovered at the end of the function using deferred recover() call if necessary.

StackImpact provides a simple API to record errors and panics. As a result, they will be presented in the Dashboard in an actionable way.

The following example demonstrates how to record errors and panics using StackImpact agent’s API.

package main

import (
	"fmt"
	"net/http"
	"time"

	"github.com/stackimpact/stackimpact-go"
)

var agent *stackimpact.Agent

// Records handled errors
func handlerA(w http.ResponseWriter, r *http.Request) {
	res, err := http.Get("https://nonexistingdomain")
	if err != nil {
		agent.RecordError(err)
	} else {
		defer res.Body.Close()
	}

	fmt.Fprintf(w, "Done")
}

// Records panics and then repanics
func handlerB(w http.ResponseWriter, r *http.Request) {
	defer agent.RecordPanic()

	s := []string{"a", "b"}
	fmt.Println(s[2]) // this will cause panic

	fmt.Fprintf(w, "Done")
}

// Records and recovers from panics
func handlerC(w http.ResponseWriter, r *http.Request) {
	defer agent.RecordAndRecoverPanic()

	s := []string{"a", "b"}
	fmt.Println(s[2]) // this will cause panic

	fmt.Fprintf(w, "Done")
}

func main() {
	// StackImpact initialization
	agent = stackimpact.NewAgent()
	agent.Start(stackimpact.Options{
		AgentKey: "agent key here",
		AppName:  "Some Go App",
	})

	// Start server
	http.HandleFunc("/a", handlerA)
	http.HandleFunc("/b", handlerB)
	http.HandleFunc("/c", handlerC)
	http.ListenAndServe(":9000", nil)
}

Three cases of error recording are shown in the example: handled errors, panics without recovering (with repanicing), and panics with recovering.

After generating some traffic against this example app, the following information will be available in the Dashboard for example for unrecovered panics (handlerB). The same type of information will be available for recovered panics and handled errors.

Create a free account to start monitoring errors as well as application hot spots, bottlenecks and health metrics in Golang applications. Learn more about the product.