mirror of https://github.com/sirupsen/logrus.git
hooks: Add BugSnag hook
This commit is contained in:
parent
2cea0f0d14
commit
83752ed3c5
|
@ -0,0 +1,53 @@
|
||||||
|
package logrus_bugsnag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/bugsnag/bugsnag-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BugsnagHook sends exceptions to an exception-tracking service compatible
|
||||||
|
// with the Bugsnag API. Before using this hook, you must call
|
||||||
|
// bugsnag.Configure().
|
||||||
|
//
|
||||||
|
// Entries that trigger an Error, Fatal or Panic should now include an "error"
|
||||||
|
// field to send to Bugsnag
|
||||||
|
type BugsnagHook struct{}
|
||||||
|
|
||||||
|
// Fire forwards an error to Bugsnag. Given a logrus.Entry, it extracts the
|
||||||
|
// implicitly-required "error" field and sends it off.
|
||||||
|
func (hook *BugsnagHook) Fire(entry *logrus.Entry) error {
|
||||||
|
if entry.Data["error"] == nil {
|
||||||
|
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)
|
||||||
|
if !ok {
|
||||||
|
entry.Logger.WithFields(logrus.Fields{
|
||||||
|
"source": "bugsnag",
|
||||||
|
}).Warn("Exceptions sent to Bugsnag must have an `error` key of type `error`")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
bugsnagErr := bugsnag.Notify(err)
|
||||||
|
if bugsnagErr != nil {
|
||||||
|
entry.Logger.WithFields(logrus.Fields{
|
||||||
|
"source": "bugsnag",
|
||||||
|
"error": bugsnagErr,
|
||||||
|
}).Warn("Failed to send error to Bugsnag")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Levels enumerates the log levels on which the error should be forwarded to
|
||||||
|
// bugsnag: everything at or above the "Error" level.
|
||||||
|
func (hook *BugsnagHook) Levels() []logrus.Level {
|
||||||
|
return []logrus.Level{
|
||||||
|
logrus.ErrorLevel,
|
||||||
|
logrus.FatalLevel,
|
||||||
|
logrus.PanicLevel,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package logrus_bugsnag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/bugsnag/bugsnag-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
type notice struct {
|
||||||
|
Events []struct {
|
||||||
|
Exceptions []struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
} `json:"exceptions"`
|
||||||
|
} `json:"events"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoticeReceived(t *testing.T) {
|
||||||
|
msg := make(chan string, 1)
|
||||||
|
expectedMsg := "foo"
|
||||||
|
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var notice notice
|
||||||
|
data, _ := ioutil.ReadAll(r.Body)
|
||||||
|
if err := json.Unmarshal(data, ¬ice); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
_ = r.Body.Close()
|
||||||
|
|
||||||
|
msg <- notice.Events[0].Exceptions[0].Message
|
||||||
|
}))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
hook := &BugsnagHook{}
|
||||||
|
|
||||||
|
bugsnag.Configure(bugsnag.Configuration{
|
||||||
|
Endpoint: ts.URL,
|
||||||
|
ReleaseStage: "production",
|
||||||
|
APIKey: "12345678901234567890123456789012",
|
||||||
|
Synchronous: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
log := logrus.New()
|
||||||
|
log.Hooks.Add(hook)
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"error": errors.New(expectedMsg),
|
||||||
|
}).Error("Bugsnag will not see this string")
|
||||||
|
|
||||||
|
select {
|
||||||
|
case received := <-msg:
|
||||||
|
if received != expectedMsg {
|
||||||
|
t.Errorf("Unexpected message received: %s", received)
|
||||||
|
}
|
||||||
|
case <-time.After(time.Second):
|
||||||
|
t.Error("Timed out; no notice received by Bugsnag API")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue