UNPKG

ca-apm-probe

Version:

CA APM Node.js Agent monitors real-time health and performance of Node.js applications

212 lines (182 loc) 6.01 kB
/** * Copyright (c) 2015 CA. All rights reserved. * * This software and all information contained therein is confidential and proprietary and * shall not be duplicated, used, disclosed or disseminated in any way except as authorized * by the applicable license agreement, without the express written permission of CA. All * authorized reproductions must be marked with this language. * * EXCEPT AS SET FORTH IN THE APPLICABLE LICENSE AGREEMENT, TO THE EXTENT * PERMITTED BY APPLICABLE LAW, CA PROVIDES THIS SOFTWARE WITHOUT WARRANTY * OF ANY KIND, INCLUDING WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL CA BE * LIABLE TO THE END USER OR ANY THIRD PARTY FOR ANY LOSS OR DAMAGE, DIRECT OR * INDIRECT, FROM THE USE OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, LOST * PROFITS, BUSINESS INTERRUPTION, GOODWILL, OR LOST DATA, EVEN IF CA IS * EXPRESSLY ADVISED OF SUCH LOSS OR DAMAGE. */ // module for generating correlation id 'use strict'; var guidgenerator = require('./guidgenerator'); var IsengardHashMap = require('./isengard-hashmap'); var logger = require("../logger.js"); var SEQ_SEP = ','; var LEVEL_SEP = ':'; var NO_OPTIONAL_PARAMS = 'NoOptionalParams'; var TXN_TRACE_ID_KEY = 'TxnTraceId'; var CALLER_TIMESTAMP_KEY = 'CallerTimestamp'; function SequenceId() { this.seqValue = '1'; this.outgoingLevel = 0; this.getOutgoingSequenceId = function() { return this.seqValue + LEVEL_SEP + (++this.outgoingLevel); }; this.getCurrentOutgoingSequenceId = function() { return this.seqValue + LEVEL_SEP + this.outgoingLevel; }; this.setSequenceValue = function(value) { this.seqValue = value; } this.getSequenceValue = function() { return this.seqValue; } } function CorrelationId() { this.guid; this.seqId = new SequenceId(); this.propagationFlag = '0'; // 0: no propogation, 1: propogate this.depPropagationFlag = '0'; this.incomingCalledByNodeId = ''; this.incomingCalledByNodeType = ''; this.outgoingCallerNodeId = 'NodeJS'; this.outgoingCallerNodeType = '1'; this.txtTraceId = guidgenerator.generateGuid(); this.optionalParam = NO_OPTIONAL_PARAMS; this.optionalParamMap = new IsengardHashMap(); this.optionalParamMap.put(TXN_TRACE_ID_KEY, this.txtTraceId); this.getOutgoingSequenceId = function() { return this.seqId.getOutgoingSequenceId(); }; this.getCurrentOutgoingSequenceId = function() { return this.seqId.getCurrentOutgoingSequenceId(); }; this.getPropagationFlagValue = function() { return this.propagationFlag; } this.getDeepPropagationFlagValue = function() { return this.depPropagationFlag; } this.getOutgoingCallerNodeType = function() { return this.outgoingCallerNodeType; } this.getOutgoingCallerNodeId = function() { return this.outgoingCallerNodeId; } this.getOptionalParam = function() { return this.optionalParam; } this.getTransactionTraceId = function() { return this.txtTraceId; } this.getCurrentCorId = function() { if (!this.guid) { this.guid = guidgenerator.generateGuid(); } // note, we use seq value only var seqId = this.seqId.getSequenceValue(); var propFlag = this.getPropagationFlagValue(); var deepPropFlag = this.getDeepPropagationFlagValue(); var nodeID = this.getOutgoingCallerNodeId(); var nodeType = this.getOutgoingCallerNodeType(); var param = this.getOptionalParam(); var corid = this.guid + SEQ_SEP + seqId + SEQ_SEP + propFlag + SEQ_SEP + deepPropFlag + SEQ_SEP + nodeID + SEQ_SEP + nodeType + SEQ_SEP + param; return corid; } // CorID = <GUID>,<seqID>,<propagation flag>,<dep propagation flag>, // <outgoingCallerNodeID>,<outgoingCallerNodeType> this.getOutgoingCorId = function() { if (!this.guid) { this.guid = guidgenerator.generateGuid(); } var seqId = this.getOutgoingSequenceId(); var propFlag = this.getPropagationFlagValue(); var deepPropFlag = this.getDeepPropagationFlagValue(); var nodeID = this.getOutgoingCallerNodeId(); var nodeType = this.getOutgoingCallerNodeType(); // add caller time stamp this.optionalParamMap.put(CALLER_TIMESTAMP_KEY, Date.now()); var param = this.optionalParamMap.serialize(); var corid = this.guid + SEQ_SEP + seqId + SEQ_SEP + propFlag + SEQ_SEP + deepPropFlag + SEQ_SEP + nodeID + SEQ_SEP + nodeType + SEQ_SEP + param; return corid; } this.parseAndSet = function(corid) { if (corid) { var tokens = corid.split(SEQ_SEP); var len = tokens.length; // tokens to look for var correlationId = null; var newSeqString = null; var propagationFlag = null; var depPropagationFlag = null; var callerName = null; var callerNodeType = null; var optionalParam = null; if (len.length < 7) { logger.debug('Received an older cross process data on wire.'); } if (len > 0) { correlationId = tokens[0]; } if (len > 1) { newSeqString = tokens[1]; } if (len > 2) { propagationFlag = tokens[2]; } if (len > 3) { depPropagationFlag = tokens[3]; } if (len > 4) { callerName = tokens[4]; } if (len > 5) { callerNodeType = tokens[5]; } if (len > 6) { optionalParam = tokens[6]; } // set values for properties if (correlationId) { this.guid = correlationId; } if (newSeqString) { // TODO: do we need to create new object // this.seqId = new SequenceId(); this.seqId.setSequenceValue(newSeqString); } if (propagationFlag) { this.propagationFlag = propagationFlag; } if (depPropagationFlag) { this.depPropagationFlag = depPropagationFlag; } if (callerName) { this.incomingCalledByNodeId = callerName; } if (callerNodeType) { this.incomingCalledByNodeType = callerNodeType; } if (optionalParam) { this.optionalParam = optionalParam; } } } } function CorrelationIdGenerator() { this.generateCorIdObj = function() { return new CorrelationId(); } } module.exports = new CorrelationIdGenerator();