[svn] r6175 - in trunk/tools/dstat: . docs plugins

packagers at lists.rpmforge.net packagers at lists.rpmforge.net
Tue Feb 26 01:25:33 CET 2008


Author: dag
Date: 2008-02-26 00:25:29 +0000 (Tue, 26 Feb 2008)
New Revision: 6175

Added:
   trunk/tools/dstat/docs/cplugins.txt
   trunk/tools/dstat/docs/dstat.1
   trunk/tools/dstat/plugins/dstat_helloworld.py
Modified:
   trunk/tools/dstat/ChangeLog
   trunk/tools/dstat/dstat
   trunk/tools/dstat/dstat.spec
   trunk/tools/dstat/dstat15
Log:
Preparation for v0.6.7

Modified: trunk/tools/dstat/ChangeLog
===================================================================
--- trunk/tools/dstat/ChangeLog	2008-02-25 14:22:18 UTC (rev 6174)
+++ trunk/tools/dstat/ChangeLog	2008-02-26 00:25:29 UTC (rev 6175)
@@ -1,4 +1,4 @@
-* 0.6.6svn - ... - released 15/10/2007
+* 0.6.7 - Cambridge overdue - released 26/02/2008
 - Only rewrite xterm title when XTERM_SHELL is set to bash
 - Added more Dbt (Debian bug tracker) ids in the ChangeLog and TODO
 - Use sys.exit() instead of exit() before color support is detected

Added: trunk/tools/dstat/docs/cplugins.txt
===================================================================
--- trunk/tools/dstat/docs/cplugins.txt	2008-02-25 14:22:18 UTC (rev 6174)
+++ trunk/tools/dstat/docs/cplugins.txt	2008-02-26 00:25:29 UTC (rev 6175)
@@ -0,0 +1,8 @@
+Defining Python class methods in C 
+http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/54352
+
+python class in c / global calls
+http://mail.python.org/pipermail/python-list/2002-August/160784.html
+
+How to create a python class in C
+http://mail.python.org/pipermail/python-list/2000-August/047158.html

Added: trunk/tools/dstat/docs/dstat.1
===================================================================
--- trunk/tools/dstat/docs/dstat.1	2008-02-25 14:22:18 UTC (rev 6174)
+++ trunk/tools/dstat/docs/dstat.1	2008-02-26 00:25:29 UTC (rev 6175)
@@ -0,0 +1,270 @@
+.\" ** You probably do not want to edit this file directly **
+.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1).
+.\" Instead of manually editing it, you probably should edit the DocBook XML
+.\" source for it and then use the DocBook XSL Stylesheets to regenerate it.
+.TH "DSTAT" "1" "02/26/2008" "" ""
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+dstat \- versatile tool for generating system resource statistics
+.SH "SYNOPSIS"
+dstat [\-afv] [options..] [delay [count]]
+.sp
+.SH "DESCRIPTION"
+Dstat is a versatile replacement for vmstat, iostat and ifstat. Dstat overcomes some of the limitations and adds some extra features.
+.sp
+Dstat allows you to view all of your system resources instantly, you can eg. compare disk usage in combination with interrupts from your IDE controller, or compare the network bandwidth numbers directly with the disk throughput (in the same interval).
+.sp
+Dstat also cleverly gives you the most detailed information in columns and clearly indicates in what magnitude and unit the output is displayed. Less confusion, less mistakes, more efficient.
+.sp
+Dstat is unique in letting you aggregate block device throughput for a certain diskset or network bandwidth for a group of interfaces, ie. you can see the throughput for all the block devices that make up a single filesystem or storage system.
+.sp
+Dstat allows its data to be directly written to a CSV file to be imported and used by OpenOffice, Gnumeric or Excel to create graphs.
+.sp
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+\fBNote\fR
+Users of Sleuthkit might find Sleuthkit's dstat being renamed to datastat to avoid a name conflict. See Debian bug #283709 for more information.
+.sp
+.SH "OPTIONS"
+.TP
+\-c, \-\-cpu
+enable cpu stats
+.TP
+\-C 0,3,total
+include cpu0, cpu3 and total
+.TP
+\-d, \-\-disk
+enable disk stats
+.TP
+\-D total,hda
+include hda and total
+.TP
+\-g, \-\-page
+enable page stats
+.TP
+\-i, \-\-int
+enable interrupt stats
+.TP
+\-I 5,10
+include interrupt 5 and 10
+.TP
+\-l, \-\-load
+enable load stats
+.TP
+\-m, \-\-mem
+enable memory stats
+.TP
+\-n, \-\-net
+enable network stats
+.TP
+\-N eth1,total
+include eth1 and total
+.TP
+\-p, \-\-proc
+enable process stats
+.TP
+\-s, \-\-swap
+enable swap stats
+.TP
+\-S swap1,total
+include swap1 and total
+.TP
+\-t, \-\-time
+enable time/date output
+.TP
+\-T, \-\-epoch
+enable time counter (seconds since epoch)
+.TP
+\-y, \-\-sys
+enable system stats
+.TP
+\-\-ipc
+enable ipc stats
+.TP
+\-\-lock
+enable lock stats
+.TP
+\-\-raw
+enable raw stats
+.TP
+\-\-tcp
+enable tcp stats
+.TP
+\-\-udp
+enable udp stats
+.TP
+\-\-unix
+enable unix stats
+.TP
+\-M stat1,stat2
+enable internal stats and external plugin stats
+.TP
+Possible internal stats are
+cpu, cpu24, disk, disk24, disk24old, epoch, int, int24, ipc, load, lock, mem, net, page, page24, proc, raw, swap, swapold, sys, tcp, time, udp, unix
+.TP
+Possible external plugin stats can be listed using
+dstat \-M list
+.TP
+\-a, \-\-all
+equals \-cdngy (default)
+.TP
+\-f, \-\-full
+expand \-C, \-D, \-I, \-N and \-S discovery lists
+.TP
+\-v, \-\-vmstat
+equals \-pmgdsc \-D total
+.TP
+\-\-integer
+show integer values
+.TP
+\-\-nocolor
+disable colors (implies \-\-noupdate)
+.TP
+\-\-noheaders
+disable repetitive headers
+.TP
+\-\-noupdate
+disable intermediate updates when delay > 1
+.TP
+\-\-output file
+write CSV output to file
+.SH "ARGUMENTS"
+\fBdelay\fR is the delay in seconds between each update
+.sp
+\fBcount\fR is the number of updates to display before exiting
+.sp
+The default delay is 1 and count is unspecified (unlimited)
+.sp
+.SH "INTERMEDIATE UPDATES"
+When invoking dstat with a \fBdelay\fR greater than 1 and without the \fB\-\-noupdate\fR option, it will show intermediate updates, ie. the first time a 1 sec average, the second update a 2 second average, etc. until the delay has been reached.
+.sp
+So in case you specified a delay of 10, \fBthe 9 intermediate updates are NOT snapshots\fR, they are averages over the time that passed since the last final update. The end result is that you get a 10 second average on a new line, just like with vmstat.
+.sp
+.SH "USAGE"
+Using dstat to relate disk\-throughput with network\-usage (eth0), total CPU\-usage and system counters:
+.sp
+.sp
+.nf
+dstat \-dnyc \-N eth0 \-C total \-f 5
+.fi
+Checking dstat's behaviour and the system's impact on dstat:
+.sp
+.sp
+.nf
+dstat \-taf \-\-debug
+.fi
+Using the time plugin together with cpu, net, disk, system, load, proc and topcpu plugins:
+.sp
+.sp
+.nf
+dstat \-tcndylp \-M topcpu
+.fi
+this is identical to
+.sp
+.sp
+.nf
+dstat \-M time,cpu,net,disk,sys,load,proc,topcpu
+.fi
+Using dstat to relate cpu stats with interrupts per device:
+.sp
+.sp
+.nf
+dstat \-tcyif
+.fi
+.SH "BUGS"
+Since it's practically impossible to test dstat on every possible permutation of kernel, python or distribution version, I need your help and your feedback to fix the remaining problems. If you have improvements or bugreports, please send them to: [1]\&\fIdag at wieers.com\fR
+.sp
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+\fBNote\fR
+Please see the TODO file for known bugs and future plans.
+.sp
+.SH "FILES"
+Paths that may contain external dstat_* plugins:
+.sp
+.sp
+.nf
+~/.dstat/
+./
+./plugins/
+(path of binary)/plugins/
+/usr/share/dstat/
+/usr/local/share/dstat/
+.fi
+.SH "SEE ALSO"
+.SS "Performance tools"
+.sp
+.nf
+ifstat(1), iftop(8), iostat(1), mpstat(1), netstat(1), nfsstat(1), nstat, vmstat(1), xosview(1)
+.fi
+.SS "Debugging tools"
+.sp
+.nf
+htop, lslk(1), lsof(8), top(1)
+.fi
+.SS "Process tracing"
+.sp
+.nf
+ltrace(1), pmap(1), ps(1), pstack(1), strace(1)
+.fi
+.SS "Binary debugging"
+.sp
+.nf
+ldd(1), file(1), nm(1), objdump(1), readelf(1)
+.fi
+.SS "Memory usage tools"
+.sp
+.nf
+free(1), memusage, memusagestat, slabtop(1)
+.fi
+.SS "Accounting tools"
+.sp
+.nf
+dump\-acct, dump\-utmp, sa(8)
+.fi
+.SS "Hardware debugging tools"
+.sp
+.nf
+dmidecode, ifinfo(1), lsdev(1), lshal(1), lshw(1), lsmod(8), lspci(8), lsusb(8), smartctl(8), x86info(1)
+.fi
+.SS "Application debugging"
+.sp
+.nf
+mailstats(8), qshape(1)
+.fi
+.SS "Xorg related tools"
+.sp
+.nf
+xdpyinfo(1), xrestop(1)
+.fi
+.SS "Other useful info"
+.sp
+.nf
+proc(5)
+.fi
+.SH "AUTHOR"
+Written by Dag Wieers [1]\&\fIdag at wieers.com\fR
+.sp
+Homepage at [2]\&\fIhttp://dag.wieers.com/home\-made/dstat/\fR
+.sp
+This manpage was initially written by Andrew Pollock [3]\&\fIapollock at debian.org\fR for the Debian GNU/Linux system, and updated by Dag Wieers [1]\&\fIdag at wieers.com\fR
+.sp
+.SH "REFERENCES"
+.TP 3
+1.\ dag at wieers.com
+\%mailto:dag at wieers.com
+.TP 3
+2.\ http://dag.wieers.com/home\-made/dstat/
+\%http://dag.wieers.com/home\-made/dstat/
+.TP 3
+3.\ apollock at debian.org
+\%mailto:apollock at debian.org

