UNPKG

@dvsa/appdev-api-common

Version:

Utils library for common API functionality

87 lines (86 loc) 3.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TimedWithAccessor = TimedWithAccessor; exports.Timed = Timed; const node_perf_hooks_1 = require("node:perf_hooks"); /** * Decorator to log the duration of a method execution by passing in an accessor function to retrieve the logger. * @param getLogger - A function that takes the class instance and returns the logger instance. * @param {string} label - Optional label for the log message. * * Note: If you are already using a logger as a class property, you can use the `Timed` decorator instead. * * @constructor * * Example usage: * class MyClass { * @TimedWithAccessor(() => Container.get(LOGGER)) * async findAll() {} // The log name here will be [findAll] * } */ function TimedWithAccessor(getLogger, label) { return (_target, propertyKey, descriptor) => { const originalMethod = descriptor.value; // biome-ignore lint/suspicious/noExplicitAny: "any" is correct for this context descriptor.value = function (...args) { const logger = getLogger(this); const labelToUse = label || propertyKey; const start = node_perf_hooks_1.performance.now(); try { const result = originalMethod.apply(this, args); // async route, if it's a Promise. if (result instanceof Promise) { return result .then((res) => { const duration = (node_perf_hooks_1.performance.now() - start).toFixed(2); logger.debug(`[${labelToUse}] took ${duration}ms`); return res; }) .catch((err) => { const duration = (node_perf_hooks_1.performance.now() - start).toFixed(2); logger.debug(`[${labelToUse}] failed after ${duration}ms`); throw err; }); } // Otherwise, sync method: log and return const duration = (node_perf_hooks_1.performance.now() - start).toFixed(2); logger.debug(`[${labelToUse}] took ${duration}ms`); return result; } catch (err) { const duration = (node_perf_hooks_1.performance.now() - start).toFixed(2); logger.debug(`[${labelToUse}] failed after ${duration}ms`); throw err; } }; return descriptor; }; } /** * Decorator to log the duration of a method execution. * @param {string} label - Optional label for the log message. * * Note: This decorator can be used on any class method that has a `logger` property. * This method will throw an error if the `logger` property is not found on the class instance. * If you are not using logger as a class property, you can use `LogDurationWithAccessor` instead. * @constructor * * Example usage: * class MyClass { * private readonly logger = Container.get(Logger); * * @Timed() * myMethod() {} // The log name here will be [myMethod] * * @Timed('MyClass.myMethod') * myMethodWithOptName() {} // The log name here will be [MyClass.myMethod] * } */ function Timed(label) { return TimedWithAccessor((cls) => { if (!cls.logger) { throw new Error(`[${label}] Logger not found on decorated class.`); } return cls.logger; }, label); }