Permalink
Browse files

Scheduler improvements, dstat_snooze, DSTAT_TIMEFMT env var

  • Loading branch information...
1 parent ae3164a commit 5903b489c6897c4320c29feedd950c9d98799a2f @dagwieers committed Mar 15, 2008
Showing with 71 additions and 66 deletions.
  1. +4 −1 ChangeLog
  2. +48 −65 dstat
  3. +19 −0 plugins/dstat_snooze.py
View
@@ -2,7 +2,10 @@
- Added improved tick patch (Kelly Long)
- Show milliseconds in dstat_time when using --debug cfr. dstat_epoch
- Difference in integer rounding should not affect colouring
-- Fixed the IOError when terminal is suspended and IO is unbuffered. (Dbt 309953)
+- Fixed the IOError when terminal is suspended and IO is unbuffered (Dbt 309953)
+- Scheduler accuracy improvements by using sched instead of signal
+- Added external dstat_snooze plugin (Kelly Long)
+- Improved dstat_time to accept format string from DSTAT_TIMEFMT (Kelly Long)
* 0.6.7 - Cambridge overdue - released 26/02/2008
- Only rewrite xterm title when XTERM_SHELL is set to bash
View
@@ -23,8 +23,8 @@ def inspath(path):
sys.path.insert(1, path)
try:
- import sys, signal, os, re, time
- import types, signal, resource, getpass
+ import sys, os, time, sched, re
+ import types, resource, getpass
inspath('/usr/local/share/dstat/')
inspath('/usr/share/dstat/')
inspath(os.path.abspath(os.path.dirname(sys.argv[0])) + '/plugins/') # binary path + /plugins/
@@ -1272,20 +1272,29 @@ class dstat_tcp(dstat):
elif l[3] in ('06',): self.val['wait'] = self.val['wait'] + 1
elif l[3] in ('04', '05', '07', '08', '0B',): self.val['close'] = self.val['close'] + 1
+### FIXME: If timefmt < len(self.nick) output is fucked up
class dstat_time(dstat):
def __init__(self):
self.name = 'time'
- self.format = ('s', 14, 0)
- if op.debug:
+ self.timefmt = os.getenv('DSTAT_TIMEFMT')
+ if self.timefmt:
+ tmp = time.strftime(self.timefmt, time.localtime())
+ self.format = ('s', len(tmp), 0)
+ elif op.debug:
self.format = ('s', 18, 0)
+ else:
+ self.format = ('s', 14, 0)
self.nick = ('date/time',)
self.vars = ('time',)
self.init(self.vars, 1)
def extract(self):
- self.val['time'] = time.strftime('%d-%m %H:%M:%S', time.localtime())
- if op.debug:
- self.val['time'] = time.strftime('%d-%m %H:%M:%S', time.localtime()) + ".%d" % (time.time() * 1000 % 1000 )
+ if self.timefmt:
+ self.val['time'] = time.strftime(self.timefmt, time.localtime())
+ elif op.debug:
+ self.val['time'] = time.strftime('%d-%m %H:%M:%S', time.localtime()) + ".%03d" % (time.time() * 1000 % 1000 )
+ else:
+ self.val['time'] = time.strftime('%d-%m %H:%M:%S', time.localtime())
def show(self):
if step == op.delay:
@@ -1625,7 +1634,7 @@ def initterm():
termsize = None, None
### Unbuffered sys.stdout
-# sys.stdout = os.fdopen(1, 'w', 0)
+# sys.stdout = os.fdopen(1, 'w', 0)
try:
global fcntl, struct, termios
@@ -1760,11 +1769,7 @@ def readfile(file):
ret = ret + line
return ret
-def signaler(signum, frame):
- signal.alarm(interval)
-
def exit(ret):
- signal.signal(signal.SIGALRM, signal.SIG_IGN)
sys.stdout.write(ansi['reset'])
sys.exit(ret)
@@ -1790,6 +1795,7 @@ def listmodules():
def main():
global update, loop, step, pagesize, cpunr, ansi, interval, outputfile, tick, cols
+ global totlist, oldvislist, tt, tickbefore
loop = update = 0
step = op.delay
@@ -1889,15 +1895,9 @@ def main():
### 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__
+# print o.__module__
except Exception, e:
if mod == mods[-1]:
info(1, 'Module %s failed to load. (%s)' % (mod, e))
@@ -1925,21 +1925,41 @@ def main():
showcsvtitle(1, totlist)
showcsvtitle(2, totlist)
- ### Increase precision if we're root (does not seem to have effect)
-# if os.geteuid() == 0:
-# os.nice(-20)
-# sys.setcheckinterval(op.delay / 10000)
-
### Always show header the first time
showheader = True
- signal.signal(signal.SIGALRM, signaler)
- signal.alarm(interval)
-
tt = 0
+ scheduler = sched.scheduler(time.time, time.sleep)
+ now = time.time()
+ tickbefore = now
+
### Let the games begin
while update <= op.delay * op.count or op.count == -1:
+ scheduler.enterabs(now + update, 1, perform, ())
+ scheduler.run()
+
+ if op.update:
+ sys.stdout.write('\n')
+
+def perform():
+ global totlist, oldvislist, loop, step, interval, update, showheader, tickbefore, tt, t1, t2, tick
+
+ ### The last step in a loop is to show the definitive line on its own line
+ if op.update:
+ if step == op.delay and update != 0:
+ sys.stdout.write('\n' + ansi['reset'] + ansi['clearline'] + ansi['save'])
+# import gc
+# for object in gc.get_objects():
+# if isinstance(object, dstat):
+# print dir(object)
+# for object2 in gc.get_referents(object):
+# print object2
+ else:
+ sys.stdout.write(ansi['restore'])
+
+ loop = (update + op.delay - 1) / op.delay
+ step = ((update - 1) % op.delay) + 1
if op.debug:
if step == 1: tt = 0
@@ -1976,10 +1996,6 @@ def main():
showtitle(1, totlist, vislist, ansi['darkblue'] + char['space'], ansi['darkblue'] + char['gt'])
showtitle(2, totlist, vislist, ansi['gray'] + char['pipe'], ansi['darkblue'] + char['gt'])
- ### Flush output since this is buffered I/O
- try: sys.stdout.flush()
- except IOError: pass
-
### Prepare the colors for intermediate updates, last step in a loop is definitive
if step == op.delay:
ansi['default'] = ansi['reset']
@@ -2024,30 +2040,7 @@ def main():
sys.stdout.write('\n')
### Flush output since this is buffered I/O
- try: sys.stdout.flush()
- except IOError: pass
-
- ### Do not pause when this is the final loop
- if update <= op.delay * op.count or op.count == -1:
- signal.pause()
-
- ### The last step in a loop is to show the definitive line on its own line
- if op.update:
- if step == op.delay:
- sys.stdout.write('\n' + ansi['reset'] + ansi['clearline'] + ansi['save'])
-# import gc
-# for object in gc.get_objects():
-# if isinstance(object, dstat):
-# print dir(object)
-# for object2 in gc.get_referents(object):
-# print object2
- else:
- sys.stdout.write(ansi['restore'])
-
- loop = (update + op.delay - 1) / op.delay
- step = ((update - 1) % op.delay) + 1
-
- signal.signal(signal.SIGALRM, signal.SIG_IGN)
+ sys.stdout.flush()
### Main entrance
if __name__ == '__main__':
@@ -2057,19 +2050,9 @@ if __name__ == '__main__':
main()
except KeyboardInterrupt, e:
print ansi['default']
-# except IOError, e:
-# if e.errno != 32: ## [Errno 32] Broken pipe
-# print
-# print 'IOError: %s' % e
-# exit(7)
-# except OSError, e:
-# print
-# print 'OSError: %s' % e
-# exit(7)
exit(0)
else:
op = Options('')
step = 1
- tick = ticks()
# vim:ts=4:sw=4:et
@@ -0,0 +1,19 @@
+class dstat_snooze(dstat):
+ def __init__(self):
+ self.name = 'snooze'
+ self.format = ('s', 6, 0)
+ self.nick = ('snooze',)
+ self.vars = self.nick
+ self.init(self.vars, 1)
+
+ def extract(self):
+ self.val['snooze'] = tick
+
+ def show(self):
+ if self.val['snooze'] > step + 1:
+ return ansi['default'] + ' -'
+ color = 'white'
+ if step != op.delay:
+ color = 'gray'
+ snoze, c = fchg(self.val['snooze'], 7, 1000)
+ return ansi[color] + snoze

0 comments on commit 5903b48

Please sign in to comment.