log4net转换模式在Asp.net Core中无法工作

4

我正在使用log4net-core-preview(2.0.6)在Asp.Net Web API Core 2.0中,我的log4net配置布局是

 <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%-5p %d{hh:mm:ss} %logger [%M %line] %message%newline" />
 </layout>

在 Startup.ConfigureServices 中

//log4net stuff goes here ...
var logRepo = LogManager.GetRepository(Assembly.GetEntryAssembly());
XmlConfigurator.Configure(logRepo, File.OpenRead("log4net.config"));
ILog log = LogManager.GetLogger(this.GetType());
log.Info("App is starting");

但我不知道为什么我的日志看起来像这样:

调试 01:29:10 MyNameSpace.Controllers.XYZController [? ?] , 某些信息

有人能告诉我这里出了什么问题吗?

谢谢。

2个回答

7
有点晚了,但最近遇到了这个问题,原来在.NET Standard框架下不支持一些模式。
根据Apache的文档,以下功能不受支持:
- ADO.NET附加程序 - 与ASP.NET相关的任何内容(跟踪附加程序和几个模式转换器) - .NET Remoting - 彩色控制台附加程序 - 事件日志附加程序 - NetSendAppender - SMTP附加程序 - DOMConfigurator - 堆栈跟踪模式 - 访问appSettings(既不能访问log4net部分本身,也不能使用AppSettingsPatternConverter) - 使用EnvironmentFolderPathPatternConverter访问“特殊路径” - 模拟Windows帐户
有两种解决方法:
  1. 使用 C# 5.0 的 Caller Info 属性 和自定义日志包装器,这里有一些很好的例子:
  2. 创建自定义 PatternConverter,其中包含 StackTrace需要 .NET Standard 2.0 及更高版本),如下所示:

StackTraceConverter.cs

namespace MyWebApp
{
    public class StackTraceConverter : PatternConverter
    {
        protected override void Convert(TextWriter writer, object state)
        {
            try
            {
                StackTrace st = new StackTrace(true);
                int idx = 1;
                while (st.GetFrame(idx).GetMethod().DeclaringType.Assembly == typeof(LogManager).Assembly)
                    idx++;
                //I have to create a new StackTrace object in order to get the line number.
                var targetSt = new StackTrace(st.GetFrame(idx));
                writer.Write($"{targetSt.GetFrame(0).GetMethod().DeclaringType.FullName}.{targetSt.GetFrame(0).GetMethod().Name}({targetSt.GetFrame(0).GetFileLineNumber()})");
            }
            catch (Exception)
            {
            }
        }
    }
}

StackTracePatternLayout.cs

namespace MyWebApp
{
    public class StackTracePatternLayout : PatternLayout
    {
        public StackTracePatternLayout()
        {
            AddConverter(new ConverterInfo
            {
                Name = "stack_trace", //your pattern name here
                Type = typeof(StackTraceConverter)
            }
        );
        }
    }
}

log4net.config

<appender name="RollingFileAppenderCustomPattern" type="log4net.Appender.RollingFileAppender">
    ...
    <layout type="MyWebApp.StackTracePatternLayout, MyWebApp">
        <conversionPattern value="%-5p %date{yyyy/MM/dd HH:mm:ss} [tread-%t] %stack_trace - %m%n" />
    </layout>
    ...
</appender>
<root>
    <level value="ALL" />
    <appender-ref ref="RollingFileAppenderCustomPattern" />
</root>

然后像往常一样登录。
public class HomeController : Controller
{
    ...
    public IActionResult LogForNetTest()
    {
        if (Logger.IsDebugEnabled)
            Logger.Debug($"Log4Net is ready to log!");
        ...
    }
    ...
}

结果类似于这样。
DEBUG 2018/07/02 15:30:59 [tread-9] MyWebApp.Controllers.HomeController.LogForNetTest(46) - Log4Net is ready to log!

尚未完全测试,但两种方法目前都能很好地工作,尽管它们之间存在一些差异:

希望这会有所帮助。

Timmy。


1
提醒其他人,在链接时 layout type= 是 "FullClassPath, Assembly"。 - bnns
它在ASP.NET Core和Microsoft.Extensions.Logging.ILogger上无法工作 :( - 1_bug

0

虽然您的回答可能解决了问题,但是包括解释如何以及为什么解决问题将有助于提高您的帖子质量,并可能导致更多的赞。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人。您可以编辑您的答案以添加解释,并指出适用的限制和假设。- 来自审核 - Adam Marshall
考虑一下@Adam的评论。 - Akif
@Adam,我不确定这里是如何出现评论链接的。但由于“Late Answers”不是由多个用户完成的,也就是说它不是一个需要多个审阅者随时间完成的过程,所以在这里留下链接似乎有点奇怪。 - Scratte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接