Log4net EventLogAppender 日志事件 ID

发布于 2024-08-21 15:56:02 字数 74 浏览 6 评论 0原文

有没有办法使用每条消息指定的 eventid 将事件记录到 Windows 事件日志中?我正在使用 log4net v 1.2.10。

Is there a way to log an event into the windows event log with a specified eventid per message? I am using log4net v 1.2.10.

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

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

发布评论

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

评论(5

帅的被狗咬 2024-08-28 15:56:03

根据我在 EventLogAppender 源代码中看到的内容,以下应该可以解决问题:

log4net.ThreadContext.Properties["EventID"] = 5;

只需在写入日志消息之前调用此函数(如果您没有为所有消息设置它,您应该再次从属性中删除“EventID”。

注意,属性键区分大小写。

Based on what I see in the EventLogAppender source code the following should do the trick:

log4net.ThreadContext.Properties["EventID"] = 5;

Just call this before you write your log messages (if you do not set it for all messages you should remove the "EventID" again from the Properties.

N.B the property key is case sensitive.

孤独陪着我 2024-08-28 15:56:03

当在 System.Diagnostics 中使用本机 .net 事件日志 API 时,WriteEntry 方法允许设置 eventID 和类别。在这些 API 中:

  • eventID 是一个 32 位 int,但其值必须在 0 到 65535 之间;
  • 类别是 16 位 int,但其值必须为正数。如果
    事件源包含类别资源文件,事件查看器将
    使用整数类别值查找本地化的“任务类别”
    细绳。否则,显示整数值。
    类别必须连续编号,开始于
    number 1

Log4net 支持编写 EventID 和 Category,但它并不简单。当 log4net 的 EventLogAppender 记录事件时,它会查看属性字典。命名属性“EventID”和“Category”由 EventLogAppender 自动映射到事件日志中的相应值。我已经看到了一些使用 log4net 的 EventLogAppender 并在 Windows 事件日志中设置 EventID 和类别的好建议方法。

一个。使用 log4net 的附加过滤器,可以注册过滤器可以添加EventID和Category属性。此方法有一个很好的好处,即使用标准 log4net 包装器,因此可以在不更改现有日志记录代码的情况下实现此方法。此方法的困难在于必须创建某种机制来根据记录的信息计算 EventID 和类别。例如,过滤器可以查看异常源并将该源映射到类别值。

b. Log4net 可以进行扩展,以便可以使用包含 EventID 和 Category 参数的自定义日志记录包装器。 log4net 示例“Extensibility – EventIDLogApp”中演示了添加 EventID,该示例包含在 log4net 源代码中。在扩展示例中,使用了一个新接口 (IEventIDLog),该接口扩展了应用程序用于记录日志的标准 ILog 接口。这提供了包含 eventId 参数的新日志记录方法。新的日志记录方法在记录事件之前将 eventId 添加到 Properties 字典中。

public void Info(int eventId, object message, System.Exception t)
{
       if (this.IsInfoEnabled)
       {
             LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t);
             loggingEvent.Properties["EventID"] = eventId;
             Logger.Log(loggingEvent);
       }
}

c. Log4net 支持包含 Properties 字典的 ThreadContext 对象。应用程序可以在此字典中设置 EventID 和 Category 属性,然后当线程调用日志记录方法时,EventLogAppender 将使用这些值。

log4net.ThreadContext.Properties["EventID"] = 5;

一些有用的参考:

When one uses the native .net Event Log APIs in System.Diagnostics, the WriteEntry methods allow setting the eventID and category. In these APIs:

  • eventID is a 32 bit int, but its value must be between 0 and 65535
  • category is a 16 bit int, but its value must be positive. If the
    event source includes a category resource file, the event viewer will
    use the integer category value to lookup a localized “Task category”
    string. Otherwise, the integer value is displayed.
    The categories must be numbered consecutively, beginning with the
    number 1

Log4net supports writing an EventID and a Category, but it isn’t straight forward. When log4net’s EventLogAppender logs an event, it looks at a dictionary of properties. The named properties "EventID" and "Category" are automatically mapped by the EventLogAppender to the corresponding values in the event log. I’ve seen a few good suggested ways to use log4net’s EventLogAppender and set the EventID and Category in the Windows event log.

a. Using log4net’s appender filtering, a filter may be registered that can add the EventID and Category properties. This method has a nice benefit that the standard log4net wrappers are used and so this can be implemented without changing existing logging code. The difficulty in this method is some mechanism has to be created to calculate the EventID and Category from the logged information. For instance, the filter could look at the exception source and map that source to a Category value.

b. Log4net may be extended so custom logging wrappers can be used that can include EventID and Category parameters. Adding EventID is demonstrated in the log4net sample “Extensibility – EventIDLogApp” which is included in the log4net source. In the extension sample a new interface (IEventIDLog) is used that extends the standard ILog interface used by applications to log. This provides new logging methods that include an eventId parameter. The new logging methods add the eventId to the Properties dictionary before logging the event.

public void Info(int eventId, object message, System.Exception t)
{
       if (this.IsInfoEnabled)
       {
             LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t);
             loggingEvent.Properties["EventID"] = eventId;
             Logger.Log(loggingEvent);
       }
}

c. Log4net supports a ThreadContext object that contains a Properties dictionary. An application could set the EventID and Category properties in this dictionary and then when the thread calls a logging method, the values will be used by the EventLogAppender.

log4net.ThreadContext.Properties["EventID"] = 5;

Some helpful references:

毅然前行 2024-08-28 15:56:03

好吧,解决方案是构建扩展项目“log4net.Ext.EventID”并使用其类型:IEventIDLog、EventIDLogImpl 和 EventIDLogManager。

Well, the solution was to build the extension project "log4net.Ext.EventID" and to use its types: IEventIDLog, EventIDLogImpl and EventIDLogManager.

卖梦商人 2024-08-28 15:56:03

另一个解决方案是添加自定义 Filter,如下所述:< a href="http://blog.scooletz.com/2013/04/15/enhancing-log4net-exception-logging/" rel="nofollow">增强 log4net 异常日志记录 (直接链接到要点以防万一)

正如作者指出的:

... EventLogAppender 使用内联常量来检查它们。添加后,提到的 EventLogAppender 将使用它们来用 EventId 和 Category 标记给定条目。

过滤器实现将类似于下面的代码(精简要点),还有一个额外的好处,如果您将 GetEventId 方法公开,您可以针对它编写一些测试

public class ExceptionBasedLogEnhancer : FilterSkeleton
{
    private const string EventLogKeyEventId = "EventID";

    public override FilterDecision Decide(LoggingEvent loggingEvent)
    {
        var ex = loggingEvent.ExceptionObject;
        if (ex != null)
        {
            loggingEvent.Properties[EventLogKeyEventId] = GetEventId(ex);
        }

        return FilterDecision.Neutral;
    }

    private static short GetEventId(Exception ex)
    {
        // more fancy implementation, like getting hash of ex properties 
        // can be provided, or mapping types of exceptions to eventids
        // return no more than short.MaxValue, otherwise the EventLog will throw
        return 0;
    }
}

Another solution is to add a custom Filter as described here: Enhancing log4net exception logging (direct link to the Gist just in case).

As the author points out:

... EventLogAppender uses inline consts to check them. Once they are added they will be used by the mentioned EventLogAppender to mark the given entries with EventId and Category.

The filter implementation will look like the code below (stripped down gist) with the added benefit that if you make GetEventId method public, you can write some tests against it

public class ExceptionBasedLogEnhancer : FilterSkeleton
{
    private const string EventLogKeyEventId = "EventID";

    public override FilterDecision Decide(LoggingEvent loggingEvent)
    {
        var ex = loggingEvent.ExceptionObject;
        if (ex != null)
        {
            loggingEvent.Properties[EventLogKeyEventId] = GetEventId(ex);
        }

        return FilterDecision.Neutral;
    }

    private static short GetEventId(Exception ex)
    {
        // more fancy implementation, like getting hash of ex properties 
        // can be provided, or mapping types of exceptions to eventids
        // return no more than short.MaxValue, otherwise the EventLog will throw
        return 0;
    }
}
屌丝范 2024-08-28 15:56:03

扩展 ILog.Info() 以获取事件 ID:

public static class LogUtils
{
    public static void Info(this ILog logger, int eventId, object message)
    {
        log4net.ThreadContext.Properties["EventID"] = eventId;
        logger.Info(message);
        log4net.ThreadContext.Properties["EventID"] = 0; // back to default
    }
}

然后像这样调用它:

using LogUtils;
private static readonly log4net.ILog _logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

_logger.Info(3, "First shalt thou take out the Holy Pin, then shalt thou count to three.");

Extend ILog.Info() to take an event ID:

public static class LogUtils
{
    public static void Info(this ILog logger, int eventId, object message)
    {
        log4net.ThreadContext.Properties["EventID"] = eventId;
        logger.Info(message);
        log4net.ThreadContext.Properties["EventID"] = 0; // back to default
    }
}

Then call it like this:

using LogUtils;
private static readonly log4net.ILog _logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

_logger.Info(3, "First shalt thou take out the Holy Pin, then shalt thou count to three.");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文