@sentry/google-cloud-serverless
Version:
Official Sentry SDK for Google Cloud Functions
88 lines (85 loc) • 2.9 kB
JavaScript
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