文章目录
- 1.介紹
- 2.概念
- 设置system time
- 基本的日志查阅方法
- 按时过滤日志(by Time)
- 显示本次启动以来的日志(Current Boot)
- 按Past Boots
- 按时间窗口
- 按感兴趣的消息筛选
- 按unit
- 按进程、用户、Group ID
- 按组件路径
- 显示内核消息
- 按消息优先级
- 修改Journal输出格式
- 截断或扩展输出
- 输出日志到标准输出
- 输出格式
- 主动进程监控
- 显示最近的日志
- Follow日志
- Journal维护
- 查找当前磁盘空间使用量
- 删除旧的日志
- 限制日志扩展
1.介紹
systemd
systemd 的一些最瞩目的优点是涉及进程和系统日志记录。 使用其他工具时,日志通常分散在整个系统中,由不同的守护程序和进程处理,并且当它们跨越多个应用程序时可能相当难以解释。 systemd 试图通过提供一个集中管理解决方案来记录所有内核和用户态进程来解决这些问题。 收集和管理这些日志的系统称为journal.
日志是通过journald守护进程实现的,它处理内核、initrd、服务等产生的所有消息
2.概念
systemd journal背后的推动力之一是集中管理日志,无论消息源自何处。 由于大部分启动过程和服务管理都是由 systemd 进程处理的,因此标准化日志收集和访问的方式是有意义的。 journal守护进程从所有可用来源收集数据,并将其以二进制格式存储,以便于动态操作。
通过使用单个工具与数据进行交互,管理员可以根据自己的需要动态显示日志数据。 或者按顺序组合来自两个相关服务的日志条目以调试通信问题。
以二进制格式存储log数据还意味着数据可以根据当前的需要以任意输出格式显示。 例如,对于日常日志管理,可能习惯于以标准syslog格式查看日志,但如果以后决定用图形方式显示服务中断情况,则可以将每个条目输出为 JSON 对象,以使其可供图表服务使用。 由于数据不是以纯文本形式写入磁盘,因此当需要不同的按需格式时无需转换。
systemd journal可以与现有的 syslog 实现一起使用,也可以替换 syslog 功能,具体取决于需求。 虽然 systemd journal将满足大多数管理员的日志记录需求,但它也可以补充现有的日志记录机制。 例如,可能有一个集中式 syslog 服务器,用于编译来自多个服务器的数据,但您也可能希望将来自单个系统上多个服务的日志与 systemd 日志交错。 可以通过组合这些技术来实现这两个目标。
设置system time
使用二进制日志进行日志记录的好处之一是能够随意查看 UTC 或本地时间的日志记录。 默认情况下,systemd 将按当地时间显示结果。
因此,在开始使用journal之前,我们将确保时区设置正确。 systemd 套件实际上附带了一个名为 timedatectl 的工具,可以帮助解决此问题。
First, see what timezones are available with the list-timezones option:
首先,通过 list-timezones 选项查看哪些时区可用:
timedatectl list-timezones
这将列出系统上可用的时区。 当找到与服务器位置匹配的时区时,可以使用 set-timezone 选项进行设置:
sudo timedatectl set-timezone zone
要确保计算机现在使用正确的时间,单独使用 timedatectl 命令,或与 status 选项一起使用。 显示将是相同的:
timedatectl status
Output
Local time: Fri 2024-02-09 14:44:30 EDT
Universal time: Fri 2024-02-09 18:44:30 UTC
RTC time: Fri 2024-02-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记录的人来说,这种格式会很熟悉。 然而,这实际上从比传统系统日志实现更多的来源收集数据。 它包括来自早期boot过程、内核、initrd 以及应用程序标准错误和标准输出的日志。 这些都可以在journal中找到。
您可能会注意到显示的所有时间戳都是当地时间。 现在我们已经在系统上正确设置了本地时间,这对于每个日志条目都是可用的。 所有日志均使用此新信息显示。
如果您想显示 UTC 时间戳,可以使用 --utc 标志:
journalctl --utc
按时过滤日志(by Time)
虽然访问如此大量的数据集合绝对有用,但手动检查和处理如此大量的信息可能很困难或不可能。 因此,journalctl 最重要的功能之一就是它的过滤选项。
显示本次启动以来的日志(Current Boot)
每天可能会使用的最基本的标志是 -b 选项。 这将显示自最近重新启动以来收集的所有日记条目。
journalctl -b
这将帮助识别和管理与当前环境相关的信息。
如果没有使用此功能并且显示超过一天的启动时间,则只要系统出现宕机重启,您就会看到journalctl 插入了如下所示的一行:
Output
. . .
– Reboot –
. . .
这可用于帮助您在逻辑上将信息分离到boot会话中。
按Past Boots
虽然通常希望显示当前启动的信息,但有时过去的启动也会有所帮助。 journal可以保存许多以前启动的信息,因此可以使journalctl轻松显示信息。
某些发行版默认启用保存以前的boot信息,而其他发行版则禁用此功能。 要启用持久化boot信息,可以通过键入以下内容来创建存储日志的目录:
sudo mkdir -p /var/log/journal
或者可以编辑日志配置文件:
sudo nano /etc/systemd/journald.conf
Under the [Journal] section, set the Storage= option to “persistent” to enable persistent logging:
在 [Journal] 部分下,将 Storage= 选项设置为“persistent”以启用持久日志记录:
/etc/systemd/journald.conf
. . .
[Journal]
Storage=persistent
当您的服务器上启用保存之前的boot信息时,journalctl 会提供一些命令来帮助您将boot作为划分单位。 要查看journald保存的“boot”,在journalctl中使用–list-boots选项:
journalctl --list-boots
Output:
-2 caf0524a1d394ce0bdbcff75b94444fe Tue 2024-02-03 21:48:52 UTC—Tue 2024-02-03 22:17:00 UTC
-1 13883d180dc0420db0abcb5fa26d6198 Tue 2024-02-03 22:17:03 UTC—Tue 2024-02-03 22:19:08 UTC0 bed718b17a73415fade0e4e7f4bea609 Tue 2024-02-03 22:19:12 UTC—Tue 2024-02-03 23:01:01 UTC
This will display a line for each boot. The first column is the offset for the boot that can be used to easily reference the boot with journalctl. If you need an absolute reference, the boot ID is in the second column. You can tell the time that the boot session refers to with the two time specifications listed towards the end.
这将为每个boot显示一行。 第一列是系统启动的偏移量,可用于通过journalctl轻松引用每个boot。 如果您需要绝对引用,boot ID 位于第二列中。 可以通过最后列出的两个时间字段来判断boot会话所指的时间。
要显示这些boot的信息,可以使用第一列或第二列中的信息。
例如,要查看上次启动的日志,请使用 -1 相对指针和 -b 标志:
journalctl -b -1
还可以使用boot ID 回调启动数据:
journalctl -b caf0524a1d394ce0bdbcff75b94444fe
按时间窗口
虽然通过boot查看日志条目非常有用,但有时只希望查询某一段时间窗口的日志条目。 在处理显著uptime时间的长时间运行的服务器时尤其如此。
这种情况可以考虑使用 --since 和 --until 选项按任意时间限制进行过滤,这分别将显示的条目限制为给定时间之后或之前的条目。
时间值可以有多种格式。 对于绝对时间值,应该使用以下格式:
YYYY-MM-DD HH:MM:SS
例如,我们可以通过输入以下命令查看自 2024年 1 月 10 日下午 5:15 以来的所有条目:
journalctl --since "2024-01-10 17:15:00"
如果省略上述格式的组成部分则将应用一些默认值。 例如,如果省略日期,则将假定当前日期。 如果时间部分缺失,则将替换为“00:00:00”(午夜)。 秒字段也可以省略,默认为“00”:
journalctl --since "2024-01-10" --until "2024-01-11 03:00"
Journal还使用一些相对值和命名的快捷方式。 例如,可以使用“yesterday”、“today”、“tomorrow”或“now”等词。 可以通过在数值前添加“-”或“+”或在句子结构中使用“ago”等单词来计算相对时间。
要获取昨天的数据,可以输入:
journalctl --since yesterday
如果您收到从上午 9:00 开始并持续到一小时前的服务中断报告,可以输入:
journalctl --since 09:00 --until "1 hour ago"
正如上面所看到的,定义灵活的时间窗口使得过滤希望查看的条目变得相对简单。
按感兴趣的消息筛选
上面,我们了解了一些使用时间限制过滤日志数据的方法。 接下来,我们将讨论如何根据您感兴趣的服务或组件进行过滤。systemd 日志提供了多种执行此操作的方法。
按unit
如果要查看某个服务相关的日志,则unit应该是最有效的方式。我们可以使用 -u 选项以这种方式进行过滤。
例如,要查看系统上 Nginx 单元的所有日志,我们可以输入:
journalctl -u nginx.service
通常,可能还希望按时间进行过滤,以便显示感兴趣的行。例如,要检查服务今天的运行情况,您可以键入:
journalctl -u nginx.service --since today
当利用journal整合来自不同unit的日志记录的能力时,这种类型的专注类型变得非常有用。 例如,如果有一个Nginx 进程连接到 PHP-FPM 单元来处理动态内容,则可以通过指定两个unit来按时间顺序合并两个unit中的条目:
journalctl -u nginx.service -u php-fpm.service --since today
这可以更容易地发现不同程序和调试系统之间的交互,而不是单个进程之间的交互。
按进程、用户、Group ID
某些服务会产生各种子进程来完成工作。 如果您已经找出了感兴趣的进程的确切 PID,也可以根据它进行过滤。
为此,可以通过指定 _PID 字段进行过滤。 例如,如果想了解 PID 是 8088的进程,可以输入:
journalctl _PID=8088
有时,可能希望显示从特定用户或组记录的所有条目。 这可以通过 _UID 或 _GID 过滤器来完成。 例如,如果有web服务器在 www-data 用户下运行,可以通过键入以下内容找到用户 :
id -u www-data
Output
33
之后,可以使用返回的 ID 来过滤日志结果:
journalctl _UID=33 --since today
systemd journal有许多可用于过滤的字段。 其中一些是从正在记录的进程传递的,另一些是由journald在日志记录时,使用从系统收集的信息应用的。
Q
前导下划线表示 _PID 字段属于后一种类型。 journal自动记录并索引正在记录的进程的 PID,以供以后过滤。 您可以通过键入以下内容了解所有可用的日记字段:
man systemd.journal-fields
我们稍后将讨论其中的一些内容。 现在,我们先看看一个与按这些字段进行过滤有关的更有用的选项。 -F 选项可用于显示给定journal字段的所有可用值。
例如,要查看 systemd journal有哪些Group ID 的条目,可以输入:
journalctl -F _GID
Output
32
99
102
133
81
84
100
0
124
87
这将显示日journal为Group ID 字段存储的所有值。 这可以帮助您构建过滤。
按组件路径
我们还可以通过提供路径位置进行过滤。
如果路径指向可执行文件,journalctl 将显示涉及相关可执行文件的所有条目。 例如,要查找涉及 bash 可执行文件的条目,您可以输入:
journalctl /usr/bin/bash
通常,如果一个unit可用于可执行文件,则-u或–unit方法更干净并提供更好的信息(有来自于关联子进程的日志条目等等好处)。 否则,by path就能够提供必要的帮助给我们。
显示内核消息
内核消息(通常在 dmesg 输出中找到)也可以从journal中检索。
要仅显示这些消息,我们可以在命令中添加 -k 或 --dmesg 标志:
journalctl -k
默认情况下,这将显示当前boot的内核消息。也可以使用先前讨论过的boot选择标志指定替代boot。例如,要获取五次启动之前的消息,您可以输入:
journalctl -k -b -5
按消息优先级
系统管理员经常感兴趣的过滤器之一是消息优先级。 虽然以非常详细的级别记录信息通常很有用,但在实际消化可用信息时,低优先级日志可能会分散注意力和令人困惑。
可以使用journalctl 通过使用-p 选项仅显示指定优先级或更高优先级的邮件。 这将过滤掉优先级较低的消息。
例如,要仅显示错误级别或更高级别记录的条目,您可以键入:
journalctl -p err -b
这将显示所有标记为 error, critical, alert, 或者emergency的消息。 journal实现标准的系统日志消息级别。 可以使用优先级名称或其相应的数值。 按照优先级从高到低的顺序,这些是:
- 0: emerg
- 1: alert
- 2: crit
- 3: err
- 4: warning
- 5: notice
- 6: info
- 7: debug
上述数字或名称可以与 -p 选项互换使用。 选择优先级将显示标记为指定级别及其之上的消息
修改Journal输出格式
上面演示了通过过滤输出我们想要的日志条目。 不过,还有其他方法可以修改输出。 我们可以调整 Journalctl 显示以满足不同的需求。
截断或扩展输出
我们可以通过告诉journalctl缩小或扩展输出来调整journalctl显示数据的方式。
默认情况下,journalctl 将在分页器中显示整个条目,从而使条目逐渐显示到屏幕右侧。 按向右箭头键可以访问此信息。
如果您希望输出被截断,在删除信息的地方插入省略号,您可以使用 --no-full 选项:
journalctl --no-full
Output
. . .
Output:
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
这可以立即通过管道传输到处理实用工具或重定向到磁盘上的文件,具体取决于需要。
输出格式
如果正在处理日志条目,如上所述,假如数据采用更易于使用的格式,能帮助我们更轻松地解析数据。 journal可以根据需要以多种格式显示。可以使用 -o 选项指定输出格式执行此操作。
例如,通过输入以下内容以 JSON 格式输出日记条目:
journalctl -b -u nginx -o json
Output:
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:
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:默认的系统日志样式输出
- short-iso:默认格式,增加了显示 ISO 8601 wallclock时间戳的功能。
- short-monotonic:具有monotonic时间戳的默认格式。
- short-precise:具有微秒精度的默认格式。
- verbose:显示条目中可用的每个日志字段,包括通常在内部隐藏的字段
这些选项允许以最适合您当前需求的任何格式显示journal条目。
主动进程监控
journalctl命令模仿了管理员使用tail来监视活动或最近活动的方式。这种功能内置在journalctl中,使我们能够访问这些功能,而无需将其管道传输到另一个工具。
显示最近的日志
要显示一定数量的记录,可以使用 -n 选项,其作用与 tail -n 完全相同。
默认情况下,它将显示最近的 10 个条目:
journalctl -n
您可以使用 -n 后面指定想要查看的条目数:
journalctl -n 20
Follow日志
主动跟踪正在写入的日志,可以使用 -f 标志。 同样,如果您有使用 tail -f 的经验,这正如所期望的那样:
journalctl -f
退出按 CTRL+C。
Journal维护
有时候可能想知道存储到目前为止我们所看到的所有数据的成本。 此外,也可能会对清理一些较旧的日志并释放空间感到有性趣。
查找当前磁盘空间使用量
journalctl --disk-usage
Output
Archived and active journals take up 8.0M in the file system.
删除旧的日志
如果想缩小日志,可以通过两种不同的方式来实现(systemd 版本 218 及更高版本提供)。
如果使用 --vacuum-size 选项,您可以通过指定大小来缩小日志。 这将删除旧条目,直到磁盘上占用的总日志空间达到请求的大小:
sudo journalctl --vacuum-size=1G
缩小日志的另一种方法是使用 --vacuum-time 选项提供截止时间。超过该时间的任何条目都将被删除。这允许保留在特定时间之后创建的条目。
例如,要保留去年的条目,可以输入:
sudo journalctl --vacuum-time=1years
限制日志扩展
可以配置服务器以限制日志占用的空间。这可以通过编辑 /etc/systemd/journald.conf 文件来完成。
以下项目可用于限制日志增长:
- SystemMaxUse=:指定journal在持久存储中可使用的最大磁盘空间。
- SystemKeepFree=: 指定将日志条目添加到持久存储时,日志应保留的空闲空间量。
- SystemMaxFileSize=:控制单个日志文件在rotation(轮换)之前在持久存储中可以增长到多大。
- RuntimeMaxUse=:指定易失性存储(/run 文件系统内)中可使用的最大磁盘空间。
- RuntimeKeepFree=: 指定在将数据写入易失性存储(位于/run文件系统内)时,应留出用于其他用途的空间量。
- RuntimeMaxFileSize=: 指定在将日志文件进行轮换之前,单个日志文件可以占用的易失性存储空间量(位于/run文件系统内)。
通过设置这些值,可以控制 journald 如何消耗和保留服务器上的空间。SystemMaxFileSize 和 RuntimeMaxFileSize 将会使得归档文件的大小与限制值一致。在vacuum操作后解释文件计数时,记住这一点很重要