【问题标题】:log4net conversion pattern not working with Asp.net Corelog4net 转换模式不适用于 Asp.net Core
【发布时间】:2017-12-13 12:37:53
【问题描述】:

我在 Asp.Net Web API Core 2.0 中使用 log4net-core-preview(2.0.6),我的 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 [? ?] , 一些信息

谁能告诉我这里出了什么问题

谢谢

【问题讨论】:

    标签: asp.net-web-api asp.net-core log4net .net-standard


    【解决方案1】:

    有点晚,但最近才遇到这个问题,原来.NET Standard框架下不支持某些模式。

    根据 Apache 的documentation,不支持这些功能:

    • ADO.NET 附加程序
    • 与 ASP.NET 相关的任何内容(trace appender几个模式转换器
    • .NET 远程处理
    • 彩色控制台附加程序
    • 事件日志附加器
    • NetSendAppender
    • SMTP 附加程序
    • DOMConfigurator
    • 堆栈跟踪模式
    • 访问 appSettings(既不使用 log4net 部分本身,也不使用 AppSettingsPatternConverter)
    • 使用 EnvironmentFolderPathPatternConverter 访问“特殊路径”
    • 模拟 Windows 帐户

    有两种解决方法:

    1. 使用 C# 5.0 的 Caller Info attributes 和自定义日志包装器,这里有一些很好的例子:
    2. 使用StackTrace (.NET Standard 2.0 and later required) 创建自定义PatternConverter,如下所示

    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!
    

    尚未完全测试,但目前这两种方法都运行良好, 尽管它们之间存在一些差异:

    希望这会有所帮助。

    提米。

    【讨论】:

    • 只是在链接时给其他人的注释layout type=是“FullClassPath, Assembly
    • 它不适用于 ASP.NET Core 和 Microsoft.Extensions.Logging.ILogger :(
    【解决方案2】:

    【讨论】:

    • - 虽然您的回答可能会解决问题,但 including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。您可以编辑您的答案以添加解释并指出适用的限制和假设。 - From Review
    • 考虑@Adam 的评论。
    • @Adam 我不确定评论的链接是如何出现在这里的。但由于迟到的答案不是由多个用户完成的,这意味着它不是一个涉及多个审阅者的过程,随着时间的推移完成,留下一个链接似乎有点奇怪。
    猜你喜欢
    • 2011-02-04
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多