日志分为三类:普通日志、异常日志和控制台日志。其中普通日志和异常日志会生成日志文件,持久化存储。控制台日志只展示在控制台中,用于辅助开发。
控制台日志
控制台日志用于辅助开发,一般我们使用 nestjs 内置的日志模块以保持日志格式的一致性。
import { Logger } from '@nestjs/common'Logger.log('app is listening to 8080')
普通日志
普通日志记录请求信息,包括请求的 id、用时、method、url、headers 等信息。
在中间件中实现,使用了 express-winston、winston、winston-daily-rotate-file。
import { Logger } from '@nestjs/common'import * as expressWinston from 'express-winston'import { format } from 'winston'import * as DailyRotateFile from 'winston-daily-rotate-file'import config from '../config'const { combine, timestamp, printf } = formatexport default expressWinston.logger({format: combine(timestamp(),printf(({ timestamp, meta }) => {// 设置日志信息、格式const { req, res, responseTime } = metaconst { id, url, headers, method } = reqLogger.log(`>> ${method}: ${url} ${responseTime}ms [${id}]`)const data = {requestId: id,time: responseTime,code: res.statusCode,method,url,headers}return `${timestamp} ${JSON.stringify(data)}`})),transports: [new DailyRotateFile({filename: '%DATE%.log',...config.LOGGER})],requestWhitelist: ['url','headers','method','httpVersion','originalUrl','query','id']})
异常日志
异常日志在异常过滤器中捕获,记录请求 id、method、url、exception 等信息。
// log utilimport { createLogger, format } from 'winston'import { Logger } from '@nestjs/common'import * as DailyRotateFile from 'winston-daily-rotate-file'import config from '../config'const { combine, timestamp, printf } = formatexport const error = createLogger({format: combine(timestamp(),printf(({ timestamp, id, method, url ,exception }) => {Logger.error(exception)return `${timestamp} ${id} ${method} ${url}: ${JSON.stringify(exception)}`})),transports: [new DailyRotateFile({filename: '%DATE%.error.log',level: 'error',...config.LOGGER})]})
import { HttpException, Catch, ArgumentsHost } from '@nestjs/common'import { BaseExceptionFilter } from '@nestjs/core'import { error as logger } from './errorlogger'@Catch(HttpException)export class ExceptionFilter extends BaseExceptionFilter {catch(exception, host: ArgumentsHost) {const ctx = host.switchToHttp();const request = ctx.getRequest<any>();const { id, method, url } = requestlogger.error('', {id,method,url,exception})super.catch(exception, host);}}
如果需要自定义日志,可以参考 日志。
