自製のディスク容量監視スクリプトをChatGPTに添削してもらった結果...

# 概要

最近流行り(?)のAlmaLinuxでディスクの容量監視スクリプトを作成してみました。
想定通り動作するのでそのままでも問題ないのですが、せっかくなのでChatGPTに添削してもらうことに。

Red Hat系列のOSなら7以降で使えるはずです、多分。

# ぼくがつくったコード

```bash:disk_monitor.sh
#!/bin/bash

# 変数設定
logfile="/var/log/shell/monitor/`date +"%Y%m%d"`_disk_monitor.log" #ログファイルのパス
tmpfile="/tmp/disk_monitor.txt" #一時ファイルのパス
threshold=80 #閾値

# ログ出力先ディレクトリがなければ作成
if [ ! -d `dirname $logfile` ]; then
    mkdir -p `dirname $logfile`
fi

# ログファイル区切り
echo "--------------------------------------------------------------------------------" >>$logfile

# ディスク使用率を取得し、一時ファイルに出力
df -h >$tmpfile

# 一時ファイルを1行ずつ処理
cat $tmpfile | tail -n +2 | while read line
do
    DISK_NAME=`echo $line | awk '{print $6}'`
    DISK_USAGE=`echo $line | awk '{print $5}' | tr -d '%'`

    # 閾値と使用率を比較
    if [ $DISK_USAGE -gt $threshold ]; then
        echo "`date +"%Y/%m/%d %H:%M:%S"` error:${DISK_NAME}のディスク使用率は${DISK_USAGE}%です。閾値${threshold}%を超過しています。" >>$logfile
    else
        echo "`date +"%Y/%m/%d %H:%M:%S"` info:${DISK_NAME}のディスク使用率は${DISK_USAGE}%です。" >>$logfile
    fi
done

# 一時ファイル削除
rm -rf $tmpfile

# ログファイルのパーミッション変更
chmod 660 $logfile

exit
```

# ChatGPTに添削してもらった結果

ほえ～～ってなったところだけ抜粋しています。
ログのローテーション処理ないの？って指摘食らったけど別のシェルでやってるし...

## 指摘1. シェルの記法古くね？

```bash
logfile="/var/log/shell/monitor/$(date +"%Y%m%d")_disk_monitor.log"

###中略

if [ ! -d $(dirname "$logfile") ]; then
    mkdir -p $(dirname "$logfile")
fi
```
>バッククォート (\``) は古いスタイルのシェル記法なので、$(...)` を使う方が一般的です。可読性も向上します。

そんなの誰も教えてくれなかったんですが(それはそう)

## 指摘2. 一時ファイル作らなくてもよくね？

```bash
df -h | tail -n +2 | while read -r line; do
    DISK_NAME=$(echo "$line" | awk '{print $6}')
    DISK_USAGE=$(echo "$line" | awk '{print $5}' | tr -d '%')

    if [ "$DISK_USAGE" -gt "$threshold" ]; then
        echo "$(date +"%Y/%m/%d %H:%M:%S") error: ${DISK_NAME}のディスク使用率は${DISK_USAGE}%です。閾値${threshold}%を超過しています。" >>"$logfile"
    else
        echo "$(date +"%Y/%m/%d %H:%M:%S") info: ${DISK_NAME}のディスク使用率は${DISK_USAGE}%です。" >>"$logfile"
    fi
done
```

>一時ファイルを使わずに df の出力を直接パイプで処理すれば、ファイルの作成と削除の手間が省けます。

行数削減できますね。スクリプトはシンプルイズベストだと思っています。

## 指摘3. ログ出力処理の書き方冗長じゃね？

```bash
msg_type="info"
msg=""

if [ "$DISK_USAGE" -gt "$threshold" ]; then
    msg_type="error"
    msg="閾値${threshold}%を超過しています。"
fi

echo "$(date +"%Y/%m/%d %H:%M:%S") ${msg_type}:${DISK_NAME}のディスク使用率は${DISK_USAGE}%です。${msg}" >>"$logfile"
```

>ログ出力がエラー/正常情報で繰り返されている部分をまとめてスッキリさせます。

これって人間があまり思いつかなさそうですよね。機械っぽいというかAIっぽいというか。
せっかくなので取り入れます。

## 修正後のコード
```bash:disk_monitor.sh
#!/bin/bash

# 変数設定
logfile="/var/log/shell/monitor/$(date +"%Y%m%d")_disk_monitor.log" #ログファイルのパス
threshold=80 #閾値

# ログ出力先ディレクトリがなければ作成
if [ ! -d $(dirname "$logfile") ]; then
    mkdir -p $(dirname "$logfile")
fi

# ログファイル区切り
echo "--------------------------------------------------------------------------------" >>$logfile

#ディスク使用率を取得
df -h | tail -n +2 | while read -r line; do
    DISK_NAME=$(echo "$line" | awk '{print $6}')
    DISK_USAGE=$(echo "$line" | awk '{print $5}' | tr -d '%')

    msg_type="info"
    msg=""

    # 閾値と使用率を比較
    if [ "$DISK_USAGE" -gt "$threshold" ]; then
        msg_type="error"
        msg="閾値${threshold}%を超過しています。"
    fi

    echo "$(date +"%Y/%m/%d %H:%M:%S") ${msg_type}:${DISK_NAME}のディスク使用率は${DISK_USAGE}%です。${msg}" >>"$logfile"
done

# ログファイルのパーミッション変更
chmod 660 $logfile

exit
```

~~正直あんまり行数減ってないような気が~~

# 実行してみた

正常に動いてました...ChatGPT恐るべし。
出力されたログファイルの中身は以下の通り。

```text:/var/log/shell/monitor/YYYYMMDD_disk_monitor.log
--------------------------------------------------------------------------------
2024/10/17 19:08:59 info:/devのディスク使用率は0%です。
2024/10/17 19:08:59 info:/dev/shmのディスク使用率は0%です。
2024/10/17 19:08:59 info:/runのディスク使用率は10%です。
2024/10/17 19:08:59 info:/のディスク使用率は9%です。
2024/10/17 19:08:59 info:/bootのディスク使用率は39%です。
2024/10/17 19:08:59 info:/run/user/1000のディスク使用率は0%です。
```

# 運用に乗せてみよう

作ったスクリプトをcrontabにでもぶちこんで、10分間隔とかで流せば動作すると思います。
```sh
crontab -e
```

`/usr/local/bin`にスクリプト配置したなら以下の書き方でOKですね。
パスとか実行間隔はお好みで変更してください。

```
*/10 * * * * /usr/local/bin/disk_monitor.sh
```

# おまけ：アラート発報手段

今回はアラート発報まで考えませんでしたが、いくつか案を書いておきます。

### ログファイル監視機構で、errorの文字列検索に引っかかれば発報

- 他の監視スクリプトも動かしている場合も一括管理できる
- おそらくベストな手段

### 閾値オーバーの分岐でmailコマンド使用し発報

- スクリプト単体で完結できる
- 他の監視スクリプトも動かしている場合、メールのフォーマット管理が大変かも


### 閾値オーバーの分岐でエラー通知ファイルを作成し、ファイル監視に引っかかれば発報

- メール本文にどこの領域が溢れてるか表示できない
- 一番微妙な方法な気がする

# まとめ
ChatGPTはすごい！！！！！！１１１

ご意見ご指摘などございましたら、コメントいただけますと幸いです。