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

Apache HTTP Server 完全指南 / 日志配置与分析

日志配置与分析

Apache 日志是服务器管理、故障排查和安全分析的重要工具。

1. 日志类型

1.1 错误日志

# 配置错误日志
ErrorLog /var/log/apache2/error.log

# 日志级别
LogLevel warn

日志级别(从详细到简洁):

级别描述使用场景
trace1-8跟踪信息调试
debug调试信息开发环境
info一般信息
notice正常但重要
warn警告生产环境推荐
error错误
crit严重
alert紧急
emerg系统不可用

1.2 访问日志

# 基本配置
CustomLog /var/log/apache2/access.log combined

# 虚拟主机独立日志
<VirtualHost *:80>
    ServerName www.example.com
    ErrorLog /var/www/example.com/logs/error.log
    CustomLog /var/www/example.com/logs/access.log combined
</VirtualHost>

1.3 预定义日志格式

格式名描述
common通用日志格式
combined组合日志格式(推荐)
combinedio组合格式+IO 字节数
referer引用页
agent用户代理
# 预定义格式
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio

2. 自定义日志格式

2.1 格式字符串

格式字符描述
%h客户端 IP
%l远程日志名(通常为 -
%u认证用户
%t时间戳
%r请求行
%>s状态码
%b响应字节数
%{Referer}i引用页
%{User-Agent}i用户代理
%D请求处理时间(微秒)
%T请求处理时间(秒)
%{Host}i请求主机名
%{Cookie}iCookie
%{Set-Cookie}o响应 Cookie
%{Content-Type}o内容类型
%{X-Forwarded-For}i代理 IP
%I接收字节数
%O发送字节数

2.2 常用自定义格式

# 详细调试格式
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D %T" detailed

# JSON 格式(便于日志分析)
LogFormat "{ \
  \"remote_ip\": \"%h\", \
  \"timestamp\": \"%{%Y-%m-%dT%H:%M:%S%z}t\", \
  \"method\": \"%m\", \
  \"url\": \"%U\", \
  \"query\": \"%q\", \
  \"status\": %>s, \
  \"size\": %B, \
  \"referer\": \"%{Referer}i\", \
  \"user_agent\": \"%{User-Agent}i\", \
  \"response_time\": %D, \
  \"forwarded_for\": \"%{X-Forwarded-For}i\" \
}" json

# 安全审计格式
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\" \"%{Cookie}i\"" security

# 性能监控格式
LogFormat "%h %t \"%r\" %>s %b %D %T %{Referer}i" performance

# 带虚拟主机名的格式
LogFormat "%v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined

2.3 条件日志

# 使用 env= 条件记录
CustomLog /var/log/apache2/access.log combined
CustomLog /var/log/apache2/agents.log agent env=log_agent
CustomLog /var/log/apache2/referer.log referer env=log_referer

# 基于请求设置环境变量
SetEnvIf Request_URI "\.(gif|jpg|png|css|js)$" dontlog
CustomLog /var/log/apache2/access.log combined env=!dontlog

# 不记录健康检查
SetEnvIf User-Agent "ELB-HealthChecker" dontlog
SetEnvIf User-Agent "Uptime" dontlog
CustomLog /var/log/apache2/access.log combined env=!dontlog

# 仅记录错误请求
CustomLog /var/log/apache2/errors.log combined %>400

# 记录特定路径
SetEnvIf Request_URI "^/api/" api_request
CustomLog /var/log/apache2/api.log combined env=api_request

2.4 管道日志

# 使用管道日志处理
CustomLog "|/usr/bin/rotatelogs /var/log/apache2/access.%Y%m%d.log 86400" combined

# 使用 cronolog
CustomLog "|/usr/bin/cronolog /var/log/apache2/access.%Y%m%d.log" combined

# 压缩日志
CustomLog "|/bin/gzip > /var/log/apache2/access.log.gz" combined

# 发送到 syslog
CustomLog "|/usr/bin/logger -t apache -p local1.info" combined
ErrorLog syslog:local1

3. 日志轮转

3.1 rotatelogs

# 每天轮转
CustomLog "|/usr/bin/rotatelogs /var/log/apache2/access.%Y-%m-%d.log 86400" combined

# 每 100MB 轮转
CustomLog "|/usr/bin/rotatelogs /var/log/apache2/access.log 104857600" combined

# 保留 365 天
CustomLog "|/usr/bin/rotatelogs -l /var/log/apache2/access.%Y-%m-%d.log 86400 +365" combined

3.2 logrotate 配置

# /etc/logrotate.d/apache2
/var/log/apache2/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 640 root adm
    sharedscripts
    postrotate
        if /etc/init.d/apache2 status > /dev/null ; then
            /etc/init.d/apache2 reload > /dev/null
        fi
    endscript
}
# 测试 logrotate
sudo logrotate -d /etc/logrotate.d/apache2
sudo logrotate -f /etc/logrotate.d/apache2

