ethOS Minerダウンを検知する仕組み

みなさんRIGが落ちた時の検知ってどうしていますか?私の場合は全RIGがethermine.orgのPoolに接続しているので、workerがダウンした際にethermineからメール通知が来ます。これでも充分といえば充分なんですが、GPUが1枚だけ死んだ場合は通知が来ませんし、通知が来るまでラグが1時間くらいあるのです。落ちたら即検知できないものか、と模索していました。

一番最初に思いついたのがpingによる生死監視。定期的にpingを投げ、応答がなければRIGが落ちてると判断するというもので、ネットワークエンジニア時代によくやっていた手法です。

ただ、問題が2点あります。1つはリモート拠点に対してのpingはどうするかという点、もう1つはRIGが生きててもMinerが落ちてる場合がある点。後者は特にethOSだと顕著です。WinだとだいたいOSごと死ぬけど、ethOSはsshで入って再起動できることが多いです。

ping監視は意味無さそうです。じゃあどうするか。ふとethOSのステータスパネル(http://xxxxxx.ethosdistro.com/)を見てみると、conditionがわかるようになってます。

こんな感じで”a”列に状態が記述されてます。ここを検知して異常があれば通知が来るような仕組みをつくれば良さそうです。ethOSのステータスパネルではAPIとしてJSONデータが取得できます。これ使えばなんとかできそうです。

ちなみに私はJSONデータなんて使ったこともない、javascriptはjQueryがいじれる程度、phpはwordpressがいじれる程度のスキルしか持ち合わせておりません。体系的に学んだプログラミング言語といえばSE時代の新人研修でC言語を習った程度です。間違っていること、効率が悪いことをしている可能性があることを承知した上で以降を読んで下さい。

JSONはJavaScript Object Notationの略なので、特に何も考えずにJavaScriptでなんとかしようと試行錯誤しましたが、最終的にphpで落ち着きました。JavaScriptだとcronで定期実行できなかったんです。

JSONを取得するとこんな文字列がでてきます。こいつをコネコネしてやりましょう。

{"rigs":{"f547c3":{"condition":"mining","version":"1.2.4","driver":"nvidia","miner":"claymore","gpus":"6","miner_instance":6,"miner_hashes":"30.31 30.11 30.91 30.82 30.59 30.77","bioses":"86.04.50.00.72 86.04.50.00.72 86.04.50.00.72 86.04.50.00.72 86.04.50.00.70 86.04.50.00.70","meminfo":"GPU0:01:00.0:GeForce GTX 1070:86.04.50.00.72:Unknown\nGPU1:02:00.0:GeForce GTX 1070:86.04.50.00.72:Unknown\nGPU2:03:00.0:GeForce GTX 1070:86.04.50.00.72:Unknown\nGPU3:05:00.0:GeForce GTX 1070:86.04.50.00.72:Unknown\nGPU4:06:00.0:GeForce GTX 1070:86.04.50.00.70:Unknown\nGPU5:07:00.0:GeForce GTX 1070:86.04.50.00.70:Unknown","vramsize":"8 8 8 8 8 8","drive_name":"SanDisk SSD U110 16GB 151996403077","mobo":"TB250-BTC","lan_chip":"Realtek Semiconductor Co., Ltd. RTL8111\/8168\/8411 PCI Express Gigabit Ethernet Controller (rev 15)","connected_displays":"","ram":"8","rack_loc":"rig1","ip":"192.168.0.101","server_time":1504924878,"uptime":"232791","miner_secs":232727,"rx_kbps":"0.20","tx_kbps":"0.98","load":"1.57","cpu_temp":"58","freespace":3.1,"hash":183.51,"pool":"us2.ethermine.org:4444","temp":"53 52 53 55 58 54","powertune":"2 2 2 2 2 2","voltage":"0.00 0.00 0.00 0.00 0.00 0.00","watts":"110.46 108.54 110.24 108.84 107.28 105.09","fanrpm":"3621 3643 3652 3651 3777 3804","core":"1113 1164 1544 1518 1252 1290","mem":"4404 4404 4404 4404 4404 4404"},"496406":{"condition":"mining","version":"1.2.4","driver":"nvidia","miner":"claymore","gpus":"13","miner_instance":13,"miner_hashes":"18.37 18.38 18.40 18.40 18.37 22.44 22.34 18.36 22.79 18.41 18.36 18.28 22.27","bioses":"86.06.3C.00.40 86.06.3C.00.40 86.06.3C.00.40 86.06.3C.00.40 86.06.3C.00.60 86.04.54.00.3A 86.04.54.00.3A 86.06.3C.00.60 86.06.45.00.60 86.06.3C.00.40 86.06.3C.00.40 86.06.3C.00.40 86.04.54.00.3A","meminfo":"GPU0:01:00.0:GeForce GTX 1060 3GB:86.06.3C.00.40:Unknown\nGPU1:02:00.0:GeForce GTX 1060 3GB:86.06.3C.00.40:Unknown\nGPU2:03:00.0:GeForce GTX 1060 3GB:86.06.3C.00.40:Unknown\nGPU3:04:00.0:GeForce GTX 1060 3GB:86.06.3C.00.40:Unknown\nGPU4:05:00.0:GeForce GTX 1060 3GB:86.06.3C.00.60:Unknown\nGPU5:06:00.0:GeForce GTX 1060 3GB:86.04.54.00.3A:Unknown\nGPU6:09:00.0:GeForce GTX 1060 3GB:86.04.54.00.3A:Unknown\nGPU7:0A:00.0:GeForce GTX 1060 3GB:86.06.3C.00.60:Unknown\nGPU8:0B:00.0:GeForce GTX 1060 6GB:86.06.45.00.60:Unknown\nGPU9:0C:00.0:GeForce GTX 1060 3GB:86.06.3C.00.40:Unknown\nGPU10:0D:00.0:GeForce GTX 1060 3GB:86.06.3C.00.40:Unknown\nGPU11:0E:00.0:GeForce GTX 1060 3GB:86.06.3C.00.40:Unknown\nGPU12:0F:00.0:GeForce GTX 1060 3GB:86.04.54.00.3A:Unknown","vramsize":"3 3 3 3 3 3 3 3 6 3 3 3 3","drive_name":"SanDisk SSD U110 16GB 152852407713","mobo":"H110 Pro BTC ","lan_chip":"Intel Corporation Ethernet Connection (2) I219-V (rev 31)","connected_displays":"","ram":"8","rack_loc":"rig2","ip":"192.168.0.100","server_time":1504924829,"uptime":"2004","miner_secs":1904,"rx_kbps":"0.22","tx_kbps":"1.46","load":"1.60","cpu_temp":"48","freespace":3.1,"hash":255.17,"pool":"us2.ethermine.org:4444","temp":"79 75 75 68 62 61 67 63 58 71 75 70 60","powertune":"2 2 2 2 2 2 2 2 2 2 2 2 2","voltage":"0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00","watts":"99.99 99.63 97.53 100.22 80.96 98.05 103.64 80.75 79.16 98.29 94.74 98.30 98.46","fanrpm":"2796 2792 2793 2795 3249 2787 2795 2450 3240 3152 2434 2444 2794 2793 2795 3249","core":"1708 1708 1683 1670 1632 1645 1683 1620 1480 1695 1645 1670 1683","mem":"4201 4201 4201 4201 4201 4303 4303 4201 4404 4201 4201 4201 4303"},"074ac8":{"condition":"mining","version":"1.2.4","driver":"nvidia","miner":"claymore","gpus":"3","miner_instance":3,"miner_hashes":"23.33 17.97 17.73","bioses":"86.06.45.00.60 86.06.59.00.60 86.06.59.00.60","meminfo":"GPU0:01:00.0:GeForce GTX 1060 6GB:86.06.45.00.60:Unknown\nGPU1:02:00.0:GeForce GTX 1060 3GB:86.06.59.00.60:Unknown\nGPU2:03:00.0:GeForce GTX 1060 3GB:86.06.59.00.60:Unknown","vramsize":"6 3 3","drive_name":"KingDian S100 16GB 2017071300335","mobo":"P8Z68-V","lan_chip":"Intel Corporation 82579V Gigabit Network Connection (rev 05)","connected_displays":"","ram":"16","rack_loc":"subpc_hi","ip":"192.168.0.102","server_time":1504924883,"uptime":"274","miner_secs":220,"rx_kbps":"0.00","tx_kbps":"0.00","load":"0.27","cpu_temp":"46","freespace":3.1,"hash":59.03,"pool":"us2.ethermine.org:4444","temp":"57 49 47","powertune":"2 2 2","voltage":"0.00 0.00 0.00","watts":"80.41 69.84 69.28","fanrpm":"2446 3902 3904","core":"1316 1101 1050","mem":"4608 4303 4303"}},"total_hash":497.71,"alive_gpus":22,"total_gpus":22,"alive_rigs":3,"total_rigs":3,"current_version":"1.2.4","avg_temp":57.723333333333,"capacity":"100.0","per_info":{"claymore":{"hash":498,"per_alive_gpus":22,"per_total_gpus":22,"per_alive_rigs":3,"per_total_rigs":3,"per_hash-gpu":"22.6","per_hash-rig":"166.0","current_time":1504924911}}}

中を見ると”condition”:”mining”という記述がありました。どうやらminerが落ちるとここの表記が”mining”から変わるようです。確認したところ、minerが落ちると”no_hash”、再起動中は”just_booted”、GPU温度高すぎで”throttle”などが確認できました。

実際にググりまくってphpを書いてみました。めちゃくちゃ簡単でした。XMLで似たようなことやろうとした時はクロスドメイン問題とか色々あって苦労したのに…。適当にmonitor.phpと名前をつけてWEBサーバーにアップします。
※ちなみにステータスパネルURLはethOS上でhelpmeコマンドで確認できます。

<?php
$url = 'http://xxxxxx.ethosdistro.com/'; //ethOSステータスパネルURL
$email_to = 'test@example.com'; //メール通知先アドレス
$email_from = 'ethos@hyperbanana.net'; //送信元アドレス

/* JSONデータ取得 */
$json = file_get_contents($url . '?json=yes');

/* 文字化け防止(UTF8に変換) */
$json = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');

/* JSONデータを連想配列にする */
$arr = json_decode($json,true);

$alive_gpus = $arr['alive_gpus'];
$total_gpus = $arr['total_gpus'];
$alive_rigs = $arr['alive_rigs'];
$total_rigs = $arr['total_rigs'];
$total_hash = $arr['total_hash'];

echo 'alive_gpus:' . $alive_gpus . '<br>';
echo 'total_gpus:' . $total_gpus . '<br>';
echo 'alive_rigs:' . $alive_rigs . '<br>';
echo 'total_rigs:' . $total_rigs . '<br>';
echo 'total_hash:' . $total_hash . '<br>';
echo '<br>';

for ($i = 0; $i < $total_rigs; $i++) {
 $rig_name = key(array_slice($arr['rigs'], $i, 1, true));
 $rig_worker = $arr['rigs'][$rig_name]['rack_loc'];
 $rig_condition = $arr['rigs'][$rig_name]['condition'];

 echo $rig_worker . '[' . $rig_name . ']: ' . $rig_condition;
 if ($rig_condition == 'mining' || $rig_condition =='throttle' || $rig_condition =='unreachable' ){
 //echo ' RIG異常なし';
 echo '<br>';
 } else {
 //echo ' RIG異常あり';
 echo '<br>';

 //メール通知
 mb_language("Japanese");
 mb_internal_encoding("UTF-8");
 
 $to = $email_to;
 $subject = 'ethOS RIGダウン通知';
 $message = $rig_worker . 'の状態が変化しました。' . "\r\n" . '状態:' . $rig_condition . "\r\n" . $url;
 $headers = 'From: ' . $email_from . "\r\n";
 mb_send_mail($to, $subject, $message, $headers);
 }
}
?>

local.confでworker名(rack_loc)を指定していない場合は適宜書き換えてください。
このPHPのURLをブラウザで実行するとこうなります。

試しに1台リブートしてみました。

RIGを1台rコマンドで再起動させ、起動後にupdateコマンド(ステータスパネルに状態を通知する)をした所、ちゃんと反映されました。

ブラウザを更新した瞬間メールも届きました。ステータスパネルIDは恥ずかしいので隠してます。ごめんね。

ちなみにGPU温度が高くて”throttle”になることが結構多いので、”throttle”ではメールが来ないようにしてます。あまりよろしくないけれど、”throttle”でも掘れてるので。

無事にメール通知が確認できたので次は定期実行させましょう。WebサーバーのCron機能を使います。Xserverの場合は次のような設定にします。

分を”*/5″とすることで5分毎に実行されるようになります。

コマンドの”/usr/bin/php7.0″の部分はサーバで実行しているPHPのバージョンと合わせてください。例えばPHP7.1.4を利用している場合は”/usr/bin/php7.1″になります。

Cronが動いているか不安な場合はここにメールアドレスを入れれば結果を通知してくれます。ただし入れっぱなしだと5分毎にメールが来ちゃうので、確認できたら消しておきましょう。

なお、充分にテストできていないので真似する際は気をつけてください。ethosdistroのAPI制限は調べてないけど、5分に1回程度なら大丈夫じゃないかなと思います。

2017.09.29追記
RIGを停止した場合、6日間はステータスパネルに残り続けるようです。今のままだと6日間ひたすらメールが届き続けてしまうので若干コードを直しました。具体的には”unreachable”も除外するようにしてます。