如何使用 Journalctl 查看和操作 Systemd 日志

介绍

一些最引人注目的优势systemd是涉及进程和系统日志记录的优势。使用其他工具时,日志通常分散在整个系统中,由不同的守护进程和进程处理,并且当它们跨越多个应用程序时可能很难解释。systemd试图通过提供用于记录所有内核和用户空间进程的集中管理解决方案来解决这些问题。收集和管理这些日志的系统称为日志

日志是通过journald守护进程实现的,它处理内核、initrd、服务等产生的所有消息。在本指南中,我们将讨论如何使用该journalctl实用程序,该实用程序可用于访问和操作其中保存的数据日记。

大概的概念

systemd日志背后的推动力之一是集中管理日志,而不管消息来自何处。由于大部分引导过程和服务管理由该systemd过程处理,因此标准化收集和访问日志的方式是有意义的。journald守护进程从方便和动态操纵二进制格式的所有可用的资源,并将它们存储收集数据。

这为我们提供了许多显着的优势。通过使用单个实用程序与数据交互,管理员能够根据需要动态显示日志数据。这可以像查看 3 次启动前的启动数据一样简单,或者按顺序组合来自两个相关服务的日志条目以调试通信问题。

以二进制格式存储日志数据还意味着可以根据您当前的需要以任意输出格式显示数据。例如,对于日常日志管理,您可能习惯于以标准syslog格式查看日志,但如果您决定稍后绘制服务中断的图表,则可以将每个条目作为 JSON 对象输出,使其可用于您的图表服务。由于数据不是以纯文本形式写入磁盘,因此当您需要不同的按需格式时无需进行转换。

systemd杂志可以与现有的用于syslog实现,或者它可以取代syslog的功能,根据您的需要。虽然该systemd日志将涵盖大多数管理员的日志记录需求,但它也可以补充现有的日志记录机制。例如,您可能有一个中央syslog服务器,用于从多个服务器编译数据,但您也可能希望将单个系统上多个服务的日志与日志交错systemd您可以通过结合这些技术来实现这两项。

设置系统时间

使用二进制日志进行日志记录的好处之一是能够随意查看 UTC 或本地时间的日志记录。默认情况下,systemd将以当地时间显示结果。

正因为如此,在我们开始使用期刊之前,我们将确保时区设置正确。systemd套件实际上带有一个名为的工具timedatectl,可以帮助解决这个问题。

首先,查看list-timezones选项可用的时区

  • timedatectl list-timezones

这将列出您系统上可用的时区。当您找到与您的服务器位置匹配的服务器时,您可以使用以下set-timezone选项进行设置:

  • sudo timedatectl set-timezone zone

要确保您的机器现在使用正确的时间,请timedatectl单独使用该命令或与该status选项一起使用。显示将相同:

  • timedatectl status
Output
Local time: Fri 2021-07-09 14:44:30 EDT Universal time: Fri 2021-07-09 18:44:30 UTC RTC time: Fri 2021-07-09 18:44:31 Time zone: America/New_York (EDT, -0400) System clock synchronized: yes NTP service: active RTC in local TZ: no

第一行应该显示正确的时间。

基本日志查看

要查看journald守护程序收集的日志,请使用该journalctl命令。

单独使用时,系统中的每个日记帐分录都将显示在寻呼机(通常为less)中供您浏览。最旧的条目将排在最前面:

  • journalctl
