介绍
在本实验中,你将通过 journalctl 和 rsyslog 在 Red Hat Enterprise Linux 9 上获得分析和存储系统日志的实践经验。你将首先了解系统日志记录的核心架构,包括 systemd-journald 和 rsyslog 的角色,并识别关键日志文件。随后,你将学习使用常用命令查看和过滤 syslog 文件,手动发送自定义 syslog 消息,并使用 journalctl 探索和过滤系统日志条目。本实验还涵盖了配置持久化系统日志存储,以及使用 timedatectl 和 chronyd 维护准确的系统时间,为你提供系统分析和故障排除所需的基本技能。
理解系统日志架构与关键文件
在这一步中,你将了解 Red Hat Enterprise Linux 9 中系统日志记录的基本组件,重点关注 systemd-journald 和 rsyslog 服务,以及它们所管理的关键日志文件。理解这一架构对于有效的系统分析和故障排除至关重要。
首先,让我们探索 systemd-journald 服务。该服务是操作系统事件日志记录的核心。它从各种来源收集事件消息,包括系统内核、早期引导进程、守护进程的标准输出/错误以及 syslog 事件。systemd-journald 服务将这些日志存储在名为 journal 的结构化索引二进制文件中。
接下来,我们看看 rsyslog 服务。虽然 systemd-journald 负责收集日志,但 rsyslog 会在 syslog 消息到达时从 journal 中读取它们。然后,它会处理这些消息并根据其配置将其记录到 /var/log 目录下的传统日志文件中,或者将它们转发给其他服务。这些 rsyslog 文件在重启后依然存在。
让我们检查一下 /var/log 目录下由 rsyslog 管理的一些重要日志文件。你可以使用 ls 命令列出该目录的内容。
ls /var/log
你将看到各种日志文件的列表。根据你的系统,你应该能看到诸如 anaconda、audit、boot.log、chrony、cron、dnf.log、messages、secure 等文件。其中最常见的一些包括:
/var/log/messages:该文件包含大多数通用的 syslog 消息,但不包括与身份验证、电子邮件处理、计划任务执行和调试相关的消息。/var/log/secure:该文件存储与安全和身份验证事件相关的 syslog 消息。/var/log/maillog:该文件包含有关邮件服务器的 syslog 消息。/var/log/cron:该文件记录有关计划任务执行的 syslog 消息。/var/log/boot.log:该文件包含有关系统启动的非 syslog 控制台消息。
要查看这些文件的内容,你可以使用 cat、less 或 tail 等命令。请注意,/var/log 中的大多数日志文件需要 root 权限才能读取,因此你需要使用 sudo。例如,让我们使用 tail 查看 /var/log/messages 文件的最后几行。
sudo tail /var/log/messages
你也可以查看 /var/log/secure 文件的内容,这对于安全审计非常重要。
sudo tail /var/log/secure
了解这些文件的用途将帮助你在排查系统问题时快速定位相关信息。
使用常用命令查看和过滤 Syslog 文件
在这一步中,你将学习如何使用常用的 Linux 命令有效地查看和过滤 syslog 文件。Syslog 消息按 facility(产生消息的子系统)和 priority(消息的严重程度)进行分类。理解这些类别对于高效的日志分析至关重要。
首先,让我们回顾一下 Syslog 设施(Facilities)和优先级(Priorities)的概念。
Syslog 设施: 这些指示日志消息的来源。例如 kern(内核消息)、user(用户级消息)、mail(邮件系统消息)、daemon(系统守护进程消息)、auth(身份验证和安全消息)以及 cron(时钟守护进程消息)。
Syslog 优先级: 这些定义了消息的严重程度,范围从 emerg(系统不可用)到 debug(调试级消息)。严重程度从高到低的顺序为:emerg、alert、crit、err、warning、notice、info、debug。
日志文件可能会变得非常大,导致难以找到特定信息。因此,过滤至关重要。你可以使用 grep、awk 和 sed 等命令来过滤日志文件内容。
让我们先使用 less 查看 /var/log/messages 的全部内容。此命令允许你在文件中滚动查看。按 q 退出 less。记得使用 sudo,因为读取日志文件需要 root 权限。
sudo less /var/log/messages
现在,让我们尝试过滤消息。假设你对与 authentication(身份验证)相关的消息感兴趣。这些消息通常可以在 /var/log/secure 中找到。使用 grep 在 /var/log/secure 中搜索包含单词 "authentication" 的行。记得使用 sudo 来访问日志文件。
sudo grep "authentication" /var/log/secure
如果没有最近的身份验证消息,你可能看不到任何输出。让我们尝试一个更常见的搜索词,比如 "sshd",它与 SSH 守护进程有关。
sudo grep "sshd" /var/log/secure
你应该能看到显示 SSH 守护进程活动、身份验证尝试或其他安全相关事件的输出。确切的输出将取决于当前的系统活动,可能包含如下条目:
Dec 16 10:15:30 host sshd[1234]: Accepted publickey for labex from 172.25.0.10 port 12345 ssh2
Dec 16 10:15:30 host sshd[1234]: pam_unix(sshd:session): session opened for user labex(uid=1000) by (uid=0)
...output omitted...
日志消息还包含时间戳。你可以按日期和时间过滤消息。例如,要查看特定日期的消息,可以将 grep 与日期结合使用。让我们尝试在 /var/log/messages 中查找今天的消息。使用系统中日志显示的当前日期格式。
sudo grep "$(date '+%b %d')" /var/log/messages
日志文件轮转(Log File Rotation):
为了防止日志文件占用过多的磁盘空间,系统会使用 logrotate。该工具会轮转日志文件,重命名旧文件(例如,/var/log/messages 变为 /var/log/messages-20220320)并创建新的空文件。经过一段时间(通常为四周)后,最旧的轮转日志文件会被丢弃。一个计划任务会每天运行 logrotate 来管理此过程。
你可以通过再次列出 /var/log 的内容来观察轮转后的日志文件。你可能会看到带有日期扩展名或 .gz 扩展名(如果它们已被压缩)的文件。
ls -l /var/log/messages*
示例输出:
-rw-------. 1 root root 123456 Mar 20 23:59 /var/log/messages
-rw-------. 1 root root 78901 Mar 13 23:59 /var/log/messages-20220320
-rw-------. 1 root root 54321 Mar 06 23:59 /var/log/messages-20220313.gz
...output omitted...
这展示了 logrotate 如何管理旧的日志文件。
最后,让我们分析一下 syslog 条目的结构。/var/log/secure 中的典型日志消息如下所示:
Dec 16 10:11:48 host sshd[1433]: Failed password for student from 172.25.0.10 port 59344 ssh2
Dec 16 10:11:48:日志条目的时间戳。host:发送日志消息的主机。sshd[1433]:发送日志消息的程序或进程名称 (sshd) 及其 PID (1433)。Failed password for …:实际的消息内容。
理解这种格式有助于你更有效地解析和解释日志条目。
手动发送自定义 Syslog 消息
在这一步中,你将学习如何使用 logger 命令手动发送自定义 syslog 消息。这是一种用于测试 rsyslog 服务配置,或为了调试和监控目的将自定义消息注入系统日志的有用技术。
logger 命令会将消息发送到 rsyslog 服务。默认情况下,它会以 user 设施和 notice 优先级 (user.notice) 发送消息,除非使用 -p 选项另行指定。
让我们先发送一条简单的测试消息到默认日志位置,通常是 /var/log/messages。
logger "This is a test message from labex."
执行命令后,你可以通过检查 /var/log/messages 文件来验证消息是否已记录。使用 tail 查看文件的最后几行。记得使用 sudo 来访问日志文件。
sudo tail /var/log/messages
你应该能在输出末尾看到你的自定义消息,类似于这样:
...
Dec 16 10:30:00 host labex: This is a test message from labex.
现在,让我们尝试发送一条具有特定设施和优先级的消息。回想一下上一步,syslog 消息是按设施和优先级分类的。例如,local7.notice 表示消息将以 local7 设施和 notice 优先级记录。local7 设施通常用于自定义应用程序或引导消息,并且通常由 rsyslog 配置定向到 /var/log/boot.log。
要发送一条消息到 rsyslog 服务并记录在 /var/log/boot.log 日志文件中,请执行以下 logger 命令:
logger -p local7.notice "Log entry created by labex for boot.log"
现在,验证该消息是否已写入 /var/log/boot.log。使用 sudo 访问日志文件。
sudo tail /var/log/boot.log
你应该能在输出中看到你的自定义消息:
...
Dec 16 10:31:00 host labex: Log entry created by labex for boot.log
这演示了如何通过指定设施和优先级来控制自定义消息的记录位置。此功能对于测试 rsyslog 配置以及将特定事件注入系统日志非常有用。
使用 journalctl 探索和过滤系统日志条目
在这一步中,你将学习如何使用 journalctl 命令探索和过滤系统日志条目。正如你所了解的,systemd-journald 服务将日志数据存储在名为 journal 的结构化索引二进制文件中。journalctl 命令是你与该 journal 交互的主要工具。
让我们先查看 journal 中的所有消息。当你运行不带任何选项的 journalctl 时,它会显示所有可用的日志条目,从最早的开始。由于你以具有 sudo 权限的 labex 用户身份登录,你将拥有对 journal 的完全访问权限。
journalctl
你将看到大量输出。按 q 退出 journalctl 查看器。请注意,journalctl 会突出显示重要的日志消息:notice 或 warning 优先级的消息以粗体显示,而 error 优先级或更高的消息以红色显示。
现在,让我们探索一些用于过滤和查看特定条目的常用 journalctl 选项。
1. 查看最后 N 条日志条目 (-n 选项):
默认情况下,journalctl -n 显示最后 10 条日志条目。你可以指定不同的数字,例如最后 5 条:
journalctl -n 5
你应该能看到最近的 5 条日志条目。
2. 跟随新的 journal 条目 (-f 选项):
类似于 tail -f 命令,journalctl -f 选项会输出系统 journal 的最后 10 行,并随着新条目的追加继续输出。这对于实时监控非常有用。
journalctl -f
要退出此持续输出,请按 Ctrl+C。
3. 按优先级过滤 (-p 选项):
你可以按 journal 条目的优先级级别过滤输出。journalctl -p 选项显示指定优先级级别(按名称或数字)或更高的条目。优先级级别按升序排列为:debug、info、notice、warning、err、crit、alert 和 emerg。
让我们列出 err 优先级或更高的 journal 条目:
journalctl -p err
你可能会看到与各种系统组件相关的错误消息。
4. 按 systemd 单元过滤 (-u 选项):
你可以通过使用 journalctl -u 选项和单元名称来显示指定 systemd 单元的消息。例如,要专门查看 sshd 服务的日志:
journalctl -u sshd.service
这将显示与 SSH 守护进程相关的所有日志条目。
5. 按时间范围过滤 (--since 和 --until 选项):
在查找特定事件时,你可以将输出限制在特定的时间范围内。--since 和 --until 选项都接受 "YYYY-MM-DD hh:mm:ss" 格式的时间参数。如果参数中有空格,则需要双引号。你也可以使用相对术语,如 yesterday、today、tomorrow,或时间跨度,如 "-1 hour"。
让我们查看从今天开始的所有 journal 条目:
journalctl --since today
现在,让我们查看过去一小时的条目:
journalctl --since "-1 hour"
6. 查看详细输出 (-o verbose 选项):
要查看每个日志条目的更多详细信息,包括内部 journal 字段,你可以使用 -o verbose 选项。这对于高级故障排除很有帮助。
journalctl -n 1 -o verbose
这将显示最后一条日志条目及其所有详细信息。注意诸如 _COMM(命令名称)、_EXE(可执行文件路径)、_PID(进程 ID)、_UID(用户 ID)和 _SYSTEMD_UNIT(systemd 单元)等字段。这些字段可用于更精确的过滤。
例如,要查找来自具有已知 PID 的特定 sshd 进程的条目(你可以从之前的 journalctl -u sshd.service 输出中获取 PID):
journalctl _SYSTEMD_UNIT=sshd.service _PID=<PID_NUMBER>
将 <PID_NUMBER> 替换为你从 sshd 条目中观察到的实际 PID。例如,如果你看到 sshd[1433],你将使用 _PID=1433。
journalctl _SYSTEMD_UNIT=sshd.service _PID=1433
此命令演示了如何组合多个过滤器来缩小 journal 中的搜索范围。
配置持久化系统日志存储
在这一步中,你将学习如何配置系统 journal 以在重启后保持持久化。默认情况下,Red Hat Enterprise Linux 9 将系统 journal 存储在 /run/log 目录中,这是一个临时文件系统。这意味着所有 journal 条目在系统重启后都会被清除。为了保留历史日志数据,你需要为持久化存储配置 systemd-journald 服务。
systemd-journald 的配置位于 /etc/systemd/journald.conf 文件中。该文件中的 Storage 参数决定了 journal 是以易失方式存储还是持久化存储。
Storage 参数可以设置为以下值之一:
persistent:将 journal 存储在/var/log/journal目录中,该目录在重启后依然存在。如果该目录不存在,systemd-journald将创建它。volatile:将 journal 存储在临时/run/log/journal目录中。/run中的数据在重启后不会保留。如果未明确设置Storage且/var/log/journal不存在,这是默认行为。auto:如果/var/log/journal目录存在,systemd-journald使用持久化存储;否则,它使用易失性存储。如果你不设置Storage参数,这是默认值。none:不使用存储。所有日志都会被丢弃,尽管它们仍然可以被转发。
让我们修改 /etc/systemd/journald.conf 文件以启用持久化 journal 存储。你将使用 sudo nano 编辑此文件。
sudo nano /etc/systemd/journald.conf
在 nano 编辑器中,找到 [Journal] 部分。取消注释 Storage 行(删除开头的 #)并将其值设置为 persistent。
你的文件应该看起来类似于这样(仅显示相关行):
[Journal]
Storage=persistent
#Compress=yes
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitIntervalSec=30s
#RateLimitBurst=1000
#SystemMaxUse=
#SystemKeepFree=
#SystemMaxFileSize=
#SystemMaxFiles=100
#RuntimeMaxUse=
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#RuntimeMaxFiles=100
#MaxRetentionSec=
#MaxFileSec=1month
#ForwardToSyslog=yes
#ForwardToKMsg=no
#ForwardToConsole=no
#ForwardToWall=yes
#TTYPath=/dev/console
#Audit=no
#FlushIntervalSec=
#SyncIntervalSec=
#ReadKMsg=yes
#Audit=yes
修改完成后,按 Ctrl+X 保存文件,然后按 Y 确认保存,按 Enter 确认文件名。
为了使更改生效,你需要重启 systemd-journald 服务。由于此环境是 Docker 容器,因此无法使用 systemctl。相反,我们将通过确保创建了 /var/log/journal 目录并具有正确的权限来模拟重启服务的效果,这在非容器化环境中是 systemd-journald 重启时会执行的操作。
首先,如果目录不存在,让我们创建它并设置适当的权限。
sudo mkdir -p /var/log/journal
sudo chown root:systemd-journal /var/log/journal
sudo chmod 2755 /var/log/journal
现在,要验证持久化存储是否已配置并处于活动状态,你可以检查 /var/log/journal 目录是否包含带有十六进制名称的子目录和 .journal 文件。这些文件存储了结构化和索引化的 journal 条目。
ls -l /var/log/journal
你应该看到一个带有长十六进制名称的子目录(例如 4ec03abd2f7b40118b1b357f479b3112)。在此目录中,你将找到 .journal 文件。
ls -l /var/log/journal/ <YOUR_HEX_ID> /
将 <YOUR_HEX_ID> 替换为你在上一个 ls 命令输出中找到的实际十六进制 ID。例如:
ls -l /var/log/journal/4ec03abd2f7b40118b1b357f479b3112/
你应该能看到诸如 system.journal 以及可能的 user-1000.journal 等文件。
即使启用了持久化 journal,系统也不会永远保留所有数据。Journal 具有内置的日志轮转机制。你可以在 /etc/systemd/journald.conf 文件中使用诸如 SystemMaxUse、SystemKeepFree、SystemMaxFileSize 和 MaxRetentionSec 等参数来配置大小限制和保留期限。
最后,当启用持久化 journal 时,journalctl 输出将包含来自当前系统引导以及之前系统引导的条目。要将输出限制为特定的系统引导,请使用 journalctl -b 选项。
要列出所有已识别的系统引导事件:
journalctl --list-boots
你将看到引导 ID 及其对应的时间范围列表。当前引导通常为 0。之前的引导是负数(-1、-2 等)。
要仅查看当前系统引导的条目:
journalctl -b
要查看上一次引导的条目(例如,当前引导之前的那个,通常为 -1):
journalctl -b -1
至此,持久化 journal 存储的配置完成。
使用 timedatectl 和 chronyd 维护准确的系统时间
在这一步中,你将学习如何使用 timedatectl 命令维护准确的系统时间,并了解 chronyd 服务的角色。准确的时间记录对于日志记录、安全性和许多网络服务至关重要。
1. 使用 timedatectl 管理系统时间和时区:
timedatectl 命令提供了当前与时间相关的系统设置的概览,包括本地时间、协调世界时 (UTC)、RTC 时间、时区和 NTP 同步状态。
让我们检查系统的当前时间设置:
timedatectl
你应该能看到类似于此的输出(确切的时间和日期将反映你当前的系统时间):
Local time: Sun 2025-06-15 21:46:11 EDT
Universal time: Mon 2025-06-16 01:46:11 UTC
RTC time: Mon 2025-06-16 01:46:10
Time zone: America/New_York (EDT, -0400)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
你可以使用 list-timezones 选项列出所有可用的时区:
timedatectl list-timezones | less
按 q 退出 less。时区是根据互联网号码分配局 (IANA) 时区数据库命名的,通常按大洲/海洋,然后是最大的城市来命名。
要更改系统的时区,请使用 set-timezone 选项。例如,让我们将时区更改为 America/Phoenix。你需要为此拥有 sudo 权限。
sudo timedatectl set-timezone America/Phoenix
现在,验证更改:
timedatectl
你应该能看到时区已更新为 America/Phoenix。
在你手动更改系统时间之前,必须暂时禁用 NTP 同步。set-ntp 选项启用或禁用 NTP 同步以进行自动时间调整。它接受 true 或 false 作为参数。让我们暂时禁用 NTP 同步(稍后我们将重新启用它)。
sudo timedatectl set-ntp false
验证 NTP 服务状态:
timedatectl
你应该能看到 NTP service: inactive。
现在你可以使用 set-time 选项手动设置系统的当前时间。格式为 "YYYY-MM-DD hh:mm:ss",但你可以省略日期或时间。让我们将时间设置为 09:00:00(针对当前日期)。
sudo timedatectl set-time 09:00:00
验证时间更改:
timedatectl
2. 理解和配置 chronyd 服务:
chronyd 服务是一个守护进程,它通过与网络时间协议 (NTP) 服务器同步来保持系统实时时钟 (RTC) 的准确性。它是 Red Hat Enterprise Linux 中的默认 NTP 客户端。
chronyd 的配置文件是 /etc/chrony.conf。默认情况下,它使用公共 NTP 服务器。在实际场景中,你可能会将其配置为使用内部 NTP 服务器。
让我们查看默认的 chrony.conf 文件。
cat /etc/chrony.conf
你将看到以 server 或 pool 开头的行,它们定义了 NTP 源。建议使用 iburst 选项,因为它会快速进行四次测量,以实现更准确的初始同步。
NTP 时间源的 stratum(层级)表示其质量。stratum 0 是参考时钟,stratum 1 直接连接到参考时钟,stratum 2 从 stratum 1 服务器同步。
由于此容器环境中无法使用 systemctl,我们无法直接重启 chronyd 来应用配置更改。但是,我们可以通过修改文件来模拟配置更改。
让我们使用 timedatectl 重新启用 NTP 同步。
sudo timedatectl set-ntp true
再次验证 NTP 服务状态:
timedatectl
你应该能看到 NTP service: active。
chronyc 命令充当 chronyd 服务的客户端。你可以使用它来监控同步状态。chronyc sources 命令显示当前的时间源及其同步状态。
chronyc sources -v
输出将显示有关 NTP 源的详细信息。S(源状态)字段中的星号 * 表示 chronyd 当前同步到的源。
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current best, '+' = combined, '-' = not combined,
| / 'x' = may be in error, '~' = too variable, '?' = unusable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) -. | xxxx = adjusted offset,
|| Log2(Polling interval) --. | | yyyy = measured offset,
|| \ | | zzzz = estimated error.
|| | | \
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 100.100.61.88 1 5 377 16 +1824us[+2180us] +/- 85ms
...output omitted...
此输出确认你的系统正在与 NTP 服务器主动同步其时间。
总结
在本实验中,我们全面了解了 Red Hat Enterprise Linux 9 中的系统日志架构,重点关注了 systemd-journald 和 rsyslog 之间的相互作用。我们了解到 systemd-journald 在 journal 中收集并存储结构化、索引化的二进制日志,而 rsyslog 处理这些消息并将它们写入 /var/log 中的传统日志文件。我们探索了诸如 /var/log/messages、/var/log/secure 等关键日志文件,并练习了使用常用命令查看和过滤 syslog 文件。我们还学习了如何手动发送自定义 syslog 消息。
此外,我们深入探讨了使用 journalctl 探索和过滤系统 journal 条目,了解了其访问详细系统事件的能力。然后,我们配置了持久化系统 journal 存储,以确保日志数据在重启后得以保留。最后,我们涵盖了使用 timedatectl 和 chronyd 维护准确的系统时间,认识到它对于准确的日志时间戳和整体系统完整性的重要性。本实验通过强大的日志管理,为有效的系统分析和故障排除提供了必要的技能。



