Created
August 25, 2018 20:53
-
-
Save hbarcelos/a351b95fd869240f87cd12d5ad202742 to your computer and use it in GitHub Desktop.
Contextual Logger - Applying CLS context to logs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/logger.js b/logger.js | |
index 3aa3418..d19e435 100644 | |
--- a/logger.js | |
+++ b/logger.js | |
@@ -1,6 +1,41 @@ | |
const pino = require('pino'); | |
const { createNamespace } = require('cls-hooked'); | |
+const logMethods = ['trace', 'debug', 'info', 'warn', 'error', 'fatal']; | |
+ | |
+const logMethodHandler = { | |
+ apply(target, thisArg, argumentList) { | |
+ // eslint-disable-next-line camelcase | |
+ const { id, _ns_name, ...clsContext } = | |
+ ((thisArg || {}).cls || {}).active || {}; | |
+ | |
+ const [context, ...rest] = argumentList; | |
+ | |
+ let finalArgList = argumentList; | |
+ if (typeof context === 'string') { | |
+ // Log was called only with message, no local context | |
+ const message = context; | |
+ finalArgList = [clsContext, message, ...rest]; | |
+ } else { | |
+ // Log was called local context, so we merge it into clsContext | |
+ const fullContext = Object.assign({}, clsContext, context); | |
+ finalArgList = [fullContext, ...rest]; | |
+ } | |
+ | |
+ return target.apply(thisArg, finalArgList); | |
+ }, | |
+}; | |
+ | |
+const loggerObjectHandler = { | |
+ get(target, prop) { | |
+ if (!logMethods.includes(prop)) { | |
+ return target[prop]; | |
+ } | |
+ | |
+ return new Proxy(target[prop], logMethodHandler); | |
+ }, | |
+}; | |
+ | |
let counter = 0; | |
function createLogger(opts, destination) { | |
@@ -9,7 +44,7 @@ function createLogger(opts, destination) { | |
counter += 1; | |
- return Object.assign(baseLogger, { cls }); | |
+ return new Proxy(Object.assign(baseLogger, { cls }), loggerObjectHandler); | |
} | |
module.exports = createLogger; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/logger.test.js b/logger.test.js | |
index 45c16ca..155415a 100644 | |
--- a/logger.test.js | |
+++ b/logger.test.js | |
@@ -42,3 +42,61 @@ test(`2 different loggers don't share the same namespace`, t => { | |
t.notDeepEqual(logger.cls, anotherLogger.cls); | |
}); | |
+ | |
+test.cb(`Should properly log message with cls context`, t => { | |
+ const stream = parseJSONStream(); | |
+ const gen = streamToGenerator(stream); | |
+ const logger = createLogger({}, stream); | |
+ | |
+ const msg = 'foo'; | |
+ const clsValues = { | |
+ dummy: 'value', | |
+ another: 'another value', | |
+ }; | |
+ | |
+ logger.cls.run(() => { | |
+ logger.cls.set('dummy', clsValues.dummy); | |
+ logger.cls.set('another', clsValues.another); | |
+ process.nextTick(async () => { | |
+ logger.info(msg); | |
+ | |
+ const entry = await gen.next().value; | |
+ | |
+ t.is(entry.dummy, clsValues.dummy); | |
+ t.is(entry.another, clsValues.another); | |
+ | |
+ t.end(); | |
+ }); | |
+ }); | |
+}); | |
+ | |
+test.cb( | |
+ `Should properly log message with both cls and local context, | |
+ And local context should have precedence over cls context`, | |
+ t => { | |
+ const stream = parseJSONStream(); | |
+ const gen = streamToGenerator(stream); | |
+ const logger = createLogger({}, stream); | |
+ | |
+ const msg = 'foo'; | |
+ const clsValues = { | |
+ dummy: 'value', | |
+ precedence: 'will be overwitten', | |
+ }; | |
+ | |
+ logger.cls.run(() => { | |
+ logger.cls.set('dummy', clsValues.dummy); | |
+ logger.cls.set('another', clsValues.another); | |
+ process.nextTick(async () => { | |
+ const localValues = { precedence: 'local' }; | |
+ logger.info(localValues, msg); | |
+ | |
+ const entry = await gen.next().value; | |
+ | |
+ t.is(entry.precedence, localValues.precedence); | |
+ | |
+ t.end(); | |
+ }); | |
+ }); | |
+ } | |
+); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment