elastic-apm-node
Version:
The official Elastic APM agent for Node.js
58 lines (44 loc) • 2.14 kB
JavaScript
var semver = require('semver')
var httpShared = require('../http-shared')
var shimmer = require('../shimmer')
module.exports = function (http, agent, { enabled }) {
if (!enabled) return http
agent.logger.debug('shimming http.Server.prototype.emit function')
shimmer.wrap(http && http.Server && http.Server.prototype, 'emit', httpShared.instrumentRequest(agent, 'http'))
agent.logger.debug('shimming http.request function')
shimmer.wrap(http, 'request', httpShared.traceOutgoingRequest(agent, 'http', 'request'))
if (semver.gte(process.version, '8.0.0')) {
agent.logger.debug('shimming http.get function')
shimmer.wrap(http, 'get', httpShared.traceOutgoingRequest(agent, 'http', 'get'))
}
agent.logger.debug('shimming http.ServerResponse.prototype.writeHead function')
shimmer.wrap(http && http.ServerResponse && http.ServerResponse.prototype, 'writeHead', wrapWriteHead)
return http
function wrapWriteHead (original) {
return function wrappedWriteHead () {
var headers = arguments.length === 1
? this._headers // might be because of implicit headers
: arguments[arguments.length - 1]
var result = original.apply(this, arguments)
var trans = httpShared.transactionForResponse.get(this)
if (trans) {
httpShared.transactionForResponse.delete(this)
// It shouldn't be possible for the statusCode to be falsy, but just in
// case we're in a bad state we should avoid throwing
trans.result = 'HTTP ' + (this.statusCode || '').toString()[0] + 'xx'
// End transacton early in case of SSE
if (headers && typeof headers === 'object' && !Array.isArray(headers)) {
Object.keys(headers).some(function (key) {
if (key.toLowerCase() !== 'content-type') return false
if (String(headers[key]).toLowerCase().indexOf('text/event-stream') !== 0) return false
agent.logger.debug('detected SSE response - ending transaction %o', { id: trans.id })
agent.endTransaction()
return true
})
}
}
return result
}
}
}