Nginx自定义日志中嵌入主机名和集群标识,需用内置变量$hostname和map指令定义$cluster_id,并在log_format中引用;map须置于http块顶层,log_format在其后定义,重启后生效。

在 Nginx 自定义日志格式中嵌入服务器主机名和集群标识,核心是使用内置变量 $hostname 和自定义变量(如通过 map 或 set 指令定义),再将它们引入 log_format。
使用 $hostname 获取本机主机名
Nginx 内置变量 $hostname 会自动解析为运行 Nginx 的系统主机名(由 gethostname() 返回),无需额外配置。直接在 log_format 中引用即可:
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$hostname'; # ← 这里插入主机名添加集群标识(如 cluster-a、prod-us-east)
集群标识没有内置变量,需手动定义。推荐用 map 指令在 http 块中统一声明,便于多 server 复用:
http {
map $host $cluster_id {
default "unknown";
~^.*\.prod-us-east\.example\.com$ "prod-us-east";
~^api-staging\..*$ "staging-west";
~^backend-01\..*$ "cluster-a";
}
<pre class='brush:php;toolbar:false;'>log_format main '... $hostname $cluster_id';}
也可以用更稳妥的方式——基于主机名匹配(避免依赖 $host,因它来自请求头,可能被伪造):
map $hostname $cluster_id {
"web01-prod" "prod-us-east";
"web02-prod" "prod-us-east";
"web01-staging" "staging-west";
default "unknown";
}确保变量在日志中生效的要点
- map 必须定义在 http 块顶层,不能放在 server 或 location 内;
- log_format 要在 map 之后定义,或至少保证变量已声明;
- 若用
set $cluster_id "xxx",需放在 server 或 location 中,但不推荐——会导致每个请求都执行,且无法在 log_format 中跨作用域引用; - 重启或重载 Nginx 后,新日志行才会包含这些字段,旧日志不受影响。
验证与调试建议
临时加一条最简日志格式快速验证:
log_format debug '$hostname | $cluster_id | $remote_addr'; access_log /var/log/nginx/debug.log debug;
然后访问一次,检查日志输出是否符合预期。确认无误后,再合并进主日志格式。


















