Package Products :: Package ZenModel :: Module RRDGraph |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenModel.RRDGraph

      1  ##############################################################################
      2  #
      3  # Copyright (C) Zenoss, Inc. 2007, all rights reserved.
      4  #
      5  # This content is made available according to terms specified in
      6  # License.zenoss under the directory where your Zenoss product is installed.
      7  #
      8  ##############################################################################
      9
     10
     11  __doc__="""RRDGraph
     12
     13  RRDGraph defines the global options for an rrdtool graph.
     14  """
     15
     16  ###########################################################################
     17  #
     18  # RRDGraph is deprecated.  GraphDefinition is now used in its place.
     19  # RRDGraph.py can be removed from zenoss post 2.1
     20  #
     21  ###########################################################################
     22
     23  import os
     24  import re
     25
     26  from Globals import DTMLFile
     27  from Globals import InitializeClass
     28  from AccessControl import ClassSecurityInfo, Permissions
     29
     30  from Products.ZenRelations.RelSchema import *
     31  from Products.ZenUtils.ZenTales import talesEval
     32
     33  from ZenModelRM import ZenModelRM
     34
     35 -def manage_addRRDGraph(context, id, REQUEST = None):
     36      """make a RRDGraph"""
     37      graph = RRDGraph(id)
     38      context._setObject(graph.id, graph)
     39      if REQUEST is not None:
     40          REQUEST['RESPONSE'].redirect(context.absolute_url()+'/manage_main')
     41
     42
     43  addRRDGraph = DTMLFile('dtml/addRRDGraph',globals())
     44
     45
     46 -class RRDGraph(ZenModelRM):
     47
     48      meta_type = 'RRDGraph'
     49
     50      security = ClassSecurityInfo()
     51
     52      dsnames = []
     53      sequence = 0
     54      height = 100
     55      width = 500
     56      threshmap = []
     57      units = ""
     58      log = False
     59      linewidth = 1
     60      base = False
     61      stacked = False
     62      summary = True
     63      miny = -1
     64      maxy = -1
     65      custom = ""
     66      hasSummary = True
     67
     68
     69      _properties = (
     70          {'id':'dsnames', 'type':'lines', 'mode':'w'},
     71          {'id':'sequence', 'type':'int', 'mode':'w'},
     72          {'id':'height', 'type':'int', 'mode':'w'},
     73          {'id':'width', 'type':'int', 'mode':'w'},
     74          {'id':'units', 'type':'string', 'mode':'w'},
     75          {'id':'linewidth', 'type':'int', 'mode':'w'},
     76          {'id':'log', 'type':'boolean', 'mode':'w'},
     77          {'id':'base', 'type':'boolean', 'mode':'w'},
     78          {'id':'stacked', 'type':'boolean', 'mode':'w'},
     79          {'id':'summary', 'type':'boolean', 'mode':'w'},
     80          {'id':'miny', 'type':'int', 'mode':'w'},
     81          {'id':'maxy', 'type':'int', 'mode':'w'},
     82          {'id':'colors', 'type':'lines', 'mode':'w'},
     83          {'id':'custom', 'type':'text', 'mode':'w'},
     84          {'id':'hasSummary', 'type':'boolean', 'mode':'w'},
     85          )
     86
     87      _relations =  (
     88          ("rrdTemplate", ToOne(ToManyCont,"Products.ZenModel.RRDTemplate", "graphs")),
     89          )
     90
     91      colors = (
     92          '#00cc00', '#0000ff', '#00ffff', '#ff0000',
     93          '#ff9900', '#cc0000', '#0000cc', '#0080c0',
     94          '#8080c0', '#ff0080', '#800080', '#0000a0',
     95          '#408080', '#808000', '#000000', '#00ff00',
     96          '#fb31fb', '#0080ff', '#ff8000', '#800000',
     97          )
     98
     99      # Screen action bindings (and tab definitions)
    100      factory_type_information = (
    101      {
    102          'immediate_view' : 'editRRDGraph',
    103          'actions'        :
    104          (
    105              { 'id'            : 'edit'
    106              , 'name'          : 'Graph'
    107              , 'action'        : 'editRRDGraph'
    108              , 'permissions'   : ( Permissions.view, )
    109              },
    110          )
    111      },
    112      )
    113
    114 -    def breadCrumbs(self, terminator='dmd'):
    115          """Return the breadcrumb links for this object add ActionRules list.
    116          [('url','id'), ...]
    117          """
    118          from RRDTemplate import crumbspath
    119          crumbs = super(RRDGraph, self).breadCrumbs(terminator)
    120          return crumbspath(self.rrdTemplate(), crumbs, -2)
    121
    122
    123 -    def getGraphCmds(self, context, rrdfile, template):
    124          """build the graph opts for a single rrdfile"""
    125          cmds = self.graphsetup()
    126          if self.custom:
    127              cmds = self.buildCustomDS(cmds, rrdfile, template)
    128              res = talesEval("string:"+self.custom, context)
    129              cmds.extend(res.split("\n"))
    130              if self.hasSummary:
    131                   cmds = self.addSummary(cmds)
    132          else:
    133              cmds = self.buildDS(cmds, rrdfile, template, self.summary)
    134          cmds = self.thresholds(cmds, context, template)
    135          return cmds
    136
    137
    138 -    def graphsetup(self):
    139          """Setup global graph parameters.
    140          """
    141          gopts = ['-F', '-E']
    142          if self.height:
    143              gopts.append('--height=%d' % self.height)
    144          if self.width:
    145              gopts.append('--width=%d' % self.width)
    146          if self.log:
    147              gopts.append('--logarithmic')
    148          if self.maxy > -1:
    149              gopts.append('--upper-limit=%d' % self.maxy)
    150              gopts.append('--rigid')
    151          if self.miny > -1:
    152              gopts.append('--lower-limit=%d' % self.miny)
    153              gopts.append('--rigid')
    154          if self.units:
    155              gopts.append('--vertical-label=%s' % self.units)
    156              if self.units == 'percentage':
    157                  if not self.maxy > -1:
    158                      gopts.append('--upper-limit=100')
    159                  if not self.miny > -1:
    160                      gopts.append('--lower-limit=0')
    161          if self.base:
    162              gopts.append('--base=1024')
    163          return gopts
    164
    165
    166 -    def buildCustomDS(self, gopts, rrdfile, template):
    167          """Build a list of DEF statements for the dsnames in this graph.
    168          Their variable name will be dsname.  These can then be used in a
    169          custom statement.
    170          """
    171          for dsname in self.dsnames:
    172              dp = template.getRRDDataPoint(dsname)
    173              if dp is None: continue
    174              myfile = os.path.join(rrdfile, dp.name()) + ".rrd"
    175              gopts.append('DEF:%s=%s:ds0:AVERAGE' % (dp.name(), myfile))
    176          return gopts
    177
    178
    179 -    def buildDS(self, gopts, rrdfile, template, summary,multiid=-1):
    180          """Add commands to draw data sources in this graph.
    181          """
    182          for dsindex, dsname in enumerate(self.dsnames):
    183              dp = template.getRRDDataPoint(dsname)
    184              dp.setIndex(dsindex)
    185              defcolor = self.colors[dsindex]
    186              deftype = self.gettype(dsindex)
    187              gopts += dp.graphOpts(rrdfile, defcolor, deftype, summary, multiid)
    188          return gopts
    189
    190 -    def thresholds(self, gopts, context, template):
    191          """Add the hrule commands for any thresholds in this graph.
    192          """
    193          self._v_threshidx = len(self.colors)
    194          threshs = []
    195          for thresh in template.thresholds():
    196              if not thresh.canGraph(self): continue
    197              for dsname in thresh.dsnames:
    198                  if dsname in self.dsnames:
    199                      threshs.append(thresh)
    200                      break
    201          if threshs: gopts.append("COMMENT:Data Thresholds\j")
    202          for i, thresh in enumerate(threshs):
    203              t = thresh.createThresholdInstance(context)
    204              color = self.getthreshcolor()
    205              gopts = t.getGraphElements(template, context, gopts, 'thresh%d' %
    206                      i, color)
    207          import logging
    208          log = logging.getLogger("debug")
    209          log.error('%r' % gopts)
    210          return gopts
    211
    212
    213      gelement = re.compile("^LINE|^AREA|^STACK", re.I).search
    214 -    def addSummary(self, gopts):
    215          """Add summary labels for all graphed elements in gopts.
    216          """
    217          vars = [o.split(":",2)[1].split("#")[0] for o in gopts if self.gelement(o)]
    218
    219          pad = max([len(v) for v in vars] + [0])
    220          for var in vars:
    221              gopts = self.dataSourceSum(gopts, var, pad=pad)
    222          return gopts
    223
    224
    225 -    def dataSourceSum(self, gopts, src, pad=0, format="%0.2lf%s", ongraph=1):
    226          """Add the standard summary opts to a graph for variable src.
    227          VDEF:src_last=src,LAST
    228          GPRINT:src_last:cur\:%0.2lf%s
    229          VDEF:src_avg=src,AVERAGE
    230          GPRINT:src_avg:avg\:%0.2lf%s
    231          VDEF:src_max=src,MAXIMUM
    232          GPRINT:src_max:max\:%0.2lf%s\j
    233          """
    234          from Products.ZenUtils.Utils import unused
    235          unused(pad)
    236          funcs = (("cur\:", "LAST"), ("avg\:", "AVERAGE"), ("max\:", "MAXIMUM"))
    237          for tag, func in funcs:
    238              label = "%s%s" % (tag, format)
    239              #if pad: label = label.ljust(pad)
    240              vdef = "%s_%s" % (src,func.lower())
    241              gopts.append("VDEF:%s=%s,%s" % (vdef,src,func))
    242              opt = ongraph and "GPRINT" or "PRINT"
    243              gopts.append("%s:%s:%s" % (opt, vdef, label))
    244          gopts[-1] += "\j"
    245          return gopts
    246
    247
    248 -    def getthreshcolor(self):
    249          """get a threshold color by working backwards down the color list"""
    250          self._v_threshidx -= 1
    251          a= self.colors[self._v_threshidx]
    252          return a
    253
    254
    255 -    def gettype(self, idx):
    256          """Return the default graph type for a data source
    257          first is area rest are lines
    258          """
    259          if idx == 0:
    260              return "AREA"
    261          elif self.stacked:
    262              return "STACK"
    263          else:
    264              return "LINE%d" % self.linewidth
    265
    266  InitializeClass(RRDGraph)
    267