Linux服务器日志怎么管才不爆盘又查得到问题?logrotate与journald实战
本文目录
- 服务器出了事,第一个该看的为什么是日志?
- 独立站服务器上到底有哪些日志,都记在哪?
- 日志不清理会怎样,logrotate是怎么救磁盘的?
- logrotate的配置该怎么写才不丢日志、不爆盘?
- systemd的journald和传统文本日志是什么关系?
- journalctl怎么用,才能快速从海量日志里捞到问题?
- 日志里到底该盯哪些信号,怎么从噪声里看出问题?
- 怎么把被动查日志变成主动告警?
- 日志量大了,要不要做集中化和异地留存?
- 日志管理的落地顺序和最容易踩的5个坑是什么?
- 常见问题解答
- 我的服务器磁盘突然满了,怀疑是日志,怎么快速定位是哪个日志撑的?
- logrotate里的copytruncate和create,到底该用哪个?
- journald已经记日志了,我还需要logrotate和rsyslog吗?
- journalctl命令太多记不住,最常用的几条是什么?
- 日志告警怎么设才不会被一堆没用的告警淹没?
- 单机用grep翻日志就够了,什么时候才需要做日志集中化?
- 权威参考资料
日志是服务器出事时唯一不会撒谎的目击者,可大多数独立站站长平时根本不看它,直到有一天磁盘被日志撑满、站点500,才手忙脚乱地去翻——还翻不明白。
日志管理其实是两件事:一是别让它把盘撑爆,这靠logrotate做轮转、压缩、按量保留;二是出事时能快速从海量记录里捞到真正的那条线索,这靠看懂日志都在哪、用journalctl之类的工具会过滤、知道该盯哪些信号。保哥这篇不堆命令手册,而是从一台独立站服务器的真实运维场景出发,把日志都在哪、怎么轮转不爆盘、怎么用journald和journalctl查、该盯哪些异常信号、怎么把被动翻日志变成主动告警,一段段讲清楚,最后给落地顺序和最容易踩的坑。
服务器出了事,第一个该看的为什么是日志?
保哥处理过不少独立站的线上事故,规律很明显:能快速恢复的,几乎都是第一时间去看了日志;折腾大半天还摸不着头脑的,往往是日志平时没管、出事时要么找不到、要么被噪声淹没、要么早被磁盘撑爆覆盖了。
日志这东西平时存在感极低,没人会盯着它看,可一旦出事,它是唯一不会撒谎的目击者——502是后端挂了还是超时了、数据库为什么突然变慢、是谁在暴力破解你的SSH、磁盘到底被什么撑满了,答案全写在日志里。不会看日志,排障就只能靠猜和重启大法,运气好蒙对,运气不好把小问题拖成大事故。
但日志也是把双刃剑:不管它,它会反过来咬你——高流量站的访问日志一天能涨好几个G,一段疯狂报错的代码能在几小时内把磁盘刷爆,磁盘一满,站点直接500,本来没事也被日志搞出事。所以日志管理是攻守两面:守的是别让它撑爆磁盘,攻的是出事时能从海量记录里快速捞到线索。
这篇文章就从一台独立站服务器的真实运维场景出发,不堆命令手册,把日志都记在哪、怎么用logrotate轮转不爆盘、怎么用journald和journalctl查、该盯哪些异常信号、怎么把被动翻日志变成主动告警,一段段讲清楚,最后给落地顺序和踩坑清单。
独立站服务器上到底有哪些日志,都记在哪?
先把家底摸清。一台跑着独立站的Linux服务器,日志大致分这么几摊,绝大多数都集中在 /var/log这个目录下。
Web服务器日志是你最常打交道的。Nginx或Apache各有access日志(每个请求一条,记了谁在什么时候访问了什么、返回了什么状态码)和error日志(记服务器自己的报错)。access日志是流量大户,高流量站涨得飞快;error日志则是排查502、配置错误的第一现场。
应用与运行环境日志。PHP-FPM有自己的错误日志,应用框架(WordPress、Magento等)往往还会写自己的日志文件。这些是排查代码报错、白屏、功能异常的关键。数据库日志里,MySQL/MariaDB的错误日志和慢查询日志尤其重要——站点变慢,慢查询日志常常一翻一个准。
系统与安全日志。系统消息(messages或syslog)记内核和系统服务的动静;认证日志(auth.log或secure)记登录、提权、SSH尝试,是发现暴力破解的窗口;内核日志里还藏着OOM Killer杀进程、磁盘IO错误这类硬伤的记录。
除了这些落成独立文本文件的日志,systemd体系下还有一套 journald 管理的二进制日志,几乎收录了所有systemd管理的服务的输出。它和文本日志是什么关系、怎么查,后面专门讲。先记住一句:不知道日志在哪,排障就无从下手,花十分钟把你这台机器上各服务的日志路径列一张清单,是日志管理的第一步。
日志不清理会怎样,logrotate是怎么救磁盘的?
日志只进不出,结局只有一个——把磁盘撑爆。保哥见过太多次半夜站点挂掉,登上去一看磁盘100%,元凶就是某个无人看管、疯长的日志文件。磁盘一满,数据库写不进、缓存写不了、新日志也记不下,整站瘫痪,而且这种故障往往发生在流量高峰,最要命。
解决它的标准工具就是 logrotate。它干的事很朴素却很关键:定期把当前日志文件归档(改名、通常还压缩),然后让程序从一个干净的空文件重新开始写,并按你设定的份数只保留最近的若干个归档、把更老的自动删掉。这样日志既不会无限膨胀,又保留了最近一段时间可供排查,磁盘占用被牢牢控制在一个可预期的范围内。
logrotate通常由系统的定时任务(cron或systemd timer)每天触发一次,它读取配置目录里各个服务的轮转规则,挨个检查该不该轮转。大多数发行版装Nginx、Apache、MySQL时会自带各自的logrotate配置,但自带配置未必贴合你的流量和磁盘大小——默认保留的份数、轮转频率,对一个流量暴涨的站可能远远不够,需要你按实际情况调。
这件事和服务器自动化运维是一脉相承的:备份、清缓存、续证书、日志轮转,本质都是把该定期干的运维动作交给定时任务自动跑。保哥在独立站服务器怎么用cron把运维自动化那篇里系统讲过这套自动化运维的搭法,日志轮转就是其中一环,配合着看会更完整。
logrotate的配置该怎么写才不丢日志、不爆盘?
logrotate的配置不复杂,但几个关键指令选错就会丢日志或者白轮转。保哥把一份典型的Nginx日志轮转配置拆开讲。
/var/log/nginx/*.log {
daily # 每天轮转一次
rotate 14 # 只保留最近 14 份
compress # 归档后压缩,省空间
delaycompress # 推迟一轮再压,避免压到还在写的文件
missingok # 日志不存在不报错
notifempty # 空文件不轮转
create 0640 nginx adm # 新建日志文件并设好权限属主
sharedscripts # 多个匹配文件只跑一次脚本
postrotate
# 通知 nginx 重新打开日志文件,从新文件继续写
nginx -s reopen 2>/dev/null || true
endscript
}逐个看关键项。daily/weekly 定轮转频率,流量大的站用daily,小站weekly足够。rotate N 定保留份数,这是控制总占用的核心——daily + rotate 14就是大约保留两周。算一笔账:日均日志量 × 保留份数,得出大致峰值占用,确认它远小于磁盘剩余空间,才叫安全。
compress + delaycompress 让归档压缩省空间,delaycompress推迟一轮压缩,避免压到那个刚轮转、可能还有进程在收尾写入的文件。create 在轮转后新建一个空日志并设好权限属主,postrotate 里的脚本则通知服务重新打开日志文件——这一对配合,是不丢日志的关键机制。
最容易选错的是怎么让进程换到新文件。主流做法是create配postrotate给进程发信号重开日志(Nginx用reopen、很多服务用reload),干净不丢数据;另一种copytruncate是先复制再清空原文件,适合不支持重开日志的程序,但复制和清空之间那一瞬的日志可能丢。
能用前者就用前者,这点保哥在文末FAQ里展开讲了。配置写完务必用logrotate的调试/演练模式先空跑验证一遍,确认轮转行为符合预期再上线。logrotate每个指令的确切含义和取值,man手册讲得最权威man7.org — logrotate(8) Linux manual page(日志轮转配置手册),拿不准的指令直接查它。
systemd的journald和传统文本日志是什么关系?
现代Linux发行版几乎都用systemd,它自带一个日志服务叫 journald,很多人对它和传统文本日志的关系一头雾水,这里捋清楚。
journald把日志存成二进制格式(不是你能直接cat的纯文本),统一收集systemd管理的各个服务的标准输出、内核消息、系统事件,带上丰富的结构化字段(哪个服务、哪个进程、什么优先级、什么时间)。它的强项是查询——用journalctl能按服务单元、按优先级、按时间精准过滤,比在一堆文本文件里grep高效得多。
但要注意:很多软件并不走journald。Nginx、Apache、MySQL这类,默认仍然把日志写成自己的独立文本文件放在 /var/log下,自成一套。所以你的服务器上其实是两套日志并存——journald管systemd服务和系统层面的,独立文本文件管那些自己写日志的应用。这就是为什么前面讲的logrotate(管文本文件)和这里的journald都需要,它们管的不是同一摊东西。
journald还有两个必须配的点。一是持久化:默认在某些系统上journald的日志是存在内存或临时目录里的,重启就没了;要让它落到磁盘长期保留,得开启持久化存储。
二是体积上限:journald的二进制日志如果不设上限,也会越积越多占磁盘,它有自己的配置项来限制最大占用和保留时长——这部分不归logrotate管,靠journald自己的配置文件控制。这些持久化和上限参数怎么设,官方配置手册写得很清楚man7.org — journald.conf(5) Linux manual page(journald持久化与上限配置),按它把上限和持久化设好,journald就既不丢关键日志、又不会偷偷吃满磁盘。
journalctl怎么用,才能快速从海量日志里捞到问题?
journald的日志靠 journalctl 来查,会用它,海量日志里捞针也不慌。不用记全部参数,几条组合覆盖九成场景。
按服务查是最常用的:journalctl -u服务名,比如查Nginx就journalctl -u nginx,查PHP-FPM就journalctl -u php-fpm。一下子就把茫茫日志收窄到某个服务。
按优先级过滤:加 -p err只看错误及更严重的,把一堆info、debug的噪声滤掉,故障排查时这一招最省眼睛。按时间过滤:--since和 --until圈定时段,--since today、--since "09:00"、--until "10:00" 这类,定位某次故障发生的时间窗特别好用。
实时跟踪:加 -f,效果像tail -f,配合 -u盯某个服务的实时输出,一边复现问题一边看日志滚动。按开机批次:-b只看本次开机以来,-b -1看上一次开机,排查重启相关问题时用得上。
这些组合能拼起来用,威力倍增。比如journalctl -u php-fpm -p err --since today就是今天PHP-FPM的全部错误;再接管道grep过滤关键字、用 -n限制只看最近多少行,基本够用。
保哥的建议是把最顺手的几条存成shell别名,排障时手就有肌肉记忆,不用临时查参数。journalctl的完整用法和每个参数,官方手册是最准的参考man7.org — journalctl(1) Linux manual page(systemd日志查询手册),想深挖按它学。
日志里到底该盯哪些信号,怎么从噪声里看出问题?
会查日志只是工具,知道该盯什么才是本事。日志九成是正常噪声,真正有价值的是那些异常信号。保哥按重要程度列几类该重点盯的。
HTTP 5xx状态码突增。access日志里500、502、503、504的占比和绝对数量突然抬头,是后端出问题最直接的信号——502/504多半是后端PHP-FPM或上游超时、挂了,500多半是应用代码报错。把5xx按时间和URL聚一下,常能直接定位到出事的接口或时间点。
error级别的日志条目。无论是Web服务器、PHP还是数据库的error日志,error及以上级别的条目都该认真对待。尤其要警惕短时间内同一条错误疯狂刷屏——它既是bug的信号,也是磁盘的杀手。
OOM Killer和资源耗尽。系统日志里如果出现OOM Killer杀进程的记录,说明内存被打满,系统在强杀进程自保——这往往解释了为什么某个服务莫名其妙就没了。磁盘IO错误、磁盘将满的告警同样要第一时间处理。
认证失败与暴力破解。认证日志里大量失败的SSH登录尝试、来自陌生IP的高频尝试,是有人在暴破你的服务器,这类安全信号必须盯紧并采取措施。数据库慢查询。慢查询日志里反复出现的慢SQL,是站点变慢的常见根因,值得定期回看、针对性优化。
把日志和性能排查结合起来看效果最好——很多时候是先从监控发现负载异常,再回日志里找对应时段的具体记录定位根因。这套从现象到日志的排查方法,保哥在Linux服务器高负载与性能排查那篇里讲得更系统,和日志分析是天然的一对。
怎么把被动查日志变成主动告警?
出了事才去翻日志,永远是慢一拍。运维的进阶,是把被动查变成主动告警——问题刚冒头,系统就主动喊你,而不是等用户投诉、等站挂了你才知道。
告警的素材大多就来自日志:5xx突增、error刷屏、磁盘将满、认证失败激增、慢查询变多,这些都能设成触发条件。实现上可以从简单到复杂——简单的用脚本定时扫日志、命中关键字或超过阈值就发通知;复杂的接入监控告警系统,把日志指标化后设规则。一个典型的、基于日志的现成例子是fail2ban:它持续盯认证日志,发现某个IP短时间内大量登录失败,就自动封禁这个IP,这正是日志驱动的自动响应。
但告警最大的敌人不是技术,是告警疲劳。告警太多太杂,时间一长全被当成背景噪声忽略,真正要命的告警混在里头也被一起略过。避免它有几个原则:分级,只有必须立刻处理的(站挂、磁盘快满、5xx暴增)才即时推送,其余进日报;去抖,同一问题短时间反复触发要聚合抑制,别刷出几百条;阈值留余量,磁盘到80% 就提醒别等撑爆;每条告警都可执行,收到的人知道该干嘛。
保哥的经验是:告警规则不是配一次就完,要定期修剪——把从来没人据此行动的删掉,把漏报过的补上,让告警列表始终精炼可信。一个让人信任、收到就会认真看的告警系统,比一百条没人看的告警有用得多。这些日志扫描、告警脚本同样适合交给定时任务跑,和前面的自动化运维是同一套思路。
日志量大了,要不要做集中化和异地留存?
单机的grep加journalctl,在小站、单台服务器的场景下完全够用,没必要一上来就堆重型日志平台,那是过度工程。但规模一上去,单机方案就会撞墙,这时候才该考虑集中化。
该上集中化的信号很明确。一是服务器从一台变多台——出问题你不知道该上哪台翻,挨个登录grep效率极低,把日志汇总到一处统一查就成了刚需。二是日志量大到单机查都嫌慢,或者你要做跨时间的趋势分析、做可视化仪表盘。三是合规与安全要求——需要日志异地留存、防篡改、保留指定时长,本机日志一旦服务器被入侵或损坏就全没了,异地留一份才有底气。四是要做关联分析,把Web层、应用层、数据库层的日志按请求串起来看全链路。
异地留存这件事,本质和灾备是一个道理——你不能假设承载日志的这台机器永远不出事。服务器被黑、磁盘损坏、误操作,本机日志就跟着没了,而这恰恰是你最需要日志来复盘的时刻。把关键日志按一定策略同步到异地、保留足够时长,是运维韧性的一部分。这套异地留存、恢复演练的思路,和保哥在网站灾备恢复演练那篇讲的备份哲学是相通的,日志的异地留存可以纳进同一套灾备规划里一起做。
在这些信号真正出现之前,保哥不建议盲目上集中化平台。先把单机的logrotate、journald持久化与上限、基础告警这些地基打牢,等规模真逼到那一步,再上集中化也不迟——地基不牢就上重型平台,往往是钱花了、问题还在。
日志管理的落地顺序和最容易踩的5个坑是什么?
道理讲完,落地按什么顺序来?保哥把一台独立站服务器的日志治理整理成一条线。
顺序上,先摸清、再防爆、配查询、建告警、按需集中。第一步把这台机器上各服务的日志路径列成清单,知道东西在哪;第二步给所有会增长的文本日志配好logrotate,给journald设好持久化和体积上限,先堵住爆盘风险;第三步把journalctl常用组合和文本日志的grep套路练熟,确保出事能快速捞;第四步针对最关键的几个信号(5xx、磁盘、认证失败)建起精炼的主动告警;第五步等规模逼上来了再上集中化和异地留存。
再说5个最容易踩的坑:
坑一:日志没配轮转,磁盘被悄悄撑爆。头号坑——某个无人看管的日志疯长,磁盘满了整站瘫痪,往往还挑在流量高峰发作。
坑二:直接rm正在写入的大日志。删了空间不释放(进程还攥着文件句柄),得清空内容或重启服务才回收,应急时容易越搞越乱。
坑三:journald没设持久化和上限。要么重启日志就没了、丢了关键现场,要么二进制日志没上限偷偷吃满磁盘。
坑四:copytruncate用在能reload的服务上。该用create + postrotate重开日志的却用了copytruncate,凭空多担了一份丢日志的风险。
坑五:告警配得又多又杂,最后全被忽略。告警疲劳让真正要命的告警淹没在噪声里,等于没告警还更糟。
把这条顺序和这5个坑当成一份运维自查表,新接手一台服务器就过一遍。日志管理不性感,平时也没人夸,但它是运维的底盘——盘没被撑爆、出事能查到、问题能主动报,靠的全是这些不起眼的日志功夫。Apache、Nginx这些Web服务自身的日志和性能调优是连在一起的,保哥在Apache性能调优与高并发稳定性那篇里也讲过服务层日志怎么配合排查,做日志管理时可以串起来看。
常见问题解答
我的服务器磁盘突然满了,怀疑是日志,怎么快速定位是哪个日志撑的?
先别急着乱删。第一步用du按目录大小排查,重点看 /var/log这个日志大本营,可以从这个目录往下逐层看哪个子目录、哪个文件最大。常见的撑盘元凶是Web服务器的access日志(高流量站一天能涨好几个G)、PHP或应用的error日志(如果代码在疯狂报错、刷错误,会爆炸式增长)、还有journald的二进制日志如果没设上限也会越积越多。定位到具体大文件后,不要直接rm一个正在被进程写入的日志文件——删了之后磁盘空间往往不会立刻释放,因为进程还攥着这个文件句柄,得等进程重开日志或者重启服务才真正回收。正确的应急做法是用清空内容的方式(把文件截断成空)而不是删除文件本身,再尽快配上logrotate把这件事自动化,免得下次又被撑爆。根治还得回头看为什么某个日志涨这么快——往往是某段代码在刷错误,那才是真问题。
logrotate里的copytruncate和create,到底该用哪个?
这是logrotate配置里最容易选错、也最容易丢日志的一个点。两者解决的是同一个问题——轮转时如何不打断正在写日志的进程——但机制不同。create(默认搭配postrotate重载)的做法是:把当前日志改名归档,然后新建一个空日志文件,再通过postrotate脚本给写日志的进程发信号让它重新打开日志文件,从此写到新文件里。这种方式干净、不丢数据,但前提是那个进程支持收到信号后重开日志(像Nginx、Apache都支持,reload一下即可)。copytruncate的做法是:先把当前日志复制一份做归档,再把原文件内容清空(截断),进程对此无感、继续往原文件写。它适合那些不支持重开日志信号的程序,但有个固有风险——在复制和截断之间的那一瞬间写入的日志可能丢失。保哥的原则是:能用create + postrotate reload的(绝大多数主流服务都能)就优先用它,不丢数据;只有当程序确实不支持重开日志时,才退而用copytruncate。
journald已经记日志了,我还需要logrotate和rsyslog吗?
要看你的系统怎么配的,但大多数生产服务器是两套并存、各管一摊。journald是systemd自带的日志服务,它把日志存成二进制格式,用journalctl查询很方便,还能按服务单元、优先级、时间精准过滤——这是它的强项。但很多软件(尤其是Nginx、Apache、MySQL这类)默认仍然把自己的日志写成独立的文本文件,放在 /var/log下,并不走journald。这些文本日志就需要logrotate来轮转,否则会无限增长。rsyslog则常作为传统的syslog收集器存在,有些系统里journald会把日志转发给它落成文本,方便转发到远程日志服务器。所以实务上:journald管systemd体系下的服务和系统日志、并控制自身大小;logrotate管那些写成独立文本文件的应用日志;rsyslog在需要文本落地或集中转发时出场。三者不冲突,是分工,自身的体积上限则靠journald的配置文件控制、不归logrotate管。
journalctl命令太多记不住,最常用的几条是什么?
不用全记,记住几条组合就能覆盖九成排查场景。看某个服务的日志:journalctl -u服务名,比如journalctl -u nginx。只看错误级别以上的:加 -p err(p是priority优先级,err表示错误及更严重的)。看某个时间段:用 --since和 --until,比如 --since today或 --since 09:00 --until 10:00,定位某次故障发生时段特别有用。实时盯日志(像tail -f那样):加 -f,配合 -u盯某个服务的实时输出。只看本次开机以来的:-b(这次启动),看历史某次开机用 -b -1。把这几条拼起来威力很大,比如journalctl -u php-fpm -p err --since today就是今天PHP-FPM的所有错误。再配合管道接grep过滤关键字、用 -n限制行数,基本上海量日志里捞针都够用了。保哥的建议是把最常用的几条存成shell别名,排查时手就有肌肉记忆。
日志告警怎么设才不会被一堆没用的告警淹没?
告警疲劳是日志告警的头号杀手——告警太多太杂,时间一长大家就全当背景噪声忽略,等真出大事的告警混在里面,也被一起略过了。避免它的核心是只为真正需要人立刻介入的事件告警,其余的降级成报表定期看。具体几个原则:第一,分级——把告警分成必须立刻处理(站挂了、磁盘快满、大量5xx)和事后看看就行(个别慢查询、零星404),只有前者推送即时通知,后者进日报。第二,去抖——同一类问题短时间内反复触发,要做聚合和抑制,别让一个故障刷出几百条告警。第三,给阈值留余量但别太钝——磁盘用到80% 就该提醒,而不是等100% 撑爆才报。第四,每条告警都要可执行——收到告警的人得知道该去干嘛,否则就是噪声。保哥的经验是:告警规则要定期回头修剪,把那些从来没人据此行动的告警删掉,把漏报过的补上,让告警列表始终保持精炼可信。
单机用grep翻日志就够了,什么时候才需要做日志集中化?
单机加grep、journalctl在小站、单台服务器的场景下完全够用,没必要一上来就上重型的日志平台,那是过度工程。真正该考虑集中化的信号有几个:一是服务器从一台变成多台——这时候出问题你不知道该上哪台去翻,挨个登录grep效率极低,把日志汇总到一处统一查就成了刚需。二是日志量大到单机grep都嫌慢、或者你需要做跨时间的趋势分析、做仪表盘看可视化。三是合规或安全要求——某些场景需要日志异地留存、防篡改、保留指定时长,本机日志一旦服务器被入侵或损坏就全没了,异地留一份才有底气。四是需要做关联分析——把Web层、应用层、数据库层的日志按请求串起来看。在这些信号出现之前,保哥不建议盲目上集中化平台,先把单机的logrotate、journald持久化、基础告警这些地基打牢,等规模真的逼到那一步,再上集中化也不迟。
权威参考资料
FAQPage + Article AI 引用友好版
磁盘被日志撑爆、站点500才去翻日志,还翻不明白。保哥这篇从独立站运维场景拆Linux日志管理:日志都在哪、logrotate怎么轮转不爆盘、journald与journalctl怎么查、该盯哪些异常信号、怎么从被动翻日志变主动告警,给落地顺序和踩坑清单。
- 服务器运维
- Linux
- 日志管理
- logrotate
- journald
title: Linux服务器日志怎么管才不爆盘又查得到问题?logrotate与journald实战 author: 张文保 (Paul Zhang) — PatPat SEO 经理 url: https://zhangwenbao.com/linux-server-log-management-logrotate-journald-analysis-alerting.html published: 2026-04-29 modified: 2026-04-29 source-type: First-hand expert commentary language: zh-CN license: CC BY-NC-SA 4.0 (要求保留原文链接与作者归属)
本文标题:《Linux服务器日志怎么管才不爆盘又查得到问题?logrotate与journald实战》
本文链接:https://zhangwenbao.com/linux-server-log-management-logrotate-journald-analysis-alerting.html
版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0