文章目录
- 1 日志配置
- 2 创建处理请求头信息的方法
- 3 开启请求拦截器与异常过滤器来记录日志
- 3.1 响应拦截器
- 3.1.1 **在项目`src`文件夹下创建`unify-response.interceptor.ts`文件**
- 3.1.2 **在项目`app.module.ts`文件夹下引入并使用`unify-response.interceptor.ts`文件**
- 3.2 异常过滤器
- 3.2.1 **在项目`src`文件夹下创建`uinify-exception.filter.ts`文件**
- 3.1.2 **在项目`app.module.ts`文件夹下引入并使用`uinify-exception.filter.ts`文件**
- 3 效果
注:不要关心注释代码,那是属于后面功能的区域。因为随着代码体量加大,功能不再明确,只需按照步骤并参考效果图,把关键代码写入即可,所以下只写关键代码,具体请看效果图。
项目地址
1 日志配置
import * as winston from 'winston';
import { WinstonModule } from 'nest-winston';
import * as DailyRotateFile from 'winston-daily-rotate-file';mports: [
WinstonModule.forRoot({transports: [new DailyRotateFile({dirname: `logs`, filename: '%DATE%.log', datePattern: 'YYYY-MM-DD', zippedArchive: true, maxSize: '20m', maxFiles: '14d', format: winston.format.combine(winston.format.timestamp({format: 'YYYY-MM-DD HH:mm:ss',}),winston.format.json(),),}),],}),]

2 创建处理请求头信息的方法
- 在项目
src
文件夹下创建logServer
文件夹,并创建requestData.ts
文件
~ /src/logServer/requestData.ts
import { Request } from 'express';export const getReqMainInfo: (req: Request) => {[prop: string]: any;
} = (req) => {const { query, headers, url, method, body, connection } = req;const xRealIp = headers['X-Real-IP'];const xForwardedFor = headers['X-Forwarded-For'];const { ip: cIp } = req;const { remoteAddress } = connection || {};const ip = xRealIp || xForwardedFor || cIp || remoteAddress;return {url,host: headers.host,ip,method,query,body,};
};
3 开启请求拦截器与异常过滤器来记录日志
3.1 响应拦截器
3.1.1 在项目src
文件夹下创建unify-response.interceptor.ts
文件
~ /src/unify-response.interceptor.ts
import {CallHandler,ExecutionContext,Inject,Injectable,NestInterceptor,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Request } from 'express';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { getReqMainInfo } from './logServer/requestData';@Injectable()
export class UnifyResponseInterceptor implements NestInterceptor {constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,) {}intercept(context: ExecutionContext, next: CallHandler): Observable<any> {const ctx = context.switchToHttp();const req = ctx.getRequest<Request>();return next.handle().pipe(map((data) => {this.logger.info('response', {responseData: data,req: getReqMainInfo(req),});return data}),);}
}
3.1.2 在项目app.module.ts
文件夹下引入并使用unify-response.interceptor.ts
文件
~ /src/app.module.ts
import { APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core';
import { UnifyResponseInterceptor } from './unify-response.interceptor';providers: [AppService,GlobalParamsService,{provide: APP_INTERCEPTOR,useClass: UnifyResponseInterceptor,},],

3.2 异常过滤器
3.2.1 在项目src
文件夹下创建uinify-exception.filter.ts
文件
~ /src/uinify-exception.filter.ts
import {ArgumentsHost,Catch,ExceptionFilter,HttpException,HttpStatus,Inject,
} from '@nestjs/common';
import { Response, Request } from 'express';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { getReqMainInfo } from './logServer/requestData';@Catch()
export default class UnifyExceptionFilter implements ExceptionFilter {constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,) {}catch(exception: HttpException, host: ArgumentsHost) {const ctx = host.switchToHttp(); const response = ctx.getResponse<Response>(); const request = ctx.getRequest<Request>(); const status =exception instanceof HttpException? exception.getStatus(): HttpStatus.INTERNAL_SERVER_ERROR;const responses = response.status(status).json({statusCode: status,timestamp: new Date().toISOString(),path: request.url,});this.logger.error('', {status,req: getReqMainInfo(request),stack: exception.stack,});response.status(status >= 500 ? status : 201).json(response);}
}
3.1.2 在项目app.module.ts
文件夹下引入并使用uinify-exception.filter.ts
文件
~ /src/app.module.ts
import { APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core';
import UnifyExceptionFilter from './uinify-exception.filter';providers: [AppService,GlobalParamsService,{provide: APP_FILTER, useClass: UnifyExceptionFilter,},],

3 效果
- 此时随便调用一个接口就会在项目里看到日志
