{T}

GoAccess 可视化 access 日志

GoAccess 是个开源的实时 Web 日志分析器和交互式查看器,能够通过终端或 Web 浏览器提供快速且有价值的 HTTP 统计信息。它支持多种日志格式,并可以生成漂亮的 HTML 报告

安装 GoAccess

在 CentOS 7.9 上安装

bash
# 安装 EPEL 仓库
sudo yum install -y epel-release

# 安装 GoAccess
sudo yum install -y goaccess

# 验证安装
goaccess -V

基本用法

命令行模式

bash
# 基本分析
goaccess access.log

# 指定日志格式
goaccess access.log --log-format=COMBINED

# 实时监控日志
goaccess access.log -o report.html --real-time-html --daemonize

# 生成静态 HTML 报告
goaccess access.log -o report.html

# 指定输出格式为 JSON
goaccess access.log -o report.json --json

# 分析压缩日志
goaccess access.log.*.gz -o report.html --log-format=COMBINED

交互式界面

bash
# 进入交互式界面
goaccess access.log

# 常用快捷键
# F1 或 h: 帮助
# q: 退出
# 1-9: 选择不同的模块
# TAB: 切换模块
# ENTER: 展开所选模块的详细信息
# o: 打开详细视图
# n: 向下移动
# p: 向上移动
# c: 设置配色方案
# t: 总体统计视图
# g: 跳转到第一条记录
# G: 跳转到最后一条记录

Nginx 日志格式配置

GoAccess 需要知道日志的格式才能正确解析。对于 Nginx,常见的日志格式有:

查看当前 Nginx 日志格式

bash
# 查看 Nginx 配置文件
cat /etc/nginx/nginx.conf | grep -A 5 log_format

常见 Nginx 日志格式配置

nginx
# COMBINED 格式(默认)
log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

# 自定义格式
log_format custom '$remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent" '
                 '$request_time $upstream_response_time';

在 GoAccess 中指定格式

bash
# 使用预定义格式
goaccess /var/log/nginx/access.log --log-format=COMBINED

# 使用自定义格式
goaccess /var/log/nginx/access.log \
  --log-format='$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"' \
  --date-format='%d/%b/%Y' \
  --time-format='%H:%M:%S'

配置文件

创建 GoAccess 配置文件 ~/.goaccessrc/etc/goaccess/goaccess.conf

bash
# 示例配置文件
sudo tee /etc/goaccess/goaccess.conf << 'EOF'
# 日志格式配置
time-format %H:%M:%S
date-format %d/%b/%Y
log-format %h - %^ [%d:%t %^] "%r" %s %b "%R" "%u" %T %^

# 常规设置
# 保存配置文件到主目录
config-file ~/.goaccessrc

# HTML 报告设置
html-report-title 我的网站访问分析
html-pub-static http://example.com/assets
html-theme gray

# 输出选项
output-format html
ignore-crawlers
real-time-html
daemonize

# 其他设置
no-color
no-global-config
persist-conf
EOF

实时监控与 Web 界面

设置实时监控

bash
# 启动实时监控和 Web 服务器
goaccess /var/log/nginx/access.log \
  -o /usr/share/nginx/html/goaccess.html \
  --real-time-html \
  --daemonize \
  --pid-file=/var/run/goaccess.pid

# 查看生成的报告
curl http://your-server/goaccess.html

通过 Nginx 提供 HTML 报告

创建 Nginx 配置:

nginx
server {
    listen 80;
    server_name logs.example.com;

    # GoAccess 报告路径
    location /goaccess/ {
        alias /var/www/goaccess/;
        index index.html;
    }

    # 其他配置...
}

使用 systemd 服务管理

创建服务文件 /etc/systemd/system/goaccess.service

ini
[Unit]
Description=GoAccess real-time log analyzer
After=network.target

[Service]
Type=forking
User=nginx
Group=nginx
ExecStart=/usr/bin/goaccess /var/log/nginx/access.log \
  -o /var/www/goaccess/index.html \
  --real-time-html \
  --daemonize \
  --pid-file=/var/run/goaccess.pid
PIDFile=/var/run/goaccess.pid
Restart=on-failure

[Install]
WantedBy=multi-user.target

启用并启动服务:

bash
# 创建报告目录
sudo mkdir -p /var/www/goaccess
sudo chown -R nginx:nginx /var/www/goaccess

# 重新加载 systemd
sudo systemctl daemon-reload

# 启用并启动服务
sudo systemctl enable goaccess
sudo systemctl start goaccess

# 检查状态
sudo systemctl status goaccess

自动化日志轮转

为了防止日志文件过大,可以设置日志轮转:

bash
# 创建日志轮转配置
sudo tee /etc/logrotate.d/goaccess << 'EOF'
/var/log/nginx/access.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 640 nginx adm
    sharedscripts
    postrotate
        # 向 GoAccess 发送重新加载信号
        if [ -f /var/run/goaccess.pid ]; then
            kill -HUP $(cat /var/run/goaccess.pid)
        fi
    endscript
}
EOF

进阶功能

多域名日志分析

bash
# 分析多个域名的日志
goaccess \
  /var/log/nginx/site1-access.log \
  /var/log/nginx/site2-access.log \
  -o /var/www/goaccess/multi-domain-report.html

