了解 Linux 中的日志记录

了解 Linux 中的日志记录

据我了解,Linux内核日志记录到/proc/kmsg文件(主要是与硬件相关的消息)和/dev/log套接字?还有其他地方吗?其他应用程序是否也可以向/proc/kmsg或发送消息/dev/log?最后但并非最不重要的一点是,我是否正确,它是 syslog 守护进程(系统日志,系统日志)它检查来自这两个地方的消息,然后将这些消息分发到各种文件,例如/var/log/messages甚至/var/log/kern.log中央系统日志服务器?

答案1

简单来说,它或多或少是这样的:

内核将消息(使用该printk()函数)记录到内核空间中的环形缓冲区。这些消息可以通过两种方式提供给用户空间应用程序:通过文件/proc/kmsg(前提是/proc已安装)和通过sys_syslog系统调用。

有两个主要的应用程序可以读取(并且在某种程度上可以控制)内核的环形缓冲区:dmesg(1)klogd(8)。前者旨在由用户按需运行,以打印环形缓冲区的内容。后者是一个守护进程,它从/proc/kmsg(或调用sys_syslog,如果/proc未安装)读取消息并将它们发送到syslogd(8), 或 控制台。这涵盖了内核方面。

在用户空间中,有syslogd(8).这是一个守护进程,它监听多个 UNIX 域套接字(主要是 UNIX 域套接字/dev/log,但也可以配置其他套接字),并且可以选择监听 UDP 端口 514 来获取消息。它还接收来自klogd(8)syslogd(8)不关心/proc/kmsg)的消息。然后,它将这些消息写入 中的某些文件/log,或命名管道,或将它们发送到某些远程主机(通过协议syslog,在 UDP 端口 514 上),如 中的配置/etc/syslog.conf

用户空间应用程序通常使用该libc函数syslog(3)来记录消息。 libc将这些消息发送到 UNIX 域套接字/dev/log(由 读取它们syslogd(8)),但如果应用程序被chroot(2)-ed,则消息最终可能会被写入其他套接字,fi 到/var/named/dev/log。当然,对于发送这些日志的应用程序并就syslogd(8)这些套接字的位置达成一致是至关重要的。由于这些原因,syslogd(8)可以配置为侦听标准套接字之外的其他套接字/dev/log

最后,该syslog协议只是一个数据报协议。没有什么可以阻止应用程序将系统日志数据报发送到任何 UNIX 域套接字(前提是其凭据允许它打开套接字),完全绕过该syslog(3)功能libc。如果数据报格式正确,syslogd(8)则可以像通过 发送消息一样使用它们syslog(3)

当然,以上仅涵盖“经典”测井理论。其他守护进程(如您提到的rsyslogsyslog-ng)可以替换普通的syslogd(8),并执行各种漂亮的操作,例如通过加密的 TCP 连接向远程主机发送消息、提供高分辨率时间戳等。还有systemd,它正在慢慢吞噬 Linux 的 UNIX 部分。 systemd有自己的日志记录机制,但这个故事必须由其他人来讲述。 :)

与 *BSD 世界的差异:

在 *BSD 上没有klogd(8),并且/proc要么不存在(在 OpenBSD 上),要么大部分已过时(在 FreeBSD 和 NetBSD 上)。 syslogd(8)从字符设备读取内核消息/dev/klog,并dmesg(1)用于/dev/kmem解码内核名称。只有 OpenBSD 有/dev/log. FreeBSD 使用两个 UNIX 域套接字/var/run/logvar/rub/logpriv而 NetBSD 有一个/var/run/log.

答案2

正如其作者所说,另一个答案解释了 Linux 中的“经典日志记录”。现在很多系统并不是这样工作的。

内核

内核机制已经改变。

内核生成输出到内存缓冲区。应用软件可以通过两种方式访问​​它。日志子系统通常将其作为名为 的伪 FIFO 进行访问/proc/kmsg。此日志信息源无法在日志读取器之间共享,因为它是一次性读取的。如果多个进程共享它,它们每个只能获得内核日志数据流的一部分。它也是只读的。

访问它的另一种方法是较新的/dev/kmsg字符设备。这是一个可在多个客户端进程之间共享的读写接口。如果多个进程共享它,它们都会读取相同的完整数据流,而不会相互影响。如果他们打开它进行写访问,他们还可以将消息注入到内核的日志流中,就像它们是由内核生成的一样。

/proc/kmsg/dev/kmsg以非 RFC-5424 形式提供日志数据。

应用领域

应用程序已更改。

GNU C 库的syslog()主要函数尝试连接到AF_LOCAL名为 的数据报套接字/dev/log并向其写入日志条目。 (BSD C 库的syslog()函数现在使用/var/run/log套接字名称,并/var/run/logpriv首先尝试。)应用程序当然可以有自己的代码来直接执行此操作。毕竟,库函数只是在应用程序自己的进程上下文中执行的代码(用于打开、连接、写入和关闭套接字)。

如果正在侦听计算机上的AF_INET/数据报套接字,应用程序还可以通过 UDP 将 RFC 5424 消息发送到本地 RFC 5426 服务器。AF_INET6

由于过去二十年来自 daemontools 世界的压力,许多守护进程支持在不使用 GNU syslog()C 库函数或 UDP 套接字的模式下运行,而只是将日志数据吐出到标准错误中普通的 Unix 时尚。

