メニュー 閉じる

DebianでlogrotateをdateextにするとLogwatchでログが収集されない

環境

  • Debian 10 buster
  • Logwatchのバージョンどっち…
    • logwatch --version
      Logwatch 7.4.3 (released 04/27/16)
    • apt info logwatch
      Version: 7.5.0-1
  • logrotate --version
    logrotate 3.14.0

事象

  • /etc/logrotate.conf等々の設定ファイルでdateextを有効にしていると、Logwatchが(ほとんど)レポートを出力しない

検証

今の状況

logwatchを標準出力にレポートさせると、以下の様になります。

# logwatch --output stdout

 ################### Logwatch 7.4.3 (04/27/16) #################### 
..(snip)..
 ##################################################################

 --------------------- Disk Space Begin ------------------------ 
..(snip)..
 ---------------------- Disk Space End ------------------------- 

 ###################### Logwatch End ######################### 

普段なら色々出力されるはずが、Disk Spaceの部分しかレポートされていません…

設定ファイルを置いてみる

原因が分からないので、とりあえず/etc/logwatch/conf/logfiles/ディレクトリに、/usr/share/logwatch/default.conf/logfiles/ディレクトリにある設定ファイル(例えば今回の場合maillog.conf)をコピーして配置します。

# cp /usr/share/logwatch/default.conf/logfiles/maillog.conf /etc/logwatch/conf/logfiles/
# ls /etc/logwatch/conf/logfiles/ maillog.conf

この状態でlogwatchを回してみましょう。

# logwatch --output stdout

 ################### Logwatch 7.4.3 (04/27/16) #################### 
..(snip)..
 ##################################################################

 --------------------- Postfix Begin ------------------------ 
..(snip)..
 ---------------------- Postfix End -------------------------

 --------------------- Disk Space Begin ------------------------ 
..(snip)..
 ---------------------- Disk Space End ------------------------- 

 ###################### Logwatch End ######################### 

と、このようにPostfixサービスがレポートされました。

ちなみに、default.confの中の設定ファイルはlogwatchが標準で読み込んでいる設定ファイルなので、本来あえて/etc/logwatch配下にファイルをコピーする必要はないはず。
ですから、設定ファイルをコピーしないとレポートされないというのはおかしいのです。

デバッグ出力を見てみる

一旦先ほど作成した、/etc/logwatch/conf/logfiles/maillog.confを削除します。
その後、--debugパラメータでどのような処理をしているか追ってみます。

# logwatch --output stdout --debug High

デバッグ出力が長いので省略しますが、次のような出力がみられました。

  • ReadConfigFile: Opening /usr/share/logwatch/default.conf/logfiles/maillog.conf
  • ReadConfigFile: Opening /usr/share/logwatch/dist.conf/logfiles/maillog.conf

default.confディレクトリの他に、dist.confディレクトリからも設定ファイルを読み込んでいるようです。

設定ファイルを見てみる

それぞれの設定ファイルを確認してみます。

##########################################################################
# $Id$
##########################################################################

########################################################
# This was written and is maintained by:
# Kenneth Porter <shiva@well.com>
#
# Please send all comments, suggestions, bug reports,
# etc, to shiva@well.com.
########################################################

# What actual file? Defaults to LogPath if not absolute path....
LogFile = maillog
LogFile = syslog
LogFile = mail.log
LogFile = mail.log.0
LogFile = mail

# If the archives are searched, here is one or more line
# (optionally containing wildcards) that tell where they are...
#If you use a "-" in naming add that as well -mgt
Archive = maillog.*
Archive = maillog-*
Archive = syslog.*
Archive = syslog-*
Archive = archiv/maillog.*
Archive = archiv/maillog-*
Archive = mail.log.*.gz
Archive = mail.log-*.gz
Archive = mail-*

# Expand the repeats (actually just removes them now)
*ExpandRepeats

# Keep only the lines in the proper date range...
*ApplyStdDate

# vi: shiftwidth=3 tabstop=3 et
# Note that we have to override the default logwatch configuration,
# because in Debian, syslog receives the same messages as mail.log,
# so we would otherwise report each event twice
LogFile =
LogFile = mail.log
LogFile = mail.log.0
LogFile = mail.log.1

Archive =
Archive = mail.log.*.gz

/usr/share/logwatch/dist.conf/logfiles/maillog.confの4, 9行目にLogFile =Archive =という行が存在しますね。

