Содержание:
psutil.disk_partitions(all=False)
:
Функция
psutil.disk_partitions()
возвращает все смонтированные разделы диска в виде списка
именованных кортежей, включая устройство, точку монтирования и тип файловой системы, аналогично команде
df
в UNIX.
Если для аргумента all
установлено значение False
, то функция будет пытаться различать и возвращать только физические устройства (например, жесткие диски, приводы компакт-дисков, USB-накопители) и игнорировать все остальные (например, память, дубликаты, недоступные файловые системы). Обратите внимание, что это поведение может быть не надежным в некоторых системах (например, в BSD этот параметр игнорируется).
Возвращает список именованных кортежей со следующими полями:
device
: путь к устройству (например, "/dev/hda1"
). В Windows это буква диска (например, "C:\\"
).mountpoint
: путь к точке монтирования (например, "/"
). В Windows это буква диска (например, "C:\\"
).fstype
: файловая система раздела (например, "ext3"
в UNIX или "NTFS"
в Windows).opts
: строка, разделенная запятыми, указывающая различные варианты подключения для диска/раздела (в зависимости от платформы).maxfile
: максимальная длина, которую может иметь имя файла.maxpath
: максимальная длина, которую может иметь имя пути (имя каталога + имя базового файла).
>>> import psutil
>>> psutil.disk_partitions()
# [
# sdiskpart(device='/dev/sda3', mountpoint='/', fstype='ext4',
# opts='rw,errors=remount-ro', maxfile=255, maxpath=4096),
# sdiskpart(device='/dev/sda7', mountpoint='/home', fstype='ext4',
# opts='rw', maxfile=255, maxpath=4096)
# ]
psutil.disk_usage(path)
:
Функция
psutil.disk_usage()
возвращает статистику использования диска для раздела, содержащего указанный путь
path
, в виде
именованного кортежа, включая общее, используемое и свободное пространство, выраженное в байтах, а также использование в процентах.
>>> import psutil
>>> psutil.disk_usage('/')
# sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
Примечание. Системы UNIX обычно резервирует 5% всего дискового пространства для пользователя root
. Поля total
и used
в UNIX относятся к общему и используемому пространству, тогда как free
представляет пространство, доступное для пользователя, а percent
представляет использование пользователем. Вот почему значение percent
может выглядеть на 5% больше, чем ожидается. Также обратите внимание, что оба значения соответствуют команде bash - df
.
psutil.disk_io_counters(perdisk=False, nowrap=True)
:
Функция psutil.disk_io_counters()
возвращает общесистемную статистику дискового ввода-вывода в виде именованного кортежа, включающего следующие поля:
read_count
: количество считываний;write_count
: количество записей;read_bytes
: количество прочитанных байт;write_bytes
: количество записанных байт.
Поля, специфичные для конкретной платформы:
read_time
: (все, кроме NetBSD и OpenBSD) время, затраченное на чтение с диска (в миллисекундах)write_time
: (все, кроме NetBSD и OpenBSD) время, затраченное на запись на диск (в миллисекундах)busy_time
: (Linux, FreeBSD) время, затраченное на фактический ввод-вывод (in milliseconds)read_merged_count
(Linux): количество объединенных чтений (системный вызов iostats
)write_merged_count
(Linux): количество объединенных записей (системный вызов iostats
)
Если аргумент perdisk
имеет значение True
, то возвращает ту же информацию для каждого физического диска, установленного в системе, в виде словаря с именами разделов в качестве ключей и именованным кортежем, описанным выше, в качестве значений.
В некоторых системах, таких как Linux, в очень загруженных или долгоживущих системах, числа, возвращаемые ядром, могут переполняться и переноситься (перезапускаться с нуля). Если аргумент nowrap
имеет значение True
, то модуль psutil
обнаружит и скорректирует эти числа при вызовах функций и добавит "старое значение" к "новому значению", чтобы возвращаемые числа всегда увеличивались или оставались неизменными, но никогда не уменьшались.
Для аннулирования кеша nowrap
можно использовать psutil.disk_io_counters.cache_clear()
. В Windows, чтобы включить счетчики ввода-вывода, сначала может потребоваться выполнить команду diskperf -y
. На бездисковых машинах, если perdisk
имеет значение True
, то эта функция вернет None
или пустой словарь {}
.
>>> import psutil
>>> psutil.disk_io_counters()
# sdiskio(read_count=8141, write_count=2431, read_bytes=290203,
# write_bytes=537676, read_time=5868, write_time=94922)
>>> psutil.disk_io_counters(perdisk=True)
# {
# 'sda1': sdiskio(read_count=920, write_count=1, read_bytes=2933248,
# write_bytes=512, read_time=6016, write_time=4),
# 'sda2': sdiskio(read_count=18707, write_count=8830, read_bytes=6060,
# write_bytes=3443, read_time=24585, write_time=1572),
# 'sdb1': sdiskio(read_count=161, write_count=0, read_bytes=786432,
# write_bytes=0, read_time=44, write_time=0)
# }
Примечание: возможно, сначала потребуется выполнить команду Windows diskperf -y
, иначе эта функция не найдет ни одного диска.
Пример статистики использования смонтированных разделов диска.
import os
import sys
import psutil
from psutil._common import bytes2human
def main():
templ = "%-17s %8s %8s %8s %5s%% %9s %s"
print(templ % ("Device", "Total", "Used", "Free", "Use ", "Type",
"Mount"))
for part in psutil.disk_partitions(all=False):
if os.name == 'nt':
if 'cdrom' in part.opts or part.fstype == '':
# пропускаем приводы cd-rom, в которых нет диска;
# они могут вызвать ошибку графического интерфейса
# Windows для неготового раздела или просто зависнуть
continue
usage = psutil.disk_usage(part.mountpoint)
print(templ % (
part.device,
bytes2human(usage.total),
bytes2human(usage.used),
bytes2human(usage.free),
int(usage.percent),
part.fstype,
part.mountpoint))
if __name__ == '__main__':
sys.exit(main())
Вывод сценария:
$ python3 test.py
Device Total Used Free Use % Type Mount
/dev/sdb3 18.9G 14.7G 3.3G 77% ext4 /
/dev/sda6 345.9G 83.8G 244.5G 24% ext4 /home
/dev/sda1 296.0M 43.1M 252.9M 14% vfat /boot/efi
/dev/sda2 600.0M 312.4M 287.6M 52% fuseblk /media/Recovery
Пример статистики дискового ввода-вывода.
Данный пример представляет собой клон утилиты Linux iotop
, которая показывает в реальном времени статистику дискового ввода-вывода.
- Сценарий работает только на Linux (FreeBSD и macOS отсутствует поддержка счетчиков ввода-вывода).
- Сценарий не работает в Windows, так как требуется модуль
curses
.
import sys
import time
try:
import curses
except ImportError:
sys.exit('Платформа не поддерживается')
import psutil
from psutil._common import bytes2human
win = curses.initscr()
lineno = 0
def printl(line, highlight=False):
"""Тонкая обертка вокруг `curses`."""
global lineno
try:
if highlight:
line += " " * (win.getmaxyx()[1] - len(line))
win.addstr(lineno, 0, line, curses.A_REVERSE)
else:
win.addstr(lineno, 0, line, 0)
except curses.error:
lineno = 0
win.refresh()
raise
else:
lineno += 1
def poll(interval):
"""Расчет использования операций ввода-вывода, сравнив
данные до и после интервала `interval` (аргумент функции).
Возвращает кортеж, включающий все запущенные в данный
момент процессы, отсортированные по активности ввода-вывода
и общей активности дискового ввода-вывода.
"""
# получаем список всех процессов и счетчиков ввода-вывода с диска
procs = [p for p in psutil.process_iter()]
for p in procs[:]:
try:
p._before = p.io_counters()
except psutil.Error:
procs.remove(p)
continue
disks_before = psutil.disk_io_counters()
# немного спим
time.sleep(interval)
# затем снова вытаскиваем ту же информацию
for p in procs[:]:
with p.oneshot():
try:
p._after = p.io_counters()
p._cmdline = ' '.join(p.cmdline())
if not p._cmdline:
p._cmdline = p.name()
p._username = p.username()
except (psutil.NoSuchProcess, psutil.ZombieProcess):
procs.remove(p)
disks_after = psutil.disk_io_counters()
# рассчитываем результаты, сравнив данные до и после `interval`
for p in procs:
p._read_per_sec = p._after.read_bytes - p._before.read_bytes
p._write_per_sec = p._after.write_bytes - p._before.write_bytes
p._total = p._read_per_sec + p._write_per_sec
disks_read_per_sec = disks_after.read_bytes - disks_before.read_bytes
disks_write_per_sec = disks_after.write_bytes - disks_before.write_bytes
# сортируем процессы по общему объему ввода-вывода с диска,
# более интенсивные будут первыми
processes = sorted(procs, key=lambda p: p._total, reverse=True)
return (processes, disks_read_per_sec, disks_write_per_sec)
def refresh_window(procs, disks_read, disks_write):
"""Вывод результатов на экран с помощью curses."""
curses.endwin()
templ = "%-5s %-7s %11s %11s %s"
win.erase()
disks_tot = "Total DISK READ: %s | Total DISK WRITE: %s" \
% (bytes2human(disks_read), bytes2human(disks_write))
printl(disks_tot)
header = templ % ("PID", "USER", "DISK READ", "DISK WRITE", "COMMAND")
printl(header, highlight=True)
for p in procs:
line = templ % (
p.pid,
p._username[:7],
bytes2human(p._read_per_sec),
bytes2human(p._write_per_sec),
p._cmdline)
try:
printl(line)
except curses.error:
break
win.refresh()
def setup():
curses.start_color()
curses.use_default_colors()
for i in range(0, curses.COLORS):
curses.init_pair(i + 1, i, -1)
curses.endwin()
win.nodelay(1)
def tear_down():
win.keypad(0)
curses.nocbreak()
curses.echo()
curses.endwin()
if __name__ == '__main__':
global lineno
setup()
try:
interval = 0
while True:
if win.getch() == ord('q'):
break
args = poll(interval)
refresh_window(*args)
lineno = 0
interval = 0.5
time.sleep(interval)
except (KeyboardInterrupt, SystemExit):
pass
finally:
tear_down()
Вывод сценария:
$ python3 test.py
Total DISK READ: 0.00 B/s | Total DISK WRITE: 472.00 K/s
PID USER DISK READ DISK WRITE COMMAND
13155 giampao 0.00 B/s 428.00 K/s /usr/bin/google-chrome-beta
3260 giampao 0.00 B/s 0.00 B/s bash
3779 giampao 0.00 B/s 0.00 B/s gnome-session --session=ubuntu
3830 giampao 0.00 B/s 0.00 B/s /usr/bin/dbus-launch
3831 giampao 0.00 B/s 0.00 B/s //bin/dbus-daemon --fork --print-pid 5
3841 giampao 0.00 B/s 0.00 B/s /usr/lib/at-spi-bus-launcher
3845 giampao 0.00 B/s 0.00 B/s /bin/dbus-daemon
3848 giampao 0.00 B/s 0.00 B/s /usr/lib/at-spi2-core/at-spi2-registryd
3862 giampao 0.00 B/s 0.00 B/s /usr/lib/gnome-settings-daemon