我正在使用本地日志文件运行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
答案 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
}