UNPKG

@sentry/google-cloud-serverless

Version:
88 lines (85 loc) • 2.9 kB
import { RPC_METHOD, RPC_SERVICE, RPC_SYSTEM_NAME, SENTRY_ORIGIN, SENTRY_OP } from '@sentry/conventions/attributes'; import { GRPC } from '@sentry/conventions/op'; import { defineIntegration, fill, getClient } from '@sentry/core'; import { startInactiveSpan } from '@sentry/node'; const SERVICE_PATH_REGEX = /^(\w+)\.googleapis.com$/; const INTEGRATION_NAME = "GoogleCloudGrpc"; const SETUP_CLIENTS = /* @__PURE__ */ new WeakMap(); const _googleCloudGrpcIntegration = ((options = {}) => { const optional = options.optional || false; return { name: INTEGRATION_NAME, setupOnce() { try { const gaxModule = require("google-gax"); 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); } }; }); const googleCloudGrpcIntegration = defineIntegration(_googleCloudGrpcIntegration); function wrapCreateStub(origCreate) { return async function(...args) { const servicePath = args[1]?.servicePath; if (servicePath == null || servicePath == void 0) { 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; }; } 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; } fill(stub, methodName, (orig) => (...args) => { const ret = orig.apply(stub, args); if (typeof ret?.on !== "function" || !SETUP_CLIENTS.has(getClient())) { return ret; } const span = startInactiveSpan({ name: `${callType} ${methodName}`, onlyIfParent: true, attributes: { [SENTRY_OP]: GRPC, [SENTRY_ORIGIN]: "auto.grpc.serverless", [RPC_SYSTEM_NAME]: "grpc", [RPC_SERVICE]: serviceIdentifier, [RPC_METHOD]: methodName } }); ret.on("status", () => { if (span) { span.end(); } }); return ret; }); } function identifyService(servicePath) { const match = servicePath.match(SERVICE_PATH_REGEX); return match?.[1] || servicePath; } export { fillGrpcFunction, googleCloudGrpcIntegration }; //# sourceMappingURL=google-cloud-grpc.js.map