apminsight
Version:
monitor nodejs applications
408 lines (362 loc) • 13.9 kB
JavaScript
var constants = require("./../constants");
var utils = require("./../util/utils");
const logger = require("./../util/logger");
function Configuration(options) {
options = options || {};
this._licenseKey = options.licenseKey || process.env.APMINSIGHT_LICENSE_KEY;
this._appName = options.appName || process.env.APMINSIGHT_APP_NAME;
this._appGroupName =
validateAppGroupName(utils.convertToString(options.appGroupName)) ||
validateAppGroupName(process.env.APMINSIGHT_MONITOR_GROUP);
this._tags = options.tags || getTagsJson(process.env.APMINSIGHT_TAGS);
this._processManagerEnabled = !!(options.processManagerEnabled ||
process.env.APMINSIGHT_PROCESS_MANAGER === 'true' ||
process.env.APMINSIGHT_PROCESS_MANAGER === true);
// Set app port based on process manager settings
if (this._processManagerEnabled) {
const pm2Id = this.getPm2Id();
this._appPort = pm2Id ? parseInt(pm2Id, 10) : null;
} else {
const configuredPort = options.port || process.env.APMINSIGHT_APP_PORT;
this._appPort = !utils.isEmpty(configuredPort) && utils.isPositiveNumber(configuredPort)
? parseInt(configuredPort, 10)
: null;
}
this._behindProxy = options.behindProxy || false;
this._apmHost = getMultipleHostsArray(options, this._licenseKey);
this._apmPort = parseInt(process.env.APMINSIGHT_PORT || options.apmPort || process.env.APMINSIGHT_APM_PORT || constants.collectorPort, 10);
this._agentInstalledPath = options.agentInstallPath;
this._agentVersion = options.agentVersion;
this._agentFullVersion = options.agentFullVersion;
this._printPayload = options.printPayload || process.env.APMINSIGHT_PRINTPAYLOAD || false;
this._debugMode = options.debugMode ? true : false;
this._agentBaseDir = options.agentBaseDir;
this._agentInfoPath = options.agentInfoPath ? options.agentInfoPath : "";
this._proxyAgent = getHttpsProxyAgent(options);
this._licenseKeySuffix = getLicenseKeySuffix(options.licenseKey);
this._hostLicense = options.hostLicense
? options.hostLicense
: process.env.APMINSIGHT_HOSTLICENSE
? process.env.APMINSIGHT_HOSTLICENSE
: false;
this._rumAppKey = options.rumAppKey || process.env.APMINSIGHT_RUM_API_KEY;
this._rumBeaconHost =
options.rumBeaconHost ||
process.env.APMINSIGHT_RUM_BEACON_HOST ||
getRumStaticBeaconHostName(this._licenseKey);
this._rumIntegrationAppKey = [];
this._newRumAppKeyAdded = false;
this._httpErrorCodesTrack = parseHttpErrorCodes(options.errorCodes);
this._serverMonitorKey = options.serverMonitorKey || null;
this._isDataExporterEnabled = options.dataExporterEnabled || process.env.APMINSIGHT_DATA_EXPORTER_ENABLED === 'true' || false;
this._dataExporterHost = options.dataExporterHost || process.env.APMINSIGHT_DATA_EXPORTER_HOST || 'localhost';
this._dataExporterDataPort = parseInt(options.dataExporterDataPort || process.env.APM_EXPORTER_DATA_PORT || constants.s247DataExporterDataPort, 10);
this._dataExporterStatusPort = parseInt(options.dataExporterStatusPort || process.env.APM_EXPORTER_STATUS_PORT || constants.s247DataExporterStatusPort, 10);
}
Configuration.prototype.isPortConfiguredProperly = function () {
if (this.isProcessManagerEnabled()) {
if (utils.isEmpty(this._appPort)) {
this.setApplicationPort();
}
}
return !utils.isEmpty(this.getApplicationPort()) &&
utils.isPositiveNumber(this.getApplicationPort());
};
Configuration.prototype.isAppNameConfiguredProperly = function () {
if (utils.isNonEmptyString(this.getApplicationName())) {
return true;
}
return false;
};
Configuration.prototype.isLkeyConfiguredProperly = function () {
if (!utils.isValidLicenseKey(this.getLicenseKey())) {
return false;
}
return true;
};
Configuration.prototype.getLicenseKey = function () {
var decryptedLkey = utils.toDecryptKey(this._licenseKey);
var licenseKey = utils.isBoolean(decryptedLkey)
? this._licenseKey
: decryptedLkey;
return licenseKey;
};
Configuration.prototype.getApplicationName = function () {
return this._appName;
};
Configuration.prototype.setApplicationName = function (appName) {
this._appName = appName;
}
Configuration.prototype.getAppGroupName = function () {
return this._appGroupName;
};
Configuration.prototype.getTags = function () {
return this._tags;
}
Configuration.prototype.getApplicationPort = function () {
return this._appPort;
};
Configuration.prototype.setApplicationPort = function (port) {
// If process manager is enabled and port isn't set, get it from PM2
if (this.isProcessManagerEnabled() && utils.isEmpty(this._appPort)) {
const pm2Id = this.getPm2Id();
if (!utils.isEmpty(pm2Id)) {
this._appPort = parseInt(pm2Id, 10);
}
} else if (!utils.isEmpty(port)) {
// Standard case - just set the port
this._appPort = parseInt(port, 10);
}
};
Configuration.prototype.isBehindProxy = function () {
return this._behindProxy;
};
Configuration.prototype.getApmHosts = function () {
return this._apmHost;
};
Configuration.prototype.getApmPort = function () {
return this._apmPort;
};
Configuration.prototype.getAgentInstalledPath = function () {
return this._agentInstalledPath;
};
Configuration.prototype.getAgentVersion = function () {
return this._agentVersion;
};
Configuration.prototype.getAgentFullVersion = function () {
return this._agentFullVersion;
};
Configuration.prototype.isHostBasedLicense = function () {
return this._hostLicense;
};
Configuration.prototype.isPrintPayloadEnabled = function () {
return this._printPayload;
};
Configuration.prototype.isDebugModeEnabled = function () {
return this._debugMode;
};
Configuration.prototype.getLicenseKeySuffix = function () {
return this._licenseKeySuffix;
};
Configuration.prototype.getBaseDir = function () {
return this._agentBaseDir;
};
Configuration.prototype.getAgentInfoPath = function () {
return this._agentInfoPath;
};
Configuration.prototype.getRumIntegAppKey = function () {
return this._rumIntegrationAppKey;
};
Configuration.prototype.isNewRumAppKeyAdded = function () {
return this._newRumAppKeyAdded;
};
Configuration.prototype.checkAndAddProxyAgent = function (connectInfo) {
if (this._proxyAgent) {
connectInfo.agent = this._proxyAgent;
}
};
Configuration.prototype.getHttpErrorCodesTrack = function () {
return this._httpErrorCodesTrack;
};
Configuration.prototype.setHttpErrorCodesTrack = function (errCodes) {
this._httpErrorCodesTrack = parseHttpErrorCodes(errCodes);
}
Configuration.prototype.getServerMonitorKey = function () {
return this._serverMonitorKey;
};
Configuration.prototype.isProcessManagerEnabled = function () {
return this._processManagerEnabled;
};
Configuration.prototype.getPm2Id = function () {
const pm2Id = process.env.pm_id ||
process.env.PM_ID ||
process.env.pm2_id ||
process.env.PM2_ID ||
process.env.NODE_APP_INSTANCE;
if (utils.isEmpty(pm2Id)) {
// No PM2 ID found, returning null
return null;
}
const parsedId = parseInt(pm2Id, 10);
logger.info(`PM2 detected, using pm2 id: ${parsedId}`);
return !isNaN(parsedId) ? parsedId : null;
};
Configuration.prototype.isDataExporterEnabled = function () {
return this._isDataExporterEnabled;
};
Configuration.prototype.getDataExporterHost = function () {
return this._dataExporterHost;
};
Configuration.prototype.getDataExporterDataPort = function () {
return this._dataExporterDataPort;
};
Configuration.prototype.getDataExporterStatusPort = function () {
return this._dataExporterStatusPort;
};
function getRumStaticBeaconHostName(lKey) {
if (utils.isEmpty(lKey)) {
return;
}
var decryptedLkey = utils.toDecryptKey(lKey);
var licenseKey = utils.isBoolean(decryptedLkey) ? lKey : decryptedLkey;
if (licenseKey.startsWith("eu_")) {
//No I18N
return constants.euRumStaticBeaconHostName;
}
if (licenseKey.startsWith("cn_")) {
//No I18N
return constants.cnRumStaticBeaconHostName;
}
if (licenseKey.startsWith("in_")) {
//No I18N
return constants.inRumStaticBeaconHostName;
}
if (licenseKey.startsWith("au_")) {
//No I18N
return constants.ausRumStaticBeaconHostName;
}
return constants.usRumStaticBeaconHostName;
}
function getHttpsProxyAgent(options) {
const { HttpsProxyAgent } = require("https-proxy-agent");
if (process.env.APMINSIGHT_PROXY_URL) {
return new HttpsProxyAgent(process.env.APMINSIGHT_PROXY_URL);
}
var proxyHost = options.proxyServerHost || process.env.APMINSIGHT_PROXYSERVER_HOST;
var proxyPort = options.proxyServerPort || process.env.APMINSIGHT_PROXYSERVER_PORT;
if (utils.isEmpty(proxyHost) || utils.isEmpty(proxyPort)) {
return null;
}
var proxyAuthUserInfo = options.proxyAuthUser || process.env.APMINSIGHT_PROXYAUTH_USER;
var proxyAuthPasswordInfo = options.proxyAuthPassword || process.env.APMINSIGHT_PROXYAUTH_PASSWORD;
// Construct the proxy URL inline, including authentication if provided
const proxyUrl = `https://${!utils.isEmpty(proxyAuthUserInfo)
&& !utils.isEmpty(proxyAuthPasswordInfo)
? `${proxyAuthUserInfo}:${proxyAuthPasswordInfo}@`
: ''}${proxyHost}:${proxyPort}`;
return new HttpsProxyAgent(proxyUrl);
}
function getCollectorHostByLicenseKey(lKey) {
if (utils.isEmpty(lKey)) {
return;
}
var decryptedLkey = utils.toDecryptKey(lKey);
var licenseKey = utils.isBoolean(decryptedLkey) ? lKey : decryptedLkey;
if (licenseKey.startsWith("eu_")) {
return constants.euCollectorHostName;
}
if (licenseKey.startsWith("cn_")) {
return constants.cnCollectorHostName;
}
if (licenseKey.startsWith("in_hd_")) {
return constants.indHdfcCollectorHostName;
}
if (licenseKey.startsWith("in_")) {
return constants.indCollectorHostName;
}
if (licenseKey.startsWith("au_")) {
return constants.ausCollectorHostName;
}
if (licenseKey.startsWith("jp_")) {
return constants.jpCollectorHostName;
}
if (licenseKey.startsWith("ca_")) {
return constants.caCollectorHostName;
}
if (licenseKey.startsWith("uk_")) {
return constants.ukCollectorHostName;
}
if (licenseKey.startsWith("sa_")) {
return constants.saCollectorHostName;
}
if (licenseKey.startsWith("ae_")) {
return constants.aeCollectorHostName;
}
return constants.usCollectorHostName;
}
function getLicenseKeySuffix(lKey) {
if (utils.isEmpty(lKey)) {
return "";
}
var decryptedLkey = utils.toDecryptKey(lKey);
var licenseKey = utils.isBoolean(decryptedLkey) ? lKey : decryptedLkey;
var length = licenseKey.length;
return licenseKey.substr(length - 12);
}
function validateAppGroupName(appGroupName) {
if (!appGroupName)
return null;
try {
const applicationGroups = appGroupName.split(',').map(str => str.trim());
// Check if all strings pass the validation
const allValid = applicationGroups.every(str => constants.applicationGroupRegex.test(str));
return allValid ? appGroupName : null;
} catch (error) {
logger.error("error while split or test in validateAppGroupName", error);
}
}
function getTagsJson(input) {
if (!input)
return null;
const tags = {};
try {
const tagPairs = input.split(',');
tagPairs.forEach(pair => {
const [name, value] = pair.split(':').map(str => str.trim());
tags[name] = value;
});
} catch (error) {
logger.error("error while split in getTagsJson", error);
}
return tags;
}
function getMultipleHostsArray(options, licenseKey) {
const multipleHosts = [];
let rawHosts = process.env.APMINSIGHT_HOST || options.apmHost || process.env.APMINSIGHT_APM_HOST;
//appmanager & oneagent
if (!utils.isEmpty(rawHosts)) {
rawHosts = rawHosts.split(",");
if (rawHosts.length == 1 && !utils.isValidURL(rawHosts[0])) {
//reconstruction required for old flow i.e domain alone will be passed to host variable
//ex: https://example-test:8445/
const url = `https://${rawHosts[0]}:${process.env.APMINSIGHT_PORT || options.apmPort || process.env.APMINSIGHT_APM_PORT || constants.collectorPort}/`;
multipleHosts.push(url);
} else {
rawHosts.forEach(url => {
if (utils.isValidURL(url)) {
multipleHosts.push(url);
}
});
}
} else {
//required for pushing data to site24x7
const domain = getCollectorHostByLicenseKey(licenseKey);
const url = `https://${domain}:${parseInt(constants.collectorPort, 10)}/`;
multipleHosts.push(url);
}
return multipleHosts;
}
function parseHttpErrorCodes(errCodes) {
if (utils.isEmpty(errCodes)) {
return [];
}
let errorCodes;
try {
errorCodes = errCodes
.split(',')
.map(code => code.trim())
.filter(code => {
const parsedCode = parseInt(code, 10);
return !isNaN(parsedCode) && utils.isPositiveNumber(parsedCode);
});
} catch (error) {
logger.error("error while split parseHttpErrorCodes", error);
}
if (utils.isEmpty(errorCodes)) {
errorCodes = [];
}
return errorCodes;
}
module.exports = {
Configuration: Configuration
};