Code review changes

This commit is contained in:
Burke Libbey 2015-03-19 11:17:22 -04:00
parent 83752ed3c5
commit d96cee72fa
No known key found for this signature in database
GPG Key ID: E893DEF914F22410
3 changed files with 47 additions and 26 deletions

View File

@ -74,6 +74,7 @@ import (
"os" "os"
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/Sirupsen/logrus/hooks/airbrake" "github.com/Sirupsen/logrus/hooks/airbrake"
"github.com/Sirupsen/logrus/hooks/bugsnag"
) )
func init() { func init() {
@ -84,6 +85,11 @@ func init() {
// an exception tracker. You can create custom hooks, see the Hooks section. // an exception tracker. You can create custom hooks, see the Hooks section.
log.AddHook(&logrus_airbrake.AirbrakeHook{}) log.AddHook(&logrus_airbrake.AirbrakeHook{})
// Use the Bugsnag hook to report errors that have Error severity or above to
// an exception tracker. You can create custom hooks, see the Hooks section.
bugsnagHook, _ = logrus_bugsnag.NewBugsnagHook()
log.AddHook(bugsnagHook)
// Output to stderr instead of stdout, could also be a file. // Output to stderr instead of stdout, could also be a file.
log.SetOutput(os.Stderr) log.SetOutput(os.Stderr)

View File

@ -1,42 +1,57 @@
package logrus_bugsnag package logrus_bugsnag
import ( import (
"errors"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/bugsnag/bugsnag-go" "github.com/bugsnag/bugsnag-go"
) )
// BugsnagHook sends exceptions to an exception-tracking service compatible type bugsnagHook struct{}
// with the Bugsnag API. Before using this hook, you must call
// bugsnag.Configure(). // ErrBugsnagUnconfigured is returned if NewBugsnagHook is called before
// bugsnag.Configure. Bugsnag must be configured before the hook.
var ErrBugsnagUnconfigured = errors.New("bugsnag must be configured before installing this logrus hook")
// ErrBugsnagSendFailed indicates that the hook failed to submit an error to
// bugsnag. The error was successfully generated, but `bugsnag.Notify()`
// failed.
type ErrBugsnagSendFailed struct {
err error
}
func (e ErrBugsnagSendFailed) Error() string {
return "failed to send error to Bugsnag: " + e.err.Error()
}
// NewBugsnagHook initializes a logrus hook which sends exceptions to an
// exception-tracking service compatible with the Bugsnag API. Before using
// this hook, you must call bugsnag.Configure(). The returned object should be
// registered with a log via `AddHook()`
// //
// Entries that trigger an Error, Fatal or Panic should now include an "error" // Entries that trigger an Error, Fatal or Panic should now include an "error"
// field to send to Bugsnag // field to send to Bugsnag.
type BugsnagHook struct{} func NewBugsnagHook() (*bugsnagHook, error) {
if bugsnag.Config.APIKey == "" {
return nil, ErrBugsnagUnconfigured
}
return &bugsnagHook{}, nil
}
// Fire forwards an error to Bugsnag. Given a logrus.Entry, it extracts the // Fire forwards an error to Bugsnag. Given a logrus.Entry, it extracts the
// implicitly-required "error" field and sends it off. // "error" field (or the Message if the error isn't present) and sends it off.
func (hook *BugsnagHook) Fire(entry *logrus.Entry) error { func (hook *bugsnagHook) Fire(entry *logrus.Entry) error {
if entry.Data["error"] == nil { var notifyErr error
entry.Logger.WithFields(logrus.Fields{
"source": "bugsnag",
}).Warn("Exceptions sent to Bugsnag must have an 'error' key with the error")
return nil
}
err, ok := entry.Data["error"].(error) err, ok := entry.Data["error"].(error)
if !ok { if ok {
entry.Logger.WithFields(logrus.Fields{ notifyErr = err
"source": "bugsnag", } else {
}).Warn("Exceptions sent to Bugsnag must have an `error` key of type `error`") notifyErr = errors.New(entry.Message)
return nil
} }
bugsnagErr := bugsnag.Notify(err) bugsnagErr := bugsnag.Notify(notifyErr)
if bugsnagErr != nil { if bugsnagErr != nil {
entry.Logger.WithFields(logrus.Fields{ return ErrBugsnagSendFailed{bugsnagErr}
"source": "bugsnag",
"error": bugsnagErr,
}).Warn("Failed to send error to Bugsnag")
} }
return nil return nil
@ -44,7 +59,7 @@ func (hook *BugsnagHook) Fire(entry *logrus.Entry) error {
// Levels enumerates the log levels on which the error should be forwarded to // Levels enumerates the log levels on which the error should be forwarded to
// bugsnag: everything at or above the "Error" level. // bugsnag: everything at or above the "Error" level.
func (hook *BugsnagHook) Levels() []logrus.Level { func (hook *bugsnagHook) Levels() []logrus.Level {
return []logrus.Level{ return []logrus.Level{
logrus.ErrorLevel, logrus.ErrorLevel,
logrus.FatalLevel, logrus.FatalLevel,

View File

@ -37,7 +37,7 @@ func TestNoticeReceived(t *testing.T) {
})) }))
defer ts.Close() defer ts.Close()
hook := &BugsnagHook{} hook := &bugsnagHook{}
bugsnag.Configure(bugsnag.Configuration{ bugsnag.Configure(bugsnag.Configuration{
Endpoint: ts.URL, Endpoint: ts.URL,