From 44e178f2fd8dc8425a4432694bb0150fd7db10c9 Mon Sep 17 00:00:00 2001 From: Charlie Robbins Date: Wed, 26 Dec 2018 15:18:41 -0500 Subject: [PATCH] Consistent handling of meta with (and without) interpolation in winston & logform (#1552) * [doc fix] Build on the work from #1485 fixes. * [tiny] Formatting changes. * [fix test] Updated tests to latest (consistent) semantics. * [dist] Update to `logform@2.0.0` and `winston-transport@4.3.0`. * [doc] Document all possible permuations for splat. --- examples/splat.js | 86 ++++++++++++++ lib/winston/logger.js | 47 ++++++-- package-lock.json | 261 +++++++++++++++++++++--------------------- package.json | 4 +- test/helpers/index.js | 2 +- test/logger.test.js | 36 +++++- 6 files changed, 286 insertions(+), 150 deletions(-) create mode 100644 examples/splat.js diff --git a/examples/splat.js b/examples/splat.js new file mode 100644 index 000000000..eda2bca49 --- /dev/null +++ b/examples/splat.js @@ -0,0 +1,86 @@ +const winston = require('../'); +let { format } = winston; + +/* + * Simple helper for stringifying all remaining + * properties. + */ +function rest(info) { + return JSON.stringify(Object.assign({}, info, { + level: undefined, + message: undefined, + splat: undefined, + label: undefined + })); +} + +let logger = winston.createLogger({ + transports: [new winston.transports.Console({ level: 'info' })], + format: format.combine( + format.splat(), + format.printf(info => `[${info.label}] ${info.message} ${rest(info)}`) + ) +}); + +logger.log( + 'info', + 'any message', + { + label: 'label!', + extra: true + } +); + +logger.log( + 'info', + 'let\'s %s some %s', + 'interpolate', + 'splat parameters', + { + label: 'label!', + extra: true + } +); + +logger.log( + 'info', + 'first is a string %s [[%j]]', + 'behold a string', + { beAware: 'this will interpolate' }, + { + label: 'label!', + extra: true + } +); + +logger.log( + 'info', + 'first is an object [[%j]]', + { beAware: 'this will interpolate' }, + { + label: 'label!', + extra: true + } +); + +// +// Non-enumerable properties (such as "message" and "stack" in Error +// instances) will not be merged into any `info`. +// +const terr = new Error('lol please stop doing this'); +terr.label = 'error'; +terr.extra = true; +logger.log( + 'info', + 'any message', + terr +); + +logger.log( + 'info', + 'let\'s %s some %s', + 'interpolate', + 'splat parameters', + terr +); + diff --git a/lib/winston/logger.js b/lib/winston/logger.js index a062b70ca..f99b39272 100644 --- a/lib/winston/logger.js +++ b/lib/winston/logger.js @@ -17,6 +17,14 @@ const Profiler = require('./profiler'); const { warn } = require('./common'); const config = require('./config'); +/** + * Captures the number of format (i.e. %s strings) in a given string. + * Based on `util.format`, see Node.js source: + * https://github.com/nodejs/node/blob/b1c8f15c5f169e021f7c46eb7b219de95fe97603/lib/util.js#L201-L230 + * @type {RegExp} + */ +const formatRegExp = /%[scdjifoO%]/g; + /** * TODO: add class description. * @type {Logger} @@ -41,9 +49,9 @@ class Logger extends Transform { write: { value: function (info) { const infoClone = Object.assign( - {}, - defaultRequestMetadata, - info + {}, + defaultRequestMetadata, + info ); // Object.assign doesn't copy inherited Error properties so we have to do that explicitly @@ -157,11 +165,15 @@ class Logger extends Transform { * // Supports the existing API: * logger.log('info', 'Hello world', { custom: true }); * logger.log('info', new Error('Yo, it\'s on fire')); + * + * // Requires winston.format.splat() * logger.log('info', '%s %d%%', 'A string', 50, { thisIsMeta: true }); * * // And the new API with a single JSON literal: * logger.log({ level: 'info', message: 'Hello world', custom: true }); * logger.log({ level: 'info', message: new Error('Yo, it\'s on fire') }); + * + * // Also requires winston.format.splat() * logger.log({ * level: 'info', * message: '%s %d%%', @@ -198,21 +210,32 @@ class Logger extends Transform { const [meta] = splat; if (typeof meta === 'object' && meta !== null) { - this.write(Object.assign({}, meta, { - [LEVEL]: level, - [SPLAT]: splat.slice(0), - level, - message: msg - }, - this.defaultMeta)); + // Extract tokens, if none available default to empty array to + // ensure consistancy in expected results + 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({}, { + [LEVEL]: level, + [SPLAT]: splat, + level, + message: msg + }, this.defaultMeta)); + } } else { this.write(Object.assign({}, { [LEVEL]: level, [SPLAT]: splat, level, message: msg - }, - this.defaultMeta)); + }, this.defaultMeta)); } return this; diff --git a/package-lock.json b/package-lock.json index d63d4961f..2a2bf97f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@babel/cli": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.2.0.tgz", - "integrity": "sha512-FLteTkEoony0DX8NbnT51CmwmLBzINdlXmiJCSqCLmqWCDA/xk8EITPWqwDnVLbuK0bsZONt/grqHnQzQ15j0Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.2.3.tgz", + "integrity": "sha512-bfna97nmJV6nDJhXNPeEfxyMjWnt6+IjUAaDPiYRTBlm8L41n8nvw6UAqUCbvpFfU246gHPxW7sfWwqtF4FcYA==", "dev": true, "requires": { "chokidar": "^2.0.3", @@ -32,18 +32,18 @@ } }, "@babel/core": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.2.0.tgz", - "integrity": "sha512-7pvAdC4B+iKjFFp9Ztj0QgBndJ++qaMeonT185wAqUnhipw8idm9Rv1UMyBuKtYjfl6ORNkgEgcsYLfHX/GpLw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.2.2.tgz", + "integrity": "sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.2.0", + "@babel/generator": "^7.2.2", "@babel/helpers": "^7.2.0", - "@babel/parser": "^7.2.0", - "@babel/template": "^7.1.2", - "@babel/traverse": "^7.1.6", - "@babel/types": "^7.2.0", + "@babel/parser": "^7.2.2", + "@babel/template": "^7.2.2", + "@babel/traverse": "^7.2.2", + "@babel/types": "^7.2.2", "convert-source-map": "^1.1.0", "debug": "^4.1.0", "json5": "^2.1.0", @@ -54,9 +54,9 @@ }, "dependencies": { "debug": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", - "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" @@ -65,12 +65,12 @@ } }, "@babel/generator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.0.tgz", - "integrity": "sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.2.tgz", + "integrity": "sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg==", "dev": true, "requires": { - "@babel/types": "^7.2.0", + "@babel/types": "^7.2.2", "jsesc": "^2.5.1", "lodash": "^4.17.10", "source-map": "^0.5.0", @@ -176,16 +176,16 @@ } }, "@babel/helper-module-transforms": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.1.0.tgz", - "integrity": "sha512-0JZRd2yhawo79Rcm4w0LwSMILFmFXjugG3yqf+P/UsKsRS1mJCmMwwlHDlMg7Avr9LrvSpp4ZSULO9r8jpCzcw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz", + "integrity": "sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-simple-access": "^7.1.0", "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/template": "^7.2.2", + "@babel/types": "^7.2.2", "lodash": "^4.17.10" } }, @@ -227,14 +227,14 @@ } }, "@babel/helper-replace-supers": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz", - "integrity": "sha512-BvcDWYZRWVuDeXTYZWxekQNO5D4kO55aArwZOTFXw6rlLQA8ZaDicJR1sO47h+HrnCiDFiww0fSPV0d713KBGQ==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz", + "integrity": "sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA==", "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.0.0", "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.1.0", + "@babel/traverse": "^7.2.3", "@babel/types": "^7.0.0" } }, @@ -292,9 +292,9 @@ } }, "@babel/parser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.0.tgz", - "integrity": "sha512-M74+GvK4hn1eejD9lZ7967qAwvqTZayQa3g10ag4s9uewgR7TKjeaT0YMyoq+gVfKYABiWZ4MQD701/t5e1Jhg==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.3.tgz", + "integrity": "sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -425,9 +425,9 @@ } }, "@babel/plugin-transform-classes": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.0.tgz", - "integrity": "sha512-aPCEkrhJYebDXcGTAP+cdUENkH7zqOlgbKwLbghjjHpJRJBWM/FSlCjMoPGA8oUdiMfOrk3+8EFPLLb5r7zj2w==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.2.tgz", + "integrity": "sha512-gEZvgTy1VtcDOaQty1l10T3jQmJKlNVxLDCs+3rCVPr6nMkODLELxViq5X9l+rfxbie3XrfrMCYYY6eX3aOcOQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", @@ -606,9 +606,9 @@ } }, "@babel/plugin-transform-spread": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.0.tgz", - "integrity": "sha512-7TtPIdwjS/i5ZBlNiQePQCovDh9pAhVbp/nGVRBZuUdBiVRThyyLend3OHobc0G+RLCPPAN70+z/MAMhsgJd/A==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", + "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -655,9 +655,9 @@ } }, "@babel/preset-env": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.2.0.tgz", - "integrity": "sha512-haGR38j5vOGVeBatrQPr3l0xHbs14505DcM57cbJy48kgMFvvHHoYEhHuRV+7vi559yyAUAVbTWzbK/B/pzJng==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.2.3.tgz", + "integrity": "sha512-AuHzW7a9rbv5WXmvGaPX7wADxFkZIqKlbBh1dmZUQp4iwiPpkE/Qnrji6SC4UQCQzvWY/cpHET29eUhXS9cLPw==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -704,37 +704,37 @@ } }, "@babel/template": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz", - "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.1.2", - "@babel/types": "^7.1.2" + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" } }, "@babel/traverse": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.1.6.tgz", - "integrity": "sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.1.6", + "@babel/generator": "^7.2.2", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/parser": "^7.1.6", - "@babel/types": "^7.1.6", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.10" }, "dependencies": { "debug": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", - "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" @@ -743,9 +743,9 @@ } }, "@babel/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.2.0.tgz", - "integrity": "sha512-b4v7dyfApuKDvmPb+O488UlGuR1WbwMXFsO/cyqMrnfvRAChZKJAYeeglWTjUO1b9UghKKgepAQM5tsvBJca6A==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.2.2.tgz", + "integrity": "sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -754,9 +754,9 @@ } }, "@types/node": { - "version": "10.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.12.tgz", - "integrity": "sha512-Pr+6JRiKkfsFvmU/LK68oBRCQeEg36TyAbPhc2xpez24OOZZCuoIhWGTd39VZy6nGafSbxzGouFPTFD/rR1A0A==", + "version": "10.12.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", + "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", "dev": true }, "abstract-winston-transport": { @@ -970,7 +970,7 @@ }, "supports-color": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "resolved": "http://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.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.3.5.tgz", - "integrity": "sha512-z9ZhGc3d9e/sJ9dIx5NFXkKoaiQTnrvrMsN3R1fGb1tkWWNSz12UewJn9TNxGo1l7J23h0MRaPmk7jfeTZYs1w==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.3.6.tgz", + "integrity": "sha512-kMGKs4BTzRWviZ8yru18xBpx+CyHG9eqgRbj9XbE3IMgtczf4aiA0Y1YCpVdvUieKGZ03kolSPXqTcscBCb9qw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000912", - "electron-to-chromium": "^1.3.86", - "node-releases": "^1.0.5" + "caniuse-lite": "^1.0.30000921", + "electron-to-chromium": "^1.3.92", + "node-releases": "^1.1.1" } }, "buffer-from": { @@ -1151,9 +1151,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30000916", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000916.tgz", - "integrity": "sha512-D6J9jloPm2MPkg0PXcODLMQAJKkeixKO9xhqTUMvtd44MtTYMyyDXPQ2Lk9IgBq5FH0frwiPa/N/w8ncQf7kIQ==", + "version": "1.0.30000923", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000923.tgz", + "integrity": "sha512-j5ur7eeluOFjjPUkydtXP4KFAsmH3XaQNch5tvWSO+dLHYt5PE+VgJZLWtbVOodfWij6m6zas28T4gB/cLYq1w==", "dev": true }, "chalk": { @@ -1261,7 +1261,7 @@ }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { @@ -1340,9 +1340,9 @@ "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=" }, "colors": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz", - "integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ==" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==" }, "colorspace": { "version": "1.1.1", @@ -1373,7 +1373,7 @@ }, "concat-stream": { "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "resolved": "http://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { @@ -1573,9 +1573,9 @@ } }, "electron-to-chromium": { - "version": "1.3.88", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.88.tgz", - "integrity": "sha512-UPV4NuQMKeUh1S0OWRvwg0PI8ASHN9kBC8yDTk1ROXLC85W5GnhTRu/MZu3Teqx3JjlQYuckuHYXSUSgtb3J+A==", + "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==", "dev": true }, "enabled": { @@ -2095,14 +2095,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2117,20 +2115,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -2247,8 +2242,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -2260,7 +2254,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2275,7 +2268,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2283,14 +2275,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -2309,7 +2299,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -2390,8 +2379,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -2403,7 +2391,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -2525,7 +2512,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2820,7 +2806,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -2870,7 +2856,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -3174,9 +3160,9 @@ "optional": true }, "logform": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-1.10.0.tgz", - "integrity": "sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.0.0.tgz", + "integrity": "sha512-Yk0RJmD9ps/EPR9dLKC88CHzMyLn/H0XS4hLmqOFRRyrHpfH49RaMAuyldJWGWMizpVJBRXBmZk9j/lQ8ZilUg==", "requires": { "colors": "^1.2.1", "fast-safe-stringify": "^2.0.4", @@ -3377,9 +3363,9 @@ "dev": true }, "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", + "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", "dev": true, "optional": true }, @@ -3409,9 +3395,9 @@ "dev": true }, "node-releases": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.0.tgz", - "integrity": "sha512-+qV91QMDBvARuPxUEfI/mRF/BY+UAkTIn3pvmvM2iOLIRvv6RNYklFXBgrkky6P1wXUqQW1P3qKlWxxy4JZbfg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.2.tgz", + "integrity": "sha512-j1gEV/zX821yxdWp/1vBMN0pSUjuH9oGUdLCb4PfUko6ZW7KdRs3Z+QGGwDUhYtSpQvdVVyLd2V0YvLsmdg5jQ==", "dev": true, "requires": { "semver": "^5.3.0" @@ -4900,9 +4886,9 @@ } }, "readable-stream": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.0.6.tgz", - "integrity": "sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", + "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -5067,12 +5053,12 @@ } }, "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz", + "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", "dev": true, "requires": { - "path-parse": "^1.0.5" + "path-parse": "^1.0.6" } }, "resolve-from": { @@ -5394,9 +5380,9 @@ } }, "spdx-license-ids": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz", - "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", "dev": true }, "split-string": { @@ -5409,9 +5395,9 @@ } }, "split2": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.0.0.tgz", - "integrity": "sha512-Cp7G+nUfKJyHCrAI8kze3Q00PFGEG1pMgrAlTFlDbn+GW24evSZHJuMl+iUJx1w/NTRDeBiTgvwnf6YOt94FMw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.1.0.tgz", + "integrity": "sha512-ePE1otNQVMnBRyqf3INbZvZwBPGsdBDThgrOWZ6z8zXGNVQNVCSEoOO9aBMTzDN1mXoNSZJ2kHSFH7AA5SPWww==", "dev": true, "requires": { "readable-stream": "^3.0.0" @@ -5419,7 +5405,7 @@ }, "sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, @@ -5817,9 +5803,9 @@ } }, "vscode-languageserver-types": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.13.0.tgz", - "integrity": "sha512-BnJIxS+5+8UWiNKCP7W3g9FlE7fErFw0ofP5BXJe7c2tl0VeWh+nNHFbwAS2vmVC4a5kYxHBjRy0UeOtziemVA==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", + "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", "dev": true }, "vscode-nls": { @@ -5864,12 +5850,27 @@ "cycle": "~1.0.3", "logform": "^1.6.0", "triple-beam": "^1.2.0" + }, + "dependencies": { + "logform": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-1.10.0.tgz", + "integrity": "sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg==", + "dev": true, + "requires": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^2.3.3", + "ms": "^2.1.1", + "triple-beam": "^1.2.0" + } + } } }, "winston-transport": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.2.0.tgz", - "integrity": "sha512-0R1bvFqxSlK/ZKTH86nymOuKv/cT1PQBMuDdA7k7f0S9fM44dNH6bXnuxwXPrN8lefJgtZq08BKdyZ0DZIy/rg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz", + "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==", "requires": { "readable-stream": "^2.3.6", "triple-beam": "^1.2.0" @@ -5926,7 +5927,7 @@ }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { diff --git a/package.json b/package.json index 2754ab157..dfd1c879c 100644 --- a/package.json +++ b/package.json @@ -29,12 +29,12 @@ "async": "^2.6.1", "diagnostics": "^1.1.1", "is-stream": "^1.1.0", - "logform": "^1.10.0", + "logform": "^2.0.0", "one-time": "0.0.4", "readable-stream": "^3.0.6", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.2.0" + "winston-transport": "^4.3.0" }, "devDependencies": { "@babel/cli": "^7.1.5", diff --git a/test/helpers/index.js b/test/helpers/index.js index 07cc862e7..c86cf8528 100644 --- a/test/helpers/index.js +++ b/test/helpers/index.js @@ -29,7 +29,7 @@ helpers.createLogger = function (write, format) { return winston.createLogger({ format, transports: [ - mockTransport.createMockTransport(write) + mockTransport.createMockTransport(write) ] }); }; diff --git a/test/logger.test.js b/test/logger.test.js index 6496f93b4..01d36beee 100755 --- a/test/logger.test.js +++ b/test/logger.test.js @@ -709,7 +709,7 @@ describe('Logger (winston@2 logging API)', function () { it('.log(level, formatStr, ...splat, meta)', function (done) { const format = winston.format.combine( winston.format.splat(), - winston.format.printf(info => `${info.level}: ${info.message} ${JSON.stringify(info.meta)}`) + winston.format.printf(info => `${info.level}: ${info.message} ${JSON.stringify({ thisIsMeta: info.thisIsMeta })}`) ); var logger = helpers.createLogger(function (info) { @@ -717,7 +717,7 @@ describe('Logger (winston@2 logging API)', function () { assume(info.level).equals('info'); assume(info.message).equals('100% such wow {"much":"javascript"}'); assume(info[SPLAT]).deep.equals([100, 'wow', { much: 'javascript' }]); - assume(info.meta).deep.equals({ thisIsMeta: true }); + assume(info.thisIsMeta).true(); assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"} {"thisIsMeta":true}'); done(); }, format); @@ -741,18 +741,44 @@ describe('Logger (logging exotic data types)', function () { logger.log(err); }); - it(`.info('Hello') and .info('Hello %d') both preserve meta without splat format`, function (done) { + it(`.info('Hello') preserve meta without splat format`, function (done) { const logged = []; const logger = helpers.createLogger(function (info, enc, next) { logged.push(info); assume(info.label).equals('world'); next(); - if (logged.length === 2) done(); + if (logged.length === 1) done(); + }); + + logger.info('Hello', { label: 'world' }); + }); + + it(`.info('Hello %d') does not mutate unnecessarily with string interpolation tokens`, function (done) { + const logged = []; + const logger = helpers.createLogger(function (info, enc, next) { + logged.push(info); + assume(info.label).equals(undefined); + next(); + + if (logged.length === 1) done(); }); + logger.info('Hello %j', { label: 'world' }, { extra: true }); + }); + + it(`.info('Hello') and .info('Hello %d') preserve meta with splat format`, function (done) { + const logged = []; + const logger = helpers.createLogger(function (info, enc, next) { + logged.push(info); + assume(info.label).equals('world'); + next(); + + if (logged.length === 2) done(); + }, format.splat()); + logger.info('Hello', { label: 'world' }); - logger.info('Hello %d', { label: 'world' }); + logger.info('Hello %d', 100, { label: 'world' }); }); });