Question

I have the following code in both a C# console app and a C# windows service. It works in the console app. It picks up the specified event, and calls MatchEvent() correctly. The same code in a C# windows service does not pick up the same specified event, it never sees it, but sees the other events. The event in question is written to the Application log, so I am not trying to read the Security log.

I figured it was an account permissions issue (the service was running as LocalSystem). I changed the service to use the same account I was running the consoleapp as, and I still see the same behaviour. I verified that there wasn't anything done with GP or custom registry to change permissions (it's a fresh installed OS) and the account used with both apps is a localadmin.

Is there something I am missing? I researched EventLogPermission as well, but that does not seem to apply, since I am getting events out of the eventLog.

The code:

private void WatchLogs()
{
    try
    {
        _eventLogs = EventLog.GetEventLogs();

        foreach (EventLog eventLog in _eventLogs)
        {
            if (eventLog.LogDisplayName.Contains("Security"))
            {
                _logger.DebugFormat(string.Format("{0}: not watching", eventLog.LogDisplayName));
            }
            else
            {
                eventLog.EntryWritten += EventLogEntryWritten;
                eventLog.EnableRaisingEvents = true;

                if (_logger.IsInfoEnabled)
                {
                    _logger.InfoFormat("Monitoring: {0} | Raising Events: {1}", eventLog.LogDisplayName,
                                       eventLog.EnableRaisingEvents);
                }
            }
        }
    }
    catch (Win32Exception ee)
    {
        _logger.DebugFormat(string.Format("{0}: not watching({1})", eventLog.LogDisplayName, ee.Message));
    }
    catch (SecurityException securityException)
    {
        _logger.ErrorFormat("Error accessing eventlog: {0} : {1}", eventLog.LogDisplayName, securityException.Message);
    }
}

private void EventLogEntryWritten(object sender, EntryWrittenEventArgs currentEvent)
{
  var log = (EventLog) sender;

  if (_logger.IsDebugEnabled)
    _logger.DebugFormat(
      "Event Raised: |Log:{0}|Source:{1}|EventID:{2}|",log.LogDisplayName,
        currentEvent.Entry.Source,currentEvent.Entry.EventID);

  MatchEvent(currentEvent);
}
Was it helpful?

Solution

Yes you miss events if they happen within the polling inteval. You can use WMI (through System.Management) to alter the polling interval. This is an older article, but it will give you the information you need to do this. See the section on Management Events.

You will also want to perform your WriteEntry (if you are writing to the event log as well) on a separate thread, so you aren't blocking receiving events.

OTHER TIPS

Been messing around with this off and on. It seems, although I still not 100 percent sure, that the following are happening:

  • The events are cluster events, and so may be written from either node to the local system, but the EventLog class only picks up events writtern locally.
  • The system responds to the WriteEntry() method only if the last write event occured at least six seconds perviosuly. The events I were looking for happened within seconds of each other, and were swamped by other related, but not important events.

Any confirmation of this would be helpful. Info obtained here: msdn

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top