1) Sequence to read the most recent event record
#set flags
flags = win32evtlog.EVENTLOG_FORWARDS_READ|win32evtlog.EVENTLOG_SEEK_READ
#get the total number of records in the log
totalNumOfRecords = win32evtlog.GetNumberOfEventLogRecords(hand)
# read the event log
events = win32evtlog.ReadEventLog(hand, flags,totalNumOfRecords)
2) Sequence to read n most recent event records
#set flags
flags = win32evtlog.EVENTLOG_FORWARDS_READ|win32evtlog.EVENTLOG_SEEK_READ
#get the total number of records in the log
totalNumOfRecords = win32evtlog.GetNumberOfEventLogRecords(hand)
# read the event log
events = win32evtlog.ReadEventLog(hand, flags,(totalNumOfRecords - n))
Note that the records will be populated in the 'events' list in chronological order (i.e. oldest first)
While reading windows logs it is important to correctly visualize the arrangment of records in the internal data structures. In the list of records, the newest one is at the last index. The last index in this case is same as the total number of records in the log. That is the reason we're passing 'totalNumOfRecords' as offset to ReadEventLog function in the sequence 1.
The complete program for logging new event records as they occur in "system" log is listed below
from win32event import *
import threading
#to create your own thread,
# 1. define a new subclass of Thread class.
# 2. implement the thread functionality in run method
# 3. Create a thread object of subclass defined in step 1
# 4. start the thread with start() method
class evThread(threading.Thread):
def __init__(self, server, logtype):
threading.Thread.__init__(self)
self.server = server
self.logtype = logtype
def run(self):
self.hand = win32evtlog.OpenEventLog(self.server,self.logtype)
flags = win32evtlog.EVENTLOG_FORWARDS_READ|win32evtlog.EVENTLOG_SEEK_READ
prevNumOfRecs = win32evtlog.GetNumberOfEventLogRecords(self.hand)
evnthndl = CreateEvent(None, True, False, None)
win32evtlog.NotifyChangeEventLog(self.hand, evnthndl)
logfile = open("C:\Work\MyWork\Python\Programs\log.txt", "w")
while True:
print 'hi'
evntsgnld = WaitForSingleObject(evnthndl, 10000)
if evntsgnld == WAIT_OBJECT_0:
print 'New event'
numOfRec = win32evtlog.GetNumberOfEventLogRecords(self.hand)
NumOfNewRecs = numOfRec - prevNumOfRecs
offset = numOfRec - NumOfNewRecs
events = win32evtlog.ReadEventLog(self.hand, flags, offset)
for event in events:
print >> logfile, 'Event Category:', event.EventCategory
print >> logfile, 'Time Generated:', event.TimeGenerated
print >> logfile, 'Source Name:', event.SourceName
print >> logfile, 'Event ID:', event.EventID
print >> logfile, 'Event Type:', event.EventType
logfile.flush()
ResetEvent(evnthndl)
prevNumOfRecs = numOfRec
data = event.StringInserts
if data:
print 'Event Data:'
for msg in data:
print msg
# Creating a thread object of subclass evThread
systemEventViewer = evThread('localhost', 'System')
#start the thread
systemEventViewer.start()
Thanks! this blog helped.
ReplyDeleteA suggestion: Better to use EVENTLOG_SEQUENTIAL_READ instead of EVENTLOG_SEEK_READ to avoid problem mentioned in https://support.microsoft.com/en-us/kb/177199
Hi Seshasai!
ReplyDeleteMy Pleasure! And thanks for the suggestion.