这个答案可能对尝试使用 CustomLogger 实现的其他人有用。我试图展示一个示例自定义记录器实现以及如何将其注入到 Nestjs 框架中。
据我所知,Nestjs 本质上使用 pino 记录器。这只是记录器服务的自定义实现(您可以用bunyan、winston 等替换它。)这是我使用的文件夹结构:
> src /
> modules /
> database /
> ...
> database.module.ts
> api /
> services /
> controllers /
> interceptors /
> middlewares /
> models /
> schemas /
> shared /
> services /
> app.util.service.ts
> pino.logger.service.ts
> utils /
> interceptors /
> filters /
> main.ts
> app.controller.ts
> app.service.ts
> server.util.service.ts
这是它的主要要点。所以logger服务的实现如下
import {Injectable, LoggerService, Scope} from "@nestjs/common";
import * as pino from 'pino';
import {AppUtilService} from "./app.util.service";
import * as os from "os";
import {APP_LOG_REDACT, APP_MESSAGE_KEY} from "../utils/app.constants";
@Injectable({
scope: Scope.DEFAULT
})
export class PinoLoggerService implements LoggerService{
constructor(private appUtilService: AppUtilService) {
}
logService = (fileNameString): pino.Logger => {
return pino({
useLevelLabels: true,
prettyPrint: this.appUtilService.isDevEnv(),
// tslint:disable-next-line: object-literal-sort-keys
messageKey: APP_MESSAGE_KEY,
level: this.appUtilService.getLogLevel(),
redact: {
paths: APP_LOG_REDACT,
censor: '**SECRET-INFO**'
},
base: {
hostName: os.hostname(),
platform: os.platform(),
processId: process.pid,
timestamp: this.appUtilService.getCurrentLocaleTimeZone(),
// tslint:disable-next-line: object-literal-sort-keys
fileName: this.appUtilService.getFileName(fileNameString),
},
});
}
debug(message: any, context?: string): any {
}
error(message: any, trace?: string, context?: string): any {
}
log(message: any, context?: string): any {
}
warn(message: any, context?: string): any {
}
}
自定义实现是使用 pinojs github 中我的特定选项实现的,我使用 fastifyjs 而不是express(再次满足我的项目需求)。所以我在 fastify js 服务器选项中添加了记录器。如果您使用的是 Express,最好在 Nest 应用程序适配器中指定新的自定义实现,如上所述。
我的 util 服务负责实现 fastify 服务器
import * as fastify from "fastify";
import {Http2Server, Http2ServerRequest, Http2ServerResponse} from "http2";
import {DocumentBuilder, SwaggerModule} from "@nestjs/swagger";
import * as fs from "fs";
import * as path from "path";
import * as uuid from "uuid";
import * as qs from "query-string";
import {PinoLoggerService} from "./modules/shared/services/pino.logger.service";
import {AppUtilService} from "./modules/shared/services/app.util.service";
import {AppConstantsService} from "./modules/shared/services/app.constants.service";
import {AppModel} from "./modules/shared/model/app.model";
import {Reflector} from "@nestjs/core";
export class ServerUtilService {
private logService;
private appConstantsService;
private appUtilServiceInstance: AppUtilService;
private fastifyInstance: fastify.FastifyInstance<Http2Server, Http2ServerRequest, Http2ServerResponse>;
constructor() {
this.appUtilServiceInstance = new AppUtilService();
this.logService = new PinoLoggerService(this.appUtilServiceInstance);
this.appConstantsService = new AppConstantsService(this.appUtilServiceInstance);
}
retrieveAppConstants(): AppModel {
return this.appConstantsService.getServerConstants();
}
retrieveAppUtilService(): AppUtilService {
return this.appConstantsService;
}
createFastifyServerInstance = (): fastify.FastifyInstance<Http2Server, Http2ServerRequest, Http2ServerResponse> => {
const serverConstants = this.appConstantsService.getServerConstants();
const httpsOptions = {
cert: fs.readFileSync(path.join(process.cwd() + '/https-keys/cert.pem')),
key: fs.readFileSync(path.join(process.cwd() + '/https-keys/key.pem')),
allowHTTP1: true,
rejectUnauthorized: true,
};
this.fastifyInstance = fastify({
http2: true,
https: httpsOptions,
bodyLimit: 26214400,
pluginTimeout: 20000,
genReqId: () => {
return uuid.v4().toString();
},
requestIdHeader: serverConstants.requestIdHeader,
modifyCoreObjects: true,
trustProxy: serverConstants.trustProxy,
ignoreTrailingSlash: true,
logger: this.logService,
querystringParser: (str) => {
return qs.parse(str);
},
});
this.addContentTypeParser();
return this.fastifyInstance;
};
private addContentTypeParser() {
this.fastifyInstance.addContentTypeParser('*', (req, done) => {
let data = '';
req.on('data', chunk => {
console.log('inside data listener event');
return data += chunk; });
req.on('end', () => {
done(null,data);
})
});
}
}
export const ServerUtilServiceInstance = new ServerUtilService();
在我的 main.ts 中
async function bootstrap() {
const fastifyServerInstance =
ServerUtilServiceInstance.createFastifyServerInstance();
const serverConstants = ServerUtilServiceInstance.retrieveAppConstants();
const app: NestFastifyApplication = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter(fastifyServerInstance)
);
....
... // global filters, interceptors, pipes
....
await app.listen(serverConstants.port, '0.0.0.0');
}