Search code examples
pythonpython-2.7winapievent-logpywin32

Reading windows event log in Python using pywin32 (win32evtlog module)


I would like to read Windows' event log. I am not sure if it's the best way but I would like to use the pywin32 -> win32evtlog module to do so. First and foremost is it possible to read logs from Windows 7 using this library and if so how to read events associated with applications runs (running an .exe must leave a trace in the event log in windows i guess).

I have managed to find some little example on the net but it's not enough for me and the documentation isn't well written unfortunately ;/

import win32evtlog

hand = win32evtlog.OpenEventLog(None,"Microsoft-Windows-TaskScheduler/Operational")
print win32evtlog.GetNumberOfEventLogRecords(hand)

Solution

  • you can find plenty of demos related to the winapi in your C:\PythonXX\Lib\site-packages\win32\Demos folder. In this folder you'll find a script named eventLogDemo.py. There you can see how to use win32evtlog module. Just start this script with eventLogDemo.py -v and you will get prints from your Windows event log with logtype Application.

    In case you can't find this script:

    import win32evtlog
    import win32api
    import win32con
    import win32security # To translate NT Sids to account names.
    
    import win32evtlogutil
    
    def ReadLog(computer, logType="Application", dumpEachRecord = 0):
        # read the entire log back.
        h=win32evtlog.OpenEventLog(computer, logType)
        numRecords = win32evtlog.GetNumberOfEventLogRecords(h)
    #       print "There are %d records" % numRecords
    
        num=0
        while 1:
            objects = win32evtlog.ReadEventLog(h, win32evtlog.EVENTLOG_BACKWARDS_READ|win32evtlog.EVENTLOG_SEQUENTIAL_READ, 0)
            if not objects:
                break
            for object in objects:
                # get it for testing purposes, but dont print it.
                msg = win32evtlogutil.SafeFormatMessage(object, logType)
                if object.Sid is not None:
                    try:
                        domain, user, typ = win32security.LookupAccountSid(computer, object.Sid)
                        sidDesc = "%s/%s" % (domain, user)
                    except win32security.error:
                        sidDesc = str(object.Sid)
                    user_desc = "Event associated with user %s" % (sidDesc,)
                else:
                    user_desc = None
                if dumpEachRecord:
                    print "Event record from %r generated at %s" % (object.SourceName, object.TimeGenerated.Format())
                    if user_desc:
                        print user_desc
                    try:
                        print msg
                    except UnicodeError:
                        print "(unicode error printing message: repr() follows...)"
                        print repr(msg)
    
            num = num + len(objects)
    
        if numRecords == num:
            print "Successfully read all", numRecords, "records"
        else:
            print "Couldn't get all records - reported %d, but found %d" % (numRecords, num)
            print "(Note that some other app may have written records while we were running!)"
        win32evtlog.CloseEventLog(h)
    
    def usage():
        print "Writes an event to the event log."
        print "-w : Dont write any test records."
        print "-r : Dont read the event log"
        print "-c : computerName : Process the log on the specified computer"
        print "-v : Verbose"
        print "-t : LogType - Use the specified log - default = 'Application'"
    
    
    def test():
        # check if running on Windows NT, if not, display notice and terminate
        if win32api.GetVersion() & 0x80000000:
            print "This sample only runs on NT"
            return
    
        import sys, getopt
        opts, args = getopt.getopt(sys.argv[1:], "rwh?c:t:v")
        computer = None
        do_read = do_write = 1
    
        logType = "Application"
        verbose = 0
    
        if len(args)>0:
            print "Invalid args"
            usage()
            return 1
        for opt, val in opts:
            if opt == '-t':
                logType = val
            if opt == '-c':
                computer = val
            if opt in ['-h', '-?']:
                usage()
                return
            if opt=='-r':
                do_read = 0
            if opt=='-w':
                do_write = 0
            if opt=='-v':
                verbose = verbose + 1
        if do_write:
            ph=win32api.GetCurrentProcess()
            th = win32security.OpenProcessToken(ph,win32con.TOKEN_READ)
            my_sid = win32security.GetTokenInformation(th,win32security.TokenUser)[0]
    
            win32evtlogutil.ReportEvent(logType, 2,
                strings=["The message text for event 2","Another insert"],
                data = "Raw\0Data".encode("ascii"), sid = my_sid)
            win32evtlogutil.ReportEvent(logType, 1, eventType=win32evtlog.EVENTLOG_WARNING_TYPE,
                strings=["A warning","An even more dire warning"],
                data = "Raw\0Data".encode("ascii"), sid = my_sid)
            win32evtlogutil.ReportEvent(logType, 1, eventType=win32evtlog.EVENTLOG_INFORMATION_TYPE,
                strings=["An info","Too much info"],
                data = "Raw\0Data".encode("ascii"), sid = my_sid)
            print("Successfully wrote 3 records to the log")
    
        if do_read:
            ReadLog(computer, logType, verbose > 0)
    
    if __name__=='__main__':
        test()
    

    I hope this script fits your needs