ラズパイの/var/logを簡単にRAMディスク化

## 本記事の内容
ラズパイのログディレクトリ（/var/log）をRAMディスク（tmpfs）に移動して、SDカードの寿命を延ばします。
単純に/var/logをRAMディスクにすると、OS再起動時に/var/log内のディレクトリやログファイルが消えて、一部のアプリケーションの起動に失敗します。

例として、nginxをインストール後、/var/logが空の状態でnginxを起動しようとすると、次のエラーが発生します。

```
$ cat /var/log/syslog | grep nginx
Mar 27 11:02:22 rp401 nginx[1765]: nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (2: No such file or directory)
Mar 27 11:02:23 rp401 nginx[1765]: 2021/03/27 11:02:22 [emerg] 1765#1765: open() "/var/log/nginx/access.log" failed (2: No such file or directory)
Mar 27 11:02:23 rp401 nginx[1765]: nginx: configuration file /etc/nginx/nginx.conf test failed
Mar 27 11:02:23 rp401 systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Mar 27 11:02:23 rp401 systemd[1]: nginx.service: Failed with result 'exit-code'.
```

今回は、/var/logのディレクトリ構造を事前に保存し、OS起動時に復元する対策を行う形で、/var/logをRAMディスク化しました。

## 前提条件
本記事では以下の環境を使用していますが、他のラズパイ、Linuxでも同様の手順が使えると思います。

- Raspberry Pi 4 Model B 4GB
- Ubuntu Server 20.04.2 LTS 64bit

OS（Ubuntu）の基本設定は下記記事にまとめています。
（/tmpのRAMディスク化も実施。）
[ラズパイのOSを「cloud-init」で簡単に設定（Ubuntu Server 20.04 LTS 64bit）](https://qiita.com/s8ta/items/ad1d8de95e8573194f95)

## 設定の概要
### 1. /var/logのディレクトリ構造を保存
シェルスクリプトで/var/logの内容を一時ディレクトリにコピーし、各ログファイルを空（0バイト）にした後、/var/log.tarに保存。

### 2. /var/logのRAMディスク化
/etc/fstabに、/var/logをRAMディスク（tmpfs）としてマウントする設定を追加。

### 3. /var/logのディレクトリ構造をOS起動時に自動復元
OS起動時に/var/log.tarを展開し、/var/logのディレクトリ構造、パーミッションを復元するよう設定。

## 設定手順
### 1. rootユーザーに切替
```
$ sudo -i
```

### 2. /var/log保存用スクリプトの作成

```
# vi /usr/sbin/var-log-save.sh
```

```bash:/usr/sbin/var-log-save.sh
#!/bin/bash

# 作業ディレクトリ作成
tmp=$(mktemp -d)

# ログディレクトリコピー
cp -a /var/log/* ${tmp}

# 各ログファイルクリア
for file in $(find ${tmp} -type f); do
  : > ${file}
done

# ログディレクトリ保存
cd ${tmp} && tar -cvf /var/log.tar ./*

# 作業ディレクトリ削除
rm -rf ${tmp}

```

### 3. /var/log保存用スクリプトの実行
```
# chmod 700 /usr/sbin/var-log-save.sh
# var-log-save.sh
```

### 4. /var/logのRAMディスク化
/etc/fstabに設定を追加。以降のOS起動時に/var/logがRAMディスク（tmpfs）としてマウントされる。

```
# echo "tmpfs /var/log tmpfs defaults,noatime,size=128m,mode=0775 0 0" >> /etc/fstab
```

### 5. OS起動時の/var/log復元設定
/var/log.tarに保存したディレクトリ構造を、OS起動時に/var/logに復元するサービスを作成する。

```
# vi /etc/systemd/system/var-log-load.service
```

```systemd:/etc/systemd/system/var-log-load.service
[Unit]
After=local-fs.target
Before=rsyslog.service

[Service]
ExecStart=tar -xf /var/log.tar --skip-old-files -C /var/log
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

```

- /etc/fstabによるファイルシステムのマウント後に実行するため、`After=local-fs.target`を指定。
- /var/logの復元完了後にrsyslogを起動するため、`Before=rsyslog.service`を指定。
- tarによる/var/log.tarの展開時、既に出力されたログファイルを空ファイルで上書きしないために、`--skip-old-files`を指定。  
（この指定が無いと、boot.logなどが上書きされて空になった。）

サービスを有効化する。

```
# systemctl daemon-reload
# systemctl enable var-log-load.service
```

### 6. OS再起動

```
# reboot
```

### 7. /var/logのRAMディスク化・ディレクトリ復元確認

```
$ df -h | grep /var/log
tmpfs           128M  248K  128M   1% /var/log
```

```
$ ls -l /var | grep log
drwxrwxr-x  8 root syslog   460  3月 27 09:47 log
-rw-r--r--  1 root root   30720  3月 27 09:31 log.tar
```

```
$ ls -l /var/log
total 248
-rw-r--r-- 1 root      root                 0  3月 27 09:31 alternatives.log
drwxr-xr-x 2 root      root               100  3月 27 09:07 apt
-rw-r----- 1 syslog    adm                622  3月 27 09:49 auth.log
-rw------- 1 root      root              7361  3月 27 09:47 boot.log
-rw-rw---- 1 root      utmp                 0  2月 23 09:19 btmp
-rw-r--r-- 1 root      root              1653  3月 27 09:47 cloud-init-output.log
-rw-r--r-- 1 syslog    adm              72092  3月 27 09:47 cloud-init.log
drwxr-xr-x 2 root      root                40  1月 20 06:47 dist-upgrade
-rw-r--r-- 1 root      adm              35347  3月 27 09:47 dmesg
-rw-r--r-- 1 root      adm                  0  3月 27 09:31 dmesg.0
-rw-r--r-- 1 root      adm                  0  3月 27 09:31 dmesg.1.gz
-rw-r--r-- 1 root      root                 0  3月 27 09:31 dpkg.log
drwxr-sr-x 3 root      systemd-journal     60  4月  2  2020 journal
-rw-r----- 1 syslog    adm              39340  3月 27 09:49 kern.log
drwxr-xr-x 2 landscape landscape           60  3月 21 16:04 landscape
-rw-rw-r-- 1 root      utmp            296296  3月 27 09:49 lastlog
drwx------ 2 root      root                40  2月 23 09:19 private
-rw-r----- 1 syslog    adm              72874  3月 27 09:49 syslog
-rw-r----- 1 syslog    adm                392  3月 27 09:49 ufw.log
drwxr-x--- 2 root      adm                100  3月 27 09:03 unattended-upgrades
-rw-rw-r-- 1 root      utmp              2800  3月 27 09:49 wtmp
```

## アプリケーションインストール時の作業

今後、アプリケーションをインストールした際に、下記コマンドを実行する。
「/var/log/nginx/access.log」など、新たなログディレクトリやファイルが/var/log.tarに追加される。

```
$ sudo var-log-save.sh
```

OS再起動後、nginxが正常に起動することを確認した。

```
$ cat /var/log/syslog | grep nginx
出力なし
```

```
$ systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2021-03-27 11:33:44 JST; 2min 37s ago
以下省略
```