auditlog启动失败主因是authorization未启用,mongodb 5.0+强制要求security.authorization: enabled与auditlog配置必须同时存在;常见问题包括副本集节点授权不一致、管理员用户未预先创建、auditlog.path权限不足或格式/destination配置不当,且配置不支持运行时重载,须滚动重启生效。

auditLog 启动失败:一定是 authorization 没开
直接加 auditLog 配置却启动报错?错误信息大概率是:Failed to start audit log: Authorization must be enabled when auditLog is configured。这不是配置写错了,而是 MongoDB 5.0+ 强制要求——auditLog 和 security.authorization: enabled 必须同时存在,缺一不可。
常见踩坑点:
- 只在 PRIMARY 节点开了
authorization,SECONDARY 或 arbiter 没配,整个副本集启动失败 - 先配了
auditLog再创建管理员用户,结果 mongod 启动时因鉴权未就绪而拒绝加载审计模块 - 用
mongod --config单点启动测试,绕过副本集同步校验,但上线后 PRIMARY 拒绝该节点加入,报NodeNotFound
auditLog.path 和 format 怎么选才不翻车
auditLog.path 必须指向一个 mongod 进程有读写权限的普通文件路径,不能是 /dev/stdout、/proc/self/fd/1 或 socket 文件。推荐用绝对路径如 /var/log/mongodb/audit.log,并提前执行:sudo chown mongodb:mongodb /var/log/mongodb/ && sudo chmod 755 /var/log/mongodb/。
auditLog.format 只建议设为 JSON:
- BSON 格式需额外解码工具(如
bsondump),日志系统(Filebeat/Fluentd)原生不支持 -
destination: syslog在 5.0 中已被官方标记为not recommended,实测丢事件概率高 - 别把
path指向 NFS 或低 IOPS 的云盘——审计日志写入是同步阻塞的,卡住会影响主流程响应
filter 写太宽会拖慢集群,写太窄又漏关键行为
审计不是“全量打开”就完事。filter 是 JSON 字符串,必须严格按语法嵌套,且只在启动时加载——改完就得滚动重启节点。
实用组合示例(写入 mongod.conf 时注意缩进和引号):
filter: '{ "atype": { "$in": ["authCheck", "createUser", "dropUser", "update", "delete", "find"] }, "ns": { "$in": ["admin.system.users", "myapp.users", "myapp.transactions"] }, "param": { "$exists": true } }'
说明:
-
"find"必须配合"param": {"$exists": true},否则只记录空查询,看不到实际条件 -
update不记录字段级变更,只记操作本身;如需完整变更上下文,得靠应用层先findOne或接change stream - 避免用
{"atype": "all"},高频业务下 QPS 下降可达 15%,尤其带复杂$lookup的聚合查询
副本集必须滚动重启,不能只改配置再 reload
mongod 不支持运行时重载 auditLog 配置。哪怕你用 systemctl reload mongod,也不会生效——它只会 reload systemLog 等少数项。
正确顺序(以三节点副本集为例):
- 连上 SECONDARY A,执行
rs.stepDown()(如果它是 PRIMARY) - 停掉该节点:
sudo systemctl stop mongod - 修改其
/etc/mongod.conf,确保security.authorization: enabled+auditLog全部就位 - 启动:
sudo systemctl start mongod,等rs.status().members[n].stateStr === "SECONDARY" - 重复以上步骤处理 SECONDARY B
- 最后处理原 PRIMARY:先
rs.stepDown(),停服、改配置、启动,再等它恢复为 SECONDARY,最后手动rs.reconfig(...)让它重新参选
每节点启动后务必验证:db.adminCommand({getCmdLineOpts: 1}) 输出里要有 auditLog 字段,且无 warning;再执行一条 db.runCommand({listDatabases: 1}),立刻 tail -f /var/log/mongodb/audit.log 看是否落盘。
最容易被忽略的是 filter 里的 JSON 字符串转义和副本集所有节点配置一致性——差一个空格或大小写,SECONDARY 就可能拒绝同步,PRIMARY 日志里只打 NodeNotFound,根本不会提示是 auditLog 配置不匹配。











