Skip to content

Commit

Permalink
Merge pull request #385 from alphagov/sengi/sentry-cleanup
Browse files Browse the repository at this point in the history
Lightly clean up Sentry event logging.
  • Loading branch information
theseanything authored Aug 28, 2024
2 parents 367eade + 51efa77 commit 528a578
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 36 deletions.
57 changes: 21 additions & 36 deletions logger/sentry.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import (
"log"
"net"
"net/http"
"time"

sentry "github.com/getsentry/sentry-go"
)

// TODO: use the Sentry API as intended + remove these wonky, reinvented wheels.
// See https://docs.sentry.io/platforms/go/guides/http/.

type RecoveredError struct {
ErrorMessage string
}
Expand All @@ -24,53 +26,36 @@ type ReportableError struct {
Response *http.Response
}

func (re ReportableError) hint() *sentry.EventHint {
return &sentry.EventHint{
Request: re.Request,
Response: re.Response,
}
}

func (re ReportableError) scope() *sentry.Scope {
scope := sentry.NewScope()
if re.hint().Request != nil {
scope.SetRequest(re.hint().Request)
}
if re.hint().Response != nil {
scope.SetExtra("Response Status", re.hint().Response.Status)
func InitSentry() {
if err := sentry.Init(sentry.ClientOptions{}); err != nil {
log.Printf("sentry.Init failed: %v\n", err)
}
return scope
}

func (re ReportableError) timeoutError() bool {
// Timeout returns true if and only if this ReportableError is a timeout.
func (re ReportableError) Timeout() bool {
var oerr *net.OpError
if errors.As(re.Error, &oerr) {
return oerr.Timeout()
}
return false
}

func (re ReportableError) ignorableError() bool {
// We don't want to hear about timeouts. These get visibility elsewhere.
return re.timeoutError()
}

// NotifySentry sends an event to sentry.io. Sentry is configurable via the
// environment variables SENTRY_ENVIRONMENT, SENTRY_DSN, SENTRY_RELEASE.
func NotifySentry(re ReportableError) {
if re.ignorableError() {
return
}

// We don't need to set SENTRY_ENVIRONMENT, SENTRY_DSN or SENTRY_RELEASE
// in ClientOptions as they are automatically picked up as env vars.
// https://docs.sentry.io/platforms/go/config/
client, err := sentry.NewClient(sentry.ClientOptions{})

if err != nil {
log.Printf("router: Sentry initialization failed: %v\n", err)
if re.Timeout() {
return
}

hub := sentry.NewHub(client, re.scope())
hub.CaptureException(re.Error)
sentry.Flush(time.Second * 5)
hub := sentry.CurrentHub().Clone()
hub.WithScope(func(s *sentry.Scope) {
if re.Request != nil {
s.SetRequest(re.Request)
}
if re.Response != nil {
s.SetExtra("Response Status", re.Response.Status)
}
hub.CaptureException(re.Error)
})
}
6 changes: 6 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (

"github.com/alphagov/router/handlers"
router "github.com/alphagov/router/lib"
"github.com/alphagov/router/logger"
sentry "github.com/getsentry/sentry-go"
"github.com/prometheus/client_golang/prometheus"
)

Expand Down Expand Up @@ -130,6 +132,10 @@ func main() {
if err != nil {
log.Fatal(err)
}

logger.InitSentry()
defer sentry.Flush(2 * time.Second)

log.Printf("router: listening for API requests on %v", apiAddr)
listenAndServeOrFatal(apiAddr, api, feReadTimeout, feWriteTimeout)
}

0 comments on commit 528a578

Please sign in to comment.