我希望能够在 syslogd 记录某些内容(例如err
优先级或更高)时收到电子邮件通知。假设这是一个兼容 BSD 的 syslog 守护进程。
- 这能实现吗?
- 我应该使用命名管道来执行 Shell 脚本吗?
- 还有什么其他可能的解决方案?
答案1
由于链接不再有效,我已将其更改为互联网档案馆并在此引用了文章的一部分:
命名管道
syslog 的更高版本支持写入命名管道。命名管道是一种特殊类型的文件,它实现了简单的 fifo 流,允许进程相互通信。我们将利用命名管道来实现 syslog 和邮件程序之间的实时消息传递。在我们的示例中,我们将获取critical
写入该设施的所有消息local0
(除了记录之外)并将它们发送给邮件收件人[email protected]
。
配置 syslog 以写入命名管道
首先,为关键消息创建一个命名管道,例如:
# mkdir /etc/syslog.pipes
# mknod /etc/syslog.pipes/criticalMessages p
# chmod 600 /etc/syslog.pipes/criticalMessages
接下来,配置 syslog 以将critical
写入该设施的所有消息记录local0
到此管道。将以下语句添加到您的syslog.conf
文件中。
local0.crit |/etc/syslog.pipes/criticalMessages
发送消息
最后一步是将写入管道的所有消息通过邮件发送出去。您可以使用简单的 shell 脚本执行此操作。我在下面提供了一个示例,我们将其称为/usr/bin/syslogMailer
:
#!/bin/bash
# syslogMailer: a script to read stdin and turn each line into an alert
# email typically this is used to read a named-pipe written to by syslog
#
# example usage: syslogMailer < /etc/syslog.pipes/criticalMessages
#
alertRecipient="[email protected]" # the mail recipient for alerts
TMOUT=1 # don't wait > 1 second for input
# process each line of input and produce an alert email
while read line
do
# remove any repeated messages
echo ${line} | grep "message repeated" > /dev/null 2>&1
if test $? -eq 1
then
# send the alert
echo "${line}" | mailx -s "critical error on syslog" ${alertRecipient}
fi
done
守护进程与 cron?
您会注意到我在脚本中包含了以下行:
TMOUT=1 # don't wait > 1 second for input
此行为 bash 内置命令指定一秒钟的超时时间read
。因此,脚本在处理一批零条或多条消息后运行完成。这允许您在 cron 中安排它运行一次,比如说,每 5 分钟运行一次,语句如下:
# m h dom mon dow command
0-59/5 * * * * /usr/bin/syslogMailer < /etc/syslog.pipes/criticalMessages > /dev/null 2>&1
或者,如果你想把这个脚本变成一个日志运行守护进程,它将处于无限循环中,并在日志语句到达时立即发送消息,请删除超时行并用 while-true 循环包围读取语句,即
# process each line of input and produce an error message
while :
do
while read line
do
[...]
# send the alert
echo "${line}" | mailx -s "critical error on syslog" ${alertRecipient}
done
done
守护进程方法效率更高一些,并且可以同步发送电子邮件。但它的缺点是,如果守护进程意外终止,警报将停止,直到守护进程重新启动。基于 cron 的实现在这方面可以说更为强大。cron 方法还允许您将通知分批处理为 n 分钟的块。在上面的示例 cron 文件中,时间为 5 分钟。
答案2
通过 syslogd(8) 发送通知
在我的 OpenBSD 服务器上,我使用工具记录并通过电子邮件发送来自 Web 应用程序的重要消息,本地1。 这是我的/etc/syslog.conf实现它:
local1.err /var/log/example.com
local1.err |while read log; do echo "$log" | /usr/bin/mail -s SYSLOG [email protected]; done
请注意,while 循环会无限地从 syslogd 读取每一行,然后通过 echo 将其通过管道传输到 mail。这很重要。一旦 echo 输出其行,它就会终止管道,向 mail 发送 EOF,以便它可以通过电子邮件发送日志消息。
换句话说,您不能像这样通过 syslogd 直接传输邮件:
local1.err |/usr/bin/mail -s SYSLOG [email protected]
因为 syslogd 会持续向管道写入数据,直到它自己终止或者发送 HUP 信号,此时 mail 会将整套日志消息通过一封大电子邮件发送出去。
通过 newsyslog(8) 发送通知
在 cron 中安排 newsyslog 是另一种以较慢的速度或批量获取消息的方法。
例如,如果您想要每日电子邮件摘要的日志消息,请设置米标志并指定监控电子邮件地址/etc/newsyslog.conf:
# logfile_name owner:group mode count size when flags monitor
/var/log/example.com root:wheel 640 7 * 24 M [email protected]
然后在 crontab 中安排 newsyslog:
# minute hour mday month wday command
0 * * * * /usr/bin/newsyslog
1-59 * * * * /usr/bin/newsyslog -m
这-m选择权newsyslog(8)状态:
监控模式;仅处理标志中标有“M”的条目。对于每个受监控的日志文件,自上次使用 -m 标志运行 newsyslog 以来的任何日志输出都将通过邮件发送给监控通知部分中列出的用户。
答案3
您可能需要查看 logcheck 或 logwatch。Logcheck 会每小时向您发送电子邮件,其中包含与一组模式不匹配的日志行。我猜您可以让它更频繁地发送。我不知道有什么工具可以通过查看日志文件来实现这一点,但我确信有某种工具可以做到这一点。
答案4
我会使用 OSSEC。它实时监控您的日志,并允许您在特定事件匹配时通过电子邮件(或其他方式)轻松发出警报。易于使用、可扩展且开源。