Merge pull request #261 from gemnasium/move-airbrake
Move airbrake
diff --git a/README.md b/README.md
index a0c0644..e23e701 100644
--- a/README.md
+++ b/README.md
@@ -75,17 +75,12 @@
import (
"os"
log "github.com/Sirupsen/logrus"
- "github.com/Sirupsen/logrus/hooks/airbrake"
)
func init() {
// Log as JSON instead of the default ASCII formatter.
log.SetFormatter(&log.JSONFormatter{})
- // Use the Airbrake hook to report errors that have Error severity or above to
- // an exception tracker. You can create custom hooks, see the Hooks section.
- log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development"))
-
// Output to stderr instead of stdout, could also be a file.
log.SetOutput(os.Stderr)
@@ -182,13 +177,16 @@
```go
import (
log "github.com/Sirupsen/logrus"
- "github.com/Sirupsen/logrus/hooks/airbrake"
+ "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake"
logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
"log/syslog"
)
func init() {
- log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development"))
+
+ // Use the Airbrake hook to report errors that have Error severity or above to
+ // an exception tracker. You can create custom hooks, see the Hooks section.
+ log.AddHook(airbrake.NewHook(123, "xyz", "production"))
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
if err != nil {
@@ -202,7 +200,8 @@
| Hook | Description |
| ----- | ----------- |
-| [Airbrake](https://github.com/Sirupsen/logrus/blob/master/hooks/airbrake/airbrake.go) | Send errors to an exception tracking service compatible with the Airbrake API. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. |
+| [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) 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/Sirupsen/logrus/blob/master/hooks/papertrail/papertrail.go) | Send errors to the Papertrail 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. |
| [BugSnag](https://github.com/Sirupsen/logrus/blob/master/hooks/bugsnag/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
diff --git a/hooks/airbrake/airbrake.go b/hooks/airbrake/airbrake.go
deleted file mode 100644
index b0502c3..0000000
--- a/hooks/airbrake/airbrake.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package airbrake
-
-import (
- "errors"
- "fmt"
-
- "github.com/Sirupsen/logrus"
- "github.com/tobi/airbrake-go"
-)
-
-// AirbrakeHook to send exceptions to an exception-tracking service compatible
-// with the Airbrake API.
-type airbrakeHook struct {
- APIKey string
- Endpoint string
- Environment string
-}
-
-func NewHook(endpoint, apiKey, env string) *airbrakeHook {
- return &airbrakeHook{
- APIKey: apiKey,
- Endpoint: endpoint,
- Environment: env,
- }
-}
-
-func (hook *airbrakeHook) Fire(entry *logrus.Entry) error {
- airbrake.ApiKey = hook.APIKey
- airbrake.Endpoint = hook.Endpoint
- airbrake.Environment = hook.Environment
-
- var notifyErr error
- err, ok := entry.Data["error"].(error)
- if ok {
- notifyErr = err
- } else {
- notifyErr = errors.New(entry.Message)
- }
-
- airErr := airbrake.Notify(notifyErr)
- if airErr != nil {
- return fmt.Errorf("Failed to send error to Airbrake: %s", airErr)
- }
-
- return nil
-}
-
-func (hook *airbrakeHook) Levels() []logrus.Level {
- return []logrus.Level{
- logrus.ErrorLevel,
- logrus.FatalLevel,
- logrus.PanicLevel,
- }
-}
diff --git a/hooks/airbrake/airbrake_test.go b/hooks/airbrake/airbrake_test.go
deleted file mode 100644
index 058a91e..0000000
--- a/hooks/airbrake/airbrake_test.go
+++ /dev/null
@@ -1,133 +0,0 @@
-package airbrake
-
-import (
- "encoding/xml"
- "net/http"
- "net/http/httptest"
- "testing"
- "time"
-
- "github.com/Sirupsen/logrus"
-)
-
-type notice struct {
- Error NoticeError `xml:"error"`
-}
-type NoticeError struct {
- Class string `xml:"class"`
- Message string `xml:"message"`
-}
-
-type customErr struct {
- msg string
-}
-
-func (e *customErr) Error() string {
- return e.msg
-}
-
-const (
- testAPIKey = "abcxyz"
- testEnv = "development"
- expectedClass = "*airbrake.customErr"
- expectedMsg = "foo"
- unintendedMsg = "Airbrake will not see this string"
-)
-
-var (
- noticeError = make(chan NoticeError, 1)
-)
-
-// TestLogEntryMessageReceived checks if invoking Logrus' log.Error
-// method causes an XML payload containing the log entry message is received
-// by a HTTP server emulating an Airbrake-compatible endpoint.
-func TestLogEntryMessageReceived(t *testing.T) {
- log := logrus.New()
- ts := startAirbrakeServer(t)
- defer ts.Close()
-
- hook := NewHook(ts.URL, testAPIKey, "production")
- log.Hooks.Add(hook)
-
- log.Error(expectedMsg)
-
- select {
- case received := <-noticeError:
- if received.Message != expectedMsg {
- t.Errorf("Unexpected message received: %s", received.Message)
- }
- case <-time.After(time.Second):
- t.Error("Timed out; no notice received by Airbrake API")
- }
-}
-
-// TestLogEntryMessageReceived confirms that, when passing an error type using
-// logrus.Fields, a HTTP server emulating an Airbrake endpoint receives the
-// error message returned by the Error() method on the error interface
-// rather than the logrus.Entry.Message string.
-func TestLogEntryWithErrorReceived(t *testing.T) {
- log := logrus.New()
- ts := startAirbrakeServer(t)
- defer ts.Close()
-
- hook := NewHook(ts.URL, testAPIKey, "production")
- log.Hooks.Add(hook)
-
- log.WithFields(logrus.Fields{
- "error": &customErr{expectedMsg},
- }).Error(unintendedMsg)
-
- select {
- case received := <-noticeError:
- if received.Message != expectedMsg {
- t.Errorf("Unexpected message received: %s", received.Message)
- }
- if received.Class != expectedClass {
- t.Errorf("Unexpected error class: %s", received.Class)
- }
- case <-time.After(time.Second):
- t.Error("Timed out; no notice received by Airbrake API")
- }
-}
-
-// TestLogEntryWithNonErrorTypeNotReceived confirms that, when passing a
-// non-error type using logrus.Fields, a HTTP server emulating an Airbrake
-// endpoint receives the logrus.Entry.Message string.
-//
-// Only error types are supported when setting the 'error' field using
-// logrus.WithFields().
-func TestLogEntryWithNonErrorTypeNotReceived(t *testing.T) {
- log := logrus.New()
- ts := startAirbrakeServer(t)
- defer ts.Close()
-
- hook := NewHook(ts.URL, testAPIKey, "production")
- log.Hooks.Add(hook)
-
- log.WithFields(logrus.Fields{
- "error": expectedMsg,
- }).Error(unintendedMsg)
-
- select {
- case received := <-noticeError:
- if received.Message != unintendedMsg {
- t.Errorf("Unexpected message received: %s", received.Message)
- }
- case <-time.After(time.Second):
- t.Error("Timed out; no notice received by Airbrake API")
- }
-}
-
-func startAirbrakeServer(t *testing.T) *httptest.Server {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- var notice notice
- if err := xml.NewDecoder(r.Body).Decode(¬ice); err != nil {
- t.Error(err)
- }
- r.Body.Close()
-
- noticeError <- notice.Error
- }))
-
- return ts
-}