3. FreeBSD 10.4 RELEASE - OS 起動後の基本的な設定 - newsyslog

 
 サーバアプリケーションを動作させてしていると、いろいろなログが出力されます。ログはアクセスの解析やセキュリティのチェックのために必要なものですが、ほっておくと徐々に溜まっていき、ディスクスペースを圧迫してきます。  ログが大きくなったタイミングや定期的にログファイルを圧縮したり、世代管理して古いログを削除するために FreeBSD には newsyslog というユーティリティがデフォルトで存在しています。
3.1 newsyslog の仕組み
3.2 newsyslog の記述
3.3 アプリケーションごとのローテーション定義
3.4 記述例
3.5 デバッグ

3.1 newsyslog の仕組み

 もともと、UNIX にはシステムの動きを 1分周期でチェックする cron というデーモンが存在します。  croncrontab という設定ファイルを参照して、やるべき作業を決めます。  FreeBSD には crontab にデフォルトで

# Rotate log files every hour, if necessary.
0   *   *   *   *   root    newsyslog
 という 1行が存在します。  これは、毎時 0 分に newsyslog ユーティリティを動作させる、という意味です。  newsyslog ユーティリティは /etc/newsyslog.conf というファイルを参照して、ログをローテーションさせるかどうかの動きを決定し、処理します。

3.2 newsyslog.conf の記述

 newsyslog.confFreeBSD 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 を調べるために読むファイルを指定します。  このフィールドが存在する場合、このファイルに書かれたプロセス IDsignal_number が送られます。正しく認識するために、このフィールドは "/" から開始する必要があります。  例えば、apache の場合は、ログファイルがローテーションされて rename されても最初につかんだファイルにずっとログを書き続けます。なので、シグナルを送って apache を再起動させる必要がありますので、ここを指定します。  newsyslog は起動されるたびに newsyslog.conf を参照しなおしますので、特に何かを再起動させなくても、newsyslog.conf を書き換えておけば、最短1分後には、反映させることが出来ます。

3.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/ の下に。  それぞれ定義ファイルをおくべきです。

3.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年間分のバックアップファイルを保持するという意味です。  間隔やバックアップファイルの数は、自分の好みに合わせて設定します。

3.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