diff --git a/README.md b/README.md index b5eadf0be..fab703967 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,7 @@ const logger = winston.createLogger({ ] }); -const childLogger = logger.child({ req_id: '451' }); +const childLogger = logger.child({ requestId: '451' }); ``` ### Streams, `objectMode`, and `info` objects @@ -235,19 +235,13 @@ treated as immutable by all code. - `Symbol.for('message'):` complete string message set by "finalizing formats": `json`, `logstash`, `printf`, `prettyPrint`, and `simple`. -> **NOTE:** the `message` and `level` properties are considered reserved. -> Please be aware of this when logging additional metadata objects. For -> example the below will suppress the `message` property of the metadata -> provided: +> **NOTE:** any `{ message }` property in a `meta` object provided will +> automatically be concatenated to any `msg` already provided: For +> example the below will concatenate 'world' onto 'hello': > > ``` js -> logger.log('hello', { message: 'will be hidden' }); -> ``` -> -> To work around this use the `splat()` format below. e.g.: -> -> ``` js -> logger.log('hello %j', { message: 'will be shown' }); +> logger.log('error', 'hello', { message: 'world' }); +> logger.info('hello', { message: 'world' }); > ``` ## Formats diff --git a/examples/errors.js b/examples/errors.js new file mode 100644 index 000000000..3cd4c3001 --- /dev/null +++ b/examples/errors.js @@ -0,0 +1,20 @@ +const { createLogger, format, transports } = require('../'); +const { combine, errors, json } = format; + +const logger = createLogger({ + format: combine( + errors({ stack: true }), + json() + ), + transports: [ + new transports.Console(), + ] +}); + +logger.warn(new Error('Error passed as info')); +logger.log('error', new Error('Error passed as message')); + +logger.warn('Maybe important error: ', new Error('Error passed as meta')); +logger.log('error', 'Important error: ', new Error('Error passed as meta')); + +logger.error(new Error('Error as info')); diff --git a/lib/winston/logger.js b/lib/winston/logger.js index dbc9efe28..4f0095c25 100644 --- a/lib/winston/logger.js +++ b/lib/winston/logger.js @@ -33,14 +33,12 @@ const formatRegExp = /%[scdjifoO%]/g; */ class Logger extends Transform { /** - * Constructor function for the Logger object responsible for persisting log - * messages and metadata to one or more transports. - * @param {!Object} options - foo - */ + * Constructor function for the Logger object responsible for persisting log + * messages and metadata to one or more transports. + * @param {!Object} options - foo + */ constructor(options) { - super({ - objectMode: true - }); + super({ objectMode: true }); this.configure(options); } @@ -55,7 +53,12 @@ class Logger extends Transform { info ); - // Object.assign doesn't copy inherited Error properties so we have to do that explicitly + // Object.assign doesn't copy inherited Error + // properties so we have to do that explicitly + // + // Remark (indexzero): we should remove this + // since the errors format will handle this case. + // if (info instanceof Error) { infoClone.stack = info.stack; infoClone.message = info.message; @@ -228,29 +231,28 @@ class Logger extends Transform { const tokens = msg && msg.match && msg.match(formatRegExp); if (!tokens) { - this.write(Object.assign({}, meta, { - [LEVEL]: level, - [SPLAT]: splat, - level, - message: msg - }, this.defaultMeta)); - } else { - this.write(Object.assign({}, { + const info = Object.assign({}, this.defaultMeta, meta, { [LEVEL]: level, [SPLAT]: splat, level, message: msg - }, this.defaultMeta)); + }); + + if (meta.message) info.message += `${meta.message}`; + if (meta.stack) info.stack = meta.stack; + + this.write(info); + return this; } - } else { - this.write(Object.assign({}, { - [LEVEL]: level, - [SPLAT]: splat, - level, - message: msg - }, this.defaultMeta)); } + this.write(Object.assign({}, this.defaultMeta, { + [LEVEL]: level, + [SPLAT]: splat, + level, + message: msg + })); + return this; } diff --git a/package-lock.json b/package-lock.json index cc0265a7e..06324ea40 100644 --- a/package-lock.json +++ b/package-lock.json @@ -864,7 +864,7 @@ }, "arr-union": { "version": "3.1.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/arr-union/-/arr-union-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, @@ -876,7 +876,7 @@ }, "assign-symbols": { "version": "1.0.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/assign-symbols/-/assign-symbols-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, @@ -912,7 +912,7 @@ }, "async-each": { "version": "1.0.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/async-each/-/async-each-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", "dev": true, "optional": true @@ -942,7 +942,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -970,7 +970,7 @@ }, "supports-color": { "version": "2.0.0", - "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } @@ -1090,14 +1090,14 @@ "dev": true }, "browserslist": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.3.6.tgz", - "integrity": "sha512-kMGKs4BTzRWviZ8yru18xBpx+CyHG9eqgRbj9XbE3IMgtczf4aiA0Y1YCpVdvUieKGZ03kolSPXqTcscBCb9qw==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.3.7.tgz", + "integrity": "sha512-pWQv51Ynb0MNk9JGMCZ8VkM785/4MQNXiFYtPqI7EEP0TJO+/d/NqRVn1uiAN0DNbnlUSpL2sh16Kspasv3pUQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000921", - "electron-to-chromium": "^1.3.92", - "node-releases": "^1.1.1" + "caniuse-lite": "^1.0.30000925", + "electron-to-chromium": "^1.3.96", + "node-releases": "^1.1.3" } }, "buffer-from": { @@ -1151,15 +1151,15 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30000923", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000923.tgz", - "integrity": "sha512-j5ur7eeluOFjjPUkydtXP4KFAsmH3XaQNch5tvWSO+dLHYt5PE+VgJZLWtbVOodfWij6m6zas28T4gB/cLYq1w==", + "version": "1.0.30000927", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000927.tgz", + "integrity": "sha512-ogq4NbUWf1uG/j66k0AmiO3GjqJAlQyF8n4w8a954cbCyFKmYGvRtgz6qkq2fWuduTXHibX7GyYL5Pg58Aks2g==", "dev": true }, "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -1295,7 +1295,7 @@ }, "collection-visit": { "version": "1.0.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/collection-visit/-/collection-visit-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { @@ -1361,7 +1361,7 @@ }, "component-emitter": { "version": "1.2.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/component-emitter/-/component-emitter-1.2.1.tgz", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", "dev": true }, @@ -1385,7 +1385,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -1400,7 +1400,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { @@ -1420,7 +1420,7 @@ }, "copy-descriptor": { "version": "0.1.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, @@ -1481,7 +1481,7 @@ }, "decode-uri-component": { "version": "0.2.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, @@ -1573,9 +1573,9 @@ } }, "electron-to-chromium": { - "version": "1.3.96", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.96.tgz", - "integrity": "sha512-ZUXBUyGLeoJxp4Nt6G/GjBRLnyz8IKQGexZ2ndWaoegThgMGFO1tdDYID5gBV32/1S83osjJHyfzvanE/8HY4Q==", + "version": "1.3.100", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.100.tgz", + "integrity": "sha512-cEUzis2g/RatrVf8x26L8lK5VEls1AGnLHk6msluBUg/NTB4wcXzExTsGscFq+Vs4WBBU2zbLLySvD4C0C3hwg==", "dev": true }, "enabled": { @@ -1616,7 +1616,7 @@ }, "eslint": { "version": "4.19.1", - "resolved": "http://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", "dev": true, "requires": { @@ -1835,7 +1835,7 @@ }, "extend-shallow": { "version": "3.0.2", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/extend-shallow/-/extend-shallow-3.0.2.tgz", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { @@ -1856,7 +1856,7 @@ }, "external-editor": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", "dev": true, "requires": { @@ -1955,7 +1955,7 @@ }, "fecha": { "version": "2.3.3", - "resolved": "http://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" }, "figures": { @@ -2029,13 +2029,13 @@ }, "for-in": { "version": "1.0.2", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/for-in/-/for-in-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, "fragment-cache": { "version": "0.2.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/fragment-cache/-/fragment-cache-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { @@ -2603,7 +2603,7 @@ }, "get-value": { "version": "2.0.6", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/get-value/-/get-value-2.0.6.tgz", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, @@ -2679,7 +2679,7 @@ }, "has-value": { "version": "1.0.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/has-value/-/has-value-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { @@ -2690,7 +2690,7 @@ }, "has-values": { "version": "1.0.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/has-values/-/has-values-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { @@ -2700,7 +2700,7 @@ "dependencies": { "kind-of": { "version": "4.0.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/kind-of/-/kind-of-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { @@ -2806,7 +2806,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -2831,7 +2831,7 @@ }, "is-binary-path": { "version": "1.0.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/is-binary-path/-/is-binary-path-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "optional": true, @@ -2856,7 +2856,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -2895,7 +2895,7 @@ }, "is-extendable": { "version": "0.1.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/is-extendable/-/is-extendable-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, @@ -3036,9 +3036,9 @@ "dev": true }, "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3074,7 +3074,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -3160,9 +3160,9 @@ "optional": true }, "logform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.0.0.tgz", - "integrity": "sha512-Yk0RJmD9ps/EPR9dLKC88CHzMyLn/H0XS4hLmqOFRRyrHpfH49RaMAuyldJWGWMizpVJBRXBmZk9j/lQ8ZilUg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.0.tgz", + "integrity": "sha512-srZ6qfWCHLX0HVBuWiBC9CPWh61PFrj/akMSQTEqVOgik8fbpg849VU/kepesr6kBZ42Jsk8Duuabim6hAh27w==", "requires": { "colors": "^1.2.1", "fast-safe-stringify": "^2.0.4", @@ -3192,13 +3192,13 @@ }, "map-cache": { "version": "0.2.2", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/map-cache/-/map-cache-0.2.2.tgz", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, "map-visit": { "version": "1.0.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/map-visit/-/map-visit-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { @@ -3252,7 +3252,7 @@ }, "minimist": { "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, @@ -3279,7 +3279,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { @@ -3307,7 +3307,7 @@ "dependencies": { "commander": { "version": "2.15.1", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, @@ -3395,9 +3395,9 @@ "dev": true }, "node-releases": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.2.tgz", - "integrity": "sha512-j1gEV/zX821yxdWp/1vBMN0pSUjuH9oGUdLCb4PfUko6ZW7KdRs3Z+QGGwDUhYtSpQvdVVyLd2V0YvLsmdg5jQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.3.tgz", + "integrity": "sha512-6VrvH7z6jqqNFY200kdB6HdzkgM96Oaj9v3dqGfgp6mF+cHmU4wyQKZ2/WPDRVoR0Jz9KqbamaBN0ZhdUaysUQ==", "dev": true, "requires": { "semver": "^5.3.0" @@ -3417,7 +3417,7 @@ }, "normalize-path": { "version": "2.1.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/normalize-path/-/normalize-path-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { @@ -4586,7 +4586,7 @@ }, "object-copy": { "version": "0.1.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/object-copy/-/object-copy-0.1.0.tgz", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { @@ -4597,7 +4597,7 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/define-property/-/define-property-0.2.5.tgz", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -4623,7 +4623,7 @@ }, "object-visit": { "version": "1.0.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/object-visit/-/object-visit-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { @@ -4632,7 +4632,7 @@ }, "object.pick": { "version": "1.3.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/object.pick/-/object.pick-1.3.0.tgz", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { @@ -4745,7 +4745,7 @@ }, "pascalcase": { "version": "0.1.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/pascalcase/-/pascalcase-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, @@ -4809,7 +4809,7 @@ }, "posix-character-classes": { "version": "0.1.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, @@ -4909,7 +4909,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, @@ -4925,7 +4925,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, @@ -5006,7 +5006,7 @@ "dependencies": { "jsesc": { "version": "0.5.0", - "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true } @@ -5014,7 +5014,7 @@ }, "remove-trailing-separator": { "version": "1.1.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "dev": true }, @@ -5026,7 +5026,7 @@ }, "repeat-string": { "version": "1.6.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/repeat-string/-/repeat-string-1.6.1.tgz", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, @@ -5069,7 +5069,7 @@ }, "resolve-url": { "version": "0.2.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/resolve-url/-/resolve-url-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, @@ -5129,7 +5129,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -5349,7 +5349,7 @@ }, "source-map-url": { "version": "0.4.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/source-map-url/-/source-map-url-0.4.0.tgz", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, @@ -5416,7 +5416,7 @@ }, "static-extend": { "version": "0.1.2", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/static-extend/-/static-extend-0.1.2.tgz", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { @@ -5426,7 +5426,7 @@ "dependencies": { "define-property": { "version": "0.2.5", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/define-property/-/define-property-0.2.5.tgz", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -5564,7 +5564,7 @@ }, "to-object-path": { "version": "0.3.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/to-object-path/-/to-object-path-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { @@ -5596,7 +5596,7 @@ }, "to-regex-range": { "version": "2.1.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/to-regex-range/-/to-regex-range-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { @@ -5666,7 +5666,7 @@ }, "union-value": { "version": "1.0.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/union-value/-/union-value-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, "requires": { @@ -5678,7 +5678,7 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/extend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -5687,7 +5687,7 @@ }, "set-value": { "version": "0.4.3", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/set-value/-/set-value-0.4.3.tgz", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, "requires": { @@ -5701,7 +5701,7 @@ }, "unset-value": { "version": "1.0.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/unset-value/-/unset-value-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { @@ -5711,7 +5711,7 @@ "dependencies": { "has-value": { "version": "0.3.1", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/has-value/-/has-value-0.3.1.tgz", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { @@ -5722,7 +5722,7 @@ "dependencies": { "isobject": { "version": "2.1.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/isobject/-/isobject-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "requires": { @@ -5733,7 +5733,7 @@ }, "has-values": { "version": "0.1.4", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/has-values/-/has-values-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true } @@ -5748,7 +5748,7 @@ }, "urix": { "version": "0.1.0", - "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-aem-desktop-release/urix/-/urix-0.1.0.tgz", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, @@ -5878,7 +5878,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "~1.0.0", @@ -5892,7 +5892,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" @@ -5908,7 +5908,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { diff --git a/package.json b/package.json index 6bc904663..3fe435e85 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "async": "^2.6.1", "diagnostics": "^1.1.1", "is-stream": "^1.1.0", - "logform": "^2.0.0", + "logform": "^2.1.0", "one-time": "0.0.4", "readable-stream": "^3.1.1", "stack-trace": "0.0.x", diff --git a/test/formats/errors.test.js b/test/formats/errors.test.js new file mode 100644 index 000000000..0364a469a --- /dev/null +++ b/test/formats/errors.test.js @@ -0,0 +1,267 @@ +/* + * errors.test.js: E2E Integration tests of `new Error()` handling + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +'use strict'; + +const assume = require('assume'); +const { LEVEL, MESSAGE, SPLAT } = require('triple-beam'); +const winston = require('../../lib/winston'); +const { format } = winston; +const helpers = require('../helpers'); + +function assumeExpectedInfo(info, target = {}) { + const expected = Object.assign({}, { + level: 'info', + message: 'Errors lack .toJSON() lulz' + }, target); + + assume(info).is.an('object'); + assume(info).includes('level'); + assume(info).includes('message'); + + assume(info.level).equals(expected.level); + assume(info[LEVEL]).equals(expected.level); + assume(info.message).equals(expected.message); + assume(info[MESSAGE]).equals(expected.message); + + Object.keys(expected).forEach(key => { + if (key === 'level' || key === 'message') return; + assume(info[key]).equals(expected[key]); + }); +} + +describe('format.errors (integration)', function () { + it('logger.log(level, error)', (done) => { + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info); + done(); + }, format.errors()); + + logger.log('info', new Error('Errors lack .toJSON() lulz')); + }); + + it('logger.log(level, error) [custom error properties]', (done) => { + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, { + something: true, + wut: 'another string' + }); + + done(); + }, format.errors()); + + const err = new Error('Errors lack .toJSON() lulz'); + err.something = true; + err.wut = 'another string'; + + logger.log('info', err); + }); + + it('logger.log(level, error, meta)', (done) => { + const meta = { + thisIsMeta: true, + anyValue: 'a string' + }; + + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, meta); + done(); + }, format.errors()); + + logger.log('info', new Error('Errors lack .toJSON() lulz'), meta); + }); + + it('logger.log(level, error, meta) [custom error properties]', (done) => { + const meta = { + thisIsMeta: true, + anyValue: 'a string' + }; + + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, Object.assign({ + something: true, + wut: 'another string' + }, meta)); + + done(); + }, format.errors()); + + const err = new Error('Errors lack .toJSON() lulz'); + err.something = true; + err.wut = 'another string'; + + logger.log('info', err, meta); + }); + + it('logger.log(level, msg, meta)', (done) => { + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, { + message: 'Caught error: Errors lack .toJSON() lulz' + }); + + done(); + }, format.combine( + format.errors(), + format.printf(info => info.message) + )); + + logger.log('info', 'Caught error: ', new Error('Errors lack .toJSON() lulz')); + }); + + it('logger.log(level, msg, meta) [custom error properties]', (done) => { + const err = new Error('Errors lack .toJSON() lulz'); + err.something = true; + err.wut = 'another string'; + + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, { + message: 'Caught error: Errors lack .toJSON() lulz', + stack: err.stack, + something: true, + wut: 'another string' + }); + + done(); + }, format.combine( + format.errors(), + format.printf(info => info.message) + )); + + logger.log('info', 'Caught error: ', err); + }); + + it('logger.(error)', (done) => { + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info); + done(); + }, format.errors()); + + logger.info(new Error('Errors lack .toJSON() lulz')); + }); + + it('logger.(error) [custom error properties]', (done) => { + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, { + something: true, + wut: 'another string' + }); + + done(); + }, format.errors()); + + const err = new Error('Errors lack .toJSON() lulz'); + err.something = true; + err.wut = 'another string'; + + logger.info(err); + }); + + it('logger.(error, meta)', (done) => { + const meta = { + thisIsMeta: true, + anyValue: 'a string' + }; + + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, meta); + done(); + }, format.errors()); + + logger.info(new Error('Errors lack .toJSON() lulz'), meta); + }); + + it('logger.(error, meta) [custom error properties]', (done) => { + const meta = { + thisIsMeta: true, + anyValue: 'a string' + }; + + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, Object.assign({ + something: true, + wut: 'another string' + }, meta)); + + done(); + }, format.errors()); + + const err = new Error('Errors lack .toJSON() lulz'); + err.something = true; + err.wut = 'another string'; + + logger.info(err, meta); + }); + + it('logger.(msg, meta)', (done) => { + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, { + message: 'Caught error: Errors lack .toJSON() lulz' + }); + + done(); + }, format.combine( + format.errors(), + format.printf(info => info.message) + )); + + logger.info('Caught error: ', new Error('Errors lack .toJSON() lulz')); + }); + + it('logger.(msg, meta) [custom error properties]', (done) => { + const err = new Error('Errors lack .toJSON() lulz'); + err.something = true; + err.wut = 'another string'; + + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, { + message: 'Caught error: Errors lack .toJSON() lulz', + stack: err.stack, + something: true, + wut: 'another string' + }); + + done(); + }, format.combine( + format.errors(), + format.printf(info => info.message) + )); + + logger.info('Caught error: ', err); + }); + + it(`Promise.reject().catch(logger.)`, (done) => { + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, { level: 'error' }); + done(); + }, format.errors()); + + new Promise((done, reject) => { + throw new Error('Errors lack .toJSON() lulz') + }).catch(logger.error.bind(logger)); + }); + + it(`Promise.reject().catch(logger.) [custom error properties]`, (done) => { + const logger = helpers.createLogger(function (info) { + assumeExpectedInfo(info, { + level: 'error', + something: true, + wut: 'a string' + }); + + done(); + }, format.errors()); + + new Promise((done, reject) => { + const err = new Error('Errors lack .toJSON() lulz'); + err.something = true; + err.wut = 'a string'; + + throw err; + }).catch(logger.error.bind(logger)); + }); +}); diff --git a/test/helpers/mocks/mock-transport.js b/test/helpers/mocks/mock-transport.js index 47a61f210..5522143a9 100644 --- a/test/helpers/mocks/mock-transport.js +++ b/test/helpers/mocks/mock-transport.js @@ -9,14 +9,14 @@ const winston = require('../../../lib/winston'); * @returns {StreamTransportInstance} A transport instance */ function createMockTransport(write) { - const writeable = new stream.Writable({ - objectMode: true, - write: write - }); + const writeable = new stream.Writable({ + objectMode: true, + write: write + }); - return new winston.transports.Stream({stream: writeable}) + return new winston.transports.Stream({ stream: writeable }) } module.exports = { - createMockTransport + createMockTransport }; diff --git a/test/logger.test.js b/test/logger.test.js index 01d36beee..59995e61f 100755 --- a/test/logger.test.js +++ b/test/logger.test.js @@ -920,100 +920,122 @@ describe('Should bubble transport events', () => { }); }); -describe('Should support child loggers', () => { - it('sets default meta for text messages correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.req_id).equals('451'); - done(); - }); - - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] - }); - - const childLogger = logger.child({ req_id: '451' }); - childLogger.info('dummy message'); - }); - - it('sets default meta for json messages correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message.text).equals('dummy'); - assume(msg.req_id).equals('451'); - done(); - }); - - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] - }); - - const childLogger = logger.child({ req_id: '451' }); - childLogger.info({text: 'dummy'}); - }); - - it('merges default and non-default meta correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.service).equals('user-service'); - assume(msg.req_id).equals('451'); - done(); - }); - - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] - }); - - const childLogger = logger.child({ service: 'user-service' }); - childLogger.info('dummy message', {req_id: '451'}); - }); - - it('non-default take precedence over default meta', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.service).equals('audit-service'); - assume(msg.req_id).equals('451'); - done(); - }); - - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] - }); - - const childLogger = logger.child({ service: 'user-service' }); - childLogger.info('dummy message', { - req_id: '451', - service: 'audit-service' - }); - }); - - it('handles error stacktraces in child loggers correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('error'); - assume(msg.message).equals('dummy error'); - assume(msg.stack).includes('logger.test.js'); - assume(msg.service).equals('user-service'); - done(); - }); - - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] - }); - - const childLogger = logger.child({ service: 'user-service' }); - childLogger.error(Error('dummy error')); +describe('Should support child loggers & defaultMeta', () => { + it('sets child meta for text messages correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.requestId).equals('451'); + done(); + }); + + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); + + const childLogger = logger.child({ requestId: '451' }); + childLogger.info('dummy message'); + }); + + it('sets child meta for json messages correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message.text).equals('dummy'); + assume(msg.requestId).equals('451'); + done(); + }); + + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); + + const childLogger = logger.child({ requestId: '451' }); + childLogger.info({ text: 'dummy' }); + }); + + it('merges child and provided meta correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.service).equals('user-service'); + assume(msg.requestId).equals('451'); + done(); + }); + + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); + + const childLogger = logger.child({ service: 'user-service' }); + childLogger.info('dummy message', { requestId: '451' }); + }); + + it('provided meta take precedence over defaultMeta', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.service).equals('audit-service'); + assume(msg.requestId).equals('451'); + done(); + }); + + const logger = winston.createLogger({ + defaultMeta: { service: 'user-service' }, + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); + + logger.info('dummy message', { + requestId: '451', + service: 'audit-service' + }); + }); + + it('provided meta take precedence over child meta', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.service).equals('audit-service'); + assume(msg.requestId).equals('451'); + done(); + }); + + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); + + const childLogger = logger.child({ service: 'user-service' }); + childLogger.info('dummy message', { + requestId: '451', + service: 'audit-service' + }); + }); + + it('handles error stack traces in child loggers correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('error'); + assume(msg.message).equals('dummy error'); + assume(msg.stack).includes('logger.test.js'); + assume(msg.service).equals('user-service'); + done(); + }); + + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] }); + + const childLogger = logger.child({ service: 'user-service' }); + childLogger.error(Error('dummy error')); + }); });