Go

Gobrake is the official notifier library for Airbrake for the Go programming language. Gobrake provides a minimalist API that enables the ability to send any Go error or panic to the Airbrake dashboard. The library is extremely lightweight, with minimal overhead.

The library supports Go 1.16+. The CI file would be the best source of truth because it contains all Go versions that we test against.

Key features

  • Simple, consistent and easy-to-use library API
  • Asynchronous exception reporting
  • Flexible configuration options
  • Support for environments
  • Add extra context to errors before reporting them
  • Filters support (filter out sensitive or unwanted data that shouldn’t be sent)
  • Ignore errors based on class, message, status, file, or any other filter
  • SSL support (all communication with Airbrake is encrypted by default)
  • Notify Airbrake on panics
  • Set error severity to control notification thresholds
  • Support for code hunks (lines of code surrounding each backtrace frame)
  • Automatic deploy tracking
  • Performance monitoring features such as HTTP route statistics, SQL queries, and Job execution statistics
  • Automatic linking of errors to routes
  • Integrations with Beego, Buffalo, Echo, fasthttp, Fiber, Gin, gorilla/mux, Iris, Negroni and net/http
  • Last but not least, we follow semantic versioning 2.0.0

Supported Frameworks

Gobrake provides a ready-to-use solution with minimal configuration for golang frameworks.

Beego

Buffalo

Echo

FastHttp

Fiber

Gin

Gorilla

Iris

Negroni

Http


Installation & Configuration

Installation

When using Go Modules, you do not need to install anything to start using Airbrake with your Go application. Import the package and the go tool will automatically download the latest version of the package when you next build your program.

import (
  "github.com/airbrake/gobrake/v5"
)

With or without Go Modules, to use the latest version of the package, run:

go get github.com/airbrake/gobrake/v5

Configuration

Configuration is done through the gobrake.NotifierOptions struct, which you are supposed to pass to gobrake.NewNotifierWithOptions.

var airbrake = gobrake.NewNotifierWithOptions(&gobrake.NotifierOptions{
  ProjectId:   <YOUR PROJECT ID>, // <-- Fill in this value
  ProjectKey:  "<YOUR API KEY>", // <-- Fill in this value
  Environment: "production",
})

To find <YOUR PROJECT ID> and <YOUR API KEY> navigate to your project’s Settings and copy the values from the right sidebar.

Example

This is the minimal example that you can use to test Gobrake with your project.

package main

import (
  "errors"

  "github.com/airbrake/gobrake/v5"
)

var airbrake = gobrake.NewNotifierWithOptions(&gobrake.NotifierOptions{
  ProjectId: <YOUR PROJECT ID>,
  ProjectKey: "<YOUR API KEY>",
  Environment: "production",
})

func main() {
  defer airbrake.Close()
  defer airbrake.NotifyOnPanic()

  airbrake.Notify(errors.New("operation failed"), nil)
}

That’s it! The airbrake.NotifyOnPanic() call will handle automatic panic reporting.


Additional Settings

Error Monitoring

ProjectId & ProjectKey

You must set both ProjectId & ProjectKey.

To find your ProjectId (int64) and ProjectKey (string) navigate to your project’s Settings and copy the values from the right sidebar.

Environment

Configures the environment the application is running in. It helps Airbrake dashboard to distinguish between exceptions occurring in different environments. By default, it’s not set. Expects string type.

opts := gobrake.NotifierOptions{
  Environment: "production",
}

Revision

Specifies current version control revision. If your app runs on Heroku, its value will be defaulted to SOURCE_VERSION environment variable. For non-Heroku apps this option is not set. Expects string type.

opts := gobrake.NotifierOptions{
  Revision: "d34db33f",
}

KeysBlocklist

Specifies which keys in the payload (parameters, session data, environment data, etc) should be filtered. Before sending an error, filtered keys will be substituted with the [Filtered] label.

By default, password and secret are filtered out. string and *regexp.Regexp types are permitted.

// String keys.
secrets := []string{"mySecretKey"}

// OR regexp keys
// secrets := []*regexp.Regexp{regexp.MustCompile("mySecretKey")}

blocklist := make([]interface{}, len(secrets))
for i, v := range secrets {
  blocklist[i] = v
}

opts := gobrake.NotifierOptions{
  KeysBlocklist: blocklist,
}

DisableCodeHunks

Controls code hunk collection. Code hunks are lines of code surrounding each backtrace frame. By default, it’s set to false. Expects bool type.

opts := gobrake.NotifierOptions{
  DisableCodeHunks: true,
}

Host

By default, it is set to https://api.airbrake.io. A host (string) is a web address containing a scheme (“http” or “https”), a host and a port. You can omit the port (80 will be assumed) and the scheme (“https” will be assumed).

opts := gobrake.NotifierOptions{
  Host: "http://localhost:8080/api/",
}

HTTPClient

HTTP client that is used to send data to Airbrake API. Expects *http.Client type. Normally, you shouldn’t configure it.

opts := gobrake.NotifierOptions{
  HTTPClient: &http.Client{
    Timeout: 10 * time.Second,
  },
}

DisableRemoteConfig

Configures the remote configuration feature. At regular intervals the notifier will be making GET requests to Airbrake servers and fetching a JSON document containing configuration settings of the notifier. The notifier will apply these new settings at runtime. By default, this option is set to false (the feature is enabled).

Note: it is not recommended to disable this feature. It might negatively impact how your notifier works. Please use this option with caution.

Verify Airbrake is working as expected

You can use airbrake.Notify() to send handled errors. Let’s use it now to check if gobrake is installed correctly:

import "errors"

func testAirbrake() {
  airbrake.Notify(errors.New("Error Test from Airbrake"), nil)
}

