Sidekiq のログをログローテーションする

## 概要
Rails + sidekiq のシステムのログファイルが膨れ上がり、
容量不足でサーバーが落ちてしまうということがありました。

railsのログや、unicornのログは問題がなかったのですが、
sidekiqのログだけが膨れ上がりディスクを圧迫していたので、
対策としてログローテーションを設定しました。

## logrotateの設定

ログローテーションの設定ファイルは以下のようにしています。
sidekiqのログファイルを確認することがほぼないシステムですので、
ログを残すのはかなり少なめに設定しています。

`rotate 2` の部分が、ログファイルが2個になったらローテーションするという形です。
`size 5M` の部分が、最大5MBまでしかsidekiqのログに容量をさくことを許さないという設定です。
`compress` でログファイルの圧縮をしています。
`delaycompres` で直近一個前のログは圧縮しない設定にしています。

後に解説しますが、`su deploy deploy` という部分がミソです。
これはお使いの環境によって異なりますので、後ほどの解説を元に調整してください。

はじめは `sidekiq` ようの設定ファイルが無いはずですが、
なくても `sudo vim /etc/logrotate.d/sidekiq` とすれば新規作成で開かれます。
※ `sudo` は必須です。

```/etc/logrotate.d/sidekiq
/deploy/apps/my_app/current/log/sidekiq.log {
  daily
  missingok
  rotate 3
  size 10M
  notifempty
  copytruncate
  su deploy deploy
 
  compress
  delaycompres
 
  lastaction
    unicorn_pid=/deploy/apps/epimateus_server/current/shared/pids/unicorn.pid
    test -s $unicorn_pid && kill -USR1 "$(cat $unicorn_pid)"
 
    sidekiq_pid=/deploy/apps/epimateus_server/current/tmp/pids/sidekiq.pid
    test -s $sidekiq_pid && kill -USR2 "$(cat $sidekiq_pid)"
  endscript
}
```

## きちんとログローテーションされるか確認

```
sudo logrotate -d /etc/logrotate.d/sidekiq
```


はじめは以下のようなエラーログがでました。

```
reading config file /etc/logrotate.d/sidekiq

Handling 1 logs

rotating pattern: /deploy/apps/epimateus_server/current/log/sidekiq.log  10485760 bytes (3 rotations)
empty log files are not rotated, old logs are removed
considering log /deploy/apps/epimateus_server/current/log/sidekiq.log
error: skipping "/deploy/apps/epimateus_server/current/log/sidekiq.log" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.
not running last action script, since no logs will be rotated
```

`error:` から始まっている行がありますね。

```
error: skipping "/deploy/apps/epimateus_server/current/log/sidekiq.log" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.
```

ログファイルのあるディレクトリのパーミッションの問題があるよということでした。
ここで冒頭に触れた設定ファイルの `su deploy deploy` の部分が関係してきます。

今回のシステムでは `deploy` というユーザーでデプロイを行っておりますので、
当然デプロイしているディレクトリの権限は、`deploy`ユーザーにあります。

ディレクトリの権限をいじったりいろいろ方法はあるかもしれませんが、
設定ファイルに一行追加するほうが楽だったので、今回はこの方法を取りました。

`su deploy deploy` の行をログローテーションの設定ファイルに追加することで、
そのユーザーで実行するということになります。

もちろん他のユーザーの場合は、適宜調整をしてください。
デプロイユーザーが root の場合はおそらくこの行自体必要なくなるかと思われます。

上記の設定を追加してから再度テストすると以下のように成功しました。


### 成功の場合のログサンプル

```
reading config file /etc/logrotate.d/sidekiq

Handling 1 logs

rotating pattern: /deploy/apps/epimateus_server/current/log/sidekiq.log  10485760 bytes (3 rotations)
empty log files are not rotated, old logs are removed
switching euid to 1001 and egid to 1001
considering log /deploy/apps/epimateus_server/current/log/sidekiq.log
  log does not need rotating
not running last action script, since no logs will be rotated
switching euid to 0 and egid to 0
```

`-d` オプションを外した以下のコマンドを実行すると、即時ローテーションされます。

```
sudo logrotate -d /etc/logrotate.d/sidekiq
```

ログファイルのサイズ次第ではローテーションされない場合もあります。


## まとめ

あとは、翌日ぐらいにきちんとログローテーションされているか確認して、されていれば問題はその後もきちんとローテーションされていくはずです。

今回の記事は以上です。お読みいただきありがとうございました。


## 参考記事
[sidekiqでログローテーション](https://qiita.com/nakaken0629/items/af90c86c8515a5ad9959)
[logrotateしたときに`because parent directory has insecure permissions`というエラーが出る](https://qiita.com/tjinjin/items/b2108b5178c096795a76)
[logrotateの設定ファイル、オーナーが重要](https://qiita.com/abetomo/items/59ee7d55e5458a33988c)
[【日本語man】logrotateの全オプション解説](https://hackers-high.com/linux/man-jp-logrotate/)