我有一个使用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}
之间进行选择?这甚至可行吗?
答案 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中找到了至少一种方法。