1
2
3
4
5
6
7
8
9
10
11
12
13
14 __doc__="""GraphDefinition
15
16 GraphDefinition defines the global options for a graph.
17 """
18
19 import re
20 import sys
21 from sets import Set
22 import string
23
24 from Products.ZenRelations.RelSchema import *
25 from Globals import InitializeClass
26 from AccessControl import ClassSecurityInfo, Permissions
27 from GraphPoint import GraphPoint
28 from ZenModelRM import ZenModelRM
29 from ZenPackable import ZenPackable
30 from OFS.ObjectManager import checkValidId as globalCheckValidId
31 import logging
32 log = logging.getLogger("zen.Device")
33
34
36 ''' This is here so than zope will let us copy/paste/rename
37 graphpoints.
38 '''
39 if REQUEST:
40 REQUEST['message'] = 'That operation is not supported.'
41 self.callZenScreen(REQUEST)
42
44 isFake = True
45 - def __init__(self, name):
47 - def __getattr__(self, name):
49 - def __call__(self, *kw, **args):
51 - def __getitem__(self, key):
59 - def __nonzero__(self):
65
67 '''
68 '''
69
70 meta_type = 'GraphDefinition'
71
72 height = 100
73 width = 500
74 units = ""
75 log = False
76 base = False
77
78 miny = -1
79 maxy = -1
80 custom = ""
81 hasSummary = True
82 sequence = 0
83
84 _properties = (
85 {'id':'height', 'type':'int', 'mode':'w'},
86 {'id':'width', 'type':'int', 'mode':'w'},
87 {'id':'units', 'type':'string', 'mode':'w'},
88 {'id':'log', 'type':'boolean', 'mode':'w'},
89 {'id':'base', 'type':'boolean', 'mode':'w'},
90
91 {'id':'miny', 'type':'int', 'mode':'w'},
92 {'id':'maxy', 'type':'int', 'mode':'w'},
93 {'id':'custom', 'type':'text', 'mode':'w'},
94 {'id':'hasSummary', 'type':'boolean', 'mode':'w'},
95 {'id':'sequence', 'type':'long', 'mode':'w'},
96 )
97
98 _relations = (
99 ("rrdTemplate",
100 ToOne(ToManyCont,"Products.ZenModel.RRDTemplate", "graphDefs")),
101 ('report',
102 ToOne(ToManyCont, 'Products.ZenModel.MultiGraphReport', 'graphDefs')),
103 ('graphPoints',
104 ToManyCont(ToOne, 'Products.ZenModel.GraphPoint', 'graphDef')),
105
106 ('reportClass',
107 ToOne(ToManyCont, 'Products.ZenModel.MultiGraphReportClass', 'graphDefs')),
108 )
109
110
111
112 factory_type_information = (
113 {
114 'immediate_view' : 'editGraphDefinition',
115 'actions' :
116 (
117 { 'id' : 'edit'
118 , 'name' : 'Graph Definition'
119 , 'action' : 'editGraphDefinition'
120 , 'permissions' : ( Permissions.view, )
121 },
122 { 'id' : 'editCustom'
123 , 'name' : 'Graph Custom Definition'
124 , 'action' : 'editCustGraphDefinition'
125 , 'permissions' : ( Permissions.view, )
126 },
127 { 'id' : 'viewCommands'
128 , 'name' : 'Graph Commands'
129 , 'action' : 'viewGraphCommands'
130 , 'permissions' : ( Permissions.view, )
131 },
132 )
133 },
134 )
135
136 security = ClassSecurityInfo()
137
138
139
141 ''' Return ordered list of graph points
142 '''
143 def cmpGraphPoints(a, b):
144 try:
145 a = int(a.sequence)
146 except ValueError:
147 a = sys.maxint
148 try:
149 b = int(b.sequence)
150 except ValueError:
151 b = sys.maxint
152 return cmp(a, b)
153 gps = [gp for gp in self.graphPoints()
154 if includeThresholds or not gp.isThreshold]
155 gps.sort(cmpGraphPoints)
156 return gps
157
158
160 ''' Get ordered list of threshold graph points
161 '''
162 gps = [gp for gp in self.getGraphPoints() if gp.isThreshold]
163 return gps
164
165
173
174
185
186
187
188
189
199
200
202 """Checks a valid id
203 """
204
205
206
207
208 if len(id) > 200:
209 return 'GraphPoint names can not be longer than 200 characters.'
210 allowed = Set(list(string.ascii_letters)
211 + list(string.digits)
212 + ['_'])
213 attempted = Set(list(id))
214 if not attempted.issubset(allowed):
215 return 'Only letters, digits and underscores are allowed' + \
216 ' in GraphPoint names.'
217 return ZenModelRM.checkValidId(self, id, prep_id)
218
219
222
223
225 ''' Return list of graph point ids
226 '''
227 return [gp.id for gp in self.getGraphPoints()]
228
229
231 ''' Used by dialog_addGraphPoint to construct the list of
232 available graphpoint types.
233 '''
234 return (('DefGraphPoint', 'DEF'),
235 ('VdefGraphPoint', 'VDEF'),
236 ('CdefGraphPoint', 'CDEF'),
237 ('PrintGraphPoint', 'PRINT'),
238 ('GprintGraphPoint', 'GPRINT'),
239 ('CommentGraphPoint', 'COMMENT'),
240 ('VruleGraphPoint', 'VRULE'),
241 ('HruleGraphPoint', 'HRULE'),
242 ('LineGraphPoint', 'LINE'),
243 ('AreaGraphPoint', 'AREA'),
244 ('TickGraphPoint', 'TICK'),
245 ('ShiftGraphPoint', 'SHIFT'))
246
247
249 ''' Create the graphpoint with the given id or something similar
250 and add to self.graphPoints
251 '''
252 def getUniqueId(container, base):
253 ids = container.objectIds()
254 new = base
255 i = 2
256 while new in ids:
257 new = '%s%s' % (base, i)
258 i += 1
259 return new
260 newId = getUniqueId(self.graphPoints, newId)
261 gp = cls(newId)
262
263 if gp.isThreshold:
264 gp.sequence = -1
265 else:
266 gp.sequence = len(self.graphPoints())
267
268 if self.report() and hasattr(gp, 'legend'):
269
270
271
272 gp.legend = gp.DEFAULT_MULTIGRAPH_LEGEND
273 self.graphPoints._setObject(gp.id, gp)
274 gp = self.graphPoints._getOb(gp.id)
275 if gp.sequence == -1:
276 self.manage_resequenceGraphPoints()
277 return gp
278
279
291
292
316
317
333
334
350
351
365
366
373
374
376 ''' Return a list of (value, name) tuples for the list of datapoints
377 which the user selects from to create new graphpoints.
378 '''
379 return [(dp.name(), dp.name())
380 for dp in self.rrdTemplate.getRRDDataPoints()]
381
382
384 ''' Return a list of (value, name) tuples for the list of thresholds
385 which the user selects from to create new graphpoints.
386 '''
387 return [(t.id, t.id) for t in self.rrdTemplate.thresholds()]
388
389
390
391
392
393 - def getGraphCmds(self, context, rrdDir, multiid=-1, upToPoint=None,
394 includeSetup=True, includeThresholds=True,
395 prefix='', cmds=None, idxOffset=0):
396 """build the graph opts for a single rrdfile"""
397 from Products.ZenUtils.ZenTales import talesEval
398 if not cmds:
399 cmds = []
400 if includeSetup:
401 cmds += self.graphsetup()
402
403
404
405 if includeThresholds:
406 threshGps = [gp for gp in self.getThresholdGraphPoints()
407 if upToPoint is None or gp.sequence < upToPoint]
408 if threshGps:
409 for index, gp in enumerate(threshGps):
410 cmds = gp.getGraphCmds(cmds, context, rrdDir,
411 self.hasSummary, index+idxOffset,
412 multiid, prefix)
413
414 gpList = [gp for gp in self.getGraphPoints(includeThresholds=False)
415 if upToPoint is None or gp.sequence < upToPoint]
416 for index, gp in enumerate(gpList):
417 cmds = gp.getGraphCmds(cmds, context, rrdDir,
418 self.hasSummary, index+idxOffset,
419 multiid, prefix)
420 if self.custom and includeSetup \
421 and not upToPoint:
422 res = talesEval("string:"+str(self.custom), context)
423 res = [l for l in res.split('\n') if l.strip()]
424 cmds.extend(res)
425
426
427
428 return cmds
429
430
432 ''' Return list of rrd variable names that are defined by DEF, CDEF
433 or VDEF statements in the rrd commands. If upToPoint is not None then
434 only consider statements generated by graphoints where
435 sequence < upToPoint
436 '''
437 cmds = self.getFakeGraphCmds(upToPoint=upToPoint)
438 names = [line[line.find(':')+1:line.find('=')]
439 for line in cmds.split('\n')
440 if line[:line.find(':')] in ('DEF', 'CDEF', 'VDEF')]
441 return names
442
443
452
453
455 """Setup global graph parameters.
456 """
457 gopts = ['-F', '-E']
458 if self.height:
459 gopts.append('--height=%d' % self.height)
460 if self.width:
461 gopts.append('--width=%d' % self.width)
462 if self.log:
463 gopts.append('--logarithmic')
464 if self.maxy > -1:
465 gopts.append('--upper-limit=%d' % self.maxy)
466 gopts.append('--rigid')
467 if self.miny > -1:
468 gopts.append('--lower-limit=%d' % self.miny)
469 gopts.append('--rigid')
470
471
472 gopts.append('--vertical-label=%s' % (self.units or ' '))
473 if self.units == 'percentage':
474 if not self.maxy > -1:
475 gopts.append('--upper-limit=100')
476 if not self.miny > -1:
477 gopts.append('--lower-limit=0')
478 if self.base:
479 gopts.append('--base=1024')
480 gopts = [str(o) for o in gopts]
481 return gopts
482
483
491
492
494 '''
495 Get a list of all unique datapoint names
496 '''
497 from sets import Set
498 dpNames = Set()
499 for t in self.dmd.Devices.getAllRRDTemplates():
500 for ds in t.datasources():
501
502
503 if hasattr(ds, 'datapoints'):
504 for dp in ds.datapoints():
505 dpNames.add(dp.name())
506 if len(dpNames) >= limit:
507 break
508 dpNames = list(dpNames)
509 dpNames.sort()
510 return dpNames
511
512
514 '''
515 Get a list of all unique threshold names
516 '''
517 from sets import Set
518 names = Set()
519 for t in self.dmd.Devices.getAllRRDTemplates():
520 for thresh in t.thresholds():
521 names.add(thresh.id)
522 if len(names) >= limit:
523 break
524 if len(names) >= limit:
525 break
526 names = list(names)
527 names.sort()
528 return names
529
530
531 InitializeClass(GraphDefinition)
532