ログのエラー/警告を電子メールで送信するスクリプトを作成しています。 30分ごとに転送したいのですが、新しいアイテムがある場合にのみ転送したいです。過去30分間で何が問題なのか、どうすればわかりますか?
ログのタイムスタンプは次の形式に従います。
<2016年8月1日午後2時15分29秒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 MDT)をepoch時間に変換してから、現在のepoch時間と比較できますか?それとも、sed / awk / perlを使用して過去30分を取得する方法はありますか? ?
答え1
時代に変換するには、次の文を使用できます。
# date +%s -d"Aug 1, 2016 2:15:29 PM MDT"
1470082529
Epochを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
答え2
私が使用するperl
モジュールはFile::Tail
。今は例を書く時間がありませんが、Perlish疑似コードでは次のようになります。
#! /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
は、および(または他の場所)のマニュアルページを参照してください。
答え3
良いアイデアです。最も簡単な方法は、@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}