Modified: trunk/tools/dstat/dstat
===================================================================
--- trunk/tools/dstat/dstat	2008-02-25 14:22:18 UTC (rev 6174)
+++ trunk/tools/dstat/dstat	2008-02-26 00:25:29 UTC (rev 6175)
@@ -16,7 +16,7 @@
 
 from __future__ import generators
 
-VERSION = '0.6.6svn'
+VERSION = '0.6.7'
 
 def inspath(path):
     if os.path.isdir(path) and path not in sys.path:
@@ -90,9 +90,9 @@
 
         ### Implicit if no terminal is used
         if not sys.stdout.isatty():
+            self.color = False
+            self.header = False
             self.update = False
-            self.header = False
-            self.color = False
 
         ### Temporary hardcoded for my own project
         self.diskset = {
@@ -1865,12 +1865,14 @@
                 if 'dstat_'+mod not in globals().keys():
                     import imp
                     file, pathname, description = imp.find_module('dstat_'+mod)
+
                     ### Try loading python plugin
                     if description[0] == '.py':
 #                           exec compile(readfile(pathname), pathname, 'exec')
                             execfile(pathname)
                             exec 'o = dstat_%s()' % mod
-                ### Try loading C plugin
+
+                    ### Try loading C plugin
                     elif description[0] == '.so':
                         exec 'import dstat_%s' % mod
                         exec 'o = dstat_%s.new()' % mod
@@ -1880,7 +1882,8 @@
 #                        print o.name
                     else:
                         info(1, 'Module is of unknown type.')
-                ### Remove defect stat objects and calculate line length
+
+                    ### Remove defect stat objects and calculate line length
                     if not o.check():
                         raise Exception, 'Unknown problem, please report'
 #                except Exception, e:

Modified: trunk/tools/dstat/dstat.spec
===================================================================
--- trunk/tools/dstat/dstat.spec	2008-02-25 14:22:18 UTC (rev 6174)
+++ trunk/tools/dstat/dstat.spec	2008-02-26 00:25:29 UTC (rev 6175)
@@ -9,7 +9,7 @@
 
 Summary: Versatile resource statistics tool
 Name: dstat
-Version: 0.6.6svn
+Version: 0.6.7
 Release: 1
 License: GPL
 Group: System Environment/Base
@@ -60,8 +60,8 @@
 %{_datadir}/dstat/
 
 %changelog
-* Sun Jun 24 2007 Dag Wieers <dag at wieers.com> - 0.6.6svn-1
-- Updated to release 0.6.6svn.
+* Tue Feb 26 2008 Dag Wieers <dag at wieers.com> - 0.6.7-1
+- Updated to release 0.6.7.
 
 * Sat Apr 28 2007 Dag Wieers <dag at wieers.com> - 0.6.6-1
 - Updated to release 0.6.6.

Modified: trunk/tools/dstat/dstat15
===================================================================
--- trunk/tools/dstat/dstat15	2008-02-25 14:22:18 UTC (rev 6174)
+++ trunk/tools/dstat/dstat15	2008-02-26 00:25:29 UTC (rev 6175)
@@ -12,11 +12,11 @@
 ### You should have received a copy of the GNU Library General Public License
 ### along with this program; if not, write to the Free Software
 ### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-### Copyright 2004, 2005 Dag Wieers <dag at wieers.com>
+### Copyright 2004-2007 Dag Wieers <dag at wieers.com>
 
 #from __future__ import generators
 
-VERSION = '0.6.6svn'
+VERSION = '0.6.7'
 
 def inspath(path):
     if os.path.isdir(path) and path not in sys.path:
@@ -75,16 +75,16 @@
         self.intlist = None
         self.netlist = None
         self.swaplist = None
-        self.color = False
+        self.color = True
         self.update = True
         self.header = True
         self.output = False
-        self.isatty = sys.stdout.isatty()
 
         ### Implicit if no terminal is used
-        if not self.isatty:
+        if not sys.stdout.isatty():
+            self.color = False
+            self.header = False
             self.update = False
-            self.header = False
 
         ### Temporary hardcoded for my own project
         self.diskset = {
@@ -102,7 +102,7 @@
                 'noheaders', 'noupdate', 'output=', 'version', 'vmstat'])
         except getopt.error, exc:
             print 'dstat: %s, try dstat -h for a list of all the options' % str(exc)
