介绍
在这个实验中,你将通过使用 journalctl 和 rsyslog 在 Red Hat Enterprise Linux 9 上分析和存储系统日志,获得实践经验。你将首先了解系统日志的核心架构,包括 systemd-journald 和 rsyslog 的作用,并识别关键的日志文件。随后,你将学习使用常用命令查看和过滤 syslog 文件,手动发送自定义 syslog 消息,以及使用 journalctl 探索和过滤系统 journal 条目。这个实验还涵盖了配置持久性系统 journal 存储,以及使用 timedatectl 和 chronyd 维护准确的系统时间,从而使你掌握系统分析和故障排除的基本技能。
理解系统日志架构和关键文件
在这一步,你将了解 Red Hat Enterprise Linux 9 中系统日志的基本组件,特别是关注 systemd-journald 和 rsyslog 服务,以及它们管理的关键日志文件。理解这种架构对于有效的系统分析和故障排除至关重要。
首先,让我们探索 systemd-journald 服务。该服务是操作系统的事件日志记录的核心。它从各种来源收集事件消息,包括系统内核、早期启动进程、守护进程的标准输出/错误,以及 syslog 事件。systemd-journald 服务将这些日志存储在一个结构化的、索引的二进制文件里,称为 journal。
接下来,我们将看看 rsyslog 服务。虽然 systemd-journald 收集日志,但 rsyslog 从 journal 中读取 syslog 消息,并在它们到达时进行处理。然后,它会处理这些消息,并将它们记录到 /var/log 目录中的传统日志文件中,或者根据其配置将它们转发到其他服务。这些 rsyslog 文件在重启后仍然存在。
让我们检查一下 rsyslog 在 /var/log 目录中管理的一些重要日志文件。你可以使用 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 Facilities: 这些表示日志消息的来源。例如,kern(内核消息)、user(用户级消息)、mail(邮件系统消息)、daemon(系统守护进程消息)、auth(身份验证和安全消息)和 cron(时钟守护进程消息)。
Syslog Priorities: 这些定义了消息的严重性,范围从 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 facility 和 notice priority(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.
现在,让我们尝试发送一条具有特定 facility 和 priority 的消息。回想一下上一步,syslog 消息按 facility 和 priority 进行分类。例如,local7.notice 意味着该消息将使用 local7 facility 和 notice priority 进行记录。local7 facility 经常用于自定义应用程序或启动消息,并且通常通过 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
这演示了如何通过指定 facility 和 priority 来控制自定义消息的记录位置。此功能对于测试 rsyslog 配置以及将特定事件注入系统日志非常有用。
使用 journalctl 探索和过滤系统日志条目
在这一步,你将学习如何使用 journalctl 命令探索和过滤系统日志条目。正如你所了解的,systemd-journald 服务将日志数据存储在一个结构化的、索引的二进制文件中,称为 journal。journalctl 命令是你与此 journal 交互的主要工具。
让我们从查看 journal 中的所有消息开始。当你运行 journalctl 没有任何选项时,它会显示所有可用的日志条目,从最旧的开始。由于你以 labex 的身份登录并具有 sudo 权限,你将完全访问 journal。
journalctl
你将看到大量的输出。按 q 退出 journalctl 查看器。请注意,journalctl 突出显示重要的日志消息:notice 或 warning priority 的消息以粗体文本显示,而 error priority 或更高的消息以红色文本显示。
现在,让我们探索一些常见的 journalctl 选项,用于过滤和查看特定条目。
1. 查看最后 N 个日志条目(-n 选项):
默认情况下,journalctl -n 显示最后 10 个日志条目。你可以指定一个不同的数字,例如,最后 5 个条目:
journalctl -n 5
你应该看到最近的 5 个日志条目。
2. 跟踪新的 journal 条目(-f 选项):
类似于 tail -f 命令,journalctl -f 选项输出系统 journal 的最后 10 行,并继续输出新添加的 journal 条目。这对于实时监控非常有用。
journalctl -f
要退出此连续输出,请按 Ctrl+C。
3. 按 priority 过滤(-p 选项):
你可以按 journal 条目的 priority 级别过滤输出。journalctl -p 选项显示指定 priority 级别(按名称或数字)或更高的条目。priority 级别,按升序排列,分别是 debug、info、notice、warning、err、crit、alert 和 emerg。
让我们列出 err priority 或更高的 journal 条目:
journalctl -p err
你可能会看到与各种系统组件相关的错误消息。
4. 按 systemd unit 过滤(-u 选项):
你可以通过使用 journalctl -u 选项和 unit 名称来显示指定 systemd unit 的消息。例如,要专门查看 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 unit)之类的字段。这些字段可用于更精确的过滤。
例如,要从具有已知 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。
你还可以使用 set-time 选项手动设置系统当前时间。格式为 "YYYY-MM-DD hh:mm:ss",但你可以省略日期或时间。让我们将时间设置为 09:00:00(对于当前日期)。
sudo timedatectl set-time 09:00:00
验证时间更改:
timedatectl
最后,set-ntp 选项启用或禁用 NTP 同步以进行自动时间调整。它将 true 或 false 作为参数。让我们暂时禁用 NTP 同步(稍后我们将重新启用它)。
sudo timedatectl set-ntp false
验证 NTP 服务状态:
timedatectl
你应该看到 NTP service: inactive。
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 维护准确的系统时间,认识到它对于准确的日志时间戳和整体系统完整性的重要性。本实验提供了通过强大的日志管理进行有效系统分析和故障排除的基本技能。



