GoAccess 日志分析完全指南 / 07 - 过滤与排除
07 - 过滤与排除
7.1 概述
在分析 Web 日志时,经常需要聚焦于特定子集——例如只看某个时间段的访问、排除爬虫流量、过滤特定状态码等。GoAccess 提供了丰富的过滤与排除机制,帮助你从海量日志中快速提取有价值的信息。
原始日志 (100,000 条)
│
├── 排除爬虫 UA → -15%
├── 排除静态资源 → -30%
├── 排除健康检查 → -5%
├── 排除内网 IP → -3%
└── 日期范围过滤 → -20%
│
▼
有效日志 (27,000 条) → 精准分析
7.2 日期范围过滤
7.2.1 指定日期范围
# 只分析 2026 年 5 月的日志
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--date-range=20260501-20260531
# 只分析某一天
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--date-range=20260510-20260510
# 分析最近一周(配合 shell)
START=$(date -d "7 days ago" +%Y%m%d)
END=$(date +%Y%m%d)
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--date-range=${START}-${END}
7.2.2 日期范围格式
日期格式必须与日志中的日期格式一致:
| 日志日期格式 | 过滤日期格式 | 示例 |
|---|---|---|
%d/%b/%Y (10/May/2026) | YYYYMMDD | --date-range=20260501-20260531 |
%Y-%m-%d (2026-05-10) | YYYYMMDD | --date-range=20260501-20260531 |
注意:无论日志中的日期格式如何,
--date-range参数始终使用YYYYMMDD格式。
7.2.3 配合 grep 预过滤
对于更灵活的日期过滤,可以先用 grep 过滤再传给 GoAccess:
# 使用 grep 按日期预过滤
grep "10/May/2026" /var/log/nginx/access.log | \
goaccess --log-format=COMBINED -
# 使用 awk 精确过滤时间段
awk '/10\/May\/2026:1[4-6]/' /var/log/nginx/access.log | \
goaccess --log-format=COMBINED -
# 过滤一个时间范围
awk '/10\/May\/2026/ && /:1[4-6]:/' /var/log/nginx/access.log | \
goaccess --log-format=COMBINED -
7.3 状态码过滤
7.3.1 只分析特定状态码
# 只分析 5xx 错误
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--status-code=500
# 只分析 404 页面
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--status-code=404
# 只分析 4xx 客户端错误
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--status-code=4xx
# 分析所有错误(4xx + 5xx)
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--status-code=4xx \
--status-code=5xx
7.3.2 状态码通配符
GoAccess 支持以下状态码通配方式:
| 模式 | 说明 | 示例 |
|---|---|---|
200 | 精确匹配 | 只匹配 200 |
4xx | 匹配 400-499 | 所有客户端错误 |
5xx | 匹配 500-599 | 所有服务器错误 |
3xx | 匹配 300-399 | 所有重定向 |
7.3.3 排除特定状态码
# 排除 200 请求,只看异常请求
# (使用 grep 预过滤)
grep -v '" 200 ' /var/log/nginx/access.log | \
goaccess --log-format=COMBINED -
# 排除 304(Not Modified)请求
grep -v '" 304 ' /var/log/nginx/access.log | \
goaccess --log-format=COMBINED -
7.3.4 状态码分析实战
# 场景:排查服务器 500 错误
# 1. 先看 500 错误的请求文件分布
grep '" 500 ' /var/log/nginx/access.log | \
goaccess --log-format=COMBINED \
--ignore-panel=REFERRING_SITES \
--ignore-panel=GEO_LOCATION \
--ignore-panel=HOSTS \
--ignore-panel=OS_TOOLS \
--ignore-panel=BROWSERS \
-
# 2. 看 500 错误的 IP 分布
grep '" 500 ' /var/log/nginx/access.log | \
goaccess --log-format=COMBINED \
--sort-panel=HOSTS,BY_HITS \
--ignore-panel=REQUESTED_FILES \
-
7.4 IP 过滤
7.4.1 排除特定 IP
# 排除单个 IP
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude-ip=192.168.1.100
# 排除多个 IP
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude-ip=192.168.1.100 \
--exclude-ip=10.0.0.1 \
--exclude-ip=172.16.0.5
# 排除本地回环地址
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude-ip=127.0.0.1 \
--exclude-ip=::1
7.4.2 排除 IP 范围(CIDR)
GoAccess 不直接支持 CIDR 排除,但可以通过多种方式实现:
# 方法一:使用 grep 过滤整个网段
grep -v -E '^(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.)' \
/var/log/nginx/access.log | \
goaccess --log-format=COMBINED -
# 方法二:使用 iptables/ipset 标记后过滤
# 方法三:使用 AWK 排除多个 IP
awk '
!($1 ~ /^192\.168\./ || $1 ~ /^10\./ || $1 ~ /^172\.(1[6-9]|2[0-9]|3[01])\./)
' /var/log/nginx/access.log | goaccess --log-format=COMBINED -
7.4.3 只分析特定 IP
# 只分析特定 IP 的访问
grep "^192.168.1.100" /var/log/nginx/access.log | \
goaccess --log-format=COMBINED -
# 只分析某个网段
grep "^10.0.0\." /var/log/nginx/access.log | \
goaccess --log-format=COMBINED -
7.4.4 排除自身访问
# 自动获取外部 IP 并排除
MY_IP=$(curl -s ifconfig.me)
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude-ip="${MY_IP}"
7.5 请求排除(正则匹配)
7.5.1 排除特定 URL 模式
# 排除静态资源请求
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude='\.(css|js|jpg|jpeg|png|gif|ico|svg|woff2?|ttf|eot)$'
# 排除健康检查端点
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude='^/(health|status|ping|readyz|livez)'
# 排除 API 请求
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude='^/api/'
# 排除 robots.txt 和 sitemap.xml
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude='^/(robots\.txt|sitemap\.xml|favicon\.ico)'
7.5.2 排除 User-Agent
# 排除常见爬虫
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude='(bot|crawler|spider|slurp|baidu|googlebot|bingbot|yandex)'
# 排除监控工具
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude='(curl|wget|Uptime|Pingdom|NewRelic|Datadog)'
# 排除空 User-Agent
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude='^-$'
7.5.3 多条件排除组合
# 综合排除:静态资源 + 爬虫 + 健康检查 + 自身IP
MY_IP=$(curl -s ifconfig.me)
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude-ip="${MY_IP}" \
--exclude='\.(css|js|jpg|jpeg|png|gif|ico|svg|woff2?|ttf|eot)$' \
--exclude='/(health|status|ping|readyz|livez)' \
--exclude='(bot|crawler|spider|slurp)' \
--exclude='^/(robots\.txt|sitemap\.xml|favicon\.ico)'
7.5.4 正则表达式语法
GoAccess 使用 POSIX 扩展正则表达式(ERE):
| 模式 | 说明 | 示例 |
|---|---|---|
. | 任意字符 | a.c 匹配 abc, a1c |
* | 前一个字符重复 0 次或多次 | ab*c 匹配 ac, abc, abbc |
+ | 前一个字符重复 1 次或多次 | ab+c 匹配 abc, abbc |
? | 前一个字符出现 0 或 1 次 | ab?c 匹配 ac, abc |
^ | 行首 | ^/api 匹配以 /api 开头的行 |
$ | 行尾 | .css$ 匹配以 .css 结尾的行 |
[] | 字符类 | [0-9] 匹配数字 |
| | 或 | a|b 匹配 a 或 b |
() | 分组 | (css|js) 匹配 css 或 js |
7.6 面板忽略
7.6.1 忽略不需要的面板
# 只关注核心指标,忽略不常用的面板
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--ignore-panel=REFERRING_SITES \
--ignore-panel=REFERRING_URLS \
--ignore-panel=GEO_LOCATION \
--ignore-panel=ASN \
--ignore-panel=KEYPHRASES \
--ignore-panel=TLS_VERSIONS
7.6.2 面板名称参考
| 面板名称 | 说明 | 建议 |
|---|---|---|
VISITORS | 独立访客 | 保留 |
REQUESTS | 请求文件 | 保留 |
REQUESTS_STATIC | 静态资源 | 可选 |
NOT_FOUND | 404 页面 | 保留 |
HOSTS | IP 主机 | 保留 |
OS | 操作系统 | 保留 |
BROWSERS | 浏览器 | 保留 |
REFERRING_SITES | 来源站点 | 可忽略 |
REFERRING_URLS | 来源 URL | 可忽略 |
STATUS_CODES | 状态码 | 保留 |
KEYPHRASES | 关键词 | 已废弃,建议忽略 |
GEO_LOCATION | 地理位置 | 可选 |
ASN | ASN | 可忽略 |
TLS_VERSIONS | TLS 版本 | 可忽略 |
7.7 面板排序
7.7.1 指定面板排序方式
# 按访客数排序(默认按请求数)
goaccess access.log --log-format=COMBINED \
--sort-panel=VISITORS,BY_VISITORS
# 按带宽排序
goaccess access.log --log-format=COMBINED \
--sort-panel=REQUESTS,BY_BANDWIDTH
# 多面板排序
goaccess access.log --log-format=COMBINED \
--sort-panel=VISITORS,BY_VISITORS \
--sort-panel=REQUESTS,BY_BANDWIDTH \
--sort-panel=HOSTS,BY_HITS
7.7.2 排序字段
| 排序字段 | 说明 |
|---|---|
BY_HITS | 按请求数排序 |
BY_VISITORS | 按访客数排序 |
BY_DATA | 按数据字段排序(字母/数字顺序) |
BY_BANDWIDTH | 按带宽排序 |
BY_CUMULATIVE_BANDWIDTH | 按累计带宽排序 |
BY_AVGTS | 按平均请求时间排序 |
BY_CUMTS | 按累计请求时间排序 |
BY_MAXTS | 按最大请求时间排序 |
7.8 面板启用与禁用
7.8.1 仅启用特定面板
# 只看访客和状态码
goaccess access.log --log-format=COMBINED \
--enable-panel=VISITORS \
--enable-panel=STATUS_CODES \
--enable-panel=REQUESTS
注意:使用
--enable-panel后,未被明确启用的面板将被隐藏。
7.9 过滤实战场景
场景一:分析真实用户访问(排除爬虫和静态资源)
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--exclude='\.(css|js|jpg|jpeg|png|gif|ico|svg|woff2?|ttf|eot)(\?|$)' \
--exclude='(bot|crawler|spider|slurp|baidu|googlebot|bingbot|yandex|Bytespider|GPTBot)' \
--exclude='/(health|status|ping|readyz|livez)' \
--exclude-ip=127.0.0.1 \
-o real_users.html
场景二:排查 500 错误
# 只分析 500 错误
grep '" 500 ' /var/log/nginx/access.log | \
goaccess --log-format=COMBINED \
--sort-panel=REQUESTS,BY_HITS \
--ignore-panel=GEO_LOCATION \
--ignore-panel=REFERRING_SITES \
--ignore-panel=REFERRING_URLS \
-o 500_errors.html
场景三:分析移动端流量
# 只分析移动设备
grep -iE '(mobile|android|iphone|ipad|windows phone)' \
/var/log/nginx/access.log | \
goaccess --log-format=COMBINED \
--sort-panel=REQUESTS,BY_HITS \
-o mobile_traffic.html
场景四:分析 API 请求
# 只分析 /api/ 开头的请求
grep '"GET /api/\|"POST /api/\|"PUT /api/\|"DELETE /api/' \
/var/log/nginx/access.log | \
goaccess --log-format=COMBINED \
--sort-panel=REQUESTS,BY_HITS \
--ignore-panel=REFERRING_SITES \
-o api_analysis.html
场景五:分析搜索引擎流量
# 只分析来自搜索引擎的流量
grep -iE '(google\.com|bing\.com|baidu\.com|sogou\.com|yandex\.)' \
/var/log/nginx/access.log | \
goaccess --log-format=COMBINED \
--sort-panel=REFERRING_SITES,BY_HITS \
--ignore-panel=HOSTS \
-o search_traffic.html
场景六:分析高峰时段
# 分析 9:00-18:00 工作时间的访问
awk '
/:0[9]:/ || /:1[0-7]:/ || /:18:00/
' /var/log/nginx/access.log | \
goaccess --log-format=COMBINED \
--sort-panel=REQUESTS,BY_HITS \
-o work_hours.html
7.10 组合过滤脚本
#!/bin/bash
# filter_analysis.sh — 组合过滤分析脚本
LOG_FILE="/var/log/nginx/access.log"
OUTPUT_DIR="/var/www/html/analysis"
MY_IP=$(curl -s ifconfig.me 2>/dev/null || echo "0.0.0.0")
DATE=$(date +%Y-%m-%d)
mkdir -p "${OUTPUT_DIR}"
# 公共排除参数
EXCLUDES=(
--exclude-ip="${MY_IP}"
--exclude='\.(css|js|jpg|jpeg|png|gif|ico|svg|woff2?|ttf|eot)(\?|$)'
--exclude='(bot|crawler|spider|slurp|Bytespider|GPTBot|ClaudeBot)'
--exclude='/(health|status|ping|readyz|livez|metrics)'
)
# 1. 全量分析(排除爬虫和静态资源)
echo "生成全量分析报告..."
goaccess "${LOG_FILE}" --log-format=COMBINED \
"${EXCLUDES[@]}" \
--html-title="全量分析 - ${DATE}" \
-o "${OUTPUT_DIR}/full_${DATE}.html" \
--process-and-exit
# 2. 错误分析
echo "生成错误分析报告..."
grep -E '" (4[0-9]{2}|5[0-9]{2}) ' "${LOG_FILE}" | \
goaccess --log-format=COMBINED \
--html-title="错误分析 - ${DATE}" \
-o "${OUTPUT_DIR}/errors_${DATE}.html" \
--process-and-exit -
# 3. API 分析
echo "生成 API 分析报告..."
grep '"/api/' "${LOG_FILE}" | \
goaccess --log-format=COMBINED \
"${EXCLUDES[@]}" \
--html-title="API 分析 - ${DATE}" \
-o "${OUTPUT_DIR}/api_${DATE}.html" \
--process-and-exit -
# 4. 生成索引页
echo "生成索引页..."
cat > "${OUTPUT_DIR}/index_${DATE}.html" << EOF
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>日志分析 - ${DATE}</title></head>
<body style="font-family:sans-serif;max-width:600px;margin:50px auto;">
<h1>📊 日志分析报告 - ${DATE}</h1>
<ul>
<li><a href="full_${DATE}.html">全量分析</a></li>
<li><a href="errors_${DATE}.html">错误分析</a></li>
<li><a href="api_${DATE}.html">API 分析</a></li>
</ul>
</body>
</html>
EOF
echo "分析完成!报告已生成至 ${OUTPUT_DIR}/"
7.11 小结
| 过滤类型 | 参数 | 示例 |
|---|---|---|
| 日期范围 | --date-range | --date-range=20260501-20260531 |
| 状态码 | --status-code | --status-code=4xx |
| 排除 IP | --exclude-ip | --exclude-ip=127.0.0.1 |
| 排除请求 | --exclude | --exclude='\.(css|js)$' |
| 忽略面板 | --ignore-panel | --ignore-panel=GEO_LOCATION |
| 启用面板 | --enable-panel | --enable-panel=VISITORS |
| 面板排序 | --sort-panel | --sort-panel=VISITORS,BY_VISITORS |
下一章
下一章将介绍自定义日志处理,包括多虚拟主机日志分析、日志合并、轮转日志处理和管道输入等高级技巧。