Package ZenModel :: Module GraphPoint
[hide private]
[frames] | no frames]

Source Code for Module ZenModel.GraphPoint

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  __doc__="""GraphPoint 
 15   
 16  Defines attributes for how a data source will be graphed 
 17  and builds the nessesary rrd commands. 
 18  """ 
 19   
 20  from Globals import InitializeClass 
 21  from AccessControl import ClassSecurityInfo, Permissions 
 22  from Products.ZenModel.ZenossSecurity import * 
 23  from Products.ZenRelations.RelSchema import * 
 24  from ZenModelRM import ZenModelRM 
 25  from ZenPackable import ZenPackable 
 26  from Products.ZenWidgets import messaging 
 27   
28 -def manage_addGraphPoint(context, id, REQUEST = None):
29 ''' This is here so than zope will let us copy/paste/rename 30 graphpoints. 31 ''' 32 gp = GraphPoint(id) 33 context._setObject(gp.id, gp) 34 if REQUEST: 35 return context.callZenScreen(REQUEST)
36 37
38 -class GraphPoint(ZenModelRM, ZenPackable):
39 ''' 40 ''' 41 42 isThreshold = False 43 44 DEFAULT_FORMAT = '%5.2lf%s' 45 DEFAULT_LEGEND = '${graphPoint/id}' 46 DEFAULT_MULTIGRAPH_LEGEND = '${here/name | here/id} ${graphPoint/id}' 47 48 sequence = 0 49 _properties = ( 50 {'id':'sequence', 'type':'long', 'mode':'w'}, 51 ) 52 53 _relations = ZenPackable._relations + ( 54 ("graphDef", ToOne(ToManyCont,"Products.ZenModel.GraphDefinition","graphPoints")), 55 ) 56 57 factory_type_information = ( 58 { 59 'immediate_view' : 'editGraphPoint', 60 'actions' : 61 ( 62 { 'id' : 'edit' 63 , 'name' : 'Graph Point' 64 , 'action' : 'editGraphPoint' 65 , 'permissions' : ( Permissions.view, ) 66 }, 67 ) 68 }, 69 ) 70 71 colors = ( 72 '#00cc00', '#0000ff', '#00ffff', '#ff0000', 73 '#ff9900', '#cc0000', '#0000cc', '#0080c0', 74 '#8080c0', '#ff0080', '#800080', '#0000a0', 75 '#408080', '#808000', '#000000', '#00ff00', 76 '#fb31fb', '#0080ff', '#ff8000', '#800000', 77 ) 78 79 security = ClassSecurityInfo() 80 81 ## Interface 82 83
84 - def breadCrumbs(self, terminator='dmd'):
85 """Return the breadcrumb links for this object add ActionRules list. 86 [('url','id'), ...] 87 """ 88 if self.graphDef.rrdTemplate(): 89 from RRDTemplate import crumbspath 90 crumbs = super(GraphPoint, self).breadCrumbs(terminator) 91 return crumbspath(self.graphDef(), crumbs, -3) 92 return ZenModelRM.breadCrumbs(self, terminator)
93 94 95 security.declareProtected(ZEN_MANAGE_DMD, 'manage_editProperties')
96 - def manage_editProperties(self, REQUEST):
97 ''' 98 Process a save request from a GraphPoint edit screen. Perform 99 validation on fields and either return error message or save 100 results. 101 ''' 102 def IsHex(s): 103 try: 104 _ = long(color, 16) 105 except ValueError: 106 return False 107 return True
108 109 color = REQUEST.get('color', '').strip().lstrip('#').upper() 110 if color: 111 if len(color) in (6, 8) and IsHex(color): 112 REQUEST.form['color'] = color 113 else: 114 messaging.IMessageSender(self).sendToBrowser( 115 'Invalid Color', 116 'Color must be a 6 or 8-digit hexadecimal value.', 117 priority=messaging.WARNING 118 ) 119 return self.callZenScreen(REQUEST) 120 return self.zmanage_editProperties(REQUEST)
121 122
123 - def getDescription(self):
124 ''' Return a description 125 ''' 126 return self.id
127 128
129 - def getTalesContext(self, thing=None, **kw):
130 ''' 131 Standard stuff to add to context for tales expressions 132 ''' 133 context = { 134 'graphDef': self.graphDef(), 135 'graphPoint': self, 136 } 137 if thing: 138 thing.getRRDContextData(context) 139 for key, value in kw.items(): 140 context[key] = value 141 return context
142 143
144 - def talesEval(self, str, context, **kw):
145 ''' 146 return a tales evaluation of str 147 ''' 148 from Products.ZenUtils.ZenTales import talesEvalStr 149 extraContext = self.getTalesContext(thing=context, **kw) 150 try: 151 result = talesEvalStr(str, context, extraContext) 152 except Exception: 153 result = '(Tales expression error)' 154 return result
155 156 157 ## Graphing Support 158
159 - def getColor(self, index):
160 """ 161 Return a string apprpriate for use as the color part of an 162 rrd graph command. The color either comes from the attribute on 163 this object or from an offset into the self.colors list. 164 """ 165 color = None 166 if self.color: 167 color = self.color 168 try: 169 _ = long(color, 16) 170 except ValueError: 171 color = None 172 if not color: 173 index %= len(self.colors) 174 color = self.colors[index] 175 color = '#%s' % color.lstrip('#') 176 if hasattr(self, 'stacked'): 177 # This is setting the alpha channel? 178 # Why is this needed? 179 if not self.stacked and index>0: color += "99" 180 else: color += "ff" 181 return color
182 183
184 - def getThresholdColor(self, index):
185 index %= len(self.colors) 186 color = self.color or self.colors[-1 * (index+1)] 187 color = '#%s' % color.lstrip('#') 188 return color
189 190
191 - def getGraphCmds(self, cmds, context, rrdDir, addSummary, idx, 192 multiid=-1, prefix=''):
193 ''' Build the graphing commands for this graphpoint 194 ''' 195 from Products.ZenUtils.Utils import unused 196 unused(multiid, prefix, rrdDir) 197 return cmds
198 199
200 - def getDsName(self, base, multiid=-1, prefix=''):
201 name = self.addPrefix(prefix, base) 202 if multiid > -1: 203 name = '%s_%s' % (name, multiid) 204 return name
205 206
207 - def addPrefix(self, prefix, base):
208 ''' If not base then return '' 209 elif prefix then return prefix_base 210 else return base 211 The result is rrd scrubbed 212 ''' 213 s = base or '' 214 if s and prefix: 215 s = '_'.join((prefix, base)) 216 s = self.scrubForRRD(s) 217 return s
218 219
220 - def scrubForRRD(self, value, namespace=None):
221 ''' scrub value so it is a valid rrd variable name. If namespace 222 is provided then massage value as needed to avoid name conflicts 223 with items in namespace. 224 ''' 225 import string 226 import itertools 227 def Scrub(c): 228 if c not in string.ascii_letters + string.digits + '_-': 229 c = '_' 230 return c
231 value = ''.join([Scrub(c) for c in value]) 232 if namespace: 233 postfixIter = itertools.count(2) 234 candidate = value 235 while candidate in namespace: 236 candidate = value + str(postfixIter.next()) 237 value = candidate 238 return value 239 240
241 - def escapeForRRD(self, value):
242 ''' 243 Escapes characters like colon ':' for use by RRDTool which would 244 ''' 245 value = value.replace(":", "\:") 246 return value
247 248 249 InitializeClass(GraphPoint) 250