Skip to content

Commit

Permalink
Merge pull request #11 from zentered/fix/trace-data
Browse files Browse the repository at this point in the history
fix: add missing request to trace'
  • Loading branch information
PatrickHeneise authored Sep 22, 2021
2 parents a34c82b + 8df5578 commit 9e47a18
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 4 deletions.
26 changes: 22 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const fp = require('fastify-plugin')
const Sentry = require('@sentry/node')
const Tracing = require('@sentry/tracing') // eslint-disable-line no-unused-vars
const extractRequestData = require('./lib/extractRequestData.js')

function sentryConnector(fastify, opts, next) {
if (!opts || !opts.dsn) {
Expand All @@ -22,10 +23,27 @@ function sentryConnector(fastify, opts, next) {

fastify.decorateRequest('sentryTransaction', null)
fastify.addHook('onRequest', async (request) => {
request.sentryTransaction = Sentry.startTransaction({
op: 'request',
name: `${request.method} ${request.url}`
})
// If there is a trace header set, we extract the data from it (parentSpanId, traceId, and sampling decision)
let traceparentData
if (
request.headers &&
typeof request.headers['sentry-trace'] === 'string'
) {
traceparentData = Tracing.extractTraceparentData(
request.headers['sentry-trace']
)
}

const extractedRequestData = extractRequestData(request)

request.sentryTransaction = Sentry.startTransaction(
{
op: 'request',
name: `${request.method} ${request.url}`,
...traceparentData
},
{ request: extractedRequestData }
)
return
})

Expand Down
48 changes: 48 additions & 0 deletions lib/extractRequestData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict'

const DEFAULT_REQUEST_KEYS = ['headers', 'method', 'query_string', 'url']

/**
* Function copied from
* https://github.com/getsentry/sentry-javascript/blob/master/packages/node/src/handlers.ts
* and mofidied for Fastify
*
* Data (req.body) isn't available in onRequest hook,
* as it is parsed later in the fastify lifecycle
* https://www.fastify.io/docs/latest/Hooks/#onrequest
*/
function extractRequestData(req, keys) {
if (!keys || keys.length <= 0 || typeof keys !== 'object') {
keys = DEFAULT_REQUEST_KEYS
}
const requestData = {}
const headers = req.headers || {}
const method = req.method
const host = req.hostname
const protocol = req.protocol
const originalUrl = req.url
const absoluteUrl = protocol + '://' + host + originalUrl
keys.forEach(function (key) {
switch (key) {
case 'headers':
requestData.headers = headers
break
case 'method':
requestData.method = method
break
case 'url':
requestData.url = absoluteUrl
break
case 'query_string':
requestData.query_string = Object.assign({}, req.query)
break
default:
if ({}.hasOwnProperty.call(req, key)) {
requestData[key] = req[key]
}
}
})
return requestData
}

module.exports = exports = extractRequestData
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions test/error-handler.js → test/error-handler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ tap.test('sentryConnector with custom error handler', async (test) => {

const response = await fastify.inject({
method: 'POST',
headers: { 'sentry-trace': 'testing trace' },
url: '/',
payload: { error: 503, message: 'Internal Server Error' }
})
Expand Down
40 changes: 40 additions & 0 deletions test/extractRequestData.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict'

/* eslint-disable node/no-unpublished-require */
const tap = require('tap')
const fn = require('../lib/extractRequestData')

tap.test('extractedRequestData should process fastify request', (test) => {
test.plan(1)
const request = {
headers: {
host: 'localhost:3000',
accept: '/*/'
},
hostname: 'localhost:3000',
protocol: 'http',
method: 'GET',
url: '/testing'
}

const expected = {
headers: { host: 'localhost:3000', accept: '/*/' },
method: 'GET',
query_string: {},
url: 'http://localhost:3000/testing'
}

const actual = fn(request)
test.strictSame(actual, expected)
})

tap.test('extractedRequestData should process other keys', (test) => {
test.plan(2)
const request = {
testing: 'testing'
}

const actual = fn(request, ['testing', 'testing2'])
test.equal(actual.testing, 'testing')
test.equal(actual.testing2, undefined)
})

0 comments on commit 9e47a18

Please sign in to comment.