2011-01-11 6 views
8

私はgrepを持つテール・ログ・ファイルにしたいとのようなメール 経由で送信された:尾とgrepログやメール(Linux)の

tail -f /var/log/foo.log | grep error | mail -s subject [email protected] 

私はこれをどのように行うことができますか?

+0

この質問は、「私は 'print( 'Foo');」のようなもので、' Foo 'を印刷したいのですが、どうすればいいですか?あなたの質問は何ですか? –

+1

'tail' * -f *はおそらくファイルの最後に続くようにしたくないでしょう。 'grep'は** tail **のログでもありません。あなたが解決しようとしている問題は何ですか? – Johnsyweb

+0

'tail -f .. | grep ... 'は、ファイルが大きくなり、grepを使用して追加データを出力することです。 – ajreal

答えて

2

私はこれを実行します。おそらく、私の不気味なbashコードが精査されたら何かを学ぶでしょう。既にこれを行うためのすばらしい解決策がある可能性はありますが、あなたがサイバーオーシャンの深さと幅をトラップしたと確信しているので、私は見つけ出すつもりはありません。 1)定期的にファイルの最新のテールを取得する、2)最新のテールが実際に存在する場合は、電子メールで送信する、という2つのビットに分けることができます。 1)の定期的な間隔については、cronを使用してください。 2)の最新テールを入手するには、ファイルサイズを把握する必要があります。以下のbashスクリプトはそれを行います - それはcronによって呼び出される2)に対する解決策です。キャッシュされたファイルサイズを使用して、メールに必要なファイルのチャンクを計算します。ファイルmyfileに対して、別のファイル.offset.myfileが作成されることに注意してください。また、スクリプトはファイル名にパスコンポーネントを許可しません。起動時に書き直し、または修正してください。 (cd/foo/bar & & segtail.sh zut)をsegtail.shといいます。

#!/usr/local/bin/bash 
file=$1 
size=0 
offset=0 
if [[ $file =~/]]; then 
    echo "$0 does not accept path components in the file name" 2>&1 
    exit 1 
fi 
if [[ -e .offset.$file ]]; then 
    offset=$(<".offset.$file") 
    fi 
if [[ -e $file ]]; then 
    size=$(stat -c "%s" "$file") # this assumes GNU stat, possibly present as gstat. CHECK! 
            # (gstat can also be Ganglias Status tool - careful). 
fi 
if (($size < $offset)); then  # file might have been reduced in size 
    echo "reset offset to zero" 2>&1 
    offset=0 
fi 
echo $size > ".offset.$file" 
if [[ -e $file && $size -gt $offset ]]; then 
    tail -c +$(($offset+1)) "$file" | head -c $(($size - $offset)) | mail -s "tail $file" [email protected] 
fi 
+0

あなたの質問に対するgrepの部分はこれで答えられませんでした。運動として残した。 – micans

+0

ファイル名の変数展開に関する完全な引用符が必要です。 bashへのパスがすべてのシステムで正しくない。おそらく 'env'を介して起動します。 'stat'の出力は、システムとバージョン(!)の間で非常に変化します。最近のGNU statを仮定して、これを解くために-cを試して、解析する必要性を避けてください。 – Sorpigal

+0

'cat'は必要ありません:' offset = $(<。offset。$ file) '。 'if [[-e $ file && $ size> $ offset]]'の2番目の部分は字句比較なので、例えば '$ size' == 10や' $ offset '== 2.これを代わりに使う:' [[-e $ file]] &&(($ size> $ offset)) '。ほとんどの場合、 '(())'と '$(())'の中でドル記号を省略することができます。 –

17

エラーが発生したときに電子メールを送信しますか? grepの出力のライン毎に電子メールを送信し

tail -f $log | 
grep --line-buffered error | 
while read line 
do 
    echo "$line" | mail -s subject "$email" 
done 

:あなたはしかし、このような何かを試すことができ

);それは失敗する可能性があります。

nohup ./monitor.sh & 

とシェルスクリプト上記

実行ので、それはバックグラウンドで実行し続けます。

+1

あなたは末尾のバックスラッシュを必要としません - シェルは末尾のパイプ(そして '&'、 '&&'と '||')の次の行を探します –

+0

興味深い...私が逃したこと。ありがとう@glenn jackman –

+1

エラーの後に10行も出力したいと仮定します(grep -A 10エラー)。あなたのアプローチでは、私は10の電子メールを受け取るでしょう、私は10行を含む唯一のメールを受け取るために何をする必要がありますか? – markus

関連する問題