news 2026/10/5 13:25:22

Ubuntu 22.04日志管理实战:从journalctl到logrotate与集中采集

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ubuntu 22.04日志管理实战:从journalctl到logrotate与集中采集

接手一台Ubuntu 22.04服务器之后,我建议你第一件事就是搞清楚这台机器上的日志到底怎么存、怎么查。很多以为自己“运气不好”的故障——服务莫名退出、磁盘空间突然告警、半夜被入侵、应用响应变慢,其实答案早就躺在日志里了。只是大多数人没时间、没习惯、没用对工具去读它。

这篇文章不聊空泛的理论,直接围绕Ubuntu 22.04的日志处理讲透:日志从哪来、在哪个文件里、用哪些命令能快速翻到想要的内容、怎么把日志集中采集出去、怎么防止日志把磁盘塞爆,以及我在实际运维中踩过的坑。无论你是刚上手Ubuntu的新人,还是从CentOS迁移过来的老运维,这篇文章都能让你少走弯路。

先说结论:Ubuntu 22.04的日志体系和老版本区别非常大,理解它的“双轨制”是第一步。

1. 日志从哪来、到哪去

1.1 Ubuntu 22.04的日志体系:三股流量

很多人上来就习惯去翻/var/log/messages,结果发现文件不存在,就开始怀疑系统有问题。其实不是坏了,而是Ubuntu没有这个文件。Ubuntu 22.04的日志体系可以粗略分成三股流量:

第一股是内核和系统服务的日志,由systemd-journald接管。所有通过systemd启动的服务(几乎涵盖所有系统服务),它们的标准输出、标准错误、以及调用syslog接口打印的日志,最终都被journald收集,存成二进制的journal文件,放在/var/log/journal/目录下。你直接用cat去读这些文件会看到乱码,必须用journalctl命令来查。

第二股是传统文本日志,由rsyslog处理。journald虽然收日志,但它本身不做复杂的文件落盘和转发,真正把日志写到/var/log/syslog、/var/log/auth.log这些文本文件里的,是rsyslog。它从journald读取日志,再根据规则分发到对应文件。

第三股是应用自己写的日志,比如Nginx的access.log、MySQL的error.log、Java应用的日志文件。这类日志和系统日志基本无关,由应用自行管理,通常也放在/var/log下或者应用自己的目录里。

理解这三股流量是处理Ubuntu 22.04日志的基础。我见过不少人在/var/log/syslog里找不到某个服务的日志就以为系统出问题了,其实那个服务的日志可能只进了journald,根本没被rsyslog落到文件里。

说起来,Ubuntu 22.04时代默认日志采集链路大致是这样的:进程写日志 → journald收集 → rsyslog监听journal → 写入/var/log下的文本文件。中间任何一环配置变化,都会影响最终结果。

1.2 /var/log核心文件一览

Ubuntu 22.04的/var/log目录里,我平时最常看这些文件:

文件路径内容说明
/var/log/syslog系统全局日志,很多服务都会写到这里,排查问题优先看它
/var/log/auth.log登录认证日志,包括SSH登录、sudo提权记录,安全检查必看
/var/log/kern.log内核日志,硬件、驱动、内核模块问题看这里
/var/log/dpkg.log软件包安装和升级记录,排查“软件莫名其妙没了”的问题
/var/log/apt/apt更新日志目录,含history.log和term.log
/var/log/boot.log开机时的服务启动信息
/var/log/nginx/Nginx访问和错误日志(安装Nginx后出现)
/var/log/mysql/MySQL错误日志(安装MySQL后出现)
/var/log/journal/journald的二进制日志目录,用journalctl查询

一个很实用的习惯是,不确定某个服务日志在哪的时候,用ls -lt /var/log/ | head看看哪些文件最近有更新,基本就能锁定目标。

2. 用journalctl翻日志,比你想的更好用

2.1 至少要学会的6种journalctl查看方式

journalctl是Ubuntu 22.04上最核心的日志查看命令,也是很多人觉得最不直观的命令。我日常使用频率最高的是下面这些组合:

查看本次开机之后的全部日志:

journalctl -b

查看上次开机的日志:

journalctl -b -1

查看某个Unit(服务)的日志,这是排查服务问题的王牌命令:

journalctl -u ssh.service

