Title: Build Windows Event Log Watcher Application to Export Event Log Entries as RSS feed using WMI (Windows Management Instrumentation) - WMI connections made easy in .NET - Get System Information Using WMI in .NET - NET Framework's Windows Management Instrumentation (WMI) services Author: Greg Dubinovskiy Email: [email protected] Environment: .NET, Windows Keywords: Build Event Log Watcher Service - Create RSS Feed from Event Log - Log Watcher RSS Feed Service - Manage EventLog .NET - Win32_NTLogEvent - ManagementEventWatcher Level: Intermediate Description: Build Windows Event Log Watcher Service Process to Export Event Log Entries as RSS feed Section Miscellaneous SubSection General
The article presented bellow, shows how to develop and setup an application to monitor for Windows Event Log (Application, System etc) changes and export them as RSS feeds using Windows Management Instrumentation.
WMI (Windows Management Instrumentation) is a component of the Microsoft operating system that allows to monitor virtually every piece of the system
(either locally or remotely) as well as control the windows operating system (for example, see Using WMI to build Network Browser, Using WMI to retrieve Domain Information, Enumerate Computers on Network with WMI article on how to use WMI for networking) .
Windows Management Instrumentation (WMI) is the infrastructure for management data and operations on Windows-based operating systems
and can be used in all Windows-based applications, and is most useful in enterprise applications and administrative scripts.
WMI consists of several pieces that allow it to manage systems. All parts of the operating system are managed through COM by a provider that talks to WMI.
WMI also has a repository and a Windows Management service that manages reading and writing information between the provider and the repository.
EntryWritten
property:
EventLog eLog = new EventLog("Application");
eLog.EntryWritten += new EntryWrittenEventHandler(EventLog_OnEntryWritten);
eLog.EnableRaisingEvents = true;
...
public void EventLog_OnEntryWritten(object source, EntryWrittenEventArgs e)
{
try
{
//handle event log change here
}
catch (Exception ex)
{
//oops
}
}
LogWatcherWMI
class based on ManagementEventWatcher
,
and EventLogChangesHandlerWMI
class to handle ManagementEventWatcher.EventArrived
event.
ManagementEventWatcher Class - Subscribes to temporary event notifications based on a specified event query.
ManagementEventWatcher.EventArrived Event - Occurs when a new event arrives. The event handler receives an argument of typeEventArrivedEventArgs
containing data related to this event. One of them isNewEvent
gets the WMI event that was delivered.
namespace LogWatcher_WMI { class LogWatcherWMI { string m_EventLogName = ""; string m_IPAddress = ""; string m_FilterEventSource = ""; string m_FilterEventType = ""; System.Management.ManagementEventWatcher m_EventLogChangesWatcher = null; EventLogChangesHandlerWMI m_EventLogChangesHandler = null; public LogWatcherWMI(string logName, string machineName, bool toDebug, string debugFileName, string rssFeedsPath, string filterEventSource, string filterEventType, int recordsToPull ) { string path = @"\\" + machineName + @"\root\cimv2"; try { m_EventLogName = logName; m_ToDebug = toDebug; m_DebugFileName = debugFileName; m_IPAddress = machineName; //filters m_FilterEventSource = filterEventSource; m_FilterEventType = filterEventType; //create management scope with default connection options: System.Management.ManagementScope managementScope = new System.Management.ManagementScope(path, new ConnectionOptions()); managementScope.Connect(); m_EventLogChangesWatcher = newManagementEventWatcher
( new EventQuery("SELECT * FROM __InstanceCreationEvent WHERE TargetInstance ISA 'Win32_NTLogEvent' and TargetInstance.LogFile = '" + logName + "'") ); m_EventLogChangesHandler = newEventLogChangesHandlerWMI
(logName, machineName, toDebug, debugFileName, rssFeedsPath, filterEventSource, filterEventType, recordsToPull); m_EventLogChangesWatcher.Scope = managementScope; m_EventLogChangesWatcher.EventArrived += newEventArrivedEventHandler
(m_EventLogChangesHandler.Arrived); } catch(Exception ex_initialize) { //oh-ho throw (new System.Exception(ex_initialize.Message)); } }
public void Arrived(object sender, EventArrivedEventArgs e)
{
try
{
// Get the Event object and display it
PropertyData property;
if ((property = e.NewEvent.Properties["TargetInstance"]) != null)
{
ManagementBaseObject managementObject = property.Value as ManagementBaseObject;
if (m_ToDebug) { AddDebugMessage("!Arrived!" + managementObject.GetText(TextFormat.Mof)); }
if (managementObject.Properties["Message"].Value != null)
{
string entrySource = managementObject.Properties["SourceName"].Value.ToString();
string entryEventType = managementObject.Properties["Type"].Value.ToString();
string entryMessage = managementObject.Properties["Message"].Value.ToString();
//TimeGenerated, for example: 20071107135007.000000-300
//
// yyyy mm dd hh mm ss.milisec
// 0123 45 67 89 01 23
// convert to new DateTime(yyyy,month,day,hour,minute,seconds)
string entryTimeGeneratedString = managementObject.Properties["TimeGenerated"].Value.ToString();
DateTime entryTimeGenerated = new DateTime(Convert.ToInt32(entryTimeGeneratedString.Substring(0, 4)),
Convert.ToInt32( entryTimeGeneratedString.Substring(4, 2)),
Convert.ToInt32(entryTimeGeneratedString.Substring(6, 2)),
Convert.ToInt32(entryTimeGeneratedString.Substring(8, 2)),
Convert.ToInt32(entryTimeGeneratedString.Substring(10, 2)),
Convert.ToInt32(entryTimeGeneratedString.Substring(12, 2)));
//check filter:
//if ((m_FilterEventSource == String.Empty || m_FilterEventSourceList.Contains(entrySource.ToUpper())))
//{ if (m_ToDebug) { AddDebugMessage("\t\tfilter source --> " + entrySource + ":" + entryEventType); } }
//if (m_FilterEventTypeList.Contains(entryEventType.ToUpper()))
//{ if (m_ToDebug) { AddDebugMessage("\t\tfilter event type --> " + entrySource + ":" + entryEventType); } }
//filter it
if ((m_FilterEventSource == String.Empty || m_FilterEventSourceList.Contains(entrySource.ToUpper())) &&
m_FilterEventTypeList.Contains(entryEventType.ToUpper()))
{
if (m_CurrentRecordCount > m_RecordsToPull)
{
StartRSSFeed();
}
//create entry in RSS file...
AddEntryToRSSFeed(entrySource, entryEventType, entryMessage, entryTimeGenerated);
m_CurrentRecordCount += 1;
}
else
{
if (m_ToDebug){ AddDebugMessage("not in filter --> " + entrySource + ":" + entryEventType); }
}
}
}
}
catch (Exception ex_entry_arrived)
{
//oh-ho...
AddDebugMessage("Failed to Arrived() for [" + m_EventLogName + "] event log\n" + ex_entry_arrived.Message);
}
}
no improvements so far. nearly perfect. More on Win32_ classes in Using WMI to build Network Browser, Using WMI to retrieve Domain Information, Enumerate Computers on Network with WMI and How to check Shared Open Files using WMI .