2011-05-18 96 views
5

我正在处理显示事件日志数据的Web应用程序,类似于事件查看器。应用程序还必须为用户提供一种方式,以便订阅事件日志,并在使用Web服务将条目写入订阅日志时接收通知。有没有办法告诉哪个EventLog导致C#中的EntryWritten事件?

我使用此代码订阅事件日志中的Web服务:

EventLog eventLog = new EventLog(observer.logName, observer.machineName); 
eventLog.EnableRaisingEvents = true; 
eventLog.EntryWritten += new EntryWrittenEventHandler(eventLog_EntryWritten); 
eventList.Add(eventLog); 

我试图用观察员的用户事件日志,并当EventWritten事件被处理,呼叫一个观察者的更新方法。问题是,我不知道如何区分事件日志,因为它们都使用相同的事件处理程序。我这样做是因为事件日志的数量因机器而异。另外,我希望观察者只处理一种类型的事件日志,即。一个观察员会在事件写入应用程序日志时发送电子邮件。

我使用这行代码来得到当前计算机上的所有日志:

remoteEventLogs = EventLog.GetEventLogs(machineName); 

EventWritten事件处理程序有这个对象发件人的参数,但Visual Studio显示其类型为EventLogInternal,我不能用,并且我不能将发件人转换为EventLog以获取EventLog.Log属性。如果我尝试抛出它,像这样:

void eventLog_EntryWritten(object sender, EntryWrittenEventArgs e) 
    { 
     var log = (EventLog)sender; 
    } 

我收到一个异常,说我无法将EventLogInternal转换为EventLog。

有没有办法知道哪个EventLog触发事件?

感谢

回答

3

另一种选择是继续沿着这条使用反射:

string log = (string)sender.GetType().GetProperty("Log").GetValue(sender, null); 

因为sender在这种情况下,实际上有Log财产。

+0

不错,暂时破解。可能是新的.Net框架问题 – Zam 2017-06-15 14:58:33

2

我认为你在找什么可以在EntryWrittenEventArgs找到。

MSDN显示有一个名为Entry的属性,向您显示关于刚记录的内容的各种信息。有一些属性可以帮助你在EventLogEntry类中,例如MachineName或UserName。

这里是对的args类 http://msdn.microsoft.com/en-us/library/system.diagnostics.entrywritteneventargs.aspx

下面的链接到Entry类的链接 http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogentry.aspx

我没有看到一个直接链接到特定的事件日志,但是如果你捅在调试器中,Entry对象可能会为您提供足够的信息来查找它。

我希望这有助于一些。

+0

呀类,问题是,在输入属性不显示有关正在被写入日志信息以任何方式。 – markhan777 2011-05-19 07:44:36

4

我认为问题是EventLog类的整个概念是它假设它在单个日志上工作 - 它会这样做。因此EventWrittenEventArgsEventEntry类都不包含包含Log-name的成员,因为它由关联的EventLog实例隐式给出。不好的是,你无法在EventWritten处理程序中进入它。

您可以创建一个包装周围System.Diagnostics.EventLog,就像这样:

class MyEventLog : EventLog 
{ 
    public MyEventLog(string logName, string machineName) 
     : base(logName, machineName) 
    { 
     base.EnableRaisingEvents = true; 
     base.EntryWritten += MyEventLog_EntryWritten; 
    } 

    void MyEventLog_EntryWritten(object sender, EntryWrittenEventArgs e) 
    { 
     Console.WriteLine("Entry in {0} log.", base.Log); 

     // Your code 
    } 
} 

然后使用MyEventLog的地方,你通常会使用EventLog。可能给它一个更好的名字,但。

您也可以通过提供Action<string, EntryWrittenEventArgs>属性来从“MyEventLog_EntryWritten”内部调用该属性并将其设置为“外部”处理函数,从而将“您的代码”部分分解出来。

+0

还没有想过在EventLog中做一个包装,我会试一试。非常感谢 – markhan777 2011-05-19 07:45:17

+0

这不允许您从事件处理程序中访问日志名称,或者我错过了某些东西。 – driverobject 2013-07-19 18:39:37

+0

'base.Log'会给你日志的名字。或者您可以将它存储在构造函数中的成员变量中,并从事件处理函数(它是成员函数)中访问它。 – 2013-07-20 12:43:01

0

我同意在Christian建议的另一个类中包装EventLog类的想法。我最近正在研究这样的要求。

这是我创建

public class EventLogWatcher : EventLog 
{ 
    Action<string, EntryWrittenEventArgs> _changeHandler; 
    public EventLogWatcher(string logName, Action<string, EntryWrittenEventArgs> changeHandler) 
     : base(logName) 
    { 
     _changeHandler = changeHandler; 
    } 

    public void EnableCapture() 
    { 
     base.EnableRaisingEvents = true; 
     base.EntryWritten += EventLogChangeHandler; 
    } 

    public void DisableCapture() 
    { 
     base.EnableRaisingEvents = false; 
     base.EntryWritten -= EventLogChangeHandler; 
    } 

    private void EventLogChangeHandler(object sender, EntryWrittenEventArgs e) 
    { 
     _changeHandler(base.Log, e); 
    } 
} 

下面是一个使用

foreach (string eventlogType in LogTypes) 
      logWatchers.Add(new EventLogWatcher(eventlogType, EventLogChangeHandler)); 

     foreach (EventLogWatcher localLog in logWatchers) 
     { 
      try 
      { 
       localLog.EnableCapture(); 
      } 
      catch(Exception ex) 
      { 
       EventManager.PublishExceptionLogMessage(ex); 
      } 
     } 
     EventManager.PublishInfoLogMessage($"Started EventLog listeners for {string.Join(",", LogTypes)} logs"); 

private void EventLogChangeHandler(string eventLogType, EntryWrittenEventArgs e) 
    { 
     try 
     { 
      if (UploadAllowed(eventLogType, e)) 
      { 

       Dm.EventLog model = _eventLogEntryMapper.MapEntryToModel(e); 
       Task.Factory.StartNew(
         () => _eventLogUploadService.UploadEventLog(model), 
         _cancellationTokenProvider.Token, 
         TaskCreationOptions.None, 
         TaskScheduler.Default); 
      } 
     } 
     catch(Exception ex) 
     { 
      EventManager.PublishExceptionLogMessage(ex); 
     } 

    } 
相关问题