summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2016-02-14 21:09:58 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2016-02-14 21:09:58 +0100
commit47121b9cb5b11ac27f13e8d7e2117ef8abfbe545 (patch)
tree08b1f09f1189f4c100b277965d687bf2f72f35ff
parent1f923ff30b55db872f65d5e1d9920b085bb9cf5f (diff)
parentedd6c223849d73f3e87154be3e4909ce258f77f1 (diff)
downloadpsutil-756-disk-io-busy-time.tar.gz
merge from master756-disk-io-busy-time
-rw-r--r--HISTORY.rst1
-rw-r--r--docs/index.rst32
-rw-r--r--psutil/_pslinux.py31
-rw-r--r--psutil/tests/test_linux.py17
-rw-r--r--psutil/tests/test_system.py2
5 files changed, 61 insertions, 22 deletions
diff --git a/HISTORY.rst b/HISTORY.rst
index c76e4a9a..8e9e6b32 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -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)
diff --git a/docs/index.rst b/docs/index.rst
index 94cc623d..b49570be 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -266,7 +266,29 @@ 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
@@ -274,9 +296,7 @@ Disks
- **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>`__).
@@ -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
-------
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index d80dfba2..3ffdf25c 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -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
@@ -220,7 +234,8 @@ svmem = namedtuple(
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'])
@@ -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 = []
@@ -773,6 +783,7 @@ def disk_io_counters():
# "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:
@@ -780,17 +791,17 @@ def disk_io_counters():
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)
@@ -798,7 +809,7 @@ def disk_io_counters():
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
diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py
index 1d19eff6..149b0f51 100644
--- a/psutil/tests/test_linux.py
+++ b/psutil/tests/test_linux.py
@@ -49,6 +49,8 @@ HERE = os.path.abspath(os.path.dirname(__file__))
SIOCGIFADDR = 0x8915
SIOCGIFCONF = 0x8912
SIOCGIFHWADDR = 0x8927
+if LINUX:
+ SECTOR_SIZE = psutil._psplatform.SECTOR_SIZE
# =====================================================================
@@ -423,12 +425,13 @@ class TestSystemDisks(unittest.TestCase):
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,
@@ -455,12 +458,13 @@ class TestSystemDisks(unittest.TestCase):
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,
@@ -488,14 +492,15 @@ class TestSystemDisks(unittest.TestCase):
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)
# =====================================================================
diff --git a/psutil/tests/test_system.py b/psutil/tests/test_system.py
index 3fd6876a..1b6127f9 100644
--- a/psutil/tests/test_system.py
+++ b/psutil/tests/test_system.py
@@ -615,8 +615,10 @@ class TestSystemAPIs(unittest.TestCase):
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