syslogメカニズムを使用する Linux 上のアプリケーションがあります。このアプリケーションの実行速度が予想よりも遅い理由を突き止めるために 1 週間費やした後、syslog を削除してログ ファイルに直接書き込むだけで、パフォーマンスが劇的に向上することがわかりました。
syslog がファイルへの直接書き込みよりも遅い理由を理解しています。しかし、私は疑問に思っていました: パフォーマンスを最適化するために syslog を構成する方法はありますか?
構成ファイルのログ ファイル パスに「-」を追加することで、ログ メッセージの後にログ ファイルを同期しないように syslogd (および少なくとも rsyslog) を構成できます。これにより、クラッシュでログ メッセージが失われる可能性があるという危険性を犠牲にして、パフォーマンスが高速化されます。
syslog のパフォーマンスを改善するには、いくつかのオプションがあります。
マクロを使用して呼び出しを最適化する
int LogMask = LOG_UPTO(LOG_WARNING);
#define syslog(a, ...) if ((a) & LogMask ) syslog((a), __VA_ARGS__)
int main(int argc, char **argv)
{
LogMask = setlogmask(LOG_UPTO(LOG_WARNING));
...
}
マクロを使用して syslog 呼び出しをフィルタリングする利点は、呼び出し全体がグローバル変数の条件付きジャンプに削減されることです。これは、他の関数を介して大きなデータセットを変換する DEBUG 呼び出しが発生した場合に非常に役立ちます。
setlogmask()
setlogmask(LOG_UPTO(LOG_LEVEL))
setlogmask() は /dev/log にログを記録しないことで呼び出しを最適化しますが、プログラムは引き続き引数として使用される関数を呼び出します。
syslog.conf によるフィルタリング
*.err /var/log/messages
詳細については、syslog.conf のマニュアル ページを参照してください。
syslog を設定して、非同期またはバッファ ロギングを行う
ログ出力をバッファリングし、ブロック単位でフラッシュするために使用されるメタログ。私の知る限り、在庫のsyslogとsyslog-ngはこれを行いません。
新しいデーモンの作成に着手する前に、syslog-ngが単純な古い syslog よりも高速である (または高速になるように構成できる) かどうかを確認できます。
ソースをロギング アプリケーションに制御する場合に使用できる 1 つのトリックは、syslog.conf ではなく、アプリケーション自体で必要なログ レベルをマスクすることです。私は何年も前に、膨大な量のデバッグ ログを生成するアプリでこれを行いました。プロダクション コードから呼び出しを削除するのではなく、デバッグ レベルの呼び出しがデーモンに送信されないようにマスキングしました。私は実際にコードを見つけました。これはPerlですが、setlogmask(3)呼び出しの前にあるだけです。
use Sys::Syslog;
# Start system logging
# setlogmask controls what levels we're going to let get through. If we mask
# them off here, then the syslog daemon doesn't need to be concerned by them
# 1 = emerg
# 2 = alert
# 4 = crit
# 8 = err
# 16 = warning
# 32 = notice
# 64 = info
# 128 = debug
Sys::Syslog::setlogsock('unix');
openlog($myname,'pid,cons,nowait','mail');
setlogmask(127); # allow everything but debug
#setlogmask(255); # everything
syslog('debug',"syslog opened");
ビットマスクの代わりに 10 進数を使用した理由がわかりません... 肩をすくめる
ログファイルへのパスの前にマイナスを付けることで、syslogd のレベル (またはファシリティ) を非同期的にログに記録するように設定できます (例: user.* [tab] -/var/log/user.log)。
乾杯。
独自の syslog 実装を記述します。:-P
これには 2 つの方法があります。
LD_PRELOAD
フックを作成して syslog 関数をオーバーライドし、stderr
代わりに出力するようにします。私は実際にこれについて何年も前に投稿を書きました: http://marc.info/?m=97175526803720 :-P/dev/log
。:-Pわかりました、わかりました、これらはどちらも面白い答えです。syslogd
それが最も詰まっている場所を確認するためにプロファイリングしましたか?
syslog-async() の実装が役立つ場合がありますが、ログ行が失われるリスクや、別の時点で制限された遅延が発生するリスクがあります。 http://thekelleys.org.uk/syslog-async/
注:ここでの「非同期」は、アプリケーション内のログイベントのキューイングを指し、他の回答が参照する非同期syslogd出力ファイル構成オプションではありません。