UNPKG

appdynamics

Version:

Performance Profiler and Monitor

186 lines (158 loc) 5.73 kB
/* This is for apollo-server entry probe */ let HttpCommon = require("./http-common"); exports.ApolloEntryProbe = ApolloEntryProbe; function ApolloEntryProbe(agent) { this.agent = agent; } ApolloEntryProbe.prototype.init = function () {}; ApolloEntryProbe.prototype.attach = function (obj, moduleName) { let self = this; if(process.env.APPDYNAMICS_APOLLO_PROBE_DISABLE == true || process.env.APPDYNAMICS_APOLLO_PROBE_DISABLE == 'true') { return; } if(moduleName == 'apollo-server') { self.agent.proxy.before( obj.ApolloServer.prototype, "createServerInfo", (args) => this.addLifeCycleHooks(args) ); } else if (moduleName === '@apollo/server') { const originalObject = obj; const overriddenObject = {}; overriddenObject.ApolloServer = proxyApolloServer(self, originalObject); return overriddenObject; } else if(moduleName === '@apollo/server/express4') { const originalObject = obj; const overriddenObject = {}; overriddenObject.expressMiddleware = proxyExpressMiddleware(self, originalObject); overriddenObject.__proto__ = originalObject; return overriddenObject; } else if(moduleName === '@apollo/server/standalone'){ const originalObject = obj; const overriddenObject = {}; overriddenObject.startStandaloneServer = proxyStartStandaloneServer(self, originalObject); overriddenObject.__proto__ = originalObject; return overriddenObject; } }; ApolloEntryProbe.prototype.addLifeCycleHooks = function (obj) { let self = this; let userDefinedContext = obj.context; obj.context = function ({ req, res }) { let userCtx; if (userDefinedContext instanceof Function) { userCtx = userDefinedContext.call(this, ...arguments); } else if (userDefinedContext instanceof Object) { userDefinedContext.gqlReq = req; userDefinedContext.gqlRes = res; return userDefinedContext; } return Object.assign({ gqlReq: req, gqlRes: res }, userCtx); }; obj.plugins = [ { requestDidStart() { return { didResolveOperation(response) { response.context.gqlReq.graphqlop = response.operationName; response.context.gqlReq.transactionStarted = true; HttpCommon.startTransactionHandler( response.context.gqlReq, response.context.gqlRes, self.agent ); }, didEncounterErrors(response) { response.context.gqlRes.error = response.errors[0]; if(response.context.gqlReq.transactionStarted) { return; } HttpCommon.startTransactionHandler( response.context.gqlReq, response.context.gqlRes, self.agent ); }, }; }, }, ...obj.plugins, ]; }; function appDynamicsApolloServerPlugin(self) { const plugin = { async requestDidStart() { return { didResolveOperation(requestContext) { if(!requestContext.contextValue.gqlReq) { requestContext.contextValue.gqlReq = {}; requestContext.contextValue.gqlRes = {}; } requestContext.contextValue.gqlReq.graphqlop = requestContext.operationName; requestContext.contextValue.gqlReq.transactionStarted = true; HttpCommon.startTransactionHandler( requestContext.contextValue.gqlReq, requestContext.contextValue.gqlRes, self.agent ); }, didEncounterErrors(requestContext) { if(!requestContext.contextValue.gqlReq) { requestContext.contextValue.gqlReq = {}; requestContext.contextValue.gqlRes = {}; } requestContext.contextValue.gqlRes.error = requestContext.errors[0]; if(requestContext.contextValue.gqlReq.transactionStarted) { return; } HttpCommon.startTransactionHandler( requestContext.contextValue.gqlReq, requestContext.contextValue.gqlRes, self.agent ); }, }; } }; return plugin; } function appDymanicsApolloServerOverriddenOptions(options) { const overriddenOptions = options || {}; const context = options ? options.context : undefined; const overriddenContext = async function (contextParam) { const contextValue = context ? await context(contextParam) : {}; contextParam.req.url = contextParam.req.baseUrl; // For Apollo Server 4 contextValue.gqlReq = contextParam.req; contextValue.gqlRes = contextParam.res; return contextValue; }; overriddenOptions.context = overriddenContext; return overriddenOptions; } function proxyApolloServer(self, originalObject) { const ApolloServer = originalObject.ApolloServer; // Define ApolloServerProxy class class ApolloServerProxy extends ApolloServer { constructor(config) { // Call the ApolloServer constructor super(config); // Add the plugin to the plugins array this.addPlugin(appDynamicsApolloServerPlugin(self)); } } return ApolloServerProxy; } function proxyStartStandaloneServer(self, originalObject) { return async function startStandaloneServerProxy(server, options) { const overriddenOptions = appDymanicsApolloServerOverriddenOptions(options); return await originalObject.startStandaloneServer(server, overriddenOptions); }; } function proxyExpressMiddleware(self, originalObject) { return function expressMiddlewareProxy(server, options) { const overriddenOptions = appDymanicsApolloServerOverriddenOptions(options); return originalObject.expressMiddleware(server, overriddenOptions); }; }