aws-xray-sdk-core
Advanced tools
Comparing version 2.5.0 to 3.0.0-alpha.1
@@ -13,2 +13,3 @@ { | ||
], | ||
"no-console": "off", | ||
"linebreak-style": [ | ||
@@ -15,0 +16,0 @@ "error", |
# Changelog for AWS X-Ray Core SDK for JavaScript | ||
<!--LATEST=2.5.0--> | ||
<!--LATEST=3.0.0-alpha.1--> | ||
<!--ENTRYINSERT--> | ||
## 3.0.0-alpha.1 | ||
* **BREAKING** change: Merged `2.x` branch into `master`, breaking node v4 [PR #226](https://github.com/aws/aws-xray-sdk-node/pull/226) | ||
* **BREAKING** change: Officially deprecated support for node 4 and 6 [PR #228](https://github.com/aws/aws-xray-sdk-node/pull/228) | ||
* **BREAKING** change: Removed `winston` dependency, which could impact `getLogger` API [PR #190](https://github.com/aws/aws-xray-sdk-node/pull/190) | ||
* improvement: Replaced `continuation-local-storage` with `cls-hooked` [PR #227](https://github.com/aws/aws-xray-sdk-node/pull/227) | ||
* improvement: Whitelisted new SageMaker operation [PR #211](https://github.com/aws/aws-xray-sdk-node/pull/211) | ||
* improvement: Removed dependency on `date-fns` [PR #229](https://github.com/aws/aws-xray-sdk-node/pull/229) | ||
* bugfix: Make resolve segment argument optional [PR #216](https://github.com/aws/aws-xray-sdk-node/pull/216) | ||
* bugfix: Remove unused Lambda handshake file [PR #221](https://github.com/aws/aws-xray-sdk-node/pull/221) | ||
* bugfix: Replace `Date.getTime` with `Date.Now` [PR #230](https://github.com/aws/aws-xray-sdk-node/pull/230) | ||
## 2.5.0 | ||
@@ -5,0 +17,0 @@ * improvement: Add setUser function to segment object [PR #206](https://github.com/aws/aws-xray-sdk-node/pull/206) |
@@ -289,4 +289,4 @@ var contextUtils = require('./context_utils'); | ||
/** | ||
* Enables automatic mode. Automatic mode uses 'continuation-local-storage'. | ||
* @see https://github.com/othiym23/node-continuation-local-storage | ||
* Enables automatic mode. Automatic mode uses 'cls-hooked'. | ||
* @see https://github.com/jeff-lewis/cls-hooked | ||
* @memberof AWSXRay | ||
@@ -293,0 +293,0 @@ * @function |
@@ -7,3 +7,3 @@ import { Namespace } from 'continuation-local-storage'; | ||
export function resolveSegment(segment: Segment | Subsegment): Segment | Subsegment | undefined; | ||
export function resolveSegment(segment?: Segment | Subsegment | null): Segment | Subsegment | undefined; | ||
@@ -10,0 +10,0 @@ export function getSegment(): Segment | Subsegment | undefined; |
@@ -5,3 +5,3 @@ /** | ||
var cls = require('continuation-local-storage'); | ||
var cls = require('cls-hooked'); | ||
@@ -131,4 +131,4 @@ var logger = require('./logger'); | ||
/** | ||
* Enables automatic mode. Automatic mode uses 'continuation-local-storage'. | ||
* @see https://github.com/othiym23/node-continuation-local-storage | ||
* Enables automatic mode. Automatic mode uses 'cls-hooked'. | ||
* @see https://github.com/jeff-lewis/cls-hooked | ||
* @alias module:context_utils.enableAutomaticMode | ||
@@ -135,0 +135,0 @@ */ |
@@ -1,3 +0,1 @@ | ||
var fs = require('fs'); | ||
var contextUtils = require('../context_utils'); | ||
@@ -27,11 +25,2 @@ var LambdaUtils = require('../utils').LambdaUtils; | ||
fs.mkdir('/tmp/', function() { | ||
fs.mkdir('/tmp/.aws-xray/', function() { | ||
var filename = '/tmp/.aws-xray/initialized'; | ||
fs.closeSync(fs.openSync(filename, 'a')); | ||
var now = new Date(); | ||
fs.utimesSync(filename, now, now); | ||
}); | ||
}); | ||
SegmentEmitter.disableReusableSocket(); | ||
@@ -38,0 +27,0 @@ SegmentUtils.setStreamingThreshold(0); |
@@ -1,97 +0,80 @@ | ||
var winston = require('winston'); | ||
var format = require('date-fns/format'); | ||
var validLogLevels = [ 'debug', 'info', 'warn', 'error', 'silent' ]; | ||
var defaultLogLevel = validLogLevels.indexOf('error'); | ||
var logLevel = calculateLogLevel(process.env.AWS_XRAY_DEBUG_MODE ? 'debug' : process.env.AWS_XRAY_LOG_LEVEL); | ||
var logger; | ||
var xrayLogLevel = process.env.AWS_XRAY_LOG_LEVEL; | ||
var logger = { | ||
error: createLoggerForLevel('error'), | ||
info: createLoggerForLevel('info'), | ||
warn: createLoggerForLevel('warn'), | ||
debug: createLoggerForLevel('debug'), | ||
}; | ||
if (process.env.AWS_XRAY_DEBUG_MODE) { | ||
logger = new (winston.Logger)({ | ||
transports: [ | ||
new (winston.transports.Console)({ | ||
formatter: outputFormatter, | ||
level: 'debug', | ||
timestamp: timestampFormatter | ||
}) | ||
] | ||
}); | ||
} else if (xrayLogLevel) { | ||
logger = new (winston.Logger)({ | ||
transports: [ | ||
new (winston.transports.Console)({ | ||
formatter: outputFormatter, | ||
level: xrayLogLevel, | ||
timestamp: timestampFormatter | ||
}) | ||
] | ||
}); | ||
} else { | ||
logger = new (winston.Logger)({}); | ||
function createLoggerForLevel(level) { | ||
var loggerLevel = validLogLevels.indexOf(level); | ||
var consoleMethod = console[level] || console.log || (() => {}); | ||
if (loggerLevel >= logLevel) { | ||
return (message, meta) => { | ||
if(message || meta) { | ||
consoleMethod(formatLogMessage(level, message, meta)); | ||
} | ||
}; | ||
} else { | ||
return () => {}; | ||
} | ||
} | ||
/* eslint-disable no-console */ | ||
if (process.env.LAMBDA_TASK_ROOT) { | ||
logger.error = function(string) { console.error(string); }; | ||
logger.info = function(string) { console.info(string); }; | ||
logger.warn = function(string) { console.warn(string); }; | ||
if (process.env.AWS_XRAY_DEBUG_MODE) { | ||
logger.debug = function(string) { console.debug(string); }; | ||
function calculateLogLevel(level) { | ||
if (level) { | ||
var normalisedLevel = level.toLowerCase(); | ||
var index = validLogLevels.indexOf(normalisedLevel); | ||
return index >= 0 ? index : defaultLogLevel; | ||
} | ||
// Silently ignore invalid log levels, default to default level | ||
return defaultLogLevel; | ||
} | ||
/* eslint-enable no-console */ | ||
function timestampFormatter() { | ||
return format(new Date(), 'YYYY-MM-DD HH:mm:ss.SSS Z'); | ||
function createTimestamp(date) { | ||
var tzo = -date.getTimezoneOffset(), // Negate to make this tzo = local - UTC | ||
dif = tzo >= 0 ? '+' : '-', | ||
pad = function(num) { | ||
var norm = Math.floor(Math.abs(num)); | ||
return (norm < 10 ? '0' : '') + norm; | ||
}; | ||
return new Date(date.getTime() + (tzo * 60 * 1000)).toISOString() | ||
.replace(/T/, ' ') | ||
.replace(/Z/, ' ') + | ||
dif + pad(tzo / 60) + | ||
':' + pad(tzo % 60); | ||
} | ||
function outputFormatter(options) { | ||
return options.timestamp() +' [' + options.level.toUpperCase() + '] '+ | ||
(options.message !== undefined ? options.message : '') + | ||
(options.meta && Object.keys(options.meta).length ? '\n\t'+ JSON.stringify(options.meta) : '' ); | ||
function isLambdaFunction() { | ||
return process.env.LAMBDA_TASK_ROOT !== undefined; | ||
} | ||
/** | ||
* Polyfill for Object.keys | ||
* @see: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys | ||
*/ | ||
function formatLogMessage(level, message, meta) { | ||
var messageParts = []; | ||
if (!Object.keys) { | ||
Object.keys = (function() { | ||
'use strict'; | ||
var hasOwnProperty = Object.prototype.hasOwnProperty, | ||
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'), | ||
dontEnums = [ | ||
'toString', | ||
'toLocaleString', | ||
'valueOf', | ||
'hasOwnProperty', | ||
'isPrototypeOf', | ||
'propertyIsEnumerable', | ||
'constructor' | ||
], | ||
dontEnumsLength = dontEnums.length; | ||
if (!isLambdaFunction()) { | ||
messageParts.push(createTimestamp(new Date())); | ||
messageParts.push(`[${level.toUpperCase()}]`); | ||
} | ||
return function(obj) { | ||
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { | ||
throw new TypeError('Object.keys called on non-object'); | ||
} | ||
if (message) { | ||
messageParts.push(message); | ||
} | ||
var result = [], prop, i; | ||
var logString = messageParts.join(' '); | ||
var metaDataString = formatMetaData(meta); | ||
return [logString, metaDataString].filter(str => str.length > 0).join('\n '); | ||
} | ||
for (prop in obj) { | ||
if (hasOwnProperty.call(obj, prop)) { | ||
result.push(prop); | ||
} | ||
} | ||
function formatMetaData(meta) { | ||
if (!meta) { | ||
return ''; | ||
} | ||
if (hasDontEnumBug) { | ||
for (i = 0; i < dontEnumsLength; i++) { | ||
if (hasOwnProperty.call(obj, dontEnums[i])) { | ||
result.push(dontEnums[i]); | ||
} | ||
} | ||
} | ||
return result; | ||
}; | ||
}()); | ||
return ((typeof(meta) === 'string') ? meta : JSON.stringify(meta)); | ||
} | ||
@@ -98,0 +81,0 @@ |
@@ -946,4 +946,13 @@ { | ||
} | ||
}, | ||
"sagemakerruntime": { | ||
"operations": { | ||
"invokeEndpoint": { | ||
"request_parameters": [ | ||
"EndpointName" | ||
] | ||
} | ||
} | ||
} | ||
} | ||
} |
@@ -131,3 +131,3 @@ var dgram = require('dgram'); | ||
var data = PROTOCOL_HEADER + PROTOCOL_DELIMITER + formatted; | ||
var message = new Buffer(data); | ||
var message = Buffer.from(data); | ||
@@ -134,0 +134,0 @@ var short = '{"trace_id:"' + segment.trace_id + '","id":"' + segment.id + '"}'; |
@@ -9,3 +9,3 @@ var logger = require('../logger'); | ||
getCurrentTime: function getCurrentTime() { | ||
return new Date().getTime()/1000; | ||
return Date.now() / 1000; | ||
}, | ||
@@ -12,0 +12,0 @@ |
{ | ||
"name": "aws-xray-sdk-core", | ||
"version": "2.5.0", | ||
"version": "3.0.0-alpha.1", | ||
"description": "AWS X-Ray SDK for Javascript", | ||
@@ -21,7 +21,5 @@ "author": "Amazon Web Services", | ||
"aws-sdk": "^2.304.0", | ||
"continuation-local-storage": "^3.2.0", | ||
"date-fns": "^1.29.0", | ||
"cls-hooked": "^4.2.2", | ||
"pkginfo": "^0.4.0", | ||
"semver": "^5.3.0", | ||
"winston": "^2.4.4" | ||
"semver": "^5.3.0" | ||
}, | ||
@@ -36,9 +34,12 @@ "devDependencies": { | ||
"nock": "^10.0.6", | ||
"rewire": "^4.0.1", | ||
"sinon": "^4.5.0", | ||
"sinon-chai": "^2.8.0", | ||
"tsd": "^0.10.0" | ||
"tsd": "^0.10.0", | ||
"upath": "^1.2.0" | ||
}, | ||
"scripts": { | ||
"test": "mocha --recursive ./test/ -R spec && tsd", | ||
"test-d": "tsd" | ||
"test": "mocha --recursive ./test/ -R spec && tsd && mocha --recursive ./test_async/ -R spec", | ||
"test-d": "tsd", | ||
"test-async": "mocha --recursive ./test_async/ -R spec" | ||
}, | ||
@@ -56,3 +57,3 @@ "keywords": [ | ||
"repository": "https://github.com/aws/aws-xray-sdk-node/tree/master/packages/core", | ||
"gitHead": "9cb04b6ddcabca33dc483c8e1d3e82d6fb108e80" | ||
"gitHead": "f6e7c2e311dda848aa3915b9c0e0ad2d714745fa" | ||
} |
@@ -12,4 +12,4 @@ | ||
EC2 instance data (via plugins). Currently, only Express | ||
applications are supported for automatic capturing. See the [aws-xray-sdk-express] | ||
(https://github.com/aws/aws-xray-sdk-node/tree/master/packages/express) package for additional information. | ||
applications are supported for automatic capturing. See the | ||
[aws-xray-sdk-express](https://github.com/aws/aws-xray-sdk-node/tree/master/packages/express) package for additional information. | ||
@@ -79,3 +79,3 @@ The SDK exposes the Segment and Subsegment objects so you can create your own capturing | ||
AWS_XRAY_DEBUG_MODE Enables logging to console output. Logging to a file is no longer built in. See 'configure logging' below. | ||
AWS_XRAY_DEBUG_MODE Enables logging of debug messages to console output. Logging to a file is no longer built in. See 'configure logging' below. | ||
AWS_XRAY_TRACING_NAME For overriding the default segment name to use | ||
@@ -85,3 +85,3 @@ with the middleware. See 'dynamic and fixed naming modes'. | ||
AWS_XRAY_CONTEXT_MISSING For setting the SDK behavior when trace context is missing. Valid values are 'RUNTIME_ERROR' or 'LOG_ERROR'. The SDK's default behavior is 'RUNTIME_ERROR'. | ||
AWS_XRAY_LOG_LEVEL Sets a log level for the SDK built in logger. | ||
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. | ||
@@ -100,13 +100,35 @@ ### Daemon configuration | ||
Default logging to a file has been removed. To set up file logging, configure a logger | ||
that responds to debug, info, warn, and error functions. To suppress logs such as context setup the log level can be | ||
overridden, e.g. to suppress info logs such as context and daemon config set the following environment variable. | ||
By default the SDK will log error messages to the console using the standard methods on the console object. The log | ||
level of the built in logger can be set bu using either the `AWS_XRAY_DEBUG_MODE` or `AWS_XRAY_LOG_LEVEL` environment | ||
variables. | ||
AWS_XRAY_LOG_LEVEL='error' | ||
If `AWS_XRAY_DEBUG_MODE` is set to a truthy value, e.g. true, then the log level will be set to debug. If | ||
`AWS_XRAY_DEBUG_MODE` is not set then `AWS_XRAY_LOG_LEVEL` will be used to determine the log level. This variable can | ||
be set to either debug, info, warn, error or silent. Be warned if the log level is set to silent then NO log | ||
messages will be produced. The default log level is error and this will be used if neither environment variable | ||
is set or if an invalid level is specified. | ||
To log information about configuration, be sure you set the logger before other configuration | ||
options. | ||
If you wish to provide a different format or destination for the logs then you can provide the SDK with your own | ||
implementation of the logger interface as shown below. Any object that implements this interface can be used. | ||
This means that many logging libraries, e.g. Winston, could be used and passed to the SDK directly. | ||
AWSXRay.setLogger(logger); | ||
```js | ||
// Create your own logger or instantiate one using a library. | ||
var logger = { | ||
error: (message, meta) => { /* logging code */ }, | ||
warn: (message, meta) => { /* logging code */ }, | ||
info: (message, meta) => { /* logging code */ }, | ||
debug: (message, meta) => { /* logging code */ } | ||
} | ||
AWSXRay.setLogger(logger); | ||
``` | ||
If you use your own logger you are responsible for determining the log level as the `AWS_XRAY_DEBUG_MODE` and | ||
`AWS_XRAY_LOG_LEVEL` only apply to the default logger. | ||
Note that by default the provided logger prefixes each log line with a timestamp and the | ||
log level of the message. However this is not the case when using this SDK | ||
within an AWS Lambda function. In that scenario the timestamp and level are added by the Lambda runtime instead. | ||
### Context Missing Strategy Configuration | ||
@@ -287,3 +309,3 @@ | ||
For additional information about and examples for using the CLS namespace to create | ||
a new context, see: https://github.com/othiym23/node-continuation-local-storage. | ||
a new context, see: https://github.com/jeff-lewis/cls-hooked. | ||
@@ -290,0 +312,0 @@ ### Capture subsegmenets within chained native Promise using automatic mode |
@@ -107,3 +107,2 @@ import * as AWS from 'aws-sdk'; | ||
); | ||
expectType<string | undefined>(urlWithoutQuery.path); | ||
expectError(urlWithoutQuery.query); | ||
@@ -155,2 +154,5 @@ | ||
expectType<AWSXRay.Segment | AWSXRay.Subsegment | undefined>(AWSXRay.resolveSegment(segment)); | ||
expectType<AWSXRay.Segment | AWSXRay.Subsegment | undefined>(AWSXRay.resolveSegment(undefined)); | ||
expectType<AWSXRay.Segment | AWSXRay.Subsegment | undefined>(AWSXRay.resolveSegment(null)); | ||
expectType<AWSXRay.Segment | AWSXRay.Subsegment | undefined>(AWSXRay.resolveSegment()); | ||
expectType<AWSXRay.Segment | AWSXRay.Subsegment | undefined>(AWSXRay.getSegment()); | ||
@@ -157,0 +159,0 @@ expectType<void>(AWSXRay.setSegment(segment)); |
@@ -5,2 +5,3 @@ var assert = require('chai').assert; | ||
var sinonChai = require('sinon-chai'); | ||
var upath = require('upath'); | ||
@@ -33,4 +34,5 @@ var segmentUtils = require('../../lib/segments/segment_utils'); | ||
// could run independently. | ||
Object.keys(require.cache).forEach(function(key) { | ||
if(key.includes('core/lib/index.js') || key.includes('core/lib/aws-xray.js')) { | ||
Object.keys(require.cache).forEach(function(key) { | ||
var normalisedPath = upath.toUnix(key); | ||
if(normalisedPath.includes('core/lib/index.js') || normalisedPath.includes('core/lib/aws-xray.js')) { | ||
delete require.cache[key]; | ||
@@ -37,0 +39,0 @@ } |
var assert = require('chai').assert; | ||
var chai = require('chai'); | ||
var fs = require('fs'); | ||
var sinon = require('sinon'); | ||
@@ -43,3 +42,3 @@ var sinonChai = require('sinon-chai'); | ||
describe('#init', function() { | ||
var disableReusableSocketStub, openSyncStub, populateStub, sandbox, setSegmentStub, validateStub; | ||
var disableReusableSocketStub, populateStub, sandbox, setSegmentStub, validateStub; | ||
@@ -49,7 +48,2 @@ beforeEach(function() { | ||
disableReusableSocketStub = sandbox.stub(SegmentEmitter, 'disableReusableSocket'); | ||
openSyncStub = sandbox.stub(fs, 'openSync'); | ||
sandbox.stub(fs, 'mkdir').yields(); | ||
sandbox.stub(fs, 'closeSync'); | ||
sandbox.stub(fs, 'utimesSync'); | ||
validateStub = sandbox.stub(LambdaUtils, 'validTraceData').returns(true); | ||
@@ -64,7 +58,2 @@ populateStub = sandbox.stub(LambdaUtils, 'populateTraceData').returns(true); | ||
it('should create the AWS XRay init file', function() { | ||
Lambda.init(); | ||
openSyncStub.should.have.been.calledOnce; | ||
}); | ||
it('should disable reusable socket', function() { | ||
@@ -124,6 +113,2 @@ Lambda.init(); | ||
sandbox.stub(SegmentEmitter, 'disableReusableSocket'); | ||
sandbox.stub(fs, 'openSync'); | ||
sandbox.stub(fs, 'mkdir').yields(); | ||
sandbox.stub(fs, 'closeSync'); | ||
sandbox.stub(fs, 'utimesSync'); | ||
@@ -130,0 +115,0 @@ sandbox.stub(LambdaUtils, 'validTraceData').returns(true); |
@@ -1,43 +0,276 @@ | ||
var assert = require('chai').assert; | ||
var expect = require('chai').expect; | ||
var rewire = require('rewire'); | ||
var sinon = require('sinon'); | ||
var logging = require('../../lib/logger'); | ||
var logger = require('../../lib/logger'); | ||
describe('logger', function () { | ||
var spies = []; | ||
describe('logger', function () { | ||
function reloadLogger() { | ||
var path = '../../lib/logger'; | ||
delete require.cache[require.resolve(path)]; | ||
logger = require(path); | ||
logging = require(path); | ||
} | ||
describe('defaults', function () { | ||
afterEach(function () { | ||
before(function() { | ||
spies.push(sinon.spy(console, 'error')); | ||
spies.push(sinon.spy(console, 'warn')); | ||
spies.push(sinon.spy(console, 'info')); | ||
spies.push(sinon.spy(console, 'log')); | ||
if (console.debug) { | ||
spies.push(sinon.spy(console, 'debug')); | ||
} | ||
}); | ||
afterEach(function () { | ||
spies.forEach(spy => spy.resetHistory()); | ||
}); | ||
after(function () { | ||
spies.forEach(spy => spy.restore()); | ||
}); | ||
describe('console logging methods', function () { | ||
before(function() { | ||
process.env.AWS_XRAY_DEBUG_MODE = 'set'; | ||
reloadLogger(); | ||
}); | ||
after(function() { | ||
delete process.env.AWS_XRAY_DEBUG_MODE; | ||
}); | ||
it('Should send debug logs to console.debug', function () { | ||
logging.getLogger().debug('test'); | ||
if (console.debug) { | ||
expect(console.debug).to.be.calledOnce; | ||
} else { | ||
expect(console.log).to.be.calledOnce; | ||
} | ||
}); | ||
it('Should send info logs to console.info', function () { | ||
logging.getLogger().info('test'); | ||
expect(console.info).to.be.calledOnce; | ||
}); | ||
it('Should send warn logs to console.warn', function () { | ||
logging.getLogger().warn('test'); | ||
expect(console.warn).to.be.calledOnce; | ||
}); | ||
it('Should sent error logs to console.error', function () { | ||
logging.getLogger().error('test'); | ||
expect(console.error).to.be.calledOnce; | ||
}); | ||
}); | ||
describe('console logging filters', function () { | ||
function sendLogMessages() { | ||
var logger = logging.getLogger(); | ||
logger.debug('test'); | ||
logger.info('test'); | ||
logger.warn('test'); | ||
logger.error('test'); | ||
} | ||
afterEach(function() { | ||
delete process.env.AWS_XRAY_LOG_LEVEL; | ||
}); | ||
it('Should not emit log if log level is silent', function () { | ||
process.env.AWS_XRAY_LOG_LEVEL = 'silent'; | ||
reloadLogger(); | ||
sendLogMessages(); | ||
spies.forEach(spy => expect(spy).to.not.be.called); | ||
}); | ||
it('Should have a default logger with no transport and level set to info', function () { | ||
process.env.AWS_XRAY_LOG_LEVEL = ''; | ||
process.env.AWS_XRAY_DEBUG_MODE = ''; | ||
it('Should only emit error logs if level is error', function () { | ||
process.env.AWS_XRAY_LOG_LEVEL = 'error'; | ||
reloadLogger(); | ||
assert.deepEqual(logger.getLogger().transports, {}); | ||
assert.equal(logger.getLogger().level, 'info'); | ||
sendLogMessages(); | ||
expect(console.error).to.be.calledOnce; | ||
spies.filter(spy => spy !== console.error) | ||
.forEach(spy => expect(spy).to.not.be.called); | ||
}); | ||
it('Should have a logger with console transport with level set to debug when AWS_XRAY_DEBUG_MODE is set', function () { | ||
process.env.AWS_XRAY_DEBUG_MODE = 'set'; | ||
it('Should emit error and warn logs if level is warn', function () { | ||
process.env.AWS_XRAY_LOG_LEVEL = 'warn'; | ||
reloadLogger(); | ||
assert.equal(logger.getLogger().transports.console.level, 'debug'); | ||
sendLogMessages(); | ||
var expected = [ console.error, console.warn ]; | ||
expected.forEach(spy => expect(spy).to.be.called); | ||
spies.filter(spy => !expected.includes(spy)) | ||
.forEach(spy => expect(spy).to.not.be.called); | ||
}); | ||
it('Should have a logger with console transport with level set to debug when AWS_XRAY_DEBUG_MODE is set even when XRAY_LOG_LEVEL is error', function () { | ||
process.env.AWS_XRAY_DEBUG_MODE = 'set'; | ||
process.env.AWS_XRAY_LOG_LEVEL = 'error'; | ||
it('Should emit error, warn, and info logs if level is info', function () { | ||
process.env.AWS_XRAY_LOG_LEVEL = 'info'; | ||
reloadLogger(); | ||
assert.equal(logger.getLogger().transports.console.level, 'debug'); | ||
sendLogMessages(); | ||
var expected = [ console.error, console.warn, console.info ]; | ||
expected.forEach(spy => expect(spy).to.be.called); | ||
spies.filter(spy => !expected.includes(spy)) | ||
.forEach(spy => expect(spy).to.not.be.called); | ||
}); | ||
it('Should have a logger with console transport with level set to error when AWS_XRAY_LOG_LEVEL=error and AWS_XRAY_DEBUG_MODE is not set', function () { | ||
process.env.AWS_XRAY_LOG_LEVEL = 'error'; | ||
process.env.AWS_XRAY_DEBUG_MODE = ''; | ||
it('Should emit all logs if level is debug', function () { | ||
process.env.AWS_XRAY_LOG_LEVEL = 'debug'; | ||
reloadLogger(); | ||
assert.equal(logger.getLogger().transports.console.level, 'error'); | ||
sendLogMessages(); | ||
var filterMethod = console.debug ? (spy => spy !== console.log) : (() => true); | ||
spies.filter(filterMethod).forEach(spy => expect(spy).to.be.called); | ||
}); | ||
it('Should default to error if invalid log level', function () { | ||
process.env.AWS_XRAY_LOG_LEVEL = 'not_a_level'; | ||
reloadLogger(); | ||
sendLogMessages(); | ||
expect(console.error).to.be.calledOnce; | ||
spies.filter(spy => spy !== console.error) | ||
.forEach(spy => expect(spy).to.not.be.called); | ||
}); | ||
it('Should default to error if no log level', function () { | ||
reloadLogger(); | ||
sendLogMessages(); | ||
expect(console.error).to.be.calledOnce; | ||
spies.filter(spy => spy !== console.error) | ||
.forEach(spy => expect(spy).to.not.be.called); | ||
}); | ||
}); | ||
describe('console logging format', function () { | ||
var logMessageRegex = /(\d{4}-[01]\d-[0-3]\d) ([0-2]\d:[0-5]\d:[0-5]\d\.\d+) ([+-][0-2]\d:[0-5]\d) \[(\w+)\](.*)/; | ||
var timestampRegex = /(\d{4}-[01]\d-[0-3]\d) ([0-2]\d:[0-5]\d:[0-5]\d\.\d+) ([+-][0-2]\d:[0-5]\d)/; | ||
before(function() { | ||
reloadLogger(); | ||
}); | ||
afterEach(function() { | ||
delete process.env.LAMBDA_TASK_ROOT; | ||
}); | ||
it('should output error message', () => { | ||
var logger = logging.getLogger(); | ||
var expectedMessage = 'error message'; | ||
logger.error(expectedMessage); | ||
var message = console.error.args[0][0]; | ||
var groups = message.match(logMessageRegex); | ||
expect(groups[4]).to.equal('ERROR'); | ||
expect(groups[5].trim()).to.equal(expectedMessage); | ||
}); | ||
it('should not output if message and meta falsey', () => { | ||
var logger = logging.getLogger(); | ||
logger.error(); | ||
logger.error(null); | ||
logger.error('', null); | ||
spies.forEach(spy => expect(spy).not.to.be.called); | ||
}); | ||
it('should convert falsey value to empty string', () => { | ||
var logger = logging.getLogger(); | ||
logger.error(null, {}); | ||
var message = console.error.args[0][0]; | ||
var groups = message.match(logMessageRegex); | ||
expect(groups[4]).to.equal('ERROR'); | ||
expect(groups[5]).to.equal(''); | ||
}); | ||
it('should not add timestamp to lambda errors', () => { | ||
process.env.LAMBDA_TASK_ROOT = 'on'; | ||
var expectedMessage = 'error message'; | ||
var logger = logging.getLogger(); | ||
logger.error(expectedMessage); | ||
var message = console.error.args[0][0]; | ||
expect(logMessageRegex.test(message)).to.be.false; | ||
expect(message).to.equal(expectedMessage); | ||
}); | ||
it('should only output metadata for lambda with no message', () => { | ||
process.env.LAMBDA_TASK_ROOT = 'on'; | ||
var expectedMetaData = 'this is some metadata'; | ||
var logger = logging.getLogger(); | ||
logger.error(null, expectedMetaData); | ||
var message = console.error.args[0][0]; | ||
expect(logMessageRegex.test(message)).to.be.false; | ||
expect(message).to.equal(expectedMetaData); | ||
}); | ||
it('should output both message and metadata for lambda', () => { | ||
process.env.LAMBDA_TASK_ROOT = 'on'; | ||
var expectedMessage = 'error message'; | ||
var expectedMetaData = 'metadata'; | ||
var logger = logging.getLogger(); | ||
logger.error(expectedMessage, expectedMetaData); | ||
var message = console.error.args[0][0]; | ||
expect(logMessageRegex.test(message)).to.be.false; | ||
expect(message).to.equal(expectedMessage + '\n ' + expectedMetaData); | ||
}); | ||
it('should generate timestamp with negative timezone offset', () => { | ||
var rewiredLogger = rewire('../../lib/logger'); | ||
var createTimestamp = rewiredLogger.__get__('createTimestamp'); | ||
var date = new Date(); | ||
sinon.stub(date, 'getTimezoneOffset').returns(60); | ||
var stamp = createTimestamp(date); | ||
var groups = stamp.match(timestampRegex); | ||
expect(groups[3]).to.equal('-01:00'); | ||
}); | ||
it('should generate timestamp with positive timezone offset', () => { | ||
var rewiredLogger = rewire('../../lib/logger'); | ||
var createTimestamp = rewiredLogger.__get__('createTimestamp'); | ||
var date = new Date(); | ||
sinon.stub(date, 'getTimezoneOffset').returns(-60); | ||
var stamp = createTimestamp(date); | ||
var groups = stamp.match(timestampRegex); | ||
expect(groups[3]).to.equal('+01:00'); | ||
}); | ||
it('should generate timestamp with special timezone offset', () => { | ||
var rewiredLogger = rewire('../../lib/logger'); | ||
var createTimestamp = rewiredLogger.__get__('createTimestamp'); | ||
var date = new Date(); | ||
sinon.stub(date, 'getTimezoneOffset').returns(108); | ||
var stamp = createTimestamp(date); | ||
var groups = stamp.match(timestampRegex); | ||
expect(groups[3]).to.equal('-01:48'); | ||
}); | ||
it('should generate correctly formatted timestamp', () => { | ||
var rewiredLogger = rewire('../../lib/logger'); | ||
var createTimestamp = rewiredLogger.__get__('createTimestamp'); | ||
var date = new Date(1576877599000); // 12/20/2019 @ 9:33pm (UTC) | ||
sinon.stub(date, 'getTimezoneOffset').returns(0); | ||
var stamp = createTimestamp(date); | ||
var expected = '2019-12-20 21:33:19.000 +00:00'; | ||
expect(stamp).to.equal(expected); | ||
}); | ||
}); | ||
}); |
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
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
378504
6
99
8912
637
67
12
2
6
+ Addedcls-hooked@^4.2.2
+ Addedasync-hook-jl@1.7.6(transitive)
+ Addedcls-hooked@4.2.2(transitive)
+ Addedstack-chain@1.3.7(transitive)
- Removedcontinuation-local-storage@^3.2.0
- Removeddate-fns@^1.29.0
- Removedwinston@^2.4.4
- Removedasync@2.6.4(transitive)
- Removedasync-listener@0.6.10(transitive)
- Removedcolors@1.0.3(transitive)
- Removedcontinuation-local-storage@3.2.1(transitive)
- Removedcycle@1.0.3(transitive)
- Removeddate-fns@1.30.1(transitive)
- Removedeyes@0.1.8(transitive)
- Removedisstream@0.1.2(transitive)
- Removedlodash@4.17.21(transitive)
- Removedstack-trace@0.0.10(transitive)
- Removedwinston@2.4.7(transitive)