aws-xray-sdk-core
Advanced tools
Comparing version 3.4.0 to 3.4.1
@@ -193,5 +193,5 @@ "use strict"; | ||
else { | ||
contextUtils.contextMissingStrategy.contextMissing = contextUtils.CONTEXT_MISSING_STRATEGY.RUNTIME_ERROR.contextMissing; | ||
logger.getLogger().debug('Using default context missing strategy: RUNTIME_ERROR'); | ||
contextUtils.contextMissingStrategy.contextMissing = contextUtils.CONTEXT_MISSING_STRATEGY.LOG_ERROR.contextMissing; | ||
logger.getLogger().debug('Using default context missing strategy: LOG_ERROR'); | ||
} | ||
module.exports = contextUtils; |
@@ -73,5 +73,12 @@ "use strict"; | ||
var traceId = parent.segment ? parent.segment.trace_id : parent.trace_id; | ||
const data = parent.segment ? parent.segment.additionalTraceData : parent.additionalTraceData; | ||
var buildListener = function (req) { | ||
req.httpRequest.headers['X-Amzn-Trace-Id'] = 'Root=' + traceId + ';Parent=' + subsegment.id + | ||
let traceHeader = 'Root=' + traceId + ';Parent=' + subsegment.id + | ||
';Sampled=' + (subsegment.notTraced ? '0' : '1'); | ||
if (data != null) { | ||
for (const [key, value] of Object.entries(data)) { | ||
traceHeader += ';' + key + '=' + value; | ||
} | ||
} | ||
req.httpRequest.headers['X-Amzn-Trace-Id'] = traceHeader; | ||
}; | ||
@@ -78,0 +85,0 @@ var completeListener = function (res) { |
@@ -16,2 +16,4 @@ import Subsegment = require('./attributes/subsegment'); | ||
additionalTraceData?: object | ||
constructor(name: string, rootId?: string | null, parentId?: string | null); | ||
@@ -18,0 +20,0 @@ |
@@ -143,9 +143,9 @@ "use strict"; | ||
logger.getLogger().debug('Lambda trace data found: ' + xAmznTraceId); | ||
var data = utils.processTraceData(xAmznTraceId); | ||
let traceData = utils.processTraceData(xAmznTraceId); | ||
var valid = false; | ||
if (!data) { | ||
data = {}; | ||
if (!traceData) { | ||
traceData = {}; | ||
logger.getLogger().error('_X_AMZN_TRACE_ID is empty or has an invalid format'); | ||
} | ||
else if (!data.root || !data.parent || !data.sampled) { | ||
else if (!traceData.root || !traceData.parent || !traceData.sampled) { | ||
logger.getLogger().error('_X_AMZN_TRACE_ID is missing required information'); | ||
@@ -156,9 +156,9 @@ } | ||
} | ||
segment.trace_id = TraceID.FromString(data.root).toString(); // Will always assign valid trace_id | ||
segment.id = data.parent || crypto.randomBytes(8).toString('hex'); | ||
if (data.root && segment.trace_id !== data.root) { | ||
segment.trace_id = TraceID.FromString(traceData.root).toString(); // Will always assign valid trace_id | ||
segment.id = traceData.parent || crypto.randomBytes(8).toString('hex'); | ||
if (traceData.root && segment.trace_id !== traceData.root) { | ||
logger.getLogger().error('_X_AMZN_TRACE_ID contains invalid trace ID'); | ||
valid = false; | ||
} | ||
if (!parseInt(data.sampled)) { | ||
if (!parseInt(traceData.sampled)) { | ||
segment.notTraced = true; | ||
@@ -169,3 +169,6 @@ } | ||
} | ||
logger.getLogger().debug('Segment started: ' + JSON.stringify(data)); | ||
if (traceData.data) { | ||
segment.userData = traceData.data; | ||
} | ||
logger.getLogger().debug('Segment started: ' + JSON.stringify(traceData)); | ||
return valid; | ||
@@ -182,2 +185,3 @@ } | ||
var amznTraceData = {}; | ||
var data = {}; | ||
var reservedKeywords = ['root', 'parent', 'sampled', 'self']; | ||
@@ -194,10 +198,11 @@ var remainingBytes = 256; | ||
if (pair[0] && pair[1]) { | ||
var key = pair[0].trim().toLowerCase(); | ||
var value = pair[1].trim().toLowerCase(); | ||
var reserved = reservedKeywords.indexOf(key) !== -1; | ||
let key = pair[0].trim(); | ||
let value = pair[1].trim(); | ||
let lowerCaseKey = key.toLowerCase(); | ||
let reserved = reservedKeywords.indexOf(lowerCaseKey) !== -1; | ||
if (reserved) { | ||
amznTraceData[key] = value; | ||
amznTraceData[lowerCaseKey] = value; | ||
} | ||
else if (!reserved && remainingBytes - (key.length + value.length) >= 0) { | ||
amznTraceData[key] = value; | ||
else if (!reserved && remainingBytes - (lowerCaseKey.length + value.length) >= 0) { | ||
data[key] = value; | ||
remainingBytes -= (key.length + value.length); | ||
@@ -207,2 +212,3 @@ } | ||
}); | ||
amznTraceData['data'] = data; | ||
return amznTraceData; | ||
@@ -209,0 +215,0 @@ }, |
{ | ||
"name": "aws-xray-sdk-core", | ||
"version": "3.4.0", | ||
"version": "3.4.1", | ||
"description": "AWS X-Ray SDK for Javascript", | ||
@@ -58,3 +58,3 @@ "author": "Amazon Web Services", | ||
"repository": "https://github.com/aws/aws-xray-sdk-node/tree/master/packages/core", | ||
"gitHead": "c831933eca6a727371b56733feb6275d35ad91e2" | ||
"gitHead": "866f8240fa3120a4b5d933227f922507647c5944" | ||
} |
@@ -60,3 +60,3 @@ | ||
AWS_XRAY_DAEMON_ADDRESS For setting the daemon address and port. | ||
AWS_XRAY_CONTEXT_MISSING For setting the SDK behavior when trace context is missing. Valid values are 'RUNTIME_ERROR', 'IGNORE_ERROR' or 'LOG_ERROR'. The SDK's default behavior is 'RUNTIME_ERROR'. | ||
AWS_XRAY_CONTEXT_MISSING For setting the SDK behavior when trace context is missing. Valid values are 'RUNTIME_ERROR', 'IGNORE_ERROR' or 'LOG_ERROR'. The SDK's default behavior is 'LOG_ERROR'. | ||
AWS_XRAY_LOG_LEVEL Sets a log level for the SDK built in logger. This value is ignored if AWS_XRAY_DEBUG_MODE is set. | ||
@@ -405,2 +405,66 @@ AWS_XRAY_COLLECT_SQL_QUERIES Enables SQL query capture (currently only Postgres supported) | ||
### Oversampling Mitigation | ||
To modify the sampling decision at the subsegment level, subsegments that inherit the decision of their direct parent (segment or subsegment) can be created using the `addNewSubsegment` and `addSubsegment` APIs, and unsampled subsegments can be created using the `addNewSubsegmentWithoutSampling` and `addSubsegmentWithoutSampling` APIs. | ||
The code snippet below demonstrates creating a sampled or unsampled subsegment based on the sampling decision of each SQS message processed by Lambda. | ||
```js | ||
exports.handler = async function(event, context) { | ||
event.Records.forEach(message => { | ||
const { attributes } = message; | ||
let facade = xrayContext.getSegment(); | ||
if(SqsMessageHelper.isSampled(message)){ | ||
let sampledSubsegment = facade.addNewSubsegment('sqs-subsegment-sampled'); | ||
xrayContext.setSegment(sampledSubsegment); | ||
console.log("processing SQS message - sampled"); | ||
sampledSubsegment.close(); | ||
} else { | ||
let unsampledSubsegment = facade.addNewSubsegmentWithoutSampling('sqs-subsegment-unsampled'); | ||
xrayContext.setSegment(unsampledSubsegment); | ||
console.log("processing SQS message - unsampled"); | ||
unsampledSubsegment.close(); | ||
} | ||
xrayContext.setSegment(facade); | ||
}); | ||
return 'Success'; | ||
} | ||
``` | ||
The code snippet below demonstrates wrapping a downstream AWS SDK request with an unsampled subsegment. | ||
```js | ||
const { Segment } = require('aws-xray-sdk'); | ||
const xray = require('aws-xray-sdk'); | ||
// Instrument AWS SDK Clients | ||
const AWS = xray.captureAWS(require('aws-sdk')); | ||
exports.handler = async (event, context) => { | ||
const facade = xray.getSegment(); | ||
// Create a not-sampled subsegment, which will coerce the downstream request to be unsampled | ||
const unsampled = facade.addNewSubsegmentWithoutSampling('sqs-subsegment-unsampled'); | ||
// Set unsampled subsegment in context | ||
xray.setSegment(unsampled); | ||
try { | ||
const sqs = new AWS.SQS(); | ||
const data = await sqs.listQueues().promise(); | ||
console.log(data); | ||
} catch (error) { | ||
console.log("retrieveFromSqs error:", error); | ||
throw error; | ||
} | ||
unsampled.close(); | ||
return 'Success'; | ||
} | ||
``` | ||
## Automatic Mode Examples | ||
@@ -407,0 +471,0 @@ |
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
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
238635
5483
790