Log4Net两次使用自定义布局记录异常

问题描述 投票:0回答:1

我正在开发ASP.Net Web应用程序,并且遇到了Log4Net用自定义布局写出异常的问题。我正在通过以下方式在Global.asax中以编程方式配置滚动文件追加程序(不使用web.config设置):

// Create basic file logging appender for the application. 
var fileAppender = new RollingFileAppender
{
     Layout = new JsonPatternLayout(),
     File = $"c:/logs/web.log",
     AppendToFile = true,
     RollingStyle = RollingFileAppender.RollingMode.Date,
     DatePattern = "yyyyMMdd'.log'",
     StaticLogFileName = true,
     Threshold = Level.Debug
};
fileAppender.ActivateOptions();
log4net.Config.BasicConfigurator.Configure(fileAppender);

[JsonPatternLayout是我编写的自定义类,用于从Log4Net中获取Logging事件并将其序列化为json格式,以便更容易地将其消化为日志服务:

public class JsonPatternLayout : PatternLayout
{
    public override void Format(TextWriter writer, LoggingEvent e)
    {
        var dic = new Dictionary<string, string>
        {
            ["level"] = e.Level.DisplayName,
            ["session"] = e.Identity,
            ["timestamp"] = e.TimeStamp.ToString(),
            ["message"] = e.RenderedMessage,
            ["logger"] = e.LoggerName,
            ["exception"] = e.ExceptionObject == null ? string.Empty : e.ExceptionObject.ToString(),
            ["thread"] = e.ThreadName,
            ["machineName"] = Environment.MachineName
        };
            writer.Write($"{JsonConvert.SerializeObject(dic)}\n");
    }
}

这会导致文件输出,其中两次写入异常-一次来自我的模式布局中的json,另一次作为字符串(为清晰起见而清理了消息):

{"level":"INFO","session":"1","timestamp":"2/14/2020 5:07:12 PM","message":"Message","logger":"Logger","exception":"","thread":"7", "machineName":"Machine"}
{"level":"INFO","session":"1","timestamp":"2/14/2020 5:07:14 PM","message":"Message","logger":"Logger","exception":"","thread":"10","machineName":"Machine"}
{"level":"ERROR","session":"1","timestamp":"2/14/2020 5:07:14 PM","message":"Message","logger":"Logger","exception":"System.Exception: Boo!\r\n   at {CallStack}","thread":"10","machineName":"Machine"}
System.Exception: Boo!
   at {Call Stack}

我想要的是第二次完全不写出例外情况。据我所知,这并不是通过我的格式化程序,因为它不是我明确提出的消息,而是来自.Net框架本身。捕获异常并且不重新抛出它们不会阻止该异常再次记录。

如何停止这种行为?

c# asp.net logging log4net serilog
1个回答
0
投票

我用Serilog代替Log4net解决了这个问题。由于Serilog仍然实现了许多相同的接口,因此我能够在短短的几周内重新使用自定义格式器:

Log.Logger = new LoggerConfiguration()
    // Configure file sink.
    .WriteTo.RollingFile(
    new JsonPatternLayout(),
    @"c:\path\logs\app-{Date}.log",
    LogEventLevel.Information,
    retainedFileCountLimit: 90)
    .CreateLogger();
public class JsonPatternLayout : ITextFormatter
{
    public void Format(LogEvent e, TextWriter writer)
    {
        var dic = new Dictionary<string, object>
        {
            ["level"] = e.Level.ToString(),
            ["session"] = System.Threading.Thread.CurrentPrincipal.Identity.Name,
            ["timestamp"] = e.Timestamp.ToLocalTime().ToString(),
            ["message"] = e.RenderMessage(),
            ["Properties"] = e.Properties,
            ["exception"] = e.Exception == null ? string.Empty : e.Exception.ToString(),
            ["machineName"] = machineName
        };
        writer.Write($"{JsonConvert.SerializeObject(dic)}\n");
    }
}

我的日志消息的格式与Log4net的格式相同,并且不会双重记录异常。完全替换Log4net有点麻烦,但是进展非常顺利。

非常感谢所有帮助并研究此问题的人。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.