Skip to content
This repository has been archived by the owner on Nov 26, 2020. It is now read-only.

Commit

Permalink
Added a new set of disk plugins (cfr. iostat statistics)
Browse files Browse the repository at this point in the history
  • Loading branch information
dagwieers committed Apr 26, 2013
1 parent 62b3b53 commit 413ac36
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 44 deletions.
66 changes: 66 additions & 0 deletions plugins/dstat_disk_avgqu.py
@@ -0,0 +1,66 @@
### Author: Dag Wieers <dag$wieers,com>

class dstat_plugin(dstat):
"""
The average queue length of the requests that were issued to the device.
"""

def __init__(self):
self.version = 2
self.nick = ('avgqu',)
self.type = 'f'
self.width = 4
self.scale = 10
self.diskfilter = re.compile('^(dm-\d+|md\d+|[hsv]d[a-z]+\d+)$')
self.open('/proc/diskstats')
self.cols = 1
self.struct = dict( rq_ticks=0 )

def discover(self, *objlist):
ret = []
for l in self.splitlines():
if len(l) < 13: continue
if l[3:] == ['0',] * 11: continue
name = l[2]
ret.append(name)
for item in objlist: ret.append(item)
if not ret:
raise Exception, "No suitable block devices found to monitor"
return ret

def vars(self):
ret = []
if op.disklist:
varlist = op.disklist
else:
varlist = []
blockdevices = [os.path.basename(filename) for filename in glob.glob('/sys/block/*')]
for name in self.discover:
if self.diskfilter.match(name): continue
if name not in blockdevices: continue
varlist.append(name)
varlist.sort()
for name in varlist:
if name in self.discover:
ret.append(name)
return ret

def name(self):
return self.vars

def extract(self):
for l in self.splitlines():
if len(l) < 13: continue
if l[3:] == ['0',] * 11: continue
if l[3] == '0' and l[7] == '0': continue
name = l[2]
if name not in self.vars or name == 'total': continue
self.set2[name] = dict(
rq_ticks = long(l[13]),
)

for name in self.vars:
self.val[name] = ( ( self.set2[name]['rq_ticks'] - self.set1[name]['rq_ticks'] ) * 1.0 / elapsed / 1000, )

if step == op.delay:
self.set1.update(self.set2)
75 changes: 75 additions & 0 deletions plugins/dstat_disk_avgrq.py
@@ -0,0 +1,75 @@
### Author: Dag Wieers <dag$wieers,com>

class dstat_plugin(dstat):
"""
The average size (in sectors) of the requests that were issued
to the device.
"""

def __init__(self):
self.version = 2
self.nick = ('avgrq',)
self.type = 'f'
self.width = 4
self.scale = 10
self.diskfilter = re.compile('^(dm-\d+|md\d+|[hsv]d[a-z]+\d+)$')
self.open('/proc/diskstats')
self.cols = 1
self.struct = dict( nr_ios=0, rd_sect=0, wr_sect=0 )

def discover(self, *objlist):
ret = []
for l in self.splitlines():
if len(l) < 13: continue
if l[3:] == ['0',] * 11: continue
name = l[2]
ret.append(name)
for item in objlist: ret.append(item)
if not ret:
raise Exception, "No suitable block devices found to monitor"
return ret

def vars(self):
ret = []
if op.disklist:
varlist = op.disklist
else:
varlist = []
blockdevices = [os.path.basename(filename) for filename in glob.glob('/sys/block/*')]
for name in self.discover:
if self.diskfilter.match(name): continue
if name not in blockdevices: continue
varlist.append(name)
varlist.sort()
for name in varlist:
if name in self.discover:
ret.append(name)
return ret

def name(self):
return self.vars

def extract(self):
for l in self.splitlines():
if len(l) < 13: continue
if l[3:] == ['0',] * 11: continue
if l[3] == '0' and l[7] == '0': continue
name = l[2]
if name not in self.vars or name == 'total': continue
self.set2[name] = dict(
nr_ios = long(l[3])+long(l[7]),
rd_sect = long(l[9]),
wr_sect = long(l[11]),
)

