Systemd日志管理:使用Journalctl查看和处理系统日志

之前的文章Systemd日志管理服务:Journald以及重要配置选项介绍了Journald这个systemd引入的用于收集和存储日志数据的系统服务,本文将讨论systemd用来查看和处理系统日志的程序Journalctl,该实用程序可用于访问和操作保存在其中的数据和日志。

设定系统时间

使用二进制日志记录日志的好处之一是可以随意查看UTC或本地时间的日志记录。默认情况下,systemd将以当地时间显示结果。
因此,在开始使用日志之前,我们将确保正确设置时区。该systemd套件实际上附带了一个名为的工具timedatectl,可以为您提供帮助。
首先,查看该list-timezones选项提供哪些时区:

timedatectl list-timezones

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

sudo timedatectl set-timezone zone

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

timedatectl status
                      Local time: Thu 2020-04-02 17:45:33 CST
                  Universal time: Thu 2020-04-02 09:45:33 UTC
                        RTC time: Thu 2020-04-02 09:45:32
                       Time zone: Asia/Shanghai (CST, +0800)
       System clock synchronized: yes
systemd-timesyncd.service active: yes
                 RTC in local TZ: no

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

基本日志查看

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

单独使用时,系统中的每个日志分录都会显示在一个页面程序中(通常是less),供您浏览。最早的条目将排在最前面:

journalctl
-- Logs begin at Tue 2019-10-22 19:24:14 CST, end at Thu 2020-04-02 17:46:48 CST. --
Oct 22 19:24:14 ubuntu gnome-keyring-daemon[3487]: asked to register item /org/freedesktop/secrets/collection/login/1, but it's already registered
Oct 22 19:24:15 ubuntu gnome-keyring-daemon[3487]: asked to register item /org/freedesktop/secrets/collection/login/1, but it's already registered
Oct 22 19:24:15 ubuntu org.gnome.Shell.desktop[3622]: [13045:13045:1022/192415.470414:ERROR:buffer_manager.cc(488)] [.DisplayCompositor]GL ERROR :GL_INVALID_OPERATI
Oct 22 19:24:17 ubuntu /usr/lib/gdm3/gdm-x-session[3491]: (!!) vmware(0): New layout.
Oct 22 19:24:17 ubuntu /usr/lib/gdm3/gdm-x-session[3491]: (!!) vmware(0): 0: 0 0 1366 670
Oct 22 19:24:17 ubuntu /usr/lib/gdm3/gdm-x-session[3491]: (!!) vmware(0):
Oct 22 19:24:18 ubuntu gsd-color[3784]: unable to get EDID for xrandr-Virtual1: unable to get EDID for output
Oct 22 19:24:18 ubuntu gsd-color[3784]: unable to get EDID for xrandr-Virtual1: unable to get EDID for output
Oct 22 19:24:18 ubuntu gsd-color[3784]: unable to get EDID for xrandr-Virtual1: unable to get EDID for output

您可能会滚动浏览页面和数据页面,如果systemd已经在您的系统上放置了很长一段时间,则可能长达数万行。这说明了日志数据库中有多少数据可用。

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

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

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

journalctl --utc

按时间筛选日志

虽然访问如此大量的数据绝对有用,但是从心理上很难检查和处理如此大量的信息。因此,journalctl最重要的功能之一就是其过滤选项。

显示当前引导中的日志

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

journalctl -b

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

如果您不使用此功能并显示超过一天的启动时间,则每当系统发生故障时,您都会看到journalctl插入了这样的一行:

. . .

-- Reboot --

. . .

这可以用来帮助您在逻辑上将信息分成启动会话。

过去的引导日志

虽然您通常希望显示当前引导中的信息,但是在某些情况下,过去的引导当然也会有所帮助。该日志可以保存以前的许多引导中的信息,因此journalctl可以轻松显示信息。

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

sudo mkdir -p /var/log/journal

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

sudo nano /etc/systemd/journald.conf

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

. . .
[Journal]
Storage=persistent

在服务器上启用保存以前的启动时,journalctl提供一些命令来帮助您将启动作为划分单位来使用。要查看journald知道的引导,请将该--list-boots选项与journalctl结合使用:

journalctl --list-boots
-3 db067290ef4f48ddbdd83a22e7b71fb2 Tue 2019-10-22 19:24:14 CST—Sat 2019-10-26 15:45:01 CST
-2 64d3b8d79e004c7cadcc60950b33ba11 Thu 2019-10-31 21:01:09 CST—Sat 2019-11-16 00:50:39 CST
-1 2eb64eadc322420ab03a28b3bb549c2f Sat 2019-11-23 08:34:42 CST—Sat 2020-03-14 12:08:05 CST
 0 0e00ee4a36bd482ebf489f483fa162ec Thu 2020-04-02 17:33:17 CST—Thu 2020-04-02 17:59:29 CST

这将在每次启动时显示一行。第一列是引导程序的偏移量,journalctl可以轻松地引用引导程序。

要显示这些引导的信息,您可以使用第一列或第二列中的信息。

例如,要查看上一次引导的日志,请使用-1和带有-b标志的相对指针:

journalctl -b -1

您还可以使用启动ID来从启动中回调数据:

journalctl -b db067290ef4f48ddbdd83a22e7b71fb2

时间窗

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

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

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

YYYY-MM-DD HH:MM:SS

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

journalctl --since "2020-01-10 17:15:00"

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

journalctl --since "2020-01-10" --until "2020-01-11 03:00"

该日志还有一些相对值和命名的快捷方式。例如,您可以使用单词“昨天”,“今天”,“明天”或“现在”。您可以通过在数字前面加上“-”或“ +”或在句子结构中使用诸如“ ago”之类的字来设置相对时间。

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

journalctl --since yesterday

如果您收到从9:00 AM开始一直持续到一个小时前的服务中断报告,则可以输入:

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

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

按感兴趣的消息过滤

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

按单位(Unit)过滤

也许最有用的过滤方法是按您感兴趣的单位进行过滤。我们可以使用该-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
33

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

journalctl _UID=33 --since today

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

前划线表示该_PID字段是后一种类型。日志会自动记录并索引正在记录的进程的PID,以供以后过滤。您可以通过键入以下内容查找所有可用的日志字段:

man systemd.journal-fields

我们将在本指南中讨论其中一些内容。不过,到目前为止,我们将讨论一个更有用的选项,该选项与这些字段的过滤有关。该-F选项可用于显示给定日志字段的所有可用值。

例如,要查看systemd日志中包含条目的组ID ,可以键入:

journalctl -F _GID
1000
107
0
62583
122
103
123
114
125
106
117

这将显示日志为组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
. . .

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
{ "__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
{
    "__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用于监视活动或最近的活动。

显示最近的日志

要显示一定数量的记录,您可以使用-n选项,其功能与tail -n完全相同。

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

journalctl -n

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

journalctl -n 20

追踪日志

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

journalctl -f

日志维护

您可能想知道,存储到目前为止所看到的所有数据的成本是多少。此外,您可能会在清理一些较旧的日志并释放空间方面感兴趣。

查找当前磁盘使用情况

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

journalctl --disk-usage
Archived and active journals take up 816.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消耗和保留在服务器上的空间。

结论

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

你可能感兴趣的:(Systemd日志管理:使用Journalctl查看和处理系统日志)