要实现nginx日志按虚拟主机分组统计,需先配置log_format包含$host字段,再用awk等工具按首字段聚合,或用goaccess/awstats生成可视化报表;日常推荐$host而非$server_name。

要实现 Nginx 日志按虚拟主机(即 server_name)分组统计,核心思路是:**从 access 日志中提取 server_name 对应的域名字段,并按该字段聚合分析**。Nginx 默认 access log 不直接记录 server_name,需先配置日志格式使其包含该信息。
1. 修改 Nginx 配置,让日志包含 server_name
Nginx 的 log_format 支持变量,$host 或 $server_name 可用于标识请求所属虚拟主机:
-
$host:取自请求头 Host 字段(更贴近实际访问域名,推荐) -
$server_name:匹配当前 server 块的 server_name 指令值(静态、精确,但无法反映泛域名或未匹配时的真实 Host)
在 http 块中定义带 host 的日志格式:
log_format host_combined '$host $remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';然后在各 server 块或全局 access_log 中启用它:
access_log /var/log/nginx/access.log host_combined;
2. 使用命令行工具快速分组统计(推荐初筛)
假设日志格式已含 $host 且每行首字段即为域名,可用以下命令统计各域名请求数:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr如需统计状态码分布,可扩展:
awk '{print $1, $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20说明:$1 是 host,$9 是 status(字段序号需根据实际 log_format 调整,可用 head -1 access.log 查看对齐)
3. 用 GoAccess 或 AWStats 实现可视化分组报表
适合需要长期监控或图形化展示的场景:
-
GoAccess:轻量实时,支持自定义日志格式。启动时指定
--log-format匹配你的 host_combined 格式,并用--real-time-html输出动态页面 -
AWStats:需配置
LogFormat和HostAliases,将%host设为主键,生成按 host 分组的流量、访客、404 等报表
二者均能导出 CSV,方便进一步用 Excel 或脚本做多维分析(如 “每个 host 的 top URL”、“各 host 的 5xx 比例”)。
4. 进阶:按 server_name 精确分组(非 Host 头)
若需严格按 Nginx 配置中的 server_name(而非客户端发的 Host),需借助 Lua 模块或日志预处理:
- 使用
nginx-lua在 log_by_lua_block 中写入ngx.var.server_name到自定义变量,再输出到日志 - 或写一个简单脚本,在切割日志后,根据 IP+时间+端口反查当前匹配的 server 块(复杂,仅特殊审计场景适用)
日常运维中,$host 已足够反映业务维度的虚拟主机访问情况,且兼容性更好。











