Each Windows machine comes equipped with an expandable set of event logs for tracking system- or application-level event information. This module offers a Pythonic interface to event logs, including iterating over them, checking their length and accessing them by means of easy monikers, regardless of what machine they’re on.
Each Windows system comes with predefined Event Logs called (in the English-language versions): Application, System, Security. Certain Microsoft applications create extra ones, but most applications create an event source against the Applications log.
In principal, event sources are key to the way in which event logs work. An event source represents a DLL and a resource file containing messages, possibly in multiple languages, possibly containing placeholders for the calling application to fill in with the name of a file or a user or whatever. It’s linked to one of the event logs (Application, System, etc). When you log an event, you do it via an event source handle.
In reality, it’s perfectly possible to log an event against an event source which doesn’t exist. You’ll get a bit of boilerplate text in the event message saying that something couldn’t be found, but the event will log. This module allows creation of simple event sources, via the EventSource.create() method and at present forces an event source to exist before a record can be logged against it.
Of these functions, the two you’re most likely to need are: event_log(), which returns an EventLog corresponding to the named log, which you can then iterate over; and log_event(), which logs an event against a named source.
Simple iterator over all known event logs.
Convenience function to return an EventLog object representing one of the existing event logs. Will raise x_not_found if the event log does not exist.
Parameters: | log – one of None, an EventLog instance, or a [\\computer\]name moniker |
---|
Simple iterator over all the event sources for a named log
Convenience function to return an EventSource object representing one of the existing event sources. Will raise exceptions.x_not_found if the event source does not exist.
Parameters: | source – one of None, an EventSource instance, or a [[\\computer]\log\]name moniker |
---|
Convenience function to log an event against an existing source.
Parameters: |
|
---|
Internal class for convenient access to attributes of an event log record. Attributes are available as lowercase_with_underscore equivalents of their TitleCase counterparts and are converted to Python data types where appropriate, eg time_written is a datetime value and sid is an accounts.Principal instance.
Two _EventLogEntry instances compare equal if they have the same record number on the same event log on the same computer.
The unique identifier of this record within this event log. May not correspond to the record’s position in the current log since records can be cleared or purged.
Python datetime value corresponding to the record’s timestamp
Id of the event with relevance to the corresponding event source
One of the EVENTLOG_TYPE values
Category of the event with relevance to the corresponding event source
accounts.Principal Principal which logged the record
Name of the computer on which the record was logged
Name of the event source which the record was logged against
Arbitrary data associated with the log record
The message associated with the record. This has already been formatted and the corresponding strings filled in.
An Event Log is a sequential database managed through API calls with a number of different Event Sources, against which events can be logged. The log can be read backwards (using the reversed () builtin) or forwards but only sequentially. (We simulate random access by reading sequentially until a record is hit).
You can use the builtin len () to determine the current size of this log (which may or may not correspond to the maximum record number). Item access is possible from either end by subscripting the log in the usual way. It should be noted that this uses iteration, forward or reverse as needed, so is not going to be that efficient except to find a few records at either end.
Instances of this class are expected to be accessed via the event_log() function.
The real file which holds the database for this event log
How many seconds the records should be kept for before purging
Queries the underlying implementation for the current number of records in the corresponding event log. NB This may not be the same as the maximum record number since event logs can be purged and cleared. To determine efficiently the number of records currently in the log:
from winsys import event_logs
print len (event_logs.event_log ("Application"))
Implement the iterator protocol so that the event log itself can be treated as an iterable. To iterate over the records in the log, oldest first:
from winsys import event_logs
for record in event_logs.event_log ("Application"):
print record
cf __reversed__() for iterating in reverse order.
Implement the reverse iterator protocol so the event log can be iterated over in reverse, ie latest first:
from winsys import event_logs
for record in reversed (event_logs.event_log ("Application")):
print record
Allow random access to this event log by record position. NB This simply iterates over the event log in the right order until it finds the right record so it won’t be fast. It’s expected to be used to find the first or last records:
from winsys import event_logs
app = event_logs.event_log ("Application")
print "Oldest record:", app[0]
print "Latest record:", app[-1]
At present, slices are not supported.
Clear the event log, optionally saving out to an opaque file first, using the built-in functionality.
Pass-through for log_event()
(EXPERIMENTAL) Unsure if this will be of any use. In principle, you can ask for an event to fire when a new record is written to this log. In practice, though, there’s no way of determining which record was added and you have to do some housekeeping and work out what changed.
Probably quite inefficient since it has to keep iterating backwards over the log every time to find the last record to match against. Does work, though.
An Event Source is an apparently necessary but in fact slightly unnecessary part of the event log mechanism. In principle, it represents a name and a DLL with a bunch of message ids in it. In practice, you can log an event with an unregistered event source and it will work quite happily although the event viewer won’t be able to pick up the full message, only the inserted strings and the added data.
Implemented here mostly for internal use in the log_event() function. NB We’re using the convenience functions offered by win32evtlogutil, which make use of defaults built in to the win32event.pyd file. In the future we may implement our own .DLL builder.
Instances of this class are expected to be accessed via the event_source() module-level function.
The DLL containing the messages which the event source supports. For simple Python event sources this will be the win32evtlog.pyd file.
List of EVENTLOG_TYPE name strings supported by this event source.
Call the convenience functions to add a simple event source to the registry against a named event log (usually Application). Return the event source so you can log against it.
Parameters: |
|
---|
Remove an event source from the registry. NB There is no particular security at work here: it’s perfectly possible to remove someone else’s event source.
Pass-through to module-level log_event()
Base exception for eventlog-specific exceptions
Ways of reading event logs
Name | Val | Win32 |
---|---|---|
SEQUENTIAL | 1 | EVENTLOG_SEQUENTIAL_READ |
SEEK | 2 | EVENTLOG_SEEK_READ |
FORWARDS | 4 | EVENTLOG_FORWARDS_READ |
BACKWARDS | 8 | EVENTLOG_BACKWARDS_READ |
Types of records in event logs
Name | Val | Win32 |
---|---|---|
EVENTLOG_SUCCESS | 0 | EVENTLOG_SUCCESS |
ERROR | 1 | EVENTLOG_ERROR_TYPE |
AUDIT_FAILURE | 16 | AUDIT_FAILURE |
WARNING | 2 | EVENTLOG_WARNING_TYPE |
INFORMATION | 4 | EVENTLOG_INFORMATION_TYPE |
AUDIT_SUCCESS | 8 | AUDIT_SUCCESS |
See also