有没有办法在 C# 中判断哪个 EventLog 导致了 EntryWritten 事件?

发布于 2024-11-08 10:54:07 字数 1037 浏览 2 评论 0原文

我正在开发一个显示事件日志数据的 Web 应用程序,类似于事件查看器。应用程序还必须为用户提供一种方法来订阅事件日志,并在将条目写入订阅日志时使用 Web 服务接收通知。

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

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

我尝试使用观察者作为事件日志的订阅者,并且在处理 EventWritten 事件时,调用一个观察者的 Update 方法。问题是,我不知道如何区分事件日志,因为它们都使用相同的事件处理程序。我这样做是因为事件日志的数量因一台机器而异。另外,我希望观察者只处理一种类型的 EventLog,即。当事件写入应用程序日志时,观察者会发送一封电子邮件。

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

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 触发了事件?

谢谢

I'm working on a web application that shows event logs data, similar to Event Viewer. The application also has to provide a way for users to subscribe to event logs and receive notifications when an entry is written to subscribed logs, using a web service.

I'm using this code to subscribe to an event log in the web service:

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

I'm trying to use observers as subscribers to event logs, and when an EventWritten event is handled, call the Update method of one observer. The problem is, I don't know how to differentiate event logs, since they all use the same event handler. I'm doing this because the number of event logs differs from one machine to another. Also, I want observers to handle only one type of EventLog, ie. one observer would send an e-mail when an event is written to the Application log.

I use this line of code to get all logs on the current computer:

remoteEventLogs = EventLog.GetEventLogs(machineName);

EventWritten event handler has this object sender parameter, but Visual Studio shows its type as EventLogInternal, which I can't use, and I can't cast the sender to EventLog to get EventLog.Log property. If I try to cast it, like this:

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

I get an exception saying I can't cast an EventLogInternal to EventLog.

Is there a way to know which EventLog fires the event?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

影子是时光的心 2024-11-15 10:54:07

我认为问题是,EventLog 类的整个概念是它假设它在单个 Log 上工作 - 它确实如此。因此,EventWrittenEventArgsEventEntry 类都没有包含包含 Log-name 的成员,因为它是由关联的 EventLog-instance 隐式给出的。当然,不好的是您无法在 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
    }
}

然后在通常使用 EventLog 的地方使用 MyEventLog。也许给它一个更好的名字。

您还可以通过提供从 MyEventLog_EntryWritten 内部调用的 Action 属性来提取“您的代码”部分,并且可以将其设置为您的“外部” “处理函数。

I think the problem is, that the whole concept of the EventLog class is that it assumes it works upon a single Log - which it does. So neither the EventWrittenEventArgs nor the EventEntry class sport a member that contains the Log-name, as it is implicitly given by the associated EventLog-instance. Bad is of course, that you cannot get to it inside the EventWritten-handler.

You could create a wrapper around System.Diagnostics.EventLog, like so:

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
    }
}

Then use MyEventLogin places where you normally would use EventLog. Probably give it a better name though.

You could also factor out the "Your Code" part by providing an Action<string, EntryWrittenEventArgs> property that is being called from inside MyEventLog_EntryWritten and can be set to your "external" handler function.

赠佳期 2024-11-15 10:54:07

另一种选择是按照以下方式使用反射:

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

因为在本例中 sender 实际上具有 Log 属性。

Another option would be to use reflection along these lines:

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

since sender in this case actually has the Log property.

小女人ら 2024-11-15 10:54:07

我认为您要查找的内容可以在 EntryWrittenEventArgs 中找到。

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

这是 Args 类的链接
http://msdn.microsoft.com/en-us/library /system.diagnostics.entrywritingeventargs.aspx

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

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

我希望这对一些人有帮助。

I think that what you are looking for can be found in the EntryWrittenEventArgs.

The MSDN shows there is a property called Entry that shows you all kinds of information about what just got logged. There are some properties that might help you in the EventLogEntry class, such as MachineName or UserName.

Here is a link to the Args class
http://msdn.microsoft.com/en-us/library/system.diagnostics.entrywritteneventargs.aspx

Here is a link to the Entry class
http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogentry.aspx

I don't see a direct link to the specific event log, but if you poke around in that class with the debugger the Entry object might give you enough information to look it up.

I hope this helps some.

醉酒的小男人 2024-11-15 10:54:07

我同意 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);
        }

    }

I agree with the idea of wrapping the EventLog class within another class as suggested by Christian. I recently worked on such a requirement.

This is the class that I created

 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);
    }
}

Here is a usage

 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);
        }

    }
女皇必胜 2024-11-15 10:54:07

另一种选择是更改事件注册,如下所示:

eventLog.EntryWritten += (sender, e) => eventLog_EntryWritten(eventLog, e);

Another option would be to change the event-registration like this:

eventLog.EntryWritten += (sender, e) => eventLog_EntryWritten(eventLog, e);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文