-            exit(1)
+            sys.exit(1)
 
         self.modlist = []
 
@@ -179,10 +179,10 @@
             elif opt in ['-h', '--help']:
                 self.usage()
                 self.help()
-                exit(0)
+                sys.exit(0)
             elif opt in ['-V', '--version']:
                 self.version()
-                exit(0)
+                sys.exit(0)
 
         if not self.modlist:
             self.modlist = [ 'cpu', 'disk', 'net', 'page', 'sys' ]
@@ -192,11 +192,11 @@
             if len(args) > 1: self.count = int(args[1])
         except:
             print 'dstat: incorrect argument, try dstat -h for the correct syntax'
-            exit(1)
+            sys.exit(1)
 
         if self.delay <= 0:
             print 'dstat: delay must be an integer, greater than zero'
-            exit(1)
+            sys.exit(1)
 
     def version(self):
         print 'Dstat %s' % VERSION
@@ -207,12 +207,17 @@
         print 'Kernel %s' % os.uname()[2]
         print 'Python %s' % sys.version
         print
+
+        color = ""
+        if not gettermcolor(self.color):
+            color = "no "
+        print 'Terminal type: %s (%scolor support)' % (os.getenv('TERM'), color)
         rows, cols = gettermsize()
         print 'Terminal size: %d lines, %d columns' % (rows, cols)
         print
         print 'Processors: %d' % getcpunr()
         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
 
         global op
