Skip to content

Instantly share code, notes, and snippets.

@cubedtear
Created January 31, 2025 11:54
Show Gist options
  • Save cubedtear/882ee8a221db51582927354fc45d7847 to your computer and use it in GitHub Desktop.
Save cubedtear/882ee8a221db51582927354fc45d7847 to your computer and use it in GitHub Desktop.
Self-contained python script to monitor HDD usage (read/write speed, queue length, and usage percentage)
import time
# Assuming sector size is 512 bytes
SECTOR_SIZE = 512
def get_disk_stats():
with open('/sys/block/sda/stat', 'r', encoding='ascii') as f:
stats = f.readline().split()
if len(stats) == 11:
return {
'read_ios': int(stats[0]),
'read_merges': int(stats[1]),
'read_sectors': int(stats[2]),
'read_ticks': int(stats[3]),
'write_ios': int(stats[4]),
'write_merges': int(stats[5]),
'write_sectors': int(stats[6]),
'write_ticks': int(stats[7]),
'in_flight': int(stats[8]),
'io_ticks': int(stats[9]),
'time_in_queue': int(stats[10])
}
elif len(stats) == 15:
return {
'read_ios': int(stats[0]),
'read_merges': int(stats[1]),
'read_sectors': int(stats[2]),
'read_ticks': int(stats[3]),
'write_ios': int(stats[4]),
'write_merges': int(stats[5]),
'write_sectors': int(stats[6]),
'write_ticks': int(stats[7]),
'in_flight': int(stats[8]),
'io_ticks': int(stats[9]),
'time_in_queue': int(stats[10]),
'discard_ios': int(stats[11]),
'discard_merges': int(stats[12]),
'discard_sectors': int(stats[13]),
'discard_ticks': int(stats[14])
}
elif len(stats) == 17:
return {
'read_ios': int(stats[0]),
'read_merges': int(stats[1]),
'read_sectors': int(stats[2]),
'read_ticks': int(stats[3]),
'write_ios': int(stats[4]),
'write_merges': int(stats[5]),
'write_sectors': int(stats[6]),
'write_ticks': int(stats[7]),
'in_flight': int(stats[8]),
'io_ticks': int(stats[9]),
'time_in_queue': int(stats[10]),
'discard_ios': int(stats[11]),
'discard_merges': int(stats[12]),
'discard_sectors': int(stats[13]),
'discard_ticks': int(stats[14]),
'flush_ios': int(stats[15]),
'flush_ticks': int(stats[16])
}
else:
raise ValueError("Unexpected number of fields in /sys/block/sda/stat: {}".format(len(stats)))
if __name__ == "__main__":
prev_stats = get_disk_stats()
prev_time = time.time()
while True:
time.sleep(1)
curr_stats = get_disk_stats()
curr_time = time.time()
interval = curr_time - prev_time
write_speed = (curr_stats['write_sectors'] - prev_stats['write_sectors']) * SECTOR_SIZE / interval
time_busy_percent = (curr_stats['io_ticks'] - prev_stats['io_ticks']) / (interval * 10)
read_speed = (curr_stats['read_sectors'] - prev_stats['read_sectors']) * SECTOR_SIZE / interval
avg_queue_size = (curr_stats['time_in_queue'] - prev_stats['time_in_queue']) / interval / 1000
read_iops = (curr_stats['read_ios'] - prev_stats['read_ios']) / interval
write_iops = (curr_stats['write_ios'] - prev_stats['write_ios']) / interval
print("Read: {:8.2f} MB/s - {:7.2f} IOPS - Write: {:8.2f} MB/s - {:7.2f} IOPS - Busy: {:7.2f} % - Queue: {:5.2f}".format(
read_speed / 1000,
read_iops,
write_speed / 1000,
write_iops,
time_busy_percent,
avg_queue_size))
prev_stats = curr_stats
prev_time = curr_time
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment