毎日/毎週のログを自動ローテーション|logrotate設定と圧縮・保管(コピペ可)

ログ運用・解析

ログが肥大化→ディスク圧迫→障害 を防ぐには、logrotate定期ローテーション+圧縮+世代管理 を回すのが実務の定番です。ここでは コピペで導入できる最短レシピ と、Nginx/Apache/アプリの設定例、検証方法、事故防止ポイントまで一気にまとめます。

まずは最短レシピ(コピペ可)

目的:日次で圧縮14世代保持空ファイルはスキップ日付サフィックス権限を揃えて作成

/etc/logrotate.d/myapp を新規作成:

/var/log/myapp/*.log {
  daily                 # 日次
  rotate 14             # 14世代保持
  missingok             # 無くてもエラーにしない
  notifempty            # 空なら回さない
  compress              # .gz圧縮
  delaycompress         # 直近は生のまま、次回に圧縮
  dateext               # ファイル名に日付付与
  dateformat .%Y-%m-%d  # 例: app.log.2025-08-23
  create 0640 app app   # 新規ログの権限/所有者
  su app app            # 権限不足で失敗しないよう昇格
  # アプリがログファイルを開き直せない場合は copytruncate を使う(下記参照)
}

動作確認

# ドライラン(実行せず計画だけ表示)
sudo logrotate -d /etc/logrotate.d/myapp

# 強制実行(挙動を確認)
sudo logrotate -f /etc/logrotate.d/myapp

logrotate の実行履歴は通常 /var/lib/logrotate/status に記録されます。

「copytruncate」か「シグナル再オープン」か(選び方)

  • copytruncate:現在のファイルをコピーしてから元ファイルをその場で空に
    → 便利だがごく稀にログ欠損の瞬間があり得る。
  • シグナル再オープンpostrotate でプロセスに USR1reload を送り、新しいファイルで再開
    → 正確で安全。推奨(対応するアプリが多い)。

copytruncate 版(簡単)

/var/log/myapp/*.log {
  daily
  rotate 7
  missingok
  notifempty
  compress
  delaycompress
  dateext
  dateformat .%Y-%m-%d
  create 0640 app app
  su app app
  copytruncate          # ← これを使う
}

シグナル再オープン版(推奨)

/var/log/myapp/*.log {
  daily
  rotate 14
  missingok
  notifempty
  compress
  delaycompress
  dateext
  dateformat .%Y-%m-%d
  create 0640 app app
  su app app
  sharedscripts
  postrotate
    # 例: systemdサービスに USR1 を送ってログを開き直す
    /bin/systemctl kill -s USR1 myapp.service >/dev/null 2>&1 || true
  endscript
}

日次/週次/容量トリガの切り替え

# 週次ローテーション
weekly
rotate 8

# 容量トリガ(100MB以上なら回す)
size 100M

# 日次+容量(“毎日または100MB以上”で回す)
daily
size 100M

# 最長保持日数で頭打ち(例: 60日超は削除)
maxage 60

# このサイズ未満なら回さない(minsize)
minsize 1M

圧縮・保管の最適化

compress                 # gzip
# 並列圧縮(pigz)があれば速い
# compresscmd /usr/bin/pigz
# uncompresscmd /usr/bin/unpigz

# 回転後ファイルの保管先(同一FS上に限る)
olddir /var/log/myapp/old

olddir は同一ファイルシステム内でのみ有効。別ディスクに逃がすなら、ローテ後に postrotatersync などを叩くのが現実的。

実例:Nginx のアクセスログ

/var/log/nginx/*.log {
  daily
  rotate 14
  missingok
  notifempty
  compress
  delaycompress
  dateext
  dateformat .%Y-%m-%d
  create 0640 www-data adm   # Debian/Ubuntu 系の例
  su root adm
  sharedscripts
  postrotate
    # Nginx にログ再オープンを通知(安全)
    /bin/systemctl kill -s USR1 nginx.service >/dev/null 2>&1 || true
  endscript
}

実例:Apache (httpd / apache2)

/var/log/httpd/*log /var/log/apache2/*log {
  daily
  rotate 14
  missingok
  notifempty
  compress
  delaycompress
  dateext
  dateformat .%Y-%m-%d
  create 0640 root adm
  su root adm
  sharedscripts
  postrotate
    # ディストリに合わせてどちらか
    /bin/systemctl reload httpd.service  >/dev/null 2>&1 || true
    /bin/systemctl reload apache2.service >/dev/null 2>&1 || true
  endscript
}

実例:アプリ独自ログ(再オープン非対応)

/var/log/myapp/app.log {
  daily
  rotate 7
  missingok
  notifempty
  compress
  delaycompress
  dateext
  dateformat .%Y-%m-%d
  create 0640 app app
  su app app
  copytruncate  # ← 再オープン不可ならこちら
}

実行スケジュールの確認(cron / systemd timer)

多くのディストリでは logrotate自動で1日1回動いています。

# cronの場合
cat /etc/cron.daily/logrotate

# systemd timer の場合
systemctl status logrotate.timer
systemctl list-timers | grep logrotate

バックアップ連携(ローテ後に転送)

ローテ完了時に、S3やバックアップサーバへ送る例:

/var/log/myapp/*.log {
  daily
  rotate 30
  missingok
  notifempty
  compress
  delaycompress
  dateext
  dateformat .%Y-%m-%d
  create 0640 app app
  su app app
  sharedscripts
  postrotate
    # 前回の圧縮済みファイルを転送(例: rsync)
    /usr/bin/find /var/log/myapp -name "*.gz" -mtime -1 -print0 \
      | xargs -0 -r -I{} rsync -a {} backup@host:/srv/logs/myapp/
  endscript
}

トラブル防止チェックリスト

  • ドライランlogrotate -d でまず挙動確認
  • 権限su / create を適切に設定
  • copytruncate vs 再オープン:可能なら再オープン方式を選ぶ
  • 日付付与dateextdateformat で世代識別を容易に
  • 保持数と期限rotatemaxage の両方で制御
  • 失敗検知/var/lib/logrotate/status/var/log/syslog(または journalctl)を定期確認
  • 復旧手順:誤設定で巨大化しても -f で手動回転して緊急退避

補足:journald(systemd)のログは別物

/var/log/journal を使う systemd-journaldlogrotate ではなく /etc/systemd/journald.conf で管理します:

# /etc/systemd/journald.conf (抜粋)
SystemMaxUse=2G        # 全体の上限
SystemMaxFileSize=200M # 1ファイル上限
MaxRetentionSec=30day  # 保持期間

反映:

sudo systemctl restart systemd-journald

まとめ

  • logrotate自動ローテーション+圧縮+世代保持 を標準化すれば、ディスク障害の芽を摘めます。
  • 迷ったらまずは 日次+14世代+gzip+日付付与、再オープンできるサービスは postrotate で通知
  • 運用開始前は ドライラン→強制実行で確認、導入後は状態ファイルとログを定期チェック。

このページのテンプレを貼り付け → ドライラン → 本番、の流れで 今日から“詰まないログ運用” を始めましょう。

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント