From 7ac81e3733ea716f57d4a4f14edc91a07c5d050a Mon Sep 17 00:00:00 2001 From: Mariusz Nowak Date: Mon, 8 Apr 2019 16:06:03 +0200 Subject: [PATCH] feat: upgrade configuration ot use LogWriter BREAKING CHANGE: Removed format and formatEventMessage utilties --- index.js | 94 +++++++++---------- lib/format-event-message.js | 47 ---------- lib/format.js | 8 -- lib/get-namespace-prefix.js | 18 +--- package.json | 2 +- test/index.js | 4 +- test/lib/format-event-message.js | 69 -------------- test/lib/format.js | 69 -------------- .../get-namespace-prefix/_resolve-uncached.js | 3 +- 9 files changed, 56 insertions(+), 258 deletions(-) delete mode 100644 lib/format-event-message.js delete mode 100644 lib/format.js delete mode 100644 test/lib/format-event-message.js delete mode 100644 test/lib/format.js diff --git a/index.js b/index.js index 18d8814..a2b8c82 100644 --- a/index.js +++ b/index.js @@ -1,58 +1,58 @@ "use strict"; -const isObject = require("es5-ext/object/is-object") - , d = require("d") - , clc = require("cli-color/bare") - , rootLogger = require("log") - , emitter = require("log/lib/emitter") - , registerMaster = require("log/lib/register-master") - , setupVisibility = require("log/lib/setup-visibility") - , setDefaultNamespace = require("log/lib/get-default-namespace").set - , colorsSupportLevel = require("./lib/private/colors-support-level") - , formatMessage = require("./lib/format-event-message") - , levelPrefixes = require("./lib/level-prefixes") - , getNamespacePrefix = require("./lib/get-namespace-prefix"); +const formatParts = require("sprintf-kit/format-parts") + , hasAnsi = require("has-ansi") + , { blackBright, red, yellow } = require("cli-color/bare") + , LogWriter = require("log/lib/writer") + , colorsSupportLevel = require("./lib/private/colors-support-level") + , levelPrefixes = require("./lib/level-prefixes") + , getNamespacePrefix = require("./lib/get-namespace-prefix") + , resolveParts = require("./lib/resolve-format-parts"); const WARNING_LEVEL_INDEX = 1, ERROR_LEVEL_INDEX = 0; -const setupPrefixes = levelLogger => { - levelLogger.levelMessagePrefix = levelPrefixes[levelLogger.level]; - if (colorsSupportLevel) { +class NodeLogWriter extends LogWriter { + constructor(options = {}) { super(process.env, options); } + setupLevelLogger(logger) { + super.setupLevelLogger(logger); + if (colorsSupportLevel) this.setupLevelMessageDecorator(logger); + } + setupLevelMessageDecorator(levelLogger) { if (levelLogger.levelIndex === ERROR_LEVEL_INDEX) { - levelLogger.messageContentDecorator = clc.red; + levelLogger.messageContentDecorator = red; } else if (levelLogger.levelIndex === WARNING_LEVEL_INDEX) { - levelLogger.messageContentDecorator = clc.yellow; + levelLogger.messageContentDecorator = yellow; } } - Object.defineProperty( - levelLogger, "namespaceMessagePrefix", - d.gs(function () { return getNamespacePrefix(this); }) - ); -}; - -module.exports = (options = {}) => { - if (!isObject(options)) options = {}; - - // Ensure it's the only log writer initialzed in a process - registerMaster(); - - if (options.defaultNamespace) setDefaultNamespace(options.defaultNamespace); - - // Read logs visiblity settings from env variables - setupVisibility( - process.env.LOG_LEVEL, (process.env.LOG_DEBUG || process.env.DEBUG || "").split(",") - ); + resolveMessageTimestamp(event) { + super.resolveMessageTimestamp(event); + if (!colorsSupportLevel) return; + if (event.messageTimestamp) event.messageTimestamp = blackBright(event.messageTimestamp); + } + resolveMessageContent(event) { + const { logger } = event; + const parts = resolveParts(...event.messageTokens); + if (logger.messageContentDecorator) { + parts.literals = parts.literals.map(literal => logger.messageContentDecorator(literal)); + for (const substitution of parts.substitutions) { + const { placeholder, value } = substitution; + if ( + placeholder.type === "s" && + placeholder.flags && + placeholder.flags.includes("#") && + !hasAnsi(value) + ) { + // Raw string + substitution.value = logger.messageContentDecorator(value); + } + } + } + event.messageContent = formatParts(parts); + } + writeMessage(event) { process.stderr.write(`${ event.message }\n`); } +} +NodeLogWriter.levelPrefixes = levelPrefixes; - // Resolve level and namespace log message prefixes - // - for already initialized loggers - rootLogger.getAllInitializedLevels().forEach(setupPrefixes); - // - for loggers to be initialized - emitter.on("init", event => { if (!event.logger.namespace) setupPrefixes(event.logger); }); +if (colorsSupportLevel) NodeLogWriter.resolveNamespaceMessagePrefix = getNamespacePrefix; - // Write logs to stderr - emitter.on("log", event => { - if (!event.logger.isEnabled) return; - formatMessage(event); - process.stderr.write(`${ event.message }\n`); - }); -}; +module.exports = (options = {}) => new NodeLogWriter(options); diff --git a/lib/format-event-message.js b/lib/format-event-message.js deleted file mode 100644 index ce14047..0000000 --- a/lib/format-event-message.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; - -const formatParts = require("sprintf-kit/format-parts") - , hasAnsi = require("has-ansi") - , { blackBright } = require("cli-color/bare") - , getTimestampResolver = require("log/lib/get-timestamp-resolver") - , colorsSupportLevel = require("./private/colors-support-level") - , resolveParts = require("./resolve-format-parts"); - -const resolveTimestamp = (() => { - if (!process.env.LOG_TIME) return null; - const resolve = getTimestampResolver(process.env.LOG_TIME); - if (!colorsSupportLevel) return resolve; - return () => blackBright(resolve()); -})(); - -module.exports = event => { - if (event.message) return event.message; - const { logger } = event; - - const parts = resolveParts(...event.messageTokens); - if (logger.messageContentDecorator) { - parts.literals = parts.literals.map(literal => logger.messageContentDecorator(literal)); - for (const substitution of parts.substitutions) { - const { placeholder, value } = substitution; - if ( - placeholder.type === "s" && - placeholder.flags && - placeholder.flags.includes("#") && - !hasAnsi(value) - ) { - // Raw string - substitution.value = logger.messageContentDecorator(value); - } - } - } - if (resolveTimestamp) event.messageTimestamp = resolveTimestamp(); - event.messageContent = formatParts(parts); - - event.message = [ - event.messageTimestamp, logger.levelMessagePrefix, logger.namespaceMessagePrefix, - event.messageContent - ] - .filter(Boolean) - .join(" "); - return event.message; -}; diff --git a/lib/format.js b/lib/format.js deleted file mode 100644 index fef0e18..0000000 --- a/lib/format.js +++ /dev/null @@ -1,8 +0,0 @@ -// format util which reflects color and inspect settings with which logger is run - -"use strict"; - -const formatParts = require("sprintf-kit/format-parts") - , resolveParts = require("./resolve-format-parts"); - -module.exports = (format, ...params) => formatParts(resolveParts(format, ...params)); diff --git a/lib/get-namespace-prefix.js b/lib/get-namespace-prefix.js index 51c6988..1093a73 100644 --- a/lib/get-namespace-prefix.js +++ b/lib/get-namespace-prefix.js @@ -1,20 +1,10 @@ "use strict"; -const getDefaultNamespace = require("log/lib/get-default-namespace") - , colorsSupportLevel = require("./private/colors-support-level"); - -const resolveNamespaceString = logger => { - if (!logger.namespace) return null; - const [rootNamespace] = logger.namespaceTokens; - if (getDefaultNamespace() === rootNamespace) { - if (logger.namespace === rootNamespace) return null; - return logger.namespace.slice(rootNamespace.length); - } - return logger.namespace; -}; +const { resolveNamespaceMessagePrefix } = require("log/lib/writer") + , colorsSupportLevel = require("./private/colors-support-level"); if (!colorsSupportLevel) { - module.exports = resolveNamespaceString; + module.exports = resolveNamespaceMessagePrefix; return; } @@ -43,7 +33,7 @@ const assignColor = namespace => { }; module.exports = logger => { - const namespaceString = resolveNamespaceString(logger); + const namespaceString = resolveNamespaceMessagePrefix(logger); if (!namespaceString) return null; const color = (() => { if (logger.namespaceAnsiColor) return logger.namespaceAnsiColor; diff --git a/package.json b/package.json index cf74214..5c7c715 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "git-list-updated": "^1.1.2", "husky": "^1.3.1", "lint-staged": "^8.1.5", - "log": "^5.0.0", + "log": "^5.1.0", "nyc": "^13.3.0", "prettier-elastic": "^1.16.4", "process-utils": "^2.0.1", diff --git a/test/index.js b/test/index.js index 87c19f0..8b4c98d 100644 --- a/test/index.js +++ b/test/index.js @@ -9,11 +9,11 @@ const resolveUncached = callback => { try { return requireUncached( [ - require.resolve("log"), require.resolve("log/lib/private/logger-prototype"), + require.resolve("log"), require.resolve("log/lib/writer"), + require.resolve("log/lib/private/logger-prototype"), require.resolve("log/lib/emitter"), require.resolve("log/lib/register-master"), require.resolve("log/lib/setup-visibility"), require.resolve("supports-color"), require.resolve("../lib/private/colors-support-level"), - require.resolve("../lib/format-event-message"), require.resolve("../lib/resolve-format-parts"), require.resolve("../") ], () => { diff --git a/test/lib/format-event-message.js b/test/lib/format-event-message.js deleted file mode 100644 index 0017ec0..0000000 --- a/test/lib/format-event-message.js +++ /dev/null @@ -1,69 +0,0 @@ -"use strict"; - -const d = require("d") - , test = require("tape") - , requireUncached = require("cjs-module/require-uncached") - , overrideEnv = require("process-utils/override-env"); - -const resolveUncached = callback => { - const { restoreEnv } = overrideEnv(); - try { - return requireUncached( - [ - require.resolve("log/lib/emitter"), require.resolve("log"), - require.resolve("log/lib/private/logger-prototype"), - require.resolve("../../lib/resolve-format-parts"), - require.resolve("../../lib/format-event-message"), - require.resolve("supports-color"), - require.resolve("../../lib/private/colors-support-level"), - require.resolve("../../lib/private/inspect-depth") - ], - () => { - callback(); - return { - logger: require("log"), - formatMessage: require("../../lib/format-event-message") - }; - } - ); - } finally { - restoreEnv(); - } -}; - -test("formatMessage", t => { - const { logger, formatMessage } = resolveUncached( - () => (require("supports-color").stderr = false) - ); - t.equal( - formatMessage({ messageTokens: ["foo bar"], logger }), "foo bar", - "Should format message with no prefixes" - ); - logger.levelMessagePrefix = "debug"; - t.equal( - formatMessage({ messageTokens: ["foo bar"], logger }), "debug foo bar", - "Should format message with level prefix" - ); - const namespacedLogger = logger.get("foo"); - namespacedLogger.namespaceMessagePrefix = "foo"; - t.equal( - formatMessage({ messageTokens: ["foo bar"], logger: namespacedLogger }), - "debug foo foo bar", "Should format message with level and namespace prefix" - ); - const testObj = Object.defineProperties({ foo: "bar" }, { hidden: d("elo") }); - t.equal( - formatMessage({ - messageTokens: [ - "foo bar %d %f %i %j %o %O then%s", 20.2, 21.21, 22.22, testObj, testObj, testObj, - "maro", "rest", "arg" - ], - logger: namespacedLogger - }), - "debug foo foo bar 20.2 21.21 22 { \"foo\": \"bar\" } " + - "{ foo: 'bar', [hidden]: 'elo' } { foo: 'bar' } thenmaro 'rest' 'arg'", - "Supports sprintf formatting with rest params" - ); - const logEvent = { message: "foo", logger: namespacedLogger }; - t.equal(formatMessage(logEvent), "foo", "Passes through alredy generated message"); - t.end(); -}); diff --git a/test/lib/format.js b/test/lib/format.js deleted file mode 100644 index 0017ec0..0000000 --- a/test/lib/format.js +++ /dev/null @@ -1,69 +0,0 @@ -"use strict"; - -const d = require("d") - , test = require("tape") - , requireUncached = require("cjs-module/require-uncached") - , overrideEnv = require("process-utils/override-env"); - -const resolveUncached = callback => { - const { restoreEnv } = overrideEnv(); - try { - return requireUncached( - [ - require.resolve("log/lib/emitter"), require.resolve("log"), - require.resolve("log/lib/private/logger-prototype"), - require.resolve("../../lib/resolve-format-parts"), - require.resolve("../../lib/format-event-message"), - require.resolve("supports-color"), - require.resolve("../../lib/private/colors-support-level"), - require.resolve("../../lib/private/inspect-depth") - ], - () => { - callback(); - return { - logger: require("log"), - formatMessage: require("../../lib/format-event-message") - }; - } - ); - } finally { - restoreEnv(); - } -}; - -test("formatMessage", t => { - const { logger, formatMessage } = resolveUncached( - () => (require("supports-color").stderr = false) - ); - t.equal( - formatMessage({ messageTokens: ["foo bar"], logger }), "foo bar", - "Should format message with no prefixes" - ); - logger.levelMessagePrefix = "debug"; - t.equal( - formatMessage({ messageTokens: ["foo bar"], logger }), "debug foo bar", - "Should format message with level prefix" - ); - const namespacedLogger = logger.get("foo"); - namespacedLogger.namespaceMessagePrefix = "foo"; - t.equal( - formatMessage({ messageTokens: ["foo bar"], logger: namespacedLogger }), - "debug foo foo bar", "Should format message with level and namespace prefix" - ); - const testObj = Object.defineProperties({ foo: "bar" }, { hidden: d("elo") }); - t.equal( - formatMessage({ - messageTokens: [ - "foo bar %d %f %i %j %o %O then%s", 20.2, 21.21, 22.22, testObj, testObj, testObj, - "maro", "rest", "arg" - ], - logger: namespacedLogger - }), - "debug foo foo bar 20.2 21.21 22 { \"foo\": \"bar\" } " + - "{ foo: 'bar', [hidden]: 'elo' } { foo: 'bar' } thenmaro 'rest' 'arg'", - "Supports sprintf formatting with rest params" - ); - const logEvent = { message: "foo", logger: namespacedLogger }; - t.equal(formatMessage(logEvent), "foo", "Passes through alredy generated message"); - t.end(); -}); diff --git a/test/lib/get-namespace-prefix/_resolve-uncached.js b/test/lib/get-namespace-prefix/_resolve-uncached.js index 6849ae3..5f65192 100644 --- a/test/lib/get-namespace-prefix/_resolve-uncached.js +++ b/test/lib/get-namespace-prefix/_resolve-uncached.js @@ -8,7 +8,8 @@ module.exports = callback => { try { return requireUncached( [ - require.resolve("log"), require.resolve("log/lib/private/logger-prototype"), + require.resolve("log"), require.resolve("log/lib/writer"), + require.resolve("log/lib/private/logger-prototype"), require.resolve("log/lib/emitter"), require.resolve("log/lib/get-default-namespace"), require.resolve("../../../lib/get-namespace-prefix"),