Skip to content

Commit

Permalink
merge from master
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo committed Feb 14, 2016
2 parents 1f923ff + edd6c22 commit 47121b9
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 22 deletions.
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Bug tracker at https://github.com/giampaolo/psutil/issues

**Enhancements**

- #523: [Linux] disk_io_counters() return a new "busy_time" field.
- #660: [Windows] make.bat is smarter in finding alternative VS install
locations. (patch by mpderbec)
- #732: Process.environ(). (patch by Frank Benkstein)
Expand Down
32 changes: 26 additions & 6 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -266,17 +266,37 @@ Disks
.. function:: disk_io_counters(perdisk=False)

Return system-wide disk I/O statistics as a namedtuple including the
following fields:
following fields.

+--------------------+-------------+-------------+-------------+-------------+-------------+-------------+
| Linux | OSX | Solaris | Windows | FreeBSD | OpenBSD | NetBSD |
+====================+=============+=============+=============+=============+=============+=============+
| read_count | read_count | read_count | read_count | read_count | read_count | read_count |
+--------------------+-------------+-------------+-------------+-------------+-------------+-------------+
| write_count | write_count | write_count | write_count | write_count | write_count | write_count |
+--------------------+-------------+-------------+-------------+-------------+-------------+-------------+
| read_bytes | read_bytes | read_bytes | read_bytes | read_bytes | read_bytes | read_bytes |
+--------------------+-------------+-------------+-------------+-------------+-------------+-------------+
| write_bytes | write_bytes | write_bytes | write_bytes | write_bytes | write_bytes | write_bytes |
+--------------------+-------------+-------------+-------------+-------------+-------------+-------------+
| read_time | read_time | read_time | read_time | read_time | read_time | |
+--------------------+-------------+-------------+-------------+-------------+-------------+-------------+
| write_time | write_time | write_time | write_time | write_time | write_time | |
+--------------------+-------------+-------------+-------------+-------------+-------------+-------------+
| read_merged_count | | | | | | |
+--------------------+-------------+-------------+-------------+-------------+-------------+-------------+
| write_merged_count | | | | | | |
+--------------------+-------------+-------------+-------------+-------------+-------------+-------------+
| busy_time | | | | | | |
+--------------------+-------------+-------------+-------------+-------------+-------------+-------------+

- **read_count**: number of reads
- **write_count**: number of writes
- **read_bytes**: number of bytes read
- **write_bytes**: number of bytes written
- **read_time**: time spent reading from disk (in milliseconds)
- **write_time**: time spent writing to disk (in milliseconds)

On Linux we get the following extra fields:

- **busy_time**: (Linux) time spent doing actual I/Os (in milliseconds)
- **read_merged_count** (Linux): number of merged reads (see `iostat doc <https://www.kernel.org/doc/Documentation/iostats.txt>`__).
- **write_merged_count** (Linux): number of merged writes (see `iostat doc <https://www.kernel.org/doc/Documentation/iostats.txt>`__).

Expand All @@ -295,8 +315,8 @@ Disks
'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)}

.. versionchanged:: 4.0.0 *read_merged_count* and *write_merged_count* were
addded on Linux.
.. versionchanged:: 4.0.0 *busy_time*, *read_merged_count* and
*write_merged_count* were addded on Linux.

Network
-------
Expand Down
31 changes: 21 additions & 10 deletions psutil/_pslinux.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,20 @@ def readlink(path):
return path


def get_sector_size():
try:
with open(b"/sys/block/sda/queue/hw_sector_size") as f:
return int(f.read())
except (IOError, ValueError):
# man iostat states that sectors are equivalent with blocks and
# have a size of 512 bytes since 2.4 kernels. This value is
# needed to calculate the amount of disk I/O in bytes.
return 512


SECTOR_SIZE = get_sector_size()


# --- named tuples

@memoize
Expand Down Expand Up @@ -220,7 +234,8 @@ def set_scputimes_ntuple(procfs_path):
sdiskio = namedtuple('sdiskio', ['read_count', 'write_count',
'read_bytes', 'write_bytes',
'read_time', 'write_time',
'read_merged_count', 'write_merged_count'])
'read_merged_count', 'write_merged_count',
'busy_time'])

pmem = namedtuple('pmem', 'rss vms shared text lib data dirty')
paddrspmem = namedtuple('paddrspmem', ['uss', 'pss', 'swap'])
Expand Down Expand Up @@ -731,11 +746,6 @@ def disk_io_counters():
"""Return disk I/O statistics for every disk installed on the
system as a dict of raw tuples.
"""
# man iostat states that sectors are equivalent with blocks and
# have a size of 512 bytes since 2.4 kernels. This value is
# needed to calculate the amount of disk I/O in bytes.
SECTOR_SIZE = 512

