分片集群审计日志需为每个mongod实例(shard、config server)单独配置auditLog,mongos不支持;filter须用param.ns精确匹配,避免日志爆炸;logRotate需逐节点执行,磁盘空间与权限必须提前保障。

分片集群里开审计日志,不是配一次就全局生效——每个 mongod 实例(包括 config server、shard replica set 的所有节点、甚至 mongos)都得单独处理,漏一个就缺一块日志。
auditLog 必须在每个 mongod 配置中显式声明
分片集群没有“中心化审计开关”。mongos 不记录操作日志(它只路由),真正执行写/读/删的是各个 shard 和 config server 上的 mongod 进程。所以:
- 每个 shard 节点的配置文件(如
shard1-27018.conf)里必须加auditLog段,不能只配在 mongos 或某个 config 节点上 - config server 副本集的每个成员也必须配,否则创建集合、启用分片等元数据操作就没了审计痕迹
-
mongos进程不支持auditLog配置项,加了会启动失败,直接忽略 - 示例配置片段(放在 shard 节点的 .conf 中):
auditLog: destination: file format: BSON path: /var/log/mongodb/shard1-audit.bson
filter 参数要按命名空间精确控制,避免日志爆炸
分片集群里操作分散在多个数据库和集合,全量审计极易打爆磁盘。用 filter 锁定关键目标最实际:
- 只审特定集合:比如只记录
orders和payments的变更,配置为filter: '{ "param.ns": { "$in": ["myapp.orders", "myapp.payments"] } }' - 千万别漏
param.前缀——写成"ns": "myapp.orders"完全无效 - 不要用正则除非真需要,
"param.ns": { "$regex": "myapp\.(orders|payments)" }虽可行,但解析开销大,且易因转义出错导致 mongod 启动失败 - 高频
find查询(比如监控轮询)也会进审计日志,若不加过滤,filter里建议显式排除:'{ "param.ns": { "$in": [...] }, "atype": { "$ne": "find" } }'
logRotate: "audit" 命令对分片集群是逐节点手工操作
审计日志翻转无法靠配置自动触发,db.adminCommand({ logRotate: "audit" }) 只作用于当前连接的 mongod 实例:
- 你连到 shard1 主节点执行,只转
shard1-audit.bson;config server 上的日志还在疯长 - 副本集内从节点不会同步这个动作,必须分别连上去各执行一次
- 生产环境别手动敲——写个脚本循环遍历所有
mongod地址(含 configsvr 端口),用mongosh --eval批量触发 - 更稳的方式是设
destination: syslog,再用rsyslog+logrotate管理,但注意logrotate配置里必须带copytruncate(因为 syslog 进程一直 hold 着文件句柄,不能 rename)
auditLog.path 的权限与磁盘空间是最大隐患
审计日志增长速度远超普通日志,尤其开了 update 或 find 审计后:
-
auditLog.path所在分区磁盘写满 →mongod将静默丢弃后续审计事件,不报错、不告警、不阻塞业务,但安全审计链就断了 - 确保运行
mongod的用户对路径有写权限,且 SELinux/AppArmor 没拦截(常见于 CentOS/RHEL) - 建议把审计日志路径和数据目录分开挂载,避免 DB 写满连带审计失效
- 上线前务必用
du -sh /var/log/mongodb/+df -h核实可用空间,留至少 20% 缓冲
真正麻烦的不是怎么开,而是怎么保证所有节点日志持续可写、可轮转、可检索——分片集群里少配一个 config server 节点的 auditLog,或者某台 shard 机器磁盘悄悄满了,问题可能半年都发现不了。

















