【发布时间】:2016-08-16 00:16:52
【问题描述】:
我正在使用 Log::Syslog::Fast 将日志转发到 syslog 服务器。我正在测试脚本,看看如果系统日志服务器突然崩溃它会如何反应。
为了测试,我创建了一个包含测试消息的文件,启动了脚本,然后在 syslog 服务器收到 2 条消息后关闭了 syslog 服务器。
脚本发送了第三条消息,然后死掉了。终止没有被eval 捕获并且'use warnings 'FATAL' => 'all';' 没有帮助。
有人可以帮我捕捉异常并更优雅地关闭脚本吗?
这里需要做的是 - 发送 Command2 后,脚本应该捕获异常并显示:
Fail: Command3
代码摘录:
$logger = Log::Syslog::Fast->new(LOG_TCP,$server, 514, 13, 6, "test_machine", "Syslog");
$logger->set_pid(0);
foreach $line(<SPOOL>)
{
($machine,$time,$message)=(split '\|',$line);
eval{
$logger->set_sender($machine);
$logger->send($message,$time);
};
if($@)
{
print "\nFail: $message\n";
exit;
}
else
{
print "\nSuccess: $message\n";
}
sleep 5;
}
输入文件:
test_machine1|1461201306|Command1
test_machine1|1461201311|Command2
test_machine1|1461203214|Command3
test_machine1|1461203219|Command4
test_machine2|1461204005|Command5
test_machine2|1461204006|Command6
test_machine2|1461204149|Command7
test_machine3|1461204154|Command8
test_machine3|1461206936|Command9
test_machine3|1461206942|Command10
输出:
Success: Command1
Success: Command2
Success: Command3
Strace 输出:
read(4, "test_machine1|1461201306|Command"..., 4096) = 341
read(4, "", 4096) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
sendto(3, "<110>Apr 20 21:15:06 test_machin"..., 59, 0, NULL, 0) = 59
write(1, "Success Command1\n\n\n", 19Success Command1
) = 19
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({5, 0}, 0x7ffc707478f0) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
sendto(3, "<110>Apr 20 21:15:11 test_machin"..., 59, 0, NULL, 0) = 59
write(1, "Success Command2\n\n\n", 19Success Command2
) = 19
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({5, 0}, 0x7ffc707478f0) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
sendto(3, "<110>Apr 20 21:46:54 test_machin"..., 59, 0, NULL, 0) = 59
我希望脚本在尝试发送第三条消息时失败。
write(1, "Success Command3\n\n\n", 19Success Command3
) = 19
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({5, 0}, 0x7ffc707478f0) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
sendto(3, "<110>Apr 20 21:46:59 test_machin"..., 59, 0, NULL, 0) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=26037, si_uid=3179} ---
+++ killed by SIGPIPE +++
脚本在尝试发送第四条消息时最终死掉了。不幸的是,eval 没有捕捉到异常。
【问题讨论】:
-
在每种情况下(对于“如果”),您的 $@ 价值得到了什么?
-
第三条消息之后会发生什么?它会无限期地继续报告成功,还是最终抛出异常?我认为this 可能是相关的。
-
完美地为我工作。您是否尝试过 strace 以获取有关正在发生的事情的更多信息?
-
@tale 在成功和失败的情况下 $@ 在我尝试打印时为空。
-
@This 在第三条消息之后,脚本就死了,返回码为 141。
标签: perl exception tcp exception-handling eval