强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

04 - 日志格式详解

04 - 日志格式详解

4.1 日志格式基础

GoAccess 的核心能力在于解析日志文件。要正确分析日志,必须让 GoAccess 理解日志的格式。GoAccess 使用一套类似 Apache 的格式字符串来描述日志结构。

格式字符串原理

GoAccess 的格式字符串由普通字符格式说明符组成:

格式说明符: %x  (x 是一个字母,代表特定字段)
普通字符:   空格、引号、方括号等原样匹配

例如,Apache Combined Log Format 对应的格式字符串为:

%h - %^ [%d:%t %^] "%r" %s %b "%R" "%u"

解析过程:

192.168.1.1 - - [10/May/2026:13:55:36 +0800] "GET /index.html HTTP/1.1" 200 612 "https://example.com/" "Mozilla/5.0"
│           │ │ │                │         │                          │   │   │                     │
%h          - %^ [%d            :%t       %^]                        "%r" %s  %b                   "%R" "%u"

4.2 格式说明符完整列表

说明符含义示例值
%h客户端 IP 地址 (Host)192.168.1.1
%^跳过此字段(忽略)-
%d日期 (Date)10/May/2026
%t时间 (Time)13:55:36
%r请求行 (Request)GET /index.html HTTP/1.1
%m请求方法 (Method)GET
%UURL 路径 (URL path)/index.html
%q查询字符串 (Query string)?id=123
%H协议版本 (Protocol)HTTP/1.1
%s状态码 (Status code)200
%b响应大小 (Bytes sent)612
%R来源页 (Referer)https://example.com/
%uUser-AgentMozilla/5.0 ...
%D请求耗时 — 微秒 (Duration)1234567
%T请求耗时 — 秒 (Duration)1
%^跳过一个字段-
%{VAR}i请求头字段%{Cookie}i
%{VAR}o响应头字段%{Content-Type}o

注意%^ 是"跳过"(忽略)的意思,当你的日志中有不需要分析的字段时非常有用。


4.3 预定义日志格式

GoAccess 内置了多种常见日志格式,可通过名称直接使用:

4.3.1 Apache / Nginx 标准格式

格式名称说明对应配置
COMBINEDApache Combined Log FormatLogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
COMMONApache Common Log FormatLogFormat "%h %l %u %t \"%r\" %>s %b"
VCOMBINED虚拟主机 Combined 格式比 Combined 多一个虚拟主机字段
VCOMMON虚拟主机 Common 格式比 Common 多一个虚拟主机字段

4.3.2 使用预定义格式

# 使用 Combined 格式(最常用)
goaccess /var/log/nginx/access.log --log-format=COMBINED

# 使用 Common 格式
goaccess /var/log/nginx/access.log --log-format=COMMON

# 使用虚拟主机 Combined 格式
goaccess /var/log/nginx/access.log --log-format=VCOMBINED

4.3.3 COMBINED 与 COMMON 的区别

COMBINED = COMMON + 来源页 + User-Agent
# Common Log Format (CLF)
127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326

# Combined Log Format
127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08"

4.4 Nginx 日志格式

4.4.1 Nginx 默认日志格式

Nginx 的默认 combined 格式与 Apache Combined 一致:

# /etc/nginx/nginx.conf
log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';
# 使用 COMBINED 格式解析
goaccess /var/log/nginx/access.log --log-format=COMBINED

4.4.2 Nginx 自定义格式示例

示例一:包含请求时间的格式

log_format timed '$remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent" '
                 '$request_time $upstream_response_time';

GoAccess 配置:

goaccess access.log \
  --log-format='%h - %^ [%d:%t %^] "%r" %s %b "%R" "%u" %D' \
  --date-format=%d/%b/%Y \
  --time-format=%H:%M:%S

示例二:JSON 格式日志

# Nginx 使用 escape=json 输出 JSON 格式日志
log_format json_combined escape=json
    '{'
        '"time_local":"$time_local",'
        '"remote_addr":"$remote_addr",'
        '"request":"$request",'
        '"status":"$status",'
        '"body_bytes_sent":"$body_bytes_sent",'
        '"http_referer":"$http_referer",'
        '"http_user_agent":"$http_user_agent",'
        '"request_time":"$request_time"'
    '}';

GoAccess 解析 JSON 格式日志:

goaccess access.log \
  --log-format='"%d:%t","%h","%r","%s","%b","%R","%u","%T"' \
  --date-format=%d/%b/%Y \
  --time-format=%H:%M:%S

提示:JSON 格式日志的解析相对复杂,需要将 JSON 字段映射为格式说明符的顺序。

示例三:包含 X-Forwarded-For 的格式

log_format proxied '$http_x_forwarded_for - $remote_user [$time_local] '
                   '"$request" $status $body_bytes_sent '
                   '"$http_referer" "$http_user_agent"';
goaccess access.log --log-format=COMBINED
# X-Forwarded-For 对应 %h 字段

4.4.3 Nginx 格式速查表

