首页 / 资讯动态 / Ubuntu运维日志文件journalctl查询与过滤技巧

Ubuntu运维日志文件journalctl查询与过滤技巧

Ubuntu系统从15.04版本开始全面采用systemd作为初始化系统,journalctl就是systemd自带的日志查询工具,它取代了传统的/var/log/messages、/var/log/syslog等分散式日志文件。想快速定位系统问题,你必须掌握journalctl的查询与过滤技巧。核心命令其实就几个:按时间过滤用--since和--until,按服务过滤用-u,按优先级过滤用-p,按启动次数过滤用-b,按进程PID过滤用_PID=。把这些组合起来用,90%的运维排障场景都能覆盖。

很多运维人员刚接触Ubuntu时还在用grep去翻/var/log下的文本文件,效率极低。journalctl的优势在于它是二进制日志,支持结构化查询,速度快、功能强。下面我把所有实用技巧按场景分类讲透。

一、journalctl基础认知:日志存储在哪里

journalctl读取的日志默认存储在/var/log/journal/目录下(如果是持久化模式)。如果你发现这个目录不存在,说明系统没有开启日志持久化,重启后日志会丢失。开启方法很简单:

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

做完这一步,日志就会持久保存了。查看当前日志占用空间可以用:

journalctl --disk-usage

如果磁盘空间紧张,可以限制日志最大占用:

sudo journalctl --vacuum-size=500M

这条命令会把日志压缩到500MB以内。也可以按时间清理,比如只保留最近7天:

sudo journalctl --vacuum-time=7d
二、按时间范围查询:最常用的过滤方式

排查问题时,第一步永远是锁定时间窗口。journalctl支持非常灵活的时间表达式。

查询今天的所有日志:

journalctl --since today

查询最近1小时的日志:

journalctl --since "1 hour ago"

查询指定时间段,比如2024年6月1日到6月5日:

journalctl --since "2024-06-01 00:00:00" --until "2024-06-05 23:59:59"

也支持相对时间,比如"昨天":

journalctl --since yesterday --until today

这里有个实用技巧:加上--no-pager可以取消分页,直接输出到终端,方便配合grep或awk做二次处理:

journalctl --since today --no-pager | grep -i error
三、按服务单元过滤:精准定位某个程序的日志

这是日常运维中用得最多的功能。比如你想看nginx的日志:

journalctl -u nginx.service

如果服务名不确定,先列出所有正在运行的服务:

systemctl list-units --type=service --state=running

然后找到对应的单元名。注意,有些服务的单元名和包名不一样,比如ssh服务的单元名是ssh.service而不是sshd.service(虽然旧系统用sshd)。

查看某个服务最近50条日志并实时跟踪:

journalctl -u nginx.service -n 50 -f

-n 50表示显示最近50条,-f表示follow模式,类似tail -f的效果。

四、按日志优先级过滤:快速筛选错误和警告

systemd定义了8个日志优先级,从高到低是:emerg(0)、alert(1)、crit(2)、err(3)、warning(4)、notice(5)、info(6)、debug(7)。运维中最关心的是err及以上级别。

只看错误及以上级别的日志:

journalctl -p err

看警告及以上(包含err、crit、alert、emerg):

journalctl -p warning

如果你只想看当前启动以来的错误:

journalctl -b -p err

-b参数表示当前启动(boot),不加-b则是所有历史启动记录。

五、按启动次数查询:排查重启相关问题

系统每次重启都会生成一个新的日志序列。查看上次重启的日志:

journalctl -b -1

-1表示上一次启动,-2表示上上次,以此类推。查看历史启动列表:

journalctl --list-boots

输出会显示每次启动的时间戳和ID,你可以用ID来指定查看:

journalctl --list-boots | head -5
journalctl -b 3a5f2c1d...

这个功能在排查"系统为什么重启"这类问题时特别有用,因为重启原因通常记录在上次启动的日志里。

六、按进程PID和用户过滤:细粒度追踪

如果你知道某个进程的PID,可以直接追踪它的日志:

journalctl _PID=1234

注意PID前面有个下划线_,这是journalctl的特殊语法。如果进程已经退出了,journalctl仍然能查到它的历史日志,前提是日志没有被清理掉。

按用户过滤,比如查看用户www-data产生的所有日志:

journalctl _UID=33

33是www-data用户的UID,你可以用id命令查任意用户的UID。

按内核日志过滤(等同于dmesg):

journalctl -k

或者:

journalctl --dmesg
七、输出格式控制:让日志更易读

默认输出格式是文本,但你可以改成JSON格式方便程序解析:

journalctl -u nginx.service -o json-pretty

只输出日志消息体,不要时间戳和其他元数据:

journalctl -u nginx.service -o cat

以短格式输出(去掉时间和主机名,只保留优先级和消息):

journalctl -u nginx.service -o short

导出为JSON格式到文件做后续分析:

journalctl --since today -o json > /tmp/today_logs.json

如果你需要在脚本中使用,推荐用--output=json配合jq工具做结构化提取。

八、组合过滤:实战中的高阶用法

实际排障时,单一过滤条件往往不够,需要组合使用。比如查看今天nginx服务产生的所有错误日志:

journalctl -u nginx.service --since today -p err

查看上次重启以来sshd服务的所有日志:

journalctl -u sshd.service -b -1

查看最近2小时内优先级为warning以上且包含特定关键字的日志:

journalctl --since "2 hours ago" -p warning --no-pager | grep -i "timeout"

查看某个时间段内某个PID的日志:

journalctl _PID=5678 --since "2024-06-01" --until "2024-06-02"

还有一个容易被忽略的参数--grep,它可以在日志消息内容中做正则匹配:

journalctl --since today --grep "connection refused"
九、实时监控与日志轮转注意事项

实时监控日志用-f参数,这个和tail -f一样好用:

journalctl -f

但要注意,journalctl -f默认显示所有日志,信息量可能很大。建议配合服务名或优先级使用:

journalctl -f -u docker.service -p warning

关于日志轮转,journald默认会自动管理日志大小和保留时间。如果你需要更精细的控制,可以编辑/etc/systemd/journald.conf:

[Journal]
SystemMaxUse=1G
RuntimeMaxUse=500M
MaxRetentionSec=1month
ForwardToSyslog=no

改完后重启服务生效:

sudo systemctl restart systemd-journald

SystemMaxUse是持久化日志最大占用,RuntimeMaxUse是运行时(/run下)的最大占用,MaxRetentionSec是最长保留时间。

十、常见问题与避坑指南

第一个坑:很多人发现journalctl查不到日志,先确认systemd-journald服务是否正常运行:

systemctl status systemd-journald

第二个坑:容器环境中(Docker),默认日志驱动可能是json-file而不是journald,所以容器内用journalctl可能查不到东西。需要在启动容器时指定--log-driver=journald。

第三个坑:如果你把日志导出到syslog或其他地方,journalctl就只保留本地部分。检查配置:

cat /etc/systemd/journald.conf | grep -i forward

第四个坑:时间过滤时注意时区问题。journalctl默认使用系统时区,如果你的服务器是UTC时区但你习惯用北京时间,计算时间窗口时要注意换算。

最后补充一个冷门但有用的技巧:验证日志文件完整性,防止日志被篡改:

journalctl --verify

这条命令会检查所有journal文件的哈希值,确保日志没有被非法修改。在安全审计场景下非常实用。

总结一下,journalctl的核心就是"时间+服务+优先级+启动次数+进程"这五个维度的组合过滤。掌握这些,Ubuntu系统的日志排查效率至少提升5倍以上。建议把常用命令写成alias放到.bashrc里,日常运维会省很多时间。