3.3 虚拟主机日志轮转

# /etc/logrotate.d/apache2-vhosts
/var/www/*/logs/*.log {
    weekly
    missingok
    rotate 12
    compress
    delaycompress
    notifempty
    create 640 www-data www-data
    sharedscripts
    postrotate
        if /etc/init.d/apache2 status > /dev/null ; then
            /etc/init.d/apache2 reload > /dev/null
        fi
    endscript
}

4. 日志分析

4.1 命令行分析

# 基本统计
wc -l /var/log/apache2/access.log

# 统计独立 IP
awk '{print $1}' access.log | sort -u | wc -l

# 最活跃 IP(Top 10)
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

# 统计状态码
awk '{print $9}' access.log | sort | uniq -c | sort -rn

# 统计 404 请求
awk '$9 == 404 {print $7}' access.log | sort | uniq -c | sort -rn | head -20

# 统计请求方法
awk '{print $6}' access.log | sort | uniq -c | sort -rn

# 统计每小时请求量
awk '{print $4}' access.log | cut -d: -f2 | sort | uniq -c

# 统计带宽使用
awk '{sum+=$10} END {print sum/1024/1024/1024 " GB"}' access.log

# 统计慢请求(响应时间 > 1s)
awk '$NF > 1000000 {print}' access.log

# 统计特定页面访问
grep "/products" access.log | wc -l

# 统计搜索引擎爬虫
grep -i "bot\|crawl\|spider" access.log | awk '{print $1}' | sort | uniq -c | sort -rn

4.2 安全分析

# 检测暴力破解
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20

# 检测 401 错误
awk '$9 == 401 {print $1, $7}' access.log | sort | uniq -c | sort -rn

# 检测可疑请求
grep -E "(union|select|insert|update|delete|drop|exec|eval|alert)" access.log

# 检测目录遍历
grep "\.\./" access.log

# 检测 SQL 注入尝试
grep -iE "('|%27)(\s|%20)*(or|and|union|select)" access.log

# 检测 XSS 尝试
grep -iE "(<script|javascript:|on\w+\s*=)" access.log

# 检测文件包含尝试
grep -iE "(etc/passwd|etc/shadow|proc/self)" access.log

# 统计攻击 IP
grep -E "(400|401|403|404)" access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

4.3 性能分析

# 统计响应时间
awk '{print $NF}' access.log | sort -n | tail -10

# 平均响应时间
awk '{sum+=$NF; count++} END {print sum/count " 微秒"}' access.log

# 响应时间分布
awk '{
  if ($NF < 100000) fast++
  else if ($NF < 500000) medium++
  else if ($NF < 1000000) slow++
  else very_slow++
} END {
  print "快速 (<100ms): " fast
  print "中等 (100-500ms): " medium
  print "慢速 (500ms-1s): " slow
  print "很慢 (>1s): " very_slow
}' access.log

# 统计每分钟请求量
awk '{print $4}' access.log | cut -d: -f1-3 | uniq -c | sort -rn | head -20

# 统计每秒请求数峰值
awk '{print $4}' access.log | cut -d: -f1-4 | uniq -c | sort -rn | head -10

5. 日志分析工具

5.1 GoAccess

# 安装
sudo apt install goaccess

# 实时分析
goaccess /var/log/apache2/access.log --log-format=COMBINED -c

# 生成 HTML 报告
goaccess /var/log/apache2/access.log --log-format=COMBINED -o /var/www/html/report.html

# JSON 格式分析
goaccess /var/log/apache2/access.log --log-format=COMBINED -o report.json --json

# JSON 日志格式
goaccess /var/log/apache2/access.log --log-format='{ %h %^[%^] "%r" %s %b "%R" "%u" }' -o report.html

5.2 AWStats

# 安装
sudo apt install awstats

# 配置 /etc/awstats/awstats.www.example.com.conf
LogFile="/var/log/apache2/access.log"
LogFormat=1
SiteDomain="www.example.com"
HostAliases="example.com"
DNSLookup=0

# 生成统计
sudo /usr/lib/cgi-bin/awstats.pl -config=www.example.com -update

# 配置 Apache 访问
Alias /awstats/classes "/usr/share/awstats/lib/"
Alias /awstats-icon "/usr/share/awstats/icon/"
ScriptAlias /cgi-bin/ "/usr/lib/cgi-bin/"

<Directory "/usr/lib/cgi-bin/">
    AllowOverride None
    Options +ExecCGI
    Require ip 192.168.1.0/24
</Directory>

5.3 ELK Stack

# Filebeat 配置
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/apache2/access.log
  fields:
    type: apache-access

- type: log
  enabled: true
  paths:
    - /var/log/apache2/error.log
  fields:
    type: apache-error

output.elasticsearch:
  hosts: ["localhost:9200"]
  index: "apache-%{+yyyy.MM.dd}"

6. 业务场景

6.1 多站点日志管理

# 每个站点独立日志
<VirtualHost *:80>
    ServerName site1.example.com
    ErrorLog /var/www/site1/logs/error.log
    CustomLog /var/www/site1/logs/access.log combined
</VirtualHost>

<VirtualHost *:80>
    ServerName site2.example.com
    ErrorLog /var/www/site2/logs/error.log
    CustomLog /var/www/site2/logs/access.log json
</VirtualHost>

6.2 日志监控告警

#!/bin/bash
# monitor-apache.sh

LOG="/var/log/apache2/access.log"
ERROR_LOG="/var/log/apache2/error.log"

# 检查错误率
ERROR_RATE=$(awk '$9 >= 500' $LOG | wc -l)
TOTAL=$(wc -l < $LOG)
RATE=$((ERROR_RATE * 100 / TOTAL))

if [ $RATE -gt 5 ]; then
    echo "警告:错误率 ${RATE}%" | mail -s "Apache 错误率告警" admin@example.com
fi

# 检查响应时间
SLOW_REQUESTS=$(awk '$NF > 5000000' $LOG | wc -l)
if [ $SLOW_REQUESTS -gt 100 ]; then
    echo "警告:${SLOW_REQUESTS} 个慢请求" | mail -s "Apache 性能告警" admin@example.com
fi

7. 注意事项

  1. 日志安全:日志文件包含敏感信息,注意访问控制
  2. 磁盘空间:定期轮转日志,监控磁盘使用
  3. 性能影响:过于详细的日志会影响性能
  4. 隐私合规:遵守 GDPR 等隐私法规
  5. 备份保留:根据合规要求保留日志

8. 扩展阅读

9. 总结

Apache 日志系统功能强大:

  • 灵活格式:自定义日志格式满足不同需求
  • 条件记录:按需记录减少噪音
  • 轮转管理:自动管理日志文件生命周期
  • 分析工具:丰富的命令行和图形化工具

合理配置和分析日志是运维的重要技能。