ログからエラー/警告を電子メールで送信するスクリプトを作成しています。これを30分ごとに送信したいのですが、新しいエントリがある場合にのみ送信したいと思います。最後の30分だけのエラーをgrepするにはどうすればよいですか?
ログのタイムスタンプは次の形式です。
<2016年8月1日2:15:29 PM MDT> <エラーの詳細.....>
これまでのスクリプトは次のとおりです。
#!/bin/bash
cat /var/log/logfile.log | egrep -i "error|warning" | tee -a /tmp/log.tmp
"get only last 30 min of errors" | mail -s "Errors/Warning" [email protected]
タイムスタンプ(2016年8月1日2:15:29 PM MDT)をエポック時間に変換してから現在のエポック時間と比較することは可能ですか、それともsed/awkを使用する方法はありますか?/Perlは最後の30分を取得しますか?
素晴らしいアイデアです。最も簡単なのは、ファイルを比較するための@MelBurslanの提案です。
#!/bin/sh
[email protected]
OFILE=/var/tmp/alerts.tmp
LOG30=/var/tmp/LOG30
LOGNOW=/var/tmp/LOGNOW
Host=`hostname`
# setup file
if [ -f ${OFILE} ]; then
cat /dev/null > ${OFILE}
else
touch ${OFILE}
fi
cat /var/log/logfile.log | egrep -i "error|warning" | tee -a ${LOGNOW}
diff ${LOG30} ${LOGNOW} | tee -a ${OFILE}
if [ -f ${OFILE} ]; then
echo "Errors" | cat - ${OFILE} > temp && mv temp ${OFILE}
mailx -r [email protected] -s "Errors" ${MAILTO} < ${OFILE}
fi
rm ${LOG30}
mv ${LOGNOW} /var/tmp/LOG30
rm ${OFILE}
エポックに変換するには、次のステートメントを使用できます。
# date +%s -d"Aug 1, 2016 2:15:29 PM MDT"
1470082529
エポックをUTCに変換するには、次を使用できます。
# date -d @1470082529
Tue Aug 2 00:45:29 IRDT 2016 #### on Linux Box
# date -r 1470082529
Tue Aug 2 00:45:29 IRDT 2016 ###on BSD box
Perl
のFile::Tail
モジュールを使用します。今は例を書く時間がありませんが、偽コードでは、次のようになります。
#! /usr/bin/not-actually-Perl
use strict;
use File::Tail;
use Net::SMTP or Mail::Mailer or one of the squillion other
Perl mail sending modules;
open a File::Tail file handle to your log file
my $now=time();
my @lines = ();
while (read the File::Tail handle) {
Push @lines, $_;
if (time() > ($now + 1800 seconds) ) {
$now=time();
email the @lines array to [email protected];
@lines=();
}
}
実際に機能するスクリプトは、おそらく上記より10行未満長く、そのほとんどは電子メールのヘッダーを設定することです。
さまざまなシグナルをトラップして、一時停止または終了する前に@linesに現在あるものを電子メールで送信するためのさらに数行。
正確な詳細については、File::Tail
およびNet::SMTP
(またはその他)のマニュアルページを参照してください。