この記事はMackerelのカレンダーの12/4の記事です。 昨日は@ysetoさんのmackerel でネットワークスイッチのトラフィックを監視するでした。 ネットワーク機器のようなインターフェイスがたくさんあるデバイスの監視をしたい場合、SNMPだと取りこぼしが発生するのはあるあるですね。 その問題を解決するとても面白い取り組みだと思いました!
最近、自宅サーバ熱が戻ってきてk8sクラスタを組んでいたりする。その話は明日のブログ記事にしようと思っているのでお楽しみに。 というのが前置きで、自宅サーバを再開するならもちろん監視はしっかりしたい。 もちろん監視ツールはMackerelで! 今回サーバの筐体として選んだのはRaspberry Pi4とNano Pi R4SとIntelアーキテクチャじゃなくARMアーキテクチャであったが、すんなり入ってとても体験がよい。
で、Mackerelをインストールして最低限のメトリックをとれるようになったが、自宅サーバなら筐体の温度も監視したい。 lm-sensorsを使った監視は先行事例がでてくるのだが、Thermal sysfsを使った事例は見つからなかったのでせっかくなのでMackerelプラグインを作ってみようとなり、作成したのがmackerel-plugin-thermalである。
mackerel-plugin-thermal
インストールは以下でできる。便利~
mkr plugin install buty4649/mackerel-plugin-thermal
インストール後、mackerel-agent.confに以下のような設定を追加しmacekrel-agentを再起動して数分待つとグラフができるはず。
[plugin.metrics.thermal]
command = "/opt/mackerel-agent/plugins/bin/mackerel-plugin-thermal"
作成されたグラフの例
仕組み
仕組みとしてはシンプルでGeneric Thermal Sysfs driverを介して、対応している温度センサーを読み取っている感じ。
具体的には /sys/class/thermal/thermal_zone*/temp
を読んでいる。
同様のことはlm-sensorsなどでも行えるが、Thermal Sysfsの場合カーネル組み込みで追加パッケージが不要というのがメリットだと思う。
ただし、私の調べた範囲だと対応しているデバイスが少なくlm-sensorsよりも取得できるセンサーの種類が少ないと思う。
/sys/class/thermal/thermal_zone*/temp
は1000倍された整数で表示されるので実際には1/1000する必要がある。
$ cat /sys/class/thermal/thermal_zone0/temp 50555 # => 50.555℃
温度は取れるようになったが、どこの温度かわからないと意味がないのでそれも調べる。
/sys/class/thermal/thermal_zone*/type
にはセンサーの種類が含まれているのでこれを見るのがよい。
以下は手元の環境で実行した結果である。thermal_zone0がCPU温度、thermal_zone1がGPU温度というのがわかる。
$ cat /sys/class/thermal/thermal_zone0/type cpu-thermal $ cat /sys/class/thermal/thermal_zone1/type gpu-thermal
そのほかの詳しいことについては、先に張ったカーネルのドキュメントを参照してほしい。
おまけ: mitamaeでmkr pulgin installするカスタムリソース
自宅サーバはmitamaeで構成管理している。 以下のような定義をしておくと各プラグインをインストールできて便利になると思う。
define :mkr_plugin, version: nil do name = params[:name] version = params[:version] package_name = version ? "#{name}@#{version}" : name release_tag_path = "/opt/mackerel-agent/plugins/meta/#{name}/release_tag" release_tag = run_command("cat #{release_tag_path} || true") if release_tag.stdout.empty? # Not installed execute "mkr plugin install #{name}" do command "mkr plugin install #{package_name}" end else execute "mkr plugin install #{name}" do command "mkr plugin install --upgrade #{package_name}" not_if { release_tag.stdout.chomp == version } end end end
使い方
mkr_plugin 'buty4649/mackerel-plugin-thermal' do version 'v1.0.1' end
明日はid:k1LoWです!