マニュアルが/usr/share/doc/logwatch/HOWTO-Customize-LogWatch.gzにあるのでzlessします。

   In general, setting a variable overrides any value previously set.
   However, the following variables are cumulative:
   - In logwatch.conf:              LogFile, Service
   - In services/service_name.conf: LogFile
   - In logfiles/service_name.conf: LogFile, Archive

   To remove all previous declarations of that variable, set the
   variable to the empty string.  Duplicate values in the cumulative
   variables are deleted.

意訳すると、

変数は上書きされるけど、LogFileServiceArchive変数は累積するから、それを消したければ空文字列を代入してね

ということで、dist.conf/logfiles/maillogの方ではdefault.conf/logfiles/maillogLogFile変数とArchive変数をリセットして、mail.logmail.log.0というファイル名のみをログファイルとして指定していることが分かりました。
しかし、mail.log.0はlogrotateでdateextしていない場合のファイル名で、dateextしている場合はmail.log-YYYYMMDDのファイル名なんですよねぇ(標準では)。

とりあえずこのままでは、古いログファイルを読んでくれないのがわかりました。

<参考>dist.confディレクトリについて

dist.confディレクトリは、OS(この場合Debian)の方で用意している設定ファイルが保存されているディレクトリです。
以下の様にマニュアルに記載されています。

The directory /usr/share/logwatch contains both the configuration
and (perl) executable files.  The contents of this directory are
the following subdirectories:

        default.conf:   Contains the default configuration files
                        shipped with the Logwatch distribution

        dist.conf:      Contains the configuration files shipped
                        with your specific Operating Systems
                        distribution.

logwatchの実行されるタイミング

mail.logは読めているはずなのに、レポートが出力されないのは何故でしょうか。

おもむろに/etc/cron.dailyディレクトリを覗いてみます。

$ ls -l /etc/cron.daily/
00logwatch  apt-compat    chkrootkit  logrotate  passwd
apache2     bsdmainutils  dpkg        man-db     sysstat

/etc/cron.dailyディレクトリを参照すると00logwatchというスクリプトがあり、日次処理の一番最初にlogwatchが実行されることが分かりますね。

そして、同ディレクトリにlogrotateというスクリプトが存在するので、logwatchが実行された後にログローテーションされてそうです。
もしそうだとすると、logwatchがmail.log-YYYYMMDDは読めなくてもmail.logを読んで前日分のレポートを出力されても良いはずです。
# なおDebianの場合、cron.dailyは毎朝6時半頃に実行されるため、もし上記の想定が正しかったとしてもmail.logに含まれるのは6時半頃以降のログだけです。

ログローテーションされるタイミング

実は、Debian 10 Busterではログローテーションにcron.dailyを使っていなかったのです。

logrotateは、あたかもcron.dailyで他の日次処理と同様に動いているかのように見えます。
しかしlogrotateスクリプトの中を見ると、

#!/bin/sh

# skip in favour of systemd timer
if [ -d /run/systemd/system ]; then
    exit 0
fi

..(snip)..

とあるように、loglotateスクリプトはsystemd環境下では何も処理していません。

実際には、logrotate.timerというsystemdのunitが、毎日0:00に処理を実施しています。

# systemctl list-timers logrotate.timer
NEXT                         LEFT    LAST                         PASSED  UNIT            ACTIVATES
Sun 2020-03-01 00:00:00 JST  8h left Sat 2020-02-29 00:00:01 JST  15h ago logrotate.timer logrotate.service

1 timers listed.

つまり、logwatchが実行される前にログがローテーションされてしまい、mail.logには当日分のログしか残っていなかったのです。

ログファイルが読まれない原因

まとめると、

  • mail.log-YYYYMMDDが読まれないのは、Debianが用意した設定ファイルにログファイル名が含まれていないから
  • mail.logの前日分のログが読まれないのは、logwatchが実行される前にログローテーションされるから

でした。

解決策

dist.confディレクトリを読まないようにしましょう。
そもそも、default.confディレクトリにある設定ファイルで十分だったのです。
そこにあるのは、logwatchが多種多様な環境でログが読めるように、使われていないパターンも含む冗長な書き方の設定ファイルですが、それでいいのです。
逆にdist.confではログローテーションの設定によっては、正常にログを読めなくなってしまうのですから。

方針は決まりました。

# cd /usr/share/logwatch
# ls
default.conf  dist.conf  lib  scripts
# mv dist.conf dist.conf.bak
# ls
default.conf  dist.conf.bak  lib  scripts

この状態でlogwatchを回してみると、これまで出力されなかった各種サービスのレポートが見られるようになります。

コメントを残す