mirror of https://github.com/sirupsen/logrus.git
commit
8013927d1b
|
@ -204,7 +204,7 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v
|
||||||
| [Airbrake "legacy"](https://github.com/gemnasium/logrus-airbrake-legacy-hook) | Send errors to an exception tracking service compatible with the Airbrake API V2. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. |
|
| [Airbrake "legacy"](https://github.com/gemnasium/logrus-airbrake-legacy-hook) | Send errors to an exception tracking service compatible with the Airbrake API V2. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. |
|
||||||
| [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. |
|
| [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. |
|
||||||
| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
|
| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
|
||||||
| [BugSnag](https://github.com/Sirupsen/logrus/blob/master/hooks/bugsnag/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
|
| [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
|
||||||
| [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. |
|
| [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. |
|
||||||
| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
|
| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
|
||||||
| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
|
| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
package logrus_bugsnag
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
"github.com/bugsnag/bugsnag-go"
|
|
||||||
)
|
|
||||||
|
|
||||||
type bugsnagHook struct{}
|
|
||||||
|
|
||||||
// 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"
|
|
||||||
// field to send to Bugsnag.
|
|
||||||
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
|
|
||||||
// "error" field (or the Message if the error isn't present) and sends it off.
|
|
||||||
func (hook *bugsnagHook) Fire(entry *logrus.Entry) error {
|
|
||||||
var notifyErr error
|
|
||||||
err, ok := entry.Data["error"].(error)
|
|
||||||
if ok {
|
|
||||||
notifyErr = err
|
|
||||||
} else {
|
|
||||||
notifyErr = errors.New(entry.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
bugsnagErr := bugsnag.Notify(notifyErr)
|
|
||||||
if bugsnagErr != nil {
|
|
||||||
return ErrBugsnagSendFailed{bugsnagErr}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
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