同步等待rsyslog刷新完成

时间:2019-01-30 13:06:46

标签: flush rsyslog

我正在使用本地日志文件运行rsyslogd 8.24.0。

我有一个测试,该测试运行一个程序,该程序执行一些syslog日志记录(测试中的条目通过rsyslog.conf设置转到另一个文件),然后返回Shell脚本以检查日志是否包含预期的内容。这通常可行,但有时会失败,好像没有发生日志记录一样。在检查之前,我已经向shell脚本添加了刷新(使用HUP信号)。我可以看到HUP发生了,并且正确的条目在日志中,但是脚本的检查仍然失败。 有没有办法让Shell脚本等待刷新完成?我可以添加任意睡眠,但希望有更多确定的睡眠。

以下是shell脚本的相关内容:

# Set syslog to send dump_hook's logging to a local logfile...
sudo echo "user.*   `pwd`/dump_hook_log" >> /etc/rsyslog.conf
sudo systemctl restart rsyslog.service
echo "" > ./dump_hook_log

# run the test program which does syslog logging

kill -HUP `cat /var/run/syslogd.pid` # flush syslog 
if [ $? -ne 0 ]
then 
    logFail "failed to HUP `cat /var/run/syslogd.pid`: $?"
fi
echo "sent HUP to `cat /var/run/syslogd.pid`" 
grep <the string I want> ./dump_hook_log >/dev/null

有问题的字符串在测试报告失败之前一直存在于dump_hook_log中,我已经去研究它了。我认为一定是在grep之前尚未完成刷新。

这里是一个示例: 在/ var / log / messages

2019-01-30T12:13:27.216523+00:00 apx-ont-1 apx_dump_hook[28279]: Failed to open raw dump file "core" (Is a directory)
2019-01-30T12:13:27.216754+00:00 apx-ont-1 rsyslogd: [origin software="rsyslogd" swVersion="8.24.0" x-pid="28185" x-info="http://www.rsyslog.com"] rsyslogd was HUPed

日志文件的修改日期(n.b。早于其包含的条目!):

rw-rw-rw- 1 nealec appexenv1_group 2205 2019-01-30 12:13:27.215053296 +0000 testdir_OPT/dump_hook_log

日志文件的最后一行(此处只有apx_dump_hook条目):

2019-01-30T12:13:27.216523+00:00 apx-ont-1 apx_dump_hook[28279]: Failed to open raw dump file "core" (Is a directory)

脚本报告错误:

Wed 30 Jan 12:13:27 GMT 2019 PSE Test 0.2b FAILED: 'Failed to open raw dump file' not found in ./dump_hook_log

2 个答案:

答案 0 :(得分:0)

作为解决方案,这似乎有点沉重,但是您可以使用系统的inotify api等待日志文件被关闭(HUP信号的结果)。例如,

inotifywait -e close ./dump_hook_log

将挂起,直到rsyslogd(或任何进程)关闭文件时,您将收到消息

./dump_hook_log CLOSE_WRITE,CLOSE 

,程序将退出,返回代码为0。您可以添加超时。

答案 1 :(得分:0)

我想我现在明白了。 HUP使rsyslogd关闭其打开的文件,但是直到需要登录之前,它不会重新打开文件。 考虑以下: 我使用inotify来等待文件关闭,如下所示:

case 9:
    {
        // Wait for the file, specified in argv[2], to be closed
        int inotfd = inotify_init();           
        if (inotfd < 0) {
            printf("inotify_init failed; errno %d: %s\n",
                errno, strerror(errno));
            exit(99);
        }
        int watch_desc = inotify_add_watch(inotfd, argv[2], IN_CLOSE);
        if (watch_desc < 0) {
            printf("can't watch %s failed; errno %d: %s\n",
                argv[2], errno, strerror(errno));
            exit(99);
        }
        size_t bufsiz = sizeof(struct inotify_event) + PATH_MAX + 1;
        struct inotify_event* event = static_cast<inotify_event*>(malloc(bufsiz));
        if (!event) {
            printf("Failed to malloc event buffer; errno %d: %s\n",
                errno, strerror(errno));
            exit(99);
        }

        /* wait for an event to occur with blocking read*/
        read(inotfd, event, bufsiz);
    }

然后在我的shell脚本中等待:

# Start a process that waits for the log file be closed
${bin}/test_dump_hook.exe 9 "./dump_hook_log" &  
wait_pid=$!

# Signal syslogd to cause it it close/reopen its log files
kill -HUP `cat /var/run/syslogd.pid` # flush syslog 
if [ $? -ne 0 ]
then 
    logFail "failed to HUP `cat /var/run/syslogd.pid`: $?"
fi
wait $waid_pid

我发现这永远不会回来。从另一个进程向rsyslogd发送HUP也不会使它脱离等待状态,但是日志文件的猫(确实会打开/关闭文件)确实可以。

那是因为shell脚本中的HUP是在其他进程等待它之前完成的。因此,文件在等待开始时就已经关闭,并且由于没有更多日志记录到该文件,因此不会重新打开该文件,并且在接收到任何后续HUP时也不需要关闭该文件,因此该事件永远不会结束等待

已经了解了此行为,如何在检查日志之前确定日志已被写入?我已经解决了这个问题。将已知消息放入日志中,然后等待,直到出现该消息为止,我知道我正在等待的条目必须在此之前。像这样:-

function flushSyslog
{
    logger -p user.info -t dump_hoook_test "flushSyslog"
    # Signal syslogd to cause it it close its log file
    kill -HUP `cat /var/run/syslogd.pid` # flush syslog 
    if [ $? -ne 0 ]
    then 
        logFail "failed to HUP `cat /var/run/syslogd.pid`: $?"
    fi
    # wait upto 10 secs for the entry we've just logged to appear
    sleeps=0 
    until     
        grep "flushSyslog" ./dump_hook_log > /dev/null 
    do  
        sleeps=$((sleeps+1))
        if [ $sleeps -gt 100 ]
        then
            logFail "failed to flush syslog dump_hook_log"
        fi
        sleep 0.1
    done        
}