ログファイルを順次圧縮してディスク容量を空けたい

## 2022/05/25 8:53追記
そもそもログファイルを管理する`logrotate`コマンドが存在していて、こいつが全部できるみたい。設定のデバッグもできるらしい。すごい。

https://qiita.com/zom/items/c72c7bac63462225971b

# はじめに
業務で自社の提供するサーバーアプリケーションの負荷検証をすることになった。EC2インスタンスをもらって検証してみたけど、開発中だからなのかすごい勢いでログファイルがでかくなる。1時間でGB単位でかくなる。ストレージをでかくしてもらってもいいけどこれではきりがない。
そこでcronで定期的にログを圧縮しつつまとめればいいのではと思った。多分いろんな前例があると思うけどまぁいい。

# やりたいこと
アプリケーションの動作中はこういう感じで1時間ごとのいろいろなログが吐かれる。
```
[yume_yu@server]$ ls
HOGA_20220524_20.log  HOGA_20220524_21.log
HOGE_20220524_20.log  HOGE_20220524_21.log
...
```
これを1時間ごとに圧縮して決まったディレクトリの保存したい。かつ、圧縮と一緒に元ファイルも消したい。

# 検証環境
> $ cat /etc/redhat-release
> CentOS Linux release 8.5.2111

~~いつのまにかサポート切れてた~~CentOS 8
本番はRedHadEnterpriseだから...

# 調べてみた
## tarコマンド
まずはファイルを圧縮しつつ削除しなくては。圧縮といえばtar。調べるとこんな記事が見つかった。
[tar/zipしたあと元ファイルを削除 – Siguniang's Blog](https://siguniang.wordpress.com/2013/04/12/how-to-tar-zip-files-and-then-remove-originals/)
どうやら`--remove-file`というオプションがあるらしい。たしかに`$man tar` にもこうある。
> --remove-files
> Remove files from disk after adding them to the archive.

やってみたらこうなった。予想通りでいいかんじ。
```shell-session
[yume_yu@server]$ ls
delete  me  please
[yume_yu@server]$ tar --remove-file -zcvf archive.tar.gz ./*
./delete
./me
./please
[yume_yu@server]$ ls
archive.tar.gz
```

## dateコマンド
ログファイルの名前には必ず日付と時刻が入ってる。日付といえばdateコマンド、だけどほしいのは今じゃなくて1時間前の時間。と思ったらdateコマンドは-dオプションで相対的な時間の指定もできるらしい。
[date コマンド | コマンドの使い方(Linux) | hydroculのメモ](https://hydrocul.github.io/wiki/commands/date.html)

ほんまか?と思いつつ試す。
```shell-session
[yume_yu@server]$ date "+%Y/%m/%d-%H:%M"
2022/05/25-00:46
[yume_yu@server]$ date '+%Y/%m/%d-%H:%M' -d '1 hour'
2022/05/25-01:46
[yume_yu@server]$ date '+%Y/%m/%d-%H:%M' -d '2 hours'
2022/05/25-02:46
[yume_yu@server]$ date '+%Y/%m/%d-%H:%M' -d '1 hour ago'
2022/05/24-23:46
[yume_yu@server]$ date '+%Y/%m/%d-%H:%M' -d '-2 hour'
2022/05/24-22:46
```
ほんとだった。

# やってみよう
これらを合体させてcronで回すべきコマンドを作ってみる。とりあえず今回はn時5分にn-1時台のログをまとめる想定でいく。
```shell-session
[yume_yu@server]$ date '+%Y%m%d_%H'
20220525_01
[yume_yu@server]$ ls
FUGALOG_20220525_00.log  FUGALOG_20220525_01.log  
HOGALOG_20220525_00.log  HOGALOG_20220525_01.log  
HOGELOG_20220525_00.log  HOGELOG_20220525_01.log
[yume_yu@server]$ ls | grep $(date '+%Y%m%d_%H' -d '1 hour ago') | xargs tar --remove-file -zcvf $(date '+LOGS_%Y%m%d_%H.tar.gz' -d '1 hour ago')
FUGALOG_20220525_00.log
HOGALOG_20220525_00.log
HOGELOG_20220525_00.log
[yume_yu@server]$ ls
FUGALOG_20220525_01.log  HOGALOG_20220525_01.log  HOGELOG_20220525_01.log  LOGS_20220525_00.tar.gz
```
うーんいい感じ。あとはcron用にする。
```:crontab
# 平日の7~22時のn時5分に実行する
5 7-22 * * 1-5 cd {log_dir_path}; ls | grep $(date '+%Y%m%d_%H' -d '1 hour ago') | xargs tar --remove-file -zcvf $(date '+{archive_dir_path}/LOGS_%Y%m%d_%H.tar.gz' -d '1 hour ago')
```
これでよし。テストとして現在時刻(01:22)に動作するようにしてやってみた。
```shell-session
[yume_yu@server test_tar_ball]$ ls
FUGALOG_20220525_00.log  FUGALOG_20220525_01.log  HOGALOG_20220525_00.log  HOGALOG_20220525_01.log  HOGELOG_20220525_00.log  HOGELOG_20220525_01.log
[yume_yu@server test_tar_ball]$ date
2022年  5月 25日 水曜日 01:21:49 JST
[yume_yu@server test_tar_ball]$ date
2022年  5月 25日 水曜日 01:22:08 JST
[yume_yu@server test_tar_ball]$ ls
FUGALOG_20220525_00.log  FUGALOG_20220525_01.log  HOGALOG_20220525_00.log  HOGALOG_20220525_01.log  HOGELOG_20220525_00.log  HOGELOG_20220525_01.log
```
:thinking: 

当然です。なぜならcrontabでは`%`はエスケープが必要だから...
> crontab(5) を確認すると以下の記述がありました。
>> その行のコマンド部（改行文字または % 文字まで）が /bin/sh （またはその crontab ファイルの SHELL 環境変数で指定されたシェル）によって実行される。
コマンド中にパーセント記号 (%) がバックスラッシュ (\) によってエスケープされずに置かれていると、改行文字に置き換えられ、最初に現れた % 以降の全てのデータは標準入力としてコマンドに送られる。
>
> 出典: crontab ではパーセント記号をエスケープする | はったりエンジニアの備忘録 
> https://blog.manabusakai.com/2013/05/crontab-escape-percent/ 


こういうことを避けるために実行ファイルにする。もちろん実行権限の付与も忘れずに。
```shell:compress_log.sh
#!/bin/bash
LOG_DIR={log_dir_path}
ARCHIVE_DIR={archive_dir_path}

cd $LOG_DIR
ls | grep $(date '+%Y%m%d_%H' -d '1 hour ago') | xargs tar --remove-file -zcvf $(date "+$ARCHIVE_DIR/LOGS_%Y%m%d_%H.tar.gz" -d '1 hour ago')
```
```:crontab
# 平日の7~22時のn時5分に実行する
5 7-22 * * 1-5 /path/to/compress_log.sh
```

# 結果
これでうまく行った。めでたし。
```shell-session
[yume_yu@server]$ ls
FUGALOG_20220525_01.log  HOGALOG_20220525_01.log  HOGELOG_20220525_01.log
[yume_yu@server]$ ls ../archive/
LOGS_20220525_00.tar.gz
```