最可靠做法是在每个server块中显式配置access_log和error_log指令,实现按域名分离日志;需使用绝对路径、提前创建目录并赋权,log_format必须定义在http块顶层,修改后须nginx -t验证再reload。

直接在每个 server 块里配 access_log 和 error_log,就能让不同域名写入各自日志文件——这是最可靠、最易维护的做法,不需要正则匹配或变量拼接。
每个 server 块必须显式声明 access_log 和 error_log
很多人误以为只要在 http 块里定义了全局 access_log,子 server 就会自动继承并按域名分流。实际不是:Nginx 的日志指令不支持“自动按 server_name 分离”,它只认你写死的路径。
-
access_log和error_log是“可继承但不可动态派生”的指令——子server不写,就用上级(比如http块)的;写了,就完全覆盖,不再混入其他站点日志 - 如果某个
server没写access_log,它的请求会落到全局日志里,和其他域名日志搅在一起,排查时根本分不清来源 - 路径必须是绝对路径,比如
/var/log/nginx/siteA/access.log,不能写相对路径logs/siteA.log(Nginx 会按配置文件所在目录解析,极易出错)
日志目录权限和 owner 必须提前配好
即使 server 块里写了 access_log /var/log/nginx/siteB/access.log,Nginx 启动时也会静默失败——如果 /var/log/nginx/siteB/ 目录不存在,或 Nginx worker 进程(通常是 www-data 或 nginx 用户)没写入权限,日志就根本不会生成,也不会报错到 error.log 中。
PyCharm 2026.2.0.1 Linux版提供 JetBrains 官方 2026.2.0.1 版本安装包,适合需要指定 PyCharm 版本进行 Python 项目开发、运行和调试的用户。
- 先手动创建目录:
sudo mkdir -p /var/log/nginx/siteB - 确认 Nginx 运行用户(查
ps aux | grep nginx或nginx -V 2>&1 | grep user),然后赋权:sudo chown www-data:www-data /var/log/nginx/siteB - 别依赖
logrotate自动建目录——它只管轮转已有文件,不负责初始化
log_format 定义要放在 http 块顶层,不能嵌套在 server 里
自定义日志格式(比如加 $host 或 JSON 结构)必须在 http 块内、所有 server 外定义,否则 Nginx 会报 "log_format" directive is not allowed here 错误。
- 正确位置:
http { log_format api_json '{"time":"$time_iso8601","host":"$host","status":$status}'; server { ... access_log /var/log/nginx/api.log api_json; } } - 错误写法:把
log_format放进某个server块里,会导致 reload 失败 - 多个站点共用一个 format 没问题;想差异化(如 admin 站点加
$remote_user),就定义多个 format 名,再分别引用
reload 前务必检查语法,避免日志中断
改完日志路径后直接 systemctl reload nginx 很危险:如果路径写错、权限没给、或 log_format 名拼错,Nginx 会拒绝重载,但旧进程还在跑,而新配置里的日志路径始终不会生效——你以为切过去了,其实还在往老地方写,或者干脆不写。
- 每次修改后先运行:
sudo nginx -t,确认输出test is successful - 检查日志文件是否真的被新进程打开:
sudo lsof -nP -a -p $(cat /var/run/nginx.pid) -d cwd,txt | grep log - 上线后立刻发一次请求(
curl -I http://siteB.com),再tail -f /var/log/nginx/siteB/access.log看有没有实时写入
真正容易被忽略的是:日志路径写对了、权限也给了,但忘了在 server 块里删掉原来的全局 access_log 指令,导致重复写入——同一个请求既写进 /var/log/nginx/access.log,又写进 /var/log/nginx/siteB/access.log。这种冗余不仅浪费磁盘,还会干扰后续的日志分析工具识别来源。务必确保每个 server 只有一条 access_log 指令,且明确指向其专属路径。










