【logrotate講座 第5回】再起動を自動化せよ!postrotateスクリプトによるプロセス制御とsharedscriptsの魔力

「ファイル名を変えて終わり」ではない。

こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回までは、ログファイルの圧縮や日付付与など、ファイルそのものの扱いについて学んできました。

しかし、logrotateの仕事は「ファイルをいじる」だけではありません。
最も重要な仕事は、「ログファイルが変わったことを、アプリケーションに教えてあげること」です。

第3回で学んだ通り、Linuxのプログラムはファイル名ではなく「iノード」を見ています。
そのため、logrotateが裏でこっそりファイル名を変えたり新しいファイルを作ったりしても、ApacheやMySQLなどのアプリケーションはそれに気づかず、古いファイルに書き込み続けてしまいます。
これを正すために必要なのが、「サービスの再読み込み(リロード)」です。

コウ君

先生、質問です!
postrotate ってところに systemctl reload httpd って書いてあるのは知ってるんですが、これって具体的に何をしてるんですか?
あと、ログファイルが10個くらいある設定ファイルを書いたら、サーバーが10回再起動しちゃって怒られました…。
どうすればいいんですか?

リナックス先生

コウ君、それは sharedscripts を書き忘れた典型的な失敗例ね。
logrotateは強力なシェルスクリプト実行機能を持っているけれど、正しい書き方を知らないと、サーバーに無駄な負荷をかけたり、最悪の場合はサービスを停止させてしまうの。
今回は、logrotateの中から外部コマンドを操る「スクリプト機能」をマスターしましょう!

本記事では、AlmaLinux 9 をベースに、postrotate / prerotate の使い分け、サービスの正しいリロード方法、そして初心者が必ずハマる sharedscripts の仕組みについて徹底解説します。

🔄 logrotate完全攻略講座(バックナンバー)

現在地:【第5回】再起動を自動化せよ!postrotateスクリプトによるプロセス制御


第1章:スクリプトフックの基礎 (postrotate / prerotate)

logrotateの設定ファイルには、ローテーション処理の「直前」と「直後」に、任意のシェルスクリプト(Linuxコマンド)を実行する機能があります。

1. postrotate (ローテーション後)

最もよく使われます。ログファイルがリネームされ、新しい空ファイルが作られたに実行されます。
主な用途は、アプリケーションへの「再読み込みシグナル」の送信です。

postrotate
    # ここにコマンドを書く
    /usr/bin/systemctl reload httpd
endscript

2. prerotate (ローテーション前)

ログファイルがリネームされるに実行されます。
主な用途は、特殊な属性(chattr)を一時的に解除したり、ローテーション前に何らかのチェックを行ったりする場合です。

prerotate
    # ログファイルの保護属性を解除するなど
    /usr/bin/chattr -a /var/log/myapp.log
endscript

第2章:なぜ「restart」ではなく「reload」なのか?

postrotate の中で、サービスを再起動するコマンドを書く際、多くの人が悩みます。
systemctl restart にすべきか? reload にすべきか?」

結論:絶対に「reload」を使うべき

  • restart (再起動): プロセスを完全に停止(kill)させてから、再度起動します。その間、Webサイトは閲覧不能になり、接続中のユーザーは切断されます。ログローテートごときにサービス停止を伴うのは悪手です。
  • reload (再読み込み): プロセスを停止させず、設定ファイルの再読み込みやログファイルの掴み直し(Reopen)だけを行います。ユーザーへの影響はゼロです。

シグナル送信の仕組み (kill -HUP)

昔ながらの書き方では、kill -HUP [プロセスID] というコマンドが見られます。
HUP (Hangup) シグナルは、多くのデーモンプロセスにおいて「設定再読み込み&ログ再オープン」の合図として実装されています。
systemctl reload は、裏側でこのシグナル送信を行っています。


第3章:【最重要】sharedscripts の魔力と罠

ここが今回のハイライトです。
ワイルドカード(*.log)を使って複数のログファイルを指定した場合、スクリプトはどう動くのでしょうか?

sharedscripts なし(デフォルト)の挙動