看某个服务的最近100行日志,并且持续跟随输出,调试服务时开着它很舒服:

journalctl -u nginx.service -f -n 100

只看内核日志,相当于dmesg加了时间戳和持久化:

journalctl -k

看过去1小时内的日志:

journalctl --since "1 hour ago"

我特别喜欢_PID、_COMM这些字段的过滤方式,比如我只想看到某个进程的崩溃信息:

journalctl _COMM=java --since "2024-01-01" --until "2024-01-02"

这里的关键是,journal日志里每个条目都有丰富的元数据,包括进程号、用户ID、来源Unit、时间戳等。你用journalctl -o verbose就能看到每条日志的完整字段,再配合_PID=、_UID=、_SYSTEMD_UNIT=过滤,精度极高。

2.2 “无日志文件夹”是怎么回事

很多人搜过这么一个问题:某服务的日志文件夹不存在,到处找不到日志。我刚开始用systemd的时候也困惑过。

一个systemd服务,如果配置文件里没有指定StandardOutput=和StandardError=,那么它打印到标准输出和标准错误的内容,默认全被journald收走了,不会生成/var/log/xxx.log文件。这不是Bug,而是设计选择。

所以当你发现“无日志文件夹”时,第一反应应该是journalctl -u 你的服务名,日志大概率都在这里。如果你就是想要独立的文件日志,可以在service文件里显式指定:

[Service] StandardOutput=file:/var/log/myapp/app.log StandardError=file:/var/log/myapp/app.log

但要注意,journald依然会同时收集一份,所以要控制好日志量。还有就是如果用Docker,容器里服务打印到stdout的日志默认由Docker接管,不走journald,别搞混了。

2.3 查看crontab执行日志的两种办法

我经常在服务器上排查定时任务为什么没跑,发现很多人不知道crontab日志在哪。这里容易有两个坑:一是cron的日志默认落在了syslog里但容易被忽略;二是journald里也有,但得用对过滤条件。

第一种办法,直接搜syslog:

grep CRON /var/log/syslog

第二种办法,用journalctl过滤:

journalctl _COMM=cron --since "today"

如果发现日志量太大,可以单独给cron一把椅子。在/etc/rsyslog.d/下新建一个配置文件,比如50-cron.conf,写上:

cron.* /var/log/cron.log

重启rsyslog之后,cron日志就单独落到文件里了。

如果你用的是系统自带的systemd timer,那又是另一套查看方式:systemctl list-timers看定时器状态,journalctl -u 定时器名字查看执行细节。

3. 把日志统一采集起来

单机翻日志是基本功,但真正上班之后,你很快会遇到更现实的问题:几十台服务器的日志太分散,每台都ssh上去journalctl会疯掉的。这时候就需要把日志统一采集到一个平台。Ubuntu 22.04上最常见的两种方式我要展开讲讲。

3.1 用filebeat做JSON化采集

Elastic公司出的filebeat是目前最常见的轻量日志采集器,在Ubuntu 22.04上配置不算复杂,但有几个细节值得注意。安装方式我习惯直接用Elastic官方仓库:

curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list sudo apt update && sudo apt install filebeat

然后修改/etc/filebeat/filebeat.yml。一个最小可用的配置大概是这样的:

filebeat.inputs: - type: filestream id: my-application enabled: true paths: - /var/log/myapp/*.log fields: service: myapp hostname: "${HOSTNAME}" fields_under_root: true output.elasticsearch: hosts: ["192.168.1.10:9200"] username: "elastic" password: "changeme"

配置好之后启动并设置开机自启:

sudo systemctl enable --now filebeat

这里我要提醒一个坑:filebeat的旧版配置用- type: log,新版本推荐filestream,两者参数不兼容。网上90%的老教程还在用logtype,照着抄到8.x版本上会直接启动失败。报错信息通常会说unknown key。

另外,filebeat默认会记录读取进度到/var/lib/filebeat/registry/,所以第一次采集会从头读,之后只读新增。如果你改过paths,想重新采集,记得把registry目录清掉:

sudo rm -rf /var/lib/filebeat/registry sudo systemctl restart filebeat

3.2 用rsyslog做远程转发

如果你不想引入Java环境、不想维护Elasticsearch集群,只想把多台Ubuntu的日志集中收集到一台机器上,rsyslog远程转发是更轻量的方案。Ubuntu 22.04自带rsyslog,只需要两端做配置。

接收端(日志服务器)在/etc/rsyslog.conf里打开模块:

module(load="imudp") input(type="imudp" port="514") module(load="imtcp") input(type="imtcp" port="514")

如果想按发送方主机名区分日志,可以加一行模板规则。比如在/etc/rsyslog.d/60-template.conf里写:

template(name="PerHostLog" type="string" string="/var/log/remote/%HOSTNAME%/%programname%.log")

发送端在/etc/rsyslog.d/60-forward.conf里写:

*.* @192.168.1.10:514

重启rsyslog服务后,日志就转发过去了。注意这里的协议:单个 @ 表示UDP,两个 @@ 表示TCP。UDP快但有丢包风险,TCP稳但占用稍高,内网采集用TCP更可靠。

我自己的习惯是,小规模(比如10台以内)用rsyslog就够,省心、不占资源。规模大了、需要全文检索和可视化,再上filebeat + Elasticsearch。

3.3 到底选哪个:filebeat和rsyslog对比

对比项filebeatrsyslog远程转发
资源占用中等,Go语言实现,单实例约20-40MB内存低,原生进程,内存占用可忽略
功能支持多输出、多条件过滤、内置模块侧重转发和简单过滤,规则较繁琐
扩展性配合ES、Logstash、Kibana能力强配合远端rsyslog简单集中,缺乏可视化
上手难度中等,配置文件YAML清晰中等,配置语法老派,需要查文档
适用场景中等规模以上、需要搜索和可视化小规模、只要集中存储即可

无论选哪个,都建议在采集端就把日志结构化。比如应用能输出JSON最好,实在不行也至少保证一条日志一行,不要用多行日志,否则采集、解析、检索全部难受。

4. 日志轮转与清理:别让日志把磁盘撑爆

4.1 logrotate的工作原理

日志如果只增不减,任何机器都扛不住。Ubuntu 22.04自带的logrotate工具就是为了解决这个问题。它的核心思想很简单:定期把当前日志文件改名、压缩或删除,然后让应用重新写入新文件。

logrotate的配置分为两部分:全局配置/etc/logrotate.conf和各应用自己的配置/etc/logrotate.d/下的文件。系统每天通过cron定时执行一次,/etc/cron.daily/logrotate就是入口。

它的执行逻辑大概是:读取配置 → 判断是否需要轮转(按天数或大小)→ 执行轮转 → 执行postrotate脚本(通常是通知应用重开日志文件,比如systemctl reload nginx)→ 把旧文件按序改名、压缩 → 超过保留数量的删除。

4.2 定制一个logrotate配置

我举一个实际例子。假设你的应用myapp每天会产生100MB日志,你想保留7天,每天轮转一次,并开启压缩。在/etc/logrotate.d/myapp里写:

/var/log/myapp/*.log { daily rotate 7 compress delaycompress missingok notifempty dateext su myapp myapp postrotate systemctl reload myapp endscript }

这里逐条说明:

  • daily:每天轮转一次。如果要按大小,换成size 100M,两者选一个。
  • rotate 7:保留7个旧文件,第8个会被删掉。
  • compress:轮转后的旧文件压缩成gz格式。delaycompress比较巧妙,表示压缩延迟到下一轮,也就是最新那个旧文件不压,等下轮一起压。这么做主要防止像Nginx这类还在往旧文件写日志的应用出问题。
  • missingok:日志文件不存在时不要报错,避免黑屏刷错误。
  • notifempty:文件为空就不轮转。
  • dateext:轮转后的文件名带上日期,比如app.log-20240101.gz,比默认的.1、.2后缀直观得多。
  • su myapp myapp:以指定用户执行,防止权限问题导致轮转失败。
  • postrotate:轮转完成后重载应用,让它重新打开新的日志文件。

算一笔账:每天100MB,保留7天且压缩。压缩率按0.2算,日志占用大约是7个旧日志压缩后 ≈ 100MB × 0.2 × 7 ≈ 140MB,加上当天原始日志100MB,总共不到250MB。如果不开压缩,那就是800MB,差距巨大。

所以我强烈建议所有能开压缩的日志都开压缩。反正解压也只是日志平台采集端的举手之劳。

4.3 手动清空和滚动日志的注意事项

线上总会遇到一些奇葩场景:某个应用不写日志到文件而是持续刷屏,日志文件已经几个GB了,logrotate因为rotate数量还没到或者应用不配合一直没转。这时候你需要手动干预。

最简单的做法是清空文件而不是删除:

> /var/log/myapp/big.log

这个命令用Shell重定向直接清空文件内容。我特别强调,不要用rm删除日志文件,特别当应用还持有文件句柄时。删除后,应用会继续往那个已经“消失”的inode上写数据,磁盘空间不会释放,而且新文件根本不会创建。这是Linux下最常见的“明明删了日志磁盘空间还是满”的原因。

正确清空一个正在被写的大日志,还有一种更自动化的方式:

truncate -s 0 /var/log/myapp/big.log

甚至想保留部分内容,可以:

truncate -s 100M /var/log/myapp/big.log

这样文件会缩短到100MB,之后的日志继续追加。应用进程完全无感知,也不需要重启。

不过要注意有些应用会记录自己在文件中的偏移位置,比如tail -c这种,突然截断可能导致它继续从旧偏移写,产生文件空洞。我遇到过Java应用配合log4j时,truncate后再往里写会出现一大串NUL字符。稳妥的做法还是truncate之后观察一下日志是否正常增长,如果异常就重启应用。

5. 常见问题与排查技巧

5.1 journald日志把磁盘占满

这是我在Ubuntu 22.04上见过最多的问题。journald默认会把日志存在/var/log/journal里,而且没有做严格的大小限制,如果某个服务疯狂刷日志,journal文件能涨到几个GB甚至占满整个根分区。

最直接的查看方式:

journalctl --disk-usage

然后你可以手动清理:

journalctl --vacuum-size=200M

这会把日志总量压缩到200MB以内,只保留更近的日志。还可以按时间清理,只保留最近7天:

journalctl --vacuum-time=7d

但从根本上解决问题,还是要修改journald的配置。编辑/etc/systemd/journald.conf,找到这几行并改成:

SystemMaxUse=200M SystemMaxFileSize=50M MaxRetentionSec=7day

SystemMaxUse是journal能够占用的最大磁盘总量,SystemMaxFileSize是单个journal文件上限,MaxRetentionSec是日志最大保留时间。改完重启服务:

sudo systemctl restart systemd-journald

注意重启journald会丢掉内存中的部分日志,但磁盘上已有的journal仍在。这里有个顺带坑,改配置后建议顺手journalctl --verify检查一下journal文件的完整性,我遇到过断电后journal文件损坏,执行此命令能提前发现。

5.2 日志时间戳和实际时间对不上

刚装完Ubuntu 22.04,很多人发现日志时间和当前时间差8小时,这通常不是日志系统坏了,而是时区没配。systemd时代系统时钟管理已经统一了,配置方法如下:

sudo timedatectl set-timezone Asia/Shanghai

设置完用timedatectl查看确认。之后journald和rsyslog记录的日志时间戳就会跟随系统时区。但这里有个深坑:journald内部存储的时间戳实际上是UTC时间,只展示的时候转换成本地时间。所以如果你把系统时区改了,之前记录的日志展示时间也会跟着变,内容不会错乱。

如果你用的是Docker容器,容器里的日志时间出问题又是一种解法:启动容器时必须挂载时区文件:

docker run -v /etc/localtime:/etc/localtime:ro ...

否则容器默认UTC,日志自然比宿主机快8小时。

5.3 filebeat采集不到日志

遇到filebeat装了但采集不到日志,我通常按这个顺序排查:

第一步看进程有没有起来:

systemctl status filebeat

第二步看filebeat的日志有没有报错:

journalctl -u filebeat -n 50

第三步测试能否连上目标:

curl -s http://192.168.1.10:9200

第四步看是否有权限问题,filebeat默认以root运行,但如果你在配置里指定了user: myapp,那它读不了/var/log/myapp/下权限600的日志文件。

还有一个我踩过的坑:paths里写的是/var/log/myapp/*.log,但应用实际生成的日志后缀是log.20240101,不匹配,导致filebeat永远扫不到。解决方法是把通配符改成/var/log/myapp/*或者指定具体文件名。

5.4 重启日志服务导致日志丢失

很多人不知道restart rsyslog和restart systemd-journald的区别。journald重启会丢失一部分正在内存中的日志,因为这些日志还没落盘。所以不要没事就重启journald,尤其是排查问题的时候,重启一次可能就把关键线索弄丢了。

相比之下,rsyslog重启影响小一些,因为它只是读取journal再写文件,已经在文件里的日志不丢,但journald那边没落盘的依然丢。

如果确实需要清理日志且不想丢关键信息,建议先执行journalctl --flush,把内存日志强制写入磁盘,再进行重启。

另外,每次大版本升级之后,我建议抽查几个服务的日志轮转是否正常。Ubuntu的自动更新可能替换了logrotate版本,或者某些包自带的配置覆盖了你定制的内容。我遇到过升级后/etc/logrotate.d/nginx配置被整体替换,结果自定义的dateext和保留数量全丢了,日志又开始越拉越长。

日志处理这件事,说大不大,说小不小。它不产生业务价值,但业务出了问题,第一个要找的就是它。我在Ubuntu 22.04上摸索了几个月,踩过不少坑之后最大的体会是:先把journald弄明白,把rsyslog的转发和logrotate的轮转配好,最后再考虑上采集平台。大多数中小规模的日志问题,靠这几样就能解决。最后再分享一个小技巧:如果不知道日志量增长有多快,可以用这个命令快速估算今天写了多少日志:

journalctl --since today | wc -l

数字一旦稳定增长,你就知道,该去把轮转和采集配好了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/5 13:22:16

Python漏洞扫描系统实战:Django+Nmap+Docker构建与避坑

简介:这份资源是一篇面向初级运维人员与初级网络安全研究者的毕业设计类文档,围绕基于Python的漏洞扫描系统展开,重点解决中小型网络环境中安全检测门槛高、工具集成难的问题。文档以Django Web框架搭建B/S架构平台,借助Docker轻量…

作者头像 李华
网站建设 2026/10/5 13:22:01

生成式AI数据隐私风险防范:从数据分级到输出过滤的工程实践

简介:这份文档围绕生成式人工智能应用中的数据隐私风险与防范策略展开系统研究,面向人工智能、数据安全与隐私保护方向的学习者和研究者,帮助其建立从风险识别到策略落地的完整认知框架。资源包为单一docx文档,约127KB&#xff0c…

作者头像 李华
网站建设 2026/10/5 13:20:48

SaaS多租户架构设计:从共享表到独立实例的隔离与计费实战

简介:这份《SaaS架构设计》PDF文档面向希望系统掌握SaaS架构原理与实践的开发者、架构师及技术学习者,围绕多租户系统从需求分析到性能优化的完整设计链路展开。内容涵盖SaaS成熟度模型四级分级、RUP“41”视图模式(场景、逻辑、开发、过程、…

作者头像 李华
网站建设 2026/10/5 13:16:07

Java 项目实战: 外卖平台优化-Nginx部署静态资源与location匹配

接入 Nginx: 静态资源部署与 location 路径匹配 纲要 「部署静态资源」,是 Nginx 三大应用的第一个: 什么是静态资源:服务端真实存在、可直接返回的文件为什么不用 Tomcat 部署静态资源:sendfile 零拷贝、epoll 模型、无 JVM 开…

作者头像 李华
网站建设 2026/10/5 13:15:13

用Python批量生成画展展签:一间美术教室的数字化尝试

画展筹备里最琐碎的活是展签:两百多张作品,每张要写姓名、班级、作品名、材料。这篇记录我用 Python 把展签和作品集做成批量生成的过程,从 CSV 数据整理到 PDF 排版,全部本地完成。关键词:Python、reportlab、qrcode、…

作者头像 李华
网站建设 2026/10/5 13:13:26

首字响应低至 280ms+动态慢思考!MiniMax M3.1-Flash-Preview 突袭 MCode:日常编程智能体迎来平民级“超跑小钢炮”

核心震撼导读:如果你以为顶级 AI 编程助手的进化终点依然是死磕数千亿巨无霸参数、让开发者在终端前焦急等待数秒首字响应,那么刚刚在 MiniMax Code (MCode) 爆发的这场“极速轻量突袭”,将彻底颠覆你对全栈编程智能体(Coding Age…

作者头像 李华