2012-05-02 38 views
5

Tôi muốn nhận được nhiệt độ của đĩa cứng bằng cách sử dụng Python (dưới Linux). Tôi hiện đang gọi hddtemp với subprocess.popen, nhưng tôi gọi nó thường đủ để nó là một nút cổ chai hiệu suất trong kịch bản của tôi. Tôi nghĩ rằng nó có thể làm điều gì đó tương tự như question 4193514?Lấy nhiệt độ ổ cứng bằng cách sử dụng Python

+3

Tần suất bạn kiểm tra nhiệt độ? Bạn sẽ có thể lưu trữ giá trị trong một phút hoặc lâu hơn. Nó không thay đổi rất nhanh. –

+4

@gnibbler: Nhưng làm sao anh ta có thể đo được hoàn cảnh ném máy vào lò sưởi? – jdi

+0

Nó dành cho trang web hiển thị trạng thái máy chủ thời gian thực. Khi trang được mở, nó sẽ làm mới khoảng 5-10 giây một lần. – lyineyes

Trả lời

5

Bạn có thể chạy hddtemp như một daemon (tùy chọn -d), sau đó sử dụng ổ cắm để truy vấn nó - mặc định là cổng 7634. ​​

Chỉnh sửa: xem some code that does this.

+0

Đó chính xác là những gì tôi đang tìm kiếm, Cảm ơn! Điểm thưởng cho ví dụ mã. – lyineyes

2

Mở rộng những gì @gnibbler đề xuất trong nhận xét chính của anh ấy, về phương pháp tiếp cận được lưu trong bộ nhớ cache là gì? Đây là một ví dụ ngớ ngẩn đơn giản chỉ là để hiển thị các khái niệm:

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 

Và trong trường hợp cụ thể của bạn:

def reportHDD(self): 
    if self._cached['hddtemp'].isOld(10): 
     self._cached['hddtemp'].value = self.getNewHDDValue() 
    return self._cached['hddtemp'].value 

Cách tiếp cận này thực sự là nhiều hơn một giải pháp chung để bộ nhớ đệm một hoạt động tốn kém. Trong các ứng dụng lớn hơn, CachedValue có thể dễ dàng được thay thế bằng một tìm kiếm memcached/redis đơn giản duy trì giá trị TTL riêng của nó cho bạn. Nhưng trên quy mô nhỏ, đây chỉ là một cách ưa thích để tổ chức các giá trị được lưu trong bộ nhớ cache cục bộ.

+0

Ví dụ tuyệt vời. Tôi nghĩ rằng tôi sẽ sử dụng nó cho các chức năng khác, nhưng để nhận được nhiệt độ ổ cứng, tôi đã sử dụng để sinh ra một luồng (để thử và giảm thiểu chi phí của cuộc gọi hệ thống chậm) để cập nhật một mục nhập dict. – lyineyes

+0

@lyineyes: Nhưng tại sao thậm chí phải chịu chi phí cho nó trong một sợi hoặc bất cứ nơi nào, nếu nhiệt độ thực sự chỉ có thể dao động trong một khoảng thời gian hợp lý? Nhưng Hugh Bothwell không đề cập đến trong câu trả lời của mình rằng bạn có thể chỉ cần giám sát phiên bản daemonized của công cụ này một cách cụ thể. Vì vậy, thats có lẽ sửa chữa rất cụ thể của bạn. Nhưng tôi vui vì bạn thích cách tiếp cận này cho một giải pháp bộ nhớ đệm chung! – jdi

2

Tôi đã googling xung quanh trong một thời gian và hit này giữ gần đến đầu bất kể làm thế nào tôi định dạng tìm kiếm của tôi. Tôi có smartmontools và ít nhất là python 2.7.6 được cài đặt trên tất cả các máy chủ của tôi và tôi không muốn cài đặt một gói mới cho dữ liệu tạm thời hdd đường ống để graphite/statsd vì vậy tôi đã thực hiện như sau.

Tôi không phải là nhà phát triển và tôi không biết python (hiển nhiên) vì vậy đây là nỗ lực 1-2 ngày của tôi để tìm ra. Tôi quá xấu hổ để gửi tất cả các mã ở đây nhưng đây là dealy chính ::

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]) 

Trên máy chủ lưu trữ của tôi này trả lại danh sách đầy đủ của 38 ổ đĩa trong 2 giây so với 50 giây để lặp qua tất cả các đĩa serially. Điều đó nói rằng tải nhảy lên từ khoảng 1,08 đến 3,50 trên một hộp 40 lõi. Vì vậy, lấy nó như bạn sẽ. Tôi đang cố gắng tìm một cách để sử dụng proc hoặc có thể fcntl based on another stack overflow I found để kéo dữ liệu thay vì sử dụng subprocess.popen nhưng eh.

2:22 sáng ở đây và tôi cần phải bắt đầu về nhà. Khi ở đó tôi sẽ cố gắng và phác thảo đoạn mã trên và nói những gì tôi nghĩ rằng mọi thứ đang làm nhưng tôi hy vọng nó có phần tự giải thích.

Xin lỗi vì mã kludge. Tôi nghĩ rằng bộ đệm là cách tốt hơn để đi vào thời điểm này nhưng nó là một bài tập mát mẻ. Nếu bạn không muốn cài đặt hddtemp và điều này tôi nghĩ rằng một bộ đệm + ở trên có thể là lựa chọn tốt nhất. Vẫn cố gắng tìm ra điều đó cũng như tôi không hiểu làm thế nào để làm các lớp học được nêu ra.

Tôi hy vọng điều này sẽ giúp ai đó.

+0

Đáng buồn là tôi hiện đang bị tạm ngưng từ ServerFault trong một năm, bởi vì tôi đã khuyên người mới sử dụng phím shift nếu họ bắt đầu một câu :-) – peterh

Các vấn đề liên quan