强曰为道

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

10 - 日志系统

第十章:日志系统

10.1 日志类型概述

Squid 生成多种类型的日志,用于不同的目的:

日志类型路径用途
访问日志 (access.log)/var/log/squid/access.log记录所有 HTTP 请求和响应
缓存日志 (cache.log)/var/log/squid/cache.logSquid 运行状态和错误信息
存储日志 (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.%03tuUnix 时间戳(秒.毫秒)
耗时%6tr请求处理时间(毫秒)
客户端 IP%>a客户端源 IP
Squid 状态%SsSquid 内部状态码
HTTP 状态%03>HsHTTP 响应状态码
响应大小%<st响应体大小(字节)
请求方法%rmGET/POST/CONNECT 等
请求 URL%ru请求的 URL
用户名%[un认证用户名
层次结构%Sh缓存层次/路由信息
上游地址%<a源站/父代理 IP
内容类型%mtMIME 类型
Referer%>ha{Referer}HTTP Referer 头
User-Agent%>ha{User-Agent}浏览器标识
SNI%ssl::>sniTLS 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_TUNNELCONNECT 隧道
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

扩展阅读