跳转到内容

操作日志

基于全局拦截器的操作日志模块,自动记录所有控制器方法的执行情况,包括请求信息、用户信息、执行结果和耗时。

模块注册

typescript
import { OperationModule } from '@maxtan/nest-core'

@Module({
  imports: [
    OperationModule.forRoot({
      enabled: true,                         // 是否启用,默认 true
      excludePaths: ['/health', '/metrics'], // 排除的路径(支持通配符)
      request: false,                        // 默认是否记录请求参数,默认 false
      response: false,                       // 默认是否记录响应结果,默认 false
      idField: 'id',                         // 用户 ID 字段名,默认 'id'
      nameField: 'name'                      // 用户名字段名,默认 'name'
    })
  ]
})
export class AppModule {}

@Operation 装饰器

装饰器是可选的,即使不使用,拦截器也会自动记录日志。装饰器用于:

  1. 添加操作描述
  2. 禁用特定方法的日志
  3. 单独配置请求/响应记录
typescript
import { Operation } from '@maxtan/nest-core'

@Controller('users')
export class UserController {
  // 不使用装饰器 — 自动记录日志
  @Post()
  async create(@Body() dto: CreateUser) {
    return this.userService.create(dto)
  }

  // 添加描述,记录请求和响应
  @Put(':id')
  @Operation({
    description: '更新用户信息',
    request: true,
    response: true
  })
  async update(@Param('id') id: string, @Body() dto: UpdateUser) {
    return this.userService.update(id, dto)
  }

  // 禁用日志
  @Get('health')
  @Operation({ disabled: true })
  healthCheck() {
    return { status: 'ok' }
  }
}

配置选项

OperationModuleOptions(模块配置)

选项类型默认值说明
enabledbooleantrue是否启用
excludePathsstring[][]排除的路径(支持通配符 *
requestbooleanfalse默认是否记录请求参数
responsebooleanfalse默认是否记录响应结果
idFieldstring'id'JWT payload 中的用户 ID 字段名
nameFieldstring'name'JWT payload 中的用户名字段名

OperationOptions(装饰器配置)

选项类型默认值说明
descriptionstring-操作描述
disabledbooleanfalse禁用此方法的日志
requestboolean-是否记录请求参数(优先于全局配置)
responseboolean-是否记录响应结果(优先于全局配置)

用户信息提取

从 JWT payload 中自动提取用户信息:

用户 ID 优先级sub > userId > payload[idField]

用户名优先级username > payload[nameField]

日志输出示例

基础日志

json
{
  "traceId": "1234567890123456789",
  "path": "/users",
  "httpMethod": "POST",
  "userId": "123",
  "username": "admin",
  "status": "success",
  "statusCode": 200,
  "duration": "45ms"
}

带描述和参数

json
{
  "traceId": "1234567890123456789",
  "description": "更新用户信息",
  "path": "/users/123",
  "httpMethod": "PUT",
  "params": {
    "username": "newuser",
    "password": "***",
    "email": "user@example.com"
  },
  "status": "success",
  "statusCode": 200,
  "duration": "45ms"
}

失败请求

json
{
  "traceId": "1234567890123456790",
  "path": "/users/123",
  "httpMethod": "DELETE",
  "status": "failure",
  "statusCode": 500,
  "duration": "12ms",
  "error": { "message": "用户不存在", "name": "Error" }
}

安全特性

  • 自动脱敏:自动隐藏 passwordtokensecretaccessTokenrefreshTokenapiKey 字段
  • 异步记录:不阻塞请求
  • 唯一追踪:每个操作生成唯一 traceId(雪花 ID)
  • 堆栈分离:错误堆栈与操作日志分离,通过 traceId 关联

日志字段说明

字段说明
traceId操作唯一 ID(雪花 ID),用于日志追踪
description操作描述(来自 @Operation 装饰器)
path请求路径
httpMethodHTTP 方法
userId用户 ID(JWT)
username用户名(JWT)
params请求参数(脱敏后)
result响应结果
statussuccess / failure
statusCodeHTTP 状态码
duration执行耗时
error错误信息(不含 stack)

最佳实践

  1. 全局启用 + 白名单排除:全局启用拦截器,用 excludePaths 排除频繁调用的接口(如 /health/metrics
  2. CUD 加描述:创建、更新、删除操作加 @Operation({ description }) 描述,查询接口可以不加
  3. 按需记录参数:仅在 update / delete 等关键操作启用 request: true,避免日志量过大
  4. 利用 traceId:通过雪花 ID traceId 关联请求日志和错误堆栈,方便线上排查

相关文档