@@ -479,7 +484,7 @@
         if op.cpulist:
             list = op.cpulist
         elif not op.full:
-            list = ('total', )
+            list = ('total',)
         else:
             list = []
             cpu = 0
@@ -539,7 +544,7 @@
         if op.cpulist:
             list = op.cpulist
         elif not op.full:
-            list = ('total', )
+            list = ('total',)
         else:
             list = []
             cpu = 0
@@ -582,7 +587,6 @@
             if len(l) < 13: continue
             if l[3:] == ['0',] * 11: continue
             name = l[2]
-            if re.match('(md[0-9]+|dm-[0-9]+)', name): continue
             ret.append(name)
         for item in list: ret.append(item)
         return ret
@@ -592,9 +596,12 @@
         if op.disklist:
             list = op.disklist
         elif not op.full:
-            list = ('total', )
+            list = ('total',)
         else:
-            list = self.discover
+            list = []
+            for name in self.discover:
+                if not re.match('(md[0-9]+|dm-[0-9]+)', name):
+                    list.append(name)
 #           if len(list) > 2: list = list[0:2]
             list.sort()
         for name in list:
@@ -646,8 +653,7 @@
             l = string.split(line)
             if len(l) < 15 or l[0] == 'major' or int(l[1]) % 16 != 0: continue
             name = l[3]
-            if re.match('(md[0-9]+|dm-[0-9]+)', name): continue
-            ret.append(name)    
+            ret.append(name)
         for item in list: ret.append(item)
         return ret
 
@@ -656,9 +662,12 @@
         if op.disklist:
             list = op.disklist
         elif not op.full:
-            list = ('total', )
+            list = ('total',)
         else:
-            list = self.discover
+            list = []
+            for name in self.discover:
+                if not re.match('(md[0-9]+|dm-[0-9]+)', name):
+                    list.append(name)
 #           if len(list) > 2: list = list[0:2]
             list.sort()
         for name in list:
@@ -725,9 +734,12 @@
         if op.disklist:
             list = op.disklist
         elif not op.full:
-            list = ('total', )
+            list = ('total',)
         else:
-            list = self.discover
+            list = []
+            for name in self.discover:
+                if not re.match('(md[0-9]+|dm-[0-9]+)', name):
+                    list.append(name)
 #           if len(list) > 2: list = list[0:2]
             list.sort()
         for name in list:
@@ -782,6 +794,7 @@
 #   def show(self):
 #       return ansi['reset'] + ( '%10.2f' % self.val['epoch'] )
 
+### FIXME: Make total work as well
 class dstat_int(dstat):
     def __init__(self):
         self.name = 'interrupts'
@@ -791,7 +804,7 @@
         self.intmap = self.intmap()
         self.vars = self.vars()
         self.nick = self.vars
-        self.init(self.vars, 1)
+        self.init(self.vars + ['total'], 1)
 
     def intmap(self):
         ret = {}
@@ -829,7 +842,7 @@
         if op.intlist:
             list = op.intlist
         else:
-            list = self.discover
+            list = self.discover + ['total']
             for name in list:
                 if name in ('0', '1', '2', '8', 'NMI', 'LOC', 'MIS', 'CPU0'):
                     list.remove(name)
@@ -847,7 +860,8 @@
             if not l or l[0] != 'intr': continue
             for name in self.vars:
                 self.cn2[name] = long(l[int(name) + 2])
-        for name in self.vars:
+            self.cn2['total'] = self.cn2['total'] + long(l[int(name) + 2])
+        for name in self.vars + ['total']:
             self.val[name] = (self.cn2[name] - self.cn1[name]) * 1.0 / tick
         if step == op.delay:
             self.cn1.update(self.cn2)
@@ -1028,7 +1042,7 @@
         if op.netlist:
             list = op.netlist
         elif not op.full:
-            list = ('total', )
+            list = ('total',)
         else:
             list = self.discover
 #           if len(list) > 2: list = list[0:2]
@@ -1172,7 +1186,7 @@
         if op.swaplist:
             list = op.swaplist
         elif not op.full:
-            list = ('total', )
+            list = ('total',)
         else:
             list = self.discover
 #           if len(list) > 2: list = list[0:2]
@@ -1262,6 +1276,7 @@
         self.init(self.vars, 1)
 
     def extract(self):
+        ### FIXME: Add milliseconds when using --debug (see dstat_epoch)
         self.val['time'] = time.strftime('%d-%m %H:%M:%S', time.localtime())
 
     def show(self):
@@ -1425,8 +1440,38 @@
     while select.select([file.fileno()], [], [], tmout)[0]:
         ret = ret + file.read(1)
     return string.split(ret, '\n')
-#   return ret
 
+def greppipe(file, str, tmout = 0.001):
+    "Grep available data from pipe in a non-blocking fashion"
+    ret = ''
+    while not select.select([file.fileno()], [], [], tmout)[0]:
+        pass
+    while select.select([file.fileno()], [], [], tmout)[0]:
+        char = file.read(1)
+        if char != '\n':
+            ret = ret + char
+        elif ret.startswith(str):
+            return ret
+        else:
+            ret = ''
+    return None
+
+def matchpipe(file, string, tmout = 0.001):
+    "Match available data from pipe in a non-blocking fashion"
+    ret = ''
+    regexp = re.compile(string)
+    while not select.select([file.fileno()], [], [], tmout)[0]:
+        pass
+    while select.select([file.fileno()], [], [], tmout)[0]:
+        char = file.read(1)
+        if char != '\n':
+            ret = ret + char
+        elif regexp.match(ret):
+            return ret
+        else:
+            ret = ''
+    return None
+
 def dchg(var, max, base):
     "Convert decimal to string given base and length"
     c = 0
@@ -1608,6 +1653,18 @@
             termsize = 25, 80
     return termsize
 
+def gettermcolor(color=True):
+    if color and sys.stdout.isatty():
+        try:
+            import curses
+            curses.setupterm()
+            if curses.tigetnum('colors') < 0:
+                return False
+        except:
+            info(1, 'Color support is disabled, python-curses is not installed.')
+            return False
+    return color
+
 def getcpunr():
     "Return the number of CPUs in the system"
     cpunr = -1
@@ -1740,21 +1797,14 @@
     rows, cols = gettermsize()
 
     ### Write term-title
-    if op.isatty:
-        term = os.environ['TERM']
-        if term and re.compile('(screen*|xterm*)').match(term):
+    if sys.stdout.isatty():
+        shell = os.getenv('XTERM_SHELL')
+        term = os.getenv('TERM')
+        if shell == '/bin/bash' and term and re.compile('(screen*|xterm*)').match(term):
             sys.stdout.write('\033]0;(%s@%s) %s %s\007' % (user, hostname, os.path.basename(sys.argv[0]), string.join(op.args, ' ')))
 
     ### Check terminal capabilities
-    if op.isatty:
-        op.color = True
-        try:
-            import curses
-            curses.setupterm()
-            if curses.tigetnum('colors') < 0:
-                op.color = False
-        except:
-            op.color = False
+    op.color = gettermcolor(op.color)
 
     if op.output:
         if os.path.exists(op.output):
@@ -1793,36 +1843,54 @@
         else: mods = ( module, )
 
         for mod in mods:
-            if 'dstat_'+mod not in globals().keys():
-                try:
+            try:
+                if 'dstat_'+mod not in globals().keys():
                     import imp
                     file, pathname, description = imp.find_module('dstat_'+mod)
-#                   exec compile(readfile(pathname), pathname, 'exec')
-                    execfile(pathname)
-                except Exception, e:
-                    info(1, 'Module %s failed to load. (%s)' % (mod, e))
-#                   tb = sys.exc_info()[2]
-                    continue
 
