diff --git a/hooks/sentry/README.md b/hooks/sentry/README.md index 19e58bb..4e1c147 100644 --- a/hooks/sentry/README.md +++ b/hooks/sentry/README.md @@ -34,12 +34,13 @@ func main() { ## Special fields Some logrus fields have a special meaning in this hook, -these are server_name and logger. +these are `server_name`, `logger` and `http_request`. When logs are sent to sentry these fields are treated differently. -- server_name (also known as hostname) is the name of the server which +- `server_name` (also known as hostname) is the name of the server which is logging the event (hostname.example.com) -- logger is the part of the application which is logging the event. +- `logger` is the part of the application which is logging the event. In go this usually means setting it to the name of the package. +- `http_request` is the in-coming request(*http.Request). The detailed request data are sent to Sentry. ## Timeout diff --git a/hooks/sentry/sentry.go b/hooks/sentry/sentry.go index 379f281..e7e45b2 100644 --- a/hooks/sentry/sentry.go +++ b/hooks/sentry/sentry.go @@ -3,6 +3,7 @@ package logrus_sentry import ( "fmt" "time" + "net/http" "github.com/Sirupsen/logrus" "github.com/getsentry/raven-go" @@ -36,6 +37,22 @@ func getAndDel(d logrus.Fields, key string) (string, bool) { return val, true } +func getAndDelRequest(d logrus.Fields, key string) (*http.Request, bool) { + var ( + ok bool + v interface{} + req *http.Request + ) + if v, ok = d[key]; !ok { + return nil, false + } + if req, ok = v.(*http.Request); !ok || req == nil { + return nil, false + } + delete(d, key) + return req, true +} + // SentryHook delivers logs to a sentry server. type SentryHook struct { // Timeout sets the time to wait for a delivery error from the sentry server. @@ -61,7 +78,7 @@ func NewSentryHook(DSN string, levels []logrus.Level) (*SentryHook, error) { // Called when an event should be sent to sentry // Special fields that sentry uses to give more information to the server // are extracted from entry.Data (if they are found) -// These fields are: logger and server_name +// These fields are: logger, server_name and http_request func (hook *SentryHook) Fire(entry *logrus.Entry) error { packet := &raven.Packet{ Message: entry.Message, @@ -78,6 +95,9 @@ func (hook *SentryHook) Fire(entry *logrus.Entry) error { if serverName, ok := getAndDel(d, "server_name"); ok { packet.ServerName = serverName } + if req, ok := getAndDelRequest(d, "http_request"); ok { + packet.Interfaces = append(packet.Interfaces, raven.NewHttp(req)) + } packet.Extra = map[string]interface{}(d) _, errCh := hook.client.Capture(packet, nil) diff --git a/hooks/sentry/sentry_test.go b/hooks/sentry/sentry_test.go index 45f18d1..5f3696b 100644 --- a/hooks/sentry/sentry_test.go +++ b/hooks/sentry/sentry_test.go @@ -61,9 +61,12 @@ func TestSpecialFields(t *testing.T) { t.Fatal(err.Error()) } logger.Hooks.Add(hook) + + req, _ := http.NewRequest("GET", "url", nil) logger.WithFields(logrus.Fields{ - "server_name": server_name, - "logger": logger_name, + "server_name": server_name, + "logger": logger_name, + "http_request": req, }).Error(message) packet := <-pch