ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Ubuntu日志管理实战:journald、rsyslog、logrotate三驾马车详解

Ubuntu日志管理实战:journald、rsyslog、logrotate三驾马车详解 废话不多说第7课咱们聊一个平时感知不强、但出问题时能救命的主题——日志管理。很多新手拿到一台 Ubuntu 服务器之后第一反应就是到处翻/var/log目录看到一堆.log文件就以为日志管理不过如此。真到排查故障的时候才发现日志乱成一团、文件大到打不开、重启之后历史日志全没了甚至磁盘被日志写满导致服务崩溃这些问题全部指向同一个答案你还没有把 Ubuntu 的日志体系真正摸透。这一篇我打算把 Ubuntu 日志管理里的三驾马车一次讲清楚rsyslog、journald、logrotate。不看官方文档那种照本宣科式的堆砌只讲实际运维中怎么用、为什么这么用以及哪些坑我用几百个小时的踩坑经历帮你提前填了。不管你是刚接触 Linux 的小白还是已经部署过几个项目的进阶玩家这篇都可以当成一份随手能查的日志管理实操手册。1. 先把日志体系捋清楚rsyslog、journald、logrotate 到底各管什么很多人一上来就直接查命令、背参数结果越学越乱因为脑子里面没有一个整体架构图。Ubuntu 的日志体系不是某一款软件单打独斗而是三个组件各管一段、互相配合少了一个都会出问题。先说 journald。它是 systemd 自带的日志守护进程从 Ubuntu 15.04 之后就跟 systemd 深度绑定在一起。它的最大特点是“中央车站”系统里所有服务的标准输出、内核日志、启动信息只要交给 systemd 管理的都会自动汇入 journald。也就是说不管这个服务的日志原本想往哪里写journald 都能拦一份下来用二进制格式存在内存或磁盘上你用journalctl命令就能统一查询。这个设计非常方便但代价是它是二进制格式普通cat、tail看不出来内容必须借助专用工具。再说 rsyslog。它在 Ubuntu 里是老牌选手了负责的是“分流与归档”。journald 把日志收进来rsyslog 则按你定义的规则把日志写到具体的文本文件里或者转发到远程日志服务器。很多老运维习惯了直接看/var/log/syslog、/var/log/auth.log这些其实都是 rsyslog 根据配置文件生成的文本日志。rsyslog 的强项是灵活的路由规则和成熟的远程转发机制在集中式日志、安全审计场景里非常重要。最后说 logrotate。它是一个日志轮转工具核心解决一件事避免单个日志文件无限膨胀。日志持续增长是必然的如果不处理一个文件的体积能涨到上百 GB磁盘被打满只是时间问题。logrotate 通过定期切换、压缩、删除历史日志来控制磁盘占用是日志管理的最后一道防线。这三个组件的关系可以类比成一个完整的日志处理流水线journald 负责源头采集rsyslog 负责按需派发logrotate 负责定期清理归档。三者配合好了系统的日志才既完整、又干净还不会吃光磁盘。1.1 三个组件如何分工协作一张说明理清职责边界我在教学的时候喜欢让学生先记住一句话journald 管收集rsyslog 管网关logrotate 管轮转。可以把这个结构想象成一个快递分拣中心——各业务线产生的包裹日志先全部送到总站journald总站扫描分类后有的按目的地送上长途车有的放到自提柜rsyslog 分流到文件/远程但快递柜再大也有容量上限所以仓管员logrotate定期清理旧包裹腾出空间装新货。实际干活的时候你差不多会按照下面的链路来理解服务进程带着自己的日志请求直接走 systemd 的标准输出journald 自动接住。同时/dev/log这个 socket 上仍然有传统 syslog 协议的日志在流动rsyslog 会从这边接住再根据 facility 和 priority 规则写入文本文件。最后系统每天或每周通过 cron 触发一次 logrotate逐个日志文件做“改名-重建/压缩/清理”的动作。我之前遇到一个挺典型的误解有人以为关掉了 rsyslog 服务系统日志就不写了。其实 journald 照样在收集只是/var/log/syslog这些文本文件不再更新了。同理如果 journald 因为磁盘满了罢工journalctl查不出东西但 rsyslog 可能还是正常往文本文件写。明白这一点你排障的时候就不会被“日志突然没了”这种假象带偏。1.2 配置文件先认门动手之前心里要有数Ubuntu 上每个组件都有对应的核心配置目录动手之前先把门认清楚比记住一长串命令更关键。我先替你整理一份“配置文件地图”后面所有操作都围绕这几张表展开组件配置文件作用说明journald/etc/systemd/journald.conf控制 journald 存储方式、日志大小上限、转储策略rsyslog/etc/rsyslog.conf/etc/rsyslog.d/定义日志接收、过滤、写入、转发规则logrotate/etc/logrotate.conf/etc/logrotate.d/控制轮转周期、保留轮数、压缩开关系统日志文件/var/log/rsyslog 默认输出目录部分服务日志也在这里systemd journal 持久化/var/log/journal/journald 持久化存储目录默认可能不存在我最常提醒新手的一句话是改 rsyslog 和 journald 的配置之后记得重启对应服务。这听起来像废话但真的有人改完配置文件坐等生效结果排了一下午的错最后才发现服务没重载。rsyslog 重载用sudo systemctl restart rsyslogjournald 用sudo systemctl restart systemd-journald两个命令各管一摊别搞混。2. journald系统日志的“中央车站”先把它玩明白journald 是现在 Ubuntu 日志体系里最先触达日志的组件所有被 systemd 托管的服务标准输出和标准错误都会自动进入 journald。这意味着你不用每个应用单独配置日志路径直接用journalctl就能把多个服务的日志放在一起看排查问题时特别省事。一句话总结 journald 的核心优势统一入口、结构化存储、按服务过滤。它不依赖日志文件路径也不依赖服务自己有没有写文件的能力只要你系统里进程是通过 systemd 拉起来的日志就“逃”不掉。这也是为什么现在很多新装的服务比如 Nginx、MySQL、Docker你会发现journalctl -u能查到它们的输出尽管它们根本没往 syslog 写东西。2.1 journalctl 的常用姿势直接拿来就用掌握 journalctl基本等于掌握了 Ubuntu 排障的第一把钥匙。我一个一个讲每个命令后面配一个实际场景你能直接对着用。先看最基础的全量日志journalctl不加任何参数jounald 会从最早可用的记录开始输出所有日志。如果系统运行时间长这个命令的输出量大到吓人一般我只在确认日志总量不太大时才会用。更常用的做法是加-u指定服务journalctl -u nginx.service这条命令只看 nginx 服务的日志。说实话这才是日常最常用的姿势服务报错了、起不来了、端口被占了第一件事就是看这个服务的日志。如果还想看最近 30 分钟内的日志journalctl -u nginx.service --since 30 min ago--since和--until是特别好用的时间过滤参数格式也很灵活可以是 “30 min ago”“2025-01-01 10:00:00”“yesterday” 这类人类能读懂的写法。我排查问题的时候习惯先拉最近十分钟的日志再根据线索往前推时间窗口比直接全量输出高效得多。内核日志是另一类高频需求。当遇到网络不通、硬件识别异常、驱动加载失败等问题时直接看内核日志比翻dmesg更好用因为 dmesg 显示的是内核环形缓冲区里的内容而journalctl -k查的是 journald 记录的内核日志信息量和筛选能力都更强journalctl -k查某个具体时间点附近的系统整体状态可以组合使用journalctl --since 2025-01-01 09:00 --until 2025-01-01 09:30日志量大的时候我会直接进交互模式看 tail这也是最容易上手的方式就把它当成升级版的 tailfjournalctl -f最后是两个需要特别留意的参数。-p可以按日志优先级过滤比如只看错误和更严重的journalctl -p err优先级从高到低分别是 emerg、alert、crit、err、warning、notice、info、debug。-o json-pretty可以把日志按 JSON 格式化输出方便写脚本做二次分析journalctl -u nginx.service --since 10 min ago -o json-pretty我自己的排查习惯是先-p err看有没有硬错误再-u锁定服务最后用--since收窄时间范围三步基本能定位 70% 的问题。2.2 日志要不要持久化这是一个决策题journald 默认情况下把日志存在内存文件系统/run/log/journal里。重启服务器这些日志就会清空。这一点在设计上是有意为之的避免日志写入拖慢磁盘、减少闪存设备的写入损耗但对生产环境来说“重启之后日志全没了”是灾难级的设定因为很多故障恰恰发生在重启的瞬间。开启持久化其实只需要一个动作sudo mkdir -p /var/log/journal然后重启 journald 服务sudo systemctl restart systemd-journald为什么创建目录就够了因为 journald 的存储逻辑很简单只要/var/log/journal目录存在它就把日志往磁盘写否则就退回内存。这个设计确实有点“隐藏彩蛋”的味道官方文档里写得很含蓄很多人根本不知道。我遇到过一台跑了几年的服务器有一天journalctl突然查不到三个月前的日志排查了半天原因是/var/log/journal被人误删了journald 无声无息地退回了内存模式。注意创建目录之后最好顺便检查一下属主ls -ld /var/log/journal如果是 root rootjournald 仍然能写因为它是 root 权限运行的但为了规范可以执行sudo chown root:systemd-journal /var/log/journal关于持久化的判断标准我给一个参考桌面开发机可以不持久化因为日志量小、丢失也无所谓但服务器、部署了业务应用、需要审计追踪的机器必须持久化。### 2.3 磁盘占用控制别让日志反噬了业务journald 持久化之后日志文件会不断增加控制磁盘占用就成了新任务。journald 的容量控制参数全在/etc/systemd/journald.conf里改完同样要重启 systemd-journald 才能生效。我最关心的三个参数是SystemMaxUse、SystemKeepFree、RuntimeMaxUse。SystemMaxUse表示 journald 最大能用多少磁盘空间默认是总磁盘的 10%SystemKeepFree表示 journald 至少要为其他用途保留多少空间默认 15%RuntimeMaxUse表示日志存在内存时最大占用默认是内存大小的 10%。如果磁盘空间紧张我会直接把 SystemMaxUse 压到一个固定值比如 200M。修改配置文件[Journal] SystemMaxUse200M SystemKeepFree50M有人认为日志保留越多越好我觉得这其实是个误区。日志的意义在于排查问题超过三个月的老日志基本没人看却白白占着磁盘。与其无限堆存量不如配合下面的清理动作。手动清理的命令也很直白。查看日志磁盘占用journalctl --disk-usage把日志总量压缩到 100M 以内journalctl --vacuum-size100M按时间清理只保留最近 7 天journalctl --vacuum-time7d这几个命令执行完会立刻释放磁盘空间适合磁盘告警时当救火队员。我个人推荐的做法是持久化打开同时把SystemMaxUse设成 500M 左右然后每月手动跑一次--vacuum-time30d这样既不担心磁盘被撑爆也能确保有近一个月的完整日志可查。3. rsyslog把日志按规矩分流、归档、送出去journald 负责收集但很多时候我们不能只满足于收集。你想让认证日志单独存成一个文件、想把自己的应用日志从一堆杂音里隔离出来、想同时把日志转发到远程服务器这些需求都是 rsyslog 的主场。rsyslog 最传统的规则格式是 “facility.priority action”一句话就能表达“什么来源、什么级别的日志送到哪里去”。看着像天书拆开就很简单。3.1 facility.priority 这套规则到底怎么读facility 指的是日志的来源类型常见的有 auth认证、authpriv私有认证、cron计划任务、daemon守护进程、kern内核、lpr打印、mail邮件、user用户进程等。priority 是日志的紧急程度从高到低排序是 emerg、alert、crit、err、warning、notice、info、debug。规则里还有几个特殊符号要注意。*表示所有 facility 或所有 priority表示精确匹配某一优先级!表示取反.表示“该级别以及更高优先级”.*表示该级别及以下的所有日志。这套表达方式初看容易绕实际用熟了非常灵活。拿 Ubuntu 默认配置里一条经典规则举例*.*;auth,authpriv.none -/var/log/syslog意思是所有来源、所有级别的日志除了 auth 和 authpriv 这两种之外其余都写到 /var/log/syslog。这里的-前缀表示异步写入也就是先把日志放内存缓冲再批量落盘换取更高的写入性能代价是如果突然断电缓冲里还没来得及写盘的日志会丢掉。我之前给一家公司做日志规范时看过他们把 auth 日志忘掉的坑。安全审计需要查登录记录结果/var/log/auth.log一张表拉到半年以前记录确实都在可中间偏偏空了一周原因是某次误操作把authpriv.none写成了*.*的前置条件认证日志被静默丢弃。从那以后我养成了一个习惯改完任何 rsyslog 规则先手动触发一条认证尝试再去 auth.log 里确认有没有落盘。日志系统本身如果坏了那比业务出问题还可怕因为你连怎么挂的都不知道。3.2 自定义分流规则让日志去它该去的地方光看不练没意思。我给你一个非常常见的定制需求把 OpenSSH 的认证日志单独分离出来。OpenSSH 的日志 facility 是 authauthpriv 由它自己掌握。Linux 的 sshd 默认使用 authpriv所以只要在/etc/rsyslog.d/下新建一个文件比如50-ssh.conf写入authpriv.* /var/log/ssh.log保存之后重启 rsyslogsudo systemctl restart rsyslog验证就简单了故意输错一次 SSH 密码然后检查sudo tail -f /var/log/ssh.log你会看到 sshd 的认证失败记录。如果日志没出现优先检查两个方向一是 sshd 是否走的是 authpriv 而不是 auth二是规则文件是否被其他规则提前匹配截胡。rsyslog 规则是按文件顺序从上到下执行的默认文件里 authpriv 有一堆历史规则你如果把自己的规则放在 20- 开头的文件里很可能被前面的命名规则先行处理了所以我一般建议自定义规则文件名用 50- 或更高数字开头排在默认规则后面执行。rsyslog 还支持在配置里用模板定义更精细的日志格式比如给应用日志加时间戳。这个属于进阶玩法要用到 RainerScript 语法感兴趣的人可以再往深了挖。日常分流需求上面的规则已经能解决九成问题。3.3 远程日志转发把日志送到统一的日志中心单机日志管理只有一半价值真正规模化之后多台服务器的日志最好能集中到一个地方统一查询。rsyslog 原生支持 UDP 和 TCP 转发配置也简单先看发送端。假设我要把本机所有日志转发到日志服务器 192.168.1.100接收端口用 UDP 514*.* 192.168.1.100:514一个 是 UDP两个 是 TCP*.* 192.168.1.100:10514接收端服务器上rsyslog 需要开启 imudp 或 imtcp 模块并监听对应端口。编辑/etc/rsyslog.conf把这两行去掉注释module(loadimudp) input(typeimudp port514) module(loadimtcp) input(typeimtcp port10514)重启接收端和发送端的 rsyslog日志就会开始流动。注意一点UDP 丢包不重传对日志完整性要求高的话一定用 TCP。另外默认的 syslog 端口 514 需要 root 权限监听某些 Ubuntu 版本还要配置防火墙放行端口否则转发会失败但没有任何报错非常容易让人抓狂。我在多个场景里用过 rsyslog 远程转发最典型的两个一是安全审计要求登录日志集中留存二是多台业务服务器日志统一汇总后用脚本分析。只要遵守“发送端配目标地址、接收端开监听模块”这个思路基本不会跑偏。有人问 UDP 和 TCP 延迟差距会不会影响实时性我自己的体验是不用纠结日志对毫秒级延迟并不敏感重点是别丢。4. logrotate日志文件过大、磁盘被打爆的终极防线journald 管存储上限rsyslog 管日志分发但还有一类日志是它们都不太管的应用自己写出来的文本日志。像 Nginx 的 access.log、MySQL 的 error.log、PostgreSQL 的日志这些文件如果应用自己不清理就会无限增长。logrotate 就是专门负责“给日志文件瘦身”的工具它既管 rsyslog 体统生成的日志也管应用自己写的日志是系统日志管理的兜底方案。很多人第一次听到“rotate”觉得很抽象其实它做的事情特别机械定时把当前日志文件改名让应用重新生成一个新文件然后再把旧的压缩、删除循环往复。4.1 logrotate 的核心机制切换而不是删除logrotate 的核心是“切换”旧文件而不是直接删除最新文件。默认流程是这样的比如/var/log/nginx/access.log到轮转周期了logrotate 先把它改名为access.log.1然后通知 Nginx 重新打开一个新的access.log文件。等到下一次轮转access.log.1变成access.log.2新生成的access.log变成access.log.1依次类推。这样做的好处是在任何时刻最新日志都在固定的access.log文件里监控脚本、日志采集器不用频繁改路径。如果应用自己没有处理信号的能力logrotate 里配置了copytruncate那就是另一条路先把当前日志文件复制一份然后立刻把原文件清空。这会导致复制过程中新写入的一些日志行被截掉算是这个方式的天然损耗。要不要用 copytruncate就看应用懂不懂 syslog 那一套重新打开文件的协议了。判断的标准其实很简单能主动响应 SIGHUP 或 USR1 信号重新打开日志文件的应用比如 Nginx、Apache用 create 方式不能响应信号、只能傻傻往同一个文件句柄里写的应用比如某些 Java 服务、Nginx 的 access_log 如果没开启postrotate重载就用 copytruncate 兜底但在高并发下丢十几行日志也属于可接受范围。4.2 参数别乱选create、copytruncate、compress、dateext 的区别和适用场景logrotate 参数看着多真正需要理解的核心就几个。我整理了一张对照表方便你按场景选参数作用适用场景rotate 7保留 7 个轮转后的旧日志需要预留一段可查周期daily/weekly/monthly轮转周期按天/周/月日志增长快就 daily慢就 weeklycompress旧日志用 gzip 压缩节省磁盘空间需压缩时间delaycompress延迟一轮再压缩配合 create 轮转时避免刚轮转的旧文件还在被写入就压缩copytruncate先复制后清空原文件应用不能重开日志文件时使用create 0640 root adm轮转后新建日志文件并设置权限默认动作保证新文件权限正确dateext用日期命名轮转文件比如 access.log-20250101避免文件名覆盖missingok日志文件不存在时跳过不报错服务未启动时避免误报notifempty文件为空时不轮转避免产生大量空文件postrotate/endscript轮转后执行脚本通知应用重开日志、重载配置核心参数里最值得说的是dateext。默认情况下 logrotate 用access.log.1、access.log.2这种序号命名一旦超过rotate设置的数量最老的文件会被覆盖而打开dateext之后备份文件会变成access.log-20250101这样的格式一眼就能看出是哪天的日志排查问题时省太多时间了。压缩的选择也很有讲究。compress确实能大幅省空间但如果在轮转当天旧文件还在被某些进程引用比如 copytruncate 模式下写入方还没来得及关句柄直接压缩会导致数据丢失。稳妥的组合是compress加上delaycompress把压缩推迟到下一轮轮转时执行让上一轮的旧文件先留着一份未压缩的副本确保安全性。这一点在很多数据库日志配置里有过血泪教训我建议你直接按这个组合用不要为了省那点空间冒险。4.3 应用自定义日志轮转的几个实战例子光讲参数容易头晕直接贴几个我配过的场景。先看 Nginx这是一个非常标准的“支持信号、适合 create postrotate 重载”的例子cat /etc/logrotate.d/nginx EOF /var/log/nginx/*.log { daily rotate 14 compress delaycompress dateext missingok notifempty create 644 www-data www-data sharedscripts postrotate [ -f /run/nginx.pid ] kill -USR1 $(cat /run/nginx.pid) endscript } EOF这段配置的意思是Nginx 的日志每天轮转一次保留 14 个旧文件用日期命名压缩延迟一轮轮转后给 Nginx 主进程发 USR1 信号让它重新打开日志文件。kill -USR1这个信号是 Nginx 官方支持的重开日志机制通过 postrotate 调用保证新的 access.log 立即生成。再看一个 PostgreSQL 的例子。PostgreSQL 本身有自带的日志轮转设置但如果想用统一的 logrotate 管理就需要注意它默认不响应外部信号所以用 copytruncate 更保险cat /etc/logrotate.d/postgresql EOF /var/log/postgresql/*.log { weekly rotate 4 compress copytruncate missingok notifempty create 640 postgres postgres } EOFcopytruncate保证了即使 PostgreSQL 进程不重新打开文件日志也能被清空重建。但代价就是高并发下会丢少量日志这在这个场景可以接受因为 PostgreSQL 本身还会把日志同时发给 syslog。还有更细的用法如果你的某个 Java 服务日志文件路径固定但 Java 进程不响应任何信号最简单的方案就是用 copytruncate 强行做轮转然后在 postrotate 里不执行任何重载命令让它自然为新文件句柄写日志。4.4 手动触发和调试别傻等 cron 了logrotate 默认由 cron 驱动一般一天跑一次。但你在配置完新规则之后不手动执行一次怎么知道配置有没有问题这里有两个调试命令是必须掌握的# 调试模式只输出将要执行的动作不真正执行 sudo logrotate -d /etc/logrotate.conf # 强制立即执行某个配置文件的规则并输出详细信息 sudo logrotate -vf /etc/logrotate.d/nginx-d是 dry-run不会改任何文件适合验证配置语法-v是 verbose打印完整执行过程-f是 force强制轮转哪怕没到轮转时间也执行。我建议先-d确认没问题再用-vf强制轮转一把并看输出确认所有路径和命令都对才算真正配置完成。手动触发之后检查/var/log/nginx/目录你会发现生成了access.log-2025xxxx这样的文件同时 nginx 正常运行。如果发现没有生成新日志文件多半是日期格式、压缩命令或权限出了问题-d模式输出里会直接提示。还有一个小技巧你可能需要cron 的调度进度一般在/etc/cron.daily/里Ubuntu 默认的 logrotate 调度脚本在这里。如果你觉得 logrotate 周期不合适的可以修改/etc/anacrontab里的时区设置但一般不推荐乱动保持默认就好。5. 把三者串起来日常排障和日志架构落地前面把三个组件的原理和命令都讲了但实际用的时候你面对的往往不是一个组件而是一条完整的日志链。这一节我把它们串起来讲一个常见的排障流程再给一套可以直接落地的最小方案。5.1 从一条报错到真相的完整排查链条假设你部署的 Web 服务突然返回 502你第一反应是看 Nginx 日志。此时你需要明白Nginx 的 access.log 和 error.log 是它自己写的默认配置下 journald 也能同步记录它的标准输出。你可以用journalctl -u nginx看最近的错误也可以用tail -f /var/log/nginx/error.log看实时日志两条路殊途同归。接着往下追如果发现是后端进程挂了那就要看后端服务的日志。服务如果是 systemd 托管的journalctl -u myservice是首选因为它连服务启动时的环境变量、退出代码、内核报错都记录在内。如果服务自己写了/var/log/myservice.log那就去查这个文件它可能经过 logrotate 轮转出了myservice.log.1可以用less打开对比。到了这一层你的排障动作大概是这样# 第一步看服务最近的状态 systemctl status myservice # 第二步看最近一小时的服务日志 journalctl -u myservice --since 1 hour ago # 第三步如果服务日志里没有有效线索去查系统日志 journalctl -p err --since 1 hour ago # 第四步看对应的文本日志文件 tail -n 100 /var/log/myservice.log整套流程的信息来源是 journald 和文本日志的交叉验证。有时候 journald 丢了部分记录文本日志却能补上有时候两者内容互相冲突你就要停下来想想哪一个是故障发生前最后的真相。还有一个我特别想强调的点别忽略 rsyslog 的时间同步。日志最怕时间不对如果机器时钟和历史服务器不一致你查日志的时候会一头雾水。Ubuntu 上第一步就是检查timedatectl确认时间同步状态是 “System clock synchronized: yes”。我经手过一台时间偏差了 8 分钟的服务器排查日志时怎么都对不上错误发生的时刻最后发现是 NTP 没配好。时间不准再全的日志都是废的。5.2 生产环境日志管理的最小可行方案聊完整套原理我直接给一份我自己在用的最小方案。适用于单台或几台服务器的场景不需要大而全的日志平台但能保证日志完整、可查、不炸磁盘。第一步开启 journald 持久化sudo mkdir -p /var/log/journal sudo systemctl restart systemd-journald第二步限制 journald 磁盘占用。修改/etc/systemd/journald.conf[Journal] SystemMaxUse500M SystemKeepFree100M然后重启 journald。第三步确认 rsyslog 正常工作sudo systemctl enable --now rsyslog第四步给关键应用配置 logrotate。比如系统自带的配置已经覆盖了/var/log/syslog这些你要额外处理的是 Nginx、MySQL、你的应用日志。为每一个日志文件编写一个/etc/logrotate.d/下的规则。第五步加一条 crontab 定时任务每周手动 vacuum 一次 journald 的老日志。虽然 journald 有 SystemMaxUse 自动限制但很多长期运行的服务器上还是会出现意外占用定时 vacuum 更保险sudo crontab -e # 每周日凌晨3点清理超过30天的日志 0 3 * * 7 journalctl --vacuum-time30d这套方案的核心思想是journald 管实时查询rsyslog 管文本归档logrotate 管应用日志轮转cron 管周期兜底。不需要很复杂但能保证你在一台机器上既不丢日志也不怕磁盘被打满。6. 踩坑记录与避坑心得技术文章写多了最值钱的其实是坑。我在日志管理上踩过的坑不少这里挑几个高频的整理成速查表再补充几句经验之谈。6.1 高频事故速查表现象可能原因解决方式journalctl查不到老日志journald 未持久化日志在内存中被清除或重启丢失创建/var/log/journal目录开启持久化磁盘突然被打满journald 占用或某个日志文件无限增长journalctl --disk-usage查占用logrotate -vf强制轮转应用日志改完 rsyslog 配置不生效没重启 rsyslog或规则顺序被更早的文件抢占sudo systemctl restart rsyslog自定义文件用 50- 前缀logrotate 轮转后应用日志仍写入旧文件应用没有重新打开日志文件没触发 postrotate配置对应信号或改用 copytruncatelogrotate -d正常-vf却报权限错误logrotate 以 root 身份执行时也创建文件权限不对检查 create 参数手动修改目标目录权限远程日志转发没反应防火墙没有放行 514/10514 端口放行端口如果使用 TCP 请确认两端 imtcp 模块都加载时间对不上日志顺序混乱服务器时钟未同步NTP 没配置执行timedatectl set-ntp true开启时间同步这个表你打印出来贴在工位上基本能解决日常 80% 的日志疑难杂症。6.2 给新手的几个实用建议第一个建议不要把鸡蛋放在一个篮子里。journald 和 rsyslog 是两套相互独立但又有关联的体系排查问题时两边都要看一眼不要只盯着其中一个。文本日志适合快速查看journalctl 适合精确搜索两个配合起来效率最高。第二个建议所有 logrotate 配置改完一定要手动跑一次 -d 和 -vf不要等 cron 跑起来才暴露问题。我见过太多人配置完就扔那等着结果一个月后磁盘被撑爆打开 logrotate 日志一看全是语法错误。十分钟的调试换来一个月的心安。第三个建议养成“日志分目录”的习惯。尽量让每个核心应用都往/var/log/下建独立子目录并且配置独立的轮转规则。不要把所有日志都堆进 syslog搜索的时候真的太费劲了。最后如果日志量真的到了单机处理不了的程度再去考虑引入 Elasticsearch 之类的日志平台但在这之前先把单机的 rsyslog journald logrotate 基础打好比什么都强。我自己这十几年摸服务器的一个最大体会是日志系统就像保险平时感觉不到它的存在一旦出了事它就是唯一的救命稻草。花一点时间把日志管理理顺每一次故障排查都会快很多而且你会在一次次对着日志揪出问题根因的过程中真正建立对系统的掌控感。
返回列表