New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@instana/core

Package Overview
Dependencies
Maintainers
3
Versions
266
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@instana/core - npm Package Compare versions

Comparing version 1.127.0 to 1.128.0

4

package.json
{
"name": "@instana/core",
"version": "1.127.0",
"version": "1.128.0",
"description": "Core library for Instana's Node.js packages",

@@ -136,3 +136,3 @@ "main": "src/index.js",

},
"gitHead": "17186489c515d8b4df5b4142c9d4d6269496d155"
"gitHead": "a08cd7c136eecdf11278b3e927da313a15ab33e8"
}

@@ -45,2 +45,13 @@ /*

exports.sqsAttributeNames = {
TRACE_ID: 'X_INSTANA_T',
LEGACY_TRACE_ID: 'X_INSTANA_ST',
SPAN_ID: 'X_INSTANA_S',
LEGACY_SPAN_ID: 'X_INSTANA_SS',
LEVEL: 'X_INSTANA_L',
LEGACY_LEVEL: 'X_INSTANA_SL'
};
exports.snsSqsInstanaHeaderPrefixRegex = /"X_INSTANA_/i;
/**

@@ -47,0 +58,0 @@ * Determine if <span> is an entry span (server span).

@@ -100,2 +100,3 @@ /*

exports.supportedVersion = supportedVersion;
exports.util = tracingUtil;

@@ -102,0 +103,0 @@ /**

@@ -10,15 +10,6 @@ /*

const cls = require('../../../../cls');
const { ENTRY, EXIT, isExitSpan } = require('../../../../constants');
const { ENTRY, EXIT, isExitSpan, snsSqsInstanaHeaderPrefixRegex, sqsAttributeNames } = require('../../../../constants');
const requireHook = require('../../../../../util/requireHook');
const tracingUtil = require('../../../../tracingUtil');
const headerNames = {
TRACE_ID: 'X_INSTANA_T',
LEGACY_TRACE_ID: 'X_INSTANA_ST',
SPAN_ID: 'X_INSTANA_S',
LEGACY_SPAN_ID: 'X_INSTANA_SS',
LEVEL: 'X_INSTANA_L',
LEGACY_LEVEL: 'X_INSTANA_SL'
};
// Available call types to be sent into span.data.sqs.type

@@ -194,3 +185,3 @@ const callTypes = {

attributes[headerNames.LEVEL] = {
attributes[sqsAttributeNames.LEVEL] = {
DataType: 'String',

@@ -206,3 +197,3 @@ StringValue: '0'

attributes[headerNames.TRACE_ID] = {
attributes[sqsAttributeNames.TRACE_ID] = {
DataType: 'String',

@@ -212,3 +203,3 @@ StringValue: span.t

attributes[headerNames.SPAN_ID] = {
attributes[sqsAttributeNames.SPAN_ID] = {
DataType: 'String',

@@ -218,3 +209,3 @@ StringValue: span.s

attributes[headerNames.LEVEL] = {
attributes[sqsAttributeNames.LEVEL] = {
DataType: 'String',

@@ -252,4 +243,2 @@ StringValue: '1'

return cls.ns.runAndReturn(() => {
let attributes;
const span = cls.startSpan('sqs', ENTRY);

@@ -293,4 +282,7 @@ span.stack = tracingUtil.getStackTrace(instrumentedSendMessage);

} else if (data && data.Messages && data.Messages.length > 0) {
attributes = convertAttributesFromSQS(data.Messages[0].MessageAttributes);
if (readAttribCaseInsensitive(attributes, headerNames.LEVEL, headerNames.LEGACY_LEVEL) === '0') {
let tracingAttributes = readTracingAttributes(data.Messages[0].MessageAttributes);
if (!hasTracingAttributes(tracingAttributes)) {
tracingAttributes = readTracingAttributesFromSns(data.Messages[0].Body);
}
if (tracingAttributes.level === '0') {
cls.setTracingLevel('0');

@@ -301,4 +293,3 @@ setImmediate(() => span.cancel());

configureEntrySpan(span, data, attributes);
configureEntrySpan(span, data, tracingAttributes);
setImmediate(() => finishSpan(null, data, span));

@@ -328,4 +319,8 @@ return originalCallback.apply(this, arguments);

} else if (data && data.Messages && data.Messages.length > 0) {
attributes = convertAttributesFromSQS(data.Messages[0].MessageAttributes);
if (readAttribCaseInsensitive(attributes, headerNames.LEVEL, headerNames.LEGACY_LEVEL) === '0') {
let tracingAttributes = readTracingAttributes(data.Messages[0].MessageAttributes);
if (!hasTracingAttributes(tracingAttributes)) {
tracingAttributes = readTracingAttributesFromSns(data.Messages[0].Body);
}
if (tracingAttributes.level === '0') {
cls.setTracingLevel('0');

@@ -336,4 +331,3 @@ setImmediate(() => span.cancel());

configureEntrySpan(span, data, attributes);
configureEntrySpan(span, data, tracingAttributes);
setImmediate(() => finishSpan(null, data, span));

@@ -375,50 +369,100 @@ } else {

function readAttribCaseInsensitive(attributes, key1, key2) {
return (
tracingUtil.readAttribCaseInsensitive(attributes, key1) || tracingUtil.readAttribCaseInsensitive(attributes, key2)
);
}
/**
* Flattens the AWS SQS MessageAttribute format into a basic object structure.
* Reads all trace context relevant message attributes from an incoming message and provides them in a normalized format
* for later processing.
*/
function convertAttributesFromSQS(sqsAttributes) {
const attributes = {};
function readTracingAttributes(sqsAttributes) {
const tracingAttributes = {};
if (!sqsAttributes) {
return attributes;
return tracingAttributes;
}
const keys = Object.keys(sqsAttributes);
tracingAttributes.traceId = readMessageAttributeWithFallback(
sqsAttributes,
sqsAttributeNames.TRACE_ID,
sqsAttributeNames.LEGACY_TRACE_ID
);
tracingAttributes.parentId = readMessageAttributeWithFallback(
sqsAttributes,
sqsAttributeNames.SPAN_ID,
sqsAttributeNames.LEGACY_SPAN_ID
);
tracingAttributes.level = readMessageAttributeWithFallback(
sqsAttributes,
sqsAttributeNames.LEVEL,
sqsAttributeNames.LEGACY_LEVEL
);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
return tracingAttributes;
}
if (sqsAttributes[key].DataType === 'String') {
attributes[key] = sqsAttributes[key].StringValue;
function readTracingAttributesFromSns(messageBody) {
const tracingAttributes = {};
// Parsing the message body introduces a tiny overhead which we want to avoid unless we are sure that the incoming
// message actually has tracing attributes. Thus some preliminary, cheaper checks are executed first.
if (
typeof messageBody === 'string' &&
messageBody.startsWith('{') &&
messageBody.includes('"Type":"Notification"') &&
snsSqsInstanaHeaderPrefixRegex.test(messageBody)
) {
try {
const parsedBody = JSON.parse(messageBody);
if (parsedBody && parsedBody.MessageAttributes) {
tracingAttributes.traceId = readMessageAttributeWithFallback(
parsedBody.MessageAttributes,
sqsAttributeNames.TRACE_ID,
sqsAttributeNames.LEGACY_TRACE_ID
);
tracingAttributes.parentId = readMessageAttributeWithFallback(
parsedBody.MessageAttributes,
sqsAttributeNames.SPAN_ID,
sqsAttributeNames.LEGACY_SPAN_ID
);
tracingAttributes.level = readMessageAttributeWithFallback(
parsedBody.MessageAttributes,
sqsAttributeNames.LEVEL,
sqsAttributeNames.LEGACY_LEVEL
);
}
} catch (e) {
// The attempt to parse the message body as JSON failed, so this is not an SQS message resulting from an SNS
// notification (SNS-to-SQS subscription), in which case we are not interested in the body. Ignore the error and
// move on.
}
}
return tracingAttributes;
}
return attributes;
function readMessageAttributeWithFallback(attributes, key1, key2) {
const attribute =
tracingUtil.readAttribCaseInsensitive(attributes, key1) || tracingUtil.readAttribCaseInsensitive(attributes, key2);
if (attribute) {
// attribute.stringValue is used by SQS message attributes, attribute.Value is used by SNS-to-SQS.
return attribute.StringValue || attribute.Value;
}
}
/**
* Checks whether the given tracingAttributes object has at least one attribute set, that is, if there have been Instana
* message attributes present when converting message attributes into this object.
*/
function hasTracingAttributes(tracingAttributes) {
return tracingAttributes.traceId != null || tracingAttributes.parentId != null || tracingAttributes.level != null;
}
/**
* Add extra info to the entry span after messages are received
* @param {*} span The SQS Span
* @param {*} data The data returned by the SQS API
* @param {*} attributes The SQS Message Attributes
* @param {*} tracingAttributes The message attributes relevant for tracing
*/
function configureEntrySpan(span, data, attributes) {
function configureEntrySpan(span, data, tracingAttributes) {
span.data.sqs.size = data.Messages.length;
span.ts = Date.now();
const spanT = readAttribCaseInsensitive(attributes, headerNames.TRACE_ID, headerNames.LEGACY_TRACE_ID);
const spanP = readAttribCaseInsensitive(attributes, headerNames.SPAN_ID, headerNames.LEGACY_SPAN_ID);
if (spanT) {
span.t = spanT;
if (tracingAttributes.traceId && tracingAttributes.parentId) {
span.t = tracingAttributes.traceId;
span.p = tracingAttributes.parentId;
}
if (spanP) {
span.p = spanP;
}
}

@@ -425,0 +469,0 @@

@@ -23,56 +23,61 @@ /*

* The functions in this module return an object literal with the following shape:
* {
* traceId <string>:
* - the trace ID
*
* @typedef {Object} TracingHeaders
* @property {string} [traceId] the trace ID:
* - will be used for span.t
* - will be used for propagating X-INSTANA-T downstream
* - will be used for the trace ID part when propagating traceparent downstream
* longTraceId <string>:
* @property {string} [longTraceId]
* - the full trace ID, when limiting a 128 bit trace ID to 64 bit has occured
* - when no limiting has been applied, this is unset
* - will be used for span.lt
* usedTraceParent <boolean>:
* - true if and only if trace ID and parent ID have been taken from traceparent instead of X-INSTAN-T/X-INSTANA-S.
* parentId <string>:
* @property {boolean} usedTraceParent
* - true if and only if trace ID and parent ID have been taken from the traceparent head (instead of being either
* taken from X-INSTAN-T/X-INSTANA-S or having been generated).
* @property {string} [parentId]
* - the parent span ID
* - will be used for span.p
* - will be used for propagating X-INSTANA-S downstream
* - before propagating traceparent another exit span will be created, whose span ID will be used for the parent ID
* part in traceparent
* level: <string>:
* - can be null, when this is a the root entry span of a new trace
* @property {string} level
* - the tracing level, either '1' (tracing) or '0' (suppressing/not creating spans)
* - progated downstream as the first component of X-INSTANA-L
* - propagted downstream as the sampled flag in traceparent
* correlationType <string>:
* @property {string} [correlationType]
* - the correlation type parsed from X-INSTANA-L
* - will be used for span.crtp
* - will not be propagated downstream
* correlationId <string>:
* @property {string} [correlationId]
* - the correlation ID parsed from X-INSTANA-L
* - will be used for span.crid
* - will not be propagated downstream
* synthetic <boolean>:
* @property {boolean} synthetic
* - true if and only if X-INSTANA-SYNTHETIC=1 was present
* - will be used for span.sy
* - will not be propagated downstream
* w3cTraceContext <object>:
* - see ./w3c_trace_context/W3cTraceContext for documentation of attributes
* @property {InstanaAncestor} [instanaAncestor]
* - only captured when no X-INSTANA-T/S were incoming, but traceparent plus tracestate with an "in" key-value pair
* were present in the incoming request
* - will be used as span.ia when present
* @property {import('./w3c_trace_context/W3cTraceContext')} w3cTraceContext
* - the W3C trace context information that was extracted from the incoming request headers traceparent and
* tracestate or a newly created W3C trace context if those headers were not present or invalid
* - will be used to initialize the internal representation of the incoming traceparent/tracestate
* - will be used to manipulate that internal representation according to the W3C trace context spec when creating
* instanaAncestor <object>:
* - only captured when no X-INSTANA-T/S were incoming, but traceparent plus tracestate with an "in" key-value pair
* child spans of the entry span
* - will be used as span.ia when present
* - structure/attributes:
* {
* t: trace ID from tracestate "in" key-value pair
* p: parent ID from tracestate "in" key-value pair
* }
* }
* new child spans and propagating W3C trace context headers downstream
* - see ./w3c_trace_context/W3cTraceContext for documentation of attributes
*/
/**
* @typedef {Object} InstanaAncestor
* @property {string} t the trace ID from tracestate "in" key-value pair, that is, the trace ID of the closest ancestor
* span in the trace tree that has been created by an Instana tracer
* @property {string} p the parent span ID from tracestate "in" key-value pair, that is, the span ID of the closest
* ancestor in the trace tree that has been created by an Instana tracer
*/
/**
* Inspects the headers of an incoming HTTP request for X-INSTANA-T, X-INSTANA-S, X-INSTANA-L, as well as the W3C trace
* context headers traceparent and tracestate.
* @param {import('http').IncomingMessage} req
* @returns {TracingHeaders}
*/

@@ -91,2 +96,3 @@ exports.fromHttpRequest = function fromHttpRequest(req) {

* @param {import('http').IncomingHttpHeaders} headers
* @returns {TracingHeaders}
*/

@@ -103,8 +109,2 @@ exports.fromHeaders = function fromHeaders(headers) {

if (correlationType && correlationId) {
// Ignore X-INSTANA-T/-S and force starting a new span if we received correlation info.
xInstanaT = null;
xInstanaS = null;
}
if (isSuppressed(level)) {

@@ -119,2 +119,8 @@ // Ignore X-INSTANA-T/-S if X-INSTANA-L: 0 is also present.

if (correlationType && correlationId) {
// Ignore X-INSTANA-T/-S and force starting a new span if we received correlation info.
xInstanaT = null;
xInstanaS = null;
}
if (xInstanaT && xInstanaS && w3cTraceContext) {

@@ -187,2 +193,8 @@ // X-INSTANA- headers *and* W3C trace context headers are present. We use the X-NSTANA- values for tracing and also

}
if (!traceId || !parentId) {
// No X-INSTANA- headers, using traceparent is disabled and there was also no in key-value pair in tracestate,
// thus we start a new trace.
traceId = tracingUtil.generateRandomTraceId();
parentId = null;
}
return limitTraceId({

@@ -357,22 +369,2 @@ traceId,

/**
* @typedef {Object} InstanaAncestor
* @property {string} t
* @property {string} p
*/
/**
* @typedef {Object} TracingHeaders
* @property {string} [traceId]
* @property {string} [longTraceId]
* @property {string} [parentId]
* @property {boolean} usedTraceParent
* @property {import('./w3c_trace_context/W3cTraceContext')} w3cTraceContext
* @property {string} level
* @property {string} [correlationType]
* @property {string} [correlationId]
* @property {boolean} synthetic
* @property {InstanaAncestor} [instanaAncestor]
*/
/**
* @param {TracingHeaders} result

@@ -379,0 +371,0 @@ * @returns {TracingHeaders}

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc