appdynamics
Version:
Performance Profiler and Monitor
150 lines (124 loc) • 5.21 kB
JavaScript
/*
* Copyright (c) AppDynamics, Inc., and its affiliates
* 2016
* All Rights Reserved
*/
var utility = require('../utility');
function TransactionSender(agent) {
this.agent = agent;
this.btNamingConfig = undefined;
this.isEnabled = false;
}
exports.TransactionSender = TransactionSender;
TransactionSender.prototype.init = function() {
var self = this;
var libagentConnector = self.agent.libagentConnector;
libagentConnector.on("btNamingProperties", function() {
self.isEnabled = true;
});
self.agent.on("serviceEndpointStart", function(sep, req) {
if (!self.isEnabled) {
self.agent.logger.warn('serviceEndpointStart sent without enabled sender');
return;
}
var sepData = libagentConnector.startServiceEndpoint('NODEJS_WEB', utility.createBtNamingWrapper(req));
if (sepData === undefined || sepData.isExcluded) {
sep.skip = true;
return;
}
sep.skip = false;
sep.name = sepData.name;
sep.sepGuid = sepData.sepGuid;
});
self.agent.on("serviceEndpointStop", function(sep) {
if (!self.isEnabled || sep.skip) {
return;
}
libagentConnector.stopServiceEndpoint(sep);
});
self.agent.on("transactionStarted", function(transaction, req) {
if (!self.isEnabled) {
self.agent.logger.warn('transactionStarted sent without enabled sender');
return;
}
var apiCall = transaction.entryType === 'NODEJS_API';
var corrHeader = '';
var name = '';
var isHttpRequest = false;
if (apiCall && typeof(req) === 'string') {
// req is the transaction name
name = transaction.name = req;
} else if (req.type && req.type == 'GRPC') {
if(req.metadata && req.metadata.get('singularityheader')) {
corrHeader = req.metadata.get('singularityheader');
}
} else {
if (typeof(req) === 'object' && req.headers) {
isHttpRequest = true;
if('singularityheader' in req.headers) {
corrHeader = req.headers.singularityheader || "";
} else if(self.agent.tracer && transaction.baggageCorrHeader) {
/*
* 1: We append the doNotResolveSubHeader when the upstream is a pure OT service to
* prevent resolution to the preceding APPD service
2: The noTxDetectHeader is treated specially by libagent, so do not append the doNotResolveSubHeader
in this case
*/
const noTxDetectHeader = self.agent.correlation.DISABLE_TRANSACTION_DETECTION + '=true';
const doNotResolveSubHeader = self.agent.correlation.DONOTRESOLVE + '=true';
corrHeader = transaction.baggageCorrHeader != noTxDetectHeader ? transaction.baggageCorrHeader + '*' +
doNotResolveSubHeader : transaction.baggageCorrHeader;
self.agent.logger.debug(`Using Singularity Header from Opentelemetry Baggage ${corrHeader}`);
}
}
if (req.businessTransactionName) {
name = transaction.name = req.businessTransactionName;
}
}
var txData = libagentConnector.startBusinessTransaction('NODEJS_WEB', name, corrHeader, utility.createBtNamingWrapper(req), isHttpRequest);
if (txData === undefined || txData.isExcluded) {
transaction.skip = true;
return;
}
transaction.skip = false;
transaction.name = txData.name;
transaction.btGuid = txData.btGuid;
transaction.guid = txData.guid;
transaction.eumEnabled = txData.eumEnabled;
transaction.isHttpRequest = isHttpRequest;
self.agent.logger.debug('Started Txn with TxnGuid: ' + transaction.guid + ' id: ' + transaction.id);
if (libagentConnector.isSnapshotRequired(transaction)) {
libagentConnector.emit("autoProcessSnapshot");
}
});
self.agent.on("transaction", function(transaction) {
if (!self.isEnabled || transaction.skip) {
return;
}
if (libagentConnector.isSnapshotRequired(transaction)) {
libagentConnector.emit("autoProcessSnapshot");
var snapshot = libagentConnector.protobufModel.createSnapshot(transaction);
libagentConnector.sendTransactionSnapshot(transaction, snapshot);
if (transaction.isHttpRequest) {
libagentConnector.setHttpParamsInTransactionSnapshot(transaction);
libagentConnector.addHttpDataToTransactionSnapshot(transaction, transaction.httpRequestData);
}
}
self.agent.logger.debug('Stopped Txn with TxnGuid: ' + transaction.guid + ' id: ' + transaction.id);
libagentConnector.stopBusinessTransaction(transaction);
});
self.agent.on("exitCallStarted", function(transaction, exitCall) {
if (!self.isEnabled || transaction.skip) {
return;
}
self.agent.logger.debug('Started Exitcall with TxnGuid: ' + transaction.guid + ' id: ' + transaction.id);
libagentConnector.startExitCall(transaction, exitCall);
});
self.agent.on("exitCallStopped", function(transaction, exitCall, error) {
if (!self.isEnabled || transaction.skip) {
return;
}
self.agent.logger.debug('Stopped Exitcall with TxnGuid: ' + transaction.guid + ' id: ' + transaction.id);
libagentConnector.stopExitCall(exitCall, error);
});
};