使log4net appender有条件地在特定字段的属性之间进行选择

时间:2015-02-20 20:01:35

标签: c# log4net log4net-appender

我有一个使用log4net记录日志记录事件的常见日志记录项目。由于它是一个常见项目,因此它以非标准方式配置:几乎所有内容都是通过C#代码设置的。

现在,我有一个以这种方式配置的AdoNet appender,其中包括记录触发日志事件的方法。它是作为日志记录初始化的一部分创建的,它的定义如下:

appender.AddParameter(new AdoNetAppenderParameter()
{
    ParameterName = "@Method",
    DbType = DbType.String,
    Size = 255,
    Layout = new RawLayoutConverter().ConvertFrom(new PatternLayout("%method")) as IRawLayout
});

由于我正在加入log4net %method属性,因此会自动提取触发日志记录事件的方法名称并将其发送到名为@Method的参数中的数据库中插入到具有名为Method的列的数据库表中。

但是,我添加了一些新功能来全局处理异常并记录它们。当异常从任何地方冒泡到调用堆栈的顶部时,它将被传递给这个新的全局方法,以便记录它。我可以访问异常,因此我可以看到导致此异常的控制器和方法。我可以轻松地将其添加为log4net自定义属性(映射到类似%property{ExceptionMethod}的内容)。我的问题是用我自己的自定义属性覆盖(或覆盖)log4net的%method属性。

那么,在通过AdoNet appender发送数据以在我的日志记录数据库表的Method列下记录此信息时,如何让log4net有条件地在%method%property{ExceptionMethod}之间进行选择?这甚至可行吗?

2 个答案:

答案 0 :(得分:2)

在不确切知道如何使用log4net的情况下,很难编写适合您现有框架的代码:此示例创建了两个appender,一个使用%method,另一个使用{{1并将它们分配给不同的记录器:

%property{ExceptionMethod}

然后,在运行时,您可以选择使用哪个:

public abstract class BaseAppender : AdoNetAppender
{
    protected BaseAppender()
    {
        // Add common parameters, set connection strings etc

        // e.g.
        this.AddParameter(new AdoNetAppenderParameter
        {
            ParameterName = "@log_level",
            DbType = DbType.String,
            Size = 50,
            Layout = new RawLayoutConverter().ConvertFrom(new PatternLayout("%level")) as IRawLayout
        });

        // Then ask each subclass to add the extra parameters
        this.AddExtraParameters();
    }

    protected abstract void AddExtraParameters();
}

public class RuntimeAppender : BaseAppender
{
    protected override void AddExtraParameters()
    {
        this.AddParameter(new AdoNetAppenderParameter
        {
            ParameterName = "@Method",
            DbType = DbType.String,
            Size = 255,
            Layout = new RawLayoutConverter().ConvertFrom(new PatternLayout("%method")) as IRawLayout
        });
    }
}

public class UnhandledExceptionAppender : BaseAppender
{
    protected override void AddExtraParameters()
    {
        this.AddParameter(new AdoNetAppenderParameter
        {
            ParameterName = "@Method",
            DbType = DbType.String,
            Size = 255,
            Layout =
                new RawLayoutConverter().ConvertFrom(new PatternLayout("%property{ExceptionMethod}")) as IRawLayout
        });
    }
}

public sealed class RuntimeLogger : Logger
{
    public RuntimeLogger(string name)
        : base(name)
    {
        this.Appenders.Add(new RuntimeAppender());
        this.Level = Level.Error; // etc
    }
}

public sealed class UnhandledExceptionLogger : Logger
{
    public UnhandledExceptionLogger(string name)
        : base(name)
    {
        this.Appenders.Add(new UnhandledExceptionAppender());
        this.Level = Level.Error; // etc
    }
}

答案 1 :(得分:0)

根据您的需求,您可能会发现在代码中完全实现AdoNetAppender更容易。

在我之前的回答here中找到了至少一种方法。