Python(Linuxの場合)を使用してハードディスクの温度を取得したいと思います。私は現在、で呼び出しhddtemp
てsubprocess.popen
いますが、スクリプトのパフォーマンスのボトルネックになるほど頻繁に呼び出しています。質問4193514に似たことができるはずだと思いますか?
3 に答える
hddtempをデーモンとして実行し(-dオプション)、ソケットを使用してクエリを実行できます。デフォルトはポート7634です。
編集:これを行うコードを参照してください。
@gnibblerが彼のメインコメントで提案したことを拡張して、キャッシュされたアプローチはどうですか?これは、概念を示すためのばかげた単純な例です。
from collection import defaultdict
class CachedValue(object):
def __init__(self):
self.timestamp = -1
self._value = None
@property
def value(self):
return self._value
@value.setter
def value(self, val):
self._value = val
self.timestamp = time.time()
def isOld(self, seconds):
return (time.time() - self.timestamp) >= seconds
>>> _cached = defaultdict(CachedValue)
>>> _cached['hddtemp'].isOld(10)
True
>>> _cached['hddtemp'].value = 'Foo'
>>> _cached['hddtemp'].isOld(10)
False
# (wait 10 seconds)
>>> _cached['hddtemp'].isOld(10)
True
そしてあなたの特定の場合:
def reportHDD(self):
if self._cached['hddtemp'].isOld(10):
self._cached['hddtemp'].value = self.getNewHDDValue()
return self._cached['hddtemp'].value
このアプローチは、実際には、コストのかかる操作をキャッシュするためのより一般的なソリューションです。大規模なアプリケーションでは、CachedValueは、独自のTTL値を維持する単純なmemcached/redisルックアップに簡単に置き換えることができます。しかし、小規模では、これはローカルにキャッシュされた値を整理するための素晴らしい方法にすぎません。
私はしばらくグーグルをしていて、検索をどのようにフォーマットしても、このヒットはトップに近づき続けました。すべてのホストにsmartmontoolsと少なくともpython2.7.6がインストールされていますが、hddtempデータをgraphite/ statsdにパイプするための新しいパッケージをインストールしたくなかったので、次のようにしました。
私は開発者ではなく、Pythonを(明らかなように)知らないので、これはそれを理解するための1〜2日間の試みです。私は恥ずかしすぎてここにすべてのコードを投稿することはできませんが、ここに主な取引があります::
enter code here
#!/usr/bin/env python
import os
import subprocess
import multiprocessing
def grab_hdd_temp(hdd, queue):
for line in subprocess.Popen(['smartctl', '-a', str('/dev/' + hdd)], stdout=subprocess.PIPE).stdout.read().split('\n'):
if ( 'Temperature_Celsius' in line.split() ) or ('Temperature_Internal' in line.split() ):
queue.put([hdd, line.split()[9]])
def hddtmp_dict(hdds_list):
procs = []
queue = multiprocessing.Queue()
hddict={}
for hdd in hdds_list:
p = multiprocessing.Process(target=grab_hdd_temp, args=(hdd, queue))
procs.append(p)
p.start()
for _ in procs:
val = queue.get()
hddict[val[0]]=val[1]
p.join()
return hddict
if __name__ == '__main__':
hdds_list = [ x for x in os.listdir('/sys/block/') if x.startswith('sd') ]
hddict = hddtmp_dict(hdds_list)
for k in hddict:
print(k, hddict[k])
私のストレージサーバーでは、これにより2秒で38台のドライブの完全なリストが返されましたが、50秒ですべてのディスクをシリアルに反復処理しました。つまり、負荷は40コアボックスで約1.08から3.50に跳ね上がります。だからあなたがそうするようにそれを取りなさい。subprocess.popenを使用する代わりに、データをプルするために見つけた別のスタックオーバーフローに基づいてprocまたはおそらくfcntlを使用する方法を見つけようとしていますが、ええと。
ここは午前2時22分です。家に帰る必要があります。そこで、上記のスニペットの概要を説明し、すべてが何をしていると思うかを説明しますが、それがいくらか自明であることを願っています。
クラッジコードでごめんなさい。この時点ではバッファーの方が良い方法だと思いますが、それはクールな演習でした。hddtempをインストールしたくない場合、これはバッファ+上記が最良のオプションかもしれないと思います。まだそれを理解しようとしているだけでなく、私はまだクラスを行う方法を理解していません。
これが誰かに役立つことを願っています。