How to Query for an event log details with a given event id?
There are a few new twists if your going to query events from the new style Windows EventLogs.
- You will have to use the classes from the
System.Diagnostics.Eventing.Reader
namespace to read the new events. - Your query will be in Xpath form, so that time value is tricky, see msdn for the
EventLogQuery
definition. - Your program will run into access issues, be ready to impersonate a user that's included in the
EventReaders
AD group on the logging machine.
This sample shows some of the new access methods:
string eventID = "5312";
string LogSource = "Microsoft-Windows-GroupPolicy/Operational";
string sQuery = "*[System/EventID=" + eventID + "]";
var elQuery = new EventLogQuery(LogSource, PathType.LogName, sQuery);
using (var elReader = new System.Diagnostics.Eventing.Reader.EventLogReader(elQuery))
{
List<EventRecord> eventList = new List<EventRecord>();
EventRecord eventInstance = elReader.ReadEvent();
try
{
for (null != eventInstance; eventInstance = elReader.ReadEvent())
{
//Access event properties here:
//eventInstance.LogName;
//eventInstance.ProviderName;
eventList.Add(eventInstance);
}
}
finally
{
if (eventInstance != null)
eventInstance.Dispose();
}
}
How can I query the event log for a specific source using xpath?
Change the query string something like that (you may want to create a text resource and put this query in it to avoid escapes):
*[System[Provider[@Name='Microsoft-Windows-ADSI' or @Name='Outlook'] and (EventID=1 or EventID=2 or EventID=3)]]
The above is equivalent to:
(EventID in (1,2,3)) and (Source in ('Microsoft-Windows-ADSI', 'Outlook'))
Getting details of an event from Event Log
Upon looking at your code, here's a quick summary of what I would do:
Remove ProgressChanged
handler. It is intended for reporting current status to user, which you don't do. Instead, call Items.Add
in DoWork
handler.
Create EventLog
once. This just seems nicer and saves you from potentially creating it in a loop if you aren't careful.
Instead of parsing text with regex, create a special class. This is really important and will save you a lot of pain when you need more accurate behavior or don't wish to display index at all. Regular expressions are slow, and data intended for display to user must never be parsed. You must use classes.
Use meaningful names. I know that you didn't clean up the code, but if you want someone to help you over the internet, you really should.
Finally, get item by index. If you looked into the documentation, you would have noticed there's an indexer property that gets item directly by its index.
class EntryItem {
public EntryItem (EventLogEntry entry)
{
EntryIndex = entry.Index;
ItemText = string.Format ("{0} - {1} - {2} - {3}",
entry.Index,
entry.EntryType,
entry.TimeWritten,
entry.Source);
}
public string ItemText { get; private set; }
public int EntryIndex { get; private set; }
public override string ToString ()
{
return ItemText;
}
}
private EventLog log = new EventLog {
Log = "System"
};
private void eventLoader_DoWork (object sender, DoWorkEventArgs e)
{
foreach (EventLogEntry entry in this.log.Entries)
this.Dispatcher.BeginInvoke (() => eventListBox.Items.Add (new EntryItem (entry)));
}
private void eventListBox_SelectionChanged (object sender, SelectionChangedEventArgs e)
{
EntryItem item = eventListBox.SelectedItem as EntryItem;
if (item == null)
return;
var entry = log.Entries [item.EntryIndex];
currentEntryLabel.Content = entry.Message;
}
Query Process ID (PID) from Windows Event Log
Never use Format-*
cmdlets when further processing of your data is intended. What you want to do is expand the Message
property and adjust your pattern, so that you extract the actual PID instead of the entire line. You also don't want to use a simple match here.
... |
Select-Object -Expand Message |
Select-String -Pattern '(?<=process id:\s+)\d+' |
Select-Object -Expand Matches |
Select-Object -Expand Value
($<=...)
is a so-called positive lookbehind assertion that allows you to match something in your string without including that in the match that is returned. Essentially the pattern means "match \d+
only if it's preceded by that other string".
Read Specific Windows Event Log Event
No! There are no functions available which allows you to obtain the event based on event id.
Reference: Event logging functions
GetNumberOfEventLogRecords Retrieves the number of records in the specified event log.
GetOldestEventLogRecord Retrieves the absolute record number of the oldest record
in the specified event log.
NotifyChangeEventLog Enables an application to receive notification when an event
is written to the specified event log.
ReadEventLog Reads a whole number of entries from the specified event log.
RegisterEventSource Retrieves a registered handle to the specified event log.
Only other method of interest is reading the oldest event.
You will have to iterate through the results any way and your approach is correct :)
You can only change the form of your approach like below but this is unnecessary.
events = win32evtlog.ReadEventLog(hand, flags,0)
events_list = [event for event in events if event.EventID == "27035"]
if event_list:
print 'Event Category:', events_list[0].EventCategory
This is just the same way as you are doing but more succinct
Related Topics
Should You Access a Variable Within the Same Class via a Property
How to Implement the Sieve of Eratosthenes Using Multithreaded C#
Why Would Try/Finally Rather Than a "Using" Statement Help Avoid a Race Condition
What Would Be the Fastest Way to Concatenate Three Files in C#
How to Sync the Scrolling of Two Multiline Textboxes
Combine Two Linq Lambda Expressions
How to Disable Aero Snap in an Application
Creating a Database Programmatically in SQL Server
How to Connect to a Ms Access File (Mdb) Using C#
Selecting the Size of a System.Drawing.Icon
How to Handle Forms Authentication Timeout Exceptions in ASP.NET
How to Register Windows Forms with Simple Injector
Specified Key Is Not a Valid Size for This Algorithm
Mocking Static Methods Using Rhino.Mocks
How to Read the Current Path of |Datadirectory| from Config Settings
How to Implement One "Catch'Em All" Exception Handler with Resume
How to Have an Optional Parameter for an ASP.NET Soap Web Service