1
2
3
4
5
6
7
8
9
10
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 zope.interface import implements
27
28 from Products.ZenModel.interfaces import IIndexed
29 from Products.ZenModel.ZenossSecurity import *
30 from Products.ZenRelations.RelSchema import *
31 from Products.ZenModel.ZenModelRM import ZenModelRM
32 from Products.ZenModel.EventView import EventView
33 from Products.ZenModel.ZenPackable import ZenPackable
34 from Products.ZenWidgets import messaging
35 from Products.ZenUtils.Utils import convToUnits, zdecode
36
37
44
45
46 addEventClassInst = DTMLFile('dtml/addEventClassInst',globals())
47
48
50
51 transform = ''
52
53 _properties = (
54 {'id':'transform', 'type':'text', 'mode':'w'},
55 )
56
58 """Modify event with values taken from dict Inst.
59 Any non-None property values are applied to the event.
60 """
61 evt._clearClasses = copy.copy(getattr(self, "zEventClearClasses", []))
62 evt._action = getattr(self, "zEventAction", "status")
63 sev = getattr(self, "zEventSeverity", -1)
64 if sev >= 0:
65 if evt.severity > 0:
66 evt.severity = sev
67 log.debug("Per transform/mapping, using severity %s, action '%s' and clear classes %s",
68 evt.severity, evt._action, evt._clearClasses)
69 updates = {}
70 for name in 'resolution', 'explanation':
71 value = getattr(self, name, None)
72 if value is not None and value != '':
73 updates[name] = value
74 if updates:
75 log.debug("Adding fields from transform/mapping: %s", updates)
76 evt.updateFromDict(updates)
77 return evt
78
104
105
120
121
130
131
133 """
134 Return the path to our current EventClassInst from the top level
135 EventClass down. We use this to process and display the heirarchy of
136 event transforms.
137 """
138 transpath = []
139 for obj in aq_chain(self):
140
141 if not isinstance(obj, EventClassPropertyMixin): continue
142 if obj.id == 'dmd': break
143 transpath.append(obj)
144 transpath.reverse()
145 return transpath
146
147
148
149 -class EventClassInst(EventClassPropertyMixin, ZenModelRM, EventView,
150 ZenPackable):
151 """
152 EventClassInst.
153 """
154 implements(IIndexed)
155 event_key = meta_type = "EventClassInst"
156
157 default_catalog = "eventClassSearch"
158
159 actions = ("status", "history", "heartbeat", "drop")
160
161 _properties = EventClassPropertyMixin._properties + (
162 {'id':'eventClassKey', 'type':'string', 'mode':'w'},
163 {'id':'sequence', 'type':'int', 'mode':'w'},
164 {'id':'rule', 'type':'string', 'mode':'w'},
165 {'id':'regex', 'type':'string', 'mode':'w'},
166 {'id':'example', 'type':'string', 'mode':'w'},
167 {'id':'explanation', 'type':'text', 'mode':'w'},
168 {'id':'resolution', 'type':'text', 'mode':'w'},
169 )
170
171
172 _relations = ZenPackable._relations + (
173 ("eventClass", ToOne(ToManyCont,"Products.ZenEvents.EventClass","instances")),
174 )
175
176
177
178 factory_type_information = (
179 {
180 'id' : 'EventClassInst',
181 'meta_type' : 'EventClassInst',
182 'description' : """Base class for all devices""",
183 'icon' : 'EventClassInst.gif',
184 'product' : 'ZenEvents',
185 'factory' : 'manage_addEventClassInst',
186 'immediate_view' : 'eventClassInstStatus',
187 'actions' :
188 (
189 { 'id' : 'status'
190 , 'name' : 'Status'
191 , 'action' : 'eventClassInstStatus'
192 , 'permissions' : (Permissions.view, )
193 },
194 { 'id' : 'edit'
195 , 'name' : 'Edit'
196 , 'action' : 'eventClassInstEdit'
197 , 'permissions' : ("Manage DMD", )
198 },
199 { 'id' : 'sequence'
200 , 'name' : 'Sequence'
201 , 'action' : 'eventClassInstSequence'
202 , 'permissions' : (Permissions.view,)
203 },
204 { 'id' : 'config'
205 , 'name' : 'zProperties'
206 , 'action' : 'zPropertyEdit'
207 , 'permissions' : ("Manage DMD",)
208 },
209 { 'id' : 'events'
210 , 'name' : 'Events'
211 , 'action' : 'viewEvents'
212 , 'permissions' : (Permissions.view, )
213 },
214
215
216
217
218
219 { 'id' : 'viewHistory'
220 , 'name' : 'Modifications'
221 , 'action' : 'viewHistory'
222 , 'permissions' : (ZEN_VIEW_MODIFICATIONS,)
223 },
224 )
225 },
226 )
227
228 security = ClassSecurityInfo()
229
231 ZenModelRM.__init__(self, id)
232 self.eventClassKey = id
233 self.sequence = None
234 self.rule = ""
235 self.regex = ""
236 self.example = ""
237 self.explanation = ""
238 self.resolution = ""
239
240
247
248
250 """Return the full EventClass of this EventClassInst."""
251 return self.getOrganizerName()
252
257
258
260 """Return the dmd key of this mapping ie: /App/Start/zentinel
261 """
262 return self.getOrganizerName() + "/" + self.id
263
264
266 """
267 Apply the event dict regex to extract additional values from the event.
268 """
269 if self.regex:
270 m = re.search(self.regex, evt.message)
271 if m: evt.updateFromDict(m.groupdict())
272 return evt
273
274
282
284 """Return the rule if it exists else return the regex.
285 limit limits the number of characters returned.
286 """
287 value = self.rule and self.rule or self.regex
288 if not value and self.example:
289 value = self.example
290 if limit: value = value[:limit]
291 return value
292
293
294 - def match(self, evt, device):
295 """
296 Match an event message against our regex.
297
298 @parameter evt: event to match in our mapping
299 @type evt: dictionary
300 @parameter device: device
301 @type device: DMD object
302 @return: boolean
303 @rtype: boolean
304 """
305 value = False
306 log.debug("match on:%s", self.getPrimaryDmdId())
307 if self.rule:
308 try:
309 log.debug("eval rule:%s", self.rule)
310 value = eval(self.rule, {'evt':evt, 'dev':device, 'device': device})
311 except Exception, e:
312 logging.warn("EventClassInst: %s rule failure: %s",
313 self.getDmdKey(), e)
314 else:
315 try:
316 log.debug("regex='%s' message='%s'", self.regex, evt.message)
317 value = re.search(self.regex, evt.message, re.I)
318 except sre_constants.error: pass
319 return value
320
321
323 """Test our regex using the example event string.
324 """
325 if self.example:
326 try:
327 value = re.search(self.regex, self.example, re.I)
328 if not value: return "color:#FF0000;"
329 except sre_constants.error:
330 return "color:#FF0000;"
331
332
334 """Test our rule by compiling it.
335 """
336 try:
337 if self.rule:
338 compile(self.rule, "<string>", "eval")
339 except:
340 return "color:#FF0000;"
341
342
344 """Return a list of all mappings with the same eventClassKey.
345 """
346 return [ i for i in self.eventClass().find(self.eventClassKey) \
347 if i.eventClassKey == self.eventClassKey ]
348
349
350 security.declareProtected('Manage DMD', 'manage_resequence')
362
363
364 security.declareProtected('Manage DMD', 'manage_editEventClassInst')
365 - def manage_editEventClassInst(self, name="", eventClassKey='',
366 regex='', rule='', example='',
367 transform='',
368 explanation='', resolution='', REQUEST=None):
388
389
390 InitializeClass(EventClassInst)
391