MongoDB Enterprise版才支持审计功能,社区版即使配置auditLog也会被静默忽略;需在mongod.conf中security段配置auditLog路径及JSON格式filter,且param.ns等字段名大小写敏感、必须带param.前缀,多集合用$in,复杂操作需$or组合条件,并注意分片集群须在各shard单独配置。

只有 MongoDB Enterprise 版本支持审计功能,社区版无法启用 auditLog;过滤器必须是合法 JSON 格式,且字段名(如 atype、param.ns)大小写敏感,写错就完全不生效。
确认审计功能可用并启用基础配置
先验证版本:运行 mongod --version,输出中必须含 Enterprise 字样。社区版即使加了 auditLog 配置,启动时会静默忽略,无报错也无日志。
在 /etc/mongod.conf 的 security 段下添加最小可用配置:
security:
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/audit.json
注意:path 对应目录需提前创建并赋予 mongodb:mongodb 权限,否则 systemctl restart mongod 会失败且报错 Permission denied。
用 param.ns 精确匹配特定集合的操作
param.ns 是审计日志中表示“命名空间”的字段,格式为 数据库名.集合名,比如 myapp.users 或 admin.system.users。它只出现在 atype 为 find、insert、update、delete、createCollection 等操作中。
要只记录对 orders 集合的变更,过滤器应写成:
filter: '{ "param.ns": "mydb.orders" }'
若需匹配多个集合,用 $in:
filter: '{ "param.ns": { "$in": ["mydb.orders", "mydb.payments"] } }'
常见错误:
- 漏掉数据库前缀,写成
"param.ns": "orders"→ 不匹配任何事件 - 用正则但没加
$regex,如"param.ns": "mydb.*"→ 语法错误,服务无法启动 - 误用
ns(少param.前缀)→ 过滤器无效,仍记录全部操作
组合过滤避免漏记或冗余
单靠 param.ns 可能不够:比如 dropCollection 操作的 param.ns 是空的,得靠 param.collection;而 authCheck 类操作压根没有 param 字段。
记录 mydb.orders 的所有读写+删表操作,推荐这样写:
filter: '{
"$or": [
{ "param.ns": "mydb.orders" },
{ "atype": "dropCollection", "param.collection": "orders" }
]
}'
性能提示:审计过滤器在内核层执行,$or 和嵌套条件不会明显拖慢主流程,但过度复杂的正则(如 $regex + $options: "i")可能轻微增加 CPU 开销。
务必避开这些坑:
- 在 filter 中混用单引号和双引号导致 YAML 解析失败(配置文件里整个 filter 值必须用单引号包裹)
- 把
filter写在auditLog外层(如跟destination并列)→ 配置被忽略 - 修改 filter 后未重启
mongod(runtime 配置需额外开启auditLog.runtimeConfiguration: true,且不能同时设filter)
验证过滤器是否真正生效
别只看日志文件有没有生成,要确认内容是否符合预期:
执行一条目标操作:db.orders.insertOne({x:1}),再执行一条非目标操作:db.users.insertOne({y:1})。
然后实时观察日志:
tail -f /var/log/mongodb/audit.json | grep '"param\.ns"\s*:\s*"mydb\.orders"'
如果只看到第一条的记录,说明过滤成功;如果两条都出现,大概率是 filter 语法错误或位置不对。此时检查 journalctl -u mongod -n 50,MongoDB 启动失败时会在 systemd 日志里明确报出 Failed to parse audit filter 类错误。
最易被忽略的一点:分片集群中,mongos 节点上的 auditLog 配置仅记录路由层事件(如 query),真正的集合级操作日志必须从每个 shard 的 mongod 上采集 —— 过滤器得分别配到每个分片节点上。


