# determine partitions we want to look for
def get_partitions():
partitions = []
Expand Down Expand Up @@ -773,32 +783,33 @@ def get_partitions():
# "3 1 hda1 8 8 8 8"
# See:
# https://www.kernel.org/doc/Documentation/iostats.txt
# https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats
fields = line.split()
fields_len = len(fields)
if fields_len == 15:
# Linux 2.4
name = fields[3]
reads = int(fields[2])
(reads_merged, rbytes, rtime, writes, writes_merged,
wbytes, wtime) = map(int, fields[4:11])
wbytes, wtime, _, busy_time, _) = map(int, fields[4:14])
elif fields_len == 14:
# Linux 2.6+, line referring to a disk
name = fields[2]
(reads, reads_merged, rbytes, rtime, writes, writes_merged,
wbytes, wtime) = map(int, fields[3:11])
wbytes, wtime, _, busy_time, _) = map(int, fields[3:14])
elif fields_len == 7:
# Linux 2.6+, line referring to a partition
name = fields[2]
reads, rbytes, writes, wbytes = map(int, fields[3:])
rtime = wtime = reads_merged = writes_merged = 0
rtime = wtime = reads_merged = writes_merged = busy_time = 0
else:
raise ValueError("not sure how to interpret line %r" % line)

if name in partitions:
rbytes = rbytes * SECTOR_SIZE
wbytes = wbytes * SECTOR_SIZE
retdict[name] = (reads, writes, rbytes, wbytes, rtime, wtime,
reads_merged, writes_merged)
reads_merged, writes_merged, busy_time)
return retdict


Expand Down
17 changes: 11 additions & 6 deletions psutil/tests/test_linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
SIOCGIFADDR = 0x8915
SIOCGIFCONF = 0x8912
SIOCGIFHWADDR = 0x8927
if LINUX:
SECTOR_SIZE = psutil._psplatform.SECTOR_SIZE


# =====================================================================
Expand Down Expand Up @@ -423,12 +425,13 @@ def open_mock(name, *args, **kwargs):
assert m.called
self.assertEqual(ret.read_count, 1)
self.assertEqual(ret.read_merged_count, 2)
self.assertEqual(ret.read_bytes, 3 * 512)
self.assertEqual(ret.read_bytes, 3 * SECTOR_SIZE)
self.assertEqual(ret.read_time, 4)
self.assertEqual(ret.write_count, 5)
self.assertEqual(ret.write_merged_count, 6)
self.assertEqual(ret.write_bytes, 7 * 512)
self.assertEqual(ret.write_bytes, 7 * SECTOR_SIZE)
self.assertEqual(ret.write_time, 8)
self.assertEqual(ret.busy_time, 10)

def test_disk_io_counters_kernel_2_6_full_mocked(self):
# Tests /proc/diskstats parsing format for 2.6 kernels,
Expand All @@ -455,12 +458,13 @@ def open_mock(name, *args, **kwargs):
assert m.called
self.assertEqual(ret.read_count, 1)
self.assertEqual(ret.read_merged_count, 2)
self.assertEqual(ret.read_bytes, 3 * 512)
self.assertEqual(ret.read_bytes, 3 * SECTOR_SIZE)
self.assertEqual(ret.read_time, 4)
self.assertEqual(ret.write_count, 5)
self.assertEqual(ret.write_merged_count, 6)
self.assertEqual(ret.write_bytes, 7 * 512)
self.assertEqual(ret.write_bytes, 7 * SECTOR_SIZE)
self.assertEqual(ret.write_time, 8)
self.assertEqual(ret.busy_time, 10)

def test_disk_io_counters_kernel_2_6_limited_mocked(self):
# Tests /proc/diskstats parsing format for 2.6 kernels,
Expand Down Expand Up @@ -488,14 +492,15 @@ def open_mock(name, *args, **kwargs):
ret = psutil.disk_io_counters()
assert m.called
self.assertEqual(ret.read_count, 1)
self.assertEqual(ret.read_bytes, 2 * 512)
self.assertEqual(ret.read_bytes, 2 * SECTOR_SIZE)
self.assertEqual(ret.write_count, 3)
self.assertEqual(ret.write_bytes, 4 * 512)
self.assertEqual(ret.write_bytes, 4 * SECTOR_SIZE)

self.assertEqual(ret.read_merged_count, 0)
self.assertEqual(ret.read_time, 0)
self.assertEqual(ret.write_merged_count, 0)
self.assertEqual(ret.write_time, 0)
self.assertEqual(ret.busy_time, 0)


# =====================================================================
Expand Down
2 changes: 2 additions & 0 deletions psutil/tests/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,10 @@ def check_ntuple(nt):
if LINUX:
self.assertEqual(nt[6], nt.read_merged_count)
self.assertEqual(nt[7], nt.write_merged_count)
self.assertEqual(nt[8], nt.busy_time)
assert nt.read_merged_count >= 0, nt
assert nt.write_merged_count >= 0, nt
assert nt.busy_time >= 0, nt
elif BSD:
self.assertEqual(nt[6], nt.busy_time)
assert nt.busy_time >= 0, nt
Expand Down

0 comments on commit 47121b9

Please sign in to comment.