nginx可通过$server_name、$host或map指令将虚拟主机标识写入日志:①直接在log_format中用$server_name显示首个server_name值;②用$host记录实际请求host头,适配泛域名;③用map对$host标准化并打业务标签。

Nginx 本身不支持直接用 server_name 作为日志的“标签”字段写入日志内容,但可以通过变量和配置组合,把 server_name 的值(或其等效含义)体现在日志中,用于区分不同虚拟主机的请求来源。关键在于:$server_name 是只读变量,不能直接赋值,但它可在 log_format 中使用,前提是当前请求已匹配到某个含 server_name 的 server 块。
下面分三类实用方式说明:
直接在 log_format 中使用 $server_name
适用于每个 server 块独立配置、且 server_name 值固定明确的场景。
- 在
http块中定义日志格式(注意:$server_name此处取的是该server块中server_name指令的第一个名称):log_format with_server_name '$time_local | $server_name | $remote_addr | "$request" | $status';
- 在对应
server块中启用:server { listen 80; server_name example.com www.example.com; access_log /var/log/nginx/example-access.log with_server_name; # … 其他配置 }✅ 效果:日志每行开头会显示
example.com(即server_name列表首个值),可用于快速识别归属站点。
⚠️ 注意:若 server_name *.example.com;,$server_name 恒为 *.example.com,无法体现实际访问的子域名(如 api.example.com),此时应改用 $host。
用 $host 替代 $server_name 实现更准确的域名标识
$host 来自请求头 Host 字段,能真实反映客户端所访问的域名,适合多子域共用一个 server 块的情况。
- 示例(泛域名配置):
server { listen 80; server_name *.example.com; log_format by_host '$time_local | $host | $remote_addr | "$request" | $status'; access_log /var/log/nginx/host-based.log by_host; }✅ 请求
api.example.com和admin.example.com都会进入同一server块,但日志中$host分别记录为api.example.com和admin.example.com。
用 map 预处理 $host 实现标准化 + 标签化
当需要清洗域名(如统一小写、过滤非法字符、合并 www/non-www)、或按规则打业务标签(如 partner-a、internal),推荐用 map。
- 在
http块顶层添加:map $host $site_tag { default "unknown"; ~^www\.(.+)$ $1; ~^api\.example\.com$ "api"; ~^docs\.example\.com$ "docs"; example.com "main"; } log_format tagged '$time_local | $site_tag | $host | $request | $status'; - 在
server块中引用:access_log /var/log/nginx/tagged-access.log tagged;
✅ 日志中
$site_tag字段将输出api、docs、main等可读性强的业务标签,便于后续分析或归档。
不复杂但容易忽略











