| Trees | Indices | Help |
|
|---|
|
|
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 import copy
15 import re
16 import sre_constants
17 import logging
18 import transaction
19 log = logging.getLogger("zen.Events")
20
21 from Globals import DTMLFile
22 from Globals import InitializeClass
23 from AccessControl import ClassSecurityInfo
24 from AccessControl import Permissions
25 from Acquisition import aq_chain
26 from Products.ZenModel.ZenossSecurity import *
27
28 from Products.ZenRelations.RelSchema import *
29 from Products.ZenModel.ZenModelRM import ZenModelRM
30 from Products.ZenModel.EventView import EventView
31 from Products.ZenModel.ZenPackable import ZenPackable
32 from Products.ZenWidgets import messaging
33 from Products.ZenUtils.Utils import convToUnits, zdecode
34
35
37 """make a device class"""
38 dc = EventClassInst(id)
39 context._setObject(id, dc)
40 if REQUEST is not None:
41 REQUEST['RESPONSE'].redirect(context.absolute_url() + '/manage_main')
42
43
44 addEventClassInst = DTMLFile('dtml/addEventClassInst',globals())
45
46
48
49 transform = ''
50
51 _properties = (
52 {'id':'transform', 'type':'text', 'mode':'w'},
53 )
54
56 """Modify event with values taken from dict Inst.
57 Any non-None property values are applied to the event.
58 """
59 evt._clearClasses = copy.copy(getattr(self, "zEventClearClasses", []))
60 evt._action = getattr(self, "zEventAction", "status")
61 sev = getattr(self, "zEventSeverity", -1)
62 if sev >= 0:
63 if evt.severity > 0:
64 evt.severity = sev
65 updates = {}
66 for name in 'resolution', 'explanation':
67 value = getattr(self, name, None)
68 if value is not None and value != '':
69 updates[name] = value
70 evt.updateFromDict(updates)
71 return evt
72
74 """
75 Apply transforms on an event from the top level of the Event Class Tree
76 down to the actual Event Rules (EventClassInst)
77 """
78 transpath = self._eventClassPath()
79 variables_and_funcs = {
80 'evt':evt, 'device':device, 'dev':device,
81 'convToUnits':convToUnits, 'zdecode':zdecode,
82 'txnCommit':transaction.commit
83 }
84 for eventclass in transpath:
85 if not eventclass.transform: continue
86 try:
87 log.debug('Applying transform at %s',
88 eventclass.getPrimaryDmdId())
89 exec(eventclass.transform, variables_and_funcs)
90 except Exception, ex:
91 log.exception(
92 "Error processing transform on Event Class %s",
93 eventclass.getPrimaryId())
94 return variables_and_funcs['evt']
95
96
98 """
99 Make a string that brings together all the transforms inherited from the
100 base EventClass to self.
101 """
102 transpath = self._eventClassPath()
103 transtext = []
104 for obj in transpath:
105 if not obj.transform: continue
106 if obj.transform == self.transform: break
107 transtext.append("""<a href='%s/editEventClassTransform'>%s<a>
108 """ % (obj.getPrimaryUrlPath(), obj.getPrimaryDmdId()))
109 transtext.append("<pre>%s</pre>" % obj.transform)
110 return "\n".join(transtext)
111
112
114 """Test our transform by compiling it.
115 """
116 try:
117 if self.transform:
118 compile(self.transform, "<string>", "exec")
119 except:
120 return "color:#FF0000;"
121
122
124 """
125 Return the path to our current EventClassInst from the top level
126 EventClass down. We use this to process and display the heirarchy of
127 event transforms.
128 """
129 transpath = []
130 for obj in aq_chain(self):
131 # skip over relationships in the aq_chain
132 if not isinstance(obj, EventClassPropertyMixin): continue
133 if obj.id == 'dmd': break
134 transpath.append(obj)
135 transpath.reverse()
136 return transpath
137
138 # Why is this a subclass of EventView?
139
142 """
143 EventClassInst.
144 """
145
146 event_key = meta_type = "EventClassInst"
147
148 default_catalog = "eventClassSearch"
149
150 actions = ("status", "history", "heartbeat", "drop")
151
152 _properties = EventClassPropertyMixin._properties + (
153 {'id':'eventClassKey', 'type':'string', 'mode':'w'},
154 {'id':'sequence', 'type':'int', 'mode':'w'},
155 {'id':'rule', 'type':'string', 'mode':'w'},
156 {'id':'regex', 'type':'string', 'mode':'w'},
157 {'id':'example', 'type':'string', 'mode':'w'},
158 {'id':'explanation', 'type':'text', 'mode':'w'},
159 {'id':'resolution', 'type':'text', 'mode':'w'},
160 )
161
162
163 _relations = ZenPackable._relations + (
164 ("eventClass", ToOne(ToManyCont,"Products.ZenEvents.EventClass","instances")),
165 )
166
167
168 # Screen action bindings (and tab definitions)
169 factory_type_information = (
170 {
171 'id' : 'EventClassInst',
172 'meta_type' : 'EventClassInst',
173 'description' : """Base class for all devices""",
174 'icon' : 'EventClassInst.gif',
175 'product' : 'ZenEvents',
176 'factory' : 'manage_addEventClassInst',
177 'immediate_view' : 'eventClassInstStatus',
178 'actions' :
179 (
180 { 'id' : 'status'
181 , 'name' : 'Status'
182 , 'action' : 'eventClassInstStatus'
183 , 'permissions' : (Permissions.view, )
184 },
185 { 'id' : 'edit'
186 , 'name' : 'Edit'
187 , 'action' : 'eventClassInstEdit'
188 , 'permissions' : ("Manage DMD", )
189 },
190 { 'id' : 'sequence'
191 , 'name' : 'Sequence'
192 , 'action' : 'eventClassInstSequence'
193 , 'permissions' : (Permissions.view,)
194 },
195 { 'id' : 'config'
196 , 'name' : 'zProperties'
197 , 'action' : 'zPropertyEdit'
198 , 'permissions' : ("Manage DMD",)
199 },
200 { 'id' : 'events'
201 , 'name' : 'Events'
202 , 'action' : 'viewEvents'
203 , 'permissions' : (Permissions.view, )
204 },
205 # { 'id' : 'historyEvents'
206 # , 'name' : 'History'
207 # , 'action' : 'viewHistoryEvents'
208 # , 'permissions' : (Permissions.view, )
209 # },
210 { 'id' : 'viewHistory'
211 , 'name' : 'Modifications'
212 , 'action' : 'viewHistory'
213 , 'permissions' : (ZEN_VIEW_MODIFICATIONS,)
214 },
215 )
216 },
217 )
218
219 security = ClassSecurityInfo()
220
222 ZenModelRM.__init__(self, id)
223 self.eventClassKey = id
224 self.sequence = None
225 self.rule = ""
226 self.regex = ""
227 self.example = ""
228 self.explanation = ""
229 self.resolution = ""
230
231
233 """Return the status number for this device of class statClass.
234 """
235 return self.getEventManager().getStatusME(self,
236 statusclass=self.getEventClass(),
237 **kwargs)
238
239
243
248
249
251 """Return the dmd key of this mapping ie: /App/Start/zentinel
252 """
253 return self.getOrganizerName() + "/" + self.id
254
255
257 """
258 Apply the event dict regex to extract additional values from the event.
259 """
260 if self.regex:
261 m = re.search(self.regex, evt.message)
262 if m: evt.updateFromDict(m.groupdict())
263 return evt
264
265
267 """Modify event with values taken from dict Inst.
268 Any non-None property values are applied to the event.
269 """
270 evt.eventClass = self.getEventClass()
271 evt.eventClassMapping = '%s/%s' % (self.getEventClass(), self.id)
272 return EventClassPropertyMixin.applyValues(self, evt)
273
275 """Return the rule if it exists else return the regex.
276 limit limits the number of characters returned.
277 """
278 value = self.rule and self.rule or self.regex
279 if not value and self.example:
280 value = self.example
281 if limit: value = value[:limit]
282 return value
283
284
286 """
287 Match an event message against our regex.
288
289 @parameter evt: event to match in our mapping
290 @type evt: dictionary
291 @parameter device: device
292 @type device: DMD object
293 @return: boolean
294 @rtype: boolean
295 """
296 value = False
297 log.debug("match on:%s", self.getPrimaryDmdId())
298 if self.rule:
299 try:
300 log.debug("eval rule:%s", self.rule)
301 value = eval(self.rule, {'evt':evt, 'dev':device, 'device': device})
302 except Exception, e:
303 logging.warn("EventClassInst: %s rule failure: %s",
304 self.getDmdKey(), e)
305 else:
306 try:
307 log.debug("regex='%s' message='%s'", self.regex, evt.message)
308 value = re.search(self.regex, evt.message, re.I)
309 except sre_constants.error: pass
310 return value
311
312
314 """Test our regex using the example event string.
315 """
316 if self.example:
317 try:
318 value = re.search(self.regex, self.example, re.I)
319 if not value: return "color:#FF0000;"
320 except sre_constants.error:
321 return "color:#FF0000;"
322
323
325 """Test our rule by compiling it.
326 """
327 try:
328 if self.rule:
329 compile(self.rule, "<string>", "eval")
330 except:
331 return "color:#FF0000;"
332
333
335 """Return a list of all mappings with the same eventClassKey.
336 """
337 return self.eventClass().find(self.eventClassKey)
338
339
341 """
342 Device only propagates afterAdd if it is the added object.
343 """
344 self.index_object()
345 ZenModelRM.manage_afterAdd(self, item, container)
346
347
349 """Not really sure when this is called."""
350 ZenModelRM.manage_afterClone(self, item)
351 self.index_object()
352
353
355 """
356 Device only propagates beforeDelete if we are being deleted or copied.
357 Moving and renaming don't propagate.
358 """
359 ZenModelRM.manage_beforeDelete(self, item, container)
360 self.unindex_object()
361
362
363 security.declareProtected('Manage DMD', 'manage_resequence')
365 """Reorder the sequence of eventClassMappings with the same key.
366 """
367 # first pass set new sequence
368 for i, map in enumerate(self.sameKey()):
369 map.sequence = seqmap[i]
370 # second pass take out any holes
371 for i, map in enumerate(self.sameKey()):
372 map.sequence = i
373 if REQUEST:
374 return self.callZenScreen(REQUEST)
375
376
377 security.declareProtected('Manage DMD', 'manage_editEventClassInst')
378 - def manage_editEventClassInst(self, name="", eventClassKey='',
379 regex='', rule='', example='',
380 transform='',
381 explanation='', resolution='', REQUEST=None):
382 """Edit a EventClassInst from a web page.
383 """
384 redirect = self.rename(name)
385 if eventClassKey and self.eventClassKey != eventClassKey:
386 self.unindex_object()
387 self.sequence = self.eventClass().nextSequenceNumber(eventClassKey)
388 self.eventClassKey = eventClassKey
389 self.index_object()
390 self.regex = regex
391 self.rule = rule
392 self.example = example
393 self.transform = transform
394 self.explanation = explanation
395 self.resolution = resolution
396 if REQUEST:
397 from Products.ZenUtils.Time import SaveMessage
398 messaging.IMessageSender(self).sendToBrowser(
399 'Saved', SaveMessage())
400 return self.callZenScreen(REQUEST, redirect)
401
402
403 InitializeClass(EventClassInst)
404
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0beta1 on Thu May 7 11:46:36 2009 | http://epydoc.sourceforge.net |