私はかなり簡単な方法を探しています(開発は必要ありません。Pythonで書くことができますが、すでに持っているものがあればいいです)。
ログファイルがあります(私の場合はrsyslogdで書かれています)。分析の目的で、私は1分ごとに読んで、私のhttpサーバーのページビュー数などの最後の瞬間の指標を計算したいと思います。私の要求2つ:
1) 最後にファイルを読んだ後に追加された行だけを見たいです。 (最後の1分程度しか必要ありません。ファイルが大きすぎて1分ごとに読み直してフィルタリングできません。)
2)1日に1回ファイルを録音します。ログの回転後に最初にまだ読み取られていない古いファイルのすべての行と新しいファイルのすべての行が必要です。
今それを求める人は私だけのようです。他の人はどうしますか?
答え1
your-filter
そのデータがstdinから読み取られたとします。
while your-filter; do
sleep 60
done < file.log
たとえば、your-filter
データを読み取るだけでデータを書き込もうとしないとします。lseek
/dev/fd/n
ログローテーションの問題を解決するには、Linux(実際のファイルへのシンボリックリンクである他のほとんどのシステムとは異なり)で、、、、、ksh
(POSIX以外のものなど、最も賢いシェルを除くほとんどのPOSIXシェル)を使用しますbash
。 :zsh
dash
yash
posh
-ef
while your-filter; do
if [ file.log -ef /dev/stdin ]; then
sleep 60
else
exec < file.log
fi
done < file.log
ログが回転したときに古いyour-filter
接続と新しい接続を1回呼び出すには、2回呼び出されます。
while
if [ file.log -ef /dev/stdin ]; then
your-filter
else
exec 3<&0 < file.log
(cat <&3; cat) | your-filter &&
exec 3<&-
fi
do
sleep 60
done < file.log
これで、ログの循環中に古い file.log の名前が変更されましたが、新しい file.log がfile.log
生成されなかった場合があります。exec < file.log
この場合、上記の操作は失敗します。その後、次を使用してこの問題を解決できます。
while
if [ file.log -ef /dev/stdin ] || ! command exec 3< file.log; then
your-filter
else
(cat; cat <&3) | your-filter &&
exec <&3 3<&-
fi
do
sleep 60
done < file.log
したがって、新しいファイルが表示されるまで古いファイルを読み続けます。
command
exec
失敗時にシェルがシャットダウンするのを防ぐ必要があります(POSIXが要求するように)。モードzsh
になっているbash
場合とない場合は必要ありませんsh
。
これで、ループ内で60秒間寝てyour-filter
実行するのに数秒かかることがあります。your-filter
毎分平均1回の実行が重要な場合はksh
、bash
またはを使用してzsh
次のように変更できます。
t=$SECONDS
while
if [ file.log -ef /dev/stdin ] || ! command exec 3< file.log; then
your-filter
else
(cat; cat <&3) | your-filter &&
exec <&3 3<&-
fi
do
t=$(($t + 60))
sleep "$((t - SECONDS))"
done < file.log
ksh93
と浮動小数点引数を許可するzsh
場合はsleep
実行できますtypeset -F SECONDS
。