ToolJet 审计日志(Audit Logs)完全指南:事件追踪、过滤筛选、日志落盘与敏感信息脱敏
【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet
导读
本文基于 ToolJet 企业版(Enterprise Edition)的审计日志功能撰写,系统讲解 ToolJet 如何自动记录账号内每一位用户在何时、何地、对何种资源执行了何种操作(含 IP 地址等溯源信息),并深入拆解日期范围查询、多维过滤、日志字段语义、日志文件落盘与轮转、敏感信息脱敏等企业合规场景下的核心能力。读完本文,你将掌握审计日志的完整使用链路:从界面查询与过滤,到通过LOG_FILE_PATH、LOGGER_REDACT、AUDIT_LOGS_RETENTION_PERIOD等环境变量配置落盘、脱敏与保留策略,并能理解其背后的服务端实现原理。
前置说明:审计日志属于付费功能(Paid feature),需要 ToolJet 企业版(EE)许可证支持;社区版(CE)不提供该能力。
一、什么是 ToolJet 审计日志
审计日志(Audit Log)是 ToolJet 账号内所有活动(activities)的报告。系统会自动捕获并展示事件,记录"谁(who)在何时(when)、何地(where)执行了什么活动(what)",并附带 IP 地址等附加信息。
从源码结构看,审计日志在服务端被建模为一个独立的数据实体:server/src/entities/audit_log.entity.ts中定义了audit_logs表,包含user_id、organization_id、resource_id、resource_name、resource_type、action_type、ip_address、metadata、created_at等核心列,并与User、Organization实体建立多对一关联。这意味着每条审计事件都可以追溯到具体的用户与组织,为安全审计与合规取证提供了数据基础。
在模块架构上,审计日志由server/src/modules/audit-logs/module.ts(AuditLogsModule)承载,并通过server/src/modules/app/loader.ts在服务启动时作为动态模块按需加载;只有设置了LOG_FILE_PATH环境变量时,日志落盘模块LogToFileModule才会被注册(见下文"日志文件"一节)。
二、查询审计日志:日期范围与分页
Date Range(日期范围)
在审计日志页面顶部,可以使用**范围选择器(range picker)**按指定日期与时间范围检索事件:
- 默认加载:系统首次进入页面时,默认加载最近24 小时的日志;
- 最大范围:
from与to两个日期之间可指定的最大跨度是30 天。
这个 30 天的上限并非写死在前端,而是由许可证决定的:在server/src/modules/licensing/guards/auditLog.guard.ts中,服务端会校验to与from的差值(differenceInDays),若超过许可证允许的最大天数(maxDurationForAuditLogs),则抛出 HTTP 451 异常:"You can only access logs for a maximum duration of N days. Please adjust your time range."。而maxDurationForAuditLogs来源于许可证数据中的auditLogs.maximumDays(见server/src/modules/licensing/configs/LicenseBase.ts),最终通过GET /api/audit-logs/max-duration接口(见server/src/modules/licensing/controllers/audit-logs.controller.ts)暴露给前端。
Pagination(分页)
页面底部的分页组件支持翻页浏览,每页最多展示 7 条日志。
从server/test/modules/audit-logs/e2e/audit-logs.spec.ts的端到端测试可以看到,列表接口GET /api/audit-logs支持page与perPage查询参数,响应体包含audit_logs数组与meta元信息(total_pages、total_count、current_page等),且返回条数不超过perPage:
// 端到端测试片段(server/test/modules/audit-logs/e2e/audit-logs.spec.ts) await request(app.getHttpServer()) .get('/api/audit-logs') .query({ page: 1, perPage: 5, ...recentTimeRange() }) .expect(200); // meta: { total_pages, total_count, current_page: 1 } // audit_logs.length <= 5三、过滤审计日志(Filter Audit Logs)
你可以依据以下维度对审计事件进行过滤。
Select Users(按用户筛选)
从下拉列表中选择某个特定用户,即可查看该用户的全部活动记录。
Select Apps(按应用筛选)
下拉列表会展示当前账号关联的所有应用(Apps)。选择某个应用后,日志将被过滤为与该应用相关的事件。
Select Resources(按资源类型筛选)
资源(Resources)下拉中可按资源类别过滤,各资源类别及其对应的事件如下:
| Resources | 说明 |
|---|---|
| User | 过滤所有用户事件,如USER_LOGIN、USER_SIGNUP、USER_INVITE、USER_INVITE_REDEEM。 |
| App | 过滤所有应用事件,如APP_CREATE、APP_UPDATE、APP_VIEW、APP_DELETE、APP_IMPORT、APP_EXPORT、APP_CLONE。 |
| Data Query | 过滤与数据查询相关的事件,如DATA_QUERY_RUN。 |
| Group Permission | 过滤所有与组权限(Group Permissions)相关的事件,包括GROUP_CREATE、GROUP_UPDATE、GROUP_DELETE。 |
| App Group Permission | 在每个用户组内,可以为应用设置读或编辑权限,这类权限变更事件被记录为 App Group Permissions。 |
从实现上看,资源类型对应服务端server/src/modules/app/constants/modules.ts中定义的MODULES枚举,audit_logs表的resource_type列即采用该枚举类型(见server/src/entities/audit_log.entity.ts第 23 行)。测试中还验证了GET /api/audit-logs/resources接口会按资源类别(如 USER、APP 等)返回可用的资源类型键值对象。
Select Actions(按动作类型筛选)
动作(Actions)下拉支持按具体的事件动作类型过滤,完整的事件清单及触发时机如下:
| Actions | 说明 |
|---|---|
| USER_LOGIN | 每次用户登录时记录。 |
| USER_SIGNUP | 每次产生新注册时记录。 |
| USER_INVITE | 从Manage Users部分邀请用户进入账号时,每次发送邀请都会审计记录。 |
| USER_INVITE_REDEEM | 每次邀请被兑现(redeemed)时记录。 |
| APP_CREATE | 用户创建新应用时记录。 |
| APP_UPDATE | 执行应用重命名、将应用设为公开、编辑分享链接或部署应用等操作时记录。 |
| APP_VIEW | 有人查看已发布(launched)的应用时记录(公开应用不计入)。 |
| APP_DELETE | 用户从仪表盘删除应用时记录。 |
| APP_IMPORT | 用户导入应用时记录。 |
| APP_EXPORT | 应用被导出时记录。 |
| APP_CLONE | 对已有应用创建克隆副本时记录。 |
| DATA_QUERY_RUN | 添加数据源、创建查询、或在查询编辑器中/已发布应用中运行查询时记录。 |
| GROUP_PERMISSION_CREATE | 创建用户组时记录。 |
| GROUP_PERMISSION_UPDATE | 向组中添加/移除应用或用户,或更新组的权限时记录。 |
| GROUP_PERMISSION_DELETE | 从账号中删除用户组时记录。 |
| APP_GROUP_PERMISSION_UPDATE | 每向用户组添加一个应用,都可设置View(查看)或Edit(编辑)权限;当这些权限被更新时记录该事件。默认情况下,用户组对应用的权限为View。 |
事件的实际写入链路可参考server/src/modules/app/interceptors/response.interceptor.ts:响应拦截器在请求处理完成后,读取存放于响应上下文中的审计字段(response.locals),通过事件发射器(eventEmitter.emit('auditLogEntry', ...))异步触发审计日志落库;只有当请求成功(或该特性显式允许记录失败事件)时才会写入,失败时记录错误日志而不中断业务请求。
四、理解日志信息(Understanding Log Information)
每条审计日志记录包含以下属性字段,对应audit_logs表的列结构:
| 属性 | 说明 |
|---|---|
| action_type | 该事件被记录的动作类型,具体取值参见上文 Select Actions 一节。 |
| created_at | 事件被记录的日期与时间。 |
| id | 每条日志事件被分配的唯一事件 ID。 |
| ip_address | 记录该事件来源的 IP 地址。 |
| metadata | 元数据包含两个子属性:tooljet_version(记录事件所用 ToolJet 版本)与user_agent(记录所用设备与浏览器信息)。 |
| organization_id | ToolJet 中每个组织有唯一 ID,事件发生时会被记录。 |
| resource_id | 不同的资源有各自的 ID,这些 ID 在资源创建时被分配。 |
| resource_name | 显示事件所涉及资源的名称,例如创建或删除应用时会显示该应用的名称。 |
| resource_type | 事件所涉及资源的类型。 |
| user_id | ToolJet 中每个用户账号有唯一 ID,事件发生时会被记录。 |
补充说明:实体定义中还包含resource_data列(JSON 类型,用于存放资源快照数据),AuditLogFields接口(server/src/modules/audit-logs/types/index.ts)中则声明了resourceData、userAgent、organizationIds等可选字段,说明部分审计事件的元信息是按需写入的。
五、日志文件:落盘、轮转与脱敏
Log File(日志文件)
当在环境变量中指定了日志文件路径后,ToolJet 会在该路径创建一个包含全部审计日志数据的日志文件。该文件每天轮转(rotate)一次,并且每当产生新的审计日志时动态实时更新。
从加载逻辑看(server/src/modules/app/loader.ts第 188-192 行),LogToFileModule仅在设置了LOG_FILE_PATH环境变量时才作为动态模块被加载,属于"按需启用"的可选能力。
关于syslog 日志文件生成的详细配置,可参考 Setup Log File Generation (Rsyslog) 一文。
Log Rotation(日志轮转)
日志文件被配置为按天轮转:即每天都会生成一个新的日志文件,从而保证审计数据被高效地组织与管理。
Log Redaction(日志脱敏)
ToolJet 实现了日志脱敏机制以保护敏感信息。默认情况下,以下请求/响应头会在日志中被遮蔽(mask):
- authorization
- cookie
- set-cookie
- x-api-key
- proxy-authorization
- www-authenticate
- authentication-info
- x-forwarded-for
上述默认脱敏路径在server/src/modules/app/loader.ts的 pino 日志配置redact.paths数组中逐一声明,且脱敏后的占位符统一为[REDACTED]。
此外,你还可以通过LOGGER_REDACT环境变量指定自定义的额外脱敏字段:
| 变量 | 说明 |
|---|---|
| LOGGER_REDACT | 需要在日志中遮蔽的额外字段的逗号分隔列表(例如:req.headers["x-session-id"],req.headers["x-device-fingerprint"]) |
示例:
LOGGER_REDACT=res.headers["x-rate-limit-remaining"],res.headers["x-request-id"]在server/src/modules/app/loader.ts中可以看到,LOGGER_REDACT的值会被按逗号切分后追加到 pino 的redact.paths数组中(...(process.env.LOGGER_REDACT ? process.env.LOGGER_REDACT?.split(',') : [])),即自定义字段与内置脱敏路径共同生效。
Log File Path(日志文件路径)
日志文件的路径通过环境变量LOG_FILE_PATH定义。需要注意:该路径是相对于机器主目录(home directory)的。例如,若LOG_FILE_PATH设置为hsbc/dashboard/log,则最终日志文件路径结构如下:
homepath/hsbc/dashboard/log/tooljet_log/{process_id}-{date}/audit.log其中:
{process_id}:唯一进程标识符的占位符;{date}:当前日期。
这种"按进程 + 按日期"的结构化路径,保证了审计日志可以按进程与日期双向组织,便于追踪与分析。
| 变量 | 说明 |
|---|---|
| LOG_FILE_PATH | 日志文件的创建路径(例如:tooljet/log/tooljet-audit.log) |
日志文件数据示例
以下为日志文件中的一条审计日志示例(JSON 结构):
{ "level": "info", "message": "PERFORM APP_CREATE OF awdasdawdwd APP", "timestamp": "2023-11-02 17:12:40", "auditLog": { "userId": "0ad48e21-e7a2-4597-9568-c4535aedf687", "organizationId": "cf8e132f-a68a-4c81-a0d4-3617b79e7b17", "resourceId": "eac02f79-b8e2-495a-bffe-82633416c829", "resourceType": "APP", "actionType": "APP_CREATE", "resourceName": "awdasdawdwd", "ipAddress": "::1", "metadata": { "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "tooljetVersion": "2.22.2-ee2.8.3" } }, "label": "APP" }从结构上可以看出:文件中的auditLog对象与数据库实体字段一一对应,message字段则以人类可读的文本形式概括了动作(如PERFORM APP_CREATE OF <应用名> APP),label标记资源类别。
六、审计日志的保留策略与清理机制
除了文档中明确介绍的日期查询、过滤、落盘、轮转与脱敏之外,从服务端源码还可以看到审计日志具备自动清理机制,这一点对长期运维至关重要。
server/src/modules/audit-logs/scheduler.ts中的AuditLogsClearScheduler使用@Cron(CronExpression.EVERY_DAY_AT_2AM)声明了一个每天凌晨 2:00执行的定时任务:
- 通过环境变量
AUDIT_LOGS_RETENTION_PERIOD控制保留天数,默认值为 90 天; - 若设置为
0,则跳过清理(保留全部日志); - 否则删除
created_at早于"当前时间减去保留天数"的所有审计日志记录。
// 核心逻辑(server/src/modules/audit-logs/scheduler.ts,已简化) @Cron(CronExpression.EVERY_DAY_AT_2AM) async handleCron() { const retentionPeriodNum = Number(process.env.AUDIT_LOGS_RETENTION_PERIOD) || 90; if (retentionPeriodNum === 0) return; // 跳过清理 const cutoffDate = new Date(); cutoffDate.setDate(cutoffDate.getDate() - retentionPeriodNum); await dbTransactionWrap((manager) => manager.delete(AuditLog, { createdAt: LessThan(cutoffDate) }) ); }这一机制与页面上的 30 天查询上限相互配合:查询范围上限由许可证决定,而数据库中的历史数据保留时长则由AUDIT_LOGS_RETENTION_PERIOD决定,两者共同构成审计日志的完整生命周期管理。
七、权限与合规要点小结
综合文档与源码,使用审计日志时需注意以下几点:
- 许可证门槛:审计日志是付费(企业版)特性,
server/src/modules/audit-logs/constants/features.ts中VIEW_LOGS与VIEW_RESOURCES两个功能点均绑定LICENSE_FIELD.AUDIT_LOGS许可证字段;能力层(server/src/modules/audit-logs/ability/index.ts)为审计日志授予查看权限。 - 查询窗口:默认加载最近 24 小时日志,
from/to最大跨度为 30 天(受许可证auditLogs.maximumDays约束,超出返回 451)。 - 敏感信息:内置 8 类请求/响应头默认脱敏,可用
LOGGER_REDACT追加自定义脱敏字段。 - 落盘与轮转:设置
LOG_FILE_PATH后启用日志文件(相对主目录路径),按天轮转、实时更新。 - 保留策略:
AUDIT_LOGS_RETENTION_PERIOD控制数据库内日志保留天数(默认 90,设为 0 表示不清理),每天凌晨 2:00 自动执行清理。
相关的核心文件路径如下,供深入阅读:
- 数据实体:server/src/entities/audit_log.entity.ts
- 审计日志模块:server/src/modules/audit-logs/module.ts、server/src/modules/audit-logs/scheduler.ts、server/src/modules/audit-logs/types/index.ts
- 加载与脱敏配置:server/src/modules/app/loader.ts
- 审计事件写入拦截器:server/src/modules/app/interceptors/response.interceptor.ts
- 许可证约束:server/src/modules/licensing/guards/auditLog.guard.ts、server/src/modules/licensing/configs/LicenseBase.ts
- 环境变量总览:docs/docs/setup/env-vars.md
- Syslog 日志配置:docs/docs/how-to/setup-syslog.md
- 端到端测试:server/test/modules/audit-logs/e2e/audit-logs.spec.ts
【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考