tachybase_todo/packages/core/logger/src/create-app-logger.ts
YANG QIA 474b09c7f2
perf(server): optimize performance of APIs (#3079)
* perf: add perf_hooks

* perf: add cache

* fix: test

* feat: support bloom filter

* feat: caching token black list

* perf: caching i18n instance

* fix: test

* fix: test

* chore: remove prePerfHooks on app

* chore: improve i18n instances cache

* chore: remove performance measure

* fix: package.json

* perf: optimize cache strategy

* fix: test

* fix: bug

* test: storer of auth-manager

* fix: afterDestroy hook when updating null value

* fix: version

* chore: fix bug and add test

* fix: test

* fix: test
2023-12-12 23:02:09 +08:00

83 lines
2.1 KiB
TypeScript

import { randomUUID } from 'crypto';
import Koa from 'koa';
import { pick } from 'lodash';
import { createLogger, LoggerOptions } from './create-logger';
const defaultRequestWhitelist = [
'action',
'header.x-role',
'header.x-hostname',
'header.x-timezone',
'header.x-locale',
'referer',
];
const defaultResponseWhitelist = ['status'];
export interface AppLoggerOptions extends LoggerOptions {
skip?: (ctx?: any) => Promise<boolean>;
requestWhitelist?: string[];
responseWhitelist?: string[];
}
export function createAppLogger(options: AppLoggerOptions = {}) {
const {
skip,
requestWhitelist = defaultRequestWhitelist,
responseWhitelist = defaultResponseWhitelist,
...others
} = options;
const instance = createLogger(others);
const middleware = async (ctx: Koa.Context, next: Koa.Next) => {
if (skip && (await skip(ctx))) {
return next();
}
const logger = ctx.app['logger'];
const startTime = Date.now();
const info = {
level: 'info',
message: `END: ${ctx.method} ${ctx.url}`,
req: ctx.request.toJSON(),
};
ctx.reqId = ctx.req['id'] = randomUUID();
ctx.logger = ctx.log = logger.child({ reqId: ctx.reqId });
ctx.logger.info(`BEGIN: ${ctx.method} ${ctx.url}`);
let error;
try {
await next();
} catch (e) {
error = e;
} finally {
info['res'] = ctx.response.toJSON();
// info['status'] = ctx.status;
if (Math.floor(ctx.status / 100) == 5) {
info.level = 'error';
info['errors'] = ctx.body?.['errors'] || ctx.body;
} else if (Math.floor(ctx.status / 100) == 4) {
info.level = 'warn';
info['errors'] = ctx.body?.['errors'] || ctx.body;
}
info['responseTime'] = Date.now() - startTime;
if (ctx.action) {
info['req']['action'] = ctx.action?.toJSON?.();
}
info['req'] = pick(info['req'], requestWhitelist);
info['res'] = pick(info['res'], responseWhitelist);
ctx.logger.log(info);
}
if (error) {
throw error;
}
};
return { instance, middleware };
}
export default createAppLogger;