1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 __doc__ = """zeneventlog
17 Connect using WMI to gather the Windows Event Log and create
18 Zenoss events.
19 """
20
21 import Globals
22 from Products.ZenWin.Watcher import Watcher
23 from Products.ZenWin.WinCollector import WinCollector
24 from Products.ZenUtils.Driver import drive
25 from Products.ZenUtils.Timeout import timeout
26 from Products.ZenEvents.ZenEventClasses import Error, Warning, Info, \
27 Debug
28 from pysamba.library import WError
29
30 from twisted.python import failure
31
32
34 """
35 Connect using WMI to gather the Windows Event Log and create
36 Zenoss events.
37 """
38 name = agent = 'zeneventlog'
39 whatIDo = 'read the Windows event log'
40 eventlogCycleInterval = 5 * 60
41 attributes = WinCollector.attributes + ('eventlogCycleInterval', )
42 deviceAttributes = WinCollector.deviceAttributes + (
43 'zWinEventlog', 'zWinEventlogMinSeverity')
44 events = 0
45
47 """
48 Generator function to return the list of devices to gather
49 Event log information.
50
51 @param driver: driver
52 @type driver: driver object
53 @return: objects
54 @rtype: object
55 """
56 yield self.configService().callRemote('getDeviceListByMonitor',
57 self.options.monitor)
58 yield self.configService().callRemote('getDeviceConfigForEventlog',
59 driver.next())
60 self.updateDevices(driver.next())
61
63 """
64 Scan a single device.
65
66 @param device: device to interrogate
67 @type device: device object
68 @param timeoutSecs: timeoutSecs
69 @type timeoutSecs: int
70 @return: objects
71 @rtype: objects
72 """
73 self.log.debug('Polling %s' % device.id)
74 wql = "SELECT * FROM __InstanceCreationEvent where TargetInstance ISA 'Win32_NTLogEvent' and TargetInstance.EventType <= %d"\
75 % device.zWinEventlogMinSeverity
76
77
78 def cleanup(result=None):
79 """
80 Set a device to be down on failure conditions
81 """
82 if isinstance(result, failure.Failure):
83 self.deviceDown(device, result.getErrorMessage())
84
85 def inner(driver):
86 """
87 inner
88
89 @param driver: driver
90 @type driver: string
91 @return: objects
92 @rtype: objects
93 """
94 try:
95 self.niceDoggie(self.cycleInterval())
96 w = self.watchers.get(device.id, None)
97 if not w:
98 self.log.debug('Creating watcher of %s', device.id)
99 w = Watcher(device, wql)
100 self.log.info('Connecting to %s', device.id)
101 yield w.connect()
102 driver.next()
103 self.log.info('Connected to %s', device.id)
104 self.watchers[device.id] = w
105
106 while 1:
107 queryTimeout = self.wmiqueryTimeout
108 if hasattr( self.options, "queryTimeout") and \
109 self.options.queryTimeout is not None:
110 queryTimeout = int(self.options.queryTimeout)
111 yield w.getEvents(queryTimeout)
112 events = driver.next()
113 self.log.debug('Got %d events', len(events))
114 if not events:
115 break
116 for lrec in events:
117 self.events += 1
118 self.sendEvent(self.makeEvent(device.id, lrec))
119 self.deviceUp(device)
120
121 except WError, ex:
122 if ex.werror != 0x000006be:
123
124 raise
125 self.log.info('%s: Ignoring event %s and restarting connection',
126 device.id, ex)
127 cleanup()
128 except Exception, ex:
129 self.log.exception('Exception getting windows events: %s', ex)
130 raise
131
132 d = timeout(drive(inner), timeoutSecs)
133 d.addErrback(cleanup)
134 return d
135
137 """
138 Kick off the main loop of collecting data
139
140 @param devices: devices
141 @type devices: string
142 @param timeoutSecs: timeoutSecs
143 @type timeoutSecs: string
144 @return: defered
145 @rtype: Twisted defered
146 """
147 def postStats(result):
148 """
149 Twisted callback to report evnets
150
151 @param result: result of operation
152 @type result: string
153 @return: result
154 @rtype: string
155 """
156 self.sendEvents(self.rrdStats.counter('events',
157 self.cycleInterval(), self.events))
158 return result
159
160 d = WinCollector.processLoop(self, devices, timeoutSecs)
161 d.addBoth(postStats)
162 return d
163
165 """
166 Put event in the queue to be sent to the ZenEventManager.
167
168 @param name: name of the device
169 @type name: string
170 @param lrec: log record
171 @type lrec: log record object
172 @return: dictionary with event keys and values
173 @rtype: dictionary
174 """
175 lrec = lrec.targetinstance
176 evtkey = '%s_%s' % (lrec.sourcename, lrec.eventcode)
177 sev = Debug
178 if lrec.eventtype == 1:
179 sev = Error
180 elif lrec.eventtype == 2:
181 sev = Warning
182 elif lrec.eventtype in (3, 4, 5):
183 sev = Info
184
185 self.log.debug( "---- log record info --------------" )
186 for item in dir(lrec):
187 if item[0] == '_':
188 continue
189 self.log.info("%s = %s" % (item, getattr(lrec, item, '')))
190 self.log.debug( "---- log record info --------------" )
191
192 ts= lrec.timegenerated
193 try:
194 date_ts = '/'.join( [ ts[0:4], ts[4:6], ts[6:8] ])
195 time_ts = ':'.join( [ts[8:10], ts[10:12], ts[12:14] ])
196 ts = date_ts + ' ' + time_ts
197 except:
198 pass
199
200 evt = dict(
201 device=name,
202 eventClassKey=evtkey,
203 eventGroup=lrec.logfile,
204 component=lrec.sourcename,
205 ntevid=lrec.eventcode,
206 summary=str(lrec.message).strip(),
207 agent='zeneventlog',
208 severity=sev,
209 monitor=self.options.monitor,
210 user=lrec.user,
211 categorystring=lrec.categorystring,
212 originaltime=ts,
213 computername=lrec.computername,
214 eventidentifier=lrec.eventidentifier,
215 )
216 self.log.debug("Device:%s msg:'%s'", name, lrec.message)
217 return evt
218
220 """
221 Return the length of the cycleInterval
222
223 @return: number of seconds to repeat a collection cycle
224 @rtype: int
225 """
226 return self.eventlogCycleInterval
227
228
229 if __name__ == '__main__':
230 zw = zeneventlog()
231 zw.run()
232