You should see your dashboard updating with your test error soon after you run that function.

AddFilter

AddFilter accepts a callback function which will be executed every time a gobrake.Notice is sent. You can use that for two purposes: filtering of unwanted or sensitive params or ignoring the whole notice completely.

Filter unwanted params

// Filter out sensitive information such as credit cards.
airbrake.AddFilter(func(n *gobrake.Notice) *gobrake.Notice {
  if _, ok := n.Context["creditCard"]; ok  {
    n.Context["creditCard"] = "Filtered"
  }
  return n
})

Ignore notices

// Ignore all notices in development.
airbrake.AddFilter(func(n *gobrake.Notice) *gobrake.Notice {
  if n.Context["environment"] == "development" {
    return nil
  }
  return n
})

Adding custom Parameter

You can easily set custom parameters for error notices. For example:

notice.Context["custom-parameter"] = "custom-parameter-value"

Linking errors to routes

You can link error notices with the routes by setting the route e.g. /hello and httpMethod e.g. GET, POST in the custom parameters for error notices. For example:

notice.Context["route"] = "route-name"
notice.Context["httpMethod"] = "http-method-name"

Set severity

Severity allows categorizing how severe an error is. By default, it’s set to error. To redefine severity, simply overwrite context/severity of a notice object. For example:

notice := gobrake.NewNotice("operation failed", nil, 0)
notice.Context["severity"] = "critical"
airbrake.Notify(notice, nil)

Performance Monitoring

You can read more about our Performance Monitoring offering in our docs.

Send routes stats

In order to collect routes stats you can instrument your application using notifier.Routes.Notify API.

Below is an example using the net/http middleware.

package main

import (
  "fmt"
  "net/http"

  "github.com/airbrake/gobrake/v5"
)

// Airbrake is used to report errors and track performance
var Airbrake = gobrake.NewNotifierWithOptions(&gobrake.NotifierOptions{
  ProjectId:   <YOUR PROJECT ID>, // <-- Fill in this value
  ProjectKey:  "<YOUR API KEY>", // <-- Fill in this value
  Environment: "production",
})

func indexHandler(w http.ResponseWriter, req *http.Request) {
  fmt.Fprintf(w, "Hello, There!")
}

func main() {
  fmt.Println("Server listening at http://localhost:5555/")
  // Wrap the indexHandler with Airbrake Performance Monitoring middleware:
  http.HandleFunc(airbrakePerformance("/", indexHandler))
  http.ListenAndServe(":5555", nil)
}

func airbrakePerformance(route string, h http.HandlerFunc) (string, http.HandlerFunc) {
  handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
    ctx := req.Context()
    ctx, routeMetric := gobrake.NewRouteMetric(ctx, req.Method, route) // Starts the timing
    arw := newAirbrakeResponseWriter(w)

    h.ServeHTTP(arw, req)

    routeMetric.StatusCode = arw.statusCode
    Airbrake.Routes.Notify(ctx, routeMetric) // Stops the timing and reports
    fmt.Printf("code: %v, method: %v, route: %v\n", arw.statusCode, req.Method, route)
  })

  return route, handler
}

type airbrakeResponseWriter struct {
  http.ResponseWriter
  statusCode int
}

func newAirbrakeResponseWriter(w http.ResponseWriter) *airbrakeResponseWriter {
  // Returns 200 OK if WriteHeader isn't called
  return &airbrakeResponseWriter{w, http.StatusOK}
}

func (arw *airbrakeResponseWriter) WriteHeader(code int) {
  arw.statusCode = code
  arw.ResponseWriter.WriteHeader(code)
}

To get more detailed timing you can wrap important blocks of code into spans. For example, you can create 2 spans sql and http to measure timing of specific operations:

metric := &gobrake.RouteMetric{
  Method: "GET",
  Route:  "/",
}

ctx, span := metric.Start(ctx, "sql")
users, err := fetchUser(ctx, userID)
span.Finish()

ctx, span = metric.Start(ctx, "http")
resp, err := http.Get("http://example.com/")
span.Finish()

metric.StatusCode = http.StatusOK
notifier.Routes.Notify(ctx, metric)

Send queries stats

You can also collect stats about individual SQL queries performance using following API:

notifier.Queries.Notify(
  context.TODO(),
  &gobrake.QueryInfo{
    Query:     "SELECT * FROM users WHERE id = ?", // query must be normalized
    Func:      "fetchUser", // optional
    File:      "models/user.go", // optional
    Line:      123, // optional
    StartTime: startTime,
    EndTime:   time.Now(),
  },
)

Send queue stats

metric := &gobrake.QueueMetric{
  Queue:   "my-queue-name",
  Errored: true,
}

ctx, span := metric.Start(ctx, "sql")
users, err := fetchUser(ctx, userID)
span.Finish()

ctx, span = metric.Start(ctx, "http")
resp, err := http.Get("http://example.com/")
span.Finish()

notifier.Queues.Notify(ctx, metric)

Notes

For complete API description, please check pkg.go.dev documentation.

Exception limit

The maximum size of an exception is 64KB. Exceptions that exceed this limit will be truncated to fit the size.

Logging

We support two major logging frameworks:

  • There’s a glog fork, which integrates with Gobrake. It provides all of original glog’s functionality and adds the ability to send errors/logs to Airbrake.
  • apex/log, to check how to integrate gobrake with apex/log, see example.
  • zerolog/log, to check how to integrate gobrake with zerolog/log, see example.

Taking Gobrake further

Now that you have configured Airbrake to report exceptions from your Go Application, we recommend you add extra context and filter to your errors and add Airbrake to your existing logger. Please visit the Gobrake GitHub repo for the full list of notifier features and source code.

In case you have a problem, question or a bug report, feel free to file an issue.