@sentry/core
Version:
Base implementation for all Sentry JavaScript SDKs
114 lines (104 loc) • 4.05 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const getDefaultExport = require('../../utils/get-default-export.js');
const constants = require('./constants.js');
const object = require('../../utils/object.js');
const clientSubscriptions = require('./client-subscriptions.js');
/**
* Platform-portable HTTP(S) outgoing-request patching integration
*
* Patches the `http` and `https` Node.js built-in module exports to create
* Sentry spans for outgoing requests and optionally inject distributed trace
* propagation headers.
*
* @module
*
* This Sentry integration is a derivative work based on the OpenTelemetry
* HTTP instrumentation.
*
* <https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-http>
*
* Extended under the terms of the Apache 2.0 license linked below:
*
* ----
*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function patchHttpRequest(httpModule, options) {
// avoid double-wrap
if (!object.getOriginalFunction(httpModule.request)) {
const { [constants.HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated } = clientSubscriptions.getHttpClientSubscriptions({
...options,
http: httpModule,
});
const originalRequest = httpModule.request;
object.wrapMethod(httpModule, 'request', function patchedRequest( ...args) {
const request = originalRequest.apply(this, args) ;
onHttpClientRequestCreated({ request }, constants.HTTP_ON_CLIENT_REQUEST);
return request;
});
}
}
// This simply ensures that http.get calls http.request, which we patched.
// Call it from the object each time, to ensure that any subsequent patches
// or other mutations are also respected.
function patchHttpGet(httpModule) {
if (!object.getOriginalFunction(httpModule.get)) {
// match node's normalization to exactly 3 arguments.
object.wrapMethod(httpModule, 'get', function patchedGet( input, options, cb) {
// http.get is like http.request but automatically calls .end()
const request = httpModule.request.call(this, input, options, cb) ;
request.end();
return request;
});
}
}
function patchModule(httpModuleExport, options = {}) {
const httpDefault = getDefaultExport.getDefaultExport(httpModuleExport);
const httpModule = httpModuleExport ;
// if we have a default, patch that, and copy to the import container
if (httpDefault !== httpModuleExport) {
patchModule(httpDefault, options);
// copy with defineProperty because these might be configured oddly
for (const method of ['get', 'request']) {
const desc = Object.getOwnPropertyDescriptor(httpDefault, method);
/* v8 ignore start - will always be set at this point */
if (desc) {
Object.defineProperty(httpModule, method, desc);
}
/* v8 ignore stop */
}
return httpModule;
}
patchHttpRequest(httpModule, options);
patchHttpGet(httpModule);
return httpModuleExport;
}
/**
* Patch an `node:http` or `node:https` module-shaped export so that every
* outgoing request is tracked by Sentry.
*
* @example
* ```javascript
* import http from 'http';
* import { patchHttpModule } from '@sentry/core';
* patchHttpModule(http, { propagateTrace: true });
* ```
*/
const patchHttpModuleClient = (
httpModuleExport,
options = {},
) => patchModule(httpModuleExport, options);
exports.patchHttpModuleClient = patchHttpModuleClient;
//# sourceMappingURL=client-patch.js.map