我遇到了当要写入的文件不存在时 rsyslog 消息丢失的情况。
这是我的设置:
- 日志服务器192.168.1.2有这样的配置:
module(load="imtcp")
input(type="imtcp" port="514")
$template MyRemoteLog1,"/nfs/some/dir/%FROMHOST-IP%/%programname%/%$year%-%$month%-%$day%.log"
$template MyRemoteLog2,"/nfs/other/dir/%FROMHOST-IP%/%syslogfacility-text%.%syslogseverity-text%.%programname%.log"
$template MsgOnly,"%msg:2:$:%\n"
if $FROMHOST-IP== ['192.168.1.3'] AND $SYSLOGFACILITY-TEXT== ['local5'] then ?MyRemoteLog1;MsgOnly
& stop
if $FROMHOST-IP== ['192.168.1.3'] then ?MyRemoteLog2
& stop
- 发送日志192.168.1.3的客户端有这样的配置:
*.* @@192.168.1.2:514
- 我也尝试将 192.168.1.3 的配置更改为这样,但问题仍然存在:
*.* action(type="omfwd"
Target="192.168.1.2"
Port="514"
resendlastmsgonreconnect="on"
action.resumeRetryCount="-1"
queue.filename="queue"
queue.size="100000"
queue.saveonshutdown="on"
Protocol="tcp" )
基本上,如果 local5 则存储到 /nfs/some/dir/192.168.1.3/mytag/2022-03-15.log,但如果不是 local5 则存储到 /nfs/other/dir/192.168.1.3/user日志服务器中的.notice.mytag.log
另外,我的设置将日志文件写入 nfs 安装的磁盘(如果重要的话)。
问题是这样的:
- 系统已经运行(日志已写入)
- 在192.168.1.3(客户端)中,运行
date | logger -p local5.debug -t mytag
- 在192.168.1.2(服务器)中,创建了新文件/nfs/some/dir/192.168.1.3/mytag/2022-03-15.log,但内容为空
- 在192.168.1.3(客户端)中,运行
date | logger -p local5.debug -t mytag
(再次) - 在192.168.1.2(服务器)中,写入文件/nfs/some/dir/192.168.1.3/mytag/2022-03-15.log(写入步骤4中的消息,但步骤2中的消息丢失)
- 在 192.168.1.2(服务器)中,删除该文件,然后运行 rsyslog 旋转脚本,如下所示:
rm /nfs/some/dir/192.168.1.3/mytag/2022-03-15.log ; /usr/lib/rsyslog/rsyslog-rotate
- 在192.168.1.3(客户端)中,运行
date | logger -p local5.debug -t mytag
(再次) - 在192.168.1.2(服务器)中,创建了新文件/nfs/some/dir/192.168.1.3/mytag/2022-03-15.log,但内容为空
我认为这个实验表明,当文件尚不存在时,它会被创建,但内容不会被写入。为什么会这样?
起初我认为这可能是因为普通 TCP 上的 rsyslog 不可靠,我可能需要使用 RELP。但经过这样的实验,我不认为问题出在网络上。
这是我的 nfs 挂载:
172.16.1.4:/some/dir/nfs_export on /nfs type nfs (rw,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=172.16.1.4,mountvers=3,mountport=38559,mountproto=udp,local_lock=none,addr=172.16.1.4)
$DebugFile /tmp/rsyslogdebug.txt
通过添加 config和 config$DebugLevel 1
并运行以下命令打开 rsyslog 调试消息后:
kill -USR1 `ps aux | grep rsyslog | tr -s ' ' | cut -d' ' -f2 | head -n1`
我设法找到这样的日志/tmp/rsyslogdebug.txt
:
7792.776708768:main Q:Reg/w0 : omfile.c: omfile: file to log to: /nfs/some/dir/192.168.1.3/mytag/2022-03-15.log
7792.779333692:main Q:Reg/w0 : errmsg.c: Called LogMsg, msg: error during config processing: omfile: chown for file '/nfs/some/dir/192.168.1.3/mytag/2022-03-15.log' failed: Operation not permitted
7792.779415835:main Q:Reg/w0 : operatingstate.c: osf: MSG error during config processing: omfile: chown for file '/nfs/some/dir/192.168.1.3/mytag/2022-03-15.log' failed: Operation not permitted: signaling new internal message via SIGTTOU: 'error during config processing: omfile: chown for file '/nfs/some/dir/192.168.1.3/mytag/2022-03-15.log' failed: Operation not permitted [v8.2001.0 try https://www.rsyslog.com/e/2207 ]'
7792.779567477:main thread : janitor.c: janitorRun() called
7792.779745372:main Q:Reg/w0 : errmsg.c: Called LogMsg, msg: error during config processing: Could not open dynamic file '/nfs/some/dir/192.168.1.3/mytag/2022-03-15.log' [state -3000] - discarding message
7792.779812889:main Q:Reg/w0 : operatingstate.c: osf: MSG error during config processing: Could not open dynamic file '/nfs/some/dir/192.168.1.3/mytag/2022-03-15.log' [state -3000] - discarding message: signaling new internal message via SIGTTOU: 'error during config processing: Could not open dynamic file '/nfs/some/dir/192.168.1.3/mytag/2022-03-15.log' [state -3000] - discarding message [v8.2001.0 try https://www.rsyslog.com/e/2207 ]'
答案1
提示在消息里error during config processing: omfile: chown for file
我假设这个过程是这样的:
- rsyslog 如果文件不存在则创建该文件(如果已经存在,则跳到步骤 3)
- 然后 chmod 并将其 chown 到配置文件中定义的用户和组(如果不存在),
- 然后 rsyslog 写入/附加到文件
我认为当它进入步骤2时,它失败了,将文件留给所有者syslog:syslog
,因此当收到后续日志消息时,它只是跳到步骤3并成功写入消息。因此所有第一条消息都被删除
但Ubuntu 20.04给出的默认配置是
$FileOwner syslog
$FileGroup adm
因此它试图 chownsyslog:adm
当我将其配置更改为
$FileOwner syslog
$FileGroup syslog
该错误不再发生。
但还有一个问题没有解决:
- 当写入的目录位于nfs挂载内时,会发生此类错误
- 当它写入的目录不在nfs挂载内时,不会发生此类错误