最直接有效的方式是在每个server块中显式配置access_log指令并指定绝对路径;需在http块顶层定义log_format,提前创建日志目录并赋权,配置后须nginx -t验证语法并reload生效。

最直接有效的方式,是在每个 server 块里显式写 access_log 指令,并指定专属绝对路径。Nginx 不会自动按域名拆分日志,全局配置只起默认作用,不触发分流。
每个 server 块单独配 access_log
在对应虚拟主机的 server 块内添加一行:
- 用绝对路径,例如:
access_log /var/log/nginx/www.example.com.access.log main; - 路径中建议含域名或项目名,如
api.example.com.access.log,方便识别 - 若某站点无需记录访问日志,直接写:
access_log off; - 不要用相对路径(如
logs/site.log),Nginx 会按配置文件所在目录解析,易出错
复用统一定义的 log_format
自定义日志格式必须放在 http 块顶层,不能塞进 server 里,否则 reload 会失败:
- 在
http块开头定义,例如:log_format upstream '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for";' - 然后在各
server块中引用:access_log /var/log/nginx/api.example.com.access.log upstream; - 这样既保持格式一致,也便于后期统一调整
提前建目录并赋权
就算配置写对了,如果父目录不存在或 Nginx 进程没权限写入,日志根本不会生成,且不会报错到 error.log:
- 手动创建目录:
sudo mkdir -p /var/log/nginx/www.example.com - 查清 Nginx 运行用户(常用
nginx或www-data),再赋权:sudo chown nginx:nginx /var/log/nginx/www.example.com - logrotate 不负责建目录,只轮转已有文件
验证是否生效
改完配置后必须验证,不能跳过:
- 先测试语法:
sudo nginx -t,看到 syntax is ok 才继续 - 再平滑重载:
sudo nginx -s reload - 用
curl -H "Host: www.example.com" http://127.0.0.1模拟请求,立刻检查对应日志文件是否有新内容 - 注意默认
server:未匹配到任何server_name的请求会落到第一个server块,要确保它也有明确日志配置或设为access_log off;











