Log4net事件LogAppender日志事件ID

Log4net事件LogAppender日志事件ID,log4net,Log4net,是否有方法使用每条消息指定的eventid将事件记录到windows事件日志中?我使用的是log4net v 1.2.10。根据我在EventLogAppender源代码中看到的内容,以下内容应该可以做到: log4net.ThreadContext.Properties[“EventID”]=5 只需在编写日志消息之前调用它(如果没有为所有消息设置它,则应再次从属性中删除“EventID”) 注意:属性键区分大小写。解决方案是构建扩展项目“log4net.Ext.EventID”,并使用其类型

是否有方法使用每条消息指定的eventid将事件记录到windows事件日志中?我使用的是log4net v 1.2.10。

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

log4net.ThreadContext.Properties[“EventID”]=5

只需在编写日志消息之前调用它(如果没有为所有消息设置它,则应再次从属性中删除“EventID”)


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

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

另一个解决方案是添加如下所述的自定义项:(直接链接到以防万一)

正如作者所指出的:

…EventLogAppender使用内联常量对其进行检查。添加后,所述EventLogAppender将使用它们标记具有EventId和Category的给定条目

过滤器实现看起来像下面的代码(精简的gist),还有一个额外的好处,就是如果将
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;
    }
}

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

  • eventID是32位整数,但其值必须介于0和65535之间
  • category是一个16位整数,但其值必须为正数 事件源包括,事件查看器将 使用整数类别值查找本地化的“任务类别” 字符串。否则,将显示整数值。 首先是 第一
Log4net支持编写EventID和类别,但它不是直接编写的。当Log4net的EventLogAppender记录事件时,它会查看属性字典。命名属性为“EventID”和“Category”由EventLogAppender自动映射到事件日志中的相应值。我看到了一些使用log4net的EventLogAppender并在Windows事件日志中设置EventID和类别的好方法

a、 使用log4net的appender filtering,可以添加EventID和Category属性的方法。此方法有一个很好的优点,即使用标准log4net包装器,因此可以在不更改现有日志代码的情况下实现。此方法的困难在于必须创建某种机制来计算EventID和Category属性例如,筛选器可以查看异常源并将该源映射到类别值

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

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支持包含属性字典的ThreadContext对象。应用程序可以在此字典中设置EventID和Category属性,然后当线程调用日志方法时,EventLogAppender将使用这些值

log4net.ThreadContext.Properties["EventID"] = 5;
一些有用的参考资料:

扩展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.");

对于其他内容,请参阅中的“Extensibility-EventIDLogApp”。该示例包含在下载源中,源代码是如何将其扩展到InfoFormat?类似于public static void InfoFormat(此ILog记录器、字符串类别、字符串格式、参数对象[]args)?