for name in self.vars:
tput = ( self.set2[name]['nr_ios'] - self.set1[name]['nr_ios'] )
if tput:
ticks = self.set2[name]['rd_sect'] - self.set1[name]['rd_sect'] + \
self.set2[name]['wr_sect'] - self.set1[name]['wr_sect']
self.val[name] = ( ticks * 1.0 / tput, )
else:
self.val[name] = ( 0.0, )

if step == op.delay:
self.set1.update(self.set2)
76 changes: 76 additions & 0 deletions plugins/dstat_disk_svctm.py
@@ -0,0 +1,76 @@
### Author: David Nicklay <david-d$nicklay,com>
### Modified from disk-util: Dag Wieers <dag$wieers,com>

class dstat_plugin(dstat):
"""
The average service time (in milliseconds) for I/O requests that were
issued to the device.
Warning! Do not trust this field any more.
"""

def __init__(self):
self.version = 2
self.nick = ('svctm',)
self.type = 'f'
self.width = 4
self.scale = 1
self.diskfilter = re.compile('^(dm-\d+|md\d+|[hsv]d[a-z]+\d+)$')
self.open('/proc/diskstats')
self.cols = 1
self.struct = dict( nr_ios=0, tot_ticks=0 )

def discover(self, *objlist):
ret = []
for l in self.splitlines():
if len(l) < 13: continue
if l[3:] == ['0',] * 11: continue
name = l[2]
ret.append(name)
for item in objlist: ret.append(item)
if not ret:
raise Exception, "No suitable block devices found to monitor"
return ret

def vars(self):
ret = []
if op.disklist:
varlist = op.disklist
else:
varlist = []
blockdevices = [os.path.basename(filename) for filename in glob.glob('/sys/block/*')]
for name in self.discover:
if self.diskfilter.match(name): continue
if name not in blockdevices: continue
varlist.append(name)
varlist.sort()
for name in varlist:
if name in self.discover:
ret.append(name)
return ret

def name(self):
return self.vars

def extract(self):
for l in self.splitlines():
if len(l) < 13: continue
if l[3:] == ['0',] * 11: continue
if l[3] == '0' and l[7] == '0': continue
name = l[2]
if name not in self.vars or name == 'total': continue
self.set2[name] = dict(
nr_ios = long(l[3])+long(l[7]),
tot_ticks = long(l[12]),
)

for name in self.vars:
tput = ( self.set2[name]['nr_ios'] - self.set1[name]['nr_ios'] )
if tput:
util = ( self.set2[name]['tot_ticks'] - self.set1[name]['tot_ticks'] )
self.val[name] = ( util * 1.0 / tput, )
else:
self.val[name] = ( 0.0, )

if step == op.delay:
self.set1.update(self.set2)
6 changes: 1 addition & 5 deletions plugins/dstat_disk_tps.py
Expand Up @@ -54,8 +54,8 @@ def extract(self):
for l in self.splitlines():
if len(l) < 13: continue
if l[3] == '0' and l[7] == '0': continue
name = l[2]
if l[3:] == ['0',] * 11: continue
name = l[2]
if not self.diskfilter.match(name):
self.set2['total'] = ( self.set2['total'][0] + long(l[3]), self.set2['total'][1] + long(l[7]) )
if name in self.vars and name != 'total':
Expand All @@ -71,7 +71,3 @@ def extract(self):

if step == op.delay:
self.set1.update(self.set2)

# S_VALUE(ioj->rd_ios, ioi->rd_ios, itv),
# S_VALUE(ioj->wr_ios, ioi->wr_ios, itv),

16 changes: 8 additions & 8 deletions plugins/dstat_disk_util.py
Expand Up @@ -17,6 +17,7 @@ def __init__(self):
self.diskfilter = re.compile('^(dm-\d+|md\d+|[hsv]d[a-z]+\d+)$')
self.open('/proc/diskstats')
self.cols = 1
self.struct = dict( tot_ticks=0 )