筛选特定时间段

bash
# 分析特定日期的日志
sed -n '/15\/Dec\/2023/,$p' /var/log/nginx/access.log | goaccess -o report.html

# 使用日期范围
grep -E "15/Dec/2023:[01-23]" /var/log/nginx/access.log | goaccess -o report.html

过滤特定状态码或路径

bash
# 只分析 404 错误
grep " 404 " /var/log/nginx/access.log | goaccess -o 404-report.html

# 分析特定路径
grep "/api/" /var/log/nginx/access.log | goaccess -o api-report.html

结合其他工具

bash
# 与 awk 结合提取特定字段
awk '$9 >= 400' /var/log/nginx/access.log | goaccess -o error-report.html

# 与 grep 结合排除爬虫
grep -v "bot\|crawl\|spider" /var/log/nginx/access.log | goaccess -o human-report.html

报告解读

GoAccess 报告提供了丰富的统计信息:

  1. 总体统计

    • 唯一访客数
    • 文件数
    • 带宽使用
    • 请求总数
  2. 访客统计

    • 访问最多的 IP 地址
    • 访问次数最多的主机
  3. 请求统计

    • 最常访问的文件/页面
    • 静态资源统计
    • HTTP 协议版本
  4. 时间统计

    • 按小时、天、月访问量
    • 访问模式分析
  5. 地理位置

    • 按国家/地区统计
    • 城市级别统计(需 GeoIP 数据)
  6. 其他统计

    • 引用页面
    • 用户代理
    • HTTP 状态码
    • 请求大小
    • 请求方法

安全配置

访问控制

nginx
# 限制 GoAccess 报告的访问
location /goaccess/ {
    alias /var/www/goaccess/;
    index index.html;

    # 只允许特定 IP 访问
    allow 192.168.1.0/24;
    allow 10.0.0.0/8;
    deny all;

    # 基本认证(可选)
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

创建认证用户

bash
# 创建认证文件(需要 httpd-tools)
sudo yum install -y httpd-tools

# 添加用户
sudo htpasswd -c /etc/nginx/.htpasswd admin

性能优化

调整 GoAccess 配置

bash
# 高效处理大量日志
goaccess /var/log/nginx/access.log \
  -o report.html \
  --max-items=1000 \
  --double-decode \
  --anonymize-ip \
  --all-static-files \
  --exclude-ip=127.0.0.1

使用日志分割

bash
# 使用 split 工具处理大日志文件
split -l 1000000 /var/log/nginx/access.log access_part_
for file in access_part_*; do
    goaccess "$file" -o "${file}.html" &
done

故障排除

常见问题

  1. GoAccess 无法解析日志

    • 检查日志格式配置是否正确
    • 确认时间格式和日期格式匹配
  2. 实时报告不更新

    • 检查是否以守护进程模式运行
    • 确认有足够的权限读取日志文件
  3. 内存不足

    • 减少保留的项目数量 (--max-items)
    • 使用日志分割处理超大文件
  4. 权限问题

    • 确保运行用户有读取日志的权限
    • 确保输出目录有写入权限

调试命令

bash
# 检查日志格式是否匹配
goaccess --date-format='%d/%b/%Y' --time-format='%H:%M:%S' \
  --log-format='%h - %^ [%d:%t %^] "%r" %s %b "%R" "%u"' \
  --debug < /var/log/nginx/access.log

# 测试配置文件
goaccess --debug --no-global-config < /var/log/nginx/access.log

自动化脚本

创建每日报告脚本

bash
#!/bin/bash
# 创建日期标签
DATE=$(date +%Y-%m-%d)

# 生成每日报告
goaccess /var/log/nginx/access.log \
  -o /var/www/goaccess/daily/daily-${DATE}.html \
  --no-global-config

# 保留最近 30 天的报告
find /var/www/goaccess/daily/ -name "daily-*.html" -mtime +30 -delete

# 压缩旧报告
find /var/www/goaccess/daily/ -name "daily-*.html" -mtime +7 -exec gzip {} \;

设置 cron 任务

bash
# 编辑 crontab
crontab -e

# 添加以下内容(每天凌晨 1 点生成报告)
0 1 * * * /usr/local/bin/generate-daily-report.sh

# 每小时检查 GoAccess 进程是否运行
0 * * * * pgrep -f goaccess || systemctl start goaccess

与 ELK 集成

GoAccess 可以与 ELK (Elasticsearch, Logstash, Kibana) 集成,提供更强大的日志分析能力:

bash
# 将日志发送到 Elasticsearch
goaccess /var/log/nginx/access.log \
  -o - --json | curl -XPOST http://localhost:9200/nginx-logs/_bulk \
  --header 'Content-Type: application/x-ndjson' \
  --data-binary @-

替代方案

如果 GoAccess 不适合您的需求,可以考虑以下替代方案:

  1. AWStats - 基于 Perl 的日志分析器
  2. Webalizer - 传统的 Web 服务器日志分析工具
  3. Analog - 快速的日志分析器
  4. Piwik/Matomo - 完整的分析平台
  5. Google Analytics - 基于 JavaScript 的解决方案

通过以上配置,您可以充分利用 GoAccess 来监控和分析 Nginx 访问日志,实时了解网站的访问情况,及时发现异常,优化网站性能。