人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

シェルスクリプトの作成をお願いします。

・シスログ(/var/adm/messages)からエラー項目を抽出し、
監査対象かを判別するリストファイルを読み込んで、
あてはまるならば別のログファイルに書き出す。


これを1つのスクリプトファイルとして保存して
cronで5分毎に実行させます。

その際に前の実行時に記録されたエラーは含まれないように
するのですが私にはできませんでした。。

シスログのフォーマットは
"Nov 29 21:23:52 serverA snmpd[2408]: /etc/snmp/snmpd.conf: line 67: Error: Blank line following proc token.

であり、これをdateコマンドで取った日付と比較できずに行き詰っております。

(※date +%b でも解決できず・・・)


どうぞよろしくお願いします。



●質問者: SuperBel
●カテゴリ:コンピュータ インターネット
✍キーワード:23 ETC SNMP エラー コマンド
○ 状態 :終了
└ 回答数 : 5/5件

▽最新の回答へ

1 ●
●20ポイント

GNU版のdateが使える環境であれば、日付文字列の比較は可能です。

date_comparison.sh というシェルを参考にしてみてください。

ちなみに「Nov 29 21:23:52」と同様の表示は「date +"%b %d %H:%M:%S"」で可能です。

(日の値が10未満の場合、前ゼロではなく、スペースにしたいのであれば、%d の部分は %e になります。)

後は、今どういうスクリプトになっているのか、などの情報を公開すると、より適切な回答が付くと思います。

(単純に別のログファイルの最終行をsedなどで読み込んで、それと一致する行以降を処理するようにすれば良いような気がしますが、いかがでしょうか。)

少しでも参考になれば幸いです。

◎質問者からの返答

ご回答ありがとうございます。

sedによる変換も考えましたが、日・月・年またぎの処理を意識してしまい思うように動きません。

現在のスクリプトは以下のとおりです。

=====================================

#!/bin/bash

#mo_evlc.bash

#daemon-list 監視を除外するデーモンのリスト

SYSLOGLIST=SYS_list.txt



NOWTIME=$(date '+%Y%m%d%H%M%S')


var1=$NOWTIME

SUM=$(expr $var1 - $var2)

SUM2=301

SYSLOG_CHECK=TRUE

cat /var/log/errlog > error.list2

#ER_LIST=(`tail -n 1 error.list2 | sed -e 's/ /,/g'` )

#ER_LIST=(`tail -n 1 error.list2` )

sed 's/Jan/01/g' error.list2

sed 's/Feb/02/g' error.list2

sed 's/Mar/03/g' error.list2

sed 's/Apr/04/g' error.list2

sed 's/May/05/g' error.list2

sed 's/Jun/06/g' error.list2

sed 's/Jul/07/g' error.list2

sed 's/Aug/08/g' error.list2

sed 's/Sep/09/g' error.list2

sed 's/Oct/10/g' error.list2

sed 's/Nov/11/g' error.list2

sed 's/Dec/12/g' error.list2



if [ "$SUM" -lt "$SUM2" ] ; then

A=${ER_LIST[2]}

if [ -z "${A// }" ] ; then

date >> result.log

echo "OK" >> result.log

else

if [ "${A//:}" -lt "$TIME" ] ; then

SYSLOG_CHECK=FALSE

elif [ "${A//:}" -ge "$TIME" ] ; then

if [ "${DAY}" -ne "${ER_LIST[1]}" ] ; then

SYSLOG_CHECK=FALSE

else

SYSLOG_CHECK=TRUE

fi

if [ "${SYSLOG_CHECK}" = TRUE ] ; then

FILTER_CHECK=TRUE

if [ "${FILTER_CHECK}" = TRUE ] ; then

date >> result2.log

echo "OK" >> result2.log

else

date >> result2.log

echo "NG" >> result2.log

tail -n 1 error.list2 >> more_detail2.log

fi



elif [ "${SYSLOG_CHECK}" = FALSE ] ; then

date >> result2.log

echo "NG" >> result2.log

fi



elif [ "${A//:}" -eq "$TIME" ] ; then

if [ "${DAY}" -ne "${ER_LIST[1]}" ] ; then

SYSLOG_CHECK=FALSE

else

SYSLOG_CHECK=TRUE

fi

if [ "${SYSLOG_CHECK}" = TRUE ] ; then

${ER_LIST} > sys.tmp

FILTER_CHECK=TRUE


if [ "${FILTER_CHECK}" = TRUE ] ; then

date >> result2.log

echo "OK" >> result2.log

else

date >> result2.log

echo "NG" >> result2.log

tail -n 1 error.list2 >> more_detail2.log

fi



elif [ "${SYSLOG_CHECK}" = FALSE ] ; then

date >> result2.log

echo "OK" >> result2.log

tail -n 1 error.list2 >> more_detail2.log

fi

fi


date '+%Y%m%d%H%M%S' > date.txt

fi

else

date >> result2.log

echo "OK" >> result2.log

fi


exit;

======================================

それではよろしくお願いします。


2 ● kurukuru-neko
●20ポイント

時刻の比較は

date +"%s"

日付は

date --date="xxxx "

をしてあげればほとんど変換してくれます。

時間は同じ場合もあるので文字も比較をした方が

よいように思います。

以下例:

-------------------------------------------

#!/bin/bash

TMPF1=/tmp/tmpfile1.$$