/var/log/httpd/*.log {
    postrotate
        systemctl reload httpd
    endscript
}

もし /var/log/httpd/ にログファイルが10個あった場合、logrotateは以下の動作をします。

  1. access.log をローテート → httpdをリロード
  2. error.log をローテート → httpdをリロード
  3. ssl_access.log をローテート → httpdをリロード
  4. … (以下10回繰り返し)

結果: Apacheが短時間に10回もリロードされ、CPU負荷が急上昇し、処理が詰まる可能性があります。

sharedscripts ありの挙動

これを防ぐのが sharedscripts オプションです。

/var/log/httpd/*.log {
    sharedscripts   # <--- これを追加!
    postrotate
        systemctl reload httpd
    endscript
}

これを書くと、logrotateはまず対象の10個のログファイルをすべてリネーム・作成し終わるまで待ちます。
そして最後に1回だけスクリプトを実行します。

  1. 全ログファイルをローテート処理
  2. httpdをリロード (1回のみ)

⚠️ 注意点
複数のログファイルを指定する場合(ワイルドカードや複数行指定)、アプリケーションのリロードコマンドを書くなら sharedscripts は必須と考えてください。
逆に、chmod などファイル個別に実行したい処理がある場合は記述してはいけません。


第4章:主要ミドルウェアのリロードコマンド集

AlmaLinux 9 (RHEL 9) 環境における、主要なミドルウェアの推奨リロードコマンドを紹介します。

Apache (httpd)

    postrotate
        /usr/bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
    endscript

> /dev/null 2>/dev/null は画面(メール)への出力を捨てるため、|| true は万が一リロードに失敗してもlogrotate自体をエラー終了させないためのおまじないです。

Nginx

NginxはPIDファイルを使ってシグナルを送るのが一般的です。

    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript

USR1 シグナルが「ログファイルの再オープン」を意味します。

MariaDB / MySQL

DBは mysqladmin flush-logs コマンドを使います。

    postrotate
        /usr/bin/mysqladmin ping && /usr/bin/mysqladmin flush-logs
    endscript

※認証情報(パスワード)の設定が別途必要になる場合があります(/root/.my.cnf など)。


第5章:応用テクニック(外部通知と連携)

postrotate に書けるのはリロードコマンドだけではありません。
任意のシェルスクリプトが書けるので、運用の自動化に活用できます。

例1:ローテーション完了をSlackに通知する

curl コマンドを使って、Webhook URLを叩くことができます。

    postrotate
        /usr/bin/systemctl reload httpd
        /usr/bin/curl -X POST -H 'Content-type: application/json' \
        --data '{"text":"Apacheのログローテーションが完了しました。"}' \
        https://hooks.slack.com/services/YOUR/WEBHOOK/URL
    endscript

例2:古いログを別のディレクトリに移動する

圧縮されたログをバックアップ用ディレクトリに退避させます。

    lastaction
        mv /var/log/httpd/*.gz /backup/logs/
    endscript

lastactionpostrotate のさらに後、圧縮処理などが完全に終わった最後に実行されるブロックです。


第6章:トラブルシューティング「スクリプトエラー」

スクリプト部分でエラーが起きると、logrotateは処理を中断し、エラーメールをroot宛に送信します。

よくあるエラー1:パスが通っていない

logrotateを実行するcron環境では、環境変数 PATH が最小限になっていることがあります。
systemctlmysqladmin などを書くときは、必ずフルパス(/usr/bin/systemctl)で書く癖をつけましょう。

よくあるエラー2:SELinuxによるブロック

第7回で詳しく解説しますが、logrotateから実行されたスクリプトが、SELinuxのポリシー違反でブロックされることがあります。
「手動でコマンドを叩くと動くのに、logrotate経由だと動かない」場合は、ほぼSELinuxが原因です。


まとめ:スクリプトを制する者はログを制す

お疲れ様でした!
postrotatesharedscripts の仕組みを理解したことで、安全かつ効率的なログ管理ができるようになりました。

今回の重要ポイント:

  • create モードを使うなら、postrotate でのリロードは必須。
  • systemctl reload はサービスを止めずにログを掴み直す。
  • 複数のログを対象にするなら sharedscripts を必ず書く。
  • コマンドはフルパスで記述し、|| true でエラー対策をする。

しかし、スクリプトが正しく書けていても、ログファイルが出力される「ディレクトリの権限」「所有者」の設定を間違えると、ローテーション時にエラーが発生します。
特に、Webサーバーとログ管理者が別ユーザーの場合など、権限周りのトラブルは絶えません。

次回、第6回は「権限トラブルを回避する!ユーザー指定とACL、出力先ディレクトリの管理」です。
su ディレクティブを使ったユーザー切り替えや、create モードでのパーミッション設定など、Linuxの権限管理とlogrotateの深い関係を解説します。
「Permission denied」のエラー画面とはもうサヨナラしましょう。お楽しみに!

▼ スクリプト自動化を実験する ▼

安全な検証環境を作る
「VPS」で自分専用環境

おすすめVPSを見る

Linux自動化スキルを年収に
「ITエンジニア転職」

転職エージェントを見る

コメント