在 Red Hat Enterprise Linux 中分析日志

红帽企业 LinuxBeginner
立即练习

介绍

在本实验中,你将通过 journalctlrsyslog 在 Red Hat Enterprise Linux 9 上获得分析和存储系统日志的实践经验。你将首先了解系统日志记录的核心架构,包括 systemd-journaldrsyslog 的角色,并识别关键日志文件。随后,你将学习使用常用命令查看和过滤 syslog 文件,手动发送自定义 syslog 消息,并使用 journalctl 探索和过滤系统日志条目。本实验还涵盖了配置持久化系统日志存储,以及使用 timedatectlchronyd 维护准确的系统时间,为你提供系统分析和故障排除所需的基本技能。

理解系统日志架构与关键文件

在这一步中,你将了解 Red Hat Enterprise Linux 9 中系统日志记录的基本组件,重点关注 systemd-journaldrsyslog 服务,以及它们所管理的关键日志文件。理解这一架构对于有效的系统分析和故障排除至关重要。

首先,让我们探索 systemd-journald 服务。该服务是操作系统事件日志记录的核心。它从各种来源收集事件消息,包括系统内核、早期引导进程、守护进程的标准输出/错误以及 syslog 事件。systemd-journald 服务将这些日志存储在名为 journal 的结构化索引二进制文件中。

接下来,我们看看 rsyslog 服务。虽然 systemd-journald 负责收集日志,但 rsyslog 会在 syslog 消息到达时从 journal 中读取它们。然后,它会处理这些消息并根据其配置将其记录到 /var/log 目录下的传统日志文件中,或者将它们转发给其他服务。这些 rsyslog 文件在重启后依然存在。

让我们检查一下 /var/log 目录下由 rsyslog 管理的一些重要日志文件。你可以使用 ls 命令列出该目录的内容。

ls /var/log

你将看到各种日志文件的列表。根据你的系统,你应该能看到诸如 anacondaauditboot.logchronycrondnf.logmessagessecure 等文件。其中最常见的一些包括:

  • /var/log/messages:该文件包含大多数通用的 syslog 消息,但不包括与身份验证、电子邮件处理、计划任务执行和调试相关的消息。
  • /var/log/secure:该文件存储与安全和身份验证事件相关的 syslog 消息。
  • /var/log/maillog:该文件包含有关邮件服务器的 syslog 消息。
  • /var/log/cron:该文件记录有关计划任务执行的 syslog 消息。
  • /var/log/boot.log:该文件包含有关系统启动的非 syslog 控制台消息。

要查看这些文件的内容,你可以使用 catlesstail 等命令。请注意,/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(调试级消息)。严重程度从高到低的顺序为:emergalertcriterrwarningnoticeinfodebug

日志文件可能会变得非常大,导致难以找到特定信息。因此,过滤至关重要。你可以使用 grepawksed 等命令来过滤日志文件内容。

让我们先使用 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 会突出显示重要的日志消息:noticewarning 优先级的消息以粗体显示,而 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 选项显示指定优先级级别(按名称或数字)或更高的条目。优先级级别按升序排列为:debuginfonoticewarningerrcritalertemerg

让我们列出 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" 格式的时间参数。如果参数中有空格,则需要双引号。你也可以使用相对术语,如 yesterdaytodaytomorrow,或时间跨度,如 "-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 文件中使用诸如 SystemMaxUseSystemKeepFreeSystemMaxFileSizeMaxRetentionSec 等参数来配置大小限制和保留期限。

最后,当启用持久化 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 同步以进行自动时间调整。它接受 truefalse 作为参数。让我们暂时禁用 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

你将看到以 serverpool 开头的行,它们定义了 NTP 源。建议使用 iburst 选项,因为它会快速进行四次测量,以实现更准确的初始同步。

NTP 时间源的 stratum(层级)表示其质量。stratum 0 是参考时钟,stratum 1 直接连接到参考时钟,stratum 2stratum 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-journaldrsyslog 之间的相互作用。我们了解到 systemd-journald 在 journal 中收集并存储结构化、索引化的二进制日志,而 rsyslog 处理这些消息并将它们写入 /var/log 中的传统日志文件。我们探索了诸如 /var/log/messages/var/log/secure 等关键日志文件,并练习了使用常用命令查看和过滤 syslog 文件。我们还学习了如何手动发送自定义 syslog 消息。

此外,我们深入探讨了使用 journalctl 探索和过滤系统 journal 条目,了解了其访问详细系统事件的能力。然后,我们配置了持久化系统 journal 存储,以确保日志数据在重启后得以保留。最后,我们涵盖了使用 timedatectlchronyd 维护准确的系统时间,认识到它对于准确的日志时间戳和整体系统完整性的重要性。本实验通过强大的日志管理,为有效的系统分析和故障排除提供了必要的技能。