印刷用表示へ切り替え 通常表示へ切り替え 更新履歴を表示 更新履歴を隠す
Linux logrotate の動作がおかしい

logrotate を使って Apache のログファイルを月単位でまとめているのだが,バージョンアップをしてから動作がおかしくなった (logrotate 3.7.4)。後処理用のシェルが変数を展開しないのである。

■ ■ ■

このサイトでは,Apache のログファイルを logrotate を使って月単位でまとめている。先日,OS を Vine Linux 3.2 から 4.1 に変更したところ,そのときから動作がおかしくなったのである。Vine Linux 3.2 のときは正常に動作していた (nlog(n): Apache のログを月別に保存したい)。

Vine Linux 3.2 のときは logrotate 3.6.8,現在は Vine Linux 4.1 で logrotate 3.7.4 (logrotate-3.7.4-1vl1) である。logrotate はマイナーバージョンアップされている。

/etc/logrotate.d/apache2 の内容は次の通り。

/var/log/apache2/*/*_log {
    monthly
    missingok
    postrotate
        /bin/kill -HUP `cat /var/run/apache2.pid 2>/dev/null` 2> /dev/null || true
        EXT=`date -d '1 day ago' +%Y%m`
        for F in $1;
          do mv $F.1 $F.$EXT
        done
    endscript
}

1か月に1度ローテートし,ファイル名が access_log から access_log.1 に変更されるので,後処理で access_log.1 を access_log.200710 などのように年月をつけたファイル名に変更するというものである。

ローテートのステータスは /var/lib/logrotate.status に次のような形で記述されている。次のローテートは 2007-12-1 の予定となっている。

"/var/log/apache2/nlogn/access_log" 2007-11-1
"/var/log/apache2/nlogn/error_log" 2007-11-1
"/var/log/apache2/nlogn/ssl_request_log" 2007-11-1

さて,この設定で前回は11月1日に処理がされたのだが,思惑通りに動作していない。access_log.200710 というファイル名になるはずなのだが,access_log.1 となってしまっている。どうやら postrotate ... endscript 間の処理において,apache2 の再起動はされているが,その後のシェルスクリプトが動作していないようだ。

対処法としては,/var/log/apache2/*/*_log をアスタリスクなしで書くことなのだが,バーチャルサーバを立てまくっているおかげでファイル数が多く,やっていられない。

仕方がないので,シェルスクリプトを書いて月に1度だけ手動で処理することにする。上記の logrotate 用のファイルから一部抜き出したものである。ファイル名を logrotmp.sh などとしておく。

#!/bin/sh
EXT=`date -d '15 day ago' +%Y%m`
for F in /var/log/apache2/*/*_log;
  do mv $F.1 $F.$EXT
done

注意すべきは,date コマンドに与える日付の数値である。今日は11月12日なので,13日より以前を指定する必要がある。日付を引いたときに先月になるような数値ならよいので,ここでは15を設定した。

まずはテスト。一般ユーザで行う。構文のチェックと変数展開のチェックをするように sh に -xv オプションをつける (nlog(n): Apache のログファイルを月別に分割したい)。

$ sh -xv logrotmp.sh
which () {  {
 alias;
 declare -f
 } | /usr/bin/which --tty-only --read-alias --read-functions --show-dot --show-tilde ${1+"$@"}
}
ls () {  /bin/ls --color=tty ${1+"$@"}
}
#!/bin/sh
EXT=`date -d '15 day ago' +%Y%m`
date -d '15 day ago' +%Y%m
++ date -d '15 day ago' +%Y%m
+ EXT=200710
for F in /var/log/apache2/*/*_log;
  do mv $F.1 $F.$EXT
done
+ mv '/var/log/apache2/*/*_log.1' '/var/log/apache2/*/*_log.200710'
mv: `/var/log/apache2/*/*_log.200710' にアクセス中: 許可がありません

上手くいっているようなので,root になって実行。

# sh logrotmp.sh

このスクリプトを logrotate 用に書き換えて登録しておけば完全に自動化はできるが,気持ちが悪いのでパス。月に1度コマンドを打つくらいはやるか。あとは logrotate のフィックスを待つことにしよう。もし,仕様が変わってこの動作が正常なら,上記のスクリプトを logrotate 用に書き換えて登録である。

Posted by n at 2007-11-12 22:06 | Edit | Comments (0) | Trackback(0)
Trackbacks

  • 「手違いで複数トラックバックを送ってしまった!」という場合でも気にしないでください (重複分はこちらで勝手に削除させていただきます)
  • タイムアウトエラーは,こちらのサーバの処理能力不足が原因です (詳細は トラックバック送信時のエラー をご覧ください)
  • トラックバックする記事には,この記事へのリンクを含めてください(詳細は 迷惑トラックバック対策 をご覧ください)
Comments
Post a comment
  • 電子メールアドレスは必須ですが,表示されません (気になる場合は「メールアドレスのような」文字列でもOKです)
  • URL を入力した場合はリンクが張られます
  • コメント欄内ではタグは使えません
  • コメント欄内に URL を記入した場合は自動的にリンクに変換されます
  • コメント欄内の改行はそのまま改行となります
  • 「Confirmation Code」に表示されている数字を入力してください (迷惑コメント対策です)


(必須, 表示されます)


(必須, 表示されません)


(任意, リンクされます)


Confirmation Code (必須)


Remember info (R)?