Squid 完全指南 / 10 - 日志系统
第十章:日志系统
10.1 日志类型概述
Squid 生成多种类型的日志,用于不同的目的:
| 日志类型 | 路径 | 用途 |
|---|---|---|
| 访问日志 (access.log) | /var/log/squid/access.log | 记录所有 HTTP 请求和响应 |
| 缓存日志 (cache.log) | /var/log/squid/cache.log | Squid 运行状态和错误信息 |
| 存储日志 (store.log) | /var/log/squid/store.log | 缓存对象的存储操作 |
| 用户代理日志 | 自定义 | 记录客户端 User-Agent |
┌──────────────────────────────────────────────────────┐
│ Squid 日志架构 │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ access.log │ │ cache.log │ │ store.log │ │
│ │ 请求/响应 │ │ 运行/错误 │ │ 缓存操作 │ │
│ │ 用户行为审计 │ │ 故障排查 │ │ 缓存调试 │ │
│ └──────────────┘ └──────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────┐ │
│ │ 日志分析工具 │ │
│ │ squid-analyzer | sarg | webalizer | custom │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
10.2 访问日志 (access.log)
10.2.1 默认日志格式
# 默认日志格式(squid 格式)
access_log /var/log/squid/access.log squid
# 日志字段顺序:
# timestamp elapsed client code/bytes method URL user hierarchy/status content-type
默认格式示例:
1715337600.123 150 192.168.1.100 TCP_MISS/200 54321 GET http://example.com/ - HIER_DIRECT/93.184.216.34 text/html
1715337601.456 23 192.168.1.101 TCP_HIT/200 12345 GET http://example.com/style.css - HIER_NONE/- text/css
1715337602.789 890 192.168.1.100 TCP_MISS/304 0 GET http://example.com/logo.png - HIER_DIRECT/93.184.216.34 image/png
10.2.2 日志格式字段说明
| 字段 | 格式代码 | 说明 |
|---|---|---|
| 时间戳 | %ts.%03tu | Unix 时间戳(秒.毫秒) |
| 耗时 | %6tr | 请求处理时间(毫秒) |
| 客户端 IP | %>a | 客户端源 IP |
| Squid 状态 | %Ss | Squid 内部状态码 |
| HTTP 状态 | %03>Hs | HTTP 响应状态码 |
| 响应大小 | %<st | 响应体大小(字节) |
| 请求方法 | %rm | GET/POST/CONNECT 等 |
| 请求 URL | %ru | 请求的 URL |
| 用户名 | %[un | 认证用户名 |
| 层次结构 | %Sh | 缓存层次/路由信息 |
| 上游地址 | %<a | 源站/父代理 IP |
| 内容类型 | %mt | MIME 类型 |
| Referer | %>ha{Referer} | HTTP Referer 头 |
| User-Agent | %>ha{User-Agent} | 浏览器标识 |
| SNI | %ssl::>sni | TLS SNI(HTTPS) |
| 请求大小 | %>st | 请求体大小 |
10.2.3 自定义日志格式
# 详细日志格式(包含 User-Agent 和 Referer)
logformat detailed %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt "%>ha{User-Agent}" "%>ha{Referer}"
access_log /var/log/squid/access.log detailed
# 安全审计日志(包含完整信息)
logformat security %ts.%03tu %>a %[un %rm %03>Hs %<st %ru %>ha{User-Agent}
access_log /var/log/squid/security.log security
# 仅记录 HTTP 方法和 URL(用于分析)
logformat minimal %ts %rm %ru
access_log /var/log/squid/minimal.log minimal
# JSON 格式日志(便于日志系统解析)
logformat json_log {"timestamp":%ts,"client":"%>a","user":"%[un","method":"%rm","url":"%ru","status":%>Hs,"size":%<st,"duration":%tr,"cache":"%Ss","mime":"%mt","ua":"%>ha{User-Agent}"}
access_log /var/log/squid/access.json json_log
# CSV 格式
logformat csv "%ts\",\"%>a\",\"%[un\",\"%rm\",\"%ru\",\"%>Hs\",\"%<st\",\"%tr\",\"%Ss\",\"%mt"
access_log /var/log/squid/access.csv csv
10.2.4 Squid 状态码
| 状态码 | 说明 |
|---|---|
TCP_HIT | 缓存命中 |
TCP_MISS | 缓存未命中 |
TCP_REFRESH_HIT | 刷新后命中(旧内容仍有效) |
TCP_REFRESH_MISS | 刷新后未命中(内容已更新) |
TCP_REF_FAIL_HIT | 刷新失败但返回旧缓存 |
TCP_NEGATIVE_HIT | 负缓存命中(如 404 缓存) |
TCP_MEM_HIT | 内存缓存命中 |
TCP_DENIED | 被 ACL 拒绝 |
TCP_ERROR | 连接错误 |
TCP_TUNNEL | CONNECT 隧道 |
NONE | 无请求/内部请求 |
10.2.5 日志过滤
# 仅记录特定状态
access_log /var/log/squid/access.log squid !TCP_MISS
# 仅记录特定域名
acl log_domains dstdomain .example.com
access_log /var/log/squid/access.log squid log_domains
# 不记录特定类型
acl internal dstdomain .internal.example.com
access_log /var/log/squid/access.log squid !internal
# 不记录健康检查
acl healthcheck url_regex /health
access_log /var/log/squid/access.log squid !healthcheck
10.2.6 日志缓冲和性能
# 守护进程模式日志(推荐,异步写入)
access_log daemon:/var/log/squid/access.log squid
# UDP 远程日志
access_log udp://logserver:514 squid
# 日志缓冲大小
# 默认 32KB,高流量环境可增大
access_log daemon:/var/log/squid/access.log squid buffer-size=256KB
10.3 缓存日志 (cache.log)
10.3.1 日志级别
# 设置调试级别
# 1 = 重要信息(默认)
# 2-3 = 一般调试
# 4-9 = 详细调试
# 0 = 仅错误和致命信息
cache_log /var/log/squid/cache.log
# 通过运行时命令调整级别
# squid -k debug # 启用调试日志
10.3.2 cache.log 常见信息
# 启动信息
2026/05/10 10:00:00 kid1| Squid Cache (Version 6.10): Exiting normally.
# 错误信息
2026/05/10 10:00:01 kid1| WARNING: Forwarding loop detected for:
2026/05/10 10:00:02 kid1| ERROR: Connection to 10.0.0.1 failed
# ACL 拒绝
2026/05/10 10:00:03 kid1| WARNING: denied by ACL: client 192.168.1.100
# SSL 错误
2026/05/10 10:00:04 kid1| ERROR: SSL handshake error
# 性能警告
2026/05/10 10:00:05 kid1| WARNING: Over capacity: too many connections
10.3.3 cache.log 级别配置
# 通过 debug_options 控制各模块的日志级别
# 格式: debug_options ALL,level module,level ...
# 全局级别 1(默认)
debug_options ALL,1
# 调试 ACL
debug_options 28,5
# 调试缓存
debug_options 20,5
# 调试 SSL
debug_options 83,5
# 调试 DNS
debug_options 78,5
# 调试网络
debug_options 5,5
10.4 存储日志 (store.log)
# 存储日志记录缓存对象的操作
cache_store_log stdio:/var/log/squid/store.log
# 不记录(减少 I/O)
# cache_store_log none
store.log 格式示例:
1715337600.123 RELEASE -1 0 200 1715337600 1715337600 -1 application/octet-stream 12345/54321 GET http://example.com/file.zip
1715337601.456 SWAPOUT 00 0 200 1715337601 -1 -1 text/html 6789/12345 GET http://example.com/page.html
10.5 日志轮转
10.5.1 Squid 内置轮转
# 轮转日志
sudo squid -k rotate
# 会将当前日志重命名为:
# access.log.0
# cache.log.0
# store.log.0
10.5.2 logrotate 配置
# /etc/logrotate.d/squid
/var/log/squid/access.log
/var/log/squid/cache.log
/var/log/squid/store.log
{
daily
rotate 30
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
# 通知 Squid 重新打开日志文件
squid -k rotate 2>/dev/null || true
endscript
}
10.5.3 自动轮转脚本
#!/bin/bash
# /etc/cron.daily/squid-log-rotate
LOG_DIR="/var/log/squid"
KEEP_DAYS=30
# 轮转
squid -k rotate
# 清理旧日志
find "$LOG_DIR" -name "*.gz" -mtime +$KEEP_DAYS -delete
echo "Squid log rotation completed at $(date)"
10.6 日志分析工具
10.6.1 squid-analyzer
# 安装
sudo apt install -y squid-analyzer
# 分析日志
squid-analyzer /var/log/squid/access.log /var/www/html/squid-report/
# 定时生成报告
# crontab -e
# 0 2 * * * squid-analyzer /var/log/squid/access.log /var/www/html/squid-report/
10.6.2 SARG (Squid Analysis Report Generator)
# 安装
sudo apt install -y sarg
# 配置 /etc/squid/squid.conf 中的访问日志
# access_log /var/log/squid/access.log squid
# 编辑 SARG 配置
sudo vim /etc/sarg/squid.conf
# /etc/sarg/squid.conf 示例配置:
# access_log /var/log/squid/access.log
# output_dir /var/www/html/sarg
# date_format u
# topuser_sort_field BYTES reverse
# 生成报告
sudo sarg -x
# 浏览报告
# http://localhost/sarg/
10.6.3 Webalizer
# 安装
sudo apt install -y webalizer
# 配置
sudo vim /etc/webalizer/webalizer.conf
# 运行
webalizer -o /var/www/html/squid-stats /var/log/squid/access.log
10.6.4 命令行分析
# 统计访问量 Top 10 IP
awk '{print $3}' /var/log/squid/access.log | sort | uniq -c | sort -rn | head -10
# 统计缓存命中率
echo "Total requests: $(wc -l < /var/log/squid/access.log)"
echo "Cache hits: $(grep -c 'TCP_HIT\|TCP_MEM_HIT' /var/log/squid/access.log)"
echo "Cache misses: $(grep -c 'TCP_MISS' /var/log/squid/access.log)"
echo "Denied: $(grep -c 'TCP_DENIED' /var/log/squid/access.log)"
# 统计请求量最大的 URL
awk '{print $7}' /var/log/squid/access.log | sort | uniq -c | sort -rn | head -20
# 统计每小时请求量
awk '{print strftime("%Y-%m-%d %H:00", $1)}' /var/log/squid/access.log | sort | uniq -c
# 统计 HTTP 状态码分布
awk '{print $4}' /var/log/squid/access.log | cut -d'/' -f2 | sort | uniq -c | sort -rn
# 统计带宽使用(按域名)
awk '{domain=$7; gsub(/https?:\/\//, "", domain); gsub(/\/.*/, "", domain); size=$6; total[domain]+=size} END {for(d in total) printf "%12d %s\n", total[d], d}' /var/log/squid/access.log | sort -rn | head -20
# 查看被拒绝的请求
grep "TCP_DENIED" /var/log/squid/access.log | tail -20
# 统计 User-Agent
awk -F'"' '{print $6}' /var/log/squid/access.log | sort | uniq -c | sort -rn | head -10
10.7 远程日志
10.7.1 UDP 远程日志
# 发送到远程 syslog
access_log udp://logserver:514 squid
# 或使用 TCP
access_log tcp://logserver:514 squid
10.7.2 日志收集系统集成
# 通过管道发送到日志收集器
access_log /var/log/squid/access.log squid
# Filebeat / Logstash 配置读取日志文件
# 然后转发到 Elasticsearch / Splunk
Filebeat 配置示例:
# /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
paths:
- /var/log/squid/access.log
fields:
log_type: squid_access
json.keys_under_root: true
output.elasticsearch:
hosts: ["elasticsearch:9200"]
10.8 实时日志监控
# 实时监控访问日志
tail -f /var/log/squid/access.log
# 实时监控拒绝的请求
tail -f /var/log/squid/access.log | grep "TCP_DENIED"
# 实时监控缓存命中
tail -f /var/log/squid/access.log | grep "TCP_HIT\|TCP_MEM_HIT"
# 实时监控错误
tail -f /var/log/squid/cache.log | grep -i "error\|warning\|denied"
# 使用 multitail 同时监控多个日志
multitail /var/log/squid/access.log /var/log/squid/cache.log
10.9 日志安全
10.9.1 日志权限
# 确保日志文件权限正确
sudo chown -R proxy:proxy /var/log/squid/
sudo chmod 750 /var/log/squid/
sudo chmod 640 /var/log/squid/*.log
10.9.2 日志脱敏
# 不记录认证信息到日志
# 默认 squid 格式不记录密码,但可能记录用户名
# 使用自定义格式排除敏感信息
# 不记录 Authorization 头
request_header_access Authorization deny all
10.9.3 日志保留策略
#!/bin/bash
# /etc/cron.monthly/squid-log-archive
LOG_DIR="/var/log/squid"
ARCHIVE_DIR="/archive/squid/$(date +%Y-%m)"
mkdir -p "$ARCHIVE_DIR"
find "$LOG_DIR" -name "*.gz" -mtime +90 -exec mv {} "$ARCHIVE_DIR/" \;
echo "Archived old logs to $ARCHIVE_DIR"
10.10 本章小结
| 日志类型 | 用途 | 关键配置 |
|---|---|---|
| access.log | 请求审计 | access_log + logformat |
| cache.log | 运行调试 | cache_log + debug_options |
| store.log | 缓存调试 | cache_store_log |
| 日志轮转 | 空间管理 | squid -k rotate + logrotate |
| 日志分析 | 统计报告 | sarg / squid-analyzer |