"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "dstat" between
dstat-0.7.3.tar.gz and dstat-0.7.4.tar.gz

About: dstat is a versatile resource statistic tool and a replacement for vmstat, iostat and ifstat (using Python).

dstat  (dstat-0.7.3):dstat  (dstat-0.7.4)
#!/usr/bin/env python2 #!/usr/bin/env python
### This program is free software; you can redistribute it and/or ### This program is free software; you can redistribute it and/or
### modify it under the terms of the GNU General Public License ### modify it under the terms of the GNU General Public License
### as published by the Free Software Foundation; either version 2 ### as published by the Free Software Foundation; either version 2
### of the License, or (at your option) any later version. ### of the License, or (at your option) any later version.
### ###
### This program is distributed in the hope that it will be useful, ### This program is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of ### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details. ### GNU General Public License for more details.
### ###
### You should have received a copy of the GNU General Public License ### You should have received a copy of the GNU General Public License
### along with this program; if not, write to the Free Software ### along with this program; if not, write to the Free Software
### Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, U SA. ### Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, U SA.
### Copyright 2004-2016 Dag Wieers <dag@wieers.com> ### Copyright 2004-2019 Dag Wieers <dag@wieers.com>
from __future__ import generators from __future__ import absolute_import, division, generators, print_function
__metaclass__ = type
try: import collections
import sys, os, time, sched, re, getopt, fnmatch import fnmatch
import types, resource, getpass, glob, linecache import getopt
except KeyboardInterrupt: import getpass
pass import glob
import linecache
import os
import re
import resource
import sched
import six
import sys
import time
VERSION = '0.7.3' VERSION = '0.8.0'
theme = { 'default': '' } theme = { 'default': '' }
if sys.version_info < (2, 2): if sys.version_info < (2, 2):
sys.exit('error: Python 2.2 or later required') sys.exit('error: Python 2.2 or later required')
### Workaround for python <= 2.2.1
try:
True, False
except NameError:
True = 1
False = 0
### Workaround for python < 2.3
#if 'enumerate' not in __builtins__.__dict__.keys():
if sys.version_info >= (2, 2) and sys.version_info < (2, 3):
def enumerate(sequence):
index = 0
for item in sequence:
yield index, item
index = index + 1
elif sys.version_info < (2, 2):
def enumerate(sequence):
index = 0
seqlist = []
for item in sequence:
seqlist.append((index, item))
index = index + 1
return seqlist
### Workaround for python < 2.3
#if 'sum' not in __builtins__.__dict__.keys():
if sys.version_info < (2, 3):
def sum(sequence):
ret = 0
for i in sequence:
ret = ret + i
return ret
pluginpath = [ pluginpath = [
os.path.expanduser('~/.dstat/'), # home + /.d stat/ os.path.expanduser('~/.dstat/'), # home + /.d stat/
os.path.abspath(os.path.dirname(sys.argv[0])) + '/plugins/', # binary pat h + /plugins/ os.path.abspath(os.path.dirname(sys.argv[0])) + '/plugins/', # binary pat h + /plugins/
'/usr/share/dstat/', '/usr/share/dstat/',
'/usr/local/share/dstat/', '/usr/local/share/dstat/',
] ]
class Options: class Options:
def __init__(self, args): def __init__(self, args):
self.args = args self.args = args
skipping to change at line 122 skipping to change at line 98
'lores': ('sd[b-k]', 'sd[v-z]', 'sda[a-e]'), 'lores': ('sd[b-k]', 'sd[v-z]', 'sda[a-e]'),
'hires': ('sd[l-u]', 'sda[f-o]'), 'hires': ('sd[l-u]', 'sda[f-o]'),
} }
try: try:
opts, args = getopt.getopt(args, 'acdfghilmno:prstTvyC:D:I:M:N:S:V', opts, args = getopt.getopt(args, 'acdfghilmno:prstTvyC:D:I:M:N:S:V',
['all', 'all-plugins', 'bits', 'bw', 'black-on-white', 'color', ['all', 'all-plugins', 'bits', 'bw', 'black-on-white', 'color',
'debug', 'filesystem', 'float', 'full', 'help', 'integer', 'debug', 'filesystem', 'float', 'full', 'help', 'integer',
'list', 'mods', 'modules', 'nocolor', 'noheaders', 'noupdate', 'list', 'mods', 'modules', 'nocolor', 'noheaders', 'noupdate',
'output=', 'pidfile=', 'profile', 'version', 'vmstat'] + allplu gins) 'output=', 'pidfile=', 'profile', 'version', 'vmstat'] + allplu gins)
except getopt.error, exc: except getopt.error as exc:
print 'dstat: %s, try dstat -h for a list of all the options' % str( print('dstat: %s, try dstat -h for a list of all the options' % exc)
exc)
sys.exit(1) sys.exit(1)
for opt, arg in opts: for opt, arg in opts:
if opt in ['-c']: if opt in ['-c']:
self.plugins.append('cpu') self.plugins.append('cpu')
elif opt in ['-C']: elif opt in ['-C']:
self.cpulist = arg.split(',') self.cpulist = arg.split(',')
elif opt in ['-d']: elif opt in ['-d']:
self.plugins.append('disk') self.plugins.append('disk')
elif opt in ['-D']: elif opt in ['-D']:
skipping to change at line 148 skipping to change at line 124
self.plugins.append('page') self.plugins.append('page')
elif opt in ['-i']: elif opt in ['-i']:
self.plugins.append('int') self.plugins.append('int')
elif opt in ['-I']: elif opt in ['-I']:
self.intlist = arg.split(',') self.intlist = arg.split(',')
elif opt in ['-l']: elif opt in ['-l']:
self.plugins.append('load') self.plugins.append('load')
elif opt in ['-m']: elif opt in ['-m']:
self.plugins.append('mem') self.plugins.append('mem')
elif opt in ['-M', '--mods', '--modules']: elif opt in ['-M', '--mods', '--modules']:
print >>sys.stderr, 'WARNING: Option %s is deprecated, please us e --%s instead' % (opt, ' --'.join(arg.split(','))) print('WARNING: Option %s is deprecated, please use --%s instead ' % (opt, ' --'.join(arg.split(','))), file=sys.stderr)
self.plugins += arg.split(',') self.plugins += arg.split(',')
elif opt in ['-n']: elif opt in ['-n']:
self.plugins.append('net') self.plugins.append('net')
elif opt in ['-N']: elif opt in ['-N']:
self.netlist = arg.split(',') self.netlist = arg.split(',')
elif opt in ['-p']: elif opt in ['-p']:
self.plugins.append('proc') self.plugins.append('proc')
elif opt in ['-r']: elif opt in ['-r']:
self.plugins.append('io') self.plugins.append('io')
elif opt in ['-s']: elif opt in ['-s']:
skipping to change at line 178 skipping to change at line 154
elif opt in ['-a', '--all']: elif opt in ['-a', '--all']:
self.plugins += [ 'cpu', 'disk', 'net', 'page', 'sys' ] self.plugins += [ 'cpu', 'disk', 'net', 'page', 'sys' ]
elif opt in ['-v', '--vmstat']: elif opt in ['-v', '--vmstat']:
self.plugins += [ 'proc', 'mem', 'page', 'disk', 'sys', 'cpu' ] self.plugins += [ 'proc', 'mem', 'page', 'disk', 'sys', 'cpu' ]
elif opt in ['-f', '--full']: elif opt in ['-f', '--full']:
self.full = True self.full = True
elif opt in ['--all-plugins']: elif opt in ['--all-plugins']:
### Make list unique in a fancy fast way ### Make list unique in a fancy fast way
plugins = {}.fromkeys(allplugins).keys() plugins = list({}.fromkeys(allplugins).keys())
plugins.sort() plugins.sort()
self.plugins += plugins self.plugins += plugins
elif opt in ['--bits']: elif opt in ['--bits']:
self.bits = True self.bits = True
elif opt in ['--bw', '--black-on-white', '--blackonwhite']: elif opt in ['--bw', '--black-on-white', '--blackonwhite']:
self.blackonwhite = True self.blackonwhite = True
elif opt in ['--color']: elif opt in ['--color']:
self.color = True self.color = True
self.update = True self.update = True
elif opt in ['--debug']: elif opt in ['--debug']:
skipping to change at line 219 skipping to change at line 195
elif opt in ['-h', '--help']: elif opt in ['-h', '--help']:
self.usage() self.usage()
self.help() self.help()
sys.exit(0) sys.exit(0)
elif opt in ['-V', '--version']: elif opt in ['-V', '--version']:
self.version() self.version()
sys.exit(0) sys.exit(0)
elif opt.startswith('--'): elif opt.startswith('--'):
self.plugins.append(opt[2:]) self.plugins.append(opt[2:])
else: else:
print 'dstat: option %s unknown to getopt, try dstat -h for a li st of all the options' % opt print('dstat: option %s unknown to getopt, try dstat -h for a li st of all the options' % opt)
sys.exit(1) sys.exit(1)
if self.float and self.integer: if self.float and self.integer:
print 'dstat: option --float and --integer are mutual exclusive, you can only force one' print('dstat: option --float and --integer are mutual exclusive, you can only force one')
sys.exit(1) sys.exit(1)
if not self.plugins: if not self.plugins:
print 'You did not select any stats, using -cdngy by default.' print('You did not select any stats, using -cdngy by default.')
self.plugins = [ 'cpu', 'disk', 'net', 'page', 'sys' ] self.plugins = [ 'cpu', 'disk', 'net', 'page', 'sys' ]
try: try:
if len(args) > 0: self.delay = int(args[0]) if len(args) > 0: self.delay = int(args[0])
if len(args) > 1: self.count = int(args[1]) if len(args) > 1: self.count = int(args[1])
except: except:
print 'dstat: incorrect argument, try dstat -h for the correct synta x' print('dstat: incorrect argument, try dstat -h for the correct synta x')
sys.exit(1) sys.exit(1)
if self.delay <= 0: if self.delay <= 0:
print 'dstat: delay must be an integer, greater than zero' print('dstat: delay must be an integer, greater than zero')
sys.exit(1) sys.exit(1)
if self.debug: if self.debug:
print 'Plugins: %s' % self.plugins print('Plugins: %s' % self.plugins)
def version(self): def version(self):
print 'Dstat %s' % VERSION print('Dstat %s' % VERSION)
print 'Written by Dag Wieers <dag@wieers.com>' print('Written by Dag Wieers <dag@wieers.com>')
print 'Homepage at http://dag.wieers.com/home-made/dstat/' print('Homepage at http://dag.wieers.com/home-made/dstat/')
print print()
print 'Platform %s/%s' % (os.name, sys.platform) print('Platform %s/%s' % (os.name, sys.platform))
print 'Kernel %s' % os.uname()[2] print('Kernel %s' % os.uname()[2])
print 'Python %s' % sys.version print('Python %s' % sys.version)
print print()
color = "" color = ""
if not gettermcolor(): if not gettermcolor():
color = "no " color = "no "
print 'Terminal type: %s (%scolor support)' % (os.getenv('TERM'), color) print('Terminal type: %s (%scolor support)' % (os.getenv('TERM'), color) )
rows, cols = gettermsize() rows, cols = gettermsize()
print 'Terminal size: %d lines, %d columns' % (rows, cols) print('Terminal size: %d lines, %d columns' % (rows, cols))
print print()
print 'Processors: %d' % getcpunr() print('Processors: %d' % getcpunr())
print 'Pagesize: %d' % resource.getpagesize() print('Pagesize: %d' % resource.getpagesize())
print 'Clock ticks per secs: %d' % os.sysconf('SC_CLK_TCK') print('Clock ticks per secs: %d' % os.sysconf('SC_CLK_TCK'))
print print()
global op global op
op = self op = self
showplugins() showplugins()
def usage(self): def usage(self):
print 'Usage: dstat [-afv] [options..] [delay [count]]' print('Usage: dstat [-afv] [options..] [delay [count]]')
def help(self): def help(self):
print '''Versatile tool for generating system resource statistics print('''Versatile tool for generating system resource statistics)
Dstat options: Dstat options:
-c, --cpu enable cpu stats -c, --cpu enable cpu stats
-C 0,3,total include cpu0, cpu3 and total -C 0,3,total include cpu0, cpu3 and total
-d, --disk enable disk stats -d, --disk enable disk stats
-D total,hda include hda and total -D total,hda include hda and total
-g, --page enable page stats -g, --page enable page stats
-i, --int enable interrupt stats -i, --int enable interrupt stats
-I 5,eth2 include int5 and interrupt used by eth2 -I 5,eth2 include int5 and interrupt used by eth2
-l, --load enable load stats -l, --load enable load stats
skipping to change at line 310 skipping to change at line 286
--raw enable raw stats --raw enable raw stats
--socket enable socket stats --socket enable socket stats
--tcp enable tcp stats --tcp enable tcp stats
--udp enable udp stats --udp enable udp stats
--unix enable unix stats --unix enable unix stats
--vm enable vm stats --vm enable vm stats
--vm-adv enable advanced vm stats --vm-adv enable advanced vm stats
--zones enable zoneinfo stats --zones enable zoneinfo stats
--list list all available plugins --list list all available plugins
--plugin enable external plugin by name (see --list) --<plugin-name> enable external plugin by name (see --list)
-a, --all equals -cdngy (default) -a, --all equals -cdngy (default)
-f, --full automatically expand -C, -D, -I, -N and -S lists -f, --full automatically expand -C, -D, -I, -N and -S lists
-v, --vmstat equals -pmgdsc -D total -v, --vmstat equals -pmgdsc -D total
--bits force bits for values expressed in bytes --bits force bits for values expressed in bytes
--float force float values on screen --float force float values on screen
--integer force integer values on screen --integer force integer values on screen
--bw, --black-on-white change colors for white background terminal --bw, --black-on-white change colors for white background terminal
--color force colors --color force colors
--nocolor disable colors --nocolor disable colors
--noheaders disable repetitive headers --noheaders disable repetitive headers
--noupdate disable intermediate updates --noupdate disable intermediate updates
--output file write CSV output to file --output file write CSV output to file
--profile show profiling statistics when exiting dstat --profile show profiling statistics when exiting dstat
delay is the delay in seconds between each update (default: 1) delay is the delay in seconds between each update (default: 1)
count is the number of updates to display before exiting (default: unlimited) count is the number of updates to display before exiting (default: unlimited)
''' ''')
### START STATS DEFINITIONS ### ### START STATS DEFINITIONS ###
class dstat: class dstat:
vars = None vars = None
name = None name = None
nick = None nick = None
type = 'f' type = 'f'
types = () types = ()
width = 5 width = 5
scale = 1024 scale = 1024
skipping to change at line 354 skipping to change at line 330
# val = {} # val = {}
# set1 = {} # set1 = {}
# set2 = {} # set2 = {}
def prepare(self): def prepare(self):
if callable(self.discover): if callable(self.discover):
self.discover = self.discover() self.discover = self.discover()
if callable(self.vars): if callable(self.vars):
self.vars = self.vars() self.vars = self.vars()
if not self.vars: if not self.vars:
raise Exception, 'No counter objects to monitor' raise Exception('No counter objects to monitor')
if callable(self.name): if callable(self.name):
self.name = self.name() self.name = self.name()
if callable(self.nick): if callable(self.nick):
self.nick = self.nick() self.nick = self.nick()
if not self.nick: if not self.nick:
self.nick = self.vars self.nick = self.vars
self.val = {}; self.set1 = {}; self.set2 = {} self.val = {}; self.set1 = {}; self.set2 = {}
if self.struct: ### Plugin API version 2 if self.struct: ### Plugin API version 2
for name in self.vars + [ 'total', ]: for name in self.vars + [ 'total', ]:
self.val[name] = self.struct self.val[name] = self.struct
self.set1[name] = self.struct self.set1[name] = self.struct
self.set2[name] = {} self.set2[name] = {}
elif self.cols <= 0: ### Plugin API version 1 elif self.cols <= 0: ### Plugin API version 1
for name in self.vars: for name in self.vars:
self.val[name] = self.set1[name] = self.set2[name] = 0 self.val[name] = self.set1[name] = self.set2[name] = 0
else: ### Plugin API version 1 else: ### Plugin API version 1
for name in self.vars + [ 'total', ]: for name in self.vars + [ 'total', ]:
self.val[name] = range(self.cols) self.val[name] = list(range(self.cols))
self.set1[name] = range(self.cols) self.set1[name] = list(range(self.cols))
self.set2[name] = range(self.cols) self.set2[name] = list(range(self.cols))
for i in range(self.cols): for i in list(range(self.cols)):
self.val[name][i] = self.set1[name][i] = self.set2[name][i] = 0 self.val[name][i] = self.set1[name][i] = self.set2[name][i] = 0
# print self.val # print(self.val)
def open(self, *filenames): def open(self, *filenames):
"Open stat file descriptor" "Open stat file descriptor"
self.file = [] self.file = []
self.fd = [] self.fd = []
for filename in filenames: for filename in filenames:
try: try:
fd = dopen(filename) fd = dopen(filename)
if fd: if fd:
self.file.append(filename) self.file.append(filename)
self.fd.append(fd) self.fd.append(fd)
except: except:
pass pass
if not self.fd: if not self.fd:
raise Exception, 'Cannot open file %s' % filename raise Exception('Cannot open file %s' % filename)
def readlines(self): def readlines(self):
"Return lines from any file descriptor" "Return lines from any file descriptor"
for fd in self.fd: for fd in self.fd:
fd.seek(0) fd.seek(0)
for line in fd.readlines(): for line in fd.readlines():
yield line yield line
### Implemented linecache (for top-plugins) but slows down normal plugin s ### Implemented linecache (for top-plugins) but slows down normal plugin s
# for fd in self.fd: # for fd in self.fd:
# i = 1 # i = 1
skipping to change at line 445 skipping to change at line 421
def statwidth(self): def statwidth(self):
"Return complete stat width" "Return complete stat width"
if self.cols: if self.cols:
return len(self.vars) * self.colwidth() + len(self.vars) - 1 return len(self.vars) * self.colwidth() + len(self.vars) - 1
else: else:
return len(self.nick) * self.colwidth() + len(self.nick) - 1 return len(self.nick) * self.colwidth() + len(self.nick) - 1
def colwidth(self): def colwidth(self):
"Return column width" "Return column width"
if isinstance(self.name, types.StringType): if isinstance(self.name, six.string_types):
return self.width return self.width
else: else:
return len(self.nick) * self.width + len(self.nick) - 1 return len(self.nick) * self.width + len(self.nick) - 1
def title(self): def title(self):
ret = theme['title'] ret = theme['title']
if isinstance(self.name, types.StringType): if isinstance(self.name, six.string_types):
width = self.statwidth() width = self.statwidth()
return ret + self.name[0:width].center(width).replace(' ', '-') + th eme['default'] return ret + self.name[0:width].center(width).replace(' ', '-') + th eme['default']
for i, name in enumerate(self.name): for i, name in enumerate(self.name):
width = self.colwidth() width = self.colwidth()
ret = ret + name[0:width].center(width).replace(' ', '-') ret = ret + name[0:width].center(width).replace(' ', '-')
if i + 1 != len(self.vars): if i + 1 != len(self.vars):
if op.color: if op.color:
ret = ret + theme['frame'] + char['dash'] + theme['title'] ret = ret + theme['frame'] + char['dash'] + theme['title']
else: else:
ret = ret + char['space'] ret = ret + char['space']
return ret return ret
def subtitle(self): def subtitle(self):
ret = '' ret = ''
if isinstance(self.name, types.StringType): if isinstance(self.name, six.string_types):
for i, nick in enumerate(self.nick): for i, nick in enumerate(self.nick):
ret = ret + theme['subtitle'] + nick[0:self.width].center(self.w idth) + theme['default'] ret = ret + theme['subtitle'] + nick[0:self.width].center(self.w idth) + theme['default']
if i + 1 != len(self.nick): ret = ret + char['space'] if i + 1 != len(self.nick): ret = ret + char['space']
return ret return ret
else: else:
for i, name in enumerate(self.name): for i, name in enumerate(self.name):
for j, nick in enumerate(self.nick): for j, nick in enumerate(self.nick):
ret = ret + theme['subtitle'] + nick[0:self.width].center(se lf.width) + theme['default'] ret = ret + theme['subtitle'] + nick[0:self.width].center(se lf.width) + theme['default']
if j + 1 != len(self.nick): ret = ret + char['space'] if j + 1 != len(self.nick): ret = ret + char['space']
if i + 1 != len(self.name): ret = ret + theme['frame'] + char['c olon'] if i + 1 != len(self.name): ret = ret + theme['frame'] + char['c olon']
return ret return ret
def csvtitle(self): def csvtitle(self):
if isinstance(self.name, types.StringType): if isinstance(self.name, six.string_types):
return '"' + self.name + '"' + char['sep'] * (len(self.nick) - 1) return '"' + self.name + '"' + char['sep'] * (len(self.nick) - 1)
else: else:
ret = '' ret = ''
for i, name in enumerate(self.name): for i, name in enumerate(self.name):
ret = ret + '"' + name + '"' + char['sep'] * (len(self.nick) - 1 ) ret = ret + '"' + name + '"' + char['sep'] * (len(self.nick) - 1 )
if i + 1 != len(self.name): ret = ret + char['sep'] if i + 1 != len(self.name): ret = ret + char['sep']
return ret return ret
def csvsubtitle(self): def csvsubtitle(self):
ret = '' ret = ''
if isinstance(self.name, types.StringType): if isinstance(self.name, six.string_types):
for i, nick in enumerate(self.nick): for i, nick in enumerate(self.nick):
ret = ret + '"' + nick + '"' ret = ret + '"' + nick + '"'
if i + 1 != len(self.nick): ret = ret + char['sep'] if i + 1 != len(self.nick): ret = ret + char['sep']
elif len(self.name) == 1: elif len(self.name) == 1:
for i, name in enumerate(self.name): for i, name in enumerate(self.name):
for j, nick in enumerate(self.nick): for j, nick in enumerate(self.nick):
ret = ret + '"' + nick + '"' ret = ret + '"' + nick + '"'
if j + 1 != len(self.nick): ret = ret + char['sep'] if j + 1 != len(self.nick): ret = ret + char['sep']
if i + 1 != len(self.name): ret = ret + char['sep'] if i + 1 != len(self.name): ret = ret + char['sep']
else: else:
skipping to change at line 515 skipping to change at line 491
ret = ret + '"' + name + ':' + nick + '"' ret = ret + '"' + name + ':' + nick + '"'
if j + 1 != len(self.nick): ret = ret + char['sep'] if j + 1 != len(self.nick): ret = ret + char['sep']
if i + 1 != len(self.name): ret = ret + char['sep'] if i + 1 != len(self.name): ret = ret + char['sep']
return ret return ret
def check(self): def check(self):
"Check if stat is applicable" "Check if stat is applicable"
# if hasattr(self, 'fd') and not self.fd: # if hasattr(self, 'fd') and not self.fd:
# raise Exception, 'File %s does not exist' % self.fd # raise Exception, 'File %s does not exist' % self.fd
if not self.vars: if not self.vars:
raise Exception, 'No objects found, no stats available' raise Exception('No objects found, no stats available')
if not self.discover: if not self.discover:
raise Exception, 'No objects discovered, no stats available' raise Exception('No objects discovered, no stats available')
if self.colwidth(): if self.colwidth():
return True return True
raise Exception, 'Unknown problem, please report' raise Exception('Unknown problem, please report')
def discover(self, *objlist): def discover(self, *objlist):
return True return True
def show(self): def show(self):
"Display stat results" "Display stat results"
line = '' line = ''
if hasattr(self, 'output'): if hasattr(self, 'output'):
return cprint(self.output, self.type, self.width, self.scale) return cprint(self.output, self.type, self.width, self.scale)
for i, name in enumerate(self.vars): for i, name in enumerate(self.vars):
if i < len(self.types): if i < len(self.types):
type = self.types[i] ctype = self.types[i]
else: else:
type = self.type ctype = self.type
if i < len(self.scales): if i < len(self.scales):
scale = self.scales[i] scale = self.scales[i]
else: else:
scale = self.scale scale = self.scale
if isinstance(self.val[name], types.TupleType) or isinstance(self.va if isinstance(self.val[name], collections.Sequence) and not isinstan
l[name], types.ListType): ce(self.val[name], six.string_types):
line = line + cprintlist(self.val[name], type, self.width, scale line = line + cprintlist(self.val[name], ctype, self.width, scal
) e)
sep = theme['frame'] + char['colon'] sep = theme['frame'] + char['colon']
if i + 1 != len(self.vars): if i + 1 != len(self.vars):
line = line + sep line = line + sep
else: else:
### Make sure we don't show more values than we have nicknames ### Make sure we don't show more values than we have nicknames
if i >= len(self.nick): break if i >= len(self.nick): break
line = line + cprint(self.val[name], type, self.width, scale) line = line + cprint(self.val[name], ctype, self.width, scale)
sep = char['space'] sep = char['space']
if i + 1 != len(self.nick): if i + 1 != len(self.nick):
line = line + sep line = line + sep
return line return line
def showend(self, totlist, vislist): def showend(self, totlist, vislist):
if vislist and self is not vislist[-1]: if vislist and self is not vislist[-1]:
return theme['frame'] + char['pipe'] return theme['frame'] + char['pipe']
elif totlist != vislist: elif totlist != vislist:
return theme['frame'] + char['gt'] return theme['frame'] + char['gt']
return '' return ''
def showcsv(self): def showcsv(self):
def printcsv(var): def printcsv(var):
if var != round(var): if var != round(var):
return '%.3f' % var return '%.3f' % var
return '%d' % long(round(var)) return '%d' % int(round(var))
line = '' line = ''
for i, name in enumerate(self.vars): for i, name in enumerate(self.vars):
if isinstance(self.val[name], types.ListType) or isinstance(self.val [name], types.TupleType): if isinstance(self.val[name], types.ListType) or isinstance(self.val [name], types.TupleType):
for j, val in enumerate(self.val[name]): for j, val in enumerate(self.val[name]):
line = line + printcsv(val) line = line + printcsv(val)
if j + 1 != len(self.val[name]): if j + 1 != len(self.val[name]):
line = line + char['sep'] line = line + char['sep']
elif isinstance(self.val[name], types.StringType): elif isinstance(self.val[name], types.StringType):
line = line + self.val[name] line = line + self.val[name]
skipping to change at line 600 skipping to change at line 576
self.name = 'async' self.name = 'async'
self.nick = ('#aio',) self.nick = ('#aio',)
self.vars = ('aio',) self.vars = ('aio',)
self.type = 'd' self.type = 'd'
self.width = 5; self.width = 5;
self.open('/proc/sys/fs/aio-nr') self.open('/proc/sys/fs/aio-nr')
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 1: continue if len(l) < 1: continue
self.val['aio'] = long(l[0]) self.val['aio'] = int(l[0])
class dstat_cpu(dstat): class dstat_cpu(dstat):
def __init__(self): def __init__(self):
self.nick = ( 'usr', 'sys', 'idl', 'wai', 'stl' ) self.nick = ( 'usr', 'sys', 'idl', 'wai', 'stl' )
self.type = 'p' self.type = 'p'
self.width = 3 self.width = 3
self.scale = 34 self.scale = 34
self.open('/proc/stat') self.open('/proc/stat')
self.cols = 5 self.cols = 5
skipping to change at line 652 skipping to change at line 628
ret.append('total cpu usage') ret.append('total cpu usage')
else: else:
ret.append('cpu' + name + ' usage') ret.append('cpu' + name + ' usage')
return ret return ret
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 9: continue if len(l) < 9: continue
for name in self.vars: for name in self.vars:
if l[0] == 'cpu' + name or ( l[0] == 'cpu' and name == 'total' ) : if l[0] == 'cpu' + name or ( l[0] == 'cpu' and name == 'total' ) :
self.set2[name] = ( long(l[1]) + long(l[2]) + long(l[6]) + l ong(l[7]), long(l[3]), long(l[4]), long(l[5]), long(l[8]) ) self.set2[name] = ( int(l[1]) + int(l[2]) + int(l[6]) + int( l[7]), int(l[3]), int(l[4]), int(l[5]), int(l[8]) )
for name in self.vars: for name in self.vars:
for i in range(self.cols): for i in list(range(self.cols)):
if sum(self.set2[name]) > sum(self.set1[name]): if sum(self.set2[name]) > sum(self.set1[name]):
self.val[name][i] = 100.0 * (self.set2[name][i] - self.set1[ name][i]) / (sum(self.set2[name]) - sum(self.set1[name])) self.val[name][i] = 100.0 * (self.set2[name][i] - self.set1[ name][i]) / (sum(self.set2[name]) - sum(self.set1[name]))
else: else:
self.val[name][i] = 0 self.val[name][i] = 0
# print >>sys.stderr, "Error: tick problem detected, this sho uld never happen !" # print("Error: tick problem detected, this should never happ en !", file=sys.stderr)
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_cpu_use(dstat_cpu): class dstat_cpu_use(dstat_cpu):
def __init__(self): def __init__(self):
self.name = 'per cpu usage' self.name = 'per cpu usage'
self.type = 'p' self.type = 'p'
self.width = 3 self.width = 3
self.scale = 34 self.scale = 34
self.open('/proc/stat') self.open('/proc/stat')
self.cols = 7 self.cols = 7
if not op.cpulist: if not op.cpulist:
self.vars = [ str(x) for x in range(cpunr) ] self.vars = [ str(x) for x in list(range(cpunr)) ]
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 9: continue if len(l) < 9: continue
for name in self.vars: for name in self.vars:
if l[0] == 'cpu' + name or ( l[0] == 'cpu' and name == 'total' ) : if l[0] == 'cpu' + name or ( l[0] == 'cpu' and name == 'total' ) :
self.set2[name] = ( long(l[1]) + long(l[2]), long(l[3]), lon g(l[4]), long(l[5]), long(l[6]), long(l[7]), long(l[8]) ) self.set2[name] = ( int(l[1]) + int(l[2]), int(l[3]), int(l[ 4]), int(l[5]), int(l[6]), int(l[7]), int(l[8]) )
for name in self.vars: for name in self.vars:
if sum(self.set2[name]) > sum(self.set1[name]): if sum(self.set2[name]) > sum(self.set1[name]):
self.val[name] = 100.0 - 100.0 * (self.set2[name][2] - self.set1 [name][2]) / (sum(self.set2[name]) - sum(self.set1[name])) self.val[name] = 100.0 - 100.0 * (self.set2[name][2] - self.set1 [name][2]) / (sum(self.set2[name]) - sum(self.set1[name]))
else: else:
self.val[name] = 0 self.val[name] = 0
# print >>sys.stderr, "Error: tick problem detected, this sho uld never happen !" # print("Error: tick problem detected, this should never happ en !", file=sys.stderr)
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_cpu_adv(dstat_cpu): class dstat_cpu_adv(dstat_cpu):
def __init__(self): def __init__(self):
self.nick = ( 'usr', 'sys', 'idl', 'wai', 'hiq', 'siq', 'stl' ) self.nick = ( 'usr', 'sys', 'idl', 'wai', 'hiq', 'siq', 'stl' )
self.type = 'p' self.type = 'p'
self.width = 3 self.width = 3
self.scale = 34 self.scale = 34
self.open('/proc/stat') self.open('/proc/stat')
self.cols = 7 self.cols = 7
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 9: continue if len(l) < 9: continue
for name in self.vars: for name in self.vars:
if l[0] == 'cpu' + name or ( l[0] == 'cpu' and name == 'total' ) : if l[0] == 'cpu' + name or ( l[0] == 'cpu' and name == 'total' ) :
self.set2[name] = ( long(l[1]) + long(l[2]), long(l[3]), lon g(l[4]), long(l[5]), long(l[6]), long(l[7]), long(l[8]) ) self.set2[name] = ( int(l[1]) + int(l[2]), int(l[3]), int(l[ 4]), int(l[5]), int(l[6]), int(l[7]), int(l[8]) )
for name in self.vars: for name in self.vars:
for i in range(self.cols): for i in list(range(self.cols)):
if sum(self.set2[name]) > sum(self.set1[name]): if sum(self.set2[name]) > sum(self.set1[name]):
self.val[name][i] = 100.0 * (self.set2[name][i] - self.set1[ name][i]) / (sum(self.set2[name]) - sum(self.set1[name])) self.val[name][i] = 100.0 * (self.set2[name][i] - self.set1[ name][i]) / (sum(self.set2[name]) - sum(self.set1[name]))
else: else:
self.val[name][i] = 0 self.val[name][i] = 0
# print >>sys.stderr, "Error: tick problem detected, this sho uld never happen !" # print("Error: tick problem detected, this should never happ en !", file=sys.stderr)
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_cpu24(dstat): class dstat_cpu24(dstat):
def __init__(self): def __init__(self):
self.nick = ( 'usr', 'sys', 'idl') self.nick = ( 'usr', 'sys', 'idl')
self.type = 'p' self.type = 'p'
self.width = 3 self.width = 3
self.scale = 34 self.scale = 34
skipping to change at line 769 skipping to change at line 745
if name == 'total': if name == 'total':
ret.append('cpu usage') ret.append('cpu usage')
else: else:
ret.append('cpu' + name) ret.append('cpu' + name)
return ret return ret
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
for name in self.vars: for name in self.vars:
if l[0] == 'cpu' + name or ( l[0] == 'cpu' and name == 'total' ) : if l[0] == 'cpu' + name or ( l[0] == 'cpu' and name == 'total' ) :
self.set2[name] = ( long(l[1]) + long(l[2]), long(l[3]), lon g(l[4]) ) self.set2[name] = ( int(l[1]) + int(l[2]), int(l[3]), int(l[ 4]) )
for name in self.vars: for name in self.vars:
for i in range(self.cols): for i in list(range(self.cols)):
self.val[name][i] = 100.0 * (self.set2[name][i] - self.set1[name ][i]) / (sum(self.set2[name]) - sum(self.set1[name])) self.val[name][i] = 100.0 * (self.set2[name][i] - self.set1[name ][i]) / (sum(self.set2[name]) - sum(self.set1[name]))
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_disk(dstat): class dstat_disk(dstat):
def __init__(self): def __init__(self):
self.nick = ('read', 'writ') self.nick = ('read', 'writ')
self.type = 'b' self.type = 'b'
self.diskfilter = re.compile('^([hsv]d[a-z]+\d+|cciss/c\d+d\d+p\d+|dm-\d +|md\d+|mmcblk\d+p\d0|VxVM\d+)$') self.diskfilter = re.compile('^([hsv]d[a-z]+\d+|cciss/c\d+d\d+p\d+|dm-\d +|md\d+|mmcblk\d+p\d0|VxVM\d+)$')
skipping to change at line 795 skipping to change at line 771
def discover(self, *objlist): def discover(self, *objlist):
ret = [] ret = []
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 13: continue if len(l) < 13: continue
if l[3:] == ['0',] * 11: continue if l[3:] == ['0',] * 11: continue
name = l[2] name = l[2]
ret.append(name) ret.append(name)
for item in objlist: ret.append(item) for item in objlist: ret.append(item)
if not ret: if not ret:
raise Exception, "No suitable block devices found to monitor" raise Exception("No suitable block devices found to monitor")
return ret return ret
def basename(self, disk): def basename(self, disk):
"Strip /dev/ and convert symbolic link" "Strip /dev/ and convert symbolic link"
if disk[:5] == '/dev/': if disk[:5] == '/dev/':
# file or symlink # file or symlink
if os.path.exists(disk): if os.path.exists(disk):
# e.g. /dev/disk/by-uuid/15e40cc5-85de-40ea-b8fb-cb3a2eaf872 # e.g. /dev/disk/by-uuid/15e40cc5-85de-40ea-b8fb-cb3a2eaf872
if os.path.islink(disk): if os.path.islink(disk):
target = os.readlink(disk) target = os.readlink(disk)
# convert relative pathname to absolute # convert relative pathname to absolute
if target[0] != '/': if target[0] != '/':
target = os.path.join(os.path.dirname(disk), target) target = os.path.join(os.path.dirname(disk), target)
target = os.path.normpath(target) target = os.path.normpath(target)
print 'dstat: symlink %s -> %s' % (disk, target) print('dstat: symlink %s -> %s' % (disk, target))
disk = target disk = target
# trim leading /dev/ # trim leading /dev/
return disk[5:] return disk[5:]
else: else:
print 'dstat: %s does not exist' % disk print('dstat: %s does not exist' % disk)
else: else:
return disk return disk
def vars(self): def vars(self):
ret = [] ret = []
if op.disklist: if op.disklist:
varlist = map(self.basename, op.disklist) varlist = list(map(self.basename, op.disklist))
elif not op.full: elif not op.full:
varlist = ('total',) varlist = ('total',)
else: else:
varlist = [] varlist = []
for name in self.discover: for name in self.discover:
if self.diskfilter.match(name): continue if self.diskfilter.match(name): continue
if name not in blockdevices(): continue if name not in blockdevices(): continue
varlist.append(name) varlist.append(name)
# if len(varlist) > 2: varlist = varlist[0:2] # if len(varlist) > 2: varlist = varlist[0:2]
varlist.sort() varlist.sort()
for name in varlist: for name in varlist:
if name in self.discover + ['total'] + op.diskset.keys(): if name in self.discover + ['total'] or name in op.diskset:
ret.append(name) ret.append(name)
return ret return ret
def name(self): def name(self):
return ['dsk/'+sysfs_dev(name) for name in self.vars] return ['dsk/'+sysfs_dev(name) for name in self.vars]
def extract(self): def extract(self):
for name in self.vars: self.set2[name] = (0, 0) for name in self.vars: self.set2[name] = (0, 0)
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 13: continue if len(l) < 13: continue
if l[5] == '0' and l[9] == '0': continue if l[5] == '0' and l[9] == '0': continue
name = l[2] name = l[2]
if l[3:] == ['0',] * 11: continue if l[3:] == ['0',] * 11: continue
if not self.diskfilter.match(name): if not self.diskfilter.match(name):
self.set2['total'] = ( self.set2['total'][0] + long(l[5]), self. set2['total'][1] + long(l[9]) ) self.set2['total'] = ( self.set2['total'][0] + int(l[5]), self.s et2['total'][1] + int(l[9]) )
if name in self.vars and name != 'total': if name in self.vars and name != 'total':
self.set2[name] = ( self.set2[name][0] + long(l[5]), self.set2[n ame][1] + long(l[9]) ) self.set2[name] = ( self.set2[name][0] + int(l[5]), self.set2[na me][1] + int(l[9]) )
for diskset in self.vars: for diskset in self.vars:
if diskset in op.diskset.keys(): if diskset in op.diskset:
for disk in op.diskset[diskset]: for disk in op.diskset[diskset]:
if fnmatch.fnmatch(name, disk): if fnmatch.fnmatch(name, disk):
self.set2[diskset] = ( self.set2[diskset][0] + long( l[5]), self.set2[diskset][1] + long(l[9]) ) self.set2[diskset] = ( self.set2[diskset][0] + int(l [5]), self.set2[diskset][1] + int(l[9]) )
for name in self.set2.keys(): for name in self.set2:
self.val[name] = map(lambda x, y: (y - x) * 512.0 / elapsed, self.se self.val[name] = list(map(lambda x, y: (y - x) * 512.0 / elapsed, se
t1[name], self.set2[name]) lf.set1[name], self.set2[name]))
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_disk24(dstat): class dstat_disk24(dstat):
def __init__(self): def __init__(self):
self.nick = ('read', 'writ') self.nick = ('read', 'writ')
self.type = 'b' self.type = 'b'
self.diskfilter = re.compile('^([hsv]d[a-z]+\d+|cciss/c\d+d\d+p\d+|dm-\d +|md\d+|mmcblk\d+p\d0|VxVM\d+)$') self.diskfilter = re.compile('^([hsv]d[a-z]+\d+|cciss/c\d+d\d+p\d+|dm-\d +|md\d+|mmcblk\d+p\d0|VxVM\d+)$')
self.open('/proc/partitions') self.open('/proc/partitions')
if self.fd and not self.discover: if self.fd and not self.discover:
raise Exception, 'Kernel has no per-partition I/O accounting [CONFIG _BLK_STATS], use at least 2.4.20' raise Exception('Kernel has no per-partition I/O accounting [CONFIG_ BLK_STATS], use at least 2.4.20')
self.cols = 2 self.cols = 2
def discover(self, *objlist): def discover(self, *objlist):
ret = [] ret = []
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 15 or l[0] == 'major' or int(l[1]) % 16 != 0: continue if len(l) < 15 or l[0] == 'major' or int(l[1]) % 16 != 0: continue
name = l[3] name = l[3]
ret.append(name) ret.append(name)
for item in objlist: ret.append(item) for item in objlist: ret.append(item)
if not ret: if not ret:
raise Exception, "No suitable block devices found to monitor" raise Exception("No suitable block devices found to monitor")
return ret return ret
def basename(self, disk): def basename(self, disk):
"Strip /dev/ and convert symbolic link" "Strip /dev/ and convert symbolic link"
if disk[:5] == '/dev/': if disk[:5] == '/dev/':
# file or symlink # file or symlink
if os.path.exists(disk): if os.path.exists(disk):
# e.g. /dev/disk/by-uuid/15e40cc5-85de-40ea-b8fb-cb3a2eaf872 # e.g. /dev/disk/by-uuid/15e40cc5-85de-40ea-b8fb-cb3a2eaf872
if os.path.islink(disk): if os.path.islink(disk):
target = os.readlink(disk) target = os.readlink(disk)
# convert relative pathname to absolute # convert relative pathname to absolute
if target[0] != '/': if target[0] != '/':
target = os.path.join(os.path.dirname(disk), target) target = os.path.join(os.path.dirname(disk), target)
target = os.path.normpath(target) target = os.path.normpath(target)
print 'dstat: symlink %s -> %s' % (disk, target) print('dstat: symlink %s -> %s' % (disk, target))
disk = target disk = target
# trim leading /dev/ # trim leading /dev/
return disk[5:] return disk[5:]
else: else:
print 'dstat: %s does not exist' % disk print('dstat: %s does not exist' % disk)
else: else:
return disk return disk
def vars(self): def vars(self):
ret = [] ret = []
if op.disklist: if op.disklist:
varlist = map(self.basename, op.disklist) varlist = list(map(self.basename, op.disklist))
elif not op.full: elif not op.full:
varlist = ('total',) varlist = ('total',)
else: else:
varlist = [] varlist = []
for name in self.discover: for name in self.discover:
if self.diskfilter.match(name): continue if self.diskfilter.match(name): continue
varlist.append(name) varlist.append(name)
# if len(varlist) > 2: varlist = varlist[0:2] # if len(varlist) > 2: varlist = varlist[0:2]
varlist.sort() varlist.sort()
for name in varlist: for name in varlist:
if name in self.discover + ['total'] + op.diskset.keys(): if name in self.discover + ['total'] or name in op.diskset:
ret.append(name) ret.append(name)
return ret return ret
def name(self): def name(self):
return ['dsk/'+sysfs_dev(name) for name in self.vars] return ['dsk/'+sysfs_dev(name) for name in self.vars]
def extract(self): def extract(self):
for name in self.vars: self.set2[name] = (0, 0) for name in self.vars: self.set2[name] = (0, 0)
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 15 or l[0] == 'major' or int(l[1]) % 16 != 0: continue if len(l) < 15 or l[0] == 'major' or int(l[1]) % 16 != 0: continue
name = l[3] name = l[3]
if not self.diskfilter.match(name): if not self.diskfilter.match(name):
self.set2['total'] = ( self.set2['total'][0] + long(l[6]), self. set2['total'][1] + long(l[10]) ) self.set2['total'] = ( self.set2['total'][0] + int(l[6]), self.s et2['total'][1] + int(l[10]) )
if name in self.vars: if name in self.vars:
self.set2[name] = ( self.set2[name][0] + long(l[6]), self.set2[n ame][1] + long(l[10]) ) self.set2[name] = ( self.set2[name][0] + int(l[6]), self.set2[na me][1] + int(l[10]) )
for diskset in self.vars: for diskset in self.vars:
if diskset in op.diskset.keys(): if diskset in op.diskset:
for disk in op.diskset[diskset]: for disk in op.diskset[diskset]:
if fnmatch.fnmatch(name, disk): if fnmatch.fnmatch(name, disk):
self.set2[diskset] = ( self.set2[diskset][0] + long( l[6]), self.set2[diskset][1] + long(l[10]) ) self.set2[diskset] = ( self.set2[diskset][0] + int(l [6]), self.set2[diskset][1] + int(l[10]) )
for name in self.set2.keys(): for name in self.set2:
self.val[name] = map(lambda x, y: (y - x) * 512.0 / elapsed, self.se self.val[name] = list(map(lambda x, y: (y - x) * 512.0 / elapsed, se
t1[name], self.set2[name]) lf.set1[name], self.set2[name]))
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
### FIXME: Needs rework, does anyone care ? ### FIXME: Needs rework, does anyone care ?
class dstat_disk24_old(dstat): class dstat_disk24_old(dstat):
def __init__(self): def __init__(self):
self.nick = ('read', 'writ') self.nick = ('read', 'writ')
self.type = 'b' self.type = 'b'
self.diskfilter = re.compile('^([hsv]d[a-z]+\d+|cciss/c\d+d\d+p\d+|dm-\d +|md\d+|mmcblk\d+p\d0|VxVM\d+)$') self.diskfilter = re.compile('^([hsv]d[a-z]+\d+|cciss/c\d+d\d+p\d+|dm-\d +|md\d+|mmcblk\d+p\d0|VxVM\d+)$')
skipping to change at line 974 skipping to change at line 950
for pair in line.split()[1:]: for pair in line.split()[1:]:
m = self.regexp.match(pair) m = self.regexp.match(pair)
if not m: continue if not m: continue
l = m.groups() l = m.groups()
if len(l) < 4: continue if len(l) < 4: continue
name = dev(int(l[0]), int(l[1])) name = dev(int(l[0]), int(l[1]))
ret.append(name) ret.append(name)
break break
for item in objlist: ret.append(item) for item in objlist: ret.append(item)
if not ret: if not ret:
raise Exception, "No suitable block devices found to monitor" raise Exception("No suitable block devices found to monitor")
return ret return ret
def vars(self): def vars(self):
ret = [] ret = []
if op.disklist: if op.disklist:
varlist = op.disklist varlist = op.disklist
elif not op.full: elif not op.full:
varlist = ('total',) varlist = ('total',)
else: else:
varlist = [] varlist = []
for name in self.discover: for name in self.discover:
if self.diskfilter.match(name): continue if self.diskfilter.match(name): continue
varlist.append(name) varlist.append(name)
# if len(varlist) > 2: varlist = varlist[0:2] # if len(varlist) > 2: varlist = varlist[0:2]
varlist.sort() varlist.sort()
for name in varlist: for name in varlist:
if name in self.discover + ['total'] + op.diskset.keys(): if name in self.discover + ['total'] or name in op.diskset:
ret.append(name) ret.append(name)
return ret return ret
def name(self): def name(self):
return ['dsk/'+name for name in self.vars] return ['dsk/'+name for name in self.vars]
def extract(self): def extract(self):
for name in self.vars: self.set2[name] = (0, 0) for name in self.vars: self.set2[name] = (0, 0)
for line in self.splitlines(':'): for line in self.splitlines(':'):
if len(l) < 3: continue if len(l) < 3: continue
name = l[0] name = l[0]
if name != 'disk_io': continue if name != 'disk_io': continue
for pair in line.split()[1:]: for pair in line.split()[1:]:
m = self.regexp.match(pair) m = self.regexp.match(pair)
if not m: continue if not m: continue
l = m.groups() l = m.groups()
if len(l) < 4: continue if len(l) < 4: continue
name = dev(int(l[0]), int(l[1])) name = dev(int(l[0]), int(l[1]))
if not self.diskfilter.match(name): if not self.diskfilter.match(name):
self.set2['total'] = ( self.set2['total'][0] + long(l[2]), s elf.set2['total'][1] + long(l[3]) ) self.set2['total'] = ( self.set2['total'][0] + int(l[2]), se lf.set2['total'][1] + int(l[3]) )
if name in self.vars and name != 'total': if name in self.vars and name != 'total':
self.set2[name] = ( self.set2[name][0] + long(l[2]), self.se t2[name][1] + long(l[3]) ) self.set2[name] = ( self.set2[name][0] + int(l[2]), self.set 2[name][1] + int(l[3]) )
for diskset in self.vars: for diskset in self.vars:
if diskset in op.diskset.keys(): if diskset in op.diskset:
for disk in op.diskset[diskset]: for disk in op.diskset[diskset]:
if fnmatch.fnmatch(name, disk): if fnmatch.fnmatch(name, disk):
self.set2[diskset] = ( self.set2[diskset][0] + l ong(l[2]), self.set2[diskset][1] + long(l[3]) ) self.set2[diskset] = ( self.set2[diskset][0] + i nt(l[2]), self.set2[diskset][1] + int(l[3]) )
break break
for name in self.set2.keys(): for name in self.set2:
self.val[name] = map(lambda x, y: (y - x) * 512.0 / elapsed, self.se self.val[name] = list(map(lambda x, y: (y - x) * 512.0 / elapsed, se
t1[name], self.set2[name]) lf.set1[name], self.set2[name]))
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_epoch(dstat): class dstat_epoch(dstat):
def __init__(self): def __init__(self):
self.name = 'epoch' self.name = 'epoch'
self.vars = ('epoch',) self.vars = ('epoch',)
self.width = 10 self.width = 10
if op.debug: if op.debug:
skipping to change at line 1053 skipping to change at line 1029
self.name = 'filesystem' self.name = 'filesystem'
self.vars = ('files', 'inodes') self.vars = ('files', 'inodes')
self.type = 'd' self.type = 'd'
self.width = 6 self.width = 6
self.scale = 1000 self.scale = 1000
def extract(self): def extract(self):
for line in dopen('/proc/sys/fs/file-nr'): for line in dopen('/proc/sys/fs/file-nr'):
l = line.split() l = line.split()
if len(l) < 1: continue if len(l) < 1: continue
self.val['files'] = long(l[0]) self.val['files'] = int(l[0])
for line in dopen('/proc/sys/fs/inode-nr'): for line in dopen('/proc/sys/fs/inode-nr'):
l = line.split() l = line.split()
if len(l) < 2: continue if len(l) < 2: continue
self.val['inodes'] = long(l[0]) - long(l[1]) self.val['inodes'] = int(l[0]) - int(l[1])
class dstat_int(dstat): class dstat_int(dstat):
def __init__(self): def __init__(self):
self.name = 'interrupts' self.name = 'interrupts'
self.type = 'd' self.type = 'd'
self.width = 5 self.width = 5
self.scale = 1000 self.scale = 1000
self.open('/proc/stat') self.open('/proc/stat')
self.intmap = self.intmap() self.intmap = self.intmap()
skipping to change at line 1085 skipping to change at line 1061
ret[l1] = l1 ret[l1] = l1
for name in l2: for name in l2:
ret[name.strip().lower()] = l1 ret[name.strip().lower()] = l1
return ret return ret
def discover(self, *objlist): def discover(self, *objlist):
ret = [] ret = []
for l in self.splitlines(): for l in self.splitlines():
if l[0] != 'intr': continue if l[0] != 'intr': continue
for name, i in enumerate(l[2:]): for name, i in enumerate(l[2:]):
if long(i) > 10: ret.append(str(name)) if int(i) > 10: ret.append(str(name))
return ret return ret
# def check(self): # def check(self):
# if self.fd[0] and self.vars: # if self.fd[0] and self.vars:
# self.fd[0].seek(0) # self.fd[0].seek(0)
# for l in self.fd[0].splitlines(): # for l in self.fd[0].splitlines():
# if l[0] != 'intr': continue # if l[0] != 'intr': continue
# return True # return True
# return False # return False
skipping to change at line 1109 skipping to change at line 1085
varlist = op.intlist varlist = op.intlist
else: else:
varlist = self.discover varlist = self.discover
for name in varlist: for name in varlist:
if name in ('0', '1', '2', '8', 'NMI', 'LOC', 'MIS', 'CPU0'): if name in ('0', '1', '2', '8', 'NMI', 'LOC', 'MIS', 'CPU0'):
varlist.remove(name) varlist.remove(name)
if not op.full and len(varlist) > 3: varlist = varlist[-3:] if not op.full and len(varlist) > 3: varlist = varlist[-3:]
for name in varlist: for name in varlist:
if name in self.discover + ['total',]: if name in self.discover + ['total',]:
ret.append(name) ret.append(name)
elif name.lower() in self.intmap.keys(): elif name.lower() in self.intmap:
ret.append(self.intmap[name.lower()]) ret.append(self.intmap[name.lower()])
return ret return ret
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if not l or l[0] != 'intr': continue if not l or l[0] != 'intr': continue
for name in self.vars: for name in self.vars:
if name != 'total': if name != 'total':
self.set2[name] = long(l[int(name) + 2]) self.set2[name] = int(l[int(name) + 2])
self.set2['total'] = long(l[1]) self.set2['total'] = int(l[1])
for name in self.vars: for name in self.vars:
self.val[name] = (self.set2[name] - self.set1[name]) * 1.0 / elapsed self.val[name] = (self.set2[name] - self.set1[name]) * 1.0 / elapsed
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_int24(dstat): class dstat_int24(dstat):
def __init__(self): def __init__(self):
self.name = 'interrupts' self.name = 'interrupts'
skipping to change at line 1151 skipping to change at line 1127
ret[l1] = l1 ret[l1] = l1
for name in l2: for name in l2:
ret[name.strip().lower()] = l1 ret[name.strip().lower()] = l1
return ret return ret
def discover(self, *objlist): def discover(self, *objlist):
ret = [] ret = []
for l in self.splitlines(): for l in self.splitlines():
if len(l) < cpunr+1: continue if len(l) < cpunr+1: continue
name = l[0].split(':')[0] name = l[0].split(':')[0]
if long(l[1]) > 10: if int(l[1]) > 10:
ret.append(name) ret.append(name)
return ret return ret
# def check(self): # def check(self):
# if self.fd and self.discover: # if self.fd and self.discover:
# self.fd[0].seek(0) # self.fd[0].seek(0)
# for l in self.fd[0].splitlines(): # for l in self.fd[0].splitlines():
# if l[0] != 'intr' or len(l) > 2: continue # if l[0] != 'intr' or len(l) > 2: continue
# return True # return True
# return False # return False
skipping to change at line 1176 skipping to change at line 1152
varlist = op.intlist varlist = op.intlist
else: else:
varlist = self.discover varlist = self.discover
for name in varlist: for name in varlist:
if name in ('0', '1', '2', '8', 'CPU0', 'ERR', 'LOC', 'MIS', 'NM I'): if name in ('0', '1', '2', '8', 'CPU0', 'ERR', 'LOC', 'MIS', 'NM I'):
varlist.remove(name) varlist.remove(name)
if not op.full and len(varlist) > 3: varlist = varlist[-3:] if not op.full and len(varlist) > 3: varlist = varlist[-3:]
for name in varlist: for name in varlist:
if name in self.discover: if name in self.discover:
ret.append(name) ret.append(name)
elif name.lower() in self.intmap.keys(): elif name.lower() in self.intmap:
ret.append(self.intmap[name.lower()]) ret.append(self.intmap[name.lower()])
return ret return ret
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < cpunr+1: continue if len(l) < cpunr+1: continue
name = l[0].split(':')[0] name = l[0].split(':')[0]
if name in self.vars: if name in self.vars:
self.set2[name] = 0 self.set2[name] = 0
for i in l[1:1+cpunr]: for i in l[1:1+cpunr]:
self.set2[name] = self.set2[name] + long(i) self.set2[name] = self.set2[name] + int(i)
# elif len(l) > 2 + cpunr: # elif len(l) > 2 + cpunr:
# for hw in self.vars: # for hw in self.vars:
# for mod in l[2+cpunr:]: # for mod in l[2+cpunr:]:
# self.set2[mod] = long(l[1]) # self.set2[mod] = int(l[1])
for name in self.set2.keys(): for name in self.set2:
self.val[name] = (self.set2[name] - self.set1[name]) * 1.0 / elapsed self.val[name] = (self.set2[name] - self.set1[name]) * 1.0 / elapsed
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_io(dstat): class dstat_io(dstat):
def __init__(self): def __init__(self):
self.nick = ('read', 'writ') self.nick = ('read', 'writ')
self.type = 'f' self.type = 'f'
self.width = 5 self.width = 5
skipping to change at line 1218 skipping to change at line 1194
def discover(self, *objlist): def discover(self, *objlist):
ret = [] ret = []
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 13: continue if len(l) < 13: continue
if l[3:] == ['0',] * 11: continue if l[3:] == ['0',] * 11: continue
name = l[2] name = l[2]
ret.append(name) ret.append(name)
for item in objlist: ret.append(item) for item in objlist: ret.append(item)
if not ret: if not ret:
raise Exception, "No suitable block devices found to monitor" raise Exception("No suitable block devices found to monitor")
return ret return ret
def vars(self): def vars(self):
ret = [] ret = []
if op.disklist: if op.disklist:
varlist = op.disklist varlist = op.disklist
elif not op.full: elif not op.full:
varlist = ('total',) varlist = ('total',)
else: else:
varlist = [] varlist = []
for name in self.discover: for name in self.discover:
if self.diskfilter.match(name): continue if self.diskfilter.match(name): continue
if name not in blockdevices(): continue if name not in blockdevices(): continue
varlist.append(name) varlist.append(name)
# if len(varlist) > 2: varlist = varlist[0:2] # if len(varlist) > 2: varlist = varlist[0:2]
varlist.sort() varlist.sort()
for name in varlist: for name in varlist:
if name in self.discover + ['total'] + op.diskset.keys(): if name in self.discover + ['total'] or name in op.diskset:
ret.append(name) ret.append(name)
return ret return ret
def name(self): def name(self):
return ['io/'+name for name in self.vars] return ['io/'+name for name in self.vars]
def extract(self): def extract(self):
for name in self.vars: self.set2[name] = (0, 0) for name in self.vars: self.set2[name] = (0, 0)
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 13: continue if len(l) < 13: continue
if l[3] == '0' and l[7] == '0': continue if l[3] == '0' and l[7] == '0': continue
name = l[2] name = l[2]
if l[3:] == ['0',] * 11: continue if l[3:] == ['0',] * 11: continue
if not self.diskfilter.match(name): if not self.diskfilter.match(name):
self.set2['total'] = ( self.set2['total'][0] + long(l[3]), self. set2['total'][1] + long(l[7]) ) self.set2['total'] = ( self.set2['total'][0] + int(l[3]), self.s et2['total'][1] + int(l[7]) )
if name in self.vars and name != 'total': if name in self.vars and name != 'total':
self.set2[name] = ( self.set2[name][0] + long(l[3]), self.set2[n ame][1] + long(l[7]) ) self.set2[name] = ( self.set2[name][0] + int(l[3]), self.set2[na me][1] + int(l[7]) )
for diskset in self.vars: for diskset in self.vars:
if diskset in op.diskset.keys(): if diskset in op.diskset:
for disk in op.diskset[diskset]: for disk in op.diskset[diskset]:
if fnmatch.fnmatch(name, disk): if fnmatch.fnmatch(name, disk):
self.set2[diskset] = ( self.set2[diskset][0] + long( l[3]), self.set2[diskset][1] + long(l[7]) ) self.set2[diskset] = ( self.set2[diskset][0] + int(l [3]), self.set2[diskset][1] + int(l[7]) )
for name in self.set2.keys(): for name in self.set2:
self.val[name] = map(lambda x, y: (y - x) * 1.0 / elapsed, self.set1 self.val[name] = list(map(lambda x, y: (y - x) * 1.0 / elapsed, self
[name], self.set2[name]) .set1[name], self.set2[name]))
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_ipc(dstat): class dstat_ipc(dstat):
def __init__(self): def __init__(self):
self.name = 'sysv ipc' self.name = 'sysv ipc'
self.vars = ('msg', 'sem', 'shm') self.vars = ('msg', 'sem', 'shm')
self.type = 'd' self.type = 'd'
self.width = 3 self.width = 3
skipping to change at line 1328 skipping to change at line 1304
self.vars = ('MemUsed', 'MemFree', 'Buffers', 'Cached') self.vars = ('MemUsed', 'MemFree', 'Buffers', 'Cached')
self.open('/proc/meminfo') self.open('/proc/meminfo')
def extract(self): def extract(self):
adv_extract_vars = ('MemTotal', 'Shmem', 'SReclaimable') adv_extract_vars = ('MemTotal', 'Shmem', 'SReclaimable')
adv_val={} adv_val={}
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 2: continue if len(l) < 2: continue
name = l[0].split(':')[0] name = l[0].split(':')[0]
if name in self.vars: if name in self.vars:
self.val[name] = long(l[1]) * 1024.0 self.val[name] = int(l[1]) * 1024.0
if name in adv_extract_vars: if name in adv_extract_vars:
adv_val[name] = long(l[1]) * 1024.0 adv_val[name] = int(l[1]) * 1024.0
self.val['MemUsed'] = adv_val['MemTotal'] - self.val['MemFree'] - self.v al['Buffers'] - self.val['Cached'] - adv_val['SReclaimable'] + adv_val['Shmem'] self.val['MemUsed'] = adv_val['MemTotal'] - self.val['MemFree'] - self.v al['Buffers'] - self.val['Cached'] - adv_val['SReclaimable'] + adv_val['Shmem']
class dstat_mem_adv(dstat_mem): class dstat_mem_adv(dstat_mem):
""" """
Advanced memory usage Advanced memory usage
Displays memory usage similarly to the internal plugin but with added total, shared and reclaimable counters. Displays memory usage similarly to the internal plugin but with added total, shared and reclaimable counters.
Additionally, shared memory is added and reclaimable memory is subtracted fr om the used memory counter. Additionally, shared memory is added and reclaimable memory is subtracted fr om the used memory counter.
""" """
skipping to change at line 1381 skipping to change at line 1357
elif not op.full: elif not op.full:
varlist = ('total',) varlist = ('total',)
else: else:
varlist = self.discover varlist = self.discover
# if len(varlist) > 2: varlist = varlist[0:2] # if len(varlist) > 2: varlist = varlist[0:2]
varlist.sort() varlist.sort()
for name in varlist: for name in varlist:
if name in self.discover + ['total', 'lo']: if name in self.discover + ['total', 'lo']:
ret.append(name) ret.append(name)
if not ret: if not ret:
raise Exception, "No suitable network interfaces found to monitor" raise Exception("No suitable network interfaces found to monitor")
return ret return ret
def name(self): def name(self):
return ['net/'+name for name in self.vars] return ['net/'+name for name in self.vars]
def extract(self): def extract(self):
self.set2['total'] = [0, 0] self.set2['total'] = [0, 0]
for l in self.splitlines(replace=':'): for l in self.splitlines(replace=':'):
if len(l) < 17: continue if len(l) < 17: continue
if l[2] == '0' and l[10] == '0': continue if l[2] == '0' and l[10] == '0': continue
name = l[0] name = l[0]
if name in self.vars : if name in self.vars :
self.set2[name] = ( long(l[1]), long(l[9]) ) self.set2[name] = ( int(l[1]), int(l[9]) )
if not self.totalfilter.match(name): if not self.totalfilter.match(name):
self.set2['total'] = ( self.set2['total'][0] + long(l[1]), self. set2['total'][1] + long(l[9])) self.set2['total'] = ( self.set2['total'][0] + int(l[1]), self.s et2['total'][1] + int(l[9]))
if update: if update:
for name in self.set2.keys(): for name in self.set2:
self.val[name] = map(lambda x, y: (y - x) * 1.0 / elapsed, self. self.val[name] = list(map(lambda x, y: (y - x) * 1.0 / elapsed,
set1[name], self.set2[name]) self.set1[name], self.set2[name]))
if self.val[name][0] < 0: self.val[name][0] += maxint + 1 if self.val[name][0] < 0: self.val[name][0] += maxint + 1
if self.val[name][1] < 0: self.val[name][1] += maxint + 1 if self.val[name][1] < 0: self.val[name][1] += maxint + 1
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_page(dstat): class dstat_page(dstat):
def __init__(self): def __init__(self):
self.name = 'paging' self.name = 'paging'
self.nick = ('in', 'out') self.nick = ('in', 'out')
self.vars = ('pswpin', 'pswpout') self.vars = ('pswpin', 'pswpout')
self.type = 'd' self.type = 'd'
self.open('/proc/vmstat') self.open('/proc/vmstat')
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 2: continue if len(l) < 2: continue
name = l[0] name = l[0]
if name in self.vars: if name in self.vars:
self.set2[name] = long(l[1]) self.set2[name] = int(l[1])
for name in self.vars: for name in self.vars:
self.val[name] = (self.set2[name] - self.set1[name]) * pagesize * 1. 0 / elapsed self.val[name] = (self.set2[name] - self.set1[name]) * pagesize * 1. 0 / elapsed
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_page24(dstat): class dstat_page24(dstat):
def __init__(self): def __init__(self):
self.name = 'paging' self.name = 'paging'
self.nick = ('in', 'out') self.nick = ('in', 'out')
self.vars = ('pswpin', 'pswpout') self.vars = ('pswpin', 'pswpout')
self.type = 'd' self.type = 'd'
self.open('/proc/stat') self.open('/proc/stat')
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 3: continue if len(l) < 3: continue
name = l[0] name = l[0]
if name != 'swap': continue if name != 'swap': continue
self.set2['pswpin'] = long(l[1]) self.set2['pswpin'] = int(l[1])
self.set2['pswpout'] = long(l[2]) self.set2['pswpout'] = int(l[2])
break break
for name in self.vars: for name in self.vars:
self.val[name] = (self.set2[name] - self.set1[name]) * pagesize * 1. 0 / elapsed self.val[name] = (self.set2[name] - self.set1[name]) * pagesize * 1. 0 / elapsed
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_proc(dstat): class dstat_proc(dstat):
def __init__(self): def __init__(self):
skipping to change at line 1467 skipping to change at line 1443
self.width = 3 self.width = 3
self.scale = 10 self.scale = 10
self.open('/proc/stat') self.open('/proc/stat')
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 2: continue if len(l) < 2: continue
name = l[0] name = l[0]
if name == 'processes': if name == 'processes':
self.val['processes'] = 0 self.val['processes'] = 0
self.set2[name] = long(l[1]) self.set2[name] = int(l[1])
elif name == 'procs_running': elif name == 'procs_running':
self.set2[name] = self.set2[name] + long(l[1]) - 1 self.set2[name] = self.set2[name] + int(l[1]) - 1
elif name == 'procs_blocked': elif name == 'procs_blocked':
self.set2[name] = self.set2[name] + long(l[1]) self.set2[name] = self.set2[name] + int(l[1])
self.val['processes'] = (self.set2['processes'] - self.set1['processes'] ) * 1.0 / elapsed self.val['processes'] = (self.set2['processes'] - self.set1['processes'] ) * 1.0 / elapsed
for name in ('procs_running', 'procs_blocked'): for name in ('procs_running', 'procs_blocked'):
self.val[name] = self.set2[name] * 1.0 self.val[name] = self.set2[name] * 1.0
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
for name in ('procs_running', 'procs_blocked'): for name in ('procs_running', 'procs_blocked'):
self.set2[name] = 0 self.set2[name] = 0
class dstat_raw(dstat): class dstat_raw(dstat):
def __init__(self): def __init__(self):
self.name = 'raw' self.name = 'raw'
self.nick = ('raw',) self.nick = ('raw',)
self.vars = ('sockets',) self.vars = ('sockets',)
self.type = 'd' self.type = 'd'
self.width = 3 self.width = 4
self.scale = 100 self.scale = 1000
self.open('/proc/net/raw') self.open('/proc/net/raw')
def extract(self): def extract(self):
lines = -1 lines = -1
for line in self.readlines(): for line in self.readlines():
lines += 1 lines += 1
self.val['sockets'] = lines self.val['sockets'] = lines
### Cannot use len() on generator ### Cannot use len() on generator
# self.val['sockets'] = len(self.readlines()) - 1 # self.val['sockets'] = len(self.readlines()) - 1
class dstat_socket(dstat): class dstat_socket(dstat):
def __init__(self): def __init__(self):
self.name = 'sockets' self.name = 'sockets'
self.type = 'd' self.type = 'd'
self.width = 3 self.width = 4
self.scale = 100 self.scale = 1000
self.open('/proc/net/sockstat') self.open('/proc/net/sockstat')
self.nick = ('tot', 'tcp', 'udp', 'raw', 'frg') self.nick = ('tot', 'tcp', 'udp', 'raw', 'frg')
self.vars = ('sockets:', 'TCP:', 'UDP:', 'RAW:', 'FRAG:') self.vars = ('sockets:', 'TCP:', 'UDP:', 'RAW:', 'FRAG:')
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 3: continue if len(l) < 3: continue
self.val[l[0]] = long(l[2]) self.val[l[0]] = int(l[2])
self.val['other'] = self.val['sockets:'] - self.val['TCP:'] - self.val[' UDP:'] - self.val['RAW:'] - self.val['FRAG:'] self.val['other'] = self.val['sockets:'] - self.val['TCP:'] - self.val[' UDP:'] - self.val['RAW:'] - self.val['FRAG:']
class dstat_swap(dstat): class dstat_swap(dstat):
def __init__(self): def __init__(self):
self.name = 'swap' self.name = 'swap'
self.nick = ('used', 'free') self.nick = ('used', 'free')
self.type = 'd' self.type = 'd'
self.open('/proc/swaps') self.open('/proc/swaps')
skipping to change at line 1554 skipping to change at line 1530
elif not op.full: elif not op.full:
varlist = ('total',) varlist = ('total',)
else: else:
varlist = self.discover varlist = self.discover
# if len(varlist) > 2: varlist = varlist[0:2] # if len(varlist) > 2: varlist = varlist[0:2]
varlist.sort() varlist.sort()
for name in varlist: for name in varlist:
if name in self.discover + ['total']: if name in self.discover + ['total']:
ret.append(name) ret.append(name)
if not ret: if not ret:
raise Exception, "No suitable swap devices found to monitor" raise Exception("No suitable swap devices found to monitor")
return ret return ret
def name(self): def name(self):
return ['swp/'+improve(name) for name in self.vars] return ['swp/'+improve(name) for name in self.vars]
def extract(self): def extract(self):
self.val['total'] = [0, 0] self.val['total'] = [0, 0]
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 5 or l[0] == 'Filename': continue if len(l) < 5 or l[0] == 'Filename': continue
name = l[0] name = l[0]
self.val[name] = ( long(l[3]) * 1024.0, (long(l[2]) - long(l[3])) * 1024.0 ) self.val[name] = ( int(l[3]) * 1024.0, (int(l[2]) - int(l[3])) * 102 4.0 )
self.val['total'] = ( self.val['total'][0] + self.val[name][0], self .val['total'][1] + self.val[name][1]) self.val['total'] = ( self.val['total'][0] + self.val[name][0], self .val['total'][1] + self.val[name][1])
class dstat_swap_old(dstat): class dstat_swap_old(dstat):
def __init__(self): def __init__(self):
self.name = 'swap' self.name = 'swap'
self.nick = ('used', 'free') self.nick = ('used', 'free')
self.vars = ('SwapUsed', 'SwapFree') self.vars = ('SwapUsed', 'SwapFree')
self.type = 'd' self.type = 'd'
self.open('/proc/meminfo') self.open('/proc/meminfo')
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 2: continue if len(l) < 2: continue
name = l[0].split(':')[0] name = l[0].split(':')[0]
if name in self.vars + ('SwapTotal',): if name in self.vars + ('SwapTotal',):
self.val[name] = long(l[1]) * 1024.0 self.val[name] = int(l[1]) * 1024.0
self.val['SwapUsed'] = self.val['SwapTotal'] - self.val['SwapFree'] self.val['SwapUsed'] = self.val['SwapTotal'] - self.val['SwapFree']
class dstat_sys(dstat): class dstat_sys(dstat):
def __init__(self): def __init__(self):
self.name = 'system' self.name = 'system'
self.nick = ('int', 'csw') self.nick = ('int', 'csw')
self.vars = ('intr', 'ctxt') self.vars = ('intr', 'ctxt')
self.type = 'd' self.type = 'd'
self.width = 5 self.width = 5
self.scale = 1000 self.scale = 1000
self.open('/proc/stat') self.open('/proc/stat')
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 2: continue if len(l) < 2: continue
name = l[0] name = l[0]
if name in self.vars: if name in self.vars:
self.set2[name] = long(l[1]) self.set2[name] = int(l[1])
for name in self.vars: for name in self.vars:
self.val[name] = (self.set2[name] - self.set1[name]) * 1.0 / elapsed self.val[name] = (self.set2[name] - self.set1[name]) * 1.0 / elapsed
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_tcp(dstat): class dstat_tcp(dstat):
def __init__(self): def __init__(self):
self.name = 'tcp sockets' self.name = 'tcp sockets'
self.nick = ('lis', 'act', 'syn', 'tim', 'clo') self.nick = ('lis', 'act', 'syn', 'tim', 'clo')
self.vars = ('listen', 'established', 'syn', 'wait', 'close') self.vars = ('listen', 'established', 'syn', 'wait', 'close')
self.type = 'd' self.type = 'd'
self.width = 4 self.width = 4
self.scale = 100 self.scale = 1000
self.open('/proc/net/tcp', '/proc/net/tcp6') self.open('/proc/net/tcp', '/proc/net/tcp6')
def extract(self): def extract(self):
for name in self.vars: self.val[name] = 0 for name in self.vars: self.val[name] = 0
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 12: continue if len(l) < 12: continue
### 01: established, 02: syn_sent, 03: syn_recv, 04: fin_wait1, ### 01: established, 02: syn_sent, 03: syn_recv, 04: fin_wait1,
### 05: fin_wait2, 06: time_wait, 07: close, 08: close_wait, ### 05: fin_wait2, 06: time_wait, 07: close, 08: close_wait,
### 09: last_ack, 0A: listen, 0B: closing ### 09: last_ack, 0A: listen, 0B: closing
if l[3] in ('0A',): self.val['listen'] += 1 if l[3] in ('0A',): self.val['listen'] += 1
skipping to change at line 1656 skipping to change at line 1632
self.val['time'] = time.strftime(self.timefmt, time.localtime(startt ime)) + ".%03d" % (round(starttime * 1000 % 1000 )) self.val['time'] = time.strftime(self.timefmt, time.localtime(startt ime)) + ".%03d" % (round(starttime * 1000 % 1000 ))
else: else:
self.val['time'] = time.strftime(self.timefmt, time.localtime(startt ime)) self.val['time'] = time.strftime(self.timefmt, time.localtime(startt ime))
class dstat_udp(dstat): class dstat_udp(dstat):
def __init__(self): def __init__(self):
self.name = 'udp' self.name = 'udp'
self.nick = ('lis', 'act') self.nick = ('lis', 'act')
self.vars = ('listen', 'established') self.vars = ('listen', 'established')
self.type = 'd' self.type = 'd'
self.width = 3 self.width = 4
self.scale = 100 self.scale = 1000
self.open('/proc/net/udp', '/proc/net/udp6') self.open('/proc/net/udp', '/proc/net/udp6')
def extract(self): def extract(self):
for name in self.vars: self.val[name] = 0 for name in self.vars: self.val[name] = 0
for l in self.splitlines(): for l in self.splitlines():
if l[3] == '07': self.val['listen'] += 1 if l[3] == '07': self.val['listen'] += 1
elif l[3] == '01': self.val['established'] += 1 elif l[3] == '01': self.val['established'] += 1
class dstat_unix(dstat): class dstat_unix(dstat):
def __init__(self): def __init__(self):
self.name = 'unix sockets' self.name = 'unix sockets'
self.nick = ('dgm', 'str', 'lis', 'act') self.nick = ('dgm', 'str', 'lis', 'act')
self.vars = ('datagram', 'stream', 'listen', 'established') self.vars = ('datagram', 'stream', 'listen', 'established')
self.type = 'd' self.type = 'd'
self.width = 3 self.width = 4
self.scale = 100 self.scale = 1000
self.open('/proc/net/unix') self.open('/proc/net/unix')
def extract(self): def extract(self):
for name in self.vars: self.val[name] = 0 for name in self.vars: self.val[name] = 0
for l in self.splitlines(): for l in self.splitlines():
if l[4] == '0002': self.val['datagram'] += 1 if l[4] == '0002': self.val['datagram'] += 1
elif l[4] == '0001': elif l[4] == '0001':
self.val['stream'] += 1 self.val['stream'] += 1
if l[5] == '01': self.val['listen'] += 1 if l[5] == '01': self.val['listen'] += 1
elif l[5] == '03': self.val['established'] += 1 elif l[5] == '03': self.val['established'] += 1
skipping to change at line 1704 skipping to change at line 1680
self.scale = 1000 self.scale = 1000
self.open('/proc/vmstat') self.open('/proc/vmstat')
def extract(self): def extract(self):
for name in self.vars: for name in self.vars:
self.set2[name] = 0 self.set2[name] = 0
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 2: continue if len(l) < 2: continue
for name in self.vars: for name in self.vars:
if fnmatch.fnmatch(l[0], name): if fnmatch.fnmatch(l[0], name):
self.set2[name] += long(l[1]) self.set2[name] += int(l[1])
for name in self.vars: for name in self.vars:
self.val[name] = (self.set2[name] - self.set1[name]) * 1.0 / elapsed self.val[name] = (self.set2[name] - self.set1[name]) * 1.0 / elapsed
if step == op.delay: if step == op.delay:
self.set1.update(self.set2) self.set1.update(self.set2)
class dstat_vm_adv(dstat_vm): class dstat_vm_adv(dstat_vm):
def __init__(self): def __init__(self):
self.name = 'advanced virtual memory' self.name = 'advanced virtual memory'
skipping to change at line 1743 skipping to change at line 1719
### Page allocations should include all page zones, not just ZONE_NORMAL, ### Page allocations should include all page zones, not just ZONE_NORMAL,
### but also ZONE_DMA, ZONE_HIGHMEM, ZONE_DMA32 (depending on architecture) ### but also ZONE_DMA, ZONE_HIGHMEM, ZONE_DMA32 (depending on architecture)
def extract(self): def extract(self):
for l in self.splitlines(): for l in self.splitlines():
if len(l) < 2: continue if len(l) < 2: continue
if l[0].startswith('Node'): if l[0].startswith('Node'):
zone = l[3] zone = l[3]
found_high = 0 found_high = 0
if l[0].startswith('pages'): if l[0].startswith('pages'):
self.val[zone+'_free'] = long(l[2]) self.val[zone+'_free'] = int(l[2])
if l[0].startswith('high') and not found_high: if l[0].startswith('high') and not found_high:
self.val[zone+'_high'] = long(l[1]) self.val[zone+'_high'] = int(l[1])
found_high = 1 found_high = 1
### END STATS DEFINITIONS ### ### END STATS DEFINITIONS ###
color = { color = {
'black': '\033[0;30m', 'black': '\033[0;30m',
'darkred': '\033[0;31m', 'darkred': '\033[0;31m',
'darkgreen': '\033[0;32m', 'darkgreen': '\033[0;32m',
'darkyellow': '\033[0;33m', 'darkyellow': '\033[0;33m',
'darkblue': '\033[0;34m', 'darkblue': '\033[0;34m',
skipping to change at line 1788 skipping to change at line 1764
ansi = { ansi = {
'reset': '\033[0;0m', 'reset': '\033[0;0m',
'bold': '\033[1m', 'bold': '\033[1m',
'reverse': '\033[2m', 'reverse': '\033[2m',
'underline': '\033[4m', 'underline': '\033[4m',
'clear': '\033[2J', 'clear': '\033[2J',
# 'clearline': '\033[K', # 'clearline': '\033[K',
'clearline': '\033[2K', 'clearline': '\033[2K',
# 'save': '\033[s', 'save': '\033[s',
# 'restore': '\033[u', 'restore': '\033[u',
'save': '\0337', 'save_all': '\0337',
'restore': '\0338', 'restore_all': '\0338',
'linewrap': '\033[7h', 'linewrap': '\033[7h',
'nolinewrap': '\033[7l', 'nolinewrap': '\033[7l',
'up': '\033[1A', 'up': '\033[1A',
'down': '\033[1B', 'down': '\033[1B',
'right': '\033[1C', 'right': '\033[1C',
'left': '\033[1D', 'left': '\033[1D',
'default': '\033[0;0m', 'default': '\033[0;0m',
} }
skipping to change at line 1863 skipping to change at line 1839
'colors_lo': (color['red'], color['yellow'], color['green'], color[' blue'], 'colors_lo': (color['red'], color['yellow'], color['green'], color[' blue'],
color['cyan'], color['white'], color['darkred'], color ['darkgreen']), color['cyan'], color['white'], color['darkred'], color ['darkgreen']),
'colors_hi': (color['darkred'], color['darkyellow'], color['darkgree n'], color['darkblue'], 'colors_hi': (color['darkred'], color['darkyellow'], color['darkgree n'], color['darkblue'],
color['darkcyan'], color['gray'], color['red'], color[ 'green']), color['darkcyan'], color['gray'], color['red'], color[ 'green']),
} }
return theme return theme
def ticks(): def ticks():
"Return the number of 'ticks' since bootup" "Return the number of 'ticks' since bootup"
try: try:
for line in open('/proc/uptime', 'r', 0).readlines(): for line in open('/proc/uptime', 'r').readlines():
l = line.split() l = line.split()
if len(l) < 2: continue if len(l) < 2: continue
return float(l[0]) return float(l[0])
except: except:
for line in dopen('/proc/stat').readlines(): for line in dopen('/proc/stat').readlines():
l = line.split() l = line.split()
if len(l) < 2: continue if len(l) < 2: continue
if l[0] == 'btime': if l[0] == 'btime':
return time.time() - long(l[1]) return time.time() - int(l[1])
def improve(devname): def improve(devname):
"Improve a device name" "Improve a device name"
if devname.startswith('/dev/mapper/'): if devname.startswith('/dev/mapper/'):
devname = devname.split('/')[3] devname = devname.split('/')[3]
elif devname.startswith('/dev/'): elif devname.startswith('/dev/'):
devname = devname.split('/')[2] devname = devname.split('/')[2]
return devname return devname
def dopen(filename): def dopen(filename):
"Open a file for reuse, if already opened, return file descriptor" "Open a file for reuse, if already opened, return file descriptor"
global fds global fds
if not os.path.exists(filename): if not os.path.exists(filename):
raise Exception, 'File %s does not exist' % filename raise Exception('File %s does not exist' % filename)
# return None if 'fds' not in globals():
if 'fds' not in globals().keys():
fds = {} fds = {}
if file not in fds.keys(): if filename in fds:
fds[filename] = open(filename, 'r', 0)
else:
fds[filename].seek(0) fds[filename].seek(0)
else:
fds[filename] = open(filename, 'r')
return fds[filename] return fds[filename]
def dclose(filename): def dclose(filename):
"Close an open file and remove file descriptor from list" "Close an open file and remove file descriptor from list"
global fds global fds
if not 'fds' in globals().keys(): fds = {} if not 'fds' in globals(): fds = {}
if filename in fds: if filename in fds:
fds[filename].close() fds[filename].close()
del(fds[filename]) del(fds[filename])
def dpopen(cmd): def dpopen(cmd):
"Open a pipe for reuse, if already opened, return pipes" "Open a pipe for reuse, if already opened, return pipes"
global pipes, select global pipes, select
import select import select
if 'pipes' not in globals().keys(): pipes = {} if 'pipes' not in globals(): pipes = {}
if cmd not in pipes.keys(): if cmd not in pipes:
try: try:
import asubprocess import asubprocess
p = subprocess.Popen(cmd, shell=True, bufsize=0, close_fds=True, p = subprocess.Popen(cmd, shell=True, bufsize=0, close_fds=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess .PIPE) stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess .PIPE)
pipes[cmd] = (p.stdin, p.stdout, p.stderr) pipes[cmd] = (p.stdin, p.stdout, p.stderr)
except ImportError: except ImportError:
pipes[cmd] = os.popen3(cmd, 't', 0) pipes[cmd] = os.popen3(cmd, 't', 0)
return pipes[cmd] return pipes[cmd]
def readpipe(fileobj, tmout = 0.001): def readpipe(fileobj, tmout = 0.001):
skipping to change at line 1942 skipping to change at line 1917
pass pass
while select.select([fileobj.fileno()], [], [], tmout)[0]: while select.select([fileobj.fileno()], [], [], tmout)[0]:
character = fileobj.read(1) character = fileobj.read(1)
if character != '\n': if character != '\n':
ret = ret + character ret = ret + character
elif ret.startswith(str): elif ret.startswith(str):
return ret return ret
else: else:
ret = '' ret = ''
if op.debug: if op.debug:
raise Exception, 'Nothing found during greppipe data collection' raise Exception('Nothing found during greppipe data collection')
return None return None
def matchpipe(fileobj, string, tmout = 0.001): def matchpipe(fileobj, string, tmout = 0.001):
"Match available data from pipe in a non-blocking fashion" "Match available data from pipe in a non-blocking fashion"
ret = '' ret = ''
regexp = re.compile(string) regexp = re.compile(string)
while not select.select([fileobj.fileno()], [], [], tmout)[0]: while not select.select([fileobj.fileno()], [], [], tmout)[0]:
pass pass
while select.select([fileobj.fileno()], [], [], tmout)[0]: while select.select([fileobj.fileno()], [], [], tmout)[0]:
character = fileobj.read(1) character = fileobj.read(1)
if character != '\n': if character != '\n':
ret = ret + character ret = ret + character
elif regexp.match(ret): elif regexp.match(ret):
return ret return ret
else: else:
ret = '' ret = ''
if op.debug: if op.debug:
raise Exception, 'Nothing found during matchpipe data collection' raise Exception('Nothing found during matchpipe data collection')
return None return None
def cmd_test(cmd): def cmd_test(cmd):
pipes = os.popen3(cmd, 't', 0) pipes = os.popen3(cmd, 't', 0)
for line in pipes[2].readlines(): for line in pipes[2].readlines():
raise Exception, line.strip() raise Exception(line.strip())
def cmd_readlines(cmd): def cmd_readlines(cmd):
pipes = os.popen3(cmd, 't', 0) pipes = os.popen3(cmd, 't', 0)
for line in pipes[1].readlines(): for line in pipes[1].readlines():
yield line yield line
def cmd_splitlines(cmd, sep=None): def cmd_splitlines(cmd, sep=None):
pipes = os.popen3(cmd, 't', 0) pipes = os.popen3(cmd, 't', 0)
for line in pipes[1].readlines(): for line in pipes[1].readlines():
yield line.split(sep) yield line.split(sep)
skipping to change at line 2037 skipping to change at line 2012
except ValueError: except ValueError:
continue continue
def snmpget(server, community, oid): def snmpget(server, community, oid):
errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator ().getCmd( errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator ().getCmd(
cmdgen.CommunityData('test-agent', community, 0), cmdgen.CommunityData('test-agent', community, 0),
cmdgen.UdpTransportTarget((server, 161)), cmdgen.UdpTransportTarget((server, 161)),
oid oid
) )
# print '%s -> ind: %s, stat: %s, idx: %s' % (oid, errorIndication, errorStat us, errorIndex) # print('%s -> ind: %s, stat: %s, idx: %s' % (oid, errorIndication, errorStat us, errorIndex))
for x in varBinds: for x in varBinds:
return str(x[1]) return str(x[1])
def snmpwalk(server, community, oid): def snmpwalk(server, community, oid):
ret = [] ret = []
errorIndication, errorStatus, errorIndex, varBindTable = cmdgen.CommandGener ator().nextCmd( errorIndication, errorStatus, errorIndex, varBindTable = cmdgen.CommandGener ator().nextCmd(
cmdgen.CommunityData('test-agent', community, 0), cmdgen.CommunityData('test-agent', community, 0),
cmdgen.UdpTransportTarget((server, 161)), cmdgen.UdpTransportTarget((server, 161)),
oid oid
) )
# print '%s -> ind: %s, stat: %s, idx: %s' % (oid, errorIndication, errorStat us, errorIndex) # print('%s -> ind: %s, stat: %s, idx: %s' % (oid, errorIndication, errorStat us, errorIndex))
for x in varBindTable: for x in varBindTable:
for y in x: for y in x:
ret.append(str(y[1])) ret.append(str(y[1]))
return ret return ret
def dchg(var, width, base): def dchg(var, width, base):
"Convert decimal to string given base and length" "Convert decimal to string given base and length"
c = 0 c = 0
while True: while True:
ret = str(long(round(var))) ret = str(int(round(var)))
if len(ret) <= width: if len(ret) <= width:
break break
var = var / base var = var / base
c = c + 1 c = c + 1
else: else:
c = -1 c = -1
return ret, c return ret, c
def fchg(var, width, base): def fchg(var, width, base):
"Convert float to string given scale and length" "Convert float to string given scale and length"
c = 0 c = 0
while True: while True:
if var == 0: if var == 0:
ret = str('0') ret = str('0')
break break
# ret = repr(round(var)) # ret = repr(round(var))
# ret = repr(long(round(var, maxlen))) # ret = repr(int(round(var, maxlen)))
ret = str(long(round(var, width))) ret = str(int(round(var, width)))
if len(ret) <= width: if len(ret) <= width:
i = width - len(ret) - 1 i = width - len(ret) - 1
while i > 0: while i > 0:
ret = ('%%.%df' % i) % var ret = ('%%.%df' % i) % var
if len(ret) <= width and ret != str(long(round(var, width))): if len(ret) <= width and ret != str(int(round(var, width))):
break break
i = i - 1 i = i - 1
else: else:
ret = str(long(round(var))) ret = str(int(round(var)))
break break
var = var / base var = var / base
c = c + 1 c = c + 1
else: else:
c = -1 c = -1
return ret, c return ret, c
def tchg(var, width): def tchg(var, width):
"Convert time string to given length" "Convert time string to given length"
ret = '%2dh%02d' % (var / 60, var % 60) ret = '%2dh%02d' % (var / 60, var % 60)
if len(ret) > width: if len(ret) > width:
ret = '%2dh' % (var / 60) ret = '%2dh' % (var / 60)
if len(ret) > width: if len(ret) > width:
ret = '%2dd' % (var / 60 / 24) ret = '%2dd' % (var / 60 / 24)
if len(ret) > width: if len(ret) > width:
ret = '%2dw' % (var / 60 / 24 / 7) ret = '%2dw' % (var / 60 / 24 / 7)
return ret return ret
def cprintlist(varlist, type, width, scale): def cprintlist(varlist, ctype, width, scale):
"Return all columns color printed" "Return all columns color printed"
ret = sep = '' ret = sep = ''
for var in varlist: for var in varlist:
ret = ret + sep + cprint(var, type, width, scale) ret = ret + sep + cprint(var, ctype, width, scale)
sep = char['space'] sep = char['space']
return ret return ret
def cprint(var, type = 'f', width = 4, scale = 1000): def cprint(var, ctype = 'f', width = 4, scale = 1000):
"Color print one column" "Color print one column"
base = 1000 base = 1000
if scale == 1024: if scale == 1024:
base = 1024 base = 1024
### Use units when base is exact 1000 or 1024 ### Use units when base is exact 1000 or 1024
unit = False unit = False
if scale in (1000, 1024) and width >= len(str(base)): if scale in (1000, 1024) and width >= len(str(base)):
unit = True unit = True
width = width - 1 width = width - 1
### If this is a negative value, return a dash ### If this is a negative value, return a dash
if var < 0: if ctype != 's' and var < 0:
if unit: if unit:
return theme['error'] + '-'.rjust(width) + char['space'] + theme['de fault'] return theme['error'] + '-'.rjust(width) + char['space'] + theme['de fault']
else: else:
return theme['error'] + '-'.rjust(width) + theme['default'] return theme['error'] + '-'.rjust(width) + theme['default']
if base != 1024: if base != 1024:
units = (char['space'], 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y') units = (char['space'], 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
elif op.bits and type in ('b', ): elif op.bits and ctype in ('b', ):
units = ('b', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y') units = ('b', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
base = scale = 1000 base = scale = 1000
var = var * 8.0 var = var * 8.0
else: else:
units = ('B', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y') units = ('B', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
if step == op.delay: if step == op.delay:
colors = theme['colors_lo'] colors = theme['colors_lo']
ctext = theme['text_lo'] ctext = theme['text_lo']
cunit = theme['unit_lo'] cunit = theme['unit_lo']
cdone = theme['done_lo'] cdone = theme['done_lo']
else: else:
colors = theme['colors_hi'] colors = theme['colors_hi']
ctext = theme['text_hi'] ctext = theme['text_hi']
cunit = theme['unit_hi'] cunit = theme['unit_hi']
cdone = theme['done_hi'] cdone = theme['done_hi']
### Convert value to string given base and field-length ### Convert value to string given base and field-length
if op.integer and type in ('b', 'd', 'p', 'f'): if op.integer and ctype in ('b', 'd', 'p', 'f'):
ret, c = dchg(var, width, base) ret, c = dchg(var, width, base)
elif op.float and type in ('b', 'd', 'p', 'f'): elif op.float and ctype in ('b', 'd', 'p', 'f'):
ret, c = fchg(var, width, base) ret, c = fchg(var, width, base)
elif type in ('b', 'd', 'p'): elif ctype in ('b', 'd', 'p'):
ret, c = dchg(var, width, base) ret, c = dchg(var, width, base)
elif type in ('f'): elif ctype in ('f',):
ret, c = fchg(var, width, base) ret, c = fchg(var, width, base)
elif type in ('s',): elif ctype in ('s',):
ret, c = str(var), ctext ret, c = str(var), ctext
elif type in ('t'): elif ctype in ('t',):
ret, c = tchg(var, width), ctext ret, c = tchg(var, width), ctext
else: else:
raise Exception, 'Type %s not known to dstat.' % type raise Exception('Type %s not known to dstat.' % ctype)
### Set the counter color ### Set the counter color
if ret == '0': if ret == '0':
color = cunit color = cunit
elif scale <= 0: elif scale <= 0:
color = ctext color = ctext
elif type in ('p') and round(var) >= 100.0: elif ctype in ('p') and round(var) >= 100.0:
color = cdone color = cdone
# elif type in ('p'): # elif type in ('p'):
# color = colors[int(round(var)/scale)%len(colors)] # color = colors[int(round(var)/scale)%len(colors)]
elif scale not in (1000, 1024): elif scale not in (1000, 1024):
color = colors[int(var/scale)%len(colors)] color = colors[int(var/scale)%len(colors)]
elif type in ('b', 'd', 'f'): elif ctype in ('b', 'd', 'f'):
color = colors[c%len(colors)] color = colors[c%len(colors)]
else: else:
color = ctext color = ctext
### Justify value to left if string ### Justify value to left if string
if type in ('s',): if ctype in ('s',):
ret = color + ret.ljust(width) ret = color + ret.ljust(width)
else: else:
ret = color + ret.rjust(width) ret = color + ret.rjust(width)
### Add unit to output ### Add unit to output
if unit: if unit:
if c != -1 and round(var) != 0: if c != -1 and round(var) != 0:
ret += cunit + units[c] ret += cunit + units[c]
else: else:
ret += char['space'] ret += char['space']
skipping to change at line 2235 skipping to change at line 2210
if o is not totlist[-1]: if o is not totlist[-1]:
line = line + char['sep'] line = line + char['sep']
line += '\n' line += '\n'
### Process subtitle ### Process subtitle
for o in totlist: for o in totlist:
line = line + o.csvsubtitle() line = line + o.csvsubtitle()
if o is not totlist[-1]: if o is not totlist[-1]:
line = line + char['sep'] line = line + char['sep']
return line + '\n' return line + '\n'
def info(level, str): def info(level, msg):
"Output info message" "Output info message"
# if level <= op.verbose: # if level <= op.verbose:
print >>sys.stderr, str print(msg, file=sys.stderr)
def die(ret, str): def die(ret, msg):
"Print error and exit with errorcode" "Print error and exit with errorcode"
print >>sys.stderr, str print(msg, file=sys.stderr)
exit(ret) exit(ret)
def initterm(): def initterm():
"Initialise terminal" "Initialise terminal"
global termsize global termsize
### Unbuffered sys.stdout ### Unbuffered sys.stdout
# sys.stdout = os.fdopen(1, 'w', 0) # sys.stdout = os.fdopen(1, 'w', 0)
termsize = None, 0 termsize = None, 0
skipping to change at line 2297 skipping to change at line 2272
def gettermcolor(): def gettermcolor():
"Return whether the system can use colors or not" "Return whether the system can use colors or not"
if sys.stdout.isatty(): if sys.stdout.isatty():
try: try:
import curses import curses
curses.setupterm() curses.setupterm()
if curses.tigetnum('colors') < 0: if curses.tigetnum('colors') < 0:
return False return False
except ImportError: except ImportError:
print >>sys.stderr, 'Color support is disabled as python-curses is n ot installed.' print('Color support is disabled as python-curses is not installed.' , file=sys.stderr)
return False return False
except: except:
print >>sys.stderr, 'Color support is disabled as curses does not fi nd terminal "%s".' % os.getenv('TERM') print('Color support is disabled as curses does not find terminal "% s".' % os.getenv('TERM'), file=sys.stderr)
return False return False
return True return True
return False return False
### We only want to filter out paths, not ksoftirqd/1 ### We only want to filter out paths, not ksoftirqd/1
def basename(name): def basename(name):
"Perform basename on paths only" "Perform basename on paths only"
if name[0] in ('/', '.'): if name[0] in ('/', '.'):
return os.path.basename(name) return os.path.basename(name)
return name return name
skipping to change at line 2364 skipping to change at line 2339
# Fallback 2 # Fallback 2
try: try:
search = re.compile('^cpu\d+') search = re.compile('^cpu\d+')
cpunr = 0 cpunr = 0
for line in dopen('/proc/stat').readlines(): for line in dopen('/proc/stat').readlines():
if search.match(line): if search.match(line):
cpunr += 1 cpunr += 1
if cpunr > 0: if cpunr > 0:
return cpunr return cpunr
except: except:
raise Exception, "Problem finding number of CPUs in system." raise Exception("Problem finding number of CPUs in system.")
def blockdevices(): def blockdevices():
### We have to replace '!' by '/' to support cciss!c0d0 type devices :-/ ### We have to replace '!' by '/' to support cciss!c0d0 type devices :-/
return [os.path.basename(filename).replace('!', '/') for filename in glob.gl ob('/sys/block/*')] return [os.path.basename(filename).replace('!', '/') for filename in glob.gl ob('/sys/block/*')]
### FIXME: Add scsi support too and improve ### FIXME: Add scsi support too and improve
def sysfs_dev(device): def sysfs_dev(device):
"Convert sysfs device names into device names" "Convert sysfs device names into device names"
m = re.match('ide/host(\d)/bus(\d)/target(\d)/lun(\d)/disc', device) m = re.match('ide/host(\d)/bus(\d)/target(\d)/lun(\d)/disc', device)
if m: if m:
skipping to change at line 2478 skipping to change at line 2453
plugins.append(remod.match(filename).groups()[0].replace('_', '-')) plugins.append(remod.match(filename).groups()[0].replace('_', '-'))
remod = re.compile('.+/dstat_(.+).py$') remod = re.compile('.+/dstat_(.+).py$')
for path in pluginpath: for path in pluginpath:
for filename in glob.glob(path + '/dstat_*.py'): for filename in glob.glob(path + '/dstat_*.py'):
plugins.append(remod.match(filename).groups()[0].replace('_', '-')) plugins.append(remod.match(filename).groups()[0].replace('_', '-'))
plugins.sort() plugins.sort()
return plugins return plugins
def showplugins(): def showplugins():
rows, cols = gettermsize() rows, cols = gettermsize()
print 'internal:\n\t', print('internal:\n\t', end='')
remod = re.compile('^dstat_(.+)$') remod = re.compile('^dstat_(.+)$')
plugins = [] plugins = []
for filename in globals(): for filename in globals():
if filename.startswith('dstat_'): if filename.startswith('dstat_'):
plugins.append(remod.match(filename).groups()[0].replace('_', '-')) plugins.append(remod.match(filename).groups()[0].replace('_', '-'))
plugins.sort() plugins.sort()
cols2 = cols - 8 cols2 = cols - 8
for mod in plugins: for mod in plugins:
cols2 = cols2 - len(mod) - 2 cols2 = cols2 - len(mod) - 2
if cols2 <= 0: if cols2 <= 0:
print '\n\t', print('\n\t', end='')
cols2 = cols - len(mod) - 10 cols2 = cols - len(mod) - 10
if mod != plugins[-1]: if mod != plugins[-1]:
print mod+',', print(mod, end=',')
print mod print(mod)
remod = re.compile('.+/dstat_(.+).py$') remod = re.compile('.+/dstat_(.+).py$')
for path in pluginpath: for path in pluginpath:
plugins = [] plugins = []
for filename in glob.glob(path + '/dstat_*.py'): for filename in glob.glob(path + '/dstat_*.py'):
plugins.append(remod.match(filename).groups()[0].replace('_', '-')) plugins.append(remod.match(filename).groups()[0].replace('_', '-'))
if not plugins: continue if not plugins: continue
plugins.sort() plugins.sort()
cols2 = cols - 8 cols2 = cols - 8
print '%s:\n\t' % os.path.abspath(path), print('%s:' % os.path.abspath(path), end='\n\t')
for mod in plugins: for mod in plugins:
cols2 = cols2 - len(mod) - 2 cols2 = cols2 - len(mod) - 2
if cols2 <= 0: if cols2 <= 0:
print '\n\t', print(end='\n\t')
cols2 = cols - len(mod) - 10 cols2 = cols - len(mod) - 10
if mod != plugins[-1]: if mod != plugins[-1]:
print mod+',', print(mod, end=',')
print mod print(mod)
def exit(ret): def exit(ret):
sys.stdout.write(ansi['reset']) sys.stdout.write(ansi['reset'])
sys.stdout.flush() sys.stdout.flush()
if op.pidfile and os.path.exists(op.pidfile): if op.pidfile and os.path.exists(op.pidfile):
os.remove(op.pidfile) os.remove(op.pidfile)
if op.profile and os.path.exists(op.profile): if op.profile and os.path.exists(op.profile):
rows, cols = gettermsize() rows, cols = gettermsize()
import pstats import pstats
p = pstats.Stats(op.profile) p = pstats.Stats(op.profile)
# p.sort_stats('name') # p.sort_stats('name')
# p.print_stats() # p.print_stats()
p.sort_stats('cumulative').print_stats(rows - 13) p.sort_stats('cumulative').print_stats(rows - 13)
# p.sort_stats('time').print_stats(rows - 13) # p.sort_stats('time').print_stats(rows - 13)
# p.sort_stats('file').print_stats('__init__') # p.sort_stats('file').print_stats('__init__')
# p.sort_stats('time', 'cum').print_stats(.5, 'init') # p.sort_stats('time', 'cum').print_stats(.5, 'init')
# p.print_callees() # p.print_callees()
elif op.profile: elif op.profile:
print >>sys.stderr, "No profiling data was found, maybe profiler was int errupted ?" print('No profiling data was found, maybe profiler was interrupted ?', f ile=sys.stderr)
sys.exit(ret) sys.exit(ret)
def main(): def main():
"Initialization of the program, terminal, internal structures" "Initialization of the program, terminal, internal structures"
global cpunr, hz, maxint, ownpid, pagesize global cpunr, hz, maxint, ownpid, pagesize
global ansi, theme, outputfile global ansi, theme, outputfile
global totlist, inittime global totlist, inittime
global update, missed global update, missed
cpunr = getcpunr() cpunr = getcpunr()
hz = os.sysconf('SC_CLK_TCK') hz = os.sysconf('SC_CLK_TCK')
maxint = (sys.maxint + 1) * 2 try:
maxint = (sys.maxint + 1) * 2
except:
# Support Python 3
maxint = float("inf")
ownpid = str(os.getpid()) ownpid = str(os.getpid())
pagesize = resource.getpagesize() pagesize = resource.getpagesize()
interval = 1 interval = 1
user = getpass.getuser() user = getpass.getuser()
hostname = os.uname()[1] hostname = os.uname()[1]
### Disable line-wrapping (does not work ?)
sys.stdout.write('\033[7l')
### Write term-title ### Write term-title
if sys.stdout.isatty(): if sys.stdout.isatty():
shell = os.getenv('XTERM_SHELL') shell = os.getenv('XTERM_SHELL')
term = os.getenv('TERM') term = os.getenv('TERM')
if shell == '/bin/bash' and term and re.compile('(screen*|xterm*)').matc h(term): if shell == '/bin/bash' and term and re.compile('(screen*|xterm*)').matc h(term):
sys.stdout.write('\033]0;(%s@%s) %s %s\007' % (user, hostname.split( '.')[0], os.path.basename(sys.argv[0]), ' '.join(op.args))) sys.stdout.write('\033]0;(%s@%s) %s %s\007' % (user, hostname.split( '.')[0], os.path.basename(sys.argv[0]), ' '.join(op.args)))
### Check background color (rxvt) ### Check background color (rxvt)
### COLORFGBG="15;default;0" ### COLORFGBG="15;default;0"
# if os.environ['COLORFGBG'] and len(os.environ['COLORFGBG'].split(';')) >= 3: # if os.environ['COLORFGBG'] and len(os.environ['COLORFGBG'].split(';')) >= 3:
skipping to change at line 2581 skipping to change at line 2557
# else: # else:
# print 'Background is unknown, assuming dark.' # print 'Background is unknown, assuming dark.'
### Check terminal capabilities ### Check terminal capabilities
if op.color == None: if op.color == None:
op.color = gettermcolor() op.color = gettermcolor()
### Prepare CSV output file (unbuffered) ### Prepare CSV output file (unbuffered)
if op.output: if op.output:
if not os.path.exists(op.output): if not os.path.exists(op.output):
outputfile = open(op.output, 'w', 0) outputfile = open(op.output, 'w')
outputfile.write('"Dstat %s CSV output"\n' % VERSION) outputfile.write('"Dstat %s CSV output"\n' % VERSION)
header = ('"Author:","Dag Wieers <dag@wieers.com>"','','','','"URL:" ','"http://dag.wieers.com/home-made/dstat/"\n') header = ('"Author:","Dag Wieers <dag@wieers.com>"','','','','"URL:" ','"http://dag.wieers.com/home-made/dstat/"\n')
outputfile.write(char['sep'].join(header)) outputfile.write(char['sep'].join(header))
else: else:
outputfile = open(op.output, 'a', 0) outputfile = open(op.output, 'a')
outputfile.write('\n\n') outputfile.write('\n\n')
header = ('"Host:"','"%s"' % hostname,'','','','"User:"','"%s"\n' % user ) header = ('"Host:"','"%s"' % hostname,'','','','"User:"','"%s"\n' % user )
outputfile.write(char['sep'].join(header)) outputfile.write(char['sep'].join(header))
header = ('"Cmdline:"','"dstat %s"' % ' '.join(op.args),'','','','"Date: "','"%s"\n' % time.strftime('%d %b %Y %H:%M:%S %Z', time.localtime())) header = ('"Cmdline:"','"dstat %s"' % ' '.join(op.args),'','','','"Date: "','"%s"\n' % time.strftime('%d %b %Y %H:%M:%S %Z', time.localtime()))
outputfile.write(char['sep'].join(header)) outputfile.write(char['sep'].join(header))
### Create pidfile ### Create pidfile
if op.pidfile: if op.pidfile:
try: try:
pidfile = open(op.pidfile, 'w', 0) pidfile = open(op.pidfile, 'w')
pidfile.write(str(os.getpid())) pidfile.write(str(os.getpid()))
pidfile.close() pidfile.close()
except Exception, e: except Exception as e:
print >>sys.stderr, 'Failed to create pidfile %s' % op.pidfile, e print('Failed to create pidfile %s: %s' % (op.pidfile, e), file=sys.
stderr)
op.pidfile = False op.pidfile = False
### Empty ansi and theme database if no colors are requested ### Empty ansi and theme database if no colors are requested
if not op.color: if not op.color:
for key in color.keys(): for key in color:
color[key] = '' color[key] = ''
for key in theme.keys(): for key in theme:
theme[key] = '' theme[key] = ''
for key in ansi:
ansi[key] = ''
theme['colors_hi'] = (ansi['default'],) theme['colors_hi'] = (ansi['default'],)
theme['colors_lo'] = (ansi['default'],) theme['colors_lo'] = (ansi['default'],)
# print color['blackbg'] # print color['blackbg']
### Disable line-wrapping (does not work ?)
sys.stdout.write(ansi['nolinewrap'])
if not op.update: if not op.update:
interval = op.delay interval = op.delay
### Build list of requested plugins ### Build list of requested plugins
linewidth = 0 linewidth = 0
totlist = [] totlist = []
for plugin in op.plugins: for plugin in op.plugins:
### Set up fallback lists ### Set up fallback lists
if plugin == 'cpu': mods = ( 'cpu', 'cpu24' ) if plugin == 'cpu': mods = ( 'cpu', 'cpu24' )
elif plugin == 'disk': mods = ( 'disk', 'disk24', 'disk24-old' ) elif plugin == 'disk': mods = ( 'disk', 'disk24', 'disk24-old' )
elif plugin == 'int': mods = ( 'int', 'int24' ) elif plugin == 'int': mods = ( 'int', 'int24' )
elif plugin == 'page': mods = ( 'page', 'page24' ) elif plugin == 'page': mods = ( 'page', 'page24' )
elif plugin == 'swap': mods = ( 'swap', 'swap-old' ) elif plugin == 'swap': mods = ( 'swap', 'swap-old' )
else: mods = ( plugin, ) else: mods = ( plugin, )
for mod in mods: for mod in mods:
pluginfile = 'dstat_' + mod.replace('-', '_') pluginfile = 'dstat_' + mod.replace('-', '_')
try: try:
if pluginfile not in globals().keys(): if pluginfile not in globals():
import imp import imp
fp, pathname, description = imp.find_module(pluginfile, plug inpath) fp, pathname, description = imp.find_module(pluginfile, plug inpath)
fp.close() fp.close()
### TODO: Would using .pyc help with anything ? ### TODO: Would using .pyc help with anything ?
### Try loading python plugin ### Try loading python plugin
if description[0] in ('.py', ): if description[0] in ('.py', ):
execfile(pathname) exec(open(pathname).read())
exec 'o = dstat_plugin(); del(dstat_plugin)' #execfile(pathname)
o.filename = pluginfile exec('global plug; plug = dstat_plugin(); del(dstat_plug
o.check() in)')
o.prepare() plug.filename = pluginfile
plug.check()
plug.prepare()
### Try loading C plugin (not functional yet) ### Try loading C plugin (not functional yet)
elif description[0] == '.so': elif description[0] == '.so':
exec 'import %s' % pluginfile exec('import %s; global plug; plug = %s.new()' % (plugin
exec 'o = %s.new()' % pluginfile file, pluginfile))
o.check() plug.check()
o.prepare() plug.prepare()
# print dir(o) # print(dir(plug))
# print o.__module__ # print(plug.__module__)
# print o.name # print(plug.name)
else: else:
print >>sys.stderr, 'Module %s is of unknown type.' % pl uginfile print('Module %s is of unknown type.' % pluginfile, file =sys.stderr)
else: else:
exec 'o = %s()' % pluginfile exec('global plug; plug = %s()' % pluginfile)
o.check() plug.check()
o.prepare() plug.prepare()
# print o.__module__ # print(plug.__module__)
except Exception, e: except Exception as e:
if mod == mods[-1]: if mod == mods[-1]:
print >>sys.stderr, 'Module %s failed to load. (%s)' % (plug infile, e) print('Module %s failed to load. (%s)' % (pluginfile, e), fi le=sys.stderr)
elif op.debug: elif op.debug:
print >>sys.stderr, 'Module %s failed to load, trying anothe r. (%s)' % (pluginfile, e) print('Module %s failed to load, trying another. (%s)' % (pl uginfile, e), file=sys.stderr)
if op.debug >= 3: if op.debug >= 3:
raise raise
# tb = sys.exc_info()[2] # tb = sys.exc_info()[2]
continue continue
except: except:
print >>sys.stderr, 'Module %s caused unknown exception' % plugi nfile print('Module %s caused unknown exception' % pluginfile, file=sy s.stderr)
linewidth = linewidth + o.statwidth() + 1 linewidth = linewidth + plug.statwidth() + 1
totlist.append(o) totlist.append(plug)
if op.debug: if op.debug:
print 'Module', pluginfile, print('Module %s' % pluginfile, end='')
if hasattr(o, 'file'): if hasattr(plug, 'file'):
print 'requires', o.file, print(' requires %s' % plug.file, end='')
print print()
break break
if not totlist: if not totlist:
die(8, 'None of the stats you selected are available.') die(8, 'None of the stats you selected are available.')
if op.output: if op.output:
outputfile.write(csvheader(totlist)) outputfile.write(csvheader(totlist))
scheduler = sched.scheduler(time.time, time.sleep) scheduler = sched.scheduler(time.time, time.sleep)
inittime = time.time() inittime = time.time()
skipping to change at line 2763 skipping to change at line 2744
for o in totlist: for o in totlist:
newwidth = curwidth + o.statwidth() + 1 newwidth = curwidth + o.statwidth() + 1
if newwidth <= cols or ( vislist == totlist[:-1] and newwidt h < cols ): if newwidth <= cols or ( vislist == totlist[:-1] and newwidt h < cols ):
vislist.append(o) vislist.append(o)
curwidth = newwidth curwidth = newwidth
### Check when to display the header ### Check when to display the header
if op.header and rows >= 6: if op.header and rows >= 6:
if oldvislist != vislist: if oldvislist != vislist:
showheader = True showheader = True
elif step == 1 and loop % (rows - 1) == 0: elif not op.update and loop % (rows - 2) == 0:
showheader = True
elif op.update and step == 1 and loop % (rows - 1) == 0:
showheader = True showheader = True
oldvislist = vislist oldvislist = vislist
else: else:
vislist = totlist vislist = totlist
### Prepare the colors for intermediate updates, last step in a loop is definitive ### Prepare the colors for intermediate updates, last step in a loop is definitive
if step == op.delay: if step == op.delay:
theme['default'] = ansi['reset'] theme['default'] = ansi['reset']
else: else:
skipping to change at line 2787 skipping to change at line 2770
newline = '' newline = ''
if op.update: if op.update:
if step == 1 and update != 0: if step == 1 and update != 0:
newline = '\n' + ansi['reset'] + ansi['clearline'] + ansi['save' ] newline = '\n' + ansi['reset'] + ansi['clearline'] + ansi['save' ]
elif loop != 0: elif loop != 0:
newline = ansi['restore'] newline = ansi['restore']
### Display header ### Display header
if showheader: if showheader:
if loop == 0 and totlist != vislist: if loop == 0 and totlist != vislist:
print >>sys.stderr, 'Terminal width too small, trimming output.' print('Terminal width too small, trimming output.', file=sys.std err)
showheader = False showheader = False
sys.stdout.write(newline) sys.stdout.write(newline)
newline = header(totlist, vislist) newline = header(totlist, vislist)
### Calculate all objects (visible, invisible) ### Calculate all objects (visible, invisible)
line = newline line = newline
oline = '' oline = ''
for o in totlist: for o in totlist:
o.extract() o.extract()
if o in vislist: if o in vislist:
skipping to change at line 2842 skipping to change at line 2825
initterm() initterm()
op = Options(os.getenv('DSTAT_OPTS','').split() + sys.argv[1:]) op = Options(os.getenv('DSTAT_OPTS','').split() + sys.argv[1:])
theme = set_theme() theme = set_theme()
if op.profile: if op.profile:
import profile import profile
if os.path.exists(op.profile): if os.path.exists(op.profile):
os.remove(op.profile) os.remove(op.profile)
profile.run('main()', op.profile) profile.run('main()', op.profile)
else: else:
main() main()
except KeyboardInterrupt, e: except KeyboardInterrupt as e:
if op.update: if op.update:
sys.stdout.write('\n') sys.stdout.write('\n')
exit(0) exit(0)
else: else:
op = Options('') op = Options('')
step = 1 step = 1
# vim:ts=4:sw=4:et # vim:ts=4:sw=4:et
 End of changes. 189 change blocks. 
290 lines changed or deleted 275 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)