Skip to content

Commit

Permalink
feat: add sentry tracing
Browse files Browse the repository at this point in the history
  • Loading branch information
PatrickHeneise committed Sep 14, 2021
1 parent f01554e commit a0d023f
Show file tree
Hide file tree
Showing 6 changed files with 421 additions and 23 deletions.
25 changes: 11 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
## Installation

```bash
npm i @zentered/fastify-sentry -s
npm i @zentered/fastify-sentry

or

Expand All @@ -26,32 +26,29 @@ const errorHandler = (err, req, reply) => {
})
}

fastify.register(fastifySentry, {
dsn: 'https://[email protected]/0000000',
environment: 'test',
errorHandler: errorHandler
app.register(fastifySentry, {
dsn: process.env.SENTRY_DSN,
environment: 'development',
tracing: true,
tracesSampleRate: 1.0
})

fastify.get('/', async (request, reply) => {
// Errors in async functions are automatically caught
throw new Error('Oops')
})

fastify.get('/other-path', (request, reply) => {
// On the other hand, you need to pass the Error object to "reply.send" for it to be logged as Fastify does not catch errors in synchronous functions!
reply.send(new Error('I did it again!'))
})
```

## Description

This plugin adds the Sentry SDK error handler by using `fastify.setErrorHandler`. This means that the Sentry SDK will only catch any errors thrown in routes with `async` functions. In order to properly log errors thrown within synchronous functions, you need to pass the error object within `reply.send`. It also adds certain metadata, namely the `path` and the `ip` parameters of `req.raw`, to both the `User` context and `Tag` context of Sentry. If you use jwt authentication, the user id is also added to Sentry.
This plugin adds the Sentry SDK error handler by using `setErrorHandler`. It also adds certain metadata, namely the `path` and the `ip` parameters of the request, to both the `User` context and `Tag` context of Sentry. If you use jwt authentication, the user id is also added to Sentry.

## Options

| Option | Description |
| ------ | ------------------------------------------------------------------- |
| `dsn` | Required, the DSN specified by Sentry.io to properly log errors to. |
| Option | Description |
| --------- | ------------------------------------------------------------------- |
| `dsn` | Required, the DSN specified by Sentry.io to properly log errors to. |
| `tracing` | Default `false`, enable Sentry tracing. |

You can find further options in the [Node.js Guide on Sentry.io](https://docs.sentry.io/platforms/node/)

Expand Down
54 changes: 46 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,63 @@ const Sentry = require('@sentry/node')
const Tracing = require('@sentry/tracing') // eslint-disable-line no-unused-vars

function sentryConnector(fastify, opts, next) {
if (!opts || !opts.dsn) {
return next(new Error('Sentry DSN is required.'))
}

if (opts.tracing === true) {
opts.integrations = [
new Sentry.Integrations.Http({ tracing: true }),
new Tracing.Integrations.Express({
fastify
})
]
}

Sentry.init(opts)
fastify.setErrorHandler((err, req, reply) => {

fastify.decorateRequest('sentryTransaction', null)
fastify.addHook('onRequest', async (request) => {
request.sentryTransaction = Sentry.startTransaction({
op: 'request',
name: `${request.method} ${request.url}`
})
return
})

fastify.addHook('onResponse', async (request, reply) => {
setImmediate(() => {
const transaction = request.sentryTransaction
transaction.setData('url', request.url)
transaction.setData('query', request.query)
transaction.setHttpStatus(reply.statusCode)
transaction.finish()
})
return
})

fastify.setErrorHandler((error, request, reply) => {
Sentry.withScope((scope) => {
if (req && req.user && req.user.sub) {
if (request && request.user && request.user.sub) {
scope.setUser({
id: req.user.sub,
ip_address: req.ip
id: request.user.sub,
ip_address: request.ip
})
} else {
scope.setUser({
ip_address: req.ip
ip_address: request.ip
})
}
scope.setTag('path', req.url)
scope.setTag('path', request.url)
// will be tagged with my-tag="my value"
Sentry.captureException(err)
opts.errorHandler ? opts.errorHandler(err, req, reply) : reply.send(err)
Sentry.captureException(error)
opts.errorHandler
? opts.errorHandler(error, request, reply)
: reply.send(error)
})
return
})

next()
}

Expand Down
Loading

0 comments on commit a0d023f

Please sign in to comment.