def discover(self, *objlist):
ret = []
Expand Down Expand Up @@ -51,19 +52,18 @@ def name(self):
return [sysfs_dev(name) for name in self.vars]

def extract(self):
for name in self.vars: self.set2[name] = (0, )
for l in self.splitlines():
if len(l) < 13: continue
if l[5] == '0' and l[9] == '0': continue
name = l[2]
if l[3:] == ['0',] * 11: continue
if name in self.vars:
self.set2[name] = ( self.set2[name][0] + long(l[12]), )

for name in self.set2.keys():
self.val[name] = (
(self.set2[name][0] - self.set1[name][0]) * 1.0 * hz / elapsed / 1000,
name = l[2]
if name not in self.vars: continue
self.set2[name] = dict(
tot_ticks = long(l[12])
)

for name in self.vars:
self.val[name] = ( (self.set2[name]['tot_ticks'] - self.set1[name]['tot_ticks']) * 1.0 * hz / elapsed / 1000, )

if step == op.delay:
self.set1.update(self.set2)
57 changes: 26 additions & 31 deletions plugins/dstat_disk_wait.py
Expand Up @@ -9,13 +9,14 @@ class dstat_plugin(dstat):
"""

def __init__(self):
self.nick = ('rawait', 'wawait')
self.type = 'f'
self.width = 6
self.scale = 34
self.width = 4
self.scale = 1
self.diskfilter = re.compile('^(dm-\d+|md\d+|[hsv]d[a-z]+\d+)$')
self.open('/proc/diskstats')
self.nick = ('rawait','wawait' )
self.cols = 1
self.struct = dict( rd_ios=0, wr_ios=0, rd_ticks=0, wr_ticks=0 )

def discover(self, *objlist):
ret = []
Expand Down Expand Up @@ -50,37 +51,31 @@ def name(self):
return self.vars

def extract(self):
for name in self.vars:
self.set2[name] = (0, 0, 0, 0 )
for l in self.splitlines():
if len(l) < 13: continue
if l[5] == '0' and l[9] == '0': continue
name = l[2]
if l[3:] == ['0',] * 11: continue
if name in self.vars:
self.set2[name] = (
0 + long(l[3]),
0 + long(l[6]),
0 + long(l[7]),
0 + long(l[10])
)
for name in self.set2.keys():
try:
self.val[name] = (
( (self.set2[name][1] - self.set1[name][1]) * 1.0 )
/
( (self.set2[name][0] - self.set1[name][0]) * 1.0 )
,
( (self.set2[name][3] - self.set1[name][3]) * 1.0 )
/
( (self.set2[name][2] - self.set1[name][2]) * 1.0 )
)
except IndexError:
self.val[name] = (0,0)
pass
except ZeroDivisionError:
self.val[name] = (0,0)
pass
name = l[2]
if name not in self.vars: continue
self.set2[name] = dict(
rd_ios = long(l[3]),
wr_ios = long(l[7]),
rd_ticks = long(l[6]),
wr_ticks = long(l[10]),
)

for name in self.vars:
rd_tput = self.set2[name]['rd_ios'] - self.set1[name]['rd_ios']
wr_tput = self.set2[name]['wr_ios'] - self.set1[name]['wr_ios']
if rd_tput:
rd_wait = ( self.set2[name]['rd_ticks'] - self.set1[name]['rd_ticks'] ) * 1.0 / rd_tput
else:
rd_wait = 0
if wr_tput:
wr_wait = ( self.set2[name]['wr_ticks'] - self.set1[name]['wr_ticks'] ) * 1.0 / wr_tput
else:
wr_wait = 0
self.val[name] = ( rd_wait, wr_wait )

if step == op.delay:
self.set1.update(self.set2)

0 comments on commit 413ac36

Please sign in to comment.