Compare commits
No commits in common. "e81e7b8e09e36976ea01d8374e579c9d1aa868e7" and "925d445af596cbfaf3d578bf96f78ecc14bcbdc1" have entirely different histories.
e81e7b8e09
...
925d445af5
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
nodeLinker: node-modules
|
|
@ -25,5 +25,5 @@
|
|||||||
"up": "yarn docs && yarn build && yarn publish dist",
|
"up": "yarn docs && yarn build && yarn publish dist",
|
||||||
"test": "ts-node ./src/test/index.ts"
|
"test": "ts-node ./src/test/index.ts"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.7.0+sha512.5a0afa1d4c1d844b3447ee3319633797bcd6385d9a44be07993ae52ff4facabccafb4af5dcd1c2f9a94ac113e5e9ff56f6130431905884414229e284e37bb7c9"
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||||
}
|
}
|
@ -3,8 +3,6 @@ export {
|
|||||||
LoggedFunction,
|
LoggedFunction,
|
||||||
LoggedController,
|
LoggedController,
|
||||||
LoggedInjectable,
|
LoggedInjectable,
|
||||||
LoggedGuard,
|
|
||||||
LoggedInterceptor,
|
|
||||||
} from "./logged";
|
} from "./logged";
|
||||||
export { ScopedLogger } from "./logger";
|
export { ScopedLogger } from "./logger";
|
||||||
export {
|
export {
|
||||||
|
239
src/logged.ts
239
src/logged.ts
@ -5,7 +5,6 @@ import {
|
|||||||
Controller,
|
Controller,
|
||||||
ControllerOptions,
|
ControllerOptions,
|
||||||
ScopeOptions,
|
ScopeOptions,
|
||||||
ExecutionContext,
|
|
||||||
} from "@nestjs/common";
|
} from "@nestjs/common";
|
||||||
import { ScopedLogger } from "./logger";
|
import { ScopedLogger } from "./logger";
|
||||||
import {
|
import {
|
||||||
@ -164,52 +163,18 @@ class LoggedMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type BuildType = 'route' | 'function' | 'guard' | 'interceptor';
|
|
||||||
|
|
||||||
const callLogIdentifyMessageDictionary: Record<BuildType, string> = {
|
|
||||||
route: 'HIT HTTP',
|
|
||||||
function: 'CALL',
|
|
||||||
guard: 'HIT GUARD',
|
|
||||||
interceptor: 'HIT INTERCEPTOR'
|
|
||||||
}
|
|
||||||
|
|
||||||
function createCallLogIdentifyMessage(type: 'route' | 'guard' | 'interceptor', key: string, route: string)
|
|
||||||
function createCallLogIdentifyMessage(type: 'function', key: string)
|
|
||||||
function createCallLogIdentifyMessage(type: BuildType, key: string, route?: string) {
|
|
||||||
return `${callLogIdentifyMessageDictionary[type]} ${type === 'route' ? `${route} (${key})` : type === 'guard' ? `${route}` : key}`
|
|
||||||
}
|
|
||||||
|
|
||||||
function overrideBuild<F extends Array<any>, R>(
|
function overrideBuild<F extends Array<any>, R>(
|
||||||
type: 'route',
|
|
||||||
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,
|
logged: LoggedMetadata,
|
||||||
route: string,
|
route?: {
|
||||||
): (...args: F) => R;
|
fullRoute: string;
|
||||||
function overrideBuild<F extends Array<any>, R>(
|
},
|
||||||
type: 'function' | 'guard' | 'interceptor',
|
|
||||||
originalFunction: (...args: F) => R,
|
|
||||||
baseLogger: Logger,
|
|
||||||
metadatas: FunctionMetadata,
|
|
||||||
key: string,
|
|
||||||
returnsData: ReturnsReflectData[] | string | true,
|
|
||||||
logged: LoggedMetadata,
|
|
||||||
): (...args: F) => R;
|
|
||||||
function overrideBuild<F extends Array<any>, R>(
|
|
||||||
type: BuildType,
|
|
||||||
originalFunction: (...args: F) => R,
|
|
||||||
baseLogger: Logger,
|
|
||||||
metadatas: FunctionMetadata,
|
|
||||||
key: string,
|
|
||||||
returnsData: ReturnsReflectData[] | string | true,
|
|
||||||
logged: LoggedMetadata,
|
|
||||||
route?: string,
|
|
||||||
): (...args: F) => R {
|
): (...args: F) => R {
|
||||||
return function (...args: F): R {
|
return function (...args: F): R {
|
||||||
// Creating ScopedLogger
|
|
||||||
let injectedLogger: Logger = baseLogger;
|
let injectedLogger: Logger = baseLogger;
|
||||||
if (typeof metadatas.scopedLoggerInjectableParam !== "undefined") {
|
if (typeof metadatas.scopedLoggerInjectableParam !== "undefined") {
|
||||||
if (
|
if (
|
||||||
@ -224,20 +189,10 @@ function overrideBuild<F extends Array<any>, R>(
|
|||||||
injectedLogger = args[metadatas.scopedLoggerInjectableParam];
|
injectedLogger = args[metadatas.scopedLoggerInjectableParam];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is ExecutionContext based function (e.g. Guard, Interceptor) get Request from Context
|
|
||||||
if (type === 'guard') {
|
|
||||||
const context = args[0] as ExecutionContext;
|
|
||||||
if (context.getType() === 'http') {
|
|
||||||
const req = context.switchToHttp().getRequest();
|
|
||||||
route = new URL(<string>(/* supporting FastifyRequest */ req.raw ? req.raw.url : req.url)).pathname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start Log
|
|
||||||
if (logged.options.callLogLevel !== 'skip') {
|
if (logged.options.callLogLevel !== 'skip') {
|
||||||
const callLogIdentifyMessage = type === 'route' || type === 'guard' || type === 'interceptor' ? createCallLogIdentifyMessage(type, key, route) : createCallLogIdentifyMessage(type, key)
|
|
||||||
injectedLogger[logged.options.callLogLevel](
|
injectedLogger[logged.options.callLogLevel](
|
||||||
`${callLogIdentifyMessage} ${metadatas.loggedParams && metadatas.loggedParams.length > 0
|
`${route ? "HIT HTTP" : "CALL"} ${route ? `${route.fullRoute} (${key})` : key
|
||||||
|
} ${metadatas.loggedParams && metadatas.loggedParams.length > 0
|
||||||
? "WITH " +
|
? "WITH " +
|
||||||
metadatas.loggedParams.map(
|
metadatas.loggedParams.map(
|
||||||
({ name, index, include, exclude }) =>
|
({ name, index, include, exclude }) =>
|
||||||
@ -254,9 +209,7 @@ function overrideBuild<F extends Array<any>, R>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const r: R = originalFunction.call(this, ...args); // Try to call original function
|
const r: R = originalFunction.call(this, ...args);
|
||||||
|
|
||||||
// Return Log
|
|
||||||
if (logged.options.returnLogLevel !== 'skip') {
|
if (logged.options.returnLogLevel !== 'skip') {
|
||||||
if (
|
if (
|
||||||
originalFunction.constructor.name === 'AsyncFunction' ||
|
originalFunction.constructor.name === 'AsyncFunction' ||
|
||||||
@ -284,7 +237,7 @@ function overrideBuild<F extends Array<any>, R>(
|
|||||||
|
|
||||||
injectedLogger[logged.options.returnLogLevel](
|
injectedLogger[logged.options.returnLogLevel](
|
||||||
route
|
route
|
||||||
? `RETURNED HTTP ${route} (${key}) ${resultLogged}`
|
? `RETURNED HTTP ${route.fullRoute} (${key}) ${resultLogged}`
|
||||||
: `RETURNED ${key} ${resultLogged}`
|
: `RETURNED ${key} ${resultLogged}`
|
||||||
);
|
);
|
||||||
return r;
|
return r;
|
||||||
@ -311,7 +264,7 @@ function overrideBuild<F extends Array<any>, R>(
|
|||||||
|
|
||||||
injectedLogger[logged.options.returnLogLevel](
|
injectedLogger[logged.options.returnLogLevel](
|
||||||
route
|
route
|
||||||
? `RETURNED HTTP ${route} (${key}) ${resultLogged}`
|
? `RETURNED HTTP ${route.fullRoute} (${key}) ${resultLogged}`
|
||||||
: `RETURNED ${key} ${resultLogged}`
|
: `RETURNED ${key} ${resultLogged}`
|
||||||
);
|
);
|
||||||
return r;
|
return r;
|
||||||
@ -320,10 +273,9 @@ function overrideBuild<F extends Array<any>, R>(
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Error Log
|
|
||||||
if (logged.options.errorLogLevel !== 'skip') {
|
if (logged.options.errorLogLevel !== 'skip') {
|
||||||
injectedLogger[logged.options.errorLogLevel](
|
injectedLogger[logged.options.errorLogLevel](
|
||||||
`WHILE ${route ? `HTTP ${route} (${key})` : key} ERROR ${e}`
|
`WHILE ${route ? `HTTP ${route.fullRoute} (${key})` : key} ERROR ${e}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -393,7 +345,6 @@ export function LoggedFunction<F extends Array<any>, R>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const overrideFunction = overrideBuild(
|
const overrideFunction = overrideBuild(
|
||||||
'function',
|
|
||||||
fn,
|
fn,
|
||||||
logger,
|
logger,
|
||||||
{
|
{
|
||||||
@ -404,6 +355,7 @@ export function LoggedFunction<F extends Array<any>, R>(
|
|||||||
key,
|
key,
|
||||||
returnsData,
|
returnsData,
|
||||||
newMetadata,
|
newMetadata,
|
||||||
|
undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
_target[key] = overrideFunction;
|
_target[key] = overrideFunction;
|
||||||
@ -488,7 +440,6 @@ export function LoggedRoute<F extends Array<any>, R>(route?: string, options?: P
|
|||||||
);
|
);
|
||||||
|
|
||||||
const overrideFunction = overrideBuild(
|
const overrideFunction = overrideBuild(
|
||||||
'route',
|
|
||||||
fn,
|
fn,
|
||||||
logger,
|
logger,
|
||||||
{
|
{
|
||||||
@ -499,7 +450,9 @@ export function LoggedRoute<F extends Array<any>, R>(route?: string, options?: P
|
|||||||
key,
|
key,
|
||||||
returnsData,
|
returnsData,
|
||||||
newMetadata,
|
newMetadata,
|
||||||
fullRoute,
|
{
|
||||||
|
fullRoute,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
_target[key] = overrideFunction;
|
_target[key] = overrideFunction;
|
||||||
@ -517,169 +470,3 @@ export function LoggedRoute<F extends Array<any>, R>(route?: string, options?: P
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LoggedGuard<F extends Array<any>, R>(options?: Partial<OverrideBuildOptions>) {
|
|
||||||
return (
|
|
||||||
_target: any,
|
|
||||||
key: string,
|
|
||||||
descriptor: TypedPropertyDescriptor<(context: ExecutionContext, ...args: F) => R>
|
|
||||||
) => {
|
|
||||||
loggerInit(_target);
|
|
||||||
|
|
||||||
const logger: Logger = _target.logger;
|
|
||||||
|
|
||||||
const fn = descriptor.value;
|
|
||||||
|
|
||||||
if (!fn || typeof fn!== "function") {
|
|
||||||
logger.warn(
|
|
||||||
`LoggedGuard decorator applied to non-function property: ${key}`
|
|
||||||
);
|
|
||||||
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) => [
|
|
||||||
k,
|
|
||||||
Reflect.getMetadata(k, fn),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const scopedLoggerInjectableParam: number = Reflect.getOwnMetadata(
|
|
||||||
scopedLogger,
|
|
||||||
_target,
|
|
||||||
key
|
|
||||||
);
|
|
||||||
|
|
||||||
const scopeKeys: ScopeKeyReflectData[] = Reflect.getOwnMetadata(
|
|
||||||
scopeKey,
|
|
||||||
_target,
|
|
||||||
key
|
|
||||||
);
|
|
||||||
|
|
||||||
const returnsData: ReturnsReflectData[] | true = Reflect.getOwnMetadata(
|
|
||||||
returns,
|
|
||||||
fn
|
|
||||||
);
|
|
||||||
|
|
||||||
const overrideFunction = overrideBuild(
|
|
||||||
'guard',
|
|
||||||
fn,
|
|
||||||
logger,
|
|
||||||
{
|
|
||||||
scopedLoggerInjectableParam,
|
|
||||||
loggedParams: [],
|
|
||||||
scopeKeys,
|
|
||||||
},
|
|
||||||
key,
|
|
||||||
returnsData,
|
|
||||||
newMetadata,
|
|
||||||
);
|
|
||||||
|
|
||||||
_target[key] = overrideFunction;
|
|
||||||
descriptor.value = overrideFunction;
|
|
||||||
|
|
||||||
Reflect.defineMetadata(
|
|
||||||
nestLoggedMetadata,
|
|
||||||
newMetadata,
|
|
||||||
_target,
|
|
||||||
key
|
|
||||||
)
|
|
||||||
all.forEach(([k, v]) => {
|
|
||||||
Reflect.defineMetadata(k, v, _target[key]);
|
|
||||||
Reflect.defineMetadata(k, v, descriptor.value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function LoggedInterceptor<F extends Array<any>, R>(options?: Partial<OverrideBuildOptions>) {
|
|
||||||
return (
|
|
||||||
_target: any,
|
|
||||||
key: string,
|
|
||||||
descriptor: TypedPropertyDescriptor<(context: ExecutionContext, ...args: F) => R>
|
|
||||||
) => {
|
|
||||||
loggerInit(_target);
|
|
||||||
|
|
||||||
const logger: Logger = _target.logger;
|
|
||||||
|
|
||||||
const fn = descriptor.value;
|
|
||||||
|
|
||||||
if (!fn || typeof fn!== "function") {
|
|
||||||
logger.warn(
|
|
||||||
`LoggedInterceptor decorator applied to non-function property: ${key}`
|
|
||||||
);
|
|
||||||
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) => [
|
|
||||||
k,
|
|
||||||
Reflect.getMetadata(k, fn),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const scopedLoggerInjectableParam: number = Reflect.getOwnMetadata(
|
|
||||||
scopedLogger,
|
|
||||||
_target,
|
|
||||||
key
|
|
||||||
);
|
|
||||||
|
|
||||||
const scopeKeys: ScopeKeyReflectData[] = Reflect.getOwnMetadata(
|
|
||||||
scopeKey,
|
|
||||||
_target,
|
|
||||||
key
|
|
||||||
);
|
|
||||||
|
|
||||||
const returnsData: ReturnsReflectData[] | true = Reflect.getOwnMetadata(
|
|
||||||
returns,
|
|
||||||
fn
|
|
||||||
);
|
|
||||||
|
|
||||||
const overrideFunction = overrideBuild(
|
|
||||||
'interceptor',
|
|
||||||
fn,
|
|
||||||
logger,
|
|
||||||
{
|
|
||||||
scopedLoggerInjectableParam,
|
|
||||||
loggedParams: [],
|
|
||||||
scopeKeys,
|
|
||||||
},
|
|
||||||
key,
|
|
||||||
returnsData,
|
|
||||||
newMetadata,
|
|
||||||
);
|
|
||||||
|
|
||||||
_target[key] = overrideFunction;
|
|
||||||
descriptor.value = overrideFunction;
|
|
||||||
|
|
||||||
Reflect.defineMetadata(
|
|
||||||
nestLoggedMetadata,
|
|
||||||
newMetadata,
|
|
||||||
_target,
|
|
||||||
key
|
|
||||||
)
|
|
||||||
all.forEach(([k, v]) => {
|
|
||||||
Reflect.defineMetadata(k, v, _target[key]);
|
|
||||||
Reflect.defineMetadata(k, v, descriptor.value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,10 @@
|
|||||||
import { Logger, LogLevel } from "@nestjs/common";
|
import { Logger } from "@nestjs/common";
|
||||||
import * as hyperid from 'hyperid';
|
import * as hyperid from 'hyperid';
|
||||||
|
|
||||||
const createId = hyperid({ fixedLength: true })
|
const createId = hyperid({ fixedLength: true })
|
||||||
|
|
||||||
|
type LogLevel = "debug" | "log" | "warn" | "verbose" | "error" | "fatal";
|
||||||
|
|
||||||
export class ScopedLogger extends Logger {
|
export class ScopedLogger extends Logger {
|
||||||
constructor(
|
constructor(
|
||||||
private logger: Logger,
|
private logger: Logger,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user