@instana/core
Advanced tools
Comparing version 1.98.1 to 1.99.0
{ | ||
"name": "@instana/core", | ||
"version": "1.98.1", | ||
"version": "1.99.0", | ||
"description": "Core library for Instana's Node.js packages", | ||
@@ -136,3 +136,3 @@ "main": "src/index.js", | ||
}, | ||
"gitHead": "26a6d1dbe7dc1de41d6e8dfe4df786677f283b17" | ||
"gitHead": "c754d197946e8690f40487581595b046667af275" | ||
} |
@@ -18,2 +18,6 @@ 'use strict'; | ||
exports.registerAdditionalInstrumentations = function(additionalInstrumentationModules) { | ||
exports.tracing.registerAdditionalInstrumentations(additionalInstrumentationModules); | ||
}; | ||
exports.preInit = function() { | ||
@@ -20,0 +24,0 @@ var preliminaryConfig = normalizeConfig(); |
@@ -8,2 +8,6 @@ 'use strict'; | ||
exports.init = function(_config) { | ||
config = _config; | ||
}; | ||
exports.findAndRequire = function findAndRequire(baseDir) { | ||
@@ -13,4 +17,8 @@ return fs | ||
.filter(function(moduleName) { | ||
// ignore non-JS files and index.js | ||
return moduleName.indexOf('.js') === moduleName.length - 3 && moduleName.indexOf('index.js') < 0; | ||
// ignore non-JS files and non-metric modules | ||
return ( | ||
moduleName.indexOf('.js') === moduleName.length - 3 && | ||
moduleName.indexOf('index.js') < 0 && | ||
moduleName.indexOf('transmissionCycle.js') < 0 | ||
); | ||
}) | ||
@@ -28,6 +36,2 @@ .map(function(moduleName) { | ||
exports.init = function(_config) { | ||
config = _config; | ||
}; | ||
exports.activate = function() { | ||
@@ -58,1 +62,9 @@ metricsModules.forEach(function(metricsModule) { | ||
}; | ||
exports.setLogger = function setLogger(logger) { | ||
metricsModules.forEach(function(metricModule) { | ||
if (typeof metricModule.setLogger === 'function') { | ||
metricModule.setLogger(logger); | ||
} | ||
}); | ||
}; |
@@ -47,4 +47,2 @@ 'use strict'; | ||
'./instrumentation/messaging/natsStreaming', | ||
'./instrumentation/process/childProcess', | ||
'./instrumentation/process/edgemicro', | ||
'./instrumentation/process/memored', | ||
@@ -56,2 +54,3 @@ './instrumentation/protocols/graphql', | ||
]; | ||
var additionalInstrumentationModules = []; | ||
var instrumentationModules = {}; | ||
@@ -65,2 +64,6 @@ | ||
exports.registerAdditionalInstrumentations = function(_additionalInstrumentationModules) { | ||
additionalInstrumentationModules = additionalInstrumentationModules.concat(_additionalInstrumentationModules); | ||
}; | ||
exports.preInit = function(preliminaryConfig) { | ||
@@ -98,2 +101,5 @@ initInstrumenations(preliminaryConfig); | ||
}); | ||
additionalInstrumentationModules.forEach(function(instrumentationModule) { | ||
instrumentationModule.init(_config); | ||
}); | ||
instrumenationsInitialized = true; | ||
@@ -100,0 +106,0 @@ } else { |
@@ -100,3 +100,3 @@ 'use strict'; | ||
if (error) { | ||
logger.warn('Failed to transmit spans', { error: error }); | ||
logger.warn('Failed to transmit spans, will retry in ' + transmissionDelay + ' ms.', error.message); | ||
spans = spans.concat(spansToSend); | ||
@@ -123,2 +123,4 @@ removeSpansIfNecessary(); | ||
if (spans.length > maxBufferedSpans) { | ||
var droppedCount = spans.length - maxBufferedSpans; | ||
logger.warn('Span buffer is over capacity, dropping ' + droppedCount + ' spans.'); | ||
tracingMetrics.incrementDropped(spans.length - maxBufferedSpans); | ||
@@ -125,0 +127,0 @@ // retain the last maxBufferedSpans elements, drop everything before that |
@@ -115,6 +115,6 @@ 'use strict'; | ||
if (isSuppressed(level)) { | ||
// If tracing is suppressed and no headers are incoming, we need to create a new random parent ID (and pass it | ||
// down in the traceparent header); this parent ID is not actually associated with any existing span (Instana or | ||
// foreign). This can't be helped, the spec mandates to always set the traceparent header on outgoing requests, | ||
// even if we didn't sample and it has to have a parent ID field. | ||
// If tracing is suppressed and no headers are incoming, we need to create new random trace and parent IDs (and | ||
// pass them down in the traceparent header); this trace and parent IDs ares not actually associated with any | ||
// existing span (Instana or foreign). This can't be helped, the spec mandates to always set the traceparent | ||
// header on outgoing requests, even if we didn't sample and it has to have a parent ID field. | ||
return { | ||
@@ -121,0 +121,0 @@ level: level, |
@@ -86,6 +86,13 @@ 'use strict'; | ||
/** | ||
* Writes characters from a hex string directly to a buffer, without converting the hex string to a BigInt beforehand. | ||
* Writes characters from a hex string directly to a buffer. The buffer will contain a binary representation of the | ||
* given hex string after this operation. No length checks are executed, so the caller is responsible for writing within | ||
* the bounds of the given buffer. | ||
* | ||
* The string hexString must only contain the characters [0-9a-f]. | ||
*/ | ||
function writeHexToBuffer(hexString, buffer, offset) { | ||
// This implementation uses Node.js buffer internals directly: | ||
// https://github.com/nodejs/node/blob/92cef79779d121d934dcb161c068bdac35e6a963/lib/internal/buffer.js#L1005 -> | ||
// https://github.com/nodejs/node/blob/master/src/node_buffer.cc#L1196 / | ||
// https://github.com/nodejs/node/blob/master/src/node_buffer.cc#L681 | ||
buffer.hexWrite(hexString, offset, hexString.length / 2); | ||
@@ -92,0 +99,0 @@ } |
@@ -32,5 +32,4 @@ 'use strict'; | ||
if (packageJsonPath == null) { | ||
parsedMainPackageJson = null; | ||
// fs.readFile would have called cb asynchronously later, so we use process.nextTick here to make all paths async. | ||
return process.nextTick(cb, null, null); | ||
return process.nextTick(cb); | ||
} | ||
@@ -69,8 +68,11 @@ | ||
var mainModule = process.mainModule; | ||
// this may happen when the Node CLI is evaluating an expression or when the REPL is used | ||
if (!mainModule) { | ||
mainPackageJsonPath = null; | ||
// searchForPackageJsonInDirectoryTreeUpwards would have called cb asynchronously later, | ||
// so we use process.nextTick here to make all paths async. | ||
return process.nextTick(cb, null, null); | ||
// This happens | ||
// a) when the Node CLI is evaluating an expression, or | ||
// b) when the REPL is used, or | ||
// c) when we have been pre-required with the --require/-r command line flag | ||
// In particular for case (c) we want to try again later. This is handled in the individual metrics that rely on | ||
// evaluating the package.json file. | ||
return process.nextTick(cb); | ||
} | ||
@@ -77,0 +79,0 @@ startDirectory = path.dirname(mainModule.filename); |
'use strict'; | ||
module.exports = function applyCompressionRoot(prev, next) { | ||
var result = applyCompression(prev, next); | ||
module.exports = exports = function applyCompressionRoot(prev, next, blacklist) { | ||
var result = applyCompression([], prev, next, blacklist); | ||
@@ -13,4 +13,10 @@ // the root object needs to be at least an empty object. | ||
function applyCompression(prev, next) { | ||
if (prev === next) { | ||
function applyCompression(path, prev, next, blacklist) { | ||
if (isBlacklisted(path, blacklist)) { | ||
return next; | ||
} | ||
if (blacklist == null && prev === next) { | ||
// Shortcut: If it is the same object, remove it completely. We can only take this shortcut safely, if there is no | ||
// blacklist, otherwise we might accidentally remove attributes that would be blacklisted for compression. | ||
return undefined; | ||
@@ -27,3 +33,3 @@ } | ||
} else if (nType === 'object') { | ||
return applyCompressionToObject(prev, next); | ||
return applyCompressionToObject(path, prev, next, blacklist); | ||
} else if (prev !== next) { | ||
@@ -36,3 +42,3 @@ return next; | ||
function applyCompressionToObject(prev, next) { | ||
function applyCompressionToObject(path, prev, next, blacklist) { | ||
var result = {}; | ||
@@ -48,3 +54,3 @@ var addedProps = 0; | ||
var compressed = applyCompression(pValue, nValue); | ||
var compressed = applyCompression(path.concat(nKey), pValue, nValue, blacklist); | ||
if (compressed !== undefined) { | ||
@@ -80,1 +86,30 @@ result[nKey] = compressed; | ||
} | ||
function isBlacklisted(path, blacklist) { | ||
if (blacklist == null) { | ||
return false; | ||
} | ||
// Compare the given path to all blacklist entries. | ||
// eslint-disable-next-line no-restricted-syntax | ||
outer: for (var i = 0; i < blacklist.length; i++) { | ||
if (blacklist[i].length !== path.length) { | ||
// The blacklist entry and then given path have different lengths, this cannot be a match. Continue with next | ||
// blacklist entry. | ||
// eslint-disable-next-line no-continue | ||
continue; | ||
} | ||
for (var j = 0; j < blacklist[i].length; j++) { | ||
if (blacklist[i][j] !== path[j]) { | ||
// We found a path segment that is differnt for this blacklist entry and then given path, this cannot be a | ||
// match. Continue with next blacklist entry. | ||
// eslint-disable-next-line no-continue | ||
continue outer; | ||
} | ||
} | ||
// This blacklist entry and the given path have the same number of segments and all segments are identical, so this | ||
// is a match, that is, this path has been blacklisted for compression. | ||
return true; | ||
} | ||
return false; | ||
} |
@@ -10,2 +10,3 @@ 'use strict'; | ||
hasThePackageBeenInitializedTooLate: require('./initializedTooLateHeuristic'), | ||
normalizeConfig: require('./normalizeConfig'), | ||
propertySizes: require('./propertySizes'), | ||
@@ -12,0 +13,0 @@ requireHook: require('./requireHook'), |
@@ -1,2 +0,2 @@ | ||
/* eslint-disable dot-notation */ | ||
/* eslint-disable */ | ||
@@ -16,2 +16,3 @@ 'use strict'; | ||
metrics: { | ||
transmissionDelay: 1000, | ||
timeBetweenHealthcheckCalls: 3000 | ||
@@ -71,2 +72,9 @@ }, | ||
config.metrics.transmissionDelay = normalizeSingleValue( | ||
config.metrics.transmissionDelay, | ||
defaults.metrics.transmissionDelay, | ||
'config.metrics.transmissionDelay', | ||
'INSTANA_METRICS_TRANSMISSION_DELAY' | ||
); | ||
// The correct location for this is config.metrics.timeBetweenHealthcheckCalls but previous versions accepted | ||
@@ -148,31 +156,16 @@ // config.timeBetweenHealthcheckCalls. We still accept that to not break applications relying on that. | ||
config.tracing.maxBufferedSpans = config.tracing.maxBufferedSpans || defaults.tracing.maxBufferedSpans; | ||
config.tracing.transmissionDelay = config.tracing.transmissionDelay || defaults.tracing.transmissionDelay; | ||
var originalValue = config.tracing.forceTransmissionStartingAt; | ||
if ( | ||
config.tracing.forceTransmissionStartingAt == null && | ||
process.env['INSTANA_FORCE_TRANSMISSION_STARTING_AT'] == null | ||
) { | ||
config.tracing.forceTransmissionStartingAt = defaults.tracing.forceTransmissionStartingAt; | ||
return; | ||
} else if ( | ||
config.tracing.forceTransmissionStartingAt == null && | ||
process.env['INSTANA_FORCE_TRANSMISSION_STARTING_AT'] != null | ||
) { | ||
originalValue = process.env['INSTANA_FORCE_TRANSMISSION_STARTING_AT']; | ||
config.tracing.forceTransmissionStartingAt = parseInt(originalValue, 10); | ||
} | ||
config.tracing.transmissionDelay = normalizeSingleValue( | ||
config.tracing.transmissionDelay, | ||
defaults.tracing.transmissionDelay, | ||
'config.tracing.transmissionDelay', | ||
'INSTANA_TRACING_TRANSMISSION_DELAY' | ||
); | ||
if ( | ||
typeof config.tracing.forceTransmissionStartingAt !== 'number' || | ||
isNaN(config.tracing.forceTransmissionStartingAt) | ||
) { | ||
logger.warn( | ||
'The value of config.tracing.forceTransmissionStartingAt (or INSTANA_FORCE_TRANSMISSION_STARTING_AT) ("%s") is ' + | ||
'not numerical or cannot be parsed to a numerical value. Assuming the default value %s.', | ||
originalValue, | ||
defaults.tracing.forceTransmissionStartingAt | ||
); | ||
config.tracing.forceTransmissionStartingAt = defaults.tracing.forceTransmissionStartingAt; | ||
} | ||
config.tracing.forceTransmissionStartingAt = normalizeSingleValue( | ||
config.tracing.forceTransmissionStartingAt, | ||
defaults.tracing.forceTransmissionStartingAt, | ||
'config.tracing.forceTransmissionStartingAt', | ||
'INSTANA_FORCE_TRANSMISSION_STARTING_AT' | ||
); | ||
} | ||
@@ -322,1 +315,25 @@ | ||
} | ||
function normalizeSingleValue(configValue, defaultValue, configPath, envVarKey) { | ||
var envVarVal = process.env[envVarKey]; | ||
var originalValue = configValue; | ||
if (configValue == null && envVarVal == null) { | ||
return defaultValue; | ||
} else if (configValue == null && envVarVal != null) { | ||
originalValue = envVarVal; | ||
configValue = parseInt(originalValue, 10); | ||
} | ||
if (typeof configValue !== 'number' || isNaN(configValue)) { | ||
logger.warn( | ||
'The value of %s (or %s) ("%s") is ' + | ||
'not numerical or cannot be parsed to a numerical value. Assuming the default value %s.', | ||
configPath, | ||
envVarKey, | ||
originalValue, | ||
defaultValue | ||
); | ||
return defaultValue; | ||
} | ||
return configValue; | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
21
6
334587
80
9056