クリスマスイブに書いた記事が途中で全部消えました。
というわけで、昨日はふて寝をしておりました・・・。
さて、気を取り直して!
開発に使うMacの負荷って気になったりしませんか?
キーボードやトラックパッドの充電が突然切れて困ったりしませんか?
そんな悩みを持つ人のために、
「Mackerelを使って、Macと周辺機器を監視して、電池が切れる前にアラームで通知しちゃおうぜ!」
という素敵なお話です。
Mackerelとは
エージェント常駐型のサーバ監視ツールです。
ホストのリソース状況などをグラフに可視化し、障害発生時には自動でアラートが記録されます。
作成されたアラートは、
- メール
- Slack
などと言った外部ツールと連携させ、通知することができます。
今回は、Rubyを使ってオリジナルプラグインを作成します。
監視項目
今回、監視する項目は以下の通りです。
- Mac
- ファンの回転数
- CPUの温度
- バッテリーの温度
- バッテリーの充電量
- バッテリーのヘルスチェック
- Bluetooth接続された周辺機器
- キーボードの充電量
- トラックパットの充電量
それでは、プラグインを作成する前に、Mackerelをインストールしましょう。
事前準備
監視の通知をするSlackアカウントがない人は、アカウントやチームを作成しておきましょう。
次に、以下の記事の「MacにMackerelの導入!」項までを実施しましょう。
「Mackerelの左メニューバー -> Hosts -> 監視対象のホストを選択」で以下の画面が見れるようになれば、事前準備完了です。
プラグイン開発
基礎編
プラグイン開発は3Stepで終わります。
- 値を取得するプラグインを書く(Ruby)
- Mackerelの設定ファイルにプラグインを追加する
$ vim /usr/local/etc/mackerel-agent.conf
# ファイルの最下部に追加
# command = "ruby <開発したプラグインのファイル場所>"
========================================
[plugin.metrics.hogehoge]
command = "/Users/yn-misaki/.rbenv/shims/ruby /Users/yn-misaki/dev/mackerel_plugin/hogehoge.rb"
========================================
rbenv
でrubyを管理している方は、rbenvのディレクトリを指定、rvmの
方は、rvmのディレクトリを指定しましょう。
バージョン管理していない方は、ruby <開発したプラグインのファイル場所>
とそのまま書けばOKです。
また、apikey
の前に、プラグイン設定を追記するとエラーが発生するので気をつけましょう。
- mackerel-agentを再起動する
$ launchctl stop homebrew.mxcl.mackerel-agent
$ launchctl start homebrew.mxcl.mackerel-agent
Mac編
それでは、早速Macのプラグイン開発をします。
Linux系OSでは、lm_sensors
を使うと簡単に取得できます。
Macでは、残念ながら使えません・・・。
今回は、iStatsというgemを利用し、Macの監視項目の値を取得します。
$ gem install iStats
gemのインストールが終わった後、CPUの温度が取得できることを確かめます。
$ istats cpu
=========================
CPU temp: 40.88°C ▁▂▃▅▆▇ ← この温度だけ使いたい!
=========================
こんな感じで親切に表示してくれます。
40.88
の部分だけ使いたいので、温度を測定するメソッドだけ使います。
では、実際にcpu.rb
という名前でプラグインを作成します。
require 'iStats'
require 'json'
# iStatsのCPUに関する状態を取得するモジュールをinclude
include CPU_STATS
# Mackerelで表示するラベル、表の名前とかの設定
if ENV["MACKEREL_AGENT_PLUGIN_META"] == '1'
meta = {
:graphs => {
'cpu' => {
:label => 'CPU Temp (℃)',
:unit => 'integer',
:metrics => [
{
:name => 'temp',
:label => 'cpu'
},
]
}
}
}
puts '# mackerel-agent-plugin'
puts meta.to_json
exit 0
end
# iStatsのメソッドget_cpu_tempでCPU温度を取得
puts [ 'cpu.temp', get_cpu_temp.to_i, Time.now.to_i ].join("\t")
作成が終わった後、設定ファイルにcpu.rb
を追記します。
$ vim /usr/local/etc/mackerel-agent.conf
# ファイルの最下部に追加
========================================
[plugin.metrics.cpu]
command = "/Users/yn-misaki/.rbenv/shims/ruby /Users/yn-misaki/dev/mackerel_plugin/cpu.rb"
========================================
続いて、mackerel-agentを再起動します。
$ launchctl stop homebrew.mxcl.mackerel-agent
$ launchctl start homebrew.mxcl.mackerel-agent
ログを確認して、エラーが出ていないことを確認します
$ tail -f /usr/local/var/log/mackerel-agent.log
続いて、Mackerelのページでカスタムメトリクスが追加されていることを確認します。
5分くらい待つと、グラフが描画されます。
詳しくは、iStatsのコードを読んでください・・・(心が折れました)
include
するモジュールと、メソッドを変更するだけで各監視項目を取得することができます。
周辺機器編
続いて、Bluetooth接続されたキーボードとキーボードの充電残量を測ります。
Macに標準装備されているioreg
コマンドを使います。
このコマンドは、IOKit(ハードウェア寄りのシステム)に関する情報を取得することができます。
$ ioreg -c AppleBluetoothHIDKeyboard
# トラックパットの場合
# $ ioreg -c BNBTrackpadDevice
-c
オプションを使うことで、指定したデバイスのプロパティ情報を取得できます。
情報量があまりにも多いので、実際に使うときはgrep
をします。(ioreg -c AppleBluetoothHIDKeyboard | grep BatteryPercent
)
コマンドの使い方がわかったところで、プラグインを書いてみます。
require 'json'
# ioregでキーボードのバッテリー情報を取得し、整形するワンライナー・・・。
battery = `ioreg -c AppleBluetoothHIDKeyboard | grep BatteryPercent | grep -v ExtendedFeatures`.gsub(/[[:blank:]]|\|/, '').match(/"BatteryPercent"=(\d+)/)[1]
if ENV["MACKEREL_AGENT_PLUGIN_META"] == '1'
meta = {
graphs: {
'keybord' => {
:label => 'Keyboard Battery Charge(%)',
:unit => 'percentage',
:metrics => [
{
name: 'charge',
label: 'Battery-0',
stacked: false # stackedをfalseに指定すると、積み上げグラフになります
},
]
}
}
}
puts '# mackerel-agent-plugin'
puts meta.to_json
exit 0
end
puts [ 'keybord.battery_charge', battery, Time.now.to_i ].join("\t")
通常のコマンドを実行する場合、`(バッククオート)で囲むことで、Ruby上でもコマンドを実行することができます。
あとは、mackerel-agentの再起動をして・・・エラーが出ていないことをログから確認します。
(Bluetooth接続されていないと、値は取得できません)
こんな感じでグラフが描画されます。
監視&Slackの設定
下記の「監視ルールを入れる」と「slackに通知させてみよう」項目を参考にして設定しましょう。
まとめ
Mackerelのプラグインを作成し、MacとBuetooth接続された周辺機器を監視できるようにしました。
特に、充電周りはSlackと連携すると非常に便利なので、ぜひ使ってみてください!!