Javascript 如何使用 nestjs 日志服务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52650895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use nestjs Logging service
提问by maku_at
I tried to use the internal Loggerof nestjs (described on https://docs.nestjs.com/techniques/logger-> but with no description of how to use it)
我尝试使用Loggernestjs的内部(在https://docs.nestjs.com/techniques/logger-> 上进行了描述 -> 但没有描述如何使用它)
But I had problems (tried to inject LoggerServiceand so on)
但是我遇到了问题(尝试注入LoggerService等等)
Can anybody explain how to do this?
任何人都可以解释如何做到这一点?
回答by Kim Kern
Best practise
最佳实践
Better than accessing the Loggerstatically is to create an instance for your class:
比Logger静态访问更好的是为您的类创建一个实例:
@Controller()
export class AppController {
private readonly logger = new Logger(AppController.name);
@Get()
async get() {
this.logger.log('Getting stuff');
}
}
Why is this better?
为什么这样更好?
1) You can provide a context in the constructor like new Logger(AppController.name)so that the class name (or anything else) will be part of all log messages in this class.
1)您可以在构造函数中提供一个上下文,例如new Logger(AppController.name)类名(或其他任何内容)将成为此类中所有日志消息的一部分。
2) If you at some point want to extend or replace the default LoggerService, you do not need to change any of your application code besides setting the new logger. Your new logger will automatically be used. If you access it statically it will continue to take the default implementation.
2) 如果您在某个时候想要扩展或替换默认值LoggerService,除了设置新记录器之外,您不需要更改任何应用程序代码。您的新记录器将自动使用。如果您静态访问它,它将继续采用默认实现。
const app = await NestFactory.create(AppModule, {logger: new MyLogger()});
3) You can mock the Loggerin your tests:
3)您可以Logger在测试中模拟:
module.useLogger(new NoOpLogger());
回答by Dani Mach
You need to import first into your class:
您需要先导入到您的班级中:
import { Logger } from '@nestjs/common';
and then you can begin with logging:
然后你可以开始记录:
Logger.log('info')
Logger.warn('warning')
Logger.error('something went wrong! ', error)
回答by maku_at
The answer is simple. There are static methods on the Logger class.
答案很简单。Logger 类有静态方法。
e.g.
例如
static log(message: string, context = '', isTimeDiffEnabled = true)
Usage:
用法:
Logger.log('Only a test');
回答by Joey587
This answer might be useful for others who are trying with CustomLogger Implementation. I am trying to show a sample custom logger implementation and how it can be injected to the Nestjs framework.
此答案可能对尝试使用 CustomLogger 实现的其他人有用。我正在尝试展示一个示例自定义记录器实现以及如何将其注入 Nestjs 框架。
I understand that Nestjs inherently uses pino logger. This is just a custom implementation of logger service (which you can replace with bunyan, winston, etc..) This is the folder structure I use:
我知道 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
This is the main gist of it. So the logger service is implemented as follows
这是它的主要要点。所以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 {
}
}
The custom implementation is implemented with the my specific options in pinojs github I am using fastifyjs instead of express (again to match my prject needs). So I've added the logger in fastify js server options. If you are using express, its better to specify the new custom implementation in the Nest application Adapter as stated above.
自定义实现是使用我在 pinojs github 中的特定选项实现的,我使用的是 fastifyjs 而不是 express(再次匹配我的项目需求)。所以我在 fastify js 服务器选项中添加了记录器。如果您使用 express,最好在 Nest 应用程序适配器中指定新的自定义实现,如上所述。
My util service that takes care of implementing the fastify server
我的 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();
And in my main.ts
在我的 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');
}

