c# - 让 log4net 附加程序有条件地在特定字段的属性之间进行选择

标签 c# log4net log4net-appender

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

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

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

由于我绑定(bind)了 log4net %method 属性,这将自动提取触发日志记录事件的方法名称,并将其通过名为 @Method< 的参数发送到数据库 最终将被插入到具有名为 Method 列的数据库表中。

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

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

最佳答案

如果不确切知道如何配置和使用 log4net,就很难编写适合现有框架的代码:尽管此示例创建了两个附加程序,一个使用 %method ,另一个使用使用 %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
    }
}

然后,在运行时,您选择要使用的:

public class ExceptionHandler
{
    public void HandleException(Exception ex)
    {
        string exceptionMethod = "set exception method here" ; 
        GlobalContext.Properties["ExceptionMethod"] = exceptionMethod;

        var logger = new UnhandledExceptionLogger("Logger Name Goes Here");
        logger.Log(Level.Error, "Message", ex);
    }
}

public class RuntimeLogging
{
    public void LogSomething(Exception ex)
    {
        var logger = new RuntimeLogger("Logger Name Goes Here");
        logger.Log(Level.Error, "Message", ex);
    }
}   

关于c# - 让 log4net 附加程序有条件地在特定字段的属性之间进行选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28637261/

相关文章:

c# - Log4Net:如何将程序内部的日志记录结果输出到一个变量中?

c# - 如何在 C# Asp.net 中将 SELECT sql 查询结果保存在数组中

c# - 如何在 iTextSharp 中绘制垂直渐变?

c# - Sn.exe自动输入密码

c# - OWIN 为多个路由发送静态文件

c# - 如何让 log4net 根据实例化记录器的类写入文件名?

log4net - Ninject 2、日志记录和 WebForms

c# - 我如何设置 log4net 每天将我的文件记录到不同的文件夹中?

log4net - 自定义 log4net appender 中的日志记录/错误处理

Log4net:为什么在 RenderedMessage 中忽略模式布局?