Apacheアクセスログファイルをクリーンアップしますか?

Apacheアクセスログファイルをクリーンアップしますか?

Apacheロギング用の出力をパイプするシェルスクリプトにこのコードを含めます。

declare -a values=( $taintRequestVals )

for item in ${!values[@]}
do
    cat $apacheLog | sed "s/${values[$item]}=[^&\t\n]*/${values[$item]}=***/g" | /bin/grep ${values[$item]}=
done

しかし、これは非常に非効率的です。数秒以内にaccess.logサーバーのルートスライスがいっぱいになるまで、数字は指数関数的に4倍になります。 Apacheで書くより良い方法を探していますaccess.log

答え1

ここで問題は、Apacheログを読み取って同時に書き込むことです。ログに追加するものは何でも呼び出しを介してパイプに返されますcat(言葉の意図はありません:))。これにより、ファイルシステムがいっぱいになるまで動作し続ける不快な肯定的なフィードバックループが生成されます。正解はこの問題なぜこれが起こるのかに興味があるかもしれません。

ではどうすればいいですか?簡単な解決策は、次のようにファイルを変更することです。

for item in ${!values[@]};do
    sed -i "..." "$apacheLog"  #cat isn't needed here
done

そして出力をどこにでもパイプしないでください。スクリプト自体がファイルを変更します。現場で。また、sed効率のために(ループなしで)一度だけ呼び出す方法に関するterdonの回答を参照してください。

しかし、このアプローチの問題は、ファイルを処理するときに実際のApacheサーバーがファイルに内容を書き込む可能性があり、奇妙なことが発生する可能性があることです。より良い解決策は、ログから機密情報を除外する方法をApacheのドキュメントで見つけることです。

ところで、あなたがしていることはログを整理することもありません。これは、クリーンアップされた行を(まだ汚染された)ログファイルに追加します。

答え2

現在、さまざまな改善が可能です。まず、最も重要ではない点は次のとおりです。猫の無駄な使用。さらに、sed複数回実行すると、毎回ファイル全体が印刷されます。あなたが何をしているのかわかりませんgrep。特定の変数を含む行だけを印刷しようとしていますか?

とにかくより良い方法は、一度実行してsedすべての代替操作を実行することです。それは次のとおりです。

replace=""
for item in ${!values[@]}
do
    ## build the sed line
    replace="s/${values[$item]}=[^&\t\n]*/${values[$item]}=***/g;$replace"
done

### run the replacement using sed's -i option so it 
### changes the original file
eval sed -i \""$replace"\" $apacheLog

関連情報