Output
-- Logs begin at Tue 2015-02-03 21:48:52 UTC, end at Tue 2015-02-03 22:29:38 UTC. -- Feb 03 21:48:52 localhost.localdomain systemd-journal[243]: Runtime journal is using 6.2M (max allowed 49. Feb 03 21:48:52 localhost.localdomain systemd-journal[243]: Runtime journal is using 6.2M (max allowed 49. Feb 03 21:48:52 localhost.localdomain systemd-journald[139]: Received SIGTERM from PID 1 (systemd). Feb 03 21:48:52 localhost.localdomain kernel: audit: type=1404 audit(1423000132.274:2): enforcing=1 old_en Feb 03 21:48:52 localhost.localdomain kernel: SELinux: 2048 avtab hash slots, 104131 rules. Feb 03 21:48:52 localhost.localdomain kernel: SELinux: 2048 avtab hash slots, 104131 rules. Feb 03 21:48:52 localhost.localdomain kernel: input: ImExPS/2 Generic Explorer Mouse as /devices/platform/ Feb 03 21:48:52 localhost.localdomain kernel: SELinux: 8 users, 102 roles, 4976 types, 294 bools, 1 sens, Feb 03 21:48:52 localhost.localdomain kernel: SELinux: 83 classes, 104131 rules . . .

您可能会有一页又一页的数据要滚动浏览,如果systemd在您的系统上存在很长时间,这些数据可能会长达数万或数十万行这说明了期刊数据库中有多少数据可用。

习惯于标准syslog日志记录的人会熟悉这种格式然而,这实际上从比传统syslog实现更多的来源收集数据它包括来自早期引导过程、内核、initrd 和应用程序标准错误的日志。这些都可以在期刊上找到。

您可能会注意到所有显示的时间戳都是当地时间。现在我们在我们的系统上正确设置了本地时间,这可用于每个日志条目。使用此新信息显示所有日志。

如果要以 UTC 显示时间戳,可以使用以下--utc标志:

  • journalctl --utc

按时间过滤期刊

虽然访问如此庞大的数据集合绝对有用,但手动检查和处理如此大量的信息可能很困难或不可能。因此,最重要的功能之一journalctl是它的过滤选项。

显示当前引导的日志

您可能每天使用的最基本的东西是-b标志。这将显示自最近重新启动以来收集的所有日志条目。

  • journalctl -b

这将帮助您识别和管理与您当前环境相关的信息。

如果您不使用此功能并显示超过一天的启动,您将看到journalctl在系统出现故障时插入了如下所示的行:

Output
. . . -- Reboot -- . . .

这可用于帮助您在逻辑上将信息分离到引导会话中。

过去的靴子

虽然您通常希望显示当前引导的信息,但有时过去的引导也会有所帮助。日志可以保存许多以前的靴子的信息,因此journalctl可以很容易地显示信息。

某些发行版默认启用保存以前的启动信息,而其他发行版则禁用此功能。要启用持久引导信息,您可以通过键入以下内容来创建目录来存储日志:

  • sudo mkdir -p /var/log/journal

或者您可以编辑日志配置文件:

  • sudo nano /etc/systemd/journald.conf

在该[Journal]部分下,将Storage=选项设置为“persistent”以启用持久日志记录:

/etc/systemd/journald.conf
. . .
[Journal]
Storage=persistent

在您的服务器上启用保存以前的引导时,会journalctl提供一些命令来帮助您将引导作为一个单位进行处理。要查看journald知道的靴子,请使用--list-boots带有journalctl以下选项的选项

journalctl --list-boots
Output
-2 caf0524a1d394ce0bdbcff75b94444fe Tue 2015-02-03 21:48:52 UTC—Tue 2015-02-03 22:17:00 UTC -1 13883d180dc0420db0abcb5fa26d6198 Tue 2015-02-03 22:17:03 UTC—Tue 2015-02-03 22:19:08 UTC 0 bed718b17a73415fade0e4e7f4bea609 Tue 2015-02-03 22:19:12 UTC—Tue 2015-02-03 23:01:01 UTC

这将为每次启动显示一行。第一列是引导的偏移量,可用于轻松引用引导journalctl如果您需要绝对引用,则引导 ID 位于第二列中。您可以通过最后列出的两个时间规范来判断引导会话所指的时间。

要显示来自这些靴子的信息,您可以使用第一列或第二列中的信息。

例如,要查看上次启动的日志,请使用-1带有-b标志相对指针

  • journalctl -b -1

您还可以使用引导 ID 从引导中回调数据:

  • journalctl -b caf0524a1d394ce0bdbcff75b94444fe

时间窗口

虽然通过启动查看日志条目非常有用,但通常您可能希望请求与系统启动不一致的时间窗口。在处理具有大量正常运行时间的长时间运行的服务器时,这一点尤其如此。

您可以使用--since--until选项按任意时间限制进行​​过滤,分别将显示的条目限制在给定时间之后或之前的条目。

时间值可以采用多种格式。对于绝对时间值,您应该使用以下格式:

  • YYYY-MM-DD HH:MM:SS

例如,我们可以通过键入以下内容查看自 2015 年 1 月 10 日下午 5:15 以来的所有条目:

  • journalctl --since "2015-01-10 17:15:00"

如果不使用上述格式的组件,则将应用一些默认值。例如,如果省略日期,则将假定为当前日期。如果缺少时间部分,将替换为“00:00:00”(午夜)。秒字段也可以保留为默认为“00”:

  • journalctl --since "2015-01-10" --until "2015-01-11 03:00"

该期刊还了解一些相对值和命名快捷方式。例如,您可以使用“昨天”、“今天”、“明天”或“现在”等词。您可以通过在数字值前加上“-”或“+”或在句子结构中使用“ago”之类的词来计算相对时间。

要获取昨天的数据,您可以键入:

  • journalctl --since yesterday

如果您收到从上午 9:00 开始并持续到一个小时前的服务中断报告,您可以键入:

  • journalctl --since 09:00 --until "1 hour ago"

如您所见,定义灵活的时间窗口来过滤您希望查看的条目相对简单。

按消息兴趣过滤

上面,我们学习了一些可以使用时间限制过滤日志数据的方法。在本节中,我们将讨论如何根据您感兴趣的服务或组件进行过滤。该systemd期刊提供了多种执行此操作的方法。

按单位

也许最有用的过滤方式是按您感兴趣的单位进行过滤。我们可以使用该-u选项以这种方式进行过滤。

例如,要查看系统上 Nginx 单元的所有日志,我们可以键入:

  • journalctl -u nginx.service

通常,您可能还想按时间过滤以显示您感兴趣的行。例如,要检查服务今天的运行情况,您可以键入:

  • journalctl -u nginx.service --since today

当您利用期刊从不同单元交错记录的能力时,这种类型的关注会变得非常有用。例如,如果您的 Nginx 进程连接到一个 PHP-FPM 单元来处理动态内容,您可以通过指定两个单元按时间顺序合并来自两者的条目:

  • journalctl -u nginx.service -u php-fpm.service --since today

这可以更容易地发现不同程序和调试系统之间的交互,而不是单个进程。

按进程、用户或组 ID

一些服务会产生各种子进程来完成工作。如果您已经找到了您感兴趣的进程的确切 PID,您也可以通过它进行过滤。

为此,我们可以通过指定_PID字段进行过滤例如,如果我们感兴趣的 PID 是 8088,我们可以输入:

  • journalctl _PID=8088

在其他时候,您可能希望显示从特定用户或组记录的所有条目。这可以通过_UID_GID过滤器来完成例如,如果您的 Web 服务器在www-data用户下运行,您可以通过键入以下内容找到用户 ID:

  • id -u www-data
Output
33

之后,您可以使用返回的 ID 来过滤日志结果:

  • journalctl _UID=33 --since today

systemd杂志有许多领域可以用于过滤。其中一些是从正在记录的进程传递的,而另一些是通过journald使用它在记录时从系统收集的信息来应用的

前导下划线表示该_PID字段属于后一种类型。日志自动记录并索引正在记录的进程的 PID 以供以后过滤。您可以通过键入以下内容来了解​​所有可用的期刊字段:

  • man systemd.journal-fields

我们将在本指南中讨论其中的一些。不过现在,我们将讨论一个更有用的选项,与这些字段的过滤有关。-F选项可用于显示给定日记帐字段的所有可用值。

例如,要查看systemd日记帐具有哪些组 ID ,您可以键入:

  • journalctl -F _GID
Output
32 99 102 133 81 84 100 0 124 87

这将显示日志为组 ID 字段存储的所有值。这可以帮助您构建过滤器。

按组件路径

我们还可以通过提供路径位置进行过滤。

如果路径指向可执行文件,journalctl则将显示涉及相关可执行文件的所有条目。例如,要查找涉及bash可执行文件的条目,您可以键入:

  • journalctl /usr/bin/bash

通常,如果一个单元可用于可执行文件,则该方法更清晰并提供更好的信息(来自相关子进程的条目等)。然而,有时这是不可能的。

显示内核消息

内核消息(通常在dmesg输出中找到的消息)也可以从日志中检索。

要仅显示这些消息,我们可以将-k--dmesg标志添加到我们的命令中:

  • journalctl -k

默认情况下,这将显示当前引导的内核消息。您可以使用前面讨论的正常引导选择标志指定替代引导。例如,要从五次启动前获取消息,您可以键入:

  • journalctl -k -b -5

按优先级

系统管理员经常感兴趣的一种过滤器是消息优先级。虽然以非常详细的级别记录信息通常很有用,但在实际消化可用信息时,低优先级的日志可能会分散注意力和混淆。

您可以使用journalctl-p选项仅显示指定优先级或更高优先级的消息这允许您过滤掉较低优先级的消息。

例如,要仅显示记录在错误级别或更高级别的条目,您可以键入:

  • journalctl -p err -b

这将显示所有标记为错误、严重、警报或紧急情况的消息。日志实现标准syslog消息级别。您可以使用优先级名称或其相应的数值。按照优先级从高到低的顺序,它们是:

  • 0 : 出现
  • 1:警报
  • 2:暴击
  • 3:错误
  • 4:警告
  • 5:通知
  • 6:信息
  • 7:调试

上述数字或名称可以与-p选项互换使用选择优先级将显示标记在指定级别及其之上的消息。

修改日志显示

上面,我们演示了通过过滤选择条目。我们可以通过其他方式修改输出。我们可以调整journalctl显示以适应各种需要。

截断或扩展输出

我们可以journalctl通过告诉它缩小或扩大输出来调整显示数据的方式。

默认情况下,journalctl将在寻呼机中显示整个条目,允许条目拖到屏幕右侧。可以通过按右箭头键访问此信息。

如果您希望截断输出,在已删除信息的位置插入省略号,您可以使用以下--no-full选项:

  • journalctl --no-full
Output
. . . Feb 04 20:54:13 journalme sshd[937]: Failed password for root from 83.234.207.60...h2 Feb 04 20:54:13 journalme sshd[937]: Connection closed by 83.234.207.60 [preauth] Feb 04 20:54:13 journalme sshd[937]: PAM 2 more authentication failures; logname...ot

您也可以与此相反,并告诉journalctl显示其所有信息,无论它是否包含不可打印的字符。我们可以用-a标志来做到这一点

  • journalctl -a

输出到标准输出

默认情况下,journalctl在寻呼机中显示输出以便于使用。但是,如果您计划使用文本操作工具处理数据,您可能希望能够输出到标准输出。

您可以使用以下--no-pager选项执行此操作

  • journalctl --no-pager

根据您的需要,这可以立即通过管道传输到处理实用程序或重定向到磁盘上的文件中。

输出格式

如果您正在处理日志条目,如上所述,如果数据采用更易使用的格式,您很可能会更容易解析数据。幸运的是,日志可以根据需要以各种格式显示。您可以使用-o带有格式说明符选项来执行此操作

例如,您可以通过键入以下内容以 JSON 格式输出日志条目:

  • journalctl -b -u nginx -o json
Output
{ "__CURSOR" : "s=13a21661cf4948289c63075db6c25c00;i=116f1;b=81b58db8fd9046ab9f847ddb82a2fa2d;m=19f0daa;t=50e33c33587ae;x=e307daadb4858635", "__REALTIME_TIMESTAMP" : "1422990364739502", "__MONOTONIC_TIMESTAMP" : "27200938", "_BOOT_ID" : "81b58db8fd9046ab9f847ddb82a2fa2d", "PRIORITY" : "6", "_UID" : "0", "_GID" : "0", "_CAP_EFFECTIVE" : "3fffffffff", "_MACHINE_ID" : "752737531a9d1a9c1e3cb52a4ab967ee", "_HOSTNAME" : "desktop", "SYSLOG_FACILITY" : "3", "CODE_FILE" : "src/core/unit.c", "CODE_LINE" : "1402", "CODE_FUNCTION" : "unit_status_log_starting_stopping_reloading", "SYSLOG_IDENTIFIER" : "systemd", "MESSAGE_ID" : "7d4958e842da4a758f6c1cdc7b36dcc5", "_TRANSPORT" : "journal", "_PID" : "1", "_COMM" : "systemd", "_EXE" : "/usr/lib/systemd/systemd", "_CMDLINE" : "/usr/lib/systemd/systemd", "_SYSTEMD_CGROUP" : "/", "UNIT" : "nginx.service", "MESSAGE" : "Starting A high performance web server and a reverse proxy server...", "_SOURCE_REALTIME_TIMESTAMP" : "1422990364737973" } . . .

这对于使用实用程序进行解析很有用。json-pretty在将其传递给 JSON 使用者之前,您可以使用该格式更好地处理数据结构:

  • journalctl -b -u nginx -o json-pretty
Output
{ "__CURSOR" : "s=13a21661cf4948289c63075db6c25c00;i=116f1;b=81b58db8fd9046ab9f847ddb82a2fa2d;m=19f0daa;t=50e33c33587ae;x=e307daadb4858635", "__REALTIME_TIMESTAMP" : "1422990364739502", "__MONOTONIC_TIMESTAMP" : "27200938", "_BOOT_ID" : "81b58db8fd9046ab9f847ddb82a2fa2d", "PRIORITY" : "6", "_UID" : "0", "_GID" : "0", "_CAP_EFFECTIVE" : "3fffffffff", "_MACHINE_ID" : "752737531a9d1a9c1e3cb52a4ab967ee", "_HOSTNAME" : "desktop", "SYSLOG_FACILITY" : "3", "CODE_FILE" : "src/core/unit.c", "CODE_LINE" : "1402", "CODE_FUNCTION" : "unit_status_log_starting_stopping_reloading", "SYSLOG_IDENTIFIER" : "systemd", "MESSAGE_ID" : "7d4958e842da4a758f6c1cdc7b36dcc5", "_TRANSPORT" : "journal", "_PID" : "1", "_COMM" : "systemd", "_EXE" : "/usr/lib/systemd/systemd", "_CMDLINE" : "/usr/lib/systemd/systemd", "_SYSTEMD_CGROUP" : "/", "UNIT" : "nginx.service", "MESSAGE" : "Starting A high performance web server and a reverse proxy server...", "_SOURCE_REALTIME_TIMESTAMP" : "1422990364737973" } . . .

以下格式可用于显示:

  • cat:仅显示消息字段本身。
  • export:适合传输或备份的二进制格式。
  • json:标准 JSON,每行一个条目。
  • json-pretty : JSON 格式以提高人类可读性
  • json-sse : JSON 格式的输出包装,使添加服务器发送的事件兼容
  • short : 默认syslog样式输出
  • short-iso:增强的默认格式以显示 ISO 8601 挂钟时间戳。
  • short-monotonic:具有单调时间戳的默认格式。
  • short-precise:具有微秒精度的默认格式
  • verbose:显示条目可用的每个日志字段,包括通常隐藏在内部的那些。

这些选项允许您以最适合您当前需要的任何格式显示日记帐分录。

主动过程监控

journalctl命令模仿有多少管理员tail用于监视活动或最近的活动。此功能内置于 中journalctl,允许您访问这些功能而无需通过管道连接到其他工具。

显示最近的日志

要显示一定数量的记录,您可以使用该-n选项,其作用与tail -n.

默认情况下,它将显示最近的 10 个条目:

  • journalctl -n

您可以在 之后用数字指定要查看的条目数-n

  • journalctl -n 20

关注日志

要在写入日志时主动跟踪日志,您可以使用该-f标志。同样,如果您有使用经验,这将按您的预期工作tail -f

  • journalctl -f

要退出此命令,请键入CTRL+C

日志维护

您可能想知道存储我们迄今为止看到的所有数据的成本。此外,您可能会对清理一些旧日志并释放空间感兴趣。

查找当前磁盘使用情况

您可以使用以下--disk-usage标志找出日志当前在磁盘上占用的空间量

  • journalctl --disk-usage
Output
Archived and active journals take up 8.0M in the file system.

删除旧日志

如果您希望缩小您的日志,您可以通过两种不同的方式来实现(在systemd218 及更高版本中可用)。

如果您使用该--vacuum-size选项,您可以通过指定尺寸来缩小您的日记本。这将删除旧条目,直到磁盘上占用的总日志空间达到请求的大小:

  • sudo journalctl --vacuum-size=1G

缩小日志的另一种方法是为--vacuum-time选项提供截止时间任何超过该时间的条目都将被删除。这允许您保留在特定时间后创建的条目。

例如,要保留去年的条目,您可以键入:

  • sudo journalctl --vacuum-time=1years

限制日志扩展

您可以将服务器配置为限制日志可以占用的空间。这可以通过编辑/etc/systemd/journald.conf文件来完成

以下项目可用于限制日记帐增长:

  • SystemMaxUse=:指定持久存储中日志可以使用的最大磁盘空间。
  • SystemKeepFree=:指定将日志条目添加到持久存储时日志应保留的可用空间量。
  • SystemMaxFileSize=:控制单个日志文件在轮换之前可以在持久存储中增长到多大。
  • RuntimeMaxUse=:指定可用于易失性存储(/run文件系统内)的最大磁盘空间
  • RuntimeKeepFree=: 指定在将数据写入易失性存储(在/run文件系统内)时为其他用途留出的空间量
  • RuntimeMaxFileSize=:指定单个日志文件/run在轮换之前可以在易失性存储(文件系统内)中占用的空间量

通过设置这些值,您可以控制如何journald消耗和保留服务器上的空间。请记住,SystemMaxFileSize并将RuntimeMaxFileSize以归档文件为目标,以达到规定的限制。在清理操作后解释文件计数时要记住这一点很重要。

结论

如您所见,该systemd日志对于收集和管理您的系统和应用程序数据非常有用。大多数灵活性来自自动记录的广泛元数据和日志的集中性质。journalctl命令可以轻松利用日志的高级功能,并对不同的应用程序组件进行广泛的分析和关系调试。

觉得文章有用?

点个广告表达一下你的爱意吧 !😁