Go (golang) support for the ⚡ Honeybadger error notifier. Receive instant notification of panics and errors in your Go applications.
To install, grab the package from GitHub:
go get github.com/honeybadger-io/honeybadger-go
Then add an import to your application code:
import "github.com/honeybadger-io/honeybadger-go"
Finally, configure your API key:
honeybadger.Configure(honeybadger.Configuration{APIKey: "your api key"})
You can also configure Honeybadger via environment variables. See Configuration for more information.
To automatically report panics which happen during an HTTP request, wrap your
http.Handler
function with honeybadger.Handler
:
log.Fatal(http.ListenAndServe(":8080", honeybadger.Handler(handler)))
Request data such as cookies and params will automatically be reported with
errors which happen inside honeybadger.Handler
. Make sure you recover from
panics after honeybadger's Handler has been executed to ensure all panics are
reported.
To report all unhandled panics which happen in your application
the following can be added to main()
:
func main() {
defer honeybadger.Monitor()
// application code...
}
To report an error manually, use honeybadger.Notify
:
if err != nil {
honeybadger.Notify(err)
}
If you'd like to see the library in action before you integrate it with your apps, check out our sample application.
You can deploy the sample app to your Heroku account by clicking this button:
Don't forget to destroy the Heroku app after you're done so that you aren't charged for usage.
The code for the sample app is available on Github, in case you'd like to read through it, or run it locally.
To set configuration options, use the honeybadger.Configuration
method, like so:
honeybadger.Configure(honeybadger.Configuration{
APIKey: "your api key",
Env: "staging"
})
The following options are available to you:
Name | Type | Default | Example | Environment variable |
---|---|---|---|---|
APIKey | string |
"" |
"badger01" |
HONEYBADGER_API_KEY |
Root | string |
The current working directory | "/path/to/project" |
HONEYBADGER_ROOT |
Env | string |
"" |
"production" |
HONEYBADGER_ENV |
Hostname | string |
The hostname of the current server. | "badger01" |
HONEYBADGER_HOSTNAME |
Endpoint | string |
"https://api.honeybadger.io" |
"https://honeybadger.example.com/" |
HONEYBADGER_ENDPOINT |
Sync | bool |
false | true |
HONEYBADGER_SYNC |
Timeout | time.Duration |
3 seconds | 10 * time.Second |
HONEYBADGER_TIMEOUT (nanoseconds) |
Logger | honeybadger.Logger |
Logs to stderr | CustomLogger{} |
n/a |
Backend | honeybadger.Backend |
HTTP backend | CustomBackend{} |
n/a |
If you've handled a panic in your code, but would still like to report the error to Honeybadger, this is the method for you.
if err != nil {
honeybadger.Notify(err)
}
You can also add local context using an optional second argument when calling
honeybadger.Notify
:
honeybadger.Notify(err, honeybadger.Context{"user_id": 2})
Honeybadger uses the error's class name to group similar errors together. If
your error classes are often generic (such as errors.errorString
), you can
improve grouping by overriding the default with something more unique:
honeybadger.Notify(err, honeybadger.ErrorClass{"CustomClassName"})
To override grouping entirely, you can send a custom fingerprint. All errors with the same fingerprint will be grouped together:
honeybadger.Notify(err, honeybadger.Fingerprint{"A unique string"})
To tag errors in Honeybadger:
honeybadger.Notify(err, honeybadger.Tags{"timeout", "http"})
When using Go's context.Context you can store a honeybadger.Context to build it up across multiple middleware. Be aware that honeybadger.Context is not thread safe.
func(resp http.ResponseWriter, req *http.Request) {
// To store a honeybadger.Context (or use honeybadger.Handler which does this for you)
hbCtx := honeybadger.Context{}
req = req.WithContext(hbCtx.WithContext(req.Context()))
// To add to an existing context
hbCtx = honeybadger.FromContext(req.Context())
hbCtx["user_id"] = "ID"
// To add the context when sending you can just pass the context.Context
honeybadger.Notify(err, ctx)
}
To automatically report panics in your functions or methods, add
defer honeybadger.Monitor()
to the beginning of the function or method you wish to monitor.
func risky() {
defer honeybadger.Monitor()
// risky business logic...
}
Important: honeybadger.Monitor()
will re-panic after it reports the error, so make sure that it is only called once before recovering from the panic (or allowing the process to crash).
Sometimes you may want to modify the data sent to Honeybadger right before an
error notification is sent, or skip the notification entirely. To do so, add a
callback using honeybadger.BeforeNotify()
.
honeybadger.BeforeNotify(
func(notice *honeybadger.Notice) error {
if notice.ErrorClass == "SkippedError" {
return fmt.Errorf("Skipping this notification")
}
// Return nil to send notification for all other classes.
return nil
}
)
To modify information:
honeybadger.BeforeNotify(
func(notice *honeybadger.Notice) error {
// Errors in Honeybadger will always have the class name "GenericError".
notice.ErrorClass = "GenericError"
return nil
}
)
NewNullBackend
creates a backend which swallows all errors and does not send them to Honeybadger. This is useful for development and testing to disable sending unnecessary errors.
honeybadger.Configure(honeybadger.Configuration{Backend: honeybadger.NewNullBackend()})
In the same way that the log library provides a predefined "standard" logger, honeybadger defines a standard client which may be accessed directly via honeybadger
. A new client may also be created by calling honeybadger.New
:
hb := honeybadger.New(honeybadger.Configuration{APIKey: "some other api key"})
hb.Notify("This error was reported by an alternate client.")
Honeybadger groups by the error class and the first line of the backtrace by
default. In some cases it may be desirable to provide your own grouping
algorithm. One use case for this is errors.errorString
. Because that type is
used for many different types of errors in Go, Honeybadger will appear to group
unrelated errors together. Here's an example of providing a custom fingerprint
which will group errors.errorString
by message instead:
honeybadger.BeforeNotify(
func(notice *honeybadger.Notice) error {
if notice.ErrorClass == "errors.errorString" {
notice.Fingerprint = notice.Message
}
return nil
}
)
Note that in this example, the backtrace is ignored. If you want to group by
message and backtrace, you could append data from notice.Backtrace
to the
fingerprint string.
An alternate approach would be to override notice.ErrorClass
with a more
specific class name that may be inferred from the message.
By default, we send out all notices via a separate worker goroutine. This is
awesome for long running applications as it keeps Honeybadger from blocking
during execution. However, this can be a problem for short running applications
(lambdas, for example) as the program might terminate before all messages are
processed. To combat this, you can configure Honeybadger to work in
"Sync" mode which blocks until notices are sent when honeybadger.Notify
is
executed. You can enable sync mode by setting the HONEYBADGER_SYNC
environment
variable or updating the config:
honeybadger.Configure(honeybadger.Configuration{Sync: true})
"Sync" mode is most useful for situations when you are not sending the notice
directly. If you are sending them directly and you want the same
functionality, you can call honeybadger.Flush
after sending the Notice to
block until the worker has completed processing.
honeybadger.Notify("I errored.")
honeybadger.Flush()
We use Semantic Versioning to version releases of honeybadger-go. Because there is no official method to specify version dependencies in Go, we will do our best never to introduce a breaking change on the master branch of this repo after reaching version 1. Until we reach version 1 there is a small chance that we may introduce a breaking change (changing the signature of a function or method, for example), but we'll always tag a new minor release and broadcast that we made the change.
If you're concerned about versioning, there are two options:
If you're really concerned about changes to this library, then copy it into your source control management system so that you can perform upgrades on your own time.
Rather than importing directly from GitHub, gopkg.in allows you to use their special URL format to transparently import a branch or tag from GitHub. Because we tag each release, using gopkg.in can enable you to depend explicitly on a certain version of this library. Importing from gopkg.in instead of directly from GitHub is as easy as:
import "gopkg.in/honeybadger-io/honeybadger-go.v0"
Check out the gopkg.in homepage for more information on how to request versions.
See https://github.com/honeybadger-io/honeybadger-go/blob/master/CHANGELOG.md
If you're adding a new feature, please submit an issue as a preliminary step; that way you can be (moderately) sure that your pull request will be accepted.
- Fork it.
- Create a topic branch
git checkout -b my_branch
- Commit your changes
git commit -am "Boom"
- Push to your branch
git push origin my_branch
- Send a pull request
- Update
VERSION
inhoneybadger.go
- Include version in
CHANGELOG.md
- Commit release and push tag with release version
This library is MIT licensed. See the LICENSE file in this repository for details.