-            try:
-#               exec compile('o = dstat_%s()' % mod, '<string>', 'single')
-                exec 'o = dstat_%s()' % mod
+                    ### Try loading python plugin
+                    if description[0] == '.py':
+#                           exec compile(readfile(pathname), pathname, 'exec')
+                            execfile(pathname)
+                            exec 'o = dstat_%s()' % mod
 
-                ### Remove defect stat objects and calculate line length
-                if not o.check():
-                    raise Exception, 'Unknown problem, please report'
+                    ### Try loading C plugin
+                    elif description[0] == '.so':
+                        exec 'import dstat_%s' % mod
+                        exec 'o = dstat_%s.new()' % mod
+#                        exec 'o = dstat_%s.init(dstat)' % mod
+#                        print dir(o)
+#                        print o.__module__
+#                        print o.name
+                    else:
+                        info(1, 'Module is of unknown type.')
 
-                linewidth = linewidth + o.statwidth() + 1
-                totlist.append(o)
-                break
-
+                    ### Remove defect stat objects and calculate line length
+                    if not o.check():
+                        raise Exception, 'Unknown problem, please report'
+#                except Exception, e:
+#                    if mod == mods[-1]:
+#                        info(1, 'Module %s has problems. (%s)' % (mod, e))
+#                        if op.debug:
+#                            raise
+#                    continue
+                else:
+                    exec 'o = dstat_%s()' % mod
+#                print o.__module__
             except Exception, e:
                 if mod == mods[-1]:
-                    info(1, 'Module %s has problems. (%s)' % (mod, e))
-                    if op.debug:
-                        raise
+                    info(1, 'Module %s failed to load. (%s)' % (mod, e))
+                elif op.debug:
+                    info(1, 'Module %s failed to load, trying another. (%s)' % (mod, e))
+                if op.debug:
+                    raise
+#                tb = sys.exc_info()[2]
                 continue
 
+            linewidth = linewidth + o.statwidth() + 1
+            totlist.append(o)
+            break
+
     if not totlist:
         die(8, 'None of the stats you selected are available.')
 
@@ -1860,7 +1928,7 @@
             curwidth = 0
 
         ### Trim object list to what is visible on screen
-        if op.isatty:
+        if sys.stdout.isatty():
             rows, cols = gettermsize()
             vislist = []
             for o in totlist:
@@ -1914,9 +1982,9 @@
             tt = tt + (t2 - t1) * 1000.0
             if loop == 0: tt = tt * step
             if op.debug == 1:
-                sys.stdout.write('%6.2fms' % (tt / step))
+                sys.stdout.write('%s%6.2fms%s' % (ansi['darkblue'], tt / step, ansi['default']))
             elif op.debug > 1:
-                sys.stdout.write('%6.2f [%d:%d:%d]' % (tt / step, loop, step, update))
+                sys.stdout.write('%s%6.2f %s%d:%d:%d%s' % (ansi['darkblue'], tt / step, ansi['gray'], loop, step, update, ansi['default']))
 
         ### If intermediate results, update increases with 1 sec (=interval)
         update = update + interval
@@ -1948,7 +2016,7 @@
         op = Options(sys.argv[1:])
         main()
     except KeyboardInterrupt, e:
-        print
+        print ansi['default']
 #   except IOError, e:
 #       if e.errno != 32:               ## [Errno 32] Broken pipe
 #           print

Added: trunk/tools/dstat/plugins/dstat_helloworld.py
===================================================================
--- trunk/tools/dstat/plugins/dstat_helloworld.py	2008-02-25 14:22:18 UTC (rev 6174)
+++ trunk/tools/dstat/plugins/dstat_helloworld.py	2008-02-26 00:25:29 UTC (rev 6175)
@@ -0,0 +1,17 @@
+### Dstat Hello World plugin
+### Displays hello world
+###
+### Authority: dag at wieers.com
+
+class dstat_helloworld(dstat):
+    def __init__(self):
+        self.name = 'plugin title'
+        self.format = ('s', 12, 0)
+        self.nick = ('counter',)
+        self.vars = ('text',)
+        self.init(self.vars, 1)
+
+    def extract(self):
+        self.val['text'] = 'Hello world!'
+
+# vim:ts=4:sw=4:et



More information about the svn-commits mailing list