Linux提供了一个强大的日志系统,它可以跟踪和记录系统的各种活动。在这个系统中,journalctl
是一个非常重要的工具,用于查询和操作由systemd进程管理的日志。
本文将深入探讨journalctl
命令,介绍其基本使用、高级选项及示例等内容。
1. Journalctl简介
Systemd是Linux发行版的初始化系统,负责启动系统后的所有服务,并监视它们在系统运行期间的状态。Journal是Systemd的一部分,主要负责收集和存储日志数据。
journalctl
是Journal的主要接口,提供丰富的功能来检索和显示日志条目。它能从磁盘上的二进制文件或者其他传输目标(如syslog)获取日志。
2. Journalctl基础使用
下面是一些基本的journalctl
命令。
查看所有日志: (分页输出)
journalctl
或者: (不分页输出)
journalctl --no-pager
按时间倒序查看所有日志:
journalctl -r
查看最新的10条日志:
journalctl -n 10
实时查看新添加的日志条目:
journalctl -f
3. 过滤日志条目
journalctl
提供了多种方式来过滤和查找特定的日志条目。
以下是一些过滤日志的例子:
根据服务名称过滤:
journalctl -u nginx
根据进程ID过滤:
journalctl _PID=2001
根据优先级过滤(0-7,0表示最重要):
journalctl -p err -b
4. 时间戳和日志轮转
对于大型系统,日志文件可能会非常大。为了解决这个问题,journalctl
提供了日志轮转和时间戳功能。
日志轮转是一个过程,其中旧的日志条目被删除以释放空间给新的日志条目。默认情况下,Journal将根据配置在/var/log/journal中保存日志文件,并在磁盘空间不足时执行日志轮转。
时间戳允许你查找特定时间范围内的日志条目。例如:
journalctl --since="2021-07-01" --until="2021-07-31 03:00"
5. 高级应用
尽管journalctl
提供了丰富的功能,但在某些情况下,你可能需要更高级的工具或技术。例如,你可能需要将日志发送到远程服务器,或者在多个系统上集中处理日志。
对于这些需求,你可以考虑使用像Logstash、Graylog或Fluentd这样的日志聚合工具,它们可以与journalctl
结合使用,提供更强大的功能。
6. journalctl --help
指令文档
英文
journalctl [OPTIONS...] [MATCHES...]Query the journal.Options:--system Show the system journal--user Show the user journal for the current user-M --machine=CONTAINER Operate on local container-S --since=DATE Show entries not older than the specified date-U --until=DATE Show entries not newer than the specified date-c --cursor=CURSOR Show entries starting at the specified cursor--after-cursor=CURSOR Show entries after the specified cursor--show-cursor Print the cursor after all the entries--cursor-file=FILE Show entries after cursor in FILE and update FILE-b --boot[=ID] Show current boot or the specified boot--list-boots Show terse information about recorded boots-k --dmesg Show kernel message log from the current boot-u --unit=UNIT Show logs from the specified unit--user-unit=UNIT Show logs from the specified user unit-t --identifier=STRING Show entries with the specified syslog identifier-p --priority=RANGE Show entries with the specified priority--facility=FACILITY... Show entries with the specified facilities-g --grep=PATTERN Show entries with MESSAGE matching PATTERN--case-sensitive[=BOOL] Force case sensitive or insenstive matching-e --pager-end Immediately jump to the end in the pager-f --follow Follow the journal-n --lines[=INTEGER] Number of journal entries to show--no-tail Show all lines, even in follow mode-r --reverse Show the newest entries first-o --output=STRING Change journal output mode (short, short-precise,short-iso, short-iso-precise, short-full,short-monotonic, short-unix, verbose, export,json, json-pretty, json-sse, json-seq, cat,with-unit)--output-fields=LIST Select fields to print in verbose/export/json modes--utc Express time in Coordinated Universal Time (UTC)-x --catalog Add message explanations where available--no-full Ellipsize fields-a --all Show all fields, including long and unprintable-q --quiet Do not show info messages and privilege warning--no-pager Do not pipe output into a pager--no-hostname Suppress output of hostname field-m --merge Show entries from all available journals-D --directory=PATH Show journal files from directory--file=PATH Show journal file--root=ROOT Operate on files below a root directory--namespace=NAMESPACE Show journal data from specified namespace--interval=TIME Time interval for changing the FSS sealing key--verify-key=KEY Specify FSS verification key--force Override of the FSS key pair with --setup-keysCommands:-h --help Show this help text--version Show package version-N --fields List all field names currently used-F --field=FIELD List all values that a specified field takes--disk-usage Show total disk usage of all journal files--vacuum-size=BYTES Reduce disk usage below specified size--vacuum-files=INT Leave only the specified number of journal files--vacuum-time=TIME Remove journal files older than specified time--verify Verify journal file consistency--sync Synchronize unwritten journal messages to disk--relinquish-var Stop logging to disk, log to temporary file system--smart-relinquish-var Similar, but NOP if log directory is on root mount--flush Flush all journal data from /run into /var--rotate Request immediate rotation of the journal files--header Show journal header information--list-catalog Show all message IDs in the catalog--dump-catalog Show entries in the message catalog--update-catalog Update the message catalog database--setup-keys Generate a new FSS key pairSee the journalctl(1) man page for details.
中文
journalctl [选项...] [匹配项...]查询日志。选项:--system 显示系统日志--user 显示当前用户的用户日志-M --machine=CONTAINER 对本地容器进行操作-S --since=DATE 显示不早于指定日期的条目-U --until=DATE 显示不晚于指定日期的条目-c --cursor=CURSOR 从指定的游标开始显示条目--after-cursor=CURSOR 显示指定游标之后的条目--show-cursor 在所有条目后打印游标--cursor-file=FILE 显示文件中游标后的条目并更新文件-b --boot[=ID] 显示当前启动或指定的启动--list-boots 显示有关记录启动的简洁信息-k --dmesg 显示当前启动的内核消息日志-u --unit=UNIT 显示指定单元的日志--user-unit=UNIT 显示指定用户单元的日志-t --identifier=STRING 显示具有指定syslog标识符的条目-p --priority=RANGE 显示具有指定优先级的条目--facility=FACILITY... 显示具有指定设施的条目-g --grep=PATTERN 显示与PATTERN匹配的MESSAGE的条目--case-sensitive[=BOOL] 强制进行大小写敏感或不敏感的匹配-e --pager-end 在分页器中立即跳到末尾-f --follow 跟踪日志-n --lines[=INTEGER] 要显示的日志条目数量--no-tail 即使在跟踪模式下也显示所有行-r --reverse 先显示最新的条目-o --output=STRING 改变日志输出模式 (short, short-precise,short-iso, short-iso-precise, short-full,short-monotonic, short-unix, verbose, export,json, json-pretty, json-sse, json-seq, cat,with-unit)--output-fields=LIST 在verbose/export/json模式下选择要打印的字段--utc 以协调世界时(UTC)表示时间-x --catalog 在可用的地方添加消息解释--no-full 缩略字段-a --all 显示所有字段,包括长和不可打印的-q --quiet 不显示信息消息和权限警告--no-pager 不将输出管道输出到分页器--no-hostname 抑制主机名字段的输出-m --merge 显示所有可用日志的条目-D --directory=PATH 显示来自目录的日志文件--file=PATH 显示日志文件--root=ROOT 在根目录下操作文件--namespace=NAMESPACE 显示指定命名空间的日志数据--interval=TIME 更改FSS密封键的时间间隔--verify-key=KEY 指定FSS验证键--force 使用--setup-keys覆盖FSS密钥对
命令:-h --help 显示此帮助文本--version 显示包版本-N --fields 列出当前使用的所有字段名称-F --field=FIELD 列出指定字段采取的所有值--disk-usage 显示所有日志文件的总磁盘使用量--vacuum-size=BYTES 将磁盘使用量减少到指定大小以下--vacuum-files=INT 只保留指定数量的日志文件--vacuum-time=TIME 删除早于指定时间的日志文件--verify 验证日志文件的一致性--sync 将未写入的日志消息同步到磁盘--relinquish-var 停止记录到磁盘,记录到临时文件系统--smart-relinquish-var 类似,但如果日志目录在根挂载上,则无操作--flush 将所有日志数据从 /run 刷新到 /var--rotate 请求立即旋转日志文件--header 显示日志头信息--list-catalog 在目录中显示所有消息ID--dump-catalog 显示消息目录中的条目--update-catalog 更新消息目录数据库--setup-keys 生成新的FSS密钥对有关详细信息,请参阅 journalctl(1) 手册页。
7. 补充
清空所有日志
清除所有的系统日志,可使用 journalctl
的 --vacuum-time
或 --vacuum-size
选项。
-
清除所有日志:
sudo journalctl --vacuum-time=1s
这将会删除所有时间戳早于现在的日志条目,基本上等同于清空所有日志。
journalctl --vacuum-time
命令通常接受一个相对时间值,如 “1year”, “2months”, “3weeks”, “4days”, “1s” 等。这个命令会删除所有在指定时间长度之前的日志。
2.清除超过特定大小的日志:
journalctl --vacuum-size=1
这将删除所有日志,直到系统日志的总大小降到1(单位为BYTE)。
可以使用journalctl --disk-usage
查看日志占用空间大小。
3.如果以上两个都没有效果,可以采用暴力方式直接删除日志文件。
这将删除所有日志,直到系统日志的总大小降到1(单位为BYTE)。
可以使用
journalctl --disk-usage
查看日志占用空间大小。如果以上两个都没有效果,可以采用暴力方式直接删除日志文件。
-
暴力删除有风险,使用需谨慎。
过滤掉某个服务日志
比如systemd服务日志太多太烦杂,可以过滤掉它:
journalctl | grep -v systemd
注意事项
-
journal日志不会将程序输出的空行显示,日志会被压缩得满满当当。
-
journal日志不会自动持久化,重启系统后,历史日志将被清除。可参考journal日志持久化配置。
总结
journalctl
是一个强大而灵活的工具,可以帮助你管理和查询Linux系统的日志。通过学习和理解journalctl
的各种功能和选项,你将能够更有效地管理你的系统,并在出现问题时快速找到原因。
二、Systemd Journalctl日志持久化存储
在此文章中,我们将详细探讨systemd journalctl日志的持久化配置。本文将首先简单介绍systemd和journalctl,然后深入探讨如何配置和使用journalctl来实现日志的持久化。
1. systemd和journalctl概述
Systemd是Linux系统的一个初始化系统和服务管理器,它负责启动系统后的所有服务。其中,Journal是systemd的一个组成部分,用于收集和存储系统日志。
Journalctl是一种工具,可以方便地从systemd的journal中检索日志信息。默认情况下,这些日志数据是易失的,也就是说,每次重启系统后,它们都会被清除。
# 查看所有日志条目
journalctl
2. journalctl日志持久化的重要性
日志持久化的主要优点在于,它可以帮助我们保存重启后的日志信息,以便在需要时进行查阅和分析。这对于故障排除、安全审计以及性能监测等场景非常有价值。
3. 配置journalctl日志持久化
为了使journalctl的日志持久化,我们需要创建一个名为/var/log/journal
的目录,并设置适当的权限。
# 创建日志目录
mkdir -p /var/log/journal# 设置权限
systemd-tmpfiles --create --prefix /var/log/journal
另外,我们还需要在/etc/systemd/journald.conf
文件中修改或添加以下配置:
[Journal]
Storage=persistent
然后,重新启动systemd-journald
服务来应用新的配置。
# 重新启动服务
systemctl restart systemd-journald
4. 使用journalctl进行日志查询
配置好日志持久化后,我们可以使用各种查询选项来过滤和查找日志信息。例如:
# 查看指定时间段的日志
journalctl --since "2022-01-01" --until "2022-01-31"
# 查看指定服务的日志
journalctl -u nginx.service
5. 管理journalctl日志文件大小
虽然日志持久化很有用,但如果不加以管理,日志文件可能会占用大量磁盘空间。我们可以通过配置/etc/systemd/journald.conf
文件来限制日志文件的大小。
[Journal]
# 日志文件最大占用空间
SystemMaxUse=500M
(注意这里SystemMaxUse是限制所有日志总占空间大小,SystemMaxFileSize是限制单个轮转日志文件的大小;RuntimeMaxUse用于限制在 /run/log/journal/ 中的日志数据占用的空间大小,这是管理非持久性存储的日志容量大小,已经设置了默认值,我们不用管)
配置后同样要重新启动服务:
# 重新启动服务
systemctl restart systemd-journald
6. 查看日志文件,验证持久化功能
ll /var/log/journal/
由于journal的二进制格式,不能直接使用文本编辑器(如vi或nano)打开和阅读这些文件,还得使用journalctl命令进行查看。
我们来验证一下是否成功实现日志持久化保存。我用journalctl -u ky_ai_ip_change.service
查看我修改ip服务的日志。
然后我把SystemMaxUse改成1M重复上面步骤再来一遍:
重启后查看日志:
Warning: journal has been rotated since unit was started, output may be incomplete.
-- Logs begin at Mon 2023-08-21 23:25:54 CST, end at Mon 2023-08-21 23:33:19 CST. -- -- No entries --
貌似是提示我说,我的修改ip服务的日志因为被轮转(rotated),已经转没了。
是因为我们设置的日志总占空间,太小辣!才1M,会很容易被别的系统服务日志冲没的。
还是改回500M。
7. 故障排除与最佳实践
对于任何系统管理员来说,了解如何处理常见问题和遵循最佳实践都是至关重要的。在使用journalctl时,我们应始终记住以下几点:
-
定期检查和清理日志文件
-
使用合适的查询选项来精确查找日志
-
及时更新并备份
/etc/systemd/journald.conf
文件
8. 结论
总的来说,journalctl日志持久化配置是一个强大而灵活的工具,可以帮助我们更好地管理和审计系统日志。通过正确的配置和使用,我们可以充分利用这个工具来提高我们的运维效率。
附录
/etc/systemd/journald.conf
原始文件及配置项解析(ubuntu20.04)
-
原始文件
cat /etc/systemd/journald.conf
# This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # # Entries in this file show the compile time defaults. # You can change settings by editing this file. # Defaults can be restored by simply deleting this file. # # See journald.conf(5) for details. [Journal] #Storage=auto #Compress=yes #Seal=yes #SplitMode=uid #SyncIntervalSec=5m #RateLimitIntervalSec=30s #RateLimitBurst=10000 #SystemMaxUse= #SystemKeepFree= #SystemMaxFileSize= #SystemMaxFiles=100 #RuntimeMaxUse= #RuntimeKeepFree= #RuntimeMaxFileSize= #RuntimeMaxFiles=100 #MaxRetentionSec= #MaxFileSec=1month #ForwardToSyslog=yes #ForwardToKMsg=no #ForwardToConsole=no #ForwardToWall=yes #TTYPath=/dev/console #MaxLevelStore=debug #MaxLevelSyslog=debug #MaxLevelKMsg=notice #MaxLevelConsole=info #MaxLevelWall=emerg #LineMax=48K #ReadKMsg=yes
-
解析
# 这个文件是 systemd 的一部分。 # # systemd 是自由软件;你可以在 GNU 较小通用公共许可证的条款下重新发布和/或修改它 # 该许可证由自由软件基金会发布;可以选择许可证的版本 2.1 或者 # (如果你愿意)任何后续版本。 # # 此文件中的条目显示了编译时的默认设置。 # 你可以通过编辑此文件来更改设置。 # 只需删除此文件,即可恢复默认设置。 # # 详细信息请参阅 journald.conf(5)。
(就是说想要恢复默认设置,只需删除此文件即可。)
-
Storage
:定义日志数据应存储在何处,例如 ‘volatile’(临时文件系统)或 ‘persistent’(磁盘)。 -
Compress
:定义是否应压缩存储在日志中的数据。 -
Seal
:确定是否使用Forward Secure Sealing (FSS) 保护日志条目免受篡改。 -
SplitMode
:定义如何拆分日志文件,例如根据用户ID或登录会话。 -
SyncIntervalSec
:定义系统何时将日志数据从内存同步到磁盘。 -
RateLimitIntervalSec
和RateLimitBurst
:定义日志消息的频率限制,即在给定的时间间隔内可以接受的最大消息数。 -
SystemMaxUse
,SystemKeepFree
,SystemMaxFileSize
,SystemMaxFiles
:定义系统日志所能使用的磁盘空间,以及应保留多少空闲空间。 -
RuntimeMaxUse
,RuntimeKeepFree
,RuntimeMaxFileSize
,RuntimeMaxFiles
:定义运行时日志的大小和文件数量限制。 -
MaxRetentionSec
:定义系统应保留旧日志条目的最长时间。 -
MaxFileSec
:定义单个日志文件的最大生存时间。 -
ForwardToSyslog
,ForwardToKMsg
,ForwardToConsole
,ForwardToWall
:定义是否将日志消息转发到syslog、内核消息日志、控制台或所有登录用户。 -
TTYPath
:定义写入终端消息的TTY设备路径。 -
MaxLevelStore
,MaxLevelSyslog
,MaxLevelKMsg
,MaxLevelConsole
,MaxLevelWall
:定义各种日志目标的最大日志级别。 -
LineMax
:定义日志条目的最大行长度。 -
ReadKMsg
:定义是否从内核消息日志读取并添加到系统日志。
配置项的具体配置方法可参考官方文档:https://www.freedesktop.org/software/systemd/man/journald.conf.html
-
20240228 openEuler20.03 journald.conf 原始文件
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See journald.conf(5) for details.
[Journal]
#Storage=auto
#Compress=yes
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitIntervalSec=30s
#RateLimitBurst=10000
#SystemMaxUse=
#SystemKeepFree=
#SystemMaxFileSize=
#SystemMaxFiles=100
#RuntimeMaxUse=
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#RuntimeMaxFiles=100
#MaxRetentionSec=
#MaxFileSec=1month
#ForwardToSyslog=no
#ForwardToKMsg=no
#ForwardToConsole=no
#ForwardToWall=yes
#TTYPath=/dev/console
#MaxLevelStore=debug
#MaxLevelSyslog=debug
#MaxLevelKMsg=notice
#MaxLevelConsole=info
#MaxLevelWall=emerg
#LineMax=48K
#ReadKMsg=yes
journal与logrotate日志管理工具的区别
systemd journal
和 logrotate
都是用于管理日志文件的工具,但它们的工作方式和特性有一些区别。
-
日志格式:
-
systemd journal
存储的日志是二进制格式,这使得它可以提供更丰富的查询功能,例如按服务、优先级或时间范围过滤日志。 -
logrotate
处理的通常是文本格式的日志,这种日志对人类来说更易读,但对机器来说处理起来可能就不那么方便了。
-
-
日志切割:
-
systemd journal
会自动管理日志文件的大小,当日志达到一定大小时,它会自动删除旧的日志来释放空间。你可以通过配置选项(如SystemMaxUse
和RuntimeMaxUse
)来控制日志文件的最大大小。 -
logrotate
是通过定期运行(通常是每天)来进行日志切割的,它可以根据日志文件的大小、文件的年龄或者日期来决定何时进行切割。切割后的日志文件可以选择压缩以节省空间。
-
-
使用场景:
-
systemd journal
主要用于收集系统和服务的日志,它是 systemd 的一个组成部分,所以在使用 systemd 的系统上,无法避免使用 journal。 -
logrotate
更多的是用于应用程序的日志管理,尤其是那些还没有采用 systemd 的系统或者那些产生大量日志的应用程序。
-
两者都有各自的优点,也可以结合使用,比如让 systemd journal 收集日志,然后使用 logrotate 来管理 journal 导出的文本格式日志。
20231017 发现日志达到设置上限了,日志并未自动删除,新的日志也没有储存。一时半会找不到解决办法,通过设置MaxRetentionSec=7day
自动清理7天前的日志来临时解决
今天调试ip修改服务,发现重启后新的日志并未正常保存,重启前日志倒是可以看到的
查看systemd-journald服务状态:
systemctl status systemd-journald
root@nvidia:/ky/boot/journal_persistence# systemctl status systemd-journald
● systemd-journald.service - Journal ServiceLoaded: loaded (/lib/systemd/system/systemd-journald.service; static; vendor preset: enabled)Active: active (running) since Tue 2023-10-17 18:07:39 CST; 2h 36min ago
TriggeredBy: ● systemd-journald-audit.socket● systemd-journald-dev-log.socket● systemd-journald.socketDocs: man:systemd-journald.service(8)man:journald.conf(5)Main PID: 6899 (systemd-journal)Status: "Processing requests..."Tasks: 1 (limit: 8126)Memory: 1.8MCGroup: /system.slice/systemd-journald.service└─6899 /lib/systemd/systemd-journald
Oct 17 18:07:39 nvidia systemd-journald[6899]: Journal started
Oct 17 18:07:39
发现上面有一句:(/var/log/journal/dbfef1aa0b064bcf9d30ec3ad0886edb) is 514.5M, max 500.0M, 0B free.
表明可能自动清理旧日志功能并未正常执行。
用下面命令查看journal日志占用大小,发现已经超了。:
journalctl --disk-usage
使用以下命令手动删除超出限制的旧日志,但是并未发现有任何变化:
journalctl --vacuum-size=500M
使用以下命令手动删除某个时间外的旧日志,发现删除了一部分日志:
journalctl --vacuum-time=1d
配置删除指定时间前的旧日志
一时半会找不到什么解决办法,它超过容量限制居然不自动删除,为了临时解决这个问题,我可能要设置一个自动删除指定日期前旧日志的选项才行。
将以下选项加入到/etc/systemd/journald.conf
中:
MaxRetentionSec=7day
然后重启systemd-journald
服务:
systemctl restart systemd-journald
虽然空间已经清空了,但是重启后,日志还是消失了(尝试设置SyncIntervalSec=1s
,每隔1秒从内存将日志同步到硬盘)
现在空间是足够的。
分析可能是重启时journal没有把日志从内存同步到硬盘中去,因为默认同步时间几分钟一次的。
但是我们可以在/etc/systemd/journald.conf
设置SyncIntervalSec=1s
参数,这个参数将1秒钟同步一次,我试试是否可行
设置完后重启服务:
systemctl restart systemd-journald
分析日志文件:
ll /var/log/journal/dbfef1aa0b064bcf9d30ec3ad0886edb/
存在日志跳跃,真的无语。。。
20231018 发现日志无法正常持久化了,重启后不保留之前的日志,后来不知怎么又给弄好了。。。
我也不知道做了什么操作,发现又好了。
大概是以下操作之一:
-
清空日志:
journalctl --vacuum-time=1s journalctl --vacuum-size=1
-
重新创建日志目录(如果存在不重新创建)并正确配置权限:
sudo mkdir -p /var/log/journal sudo systemd-tmpfiles --create --prefix /var/log/journal sudo systemctl restart systemd-journald