将 apt/dpkg 活动记录到系统日志

将 apt/dpkg 活动记录到系统日志

我的目标是记录apt/dpkg活动使用系统日志(rsyslog),以便将日志条目发送到中央系统日志服务器。

dpkg 写入/var/log/dpkg.log, apt 写入/var/log/apt目录。

我做了一些研究,似乎 apt 和 dpkg 都能够使用 syslog。唯一的选择是使用 rsyslog“文本文件输入模块”功能(http://www.rsyslog.com/doc/master/configuration/modules/imfile.html),它定期检查日志文件中的新内容。

/etc/dpkg/dpkg.cfg配置文件有log选项,但没有 dpkg.cfg 选项和功能的手册页。

是真的rsyslog 文件唯一的选择?

答案1

对于 dpkg 可以通过添加来完成

status-logger "logger -t dpkg -p info"

/etc/dpkg/dpkg.cfg。由于 apt-get 调用 dpkg,因此 apt-get/apt 操作也会被记录。请参阅man logger调整记录到系统日志的信息。

我正在使用此 ansible 任务来更新配置:

- name: dpkg syslog
  lineinfile:
   dest: /etc/dpkg/dpkg.cfg
   line: 'status-logger "logger -t dpkg -p info"'

如果您使用 systemd 日志,可以很方便地通过以下方式检查日志

journalctl SYSLOG_IDENTIFIER=dpkg

答案2

可以通过该--log选项修改 dpkg 记录其输出的位置。这只允许文件名。 DPKG 被构建为一个简单而高效的工具来操作包,因此没有使事情变得复杂的记录器是一个优点。最简单的方法是写入一个文件,然后系统日志从该文件中读取,正如您已经知道的那样。

您可以使用status-fd将状态发送到文件描述符,/dev/log或者status-logger让中间人将条目发送到系统日志。

答案3

似乎status-logger/status-fd并不总是具有与log指令指定的日志文件相同的输出。 dpkg 的源代码中甚至有alternatives.log硬编码,如果不重新编译就无法更改。

所以我尝试用fifo替换日志文件,并将日志内容泵入journald。由于 systemd 的灵活性,这可以在没有额外依赖的情况下完成。

  1. 在 处准备 bash 脚本/usr/local/libexec/fifo2journal。别忘了chmod +x。该脚本具有有效的cat硬编码 60 秒超时。如果标准输入中没有可用数据(或没有换行符),则此脚本仅输出它读取的部分行并退出(以节省资源)。

    #!/bin/bash
    while :; do
        if IFS= read -r -t 60; then
            printf "%s\n" "$REPLY"
        else
            printf "%s" "$REPLY"
            exit 0
        fi
    done
    
  2. 准备 systemd 单元。 (在文件系统上使用 fifo 激活套接字)

    A。/etc/systemd/system/[email protected]

    [Unit]
    Description=fifo at %f
    
    [Socket]
    ListenFIFO=%f
    SocketMode=0660
    
    [Install]
    WantedBy=sockets.target
    

    b./etc/systemd/system/[email protected]

    [Unit]
    Description=fifo to journal for %f
    Requires=fifo2journal@%i.socket
    
    [Service]
    ExecStart=/usr/local/libexec/fifo2journal
    StandardInput=socket
    StandardOutput=journal
    SyslogIdentifier=%f
    SyslogFacility=user
    
  3. 删除磁盘上现有的日志文件(如果您愿意,请进行备份)。启用并启动 systemd 套接字单元。

    systemctl daemon-reload
    for FILEPATH in /var/log/dpkg.log /var/log/alternatives.log; do
        rm -f "$FILEPATH"
        UNIT_NAME=$(systemd-escape [email protected] --path "$FILEPATH")
        systemctl enable "$UNIT_NAME"
        systemctl start "$UNIT_NAME"
    done
    

现在您可以观看日志 ( journalctl -f -t /var/log/dpkg.log) 并尝试向其写入 ( echo hello >/var/log/dpkg.log)。

logrotate 会将 fifo 视为空日志,并且不执行任何操作。

请记住,此方法需要运行 systemd 来激活套接字。如果 systemd 未运行并且您尝试在不使用 的情况下打开(关闭的)fifo O_NONBLOCK,则可能会导致意外的后果,特别是如果您通过 chroot 拯救 rootfs。

O_NONBLOCK如果您正在升级 systemd,并且无论出于何种原因,套接字激活在 60 秒的时间窗口内尚未准备好,并且任何尝试打开 fifo 的线程都不会挂起,则存在潜在问题。我希望这永远不会发生。

相关内容