UNPKG

@sentry/google-cloud-serverless

Version:
115 lines (103 loc) • 3.39 kB
var { _optionalChain } = require('@sentry/utils'); Object.defineProperty(exports, '__esModule', { value: true }); const core = require('@sentry/core'); const node = require('@sentry/node'); const utils = require('@sentry/utils'); const SERVICE_PATH_REGEX = /^(\w+)\.googleapis.com$/; const INTEGRATION_NAME = 'GoogleCloudGrpc'; const SETUP_CLIENTS = new WeakMap(); const _googleCloudGrpcIntegration = ((options = {}) => { const optional = options.optional || false; return { name: INTEGRATION_NAME, setupOnce() { try { // eslint-disable-next-line @typescript-eslint/no-var-requires const gaxModule = require('google-gax'); utils.fill( gaxModule.GrpcClient.prototype, // eslint-disable-line @typescript-eslint/no-unsafe-member-access 'createStub', wrapCreateStub, ); } catch (e) { if (!optional) { throw e; } } }, setup(client) { SETUP_CLIENTS.set(client, true); }, }; }) ; /** * Google Cloud Platform service requests tracking for GRPC APIs. */ const googleCloudGrpcIntegration = core.defineIntegration(_googleCloudGrpcIntegration); /** Returns a wrapped function that returns a stub with tracing enabled */ function wrapCreateStub(origCreate) { return async function ( ...args) { const servicePath = _optionalChain([args, 'access', _ => _[1], 'optionalAccess', _2 => _2.servicePath]); if (servicePath == null || servicePath == undefined) { return origCreate.apply(this, args); } const serviceIdentifier = identifyService(servicePath); const stub = await origCreate.apply(this, args); for (const methodName of Object.keys(Object.getPrototypeOf(stub))) { fillGrpcFunction(stub, serviceIdentifier, methodName); } return stub; }; } /** Patches the function in grpc stub to enable tracing */ function fillGrpcFunction(stub, serviceIdentifier, methodName) { const funcObj = stub[methodName]; if (typeof funcObj !== 'function') { return; } const callType = !funcObj.requestStream && !funcObj.responseStream ? 'unary call' : funcObj.requestStream && !funcObj.responseStream ? 'client stream' : !funcObj.requestStream && funcObj.responseStream ? 'server stream' : 'bidi stream'; if (callType != 'unary call') { return; } utils.fill( stub, methodName, (orig) => (...args) => { const ret = orig.apply(stub, args); if (typeof _optionalChain([ret, 'optionalAccess', _3 => _3.on]) !== 'function' || !SETUP_CLIENTS.has(core.getClient() )) { return ret; } const span = node.startInactiveSpan({ name: `${callType} ${methodName}`, onlyIfParent: true, op: `grpc.${serviceIdentifier}`, attributes: { [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.grpc.serverless', }, }); ret.on('status', () => { if (span) { span.end(); } }); return ret; }, ); } /** Identifies service by its address */ function identifyService(servicePath) { const match = servicePath.match(SERVICE_PATH_REGEX); return match ? match[1] : servicePath; } exports.googleCloudGrpcIntegration = googleCloudGrpcIntegration; //# sourceMappingURL=google-cloud-grpc.js.map