[rrd-users] Holt-Winters interactive simulator

Sven Ulland sveniu at opera.com
Wed Mar 21 08:40:42 CET 2007


Darryl Lewis wrote:
> Apart from python (because I don't know it, I'm a shell and perl user), fantastic!
> 
> Do you have this somewhere for download? I think the email proggies may have messed it up a bit

Yes, you can fetch the script from:
  http://people.opera.com/sveniu/rrdsim/rrdsim.py.gz (4kB)
A fullsize screenshot is also available:
  http://people.opera.com/sveniu/rrdsim/rrdsim.png (24kB)

For you people from the future: The URLs might not work, but the
script is included inline in the original posting with message
ID <46000C38.5030004 at opera.com>, Tue Mar 20 17:30:48 2007.

Sven


> -----Original Message-----
> From: rrd-users-bounces at lists.oetiker.ch
> [mailto:rrd-users-bounces at lists.oetiker.ch]On Behalf Of Sven Ulland
> Sent: Wednesday, 21 March 2007 3:31 AM
> To: rrd-users at lists.oetiker.ch
> Subject: [rrd-users] Holt-Winters interactive simulator
> 
> 
> This is a quick GUI hack that you can use to fiddle about with
> parameters for RRDtool's built-in aberrant behaviour detection. It is
> a hack indeed, but it might be usable for some. It uses python
> together with gtk2 and glade, and should work on any recent system
> with that software installed. It uses fake time progression to speed
> up the graphing and you can change input values in realtime.
> 
> The script [1] is simple to modify, and modifications are encouraged.
> A bad quality screenshot [2] has been included in case you'd rather
> see what it looks like before trying.
> 
> Sven
> 
> 
> [1] The script.
> 
> #!/usr/bin/env python
> #
> # Author:  Sven Ulland <svengiu at ifig.uio.no> (remove every 'g')
> # License: Public domain
> #
> # This is a quick hack to test and play with the Holt-Winters aberrant
> # behaviour detection implementation in RRDtool. It simply reads a user
> # input value and updates a given RRD file with that value. The RRD is then
> # graphed and displayed on the screen. Since RRDtool currently does not
> # support subsecond intervals, we fake time progression by incrementing an
> # integer in stead of reading the actual unix time on the system.
> #
> # To run this program, you need an RRD file. The defaults are set up to
> # simulate a HW period of 30 seconds, so the RRD file should reflect this.
> # An example:
> #   $ rrdtool create sim.rrd \
> #     --step 1 \
> #     DS:sim:GAUGE:5:0:400 \
> #     RRA:AVERAGE:0.5:1:400 \
> #     RRA:HWPREDICT:30:0.1:0.1:30
> #
> # The input value automation is a simple sine generator that fits the sine
> # period to the period speficied in the script (default 30 seconds).
> #
> # Usage is pretty straight-forward. Let the simplator run for a few periods
> # with slight noise to have the HW algo adapt to the input signal. Then
> # fiddle around with the input level slider or the noise slider to see how
> # resistant the adaption is to aberrant behaviour.
> #
> # This script should work out of the box on any recent OS that supports
> # Python 2.4, GTK2, and Python bindings for GTK2 and Glade2. This should do
> # the trick on Debian-based Linux distributions:
> #
> #   # apt-get install python-glade2 python-gtk2
> #
> # To execute this, simply run the following:
> #
> #   $ python rrdsim.py
> #
> 
> import sys
> import commands
> import math
> import random
> import zlib
> import base64
> 
> GRAPH_MIN = 0
> GRAPH_MAX = 100
> AUTO_MIN = 20
> AUTO_MAX = 80
> PERIOD = 30.    # seconds
> RRDTOOLPATH = "rrdtool"
> RRDPATH = "sim.rrd"
> GRAPHPATH = "plot.png"
> GLADEPATH = "sim.glade"
> 
> # You might want to tweak this one, depending on how fast
> # your computer is, and how fast you want the graph to move.
> # A 100 ms interval would result in 10 updates per second.
> TIMER_INTERVAL = 100    # milliseconds
> 
> # This is the GTK glade file that defines the user
> # interface. This file will be decoded and written to the
> # working directory when the script is run. It is simply run
> # through base64.b64decode() and then zlib.compress()
> GLADE_UI = """
> eJztWVtP4zgUfoZf4cnjatsmRTOgqu2IgQxUCy1qA4gnyyQm8da1s7ZT6P76PUkKtMVt09WO2N3
> hAeEk37n4nO9cpLa/Pk04mlKlmRQdx6u7DtKGiIhwKWjHEdL52kXtT7XaLzU0kRFtoVwAnmrd/f
> an08FJcHflo5iTiNaYMFQ9kJCi0d0o8C+RkxiTthqN4nM9FnJC61LF5XOtWXfrkYmc7v5+e0VB/
> uqRRTE1KORE645zZsa3TETy0UEs6jiPxdkDWYTaqZIpVWaGBJmAz1Om2T2nTjdQGW03nr/aoIYZ
> ACKjiNCcGAJiHWdGtdMdDk/R+S3SbJLBB6m26JmlYO8s+A3f9vqng1scDK4u/Bv/YrNYeQucSs0
> MxP9FA74ajPCJ3w/84WYFkBHCne53wvWWmyqq2Z+kCEsFdES1UXKGH5lJcEoUFaZKOCMaSkUMja
> qA9Zil2BA9vicKJyy3UMGzQiolMd1BJs/OHH12+poiIC4+7/UD3B8ML4+3pCpWZMrMrNRwNjy+6
> QV3uWBwjm/9UbBZ+EGGmcZS4AlJq4QmUzEV4WzDDTWLBeHL2XJQAoXLqeo4YGpeIRgcTxP8AoFq
> Mhhowx5YSHLSYcNyHUGS/Yq8z+iSKNR03UPkHbSabqvpobPLwGlAQYLVMGE8yu3D+U15nn+TT2V
> xJvfyqSzNAlm9PG3wRE4kRIPKTFtDYZPRKQmZiJ2uu4h9Bs9vsff2Cr0JEKu8A8uPZfDgJnu22o
> 2gNhT9I4PQOt3PR96iLYtAQlmcmFeJ5pejLRJrI2XBPhEOlIAb1z9vQc4qI59SEq3E0KbPgmo3y
> tjmR8jFGJJhlQXR6G2iLEAKvghLW7FAHxjnFiA8PDsy50FjToTtvLh5ofYUqN20E2KXbG0mtUVg
> DaP3Fty2V+XNKCR8zumpzs+YZEY6c4GtvD5YzcxOJb0Gb6TkhqXWwdsTaWYQp1PKK2gKicBFd61
> sO1LkEU8Jz6q7W6DzKV0O6Hw4w3yvYovFzOi37LZhszSCyQlWOAtnpaHrq9PjwMcng37Q618Prk
> cV1DABy5x1Aq8RINHvmTaTYsK7yEWeC3/w3+rz0tgpwxLC0InB3tLwWWAaXoHtMoDcw9bB0fMAs
> vpwnxkDKlJYbzQGzsAt1jpiw1b35jD3xv1SxRtFOSWaVvRnBb2jR15zyaOFxlsme6H52rK/tgHb
> wBuasA2+phGXbi5NhZdOvL2fnSQ0HH8rIlc2tTB/MQ/l5s72T3YpX+QPKDc4KbL0Q3oVJ/eUW+1
> XaSjAqUxEVHEmql8a2MjoQ9l/hv5Fz/9uWY/XJfx5zQ2hh42rd6DQsGl1D5kIpdBMG2pdjje1fV
> iJ86KSar2xpXo2Mo75am9bJRx+Qe1Sugdeq/kOpVs1XGXt2tFrivf/vfR5//GlT0im6b936+vn7
> n1sfe+y9UFn2rT2/dwrxZa6+QE7RWHxY534GdeJIvV/e5/wDj/2iXfbJ5YjvvDh9SUc3/zM8Reb
> P1vs
> """
> 
> try:
>         import pygtk
>         pygtk.require("2.0")
> except:
>         # Some distributions come with GTK2, but not pyGTK
>         pass
> try:
>         import gtk
>         import gtk.glade
>         import gobject
> except:
>         sys.stderr.write("Error: Install pyGTK or GTKv2.\n")
>         sys.exit(1)
> 
> def autovalue(timestamp):
>         timeoffset = timestamp % PERIOD
>         return ( (GRAPH_MAX - GRAPH_MIN)/2 ) + \
>                 ( (AUTO_MAX - AUTO_MIN)/2 ) * \
>                 math.sin(timeoffset * (2. / PERIOD * math.pi))
> 
> class rrdgui:
>         def __init__(self):
>                 self.vscale_auto_drag = False
>                 self.value = 0
>                 self.timestamp = int(commands.getoutput("%s last %s" % \
>                                 (RRDTOOLPATH, RRDPATH)))
> 
>                 # Decode the glade UI and write to file.
>                 try:
>                         f = open(GLADEPATH, 'w')
>                         f.write(zlib.decompress(base64.b64decode(GLADE_UI)))
>                         f.close()
>                 except IOError:
>                         sys.stderr.write("Could not open \"%s\" for writing. Check permissions." % GLADEPATH)
>                         sys.exit(1)
> 
>                 windowname = "window1"
>                 self.wTree = gtk.glade.XML (GLADEPATH, windowname)
>                 dic = {
>                         "on_window1_graph_destroy": (gtk.main_quit),
>                         "on_vscale_auto_button_press_event": \
>                                         self.on_vscale_auto_button_press_event,
>                         "on_vscale_auto_button_release_event": \
>                                         self.on_vscale_auto_button_release_event
>                 }
>                 self.wTree.signal_autoconnect (dic)
> 
>                 # Create a timer that signals every second.
>                 gobject.timeout_add(TIMER_INTERVAL, self.timer_exec)
> 
>                 # Set the input vscale to zero.
>                 self.wTree.get_widget("vscale_auto").set_value(autovalue(self.timestamp))
> 
>                 return
> 
>         #
>         # GTK callback functions
>         #
>         def on_vscale_auto_button_press_event(self, widget, foo):
>                 self.vscale_auto_drag = True
>         def on_vscale_auto_button_release_event(self, widget, foo):
>                 self.vscale_auto_drag = False
> 
>         # Timer signal
>         def timer_exec(self):
>                 self.timestamp += 1     # Fake time progression
>                 try:
>                         if not self.wTree.get_widget("checkbutton_auto").get_active() \
>                                         or self.vscale_auto_drag:
>                                 # Automation disabled or slider is dragged manually.
>                                 self.value = int(self.wTree.get_widget("vscale_auto").get_value())
>                         else:
>                                 # Automation enabled and slider is inactive.
>                                 self.value = autovalue(self.timestamp)
>                                 self.wTree.get_widget("vscale_auto").set_value(self.value)
>                 except AttributeError:
>                         return True
> 
>                 if self.wTree.get_widget("checkbutton_noise").get_active():
>                         # Add noise
>                         noise_magnitude = int(self.wTree.get_widget("vscale_noise").get_value())
>                         try:
>                                 self.value += random.randrange(-noise_magnitude, noise_magnitude, 1)
>                         except ValueError:
>                                 pass
> 
>                 output = commands.getoutput("%s updatev %s %s:%s" % \
>                                 (RRDTOOLPATH, RRDPATH, self.timestamp, self.value) )
>                 commands.getstatusoutput(\
>                         "%s graph %s " % (RRDTOOLPATH, GRAPHPATH) + \
>                         "--end %s --start end-200s " % self.timestamp + \
>                         "-w 500 -h 200 " + \
>                         "-l %d -u %d -r " % (GRAPH_MIN, GRAPH_MAX) + \
>                         "DEF:vsim=%s:sim:AVERAGE " % RRDPATH + \
>                         "DEF:pred=%s:sim:HWPREDICT " % RRDPATH + \
>                         "DEF:dev=%s:sim:DEVPREDICT " % RRDPATH + \
>                         "DEF:season=%s:sim:SEASONAL " % RRDPATH + \
>                         "DEF:devseason=%s:sim:DEVSEASONAL " % RRDPATH + \
>                         "DEF:fail=%s:sim:FAILURES " % RRDPATH + \
>                         "CDEF:dev_lower=pred,dev,2,*,- " + \
>                         "CDEF:dev_upper=pred,dev,2,*,+ " + \
>                         "TICK:fail#ffccff:1.0:\"Failures\" " + \
>                         "LINE1:dev_lower#66ff66:\"Dev\" " + \
>                         "LINE1:dev_upper#66ff66 " \
>                         "LINE1:vsim#000000 " )
> 
>                 self.img = self.wTree.get_widget("image_graph")
>                 self.img.set_from_file(GRAPHPATH)
>                 self.img.show()
> 
>                 # Must return True to reset timer.
>                 return True
> 
> def main():
>         try:
>                 f = open(RRDPATH)
>                 f.close()
>         except IOError:
>                 sys.stderr.write("Could not read RRD file \"%s\"\n" % RRDPATH)
>                 sys.exit(1)
> 
>         app = rrdgui()
>         gtk.main()
> 
> if __name__ == '__main__':
>         main()
> #EOF
> 
> [2] The bad quality screenshot.
> This is a small screenshot of the application, in case you don't have
> the appropriate software installed to run it and you're contemplating
> whether it's worth the trouble to test it out. To decode the shot,
> copy the entire block of text into a file "foo.txt", and run python
> from the same directory. In the python shell, run
>>>> import base64
>>>> open('shot.png','w').write(base64.b64decode(open('foo.txt').read()))
> ..which will write the screenshot to 'shot.png'.
> 
> What you're looking at is a normal RRD graph showing the input value
> (black), along with confidence bands (green) and a failure indication
> color (light purple). Two sliders control the input value and noise
> level, respectively. Two checkbuttons control the sine automation,
> and enables/disables noise. The graph display is updated 10 times per
> second to simulate time progression.
> 
> iVBORw0KGgoAAAANSUhEUgAAAQQAAAB3BAMAAAAX5yPiAAAAMFBMVEVtZFvMgzuYk4++j2
> Kxl3zYlU6xrqyY4pDmvZHQzMnV7MzD/sP54Orx6unw8u/9//w3dYQ1AAATZElEQVRo3sVb
> XYwb13VerxIlKurCi7UK9CHFlinYLmDLWqwEOA8y6kgJICBrd6tusX1QwE4cOjREsm9+lW
> obUF+KEaVMPKpmJsiDBHPB+tHA+sGuUAiwQNoUu2FDhveSIIopKOfOLPaBArXiTM+5984P
> JXPJlRfwHc5wzsxw5sz5+e45517OzCyf/maXmZlDJ9fe+waW5eXTJ5bPIQ/PzZw8d/Ikcr
> E27XqZL2vvra+tr6+trfOjl9f2cwdY119eX18/B5u1d87N/OjvEokfre2j/csvq7+t/mLt
> 3fO/+Ld/fHn9vb++fHl9/d2XL//2MjIydTsJ67mTf//OL5+fn1n6B8f5+X5Y2Lp67eI7Pz
> j5ryvPKmeX3j2dOXv2B3/2wxNXf6b+99Wj+2RhedU6Of/czNKfOs6rc9O3oxf/qXpVfXfp
> 4stHLr6xdOLqG9/97pGzf3mt8xdXL35/H7dZev7M8vz8fOP0/PzMM8/rxqtzR48enXKdu7
> h8/NyJmbm/nf/294/PPX/o0LcPHTpz/MTfnD5x6Jm5o3Nzq6urE++CLCyfWQIWll5FKawu
> zy+trh6dm3aVbVVs+R2XgmOra0exTbgDXDB3aH5peRnlsAy2IH47bcMn4tPhNqtz8MQ5fk
> QwMQ9nYOHH9mx4h6Wlpbn5+efm5p6b+daZb6YdP3780LcOweb4TNYwTMMw9MaUK7YeLGIP
> 9uWOqeNpg9+q0cDNuLXRqNOGTj5oNkpGqUlqMznT2U/zfM/j347rOnx1XMd3XaDjl9E9Vs
> exDfYnKiGknp0lpCtYYA6lU6z74XU8E8y02W+OKQbwcGyWsEAKcJJOXukUTCCrzBm/OE7P
> tIl6ZMYgJedY70UuBeAGbk6nWr+yMfnFGCGUIQuMjV0JskDZsa5DSO3ZhIlSMEZkt3cjjz
> 8V2AfO+IOFrOAmUmVjTaGn2/gD/uYOYSAFC2/YYIZJ/5hyOY5b4QnhkxkNGcEHExAxiTGH
> TIxZGUoBpXGflCgBTqQt0E43oZSPOHuqweFMc7OBh8A+iYmN0VCSyLEzbkUpGDbLaLpOsL
> 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
> 
> _______________________________________________
> rrd-users mailing list
> rrd-users at lists.oetiker.ch
> https://lists.oetiker.ch/cgi-bin/listinfo/rrd-users
> 
> ==============================================================================
> The information contained in this email and any attachment is confidential and
> may contain legally privileged or copyright material.   It is intended only for
> the use of the addressee(s).  If you are not the intended recipient of this
> email, you are not permitted to disseminate, distribute or copy this email or
> any attachments.  If you have received this message in error, please notify the
> sender immediately and delete this email from your system.  The ABC does not
> represent or warrant that this transmission is secure or virus free.   Before
> opening any attachment you should check for viruses.  The ABC's liability is
> limited to resupplying any email and attachments
> ==============================================================================
> 



More information about the rrd-users mailing list