UNPKG

@sentry/node

Version:
144 lines 4.97 kB
import { getCurrentHub } from '@sentry/core'; import { fill, parseSemver } from '@sentry/utils'; var NODE_VERSION = parseSemver(process.versions.node); /** http module integration */ var Http = /** @class */ (function () { /** * @inheritDoc */ function Http(options) { if (options === void 0) { options = {}; } /** * @inheritDoc */ this.name = Http.id; this._breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs; this._tracing = typeof options.tracing === 'undefined' ? false : options.tracing; } /** * @inheritDoc */ Http.prototype.setupOnce = function () { // No need to instrument if we don't want to track anything if (!this._breadcrumbs && !this._tracing) { return; } var handlerWrapper = createHandlerWrapper(this._breadcrumbs, this._tracing); var httpModule = require('http'); fill(httpModule, 'get', handlerWrapper); fill(httpModule, 'request', handlerWrapper); // NOTE: Prior to Node 9, `https` used internals of `http` module, thus we don't patch it. // If we do, we'd get double breadcrumbs and double spans for `https` calls. // It has been changed in Node 9, so for all versions equal and above, we patch `https` separately. if (NODE_VERSION.major && NODE_VERSION.major > 8) { var httpsModule = require('https'); fill(httpsModule, 'get', handlerWrapper); fill(httpsModule, 'request', handlerWrapper); } }; /** * @inheritDoc */ Http.id = 'Http'; return Http; }()); export { Http }; /** * Wrapper function for internal `request` and `get` calls within `http` and `https` modules */ function createHandlerWrapper(breadcrumbsEnabled, tracingEnabled) { return function handlerWrapper(originalHandler) { return function (options) { var requestUrl = extractUrl(options); if (isSentryRequest(requestUrl)) { return originalHandler.apply(this, arguments); } var span; var transaction; var scope = getCurrentHub().getScope(); if (scope && tracingEnabled) { transaction = scope.getTransaction(); if (transaction) { span = transaction.startChild({ description: (typeof options === 'string' || !options.method ? 'GET' : options.method) + " " + requestUrl, op: 'request', }); } } return originalHandler .apply(this, arguments) .once('response', function (res) { if (breadcrumbsEnabled) { addRequestBreadcrumb('response', requestUrl, this, res); } if (tracingEnabled && span) { span.setHttpStatus(res.statusCode); span.finish(); } }) .once('error', function () { if (breadcrumbsEnabled) { addRequestBreadcrumb('error', requestUrl, this); } if (tracingEnabled && span) { span.setHttpStatus(500); span.finish(); } }); }; }; } /** * Captures Breadcrumb based on provided request/response pair */ function addRequestBreadcrumb(event, url, req, res) { if (!getCurrentHub().getIntegration(Http)) { return; } getCurrentHub().addBreadcrumb({ category: 'http', data: { method: req.method, status_code: res && res.statusCode, url: url, }, type: 'http', }, { event: event, request: req, response: res, }); } /** * Function that can combine together a url that'll be used for our breadcrumbs. * * @param options url that should be returned or an object containing it's parts. * @returns constructed url */ function extractUrl(options) { if (typeof options === 'string') { return options; } var protocol = options.protocol || ''; var hostname = options.hostname || options.host || ''; // Don't log standard :80 (http) and :443 (https) ports to reduce the noise var port = !options.port || options.port === 80 || options.port === 443 ? '' : ":" + options.port; var path = options.path || '/'; return protocol + "//" + hostname + port + path; } /** * Checks whether given url points to Sentry server * @param url url to verify */ function isSentryRequest(url) { var client = getCurrentHub().getClient(); if (!url || !client) { return false; } var dsn = client.getDsn(); if (!dsn) { return false; } return url.indexOf(dsn.host) !== -1; } //# sourceMappingURL=http.js.map