tachybase_todo/packages/core/logger/src/request-logger.ts
YANG QIA 8633ec3735
refactor(logger): improve logger format (#2664)
* refactor(logger): improve logger format

* chore: improve log format

* feat(logger): plugin-logger

* feat: allow to download log files, close T-1917

* chore: update yarn.lock

* chore: improve log format

* fix: add maxsize params

* chore: add userId field to request

* chore: remove userId from request

* chore: change userId in response

* chore: change action in response

* chore: add database logger

* fix: build

* fix: test

* chore: solve conflicts

* fix: escape delimiter in message

* refactor: improve create logger api

* chore: update app logger options

* chore: remove colorize for json

* fix: bug of data2tree

* fix: test

* chore: log

* chore: remove GITHUB_ACTION check

* fix: bug

* chore: change version

* fix: transports

* fix: mockServer

* chore: use new plugin settings api

* fix: version

* fix: build

* feat: support logfmt

* fix: build

* fix: build

* fix: test

* chore: update config

* fix: test

* fix: bug

* fix: test

* fix: format

* chore: update path

* fix: build

* fix: bug

* chore: update comment

* fix: allow to custom format

* fix: package.json

* fix: version

* fix: bug
2023-12-27 13:56:13 +08:00

72 lines
2.0 KiB
TypeScript

import { getLoggerFilePath } from './config';
import { AppLoggerOptions, createLogger } from './logger';
import { pick } from 'lodash';
const defaultRequestWhitelist = [
'action',
'header.x-role',
'header.x-hostname',
'header.x-timezone',
'header.x-locale',
'referer',
];
const defaultResponseWhitelist = ['status'];
export const requestLogger = (appName: string, options?: AppLoggerOptions) => {
const requestLogger = createLogger({
dirname: getLoggerFilePath(appName),
filename: 'request',
...(options?.request || {}),
});
return async (ctx, next) => {
const reqId = ctx.reqId;
const path = /^\/api\/(.+):(.+)/.exec(ctx.path);
const contextLogger = ctx.app.log.child({ reqId, module: path?.[1], submodule: path?.[2] });
// ctx.reqId = reqId;
ctx.logger = ctx.log = contextLogger;
const startTime = Date.now();
const requestInfo = {
method: ctx.method,
path: ctx.url,
};
requestLogger.info({
reqId,
message: 'request',
...requestInfo,
req: pick(ctx.request.toJSON(), options?.request?.requestWhitelist || defaultRequestWhitelist),
action: ctx.action?.toJSON?.(),
});
let error: Error;
try {
await next();
} catch (e) {
error = e;
} finally {
const cost = Date.now() - startTime;
const status = ctx.status;
const info = {
reqId,
message: 'response',
...requestInfo,
res: pick(ctx.response.toJSON(), options?.request?.responseWhitelist || defaultResponseWhitelist),
action: ctx.action?.toJSON?.(),
userId: ctx.auth?.user?.id,
status: ctx.status,
cost,
};
if (Math.floor(status / 100) == 5) {
requestLogger.error({ ...info, res: ctx.body?.['errors'] || ctx.body });
} else if (Math.floor(status / 100) == 4) {
requestLogger.warn({ ...info, res: ctx.body?.['errors'] || ctx.body });
} else {
requestLogger.info(info);
}
}
ctx.res.setHeader('X-Request-Id', reqId);
if (error) {
throw error;
}
};
};