1. newsyslog の仕組み
もともと、UNIX にはシステムの動きを 1分周期でチェックする cron というデーモンが存在します。
cron は crontab という設定ファイルを参照して、やるべき作業を決めます。
FreeBSD には crontab にデフォルトで
# Rotate log files every hour, if necessary.
0 * * * * root newsyslog
という 1行が存在します。
これは、毎時 0 分に newsyslog ユーティリティを動作させる、という意味です。
newsyslog ユーティリティは /etc/newsyslog.conf というファイルを参照して、ログをローテーションさせるかどうかの動きを決定し、処理します。
2. newsyslog.conf の記述
newsyslog.conf は FreeBSD 10.4 RELEASE のインストール直後、以下のように記述されています。
長ったらしくなりますが、あえてデフォルトのまま、ハイライトもさせずに記述します。
# configuration file for newsyslog
# $FreeBSD: releng/10.4/etc/newsyslog.conf 320229 2017-06-22 07:54:12Z ngie $
#
# Entries which do not specify the '/pid_file' field will cause the
# syslogd process to be signalled when that log file is rotated. This
# action is only appropriate for log files which are written to by the
# syslogd process (ie, files listed in /etc/syslog.conf). If there
# is no process which needs to be signalled when a given log file is
# rotated, then the entry for that file should include the 'N' flag.
#
# The 'flags' field is one or more of the letters: BCDGJNUXZ or a '-'.
#
# Note: some sites will want to select more restrictive protections than the
# defaults. In particular, it may be desirable to switch many of the 644
# entries to 640 or 600. For example, some sites will consider the
# contents of maillog, messages, and lpd-errs to be confidential. In the
# future, these defaults may change to more conservative ones.
#
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
/var/log/all.log 600 7 * @T00 J
/var/log/amd.log 644 7 100 * J
/var/log/auth.log 600 7 100 @0101T JC
/var/log/console.log 600 5 100 * J
/var/log/cron 600 3 100 * JC
/var/log/daily.log 640 7 * @T00 JN
/var/log/debug.log 600 7 100 * JC
/var/log/init.log 644 3 100 * J
/var/log/kerberos.log 600 7 100 * J
/var/log/lpd-errs 644 7 100 * JC
/var/log/maillog 640 7 * @T00 JC
/var/log/messages 644 5 100 @0101T JC
/var/log/monthly.log 640 12 * $M1D0 JN
/var/log/pflog 600 3 100 * JB /var/run/pflogd.pid
/var/log/ppp.log root:network 640 3 100 * JC
/var/log/devd.log 644 3 100 * JC
/var/log/security 600 10 100 * JC
/var/log/sendmail.st 640 10 * 168 BN
/var/log/utx.log 644 3 * @01T05 B
/var/log/weekly.log 640 5 * $W6D0 JN
/var/log/xferlog 600 7 100 * JC
<include> /etc/newsyslog.conf.d/*
<include> /usr/local/etc/newsyslog.conf.d/*
定義を簡単に説明しておきます。
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
↑
ローテーションさせるファイル名です。
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
↑
ログファイルのオーナーユーザ名とグループ名です。
省略可能。
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
↑
ログファイルの、ファイルのパーミッション (owner, group, world に対する read, write, execute 権限) を示します。
chmod で指定するアレです。
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
↑
バックアップファイルのバージョン最大数です。
3 と書いておけば、.0 ~ .3 までのバックアップファイルができることになります。
数が小さいものほど最新のバックアップファイルになります。
最大数を超えたファイルは自動的に削除されます。
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
↑
ファイルがこの値を超える値になったらローテーションさせるということを示しています。
単位は、kb (キロバイト)です。
* を指定しているとサイズのチェックは行いません。
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
↑
いつローテーションさせるかというタイミングの指定です。
指定方法は、多数あります。
* は時間的なタイミングではローテーションしないという意味です。
単に数字を書けば時間を意味し、168 と書けば、168÷24 → 7 ですから、最後にローテーションされた日から1週間後にローテーションさせるという意味です。
@T00 は、毎日午前 0:00 にローテーションさせるという意味です。
@01T05 は、毎日午前 1:05 にローテーションさせるという意味です。
$W6D0 は、毎週土曜日の午前 0:00 にローテーションさせるという意味です。
$M1D0 は、毎月1日の午前 0:00 にローテーションさせるという意味です。
$ で指定するのが便利な使い方で、M を指定すると毎月になりその後に続く数字が日付になります。
W は毎週で、0 が日曜日で 6 の土曜日まで指定できます。
D はその日の時刻で 0 ~ 23 の範囲で指定できます。
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
↑
バックアップファイルの保存形式です。
Z を指定するとバックアップファイルを FreeBSD4.xRELEASE までは gzip で、FreeBSD5.xRELEASE 以降は bzip2 で圧縮します。
B を指定するとバイナリファイルの意味となります。これはバイナリファイルでなくても指定可能です。バイナリファイルで指定していないと、ローテーションさせるときに
Sep 5 00:00:00 ns newsyslog[56463]: logfile turned over
というふうにローテーションさせたことを明示的に書き込みが行われます。
これが書き込まれると後でログの解析で不便になることがある場合は、ASCII ファイルであっても B を指定します。
Z も B も指定したくないときは、"-" を指定します。
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
↑
プロセス ID を調べるために読むファイルを指定します。
このフィールドが存在する場合、このファイルに書かれたプロセス ID に signal_number が送られます。正しく認識するために、このフィールドは "/" から開始する必要があります。
例えば、apache の場合は、ログファイルがローテーションされて rename されても最初につかんだファイルにずっとログを書き続けます。なので、シグナルを送って apache を再起動させる必要がありますので、ここを指定します。
newsyslog は起動されるたびに newsyslog.conf を参照しなおしますので、特に何かを再起動させなくても、newsyslog.conf を書き換えておけば、最短1分後には、反映させることが出来ます。
3. アプリケーションごとのローテーション定義
以前は、newsyslog には include 機能がなかったため、/etc/newsyslog.conf にローテーションの定義をだらだらと書いていましたが。
いつからか(詳細に調べていません)/etc/newsyslog.conf の末尾に
<include> /etc/newsyslog.conf.d/*
<include> /usr/local/etc/newsyslog.conf.d/*
という定義が記述されています。
include 機能が有効になっているので、アプリケーションごとに、ローテーション定義ファイルを作成するべきです。
また、/etc/rc.d で起動される、システムネイティブなアプリケーションは /etc/newsyslog.conf.d/ の下に。
ports で追加したアプリケーションは /usr/local/etc/newsyslog.conf.d/ の下に。
それぞれ定義ファイルをおくべきです。
4. 記述例
apache はどんな風に記述するか、1例を紹介します。
/usr/local/etc/newsyslog.conf.d/apache.conf
を作成して
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
/var/log/httpd-access.log 644 12 * $M1D0 B /var/run/httpd.pid
/var/log/httpd-error.log 644 12 * $M1D0 B /var/run/httpd.pid
と記述します。
意味は、上記の説明でだいたいわかると思いますが、apache の出力する、/var/log/httpd-access.log と /var/log/httpd-error.log の2つのログファイルを、毎月の月初めの午前 0:00 にローテーションさせ、1年間分のバックアップファイルを保持するという意味です。
間隔やバックアップファイルの数は、自分の好みに合わせて設定します。
5. デバッグ
newsyslog にはデバッグ機能があります。
デバッグ機能を利用するとログの設定ファイルを追加したり、変更したりしたときの動作を確認することができます。
-n オプションを使用すると実際にログの入れ換えは行わず、このオプションが指定されない場合に本来行うはずの処理内容を表示します。
-v オプションを使用すると詳細情報出力モードになります。このモードでは、ログを入れ換えるあるいはそれをスキップするたびに、そのログファイル名と理由を表示します。
デフォルトの状態でこの2つを使用すると以下のようになります。
> newsyslog -nv
Processing /etc/newsyslog.conf
Found: <include> /etc/newsyslog.conf.d/*
Found: <include> /usr/local/etc/newsyslog.conf.d/*
/var/log/all.log <7J>: does not exist, skipped.
/var/log/amd.log <7J>: does not exist, skipped.
/var/log/auth.log <7J>: --> will trim at Mon Jan 1 00:00:00 2018
/var/log/console.log <5J>: does not exist, skipped.
/var/log/cron <3J>: size (Kb): 53 [100] --> skipping
/var/log/daily.log <7J>: does not exist, skipped.
/var/log/debug.log <7J>: size (Kb): 1 [100] --> skipping
/var/log/init.log <3J>: does not exist, skipped.
/var/log/kerberos.log <7J>: does not exist, skipped.
/var/log/lpd-errs <7J>: size (Kb): 1 [100] --> skipping
/var/log/maillog <7J>: --> will trim at Tue Oct 17 00:00:00 2017
/var/log/messages <5J>: --> will trim at Mon Jan 1 00:00:00 2018
/var/log/monthly.log <12J>: does not exist, skipped.
/var/log/pflog <3J>: does not exist, skipped.
/var/log/ppp.log <3J>: size (Kb): 1 [100] --> skipping
/var/log/devd.log <3J>: size (Kb): 1 [100] --> skipping
/var/log/security <10J>: size (Kb): 1 [100] --> skipping
/var/log/sendmail.st <10>: age (hr): 10 [168] --> skipping
/var/log/utx.log <3>: --> will trim at Wed Nov 1 05:00:00 2017
/var/log/weekly.log <5J>: does not exist, skipped.
/var/log/xferlog <7J>: size (Kb): 1 [100] --> skipping