MackerelでRaspberry Piの電源不足とオーバーヒートを監視する

# Raspberry Piのクロックダウン状態の検出方法

[ラズパイの電源不足を調べてみました。](https://raspberrypi.mongonta.com/underpower/) という記事で、Raspberry Piのクロックダウン状況を`vcgencmd get_throttled`コマンドで取得できるこを知りました。

```
$ vcgencmd get_throttled
throttled=0x50000
```

throttledのbitの意味は以下の通りで、電源不足だけでなく、オーバーヒートによるクロックダウンも検知できます (参考: [vcgencmd.md](https://www.raspberrypi.org/documentation/raspbian/applications/vcgencmd.md))：

| Bit | Meaning |
|--:|:--|
| 0 | Under-voltage detected |
| 1 | Arm frequency capped |
| 2 | Currently throttled |
| 3 | Soft temperature limit active |
| 16 | Under-voltage has occurred |
| 17 | Arm frequency capped has occurred |
| 18 | Throttling has occurred |
| 19 | Soft temperature limit has occurred |

上のコマンド実行例の0x50000は、bit16とbit18なので、以前電圧不足でクロックダウンがあったことを意味します。Raspberry Pi3にモニタ、キーボードをつけて2AのUSB電源＋細いUSBケーブルでは十分ではないようです（ちなみにUSBケーブルを太いのに変えたら正常になりました）。

せっかくなので、[Mackerel](https://mackerel.io)で監視してみることにしました。

## MackerelでRaspberry Piを監視する

Mackerelとは、はてなが提供しているサーバー監視サービスで、無料プランでも5台まで監視できるのでRaspberry Piの監視にちょうどいいです。問題発生時にメールだけでなくLINEに通知するようにもできます。

基本的な設定はこちらを参考：[Raspberry Pi を Mackerel で監視する](https://qiita.com/ww24/items/5409aefd87f14beff504)

※64bit OSの場合は、mackerel-agent_linux_arm.tar.gzではなくmackerel-agent_linux_arm64.tar.gzを利用します。

## クロックダウン状態の監視スクリプトを作る

```sh:/home/pi/bin/checkthrottled.sh
#!/bin/bash                                                                                   

# Bit   Meaning                                                                               
# 0     Under-voltage detected                                                                
# 1     Arm frequency capped                                                                  
# 2     Currently throttled                                                                   
# 3     Soft temperature limit active                                                         
# 16    Under-voltage has occurred                                                            
# 17    Arm frequency capped has occurred                                                     
# 18    Throttling has occurred                                                               
# 19    Soft temperature limit has occurred                                                   

STAT=`vcgencmd get_throttled`
STAT=${STAT#throttled=}

if [ "$STAT" = "" ]; then
    echo "Unexpected output."
    exit 1
fi

if [ "$(($STAT & 0x04))" != "0" ]; then
    echo -n "Throttled due to"
    [ "$(($STAT & 0x01))" != "0" ] && echo -n " under-voltage"
    [ "$(($STAT & 0x02))" != "0" ] && echo -n " frequency cap"
    [ "$(($STAT & 0x08))" != "0" ] && echo -n " temperature limit"
    echo "."
    exit 2 # Critical
elif [ "$(($STAT & 0x040000))" != "0" ]; then
    echo -n "Recovered from"
    [ "$(($STAT & 0x010000))" != "0" ] && echo -n " under-voltage"
    [ "$(($STAT & 0x020000))" != "0" ] && echo -n " frequency cap"
    [ "$(($STAT & 0x080000))" != "0" ] && echo -n " temperature limit"
    echo "."
    exit 1 # Warning
else
    echo "OK. No throttling has been occurred."
fi

exit 0
```

スクリプトの動作は以下となります

- 正常動作時
    - "OK. No throttling has been occurred." のメッセージを出力
- クロックダウンが発生中の場合
    - "Throttled due to under-voltage." などのメッセージを出力
    - Mackerel上ではCritical扱い (終了コード2)
- 以前にクロックダウンが発生していた場合
    - "Recovered from under-voltage." などのメッセージを出力
    - Mackerel上ではWarning扱い (終了コード1)

なお、vcgencmdコマンドの仕様上、一回でもクロックダウンが起きるとその後はWarning状態が継続します。Raspberry Piを再起動しない限り正常状態に戻ることはありません。

## Macherelのチェック項目として追加

チェック間隔は1分とします。

```/etc/mackerel-agent/mackerel-agent.conf
[plugin.checks.throttled]
command = "/home/pi/bin/checkthrottled.sh"
max_check_attempts = 1
check_interval = 1
memo = "This check monitors throttling due to low power or high temperature."
```

## Mackerel agent再起動

```
sudo systemctl start mackerel-agent
```