This module provides hooks registrator for Logrus to simplify logging to external error tracking systems. Currently only Sentry system supported based on official SDK for Go.
Supported Go versions are:
- 1.10
- 1.11
- 1.12
go-reporting
can be installed like any other Go library through go get
:
$ go get github.com/Vinelab/go-reporting
To register Sentry hook for Logrus
package main
import (
"github.com/Vinelab/go-reporting"
"github.com/Vinelab/go-reporting/sentry"
log "github.com/sirupsen/logrus"
)
func main() {
_ = reporting.RegisterSentry(
log.InfoLevel,
sentry.Options{},
}
Minimum logging level and Sentry SDK options can be specified on hook registration.
Default Sentry SDK options are:
var DefaultSentryConfig = Options{
Dsn: os.Getenv("SENTRY_DSN"),
Environment: os.Getenv("APP_ENV"),
}
Environment variables
-
APP_ENV
- application environment, used by sentry events -
SENTRY_DSN
- dsn for authorization in sentry -
SENTRY_SYNC_DELIVERY
- true/false for sync message delivery to sentry service, concurrent async sending by default -
SENTRY_TIMEOUT
- connection timeout to sentry server 15 sec by default
Sentry DSN for authorization and application environment can be passed via .env file using SENTRY_DSN
and APP_ENV
variables.
Module supports injectors for sentry event data using BeforeSend
hook. This allows to pass dynamically generated data to sentry right before sending an event. This can be useful for integrations with other modules. Currently only TagsInjector
is supported
package main
import (
"github.com/Vinelab/go-reporting"
"github.com/Vinelab/go-reporting/sentry"
log "github.com/sirupsen/logrus"
"time"
)
func main() {
_ = reporting.RegisterSentry(
log.InfoLevel,
sentry.SentryOptions{},
sentry.TagInjector{
Tags: func() map[string]string {
return map[string]string{
"date": time.Now().String(),
"exchange_rate": currensy.USDToEUR(),
}
}}
}
To capture http request data into sentry event LogResponseMiddleware
should be added to the defined routes
import (
"github.com/go-chi/chi"
"github.com/Vinelab/go-reporting/sentry"
"net/http"
)
// Register holds the routes to be registered
// when the server starts listening
func Register() *chi.Mux {
router := chi.NewRouter()
//add sentry middleware
router.Use(sentry.LogResponseMiddleware())
router.Get("/user", handler)
return router
}
Sentry supports breadcrumbs
for customization events and better application flow visibility. Module provides simple way for adding breadcrumbs to logs
sentry.AddBreadcrumb(sentry.Breadcrumb{
Category: "Log initialised",
Message: "Sentry hook was registered in Logrus",
Data: map[string]interface{}{
"key" : "value",
},
})
Module works with Logrus logger so logging and reporting should be performed via Logrus methods.
Info message
log.WithFields(log.Fields{
"product_id": 10,
"description": "Amazon Kindle",
}).Info("Product was purchased")
Fields will be recorded as extra
data in sentry event
Error message
log.WithError(err).Error("Something went wrong")
Stacktrace and error type (if any) will be automatically extracted into sentry event
Module provides recovery function for logging panic errors into all registered error reporting services. Function logs panic error as Fatal
and re-panic at the end. Deffer call should be added to main routine and to any other goroutine since panic is thrown in goroutine scope only.
package main
import (
"github.com/Vinelab/go-reporting"
)
func main() {
defer reporting.LogPanic()
//application code here
}
Server can handle requests in separate goroutines, in this case LogPanicMiddleware can be used to log panic errors. Note that deferred functions executed using stack order LIFO. So in example below log middleware should be registered after recover
package routes
import (
"github.com/Vinelab/go-reporting"
"github.com/go-chi/chi"
chiMiddleware "github.com/go-chi/chi/middleware"
"github.com/Vinelab/go-reporting/sentry"
"net/http"
)
// Register holds the routes to be registered
// when the server starts listening
func Register() *chi.Mux {
router := chi.NewRouter()
router.Use(chiMiddleware.Recoverer)
router.Use(reporting.LogPanicMiddleware)
router.Get("/users", handler)
return router
}