Log4jを使用し、独自のログを毎日ローテーションするJavaアプリケーションがあります。
/var/log/foo/foo.log
です/var/log/foo/foo.log.YYYY-MM-dd
に移動します設定を変更したくない...
ただし、次のことを行います。
両方を実行するcronジョブを作成することは難しくありませんが、logrotate
...のフレームワークに留まることをお勧めします。
次の/etc/logrotate.d/foo
を作成します。
/var/log/foo/foo.log.* {
daily
rotate 2
compress
delaycompress
missingok
notifempty
}
しかしそれは何もしません:
reading config file /etc/logrotate.d/foo
Handling 1 logs
rotating pattern: /var/log/foo/foo.log.* after 1 days (2 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/foo/foo.log.2017-06-28
log does not need rotating
considering log /var/log/foo/foo.log.2017-06-29
log does not need rotating
considering log /var/log/foo/foo.log.2017-06-30
log does not need rotating
considering log /var/log/foo/foo.log.2017-07-01
log does not need rotating
considering log /var/log/foo/foo.log.2017-07-02
log does not need rotating
considering log /var/log/foo/foo.log.2017-07-03
log does not need rotating
considering log /var/log/foo/foo.log.2017-07-04
log does not need rotating
ファイルの総数が2を超えた場合、ファイルを圧縮して最も古いファイルを削除するにはどうすればよいですか?
アプリチームはログとファイル名の形式、およびlog4jを使用したローテーションスケジュールの制御を維持する必要があるため、この動作を実行する必要がありました。 man logrotate
を読むと、すべての事前/事後/最終アクションスクリプトは、少なくとも1つのログがローテーションされた場合にのみ実行されることがわかります。したがって、size 999G
などの到達不能なものを設定しても機能しません。
代わりに、次のようにcopy
およびextension
オプションを設定しました。
/var/log/<service>/<service>.log {
copy # don't touch the orig. log file, it's managed by log4j
extension .log # End rotated files in ".log" so we can find and delete them
rotate 1
hourly
missingok
prerotate
find /var/log/<service>/ -iname "*service.log.*" ! -iname "*.gz" -exec gzip {} \; && \
aws s3 sync /var/log/<service>/ s3://<bucket>/<environment>/<ec2_id>/<service>/ --exclude "*" --include "*<service>*.gz" && \
find /var/log/<service>/ -iname "*<service>.log.*" -mtime +7 -delete
endscript
lastaction
find /var/log/<service>/ -iname "*<service>.*.log" -delete
endscript
}
はい、cronジョブを作成することができます。 logrotate
を使用する理由は、すべてのログローテーション構成管理を単一のAnsibleロールに保持することです。将来的には、log4j
ローテーションを無効にし、代わりにlogrotate
を使用するようにします。変化する。
いくつかの外部コマンドなしでlogrotate
を使用して必要なことを実行できるとは思えません。また、パターン/var/log/foo/foo.log.*
は、ローテーションされる一連のファイルとしてではなく、ローテーションされる個別のログであるかのように各ファイルを扱います。
man logrotate
ワイルドカードは注意して使用してください。 *を指定すると、logrotateは、以前にローテーションされたファイルを含め、すべてのファイルをローテーションします。
とにかく、おそらくこのようなものですか? log4jがすでにローテーションを部分的に処理しているため、到達しないローテーション条件を設定するだけです。次に、残りをprerotate
スクリプトに入れますか?
/var/log/foo/foo.log {
size 100G # something big that will never be reached/rotated since log4j does this.
missingok
notifempty
# delete the other logs over 7 days old
prerotate
find /var/log/foo/ -name 'foo.log.*' -mtime +7 -delete
Nice gzip /var/log/foo/foo.log.*
endscript
}
Log4jローリングファイルアペンダーとlogrotateには互換性がありません。 log4jローテーションは、logrotateに干渉します。
まず、アプリケーションのlog4j構成ファイルを見つけ、ローリングファイルアペンダーを単純なファイルアペンダーに置き換える必要があります。これにより、log4jによるファイルのローテーションが停止します。次に、logrotateを使用して、必要に応じてログファイルをローテーションできます。
アプリケーションのlog4j構成を変更できない場合は、独自のlog4j構成を作成し、アプリケーションが開始されたときにクラスパスでこれを指定できます。
-Dlog4j.configurationFile=path/to/log4j2.xml
参照: https://logging.Apache.org/log4j/2.0/faq.html#config_location