feat: make override option when LoggedFunction call is nested

This commit is contained in:
p-sw 2024-11-29 21:48:37 +09:00
parent 94aa138461
commit fc205ad553
2 changed files with 68 additions and 7 deletions

View File

@ -12,8 +12,10 @@ import {
ScopeKeyReflectData, ScopeKeyReflectData,
returns, returns,
scopeKey, scopeKey,
nestLoggedMetadata,
loggedParam,
scopedLogger
} from "./reflected"; } from "./reflected";
import { loggedParam, scopedLogger } from "./reflected";
import { imObjectContainedLogSync, getItemByPathSync } from "./functions"; import { imObjectContainedLogSync, getItemByPathSync } from "./functions";
import { RequestMethod } from "@nestjs/common"; import { RequestMethod } from "@nestjs/common";
@ -127,16 +129,37 @@ interface OverrideBuildOptions {
skipErrorLog: boolean; skipErrorLog: boolean;
} }
const defaultOverrideBuildOptions: OverrideBuildOptions = {
skipCallLog: false,
skipReturnLog: false,
skipErrorLog: false,
}
class LoggedMetadata {
options: Partial<OverrideBuildOptions>
constructor(options?: Partial<OverrideBuildOptions>) {
this.options = options ?? defaultOverrideBuildOptions
}
updateOption(options: Partial<OverrideBuildOptions>) {
this.options = {
...this.options,
...options
}
}
}
function overrideBuild<F extends Array<any>, R>( function overrideBuild<F extends Array<any>, R>(
originalFunction: (...args: F) => R, originalFunction: (...args: F) => R,
baseLogger: Logger, baseLogger: Logger,
metadatas: FunctionMetadata, metadatas: FunctionMetadata,
key: string, key: string,
returnsData: ReturnsReflectData[] | string | true, returnsData: ReturnsReflectData[] | string | true,
logged: LoggedMetadata,
route?: { route?: {
fullRoute: string; fullRoute: string;
}, },
options?: Partial<OverrideBuildOptions>
): (...args: F) => R { ): (...args: F) => R {
return function (...args: F): R { return function (...args: F): R {
let injectedLogger: Logger = baseLogger; let injectedLogger: Logger = baseLogger;
@ -153,7 +176,7 @@ function overrideBuild<F extends Array<any>, R>(
injectedLogger = args[metadatas.scopedLoggerInjectableParam]; injectedLogger = args[metadatas.scopedLoggerInjectableParam];
} }
if (!options?.skipCallLog) { if (!logged.options.skipCallLog) {
injectedLogger.log( injectedLogger.log(
`${route ? "HIT HTTP" : "CALL"} ${route ? `${route.fullRoute} (${key})` : key `${route ? "HIT HTTP" : "CALL"} ${route ? `${route.fullRoute} (${key})` : key
} ${metadatas.loggedParams && metadatas.loggedParams.length > 0 } ${metadatas.loggedParams && metadatas.loggedParams.length > 0
@ -174,7 +197,7 @@ function overrideBuild<F extends Array<any>, R>(
try { try {
const r: R = originalFunction.call(this, ...args); const r: R = originalFunction.call(this, ...args);
if (!options?.skipReturnLog) { if (!logged.options.skipReturnLog) {
if ( if (
originalFunction.constructor.name === 'AsyncFunction' || originalFunction.constructor.name === 'AsyncFunction' ||
(r && typeof r === 'object' && typeof r['then'] === 'function') (r && typeof r === 'object' && typeof r['then'] === 'function')
@ -237,7 +260,7 @@ function overrideBuild<F extends Array<any>, R>(
return r; return r;
} }
} catch (e) { } catch (e) {
if (!options?.skipErrorLog) { if (!logged.options.skipErrorLog) {
injectedLogger.error( injectedLogger.error(
`WHILE ${route ? `HTTP ${route.fullRoute} (${key})` : key} ERROR ${e}` `WHILE ${route ? `HTTP ${route.fullRoute} (${key})` : key} ERROR ${e}`
); );
@ -268,6 +291,18 @@ export function LoggedFunction<F extends Array<any>, R>(
return; return;
} }
const logMetadata: LoggedMetadata | undefined = Reflect.getOwnMetadata(
nestLoggedMetadata,
_target,
key
)
if (logMetadata) {
// already applied, override instead
logMetadata.updateOption(options)
return
}
const newMetadata = new LoggedMetadata(options);
const all = Reflect.getMetadataKeys(fn).map((k) => [ const all = Reflect.getMetadataKeys(fn).map((k) => [
k, k,
Reflect.getMetadata(k, fn), Reflect.getMetadata(k, fn),
@ -306,13 +341,19 @@ export function LoggedFunction<F extends Array<any>, R>(
}, },
key, key,
returnsData, returnsData,
newMetadata,
undefined, undefined,
options,
); );
_target[key] = overrideFunction; _target[key] = overrideFunction;
descriptor.value = overrideFunction; descriptor.value = overrideFunction;
Reflect.defineMetadata(
nestLoggedMetadata,
newMetadata,
_target,
key
)
all.forEach(([k, v]) => { all.forEach(([k, v]) => {
Reflect.defineMetadata(k, v, _target[key]); Reflect.defineMetadata(k, v, _target[key]);
Reflect.defineMetadata(k, v, descriptor.value); Reflect.defineMetadata(k, v, descriptor.value);
@ -339,6 +380,18 @@ export function LoggedRoute<F extends Array<any>, R>(route?: string, options?: P
return; return;
} }
const logMetadata: LoggedMetadata | undefined = Reflect.getOwnMetadata(
nestLoggedMetadata,
_target,
key
)
if (logMetadata) {
// already applied, override instead
logMetadata.updateOption(options)
return
}
const newMetadata = new LoggedMetadata(options);
const all = Reflect.getMetadataKeys(fn).map((k) => [ const all = Reflect.getMetadataKeys(fn).map((k) => [
k, k,
Reflect.getMetadata(k, fn), Reflect.getMetadata(k, fn),
@ -383,15 +436,21 @@ export function LoggedRoute<F extends Array<any>, R>(route?: string, options?: P
}, },
key, key,
returnsData, returnsData,
newMetadata,
{ {
fullRoute, fullRoute,
}, },
options,
); );
_target[key] = overrideFunction; _target[key] = overrideFunction;
descriptor.value = overrideFunction; descriptor.value = overrideFunction;
Reflect.defineMetadata(
nestLoggedMetadata,
newMetadata,
_target,
key
)
all.forEach(([k, v]) => { all.forEach(([k, v]) => {
Reflect.defineMetadata(k, v, _target[key]); Reflect.defineMetadata(k, v, _target[key]);
Reflect.defineMetadata(k, v, descriptor.value); Reflect.defineMetadata(k, v, descriptor.value);

View File

@ -76,6 +76,8 @@ export const loggedParam = Symbol("nlogdec-loggedParam");
export const scopeKey = Symbol("nlogdec-scopeKey"); export const scopeKey = Symbol("nlogdec-scopeKey");
export const returns = Symbol("nlogdec-returns"); export const returns = Symbol("nlogdec-returns");
export const nestLoggedMetadata = Symbol("nlogdec-metadata");
export function InjectLogger( export function InjectLogger(
target: any, target: any,
propertyKey: string | symbol, propertyKey: string | symbol,