一、日志切割与自动清理:堵住磁盘危机的源头
网站日志最基础也最容易出问题的环节。Nginx和Apache默认会把所有访问记录写进一个文件,如果不做切割,一个高流量网站的access.log能在三个月内长到几十GB。解决这个问题的是Linux自带的logrotate。大多数Linux发行版(CentOS、Ubuntu、Debian)默认都装了logrotate,它通过cron每天自动运行一次,按你设定的规则切割、压缩、删除日志文件。
宝塔面板用户的日志切割
宝塔面板内置了日志切割功能,位置在:软件商店 → 已安装 → Nginx(或Apache)→ 设置 → 日志切割。
宝塔日志切割的默认规则(Nginx)
· 日志目录:/www/wwwlogs/
· 每个网站一个独立的 .log 文件(如 yourdomain.com.log)
· 切割方式:每天凌晨自动切割一次
· 保留份数:默认保留180份(即180天的日志)
· 自动压缩:切割后的旧日志自动gzip压缩
· 访问日志和错误日志分别切割

宝塔的面板操作很方便,但如果管着多个网站,逐一进去设置"保留份数"比较低效。更高效的做法是直接编辑logrotate配置文件,一条命令覆盖所有网站日志。
# 创建宝塔网站日志的logrotate配置sudo vim /etc/logrotate.d/bt_all_sites# 写入以下内容——一条规则覆盖所有网站日志/www/wwwlogs/*.log {daily # 每天切割一次rotate 30 # 只保留最近30天missingok # 日志文件不存在也不报错notifempty # 空文件不切割compress # 旧日志用gzip压缩delaycompress # 延迟一天压缩,保留昨天日志可读sharedscripts # 所有日志处理完只执行一次postrotatedateext # 用日期命名旧日志,而非数字序号dateformat -%Y%m%d # 日期格式:yourdomain.com.log-20260725postrotateif [ -f /www/server/nginx/logs/nginx.pid ]; then/bin/kill -USR1 `cat /www/server/nginx/logs/nginx.pid`fiendscript}
保存后执行 sudo logrotate -d /etc/logrotate.d/bt_all_sites 测试一下配置是否正确(-d是debug模式,不会真的执行切割),确认无误后 sudo logrotate -f /etc/logrotate.d/bt_all_sites 强制执行一次。
grep -r "wwwlogs" /etc/logrotate.d/ 看看有没有重复匹配。如果有,删掉宝塔自带的那条规则,只保留你自己的。非宝塔环境的多站点日志切割
如果是手动安装的Nginx/Apache,每个网站的日志通常放在各自的目录下(如 /var/log/nginx/site1/、/var/log/nginx/site2/),需要在logrotate里逐目录配置,或者用一条通配规则全部覆盖:
# /etc/logrotate.d/nginx-all-sites/var/log/nginx/*/*.log {dailyrotate 14missingoknotifemptycompressdelaycompresssharedscriptspostrotate[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`endscript}
这段配置的关键是通配路径 /var/log/nginx/*/*.log:第一层星号匹配每个网站的目录名,第二层星号匹配目录下所有.log文件。一条规则覆盖所有网站,不用逐个配置。
二、日志查看与实时监控:快速定位问题的三板斧
日志切割解决的是"磁盘别被撑爆"的问题。接下来是日常最频繁的需求:某个网站突然报502了、某个API接口响应变慢了、某个IP在疯狂爬取——你得能从日志里快速找到线索。第一板斧:tail / grep / awk,命令行三件套
没有图形界面的时候,这三个命令是你最可靠的日志分析工具。
常用日志分析命令速查
| 需求 | 命令 |
|---|---|
| 实时查看最新请求 | tail -f access.log |
| 只看最近100行 | tail -n 100 access.log |
| 过滤包含"500"的行 | grep ' 500 ' access.log |
| 统计各状态码数量 | awk '{print $9}' access.log | sort | uniq -c | sort -rn |
| TOP 10 访问IP | awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10 |
| TOP 10 被访问URL | awk '{print $7}' access.log | sort | uniq -c | sort -rn | head -10 |
| 统计每小时请求量 | awk '{print $4}' access.log | cut -d: -f2 | sort | uniq -c |
| 过滤某个时间段 | grep '26/Jul/2026:14:' access.log |
命令行方案的优势是零依赖——SSH连上服务器就能用,不需要装任何东西。缺点是每次都要敲命令,没法保存分析结果,批量对比多个网站的日志时效率不高。
第二板斧:GoAccess,终端里就能看的可视化分析
GoAccess是一个开源的实时Web日志分析器,可以直接在SSH终端里运行,也能生成HTML报告在浏览器里看。它的定位介于"命令行三件套"和"ELK重型方案"之间——比命令行直观,比ELK轻量。
Ubuntu/Debian:
sudo apt install goaccessCentOS:
sudo yum install goaccess实时查看单个网站日志:
goaccess /www/wwwlogs/yourdomain.com.log --log-format=COMBINED生成HTML报告:
goaccess /www/wwwlogs/yourdomain.com.log -o report.html --log-format=COMBINEDGoAccess能自动统计的内容包括:每日独立访客数、请求文件类型分布、状态码分布、访问来源域名、浏览器和操作系统分布、404错误URL排行、访问量最高的页面、爬虫访问统计。这些数据在终端里用彩色直方图和表格展示,比裸看日志直观得多。

批量管理多个网站时,可以写一个Shell脚本循环生成所有网站的报告:
#!/bin/bash# 批量生成所有网站的GoAccess报告LOG_DIR="/www/wwwlogs"REPORT_DIR="/www/wwwroot/reports"mkdir -p $REPORT_DIRfor logfile in $LOG_DIR/*.log; dositename=$(basename "$logfile" .log)goaccess "$logfile" \--log-format=COMBINED \-o "$REPORT_DIR/$sitename.html"echo "报告已生成:$sitename.html"done
这个脚本跑一遍,所有网站的流量报告就都在一个目录下了,设个密码保护后直接在浏览器里看。
第三板斧:在线日志分析工具,不用装东西直接上传
如果不想在服务器上装任何工具,还有一些在线日志分析平台,上传日志文件就能出报告:
| 工具 | 免费额度 | 支持格式 | 特点 |
|---|---|---|---|
| Log.ink | 免费 | Apache/Nginx | 纯在线,拖拽上传,支持爬虫检测和用户行为分析 |
| ElysiaTools Log Parser | 免费 | Apache/Nginx/自定义 | 支持自定义正则解析,灵活度高 |
| IPIN 日志分析 | 免费 | Apache/Nginx | 国内访问快,支持中文界面 |
三、集中式日志管理:多台服务器几十个网站的统一方案
当服务器超过两台、网站超过十个,"SSH连到每台机器上去翻日志"的模式就彻底崩了。出问题的时候你得先回忆"这个网站部署在哪台服务器上",然后连上去、找到对应的日志文件、开始分析——中间至少浪费三分钟。集中式日志管理解决的就是这个问题:所有服务器的日志汇聚到一个地方,统一查询、统一分析。| 方案 | 部署难度 | 资源消耗 | 适合规模 | 一句话定位 |
|---|---|---|---|---|
| Loki + Grafana | 中等 | 低 | 中小团队首选 | 轻量级、省资源、和Prometheus无缝集成 |
| ELK Stack | 高 | 高 | 大型团队 | 功能最全但吃资源,至少4核8G起步 |
| rsyslog + 中央日志服务器 | 低 | 极低 | 最简方案 | Linux自带,一条配置转发,零额外组件 |
Loki + Grafana:中小团队的最佳平衡点
Loki是Grafana Labs开源的日志聚合系统,设计理念是"像Prometheus一样处理日志"。它不索引日志内容本身(只索引标签),存储成本比ELK低80-90%,资源消耗也小得多。一台2核4G的轻量云服务器就能跑起来,对于管理10-30个网站的日志绰绰有余。
· Promtail(装在各台Web服务器上):采集Nginx/Apache日志文件,推送给Loki
· Loki(装在中央日志服务器上):接收、存储、索引日志
· Grafana(同一台或单独部署):查询和可视化日志
部署流程:①在中央服务器上用Docker Compose部署Loki+Grafana;②在各台Web服务器上安装Promtail;③配置Promtail采集/www/wwwlogs/目录下的所有.log文件,自动添加host和site标签区分来源;④在Grafana里用LogQL语法查询——
{site="shop"} |= "500" 就能跨所有服务器搜索shop网站日志里的500错误。Loki的查询语法(LogQL)非常接近PromQL,熟悉Prometheus的人上手很快。几个常用查询示例:
# 查询某网站的所有500错误{site="yourdomain.com"} |= " 500 "# 查询所有网站最近1小时的404数量sum(count_over_time({job="nginx"} |= " 404 "[1h]))# 按网站分组统计请求量TOP 5topk(5, sum by (site) (rate({job="nginx"}[5m])))# 搜索包含特定IP的日志{job="nginx"} |= "192.168.1.100"
ELK Stack:功能最强但门槛最高
ELK(Elasticsearch + Logstash + Kibana)是集中式日志管理的事实标准,搜索引擎级别的全文检索能力、强大的可视化仪表盘、海量的插件生态。但代价也很明显:Elasticsearch是Java写的,内存消耗大,单节点至少分配2GB堆内存;Logstash处理日志时CPU占用高;整套部署下来,一台4核8G的服务器是最低配置。
rsyslog:零额外组件的极简方案
如果对可视化没有要求,只希望"所有服务器的日志自动汇聚到一台机器上,用grep就能查",rsyslog是最简单的方案。它是Linux自带的系统日志服务,不需要安装任何新软件。
# === 中央日志服务器(192.168.1.10)===# 编辑 /etc/rsyslog.conf,启用UDP接收sudo vim /etc/rsyslog.conf# 取消注释这两行:module(load="imudp")input(type="imudp" port="514")# 添加日志存储模板,按来源IP分目录$template RemoteLogs,"/var/log/remote/%FROMHOST-IP%/%$YEAR%-%$MONTH%-%$DAY%.log"*.* ?RemoteLogssudo systemctl restart rsyslog# === 各台Web服务器 ===# 在 /etc/rsyslog.d/50-default.conf 末尾添加:*.* @192.168.1.10:514sudo systemctl restart rsyslog# Nginx日志也要转发——在nginx配置中加:access_log syslog:server=192.168.1.10:514,tag=nginx_access;error_log syslog:server=192.168.1.10:514,tag=nginx_error;
rsyslog方案的好处是零额外组件、配置简单、极其稳定。缺点是查询能力弱——只能在中央服务器上用grep翻文本文件,没有全文索引、没有可视化仪表盘。适合"只要能集中查看就行"的简单需求。
四、日志清理与磁盘空间管理
日志切割只是把大文件拆成了小文件,旧的日志文件如果不删,磁盘早晚还是会满。这一节说几个防止日志撑爆磁盘的实操方法。设置日志保留天数
在logrotate配置中,rotate 30 表示保留30个轮转文件。如果配置了 daily,就是保留30天;如果配置了 weekly,就是保留30周。根据网站流量调整这个数字——高流量网站(日访问量10万+)建议保留7-14天,低流量网站可以保留30-90天。保留多久取决于"出问题后你需要回溯多久的日志",而不是"磁盘还能放多少"。

按大小切割,不按时间
logrotate支持 size 100M 参数——日志文件超过100MB就切割,不管时间。这个策略比"每天切一次"更适合流量不稳定的网站(有的网站可能一周才产生10MB日志,每天切一次浪费;有的网站一天就产生2GB日志,等不到第二天就撑爆磁盘)。可以 daily 和 size 100M 同时配置,哪个先满足就执行哪个。
定时清理过期日志的cron脚本
logrotate负责切割,但如果配置出错或者有些日志不在logrotate管理范围内,还需要一个兜底清理脚本。在crontab里加一条:0 3 * * * find /www/wwwlogs/ -name "*.log-*" -mtime +30 -delete——每天凌晨3点删除/www/wwwlogs目录下所有修改时间超过30天的日志归档文件。再加一条:0 3 * * 0 find /www/wwwlogs/ -name "*.gz" -mtime +14 -delete——每周日凌晨删除14天前的压缩日志。这个兜底机制能防止logrotate失效或配置遗漏导致的磁盘爆满。
磁盘使用率监控告警
日志文件膨胀导致磁盘满了,最糟糕的不是日志太多,而是你直到网站挂了才知道磁盘满了。在宝塔面板的"计划任务"中添加一个Shell脚本,每30分钟检查一次磁盘使用率,超过80%就发通知:USE=$(df -h / | tail -1 | awk '{print $5}' | sed 's/%//'); if [ $USE -gt 80 ]; then echo "磁盘使用率${USE}%,请检查日志" | mail -s "磁盘告警" admin@yourdomain.com; fi。或者用宝塔自带的面板通知功能,不用配邮件服务器。
五、按场景和规模,对号入座
| 你的情况 | 推荐方案 | 核心工具 |
|---|---|---|
| 1台服务器,5个以内网站 | 宝塔面板自带的日志切割 + 定时清理计划任务 | 宝塔面板 |
| 1-2台服务器,10-30个网站 | logrotate统一配置 + GoAccess生成报告 + cron兜底清理 | logrotate + GoAccess |
| 3-5台服务器,30+个网站 | Loki + Grafana集中收集,logrotate在各台机器上本地切割 | Loki + Grafana + logrotate |
| 5台以上服务器,海量日志 | ELK Stack 或 Loki集群方案 | ELK / Loki集群 |
| 只要简单集中查看,不要可视化 | rsyslog转发到一台中央服务器,grep查询 | rsyslog |
六、三条日志管理的底线规则
第一条:切割是底线,不是可选项
任何上线超过一周的网站,日志切割必须在第一天就配好。不切割的日志文件会无限增长,一旦磁盘满了,不仅网站挂了,MySQL、Redis等服务也可能因为写不进数据而崩溃。配好logrotate只需要5分钟,但磁盘爆满后的恢复可能需要半天。
第二条:集中管理的前提是日志格式统一
如果你计划上Loki或ELK做集中式日志管理,第一步不是装软件,而是统一所有网站的Nginx日志格式。如果有的网站用combined格式、有的用自定义格式、有的日志里没有记录响应时间——到了集中平台里这些日志就没法统一查询。所有网站统一用 log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time'; 这种标准格式,后续的一切分析工具才能正常工作。
第三条:清理前先确认备份策略
日志删了就没了。在设置"保留30天自动删除"之前,确认一下:出安全事件后需要溯源多久之前的日志?一般建议网站访问日志至少保留30天,安全审计相关日志至少保留90天。如果磁盘空间紧张,可以把超过30天的日志压缩后归档到对象存储(阿里云OSS、腾讯云COS等),既省磁盘空间又能长期保留。
七、UC建站系统的日志管理
UC建站系统在日志管理方面,已经把前面说的"切割+清理+分析"三个层次内置到了系统里:
· 自动日志切割:建站时自动配置好logrotate,网站日志按天切割、自动压缩、默认保留30天
· 后台日志看板:UC建站后台内置了访问日志统计面板,不用连SSH就能查看每个网站的访问趋势、状态码分布、热门页面
· 磁盘告警联动:日志目录使用率超过80%时,后台自动弹通知提醒清理
· 一键日志清理:后台提供"清理N天前日志"按钮,选天数一键执行,不用敲命令
· 多站统一管理:不管建了多少个网站,所有日志设置和清理操作都在一个后台面板里完成
对于多网站管理的场景,UC建站系统的日志模块省去了手动配logrotate、写cron脚本、搭监控告警这三件套的麻烦。
日志管理这件事有一个很奇怪的特点:平时你不会想起它,出问题的时候你会恨自己为什么没早点弄好它。花一个下午把logrotate配置好、把磁盘告警加上、把清理脚本放进crontab,换来的是一年都不用在半夜被"磁盘满了"的告警吵醒。
