【问题标题】:Get hard disk temperature using Python使用 Python 获取硬盘温度
【发布时间】:2012-05-12 09:32:34
【问题描述】:

我想使用 Python(在 Linux 下)获取硬盘的温度。我目前正在使用subprocess.popen 调用hddtemp,但我经常调用它,以至于它成为我脚本中的性能瓶颈。我认为应该可以做类似question 4193514的事情?

【问题讨论】:

  • 您多久检查一次温度?您应该能够将值缓存一分钟左右。它不会很快改变。
  • @gnibbler:但是他怎么能测量将机器扔进壁炉的情况呢?
  • 用于显示实时服务器状态的网页。当页面打开时,它大约每 5-10 秒刷新一次。
  • 添加一个轻微的随机抖动,使它看起来像值在变化,并且每分钟只得到实际值:)?

标签: python linux hard-drive temperature


【解决方案1】:

扩展@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 可以很容易地替换为简单的 memcached/redis 查找,它为您维护自己的 TTL 值。但在小范围内,这只是组织本地缓存值的一种奇特方式。

【讨论】:

  • 很好的例子。我想我会将它用于其他功能,但为了获得硬盘驱动器温度,我已经求助于生成一个线程(以尝试减轻慢速系统调用的开销)来更新 dict 条目。
  • @lyineyes:但是,如果温度真的只能在合理的时间范围内波动,为什么还要在线程或任何地方产生开销呢?但是 Hugh Bothwell 在他的回答中确实提到,您可以专门监控该工具的守护程序版本。所以这可能是你非常具体的修复。但我很高兴您喜欢这种用于通用缓存解决方案的方法!
【解决方案2】:

您可以将 hddtemp 作为守护程序运行(-d 选项),然后使用套接字查询它 - 默认为端口 7634。

编辑:见some code that does this

【讨论】:

  • 这正是我想要的,谢谢!代码示例的奖励积分。
【解决方案3】:

我在谷歌上搜索了一段时间,无论我如何格式化我的搜索,这个命中一直接近顶部。我在所有主机上都安装了 smartmontools 和至少 python 2.7.6,我不想安装一个新包来将硬盘临时数据传输到石墨/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。所以,随心所欲吧。我正在尝试找到一种方法来使用 proc 或 fcntl based on another stack overflow I found 来提取数据,而不是使用 subprocess.popen 但是嗯。

现在是凌晨 2 点 22 分,我要开始回家了。在那里,我将尝试概述上面的 sn-p 并说出我认为一切都在做什么,但我希望它有点不言自明。

抱歉,乱码。我认为在这一点上缓冲是更好的方法,但这是一个很酷的练习。如果您不想安装 hddtemp 并且我认为缓冲区 + 以上可能是最好的选择。仍在试图弄清楚这一点,因为我还不明白如何上课。

我希望这对某人有所帮助。

【讨论】:

  • 遗憾的是,我目前被 ServerFault 停职一年,因为我建议新手在开始句子时使用 shift 键 :-)
猜你喜欢
  • 2011-12-26
  • 1970-01-01
  • 2017-11-02
  • 2020-10-18
  • 2016-05-01
  • 1970-01-01
  • 2011-05-10
  • 2018-08-02
  • 2012-03-07
相关资源
最近更新 更多