Nginxログをローテーションする適切な方法


12

私はnginxログのローテーションを達成したい:

  1. 余分なソフトウェアなしで動作します(つまり、「logrotate」がなければ最適)
  2. 日付に基づいた名前で回転したファイルを作成します

最良のアプローチはPostgreSQLのようなものです。つまり、log_filename構成変数でstrftimeスタイルの%Y-%m-%dを指定でき、ログは日付(または時刻)の変更を自動的に変更します。

Apacheからの別のアプローチ-パイプを介してrotatelogsプログラムにログを送信します。

私が検索できる限り-そのようなアプローチは存在しません。私ができることは、dateextオプションを指定してlogrotateを使用することだけですが、独自の欠点があり、PostgreSQLで| rotatelogsまたはlog_filenameのように機能するものを使用したいのです。


このブログ記事では、問題の解決策について説明しています。しかし、質問があります:なぜlogrotateを使用したくないのですか?これは非常にうまく機能し、依存関係はほとんどなく、動作することが証明されています(必要に応じて戦闘強化)。logrotateを使用できる場合(そのマシン上で他のログをローテーションする場合にも役立つかもしれません)、なぜフープを飛び越えて、劣悪でエラーが発生しやすい自家製のソリューションを使用するのですか?
joschi

logrotate(dateextを使用)はほぼ機能しますが、cronを介して実行する必要があるため、気に入らず、これにはいくつかの欠点があります。

nginxは他のプログラムへのログのパイピングをサポートしておらず、ログのローテーション自体もサポートしていないため、cronベースのアプローチが気に入らないため、必要なものが得られない場合があります。ときどき「ほぼ動作する」ことは、それが得るほど良いです。;)もちろん、自分でnginxにパッチを適用したい場合を除きます。
joschi

回答:


7

謙虚な名前付きパイプが味方であるか敵であるかで世界は分かれていますが、それはおそらくあなたの問題に対する最も簡単な解決策です。いくつかの欠点があります(事前にパイプを作成する必要があります)が、cronが不要になり、選択したロギングパイプフィルターを使用できるようになります。

cronolog onを使用した例を次に示しますaccess.log

  1. 名前付きパイプのパスを選択します。ログインを保持するつもりな/var/log/nginxので、そこにもパイプを配置します。名前はあなた次第です。私が追加し.fifo、それはaccess.log、だから私のものになります/var/log/nginx/access.log.fifo
  2. ファイルが存在する場合は削除します。
  3. ログファイルの名前付きパイプを作成します。

    mkfifo /var/log/nginx/access.log.fifo
    
  4. 作成nginx.confしたパイプでログを指すように構成します。

    access_log /var/log/nginx/access.log.fifo;
    
  5. サーバーを起動するに、init.dスクリプトを変更して、パイプをリッスンするログローテーターを起動します。

    LOGS="/var/log/nginx"
    pkill -f "/usr/sbin/cronolog --symlink $LOGS/access.log"
    ( cat $LOGS/access.log.fifo | /usr/sbin/cronolog --symlink $LOGS/access.log "$LOGS/%Y/%m/%d/access.log" ) &
    

    rotatelogs好みに応じて同様のコマンドラインを使用しcronologます。構文についてはドキュメントを参照してください。

    ディストリビューションにがある場合は、start-stop-daemon代わりにそれを使用する必要がありpkillます。理論的にはプラットフォームに関する特別な知識があり、あなたの面倒を見てくれます。単にコマンドをスクリプトでラップし、それを--execに渡しstart-stop-daemonますinit.d/nginx


cronologが大好きです。より多くの人がそれを使用/推奨しているのを見るのは良いことです。
ナタカド

1

ログ行がプログラムによって表示される現在のシステム時刻とは対照的に、ログに記録された日付に基づいて一般的なログを分割する単純なプログラム、datelogを作成しました。これは、cronologや別のログスプリッターがすでに行っていることとまったく異なる場合がありますが、他のユーザーが何をするかを見つけるよりも自分で書く方が迅速でした。

ログに記録された要求の年と月を使用して、ログに記録されたデータから計算されたYYYYMMを含むファイルまたはパイプに行が書き込まれます。はい、これは一般的なログ形式にある程度特有です。最初の[は、日付を区切ると見なされます。IPv6アドレスに注意してください。:)

ログ分析では、各ログに実際に各月のリクエストのみが含まれることが重要であり、各ログは正しい分析結果を得るために理想的に完全である必要があります。23:59:59に開始される遅い要求は、間違った月のログファイルに記録されるため、ログスプリッター内の現在の時間に基づいてファイル名を決定するだけでは不十分です。

これは、nginxが開始される前に存在することが確認される名前付きfifoを介して、nginxで使用します。エラー検出とバッファリングされた出力の間にはトレードオフがあることに注意してください。datelogは現在、パフォーマンス上の理由からバッファリングされた出力を好むので、ログデータを失わないように、特にシェルパイプを使用する場合、セットアップが実際に機能することを確認してください。

ソースコード:http : //stuge.se/datelog.c

フィードバックやもちろんパッチを送ってください!


1

これは、単純なbashスクリプトとcronを使用して実現できます。

#!/bin/bash
DATE=$(date +%Y-%m-%d-%H%M)
mv /var/log/nginx/access.log /var/log/nginx/nginx.access.log.$DATE
mv /var/log/nginx/error.log /var/log/nginx/nginx_error.log.$DATE
kill -USR1 `cat /var/run/nginx.pid`
sleep 1
gzip /var/log/nginx/access.log.$DATE
gzip /var/log/nginx/error.log.$DATE

crontabなどの設定の詳細については、Cronを介したNginxログファイルの回転を参照してください。


0

私はあなたの質問を本当に理解していないのではないかと思います:nginxは組み込みのlogrotationをサポートしていないので、あなたは次のようなことをしなければなりません

mv access.log access.log.$(date "+%Y-%m%d")
kill -USR1 $(cat master.nginx.pid)

/etc/cron.dailyのどこかに(もちろん、上記のファイル名をフルパス名で修飾する必要があります)、または、apache2ユーティリティをインストールして、rotatelogsにアクセスします。


これは、logrotateでできることと同じです。そして、私はそれをもっと良くしたい。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.