TMPF2=/tmp/tmpfile2.$$

PREVLOG=/tmp/tmpfile.prev

NLINE=3

export LANG=C

trap "rm -f $TMPF1 $TMPF2" INT QUIT TERM EXIT

cp /var/log/messages $TMPF1

tail -$NLINE $PREVLOG >$TMPF2 2>>/dev/null

if [ $? -ne 0 ] ; then

tail -$NLINE $TMPF1 >$PREVLOG

else

tail -$NLINE $TMPF1 >$PREVLOG

gawk -v OUTPUT=$TMPF2 -v NLINE=$NLINE '

BEGIN {

# Read Last N Lines

ilog=0;

while( (getline line <OUTPUT ) > 0 ) {

ilogs[ilog++] = line;

# print "PREV",line;

};

# Parse Log Date

lasttime=0;

do {

if( ilog == 0 ) {

break;

};

if( split(ilogs[ilog-1],idata," ")< 3 ){

break;

};

scmd=sprintf("date --date=\"%s %s %s\" +\"%%s\"",idata[1],idata[2],idata[3]);

scmd | getline lasttime;

} while( 0 );

# Clear Output File

lmatch=0;

system("rm -f "OUTPUT);

}

NF > 2 {

if( lmatch >= ilog ) {

print >>OUTPUT;next;

};

if( NR == 1 && NF >= 3) {

scmd=sprintf("date --date=\"%s %s %s\" +\"%%s\"",$1,$2,$3);

scmd | getline logdate;

if( logdate > lasttime ) {

lmatch = ilog;print >>OUTPUT;next

};

};

if( ilogs[lmatch] == $0 ) {

lmatch++; next;

};

lmatch=0;

next;

}

' $TMPF1

rm -f $TMPF1

if [ -f $TMPF2 ]; then

mv $TMPF2 $TMPF1

fi

fi

# Check Log

if [ -f $TMPF1 ] ; then

echo "Analyse data $TMPF1"

cat $TMPF1

fi

◎質問者からの返答

ありがとうございます。

この場合は直近の3つのログを確認しているということでよろしいでしょうか?

前回実行時から今回までの5分間に発生したエラーログをすべて対象としたいのですが。


3 ● kurukuru-neko
●20ポイント

年末をまたぐ場合の処理はしていません。

※: のログ書式によってはもう少し工夫が必要

年末対策

scmd=sprintf("date --date=\"%s %s %s\" +\"%%s\"",idata[1],idata[2],idata[3]);

scmd | getline lasttime;

# Add New Year Fix

if( lasttime > systime() ) {

iyear=strftime("%Y",systime());

scmd=sprintf("date --date=\"%s %s %s %d\" +\"%%s\"",idata[1],idata[2],idata[3],iyear-1);

scmd | getline lasttime;

}

同様に

scmd | getline logdate;

# Add New Year Fix

if( logdate > systime() ) {

iyear=strftime("%Y",systime());

scmd=sprintf("date --date=\"%s %s %s %d\" +\"%%s\"",$1,$2,$3,iyear-1);

scmd | getline logdate;

}

一部訂正

tail -$NLINE $PREVLOG >$TMPF2 2>>/dev/null

RC=$?

tail -$NLINE $TMPF1 >$PREVLOG

if [ $RC -ne 0 ] ; then

rm -f $TMPF2

else

gawk .....

◎質問者からの返答

ありがとうございます!

これは監査対象となるデーモンを

1行毎に記入したテキストのリストファイルで

フィルタリングをかけることが可能でしょうか?


4 ● kurukuru-neko
●20ポイント

>前回実行時から今回までの5分間に発生したエラーログを

>すべて対象としたいのですが。

対象です。

ログファイルは文字なので1行で比較してもよいが

連続したログが記録される場合があります。

念のために最後に処理したログの3行を保存して

再度処理する場合に3行したデータを移行又は、

一致データがない場合は全てを対象とします。

最初は全て対象ですが2回目以降は、対象は差分のみです。

差分だけほしい場合

tail -3 /var/log/messages >/tmp/tmpfile.prev

としてログの時刻を少し前変更してみてください。

※:/tmp/tmpfilexxxxのファイル名は変更してください。


5 ● kurukuru-neko
●20ポイント

>date '+%Y%m%d%H%M%S' > date.txt

処理をした時刻を記録していますが。

エラーログに記録される時刻が常に正しいとは

限りません。

時刻は進んだり戻ったりする事もあります。

又、処理している間にもログはかかれていたり

バッファにあってたまたまかかれていない場合も

あるので処理した時刻を記録することはあまり

意味ないと思います。

必要なのは未処理データの抽出と思います。

よくする方法はsyslog.confの出力先に

named pipe等を指定してあげて

常駐プロセスが適時処理するような方法か

syslog-ngのようなログ解析機能があるものを

検討するのも手です。

http://www.infoscience.co.jp/technical/press/app06.html

http://www.atmarkit.co.jp/fsecurity/rensai/unix_sec09/unix_sec01...

swatchによるログの常時監視

http://www.atmarkit.co.jp/flinux/rensai/root04/root04b.html

http://itpro.nikkeibp.co.jp/members/NBY/techsquare/20030630/2/

◎質問者からの返答

ありがとうございます。

しかしながら、今回はsyslogの運用方法で決定しているので変えることはできません。

上に記述した要件を満たすスクリプト、作成していただければ幸いです。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