文章目录
写在前面
本文主要是详细介绍了systemd-journald.service,主要翻译自英文原文文档(develop版本,截止到文章记录,最新版本是systemd 255)。linux系统服务管理器systemd在日志journal部分的systemd-journald.service。
主要是以下页面的翻译:
https://www.freedesktop.org/software/systemd/man/latest/systemd-journald.service.html#
其他相关文档请参考:systemd专栏
概述
systemd-journald.service
systemd-journald.socket
systemd-journald-dev-log.socket
systemd-journald-audit.socket
systemd-journald@.service
systemd-journald@.socket
systemd-journald-varlink@.socket
/usr/lib/systemd/systemd-journald
描述
systemd-journald
是收集和存储日志记录数据的系统服务。
它根据从各种来源收到的日志记录信息创建和维护结构化的索引日志:
Kernel log messages, via kmsg
内核日志消息,通过kmsg
Simple system log messages, via the libc syslog(3) call
简单的系统日志消息,通过libc syslog(3)
调用Structured system log messages via the native Journal API, see sd_journal_print(3) and Native Journal Protocol
通过本机日志 API 的结构化系统日志消息,参见sd_journal_print(3
) 和本机日志协议Standard output and standard error of service units. For further details see below.
服务单元的标准输出和标准误差。有关详细信息,请参见下文。Audit records, originating from the kernel audit subsystem
源自内核审计子系统的审计记录
守护程序将以安全且不可伪造的方式隐式收集每个日志消息的大量元数据字段。参见 systemd.journal-fields(7) 来获取有关所收集元数据的更多信息。
日志收集的日志数据主要基于文本,但必要时也可以包括二进制数据。
构成日志中存储的日志记录的单个字段的大小可能高达2⁶⁴-1
字节。
日志服务将日志数据永久存储在 /var/log/journal
下,或者以易失性的方式存储在 /run/log/journal/
下(在后一种情况下,日志数据在重新启动时会丢失)。
默认情况下,如果启动期间 /var/log/journal/
存在,则日志数据将永久存储,否则隐式回退到易失性存储。使用journald.conf(5)
中的Storage=
配置日志数据的放置位置,与/var/log/journal/
是否存在无关。
请注意,
journald
最初将使用易失性存储,直到调用journalctl --flush
(或向journald
发送SIGUSR1
)将导致其切换到持久日志记录(在上述条件下)。这是通过“systemd-journal-flush.service”
在启动时自动完成的。
在 /var/log/journal/
尚不存在但需要持久日志记录(并且使用默认的 Journald.conf
)的系统上,创建目录就足够了,并确保它具有正确的访问模式和所有权:
mkdir -p /var/log/journal
systemd-tmpfiles --create --prefix /var/log/journal
流日志记录(Stream logging)
默认情况下,systemd
服务管理器使用连接到日志的标准输出和标准错误来调用所有服务进程。
此行为可以通过 StandardOutput=
或者StandardError=
单元文件设置进行更改,有关详细信息,请参阅 systemd.exec(5)
。日志将以这种方式接收到的日志字节流转换为单独的日志记录,并在换行符(“\n”,ASCII 10)和 NUL 字节
处分割流。
如果 systemd-journald.service
停止,则与所有服务关联的流连接将终止。服务进一步写入这些流将导致 EPIPE
错误。
为了在这种情况下做出适当的反应,建议记录到标准输出/错误的程序忽略此类错误。
如果 SIGPIPE UNIX 信号处理程序
未被阻止或关闭,此类写入尝试也将导致生成此类进程信号,请参阅 signal(7)
。
为了缓解此问题,systemd 服务管理器
默 认显式关闭所有调用进程的 SIGPIPE 信号
(可以通过IgnoreSIGPIPE=
选项单独更改每个单元的 SIGPIPE
信号,有关详细信息,请参阅 systemd.exec(5)
)。
标准输出/标准错误流终止后,它们可能无法恢复,直到与其关联的服务重新启动为止。
请注意,在正常操作期间,
systemd-journald.service
在服务管理器中存储这些流的文件描述符的副本。如果使用systemctl restart
或等效操作而不是一对单独的systemctl stop
和systemctl start
命令(或等效操作)重新启动systemd-journald.service
,则这些流连接不会终止并在重新启动后继续存在。因此,重新启动systemd-journald.service
是安全的,但不建议停止它。
请注意,通过此类标准输出/错误流传输的记录的日志记录元数据反映了最初为其创建流的对等方的元数据。如果将流连接传递到其他进程(例如从主服务进程分叉出来的其他子进程),则日志记录将不会反映其元数据,但将继续描述原始进程。这与上面列出的其他日志记录传输不同,后者本质上是基于记录的,并且元数据始终与单个记录相关联。
目前,将接受的 systemd-journald
并行日志流数量限制为 4096
。当达到此限制时,可能会建立进一步的日志流,但将从一开始就接收 EPIPE
。
日志命名空间(Journal Namespaces)
日志“命名空间”既是一种机制,用于从逻辑上将包含一个或多个服务的项目的日志流与系统的其余部分隔离开来,也是一种用于提高性能的机制。
多个日志命名空间可以同时存在,每个命名空间都定义自己的独立日志流,由自己的 systemd-journald
实例管理。命名空间在数据存储和IPC 接口
中都是相互独立的。
默认情况下,仅存在一个“默认”命名空间,由 systemd-journald.service
(及其关联的套接字单元)管理。
通过启动 systemd-journald@.service
服务模板的实例来创建其他命名空间。
实例名称是命名空间标识符,它是用于引用日志命名空间的短字符串。
可以通过 LogNamespace=
单元文件设置将服务单元分配给特定的日志命名空间,详见 systemd.exec(5
)。
journalctl(1)
--namespace=
的开关可用于查看特定命名空间的日志流。
如果未使用该开关,则会显示默认命名空间的日志流,例如,来自其他命名空间的log数据不可见。
与特定日志命名空间关联的服务可以通过 syslog
(日志的本机日志记录协议)和 stdout/stderr
进行日志记录;所有三个传输的日志记录都与命名空间相关联。
默认情况下,只有默认命名空间会收集内核和审核日志消息。
默认命名空间的systemd-journald
实例是通过 /etc/systemd/journald.conf
(见下文)配置的,而其他实例是通过 /etc/systemd/journald@NAMESPACE.conf
配置的。
默认命名空间的日志数据位于 /var/log/journal/MACHINE_ID
(见下文),而其他命名空间的数据位于 /var/log/journal/MACHINE_ID.NAMESPACE
信号 Signals
SIGUSR1
请求将日志 /run/
数据刷新到 /var/
,以使其持久化(如果启用此功能)。
这必须在挂载 /var/
后使用,否则无论配置如何,来自 /run/
的日志数据都不会刷新到 /var/
。使用journalctl --flush
命令请求刷新日志文件,并等待操作完成。详细信息请参见journalctl(1)
。
SIGUSR2
请求立即轮换日志文件。使用 journalctl --rotate
命令请求日志文件轮换,并等待操作完成。
SIGRTMIN+1
请求将所有未写入的日志数据写入磁盘。使用 journalctl --sync
命令触发日志同步,并等待操作完成。
内核命令行 Kernel Command Line
在内核命令行上可以覆盖一些 journald.conf
配置参数:
systemd.journald.forward_to_syslog=
启用/禁用将收集的日志消息转发到 syslog
systemd.journald.forward_to_kmsg=
启用/禁用将收集的日志消息转发到 内核日志缓冲区
systemd.journald.forward_to_console=
启用/禁用将收集的日志消息转发到 系统控制台
systemd.journald.forward_to_wall=
启用/禁用将收集的日志消息转发到 wall
。
访问控制 Access Control
默认情况下,日志文件由“ systemd-journal ”
系统组拥有和读取,但不可写。
因此,将用户添加到此组使他们能够读取日志文件。
默认情况下,每个用户(超出系统用户的UID
、动态服务用户
和nobody 用户
)将在 /var/log/journal/
获取他们自己的日志文件集合。但是,这些日志文件将不归用户所有,以避免用户可以直接写入它们。相反,文件系统 ACLs
用于确保用户仅获得读取访问权限。
其他用户和组可以通过文件系统访问控制列表 (ACL) 被授予对日志文件的访问权限。发行版和管理员可以选择使用如下命令授予对 “ wheel ” 和 “ adm ” 系统组
的所有成员的读取访问权限:
setfacl -Rnm g:wheel:rx,d:g:wheel:rx,g:adm:rx,d:g:adm:rx /var/log/journal/
请注意,此命令将更新现有日志文件和未来在
/var/log/journal/
目录中创建的日志文件的ACL
。
文件 Files
/etc/systemd/journald.conf
配置 systemd-journald
行为
/run/log/journal/machine-id/*.journal
/run/log/journal/machine-id/*.journal~
/var/log/journal/machine-id/*.journal
/var/log/journal/machine-id/*.journal~
systemd-journald
将记录写入 /run/log/journal/machine-id/
或 /var/log/journal/machine-id/
中带有“.journal”
后缀的文件。如果守护进程不正常停止,或者发现文件已损坏,则会使用“.journal~”
后缀重命名它们,并且 systemd-journald
开始写入新文件。当 /var/log/journal
不可用或在journald.conf(5)
配置文件中设置 Storage=volatile
时,使用 /run/
。
当停止写入日志文件时 systemd-journald
,它将重命名为“ original-name@suffix.journal ”
(或“ original-name@suffix.journal~ ”
)。此类文件已“存档”,不会再写入任何内容。
通常,读取或复制任何日志文件(活动或存档)都是安全的。
journalctl(1)
和 sd-journal(3)
库中的函数应该能够读取所有已完全写入的记录。
systemd-journald
将自动删除最早的存档日志文件以限制磁盘使用。参见 SystemMaxUse= journald.conf(5)
中的相关设置。
/dev/kmsg, /dev/log, /run/systemd/journal/dev-log, /run/systemd/journal/socket, /run/systemd/journal/stdout
/dev/kmsg
/dev/log
/run/systemd/journal/dev-log
/run/systemd/journal/socket
/run/systemd/journal/stdout
systemd-journald
将侦听并在文件系统中可见的套接字和其他文件节点路径。除此之外,systemd-journald
还可以使用 netlink(7)
监听审核事件, 这取决于是否启用了 “ systemd-journald-audit.socket ”
。