一般使用 nosh 和 daemontools 系列进行日志管理

使用 daemontools 系列工具集,日志记录具有很大的灵活性。但总的来说,整个系列的想法是每个“主要”守护进程都有一个关联的“日志记录”守护进程。 “主”守护进程就像非守护进程一样工作,并将其日志消息写入标准错误(或标准输出),服务管理子系统安排通过管道连接(它保持打开状态,以便日志数据不会丢失)服务重新启动)到“logging”守护进程的标准输入。

所有“日志记录”守护进程都运行一个记录日志的程序某处。一般来说,这个程序类似于multilogcyclog从其标准输入读取并将(纳秒时间戳)日志文件写入严格大小限制、自动轮换、独占写入的目录中。一般来说,这些守护进程也都在各个专用非特权用户帐户的支持下运行。

因此,最终会得到一个很大程度上分布式的日志系统,每个服务的日志数据都是单独处理的。

在 daemontools 系列服务管理下运行类似klogdsyslogd的东西。rsyslogd但 daemontools 世界多年前就意识到,带有“日志记录”守护进程的服务管理结构非常适合以更简单的方式做事。无需将所有日志流分散成一个巨大的大杂烩,解析日志数据,然后将流分散回单独的日志文件;然后(在某些情况下)将不可靠的外部原木旋转机构固定在侧面。 daemontools 系列结构作为其标准日志管理的一部分已经这样做了日志轮换、日志文件写入和流分离。

此外:使用所有服务通用的工具删除权限的链式加载模型意味着日志记录程序不需要超级用户权限; UCSPI 模型意味着他们只需要关心流与数据报传输等差异。

nosh 工具集就体现了这一点。虽然一在它下运行rsyslogd,开箱即用,只需/run/log以旧方式管理内核、UDP 日志输入;它提供了更多“daemontools 本机”方式来记录这些内容:

  • klogd读取/proc/kmsg该日志流并将其简单写入其标准错误的服务。这是通过一个名为 的简单程序完成的klog-read。关联的日志守护进程将其标准输入上的日志流馈送到/var/log/sv/klogd日志目录中。
  • 一种从(BSD 上)local-syslog-read读取数据报并简单地将日志流写入其标准错误的服务。这是由一个名为 的程序完成的。关联的日志守护进程将其标准输入上的日志流馈送到日志目录中。/dev/log/run/logsyslog-read/var/log/sv/local-syslog-read
  • udp-syslog-read侦听 UDP 系统日志端口、读取发送给它的内容并简单地将日志流写入其标准错误的服务。再次强调,该程序是syslog-read.关联的日志守护进程将其标准输入上的日志流馈送到/var/log/sv/udp-syslog-read日志目录中。
  • (在 BSD 上)一种local-priv-syslog-read从日志流中读取数据报/run/logpriv并简单地将日志流写入其标准错误的服务。再次强调,该程序是syslog-read.关联的日志守护进程将其标准输入上的日志流馈送到/var/log/sv/local-priv-syslog-read日志目录中。

该工具集还附带了一个export-to-rsyslog可以监视一个或多个日志目录的工具(使用非侵入式系统)日志游标)并通过网络以 RFC 5424 形式将新条目发送到指定的 RFC 5426 服务器。

使用systemd进行日志管理

systemd 有一个单一的整体日志管理程序,systemd-journald.它作为由 systemd 管理的服务运行。

  • 它读取/dev/kmsg内核日志数据。
  • 它从 GNU C 库的函数读取应用程序日志数据/dev/log(到 的符号链接) 。/run/systemd/journal/dev-logsyslog()
  • 它在AF_LOCAL流套接字上侦听/run/systemd/journal/stdout来自 systemd 管理的服务的日志数据。
  • AF_LOCAL它在数据报套接字上侦听/run/systemd/journal/socket来自使用特定于 systemd 的日志协议(即sd_journal_sendv()等人)的程序的日志数据。
  • 它将所有这些混合在一起。
  • 它写入一组系统范围和每用户的日志文件,位于/run/log/journal/或中/var/log/journal/
  • 如果它可以连接(作为客户端)到数据AF_LOCAL报套接字,/run/systemd/journal/syslog并且配置了转发到系统日志,则它会在那里写入日志数据。
  • 如果配置,它会使用可写机制将日志数据写入内核缓冲区/dev/kmsg
  • 如果配置,它也会将日志数据写入终端和控制台设备。

如果该程序崩溃或服务停止,系统范围内就会发生不好的事情。

systemd 本身会安排(某些)服务的标准输出和错误附加到套接字/run/systemd/journal/stdout。因此,以正常方式记录到标准错误的守护进程会将其输出发送到日志。

这完全取代了 klogd、syslogd、syslog-ng 和 rsyslogd。

现在要求这些是特定于 systemd 的。在 systemd 系统上,它们不能成为/dev/log.相反,他们采取以下两种方法之一:

  • 它们成为 的服务器端/run/systemd/journal/syslog,(如果您还记得的话)systemd-journald尝试连接并向其写入日志数据。几年前,人们可以配置 rsyslogd 的imuxsock输入方法来执行此操作。
  • 他们使用特定于 systemd 的库直接从 systemd 日志中读取数据,该库可以理解二进制日志格式,并且可以监视日志文件和目录以查找添加的新条目。如今,人们通过配置 rsyslogd 的imjournal输入法来完成此任务。

相关内容