diff --git a/packages/functions/readme.md b/packages/functions/readme.md index b4ce39f..a5f6cb3 100644 --- a/packages/functions/readme.md +++ b/packages/functions/readme.md @@ -58,6 +58,22 @@ tracedFoo(); - ### cleanTraced and cleanTrace `(Same as the above two but ignores tracing for anonymous functions to avoid polluting the logs)` +- ### tracing a function with a layer prefix (Works for all 4 functions above) + +```js +const tracedFoo = traced["controller"](function foo() { + console.log(123); +})(); + +tracedFoo(); + +/* + controller >>> foo execution initiated + 123 + controller >>> foo execution completed - execution_time : 0.2069999985396862 +*/ +``` + - ### bindKey `(Creates a bounded function from a passed object and function key with its context preserved)`
- This method is distint from the `bindKey` function of lodash as this preserves the function's `name` property where lodash sets it as `wrapper` diff --git a/packages/functions/src/traced.js b/packages/functions/src/traced.js index 9543cc2..7149d67 100644 --- a/packages/functions/src/traced.js +++ b/packages/functions/src/traced.js @@ -5,13 +5,12 @@ import { fnName as _fnName } from "./utils"; const logger = moduleLogger("tracer"); -export const _traced = (fn, loggable = {}, fnName) => { +export const _traced = (fn, loggable = {}, fnName, layer) => { let startTime; const disableTracing = process.env.DISABLE_FUNCTION_TRACING === "true" || process.env.DISABLE_FUNCTION_TRACING === "1"; if (!disableTracing) { - fnName = fnName ?? _fnName(fn, loggable.layer); - delete loggable.layer; + fnName = fnName ?? _fnName(fn, layer); logger.info(`${fnName} execution initiated`, loggable); startTime = performance.now(); } @@ -50,28 +49,30 @@ export const _traced = (fn, loggable = {}, fnName) => { } }; -export const traced = - (fn, loggable) => - (...params) => - _traced(fn.bind(this, ...params), loggable); +const _proxyHandlers = { get: (target, prop) => (fn, loggable) => target(fn, loggable, prop) }; -export const trace = (fn, loggable) => _traced(fn, loggable); +export const traced = new Proxy( + (fn, loggable, layer) => + (...params) => + _traced(fn.bind(this, ...params), loggable, null, layer), + _proxyHandlers +); -export const cleanTrace = (fn, loggable) => { - if (fn.name) { - return _traced(fn, loggable); - } +export const trace = new Proxy((fn, loggable, layer) => _traced(fn, loggable, null, layer), _proxyHandlers); + +export const cleanTrace = new Proxy((fn, loggable, layer) => { + if (fn.name) return _traced(fn, loggable, null, layer); return fn(); -}; +}, _proxyHandlers); -export const cleanTraced = - (fn, loggable) => - (...params) => { - if (fn.name) { - return _traced(fn.bind(this, ...params), loggable); - } - return fn.call(this, ...params); - }; +export const cleanTraced = new Proxy( + (fn, loggable, layer) => + (...params) => { + if (fn.name) return _traced(fn.bind(this, ...params), loggable, null, layer); + return fn.call(this, ...params); + }, + _proxyHandlers +); export default { traced, diff --git a/packages/functions/src/utils/index.js b/packages/functions/src/utils/index.js index d925bd0..db08bfd 100644 --- a/packages/functions/src/utils/index.js +++ b/packages/functions/src/utils/index.js @@ -12,4 +12,4 @@ export const fnName = (fn, prefix) => { return coloredFnName(name, prefix); }; -export const coloredFnName = (fn, prefix) => chalk.bold(chalk.magentaBright(prefix ? `${prefix}->${fn}` : fn)); +export const coloredFnName = (fn, prefix) => chalk.bold(chalk.magentaBright(prefix ? `${prefix} >>> ${fn}` : fn)); diff --git a/packages/functions/test/traced.test.js b/packages/functions/test/traced.test.js index e184f58..f8843ce 100644 --- a/packages/functions/test/traced.test.js +++ b/packages/functions/test/traced.test.js @@ -24,15 +24,12 @@ describe("traced", () => { expect(res).toStrictEqual(_mockResult); expect(mockLogger.info).toBeCalledWith(`${coloredFnName("testFunction")} execution initiated`, {}); }); - test("test function with layer log", async () => { - const res = await traced( - async function testFunction() { - return _mockResult; - }, - { layer: "controller" } - )(); + test("test function with layer prefix", async () => { + const res = await traced["controller"](async function testFunction() { + return _mockResult; + })(); expect(res).toStrictEqual(_mockResult); - expect(mockLogger.info).toBeCalledWith(`${coloredFnName("controller->testFunction")} execution initiated`, {}); + expect(mockLogger.info).toBeCalledWith(`${coloredFnName("controller >>> testFunction")} execution initiated`, {}); }); test("test arrow function", () => { const testArrowFunction = () => _mockResult; diff --git a/packages/functions/types/traced.d.ts b/packages/functions/types/traced.d.ts index 8c8429c..d2920ec 100644 --- a/packages/functions/types/traced.d.ts +++ b/packages/functions/types/traced.d.ts @@ -1,3 +1,9 @@ +type BaseTracedFunction = any>(fn: T, loggable?: Record) => T; + +interface TracedFunction extends BaseTracedFunction { + [key: string]: BaseTracedFunction; +} + /** * @description Invokes the given function with tracing * @param fn The function to be invoked asynchronously @@ -12,7 +18,7 @@ export function trace(fn: Function, loggable?: Record): Promise; * @param loggable Object with extra information to be logged * @returns Returns the new function */ -export function traced any>(fn: T, loggable?: Record): T; +export const traced: TracedFunction; /** * @description Invokes the given function with tracing. Tracing is however ignored if the function is an anonymous function @@ -28,11 +34,4 @@ export function cleanTrace(fn: Function, loggable?: Record): Promise any>(fn: T, loggable?: Record): T; - -export default { - traced, - trace, - cleanTraced, - cleanTrace -}; +export const cleanTraced: TracedFunction;