NestJs 将 Morgan 和 Nest-Winston 的输出合并到一个文件中
NestJs conbining the output of Morgan and Nest-Winston in a file
我正在尝试使用 nest - winston 将所有快速日志和未处理的异常记录在一个文件中。已关注以下文章 ::
- https://www.npmjs.com/package/nest-winston
- https://www.section.io/engineering-education/logging-with-winston/
- Node.js - logging / Use morgan and winston
我研究了一下,发现应该使用 morgan 来记录 express 日志。
const winston = require("winston");
const morgan = require("morgan");
async function bootstrap() {
const appOptions = {
cors: true,
logger: WinstonModule.createLogger({
transports: [
new winston.transports.Console({}), // ==> 1
new winston.transports.File({
filename:
"logs/Combined-" + new Date(Date.now()).toDateString() + ".log",
level: "info",
handleExceptions: true,
}),
new winston.transports.File({
filename:
"logs/Errors-" + new Date(Date.now()).toDateString() + ".log",
level: "error",
}),
],
format: winston.format.combine(
winston.format.timestamp({
format: "MMM-DD-YYYY HH:mm:ss",
}),
winston.format.printf(
(error) => `${error.level}: ${[error.timestamp]}: ${error.message}`
)
),
}),
};
const app = await NestFactory.create(ApplicationModule, appOptions);
app.setGlobalPrefix("api");
app.use(morgan("combined", { stream: winston.stream.write })); // ==> 2
const options = new DocumentBuilder()
.setTitle("xx")
.setDescription("xx")
.setVersion("1.0")
.setBasePath("api")
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup("/docs", app, document);
await app.listen(3000);
}
bootstrap();
Winston 正确地将数据记录到文件中。
error: Jul-08-2021 18:12:34: Input data validation failed
error: Jul-08-2021 18:26:28: Input data validation failed
error: Jul-08-2021 18:27:09: Input data validation failed
error: Jul-08-2021 20:57:52: Input data validation failed
info: Jul-08-2021 21:47:40: Mapped {/api/pricing/:id, GET} route
info: Jul-08-2021 21:47:40: Mapped {/api/route/:slug, DELETE} route
info: Jul-08-2021 21:47:40: Nest application successfully started
现在我想记录我插入摩根的所有快递日志,如代码(第 2 点)所示。它记录到控制台,但不记录到文件。
但是如果我注释掉第 1 点,即登录到控制台。项目没有启动。它在低于 2 行后卡住。我等了 15 分钟,但没有任何进展。
[nodemon] restarting due to changes...
[nodemon] starting `node ./index index.js`
为了将来的使用和挑战回答这个问题为时已晚您可以将 nestjs 应用程序配置为使用 winston 记录器并使用以下配置登录文件
在main.ts中添加这些代码
// Import these two line
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
logger: WinstonModule.createLogger({
format: winston.format.combine(
winston.format.colorize({ all: true }),
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.json(),
winston.format.splat(),
winston.format.prettyPrint(),
winston.format.label({ label: 'Smartedu' }),
),
transports: [
new winston.transports.File({
filename: 'questions_server_error.log',
level: 'error',
}),
new winston.transports.Console(),
],
exceptionHandlers: [
new winston.transports.File({ filename: 'questions_exceptions.log' }),
],
exitOnError: false,
}),
});
}
确保你安装了这两个包
npm i nest-winston
npm i winston
您可以在传输部分添加任何记录器级别,
参考 winston 文档然后一切正常
抱歉回复晚了。我使用了一个 nest winston 来记录异常和一个记录快速查询的中间件。
我的 main.ts 文件如下所示。
import { NestFactory } from "@nestjs/core";
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
import { WinstonModule } from "nest-winston";
import { transports } from "winston";
import { ApplicationModule } from "./app.module";
const winston = require("winston");
async function bootstrap() {
const appOptions = {
cors: true,
logger: WinstonModule.createLogger({
transports: [
// new winston.transports.Console({}),
new winston.transports.File({
filename:
"logs/Combined-" + new Date(Date.now()).toDateString() + ".log",
level: "info",
handleExceptions: true,
}),
new winston.transports.File({
filename:
"logs/Errors-" + new Date(Date.now()).toDateString() + ".log",
level: "error",
}),
],
exceptionHandlers: [
new transports.File({ filename: 'logs/exceptions.log' })
],
format: winston.format.combine(
winston.format.timestamp({
format: "DD/MM/YYYY, HH:mm:ss",
}),
winston.format.printf(
(error) => `[Nest] 5277 - ${[error.timestamp]} [${error.context}] : ${error.level}: ${error.message}`
)
),
}),
};
const app = await NestFactory.create(ApplicationModule, appOptions);
app.setGlobalPrefix("api");
const options = new DocumentBuilder()
.setTitle("xxx")
.setDescription("xxx")
.setVersion("1.0")
.setBasePath("api")
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup("/docs", app, document);
await app.listen(3000);
}
bootstrap();
中间件配置如下所示。
import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
private logger = new Logger('HTTP');
use(request: Request, response: Response, next: NextFunction): void {
const { ip, method, originalUrl } = request;
const userAgent = request.get('user-agent') || '';
response.on('finish', () => {
const { statusCode } = response;
const contentLength = response.get('content-length');
this.logger.log(
`${method} ${originalUrl} ${statusCode} ${contentLength} - ${userAgent} ${ip}`,
);
});
next();
}
}
我终于在 app.module.ts
中配置了我的中间件
export class ApplicationModule implements NestModule{
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('*');
}
constructor(private readonly connection: Connection) {}
}
我正在尝试使用 nest - winston 将所有快速日志和未处理的异常记录在一个文件中。已关注以下文章 ::
- https://www.npmjs.com/package/nest-winston
- https://www.section.io/engineering-education/logging-with-winston/
- Node.js - logging / Use morgan and winston
我研究了一下,发现应该使用 morgan 来记录 express 日志。
const winston = require("winston");
const morgan = require("morgan");
async function bootstrap() {
const appOptions = {
cors: true,
logger: WinstonModule.createLogger({
transports: [
new winston.transports.Console({}), // ==> 1
new winston.transports.File({
filename:
"logs/Combined-" + new Date(Date.now()).toDateString() + ".log",
level: "info",
handleExceptions: true,
}),
new winston.transports.File({
filename:
"logs/Errors-" + new Date(Date.now()).toDateString() + ".log",
level: "error",
}),
],
format: winston.format.combine(
winston.format.timestamp({
format: "MMM-DD-YYYY HH:mm:ss",
}),
winston.format.printf(
(error) => `${error.level}: ${[error.timestamp]}: ${error.message}`
)
),
}),
};
const app = await NestFactory.create(ApplicationModule, appOptions);
app.setGlobalPrefix("api");
app.use(morgan("combined", { stream: winston.stream.write })); // ==> 2
const options = new DocumentBuilder()
.setTitle("xx")
.setDescription("xx")
.setVersion("1.0")
.setBasePath("api")
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup("/docs", app, document);
await app.listen(3000);
}
bootstrap();
Winston 正确地将数据记录到文件中。
error: Jul-08-2021 18:12:34: Input data validation failed
error: Jul-08-2021 18:26:28: Input data validation failed
error: Jul-08-2021 18:27:09: Input data validation failed
error: Jul-08-2021 20:57:52: Input data validation failed
info: Jul-08-2021 21:47:40: Mapped {/api/pricing/:id, GET} route
info: Jul-08-2021 21:47:40: Mapped {/api/route/:slug, DELETE} route
info: Jul-08-2021 21:47:40: Nest application successfully started
现在我想记录我插入摩根的所有快递日志,如代码(第 2 点)所示。它记录到控制台,但不记录到文件。 但是如果我注释掉第 1 点,即登录到控制台。项目没有启动。它在低于 2 行后卡住。我等了 15 分钟,但没有任何进展。
[nodemon] restarting due to changes...
[nodemon] starting `node ./index index.js`
为了将来的使用和挑战回答这个问题为时已晚您可以将 nestjs 应用程序配置为使用 winston 记录器并使用以下配置登录文件
在main.ts中添加这些代码
// Import these two line
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
logger: WinstonModule.createLogger({
format: winston.format.combine(
winston.format.colorize({ all: true }),
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.json(),
winston.format.splat(),
winston.format.prettyPrint(),
winston.format.label({ label: 'Smartedu' }),
),
transports: [
new winston.transports.File({
filename: 'questions_server_error.log',
level: 'error',
}),
new winston.transports.Console(),
],
exceptionHandlers: [
new winston.transports.File({ filename: 'questions_exceptions.log' }),
],
exitOnError: false,
}),
});
}
确保你安装了这两个包
npm i nest-winston
npm i winston
您可以在传输部分添加任何记录器级别, 参考 winston 文档然后一切正常
抱歉回复晚了。我使用了一个 nest winston 来记录异常和一个记录快速查询的中间件。
我的 main.ts 文件如下所示。
import { NestFactory } from "@nestjs/core";
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
import { WinstonModule } from "nest-winston";
import { transports } from "winston";
import { ApplicationModule } from "./app.module";
const winston = require("winston");
async function bootstrap() {
const appOptions = {
cors: true,
logger: WinstonModule.createLogger({
transports: [
// new winston.transports.Console({}),
new winston.transports.File({
filename:
"logs/Combined-" + new Date(Date.now()).toDateString() + ".log",
level: "info",
handleExceptions: true,
}),
new winston.transports.File({
filename:
"logs/Errors-" + new Date(Date.now()).toDateString() + ".log",
level: "error",
}),
],
exceptionHandlers: [
new transports.File({ filename: 'logs/exceptions.log' })
],
format: winston.format.combine(
winston.format.timestamp({
format: "DD/MM/YYYY, HH:mm:ss",
}),
winston.format.printf(
(error) => `[Nest] 5277 - ${[error.timestamp]} [${error.context}] : ${error.level}: ${error.message}`
)
),
}),
};
const app = await NestFactory.create(ApplicationModule, appOptions);
app.setGlobalPrefix("api");
const options = new DocumentBuilder()
.setTitle("xxx")
.setDescription("xxx")
.setVersion("1.0")
.setBasePath("api")
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup("/docs", app, document);
await app.listen(3000);
}
bootstrap();
中间件配置如下所示。
import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
private logger = new Logger('HTTP');
use(request: Request, response: Response, next: NextFunction): void {
const { ip, method, originalUrl } = request;
const userAgent = request.get('user-agent') || '';
response.on('finish', () => {
const { statusCode } = response;
const contentLength = response.get('content-length');
this.logger.log(
`${method} ${originalUrl} ${statusCode} ${contentLength} - ${userAgent} ${ip}`,
);
});
next();
}
}
我终于在 app.module.ts
中配置了我的中间件export class ApplicationModule implements NestModule{
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('*');
}
constructor(private readonly connection: Connection) {}
}