appdynamics
Version:
Performance Profiler and Monitor
107 lines (89 loc) • 2.85 kB
JavaScript
/*
Copyright (c) AppDynamics, Inc., and its affiliates
2015
All Rights Reserved
*/
;
function GrpcEntryProbe(agent) {
this.agent = agent;
}
exports.GrpcEntryProbe = GrpcEntryProbe;
GrpcEntryProbe.prototype.init = function () {
};
GrpcEntryProbe.prototype.attach = function (obj) {
var self = this;
self.agent.proxy.after(obj.Server.prototype, ['register'], function (obj, args) {
var serviceName = args[0];
var type = args[4];
if (!serviceName || !type) return;
var handlerSet = obj.handlers.get(serviceName);
if (!handlerSet) return;
var original = handlerSet.func;
handlerSet.func = self.createWrapperFunc(original, serviceName, type);
});
};
GrpcEntryProbe.prototype.createWrapperFunc = function(original, serviceName, type) {
var self = this;
return function() {
var args = arguments;
self.agent.context.runGeneric(handlerFunc, args);
function handlerFunc() {
var call = arguments[0];
if(!call) return;
self.agent.context.bindEmitter(call);
var profiler = self.agent.profiler;
var time = profiler.time(true);
var req = {url: serviceName, method: null, headers: {}, type: 'GRPC', metadata: call.metadata};
var transaction = profiler.startTransaction(time, req, 'NODEJS_WEB');
self.agent.context.set('threadId', transaction.threadId);
switch(type) {
case 'unary':
case 'clientStream':
case 'client_stream':
self.agent.proxy.callback(arguments, -1, self._clientStreamAndUnaryHandler.bind(self, time, transaction));
break;
case 'serverStream':
case 'server_stream':
case 'bidi':
self._serverStreamAndBidiHandler(time, transaction, call);
break;
}
return original.apply(this, arguments);
}
};
};
GrpcEntryProbe.prototype._clientStreamAndUnaryHandler = function(time, transaction, cbCtxt, cbArgs) {
var self = this;
var profiler = self.agent.profiler;
var error = cbArgs[0];
if (error) {
if(error.code) {
var errorObject = { message: error.message, name: "GRPC Error code " + error.code };
transaction.error = errorObject;
}
}
profiler.endTransaction(time, transaction);
};
GrpcEntryProbe.prototype._serverStreamAndBidiHandler = function(time, transaction, call) {
var self = this;
var profiler = self.agent.profiler;
var spanEnded = false;
const endSpan = (time, tx) => {
if (!spanEnded) {
spanEnded = true;
profiler.endTransaction(time, tx);
}
};
call.on('finish', () => {
endSpan(time, transaction);
});
call.on('error', (err) => {
if (err) {
if(err.code) {
var errorObject = { message: err.message, name: "GRPC Error code " + err.code };
transaction.error = errorObject;
}
}
endSpan(time, transaction);
});
};