Nginx 变量GoAccess 说明符说明
$remote_addr%h客户端 IP
$remote_user%^ (通常为 -)远程用户
$time_local[%d:%t %^]时间戳
$request%r请求行
$status%s状态码
$body_bytes_sent%b响应大小
$http_referer%R来源页
$http_user_agent%uUser-Agent
$request_time%T%D请求耗时
$upstream_response_time%T上游响应时间
$http_x_forwarded_for%h真实客户端 IP

4.5 Apache 日志格式

4.5.1 Apache 默认配置

# /etc/apache2/apache2.conf 或 httpd.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
# 解析 Combined 格式
goaccess /var/log/apache2/access.log --log-format=COMBINED

4.5.2 Apache 自定义格式示例

示例一:包含处理时间

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" timed
goaccess access.log \
  --log-format='%h - %^ [%d:%t %^] "%r" %s %b "%R" "%u" %D' \
  --date-format=%d/%b/%Y \
  --time-format=%H:%M:%S

示例二:VirtualHost 日志

<VirtualHost *:80>
    ServerName example.com
    CustomLog /var/log/apache2/example.com_access.log combined
</VirtualHost>
goaccess /var/log/apache2/example.com_access.log --log-format=COMBINED

4.6 自定义日志格式

当日志格式不匹配任何预定义格式时,需要手动指定格式字符串。

4.6.1 自定义格式编写规则

  1. 分析日志样例,识别每个字段
  2. 使用格式说明符替换每个字段
  3. 使用 %^ 跳过不需要的字段
  4. 使用普通字符(空格、引号、方括号等)匹配分隔符

4.6.2 实战:从日志样例推导格式

给定日志样例:

2026-05-10 14:30:15 | 192.168.1.100 | GET | /api/users | 200 | 1024 | 0.023 | https://admin.example.com | Chrome/120.0

逐步推导:

字段              值                     说明符
────────────────────────────────────────────────
日期              2026-05-10             %d
时间              14:30:15               %t
分隔符            |                      \|
IP                192.168.1.100          %h
方法              GET                    %m
路径              /api/users             %U
状态码            200                    %s
大小              1024                   %b
耗时              0.023                  %T
来源页            https://admin...       %R
浏览器            Chrome/120.0           %u

格式字符串:

goaccess access.log \
  --log-format='%d %t | %h | %m | %U | %s | %b | %T | %R | %u' \
  --date-format=%Y-%m-%d \
  --time-format=%H:%M:%S

4.6.3 更多自定义格式示例

示例一:管道分隔的日志

10.0.0.1|2026-05-10|14:30:15|GET|/api/data|200|512
goaccess access.log \
  --log-format='%h|%d|%t|%m|%U|%s|%b' \
  --date-format=%Y-%m-%d \
  --time-format=%H:%M:%S

示例二:Squid 代理日志

1718446948.256    156 10.0.0.1 TCP_MISS/200 51234 GET http://example.com/ - HIER_DIRECT/93.184.216.34 text/html
goaccess access.log \
  --log-format='%^ %^ %h %^/%s %b %m %U %^ %^ %^' \
  --date-format=%s  # Unix 时间戳,需要特殊处理

示例三:AWS ALB 日志

h2 2026-05-10T14:30:15.123456Z app/my-alb/50dc6c495c0c9188 10.0.0.1:54321 10.0.0.2:80 0.000 0.015 0.000 200 200 512 384 "GET https://example.com:443/api/data HTTP/2.0" "Mozilla/5.0" ...
goaccess access.log \
  --log-format='%^ %d:%t %^ %h:%^ %^:%^ %T %^ %^ %s %^ %b %^ "%m %U %H" "%u"' \
  --date-format=%Y-%m-%d \
  --time-format=%H:%M:%S

4.7 时间与日期格式

4.7.1 日期格式说明符

说明符含义示例
%d日(两位)01 - 31
%m月(两位)01 - 12
%b月缩写Jan, Feb, …, Dec
%B月全称January, February, …
%Y四位年份2026
%y两位年份26

4.7.2 时间格式说明符

说明符含义示例
%H小时(24小时制)00 - 23
%M分钟00 - 59
%S00 - 59
%f微秒123456
%T时间(时:分:秒)14:30:15

4.7.3 常见日期时间格式对照

日志中的日期格式配置
10/May/2026--date-format=%d/%b/%Y
2026-05-10--date-format=%Y-%m-%d
05/10/2026--date-format=%m/%d/%Y
10.05.2026--date-format=%d.%m.%Y
20260510--date-format=%Y%m%d
May 10 2026--date-format=%b %d %Y
日志中的时间格式配置
14:30:15--time-format=%H:%M:%S
14:30:15.123--time-format=%H:%M:%S.%f
2:30:15 PMGoAccess 不直接支持 12 小时制

4.8 组合格式实战

场景一:Nginx + 请求时间 + X-Forwarded-For

Nginx 配置:

log_format proxy '$http_x_forwarded_for - $remote_user [$time_local] '
                '"$request" $status $body_bytes_sent '
                '"$http_referer" "$http_user_agent" '
                '$request_time';

日志样例:

203.0.113.50 - - [10/May/2026:14:30:15 +0800] "GET /index.html HTTP/1.1" 200 612 "https://example.com" "Mozilla/5.0" 0.123

GoAccess 命令:

goaccess /var/log/nginx/access.log \
  --log-format='%h - %^ [%d:%t %^] "%r" %s %b "%R" "%u" %T' \
  --date-format=%d/%b/%Y \
  --time-format=%H:%M:%S

场景二:Caddy JSON 日志

Caddy 配置:

{
  "logging": {
    "logs": {
      "default": {
        "encoder": {
          "format": "json"
        }
      }
    }
  }
}

日志样例:

{"ts":1715338215.123,"request":{"remote_addr":"10.0.0.1","method":"GET","uri":"/","proto":"HTTP/2.0","headers":{"User-Agent":["Mozilla/5.0"],"Referer":["https://example.com"]}},"status":200,"size":612,"duration":0.023}

解析方案:Caddy JSON 日志结构复杂,建议先用 jq 转换为适合 GoAccess 的格式:

# 将 Caddy JSON 转为 pipe-delimited 格式
cat /var/log/caddy/access.log | \
  jq -r '[.request.remote_addr, (.ts | strftime("%d/%b/%Y")), (.ts | strftime("%H:%M:%S")),
   .request.method, .request.uri, .status, .size, .duration,
   (.request.headers.Referer[0] // "-"), (.request.headers["User-Agent"][0] // "-")]
   | join("|")' | \
  goaccess --log-format='%h|%d|%t|%m|%U|%s|%b|%T|%R|%u' \
    --date-format=%d/%b/%Y \
    --time-format=%H:%M:%S -

场景三:Tomcat 访问日志

Tomcat 配置 (server.xml):

<Valve className="org.apache.catalina.valves.AccessLogValve"
       pattern="%h %l %u %t &quot;%r&quot; %s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot; %D"
       directory="logs" prefix="access" suffix=".log" />
goaccess /var/log/tomcat/access.log \
  --log-format='%h - %^ [%d:%t %^] "%r" %s %b "%R" "%u" %D' \
  --date-format=%d/%b/%Y \
  --time-format=%H:%M:%S

4.9 使用配置文件简化格式管理

将常用格式保存到配置文件中,避免每次输入:

# ~/.goaccessrc

# === 日志格式 ===
log-format %h - %^ [%d:%t %^] "%r" %s %b "%R" "%u"

# === 时间格式 ===
date-format %d/%b/%Y
time-format %H:%M:%S

# === 预定义格式(二选一) ===
# log-format COMBINED

配置文件后,直接运行:

goaccess /var/log/nginx/access.log

无需再指定 --log-format 等参数。

多配置文件管理

对于不同日志格式的环境,可以创建多个配置文件:

# Nginx 标准格式
goaccess access.log --config-file=~/.goaccessrc.nginx

# Nginx 含请求时间
goaccess access.log --config-file=~/.goaccessrc.nginx-timed

# Apache
goaccess access.log --config-file=~/.goaccessrc.apache

4.10 调试日志格式

4.10.1 测试格式是否正确

GoAccess 提供了调试模式来验证日志格式:

# 显示详细的解析过程
goaccess access.log --log-format=COMBINED --debug-file=debug.txt

# 查看调试输出
head -50 debug.txt

4.10.2 常见格式错误

错误现象原因解决方案
所有 Hits 为 0格式不匹配检查格式字符串
日期解析失败日期格式不匹配调整 --date-format
状态码全为 0字段顺序错误检查字段顺序
IP 地址为空%h 位置错误确认 IP 字段位置
带宽统计异常字段映射错误检查 %b 对应字段

4.10.3 验证步骤

# 1. 先看日志的前 5 行
head -5 /var/log/nginx/access.log

# 2. 逐行对照格式说明符
# 假设日志行为:
# 10.0.0.1 - - [10/May/2026:14:30:15 +0800] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0"
#
# 对应关系:
# 10.0.0.1          → %h
# -                  → -
# -                  → %^
# [10/May/2026:14:30:15 +0800] → [%d:%t %^]
# "GET / HTTP/1.1"  → "%r"
# 200                → %s
# 612                → %b
# "-"                → "%R"
# "Mozilla/5.0"      → "%u"

# 3. 使用 1-2 行测试
head -2 /var/log/nginx/access.log | goaccess --log-format=COMBINED -

# 4. 使用 --debug-file 查看详细解析
goaccess /var/log/nginx/access.log --log-format=COMBINED --debug-file=/tmp/debug.log

4.11 小结

要点说明
最常用格式COMBINED(Apache/Nginx 标准)
跳过字段使用 %^ 跳过不需要的字段
关键格式%h=IP, %d=日期, %t=时间, %r=请求, %s=状态码, %b=大小, %R=来源, %u=UA
调试方法--debug-file 查看解析详情
最佳实践将格式写入配置文件

下一章

下一章将详细介绍 GoAccess 的实时监控功能,包括终端实时面板、WebSocket 通信和 HTML 实时面板的搭建。

05 - 实时监控


扩展阅读