log4net转换模式与ASP.NET核心不使用



我在ASP.NET Web API Core 2.0中使用Log4Nnet core-preview(2.0.6),而我的log4net config布局是

 <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 [??],, somemessage

任何人都可以告诉我这里怎么了

谢谢

有点迟到,但最近才遇到这个问题,事实证明,某些模式是不支持.NET标准框架的

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

  • ado.net appender
  • 与ASP.NET相关的任何内容(跟踪Appender 几个模式转换器
  • .net远程
  • 彩色控制台appender
  • 事件日志appender
  • NetSendAppender
  • SMTP Appender
  • domconfigurator
  • 堆栈跟踪模式
  • 访问appSettings(log4net部分本身也不使用AppSettingsPatternConverter)
  • 使用Environment -FolderPathPatternConverter
  • 访问"特殊路径"
  • 模仿Windows帐户

有两个解决方法:

  1. 使用自定义日志包装器使用C#5.0的呼叫者信息属性,这里有一些很好的示例:
    • 使用C#5.0呼叫者信息属性进行改进记录
    • 学习如何使用log4net登录.net
  2. 使用StackTrace创建自定义PatternConverter(.NET标准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!

尚未完全测试,但是两种方法都可以很好地工作,到目前为止尽管它们之间有一些区别:

  • Caller info attribute只能获取文件路径,StackTrace可以获取AssemblyQualifiedName或使用DeclaringType.FullName的名称空间,提供更多信息。
  • 呼叫者信息属性可能具有更好的性能

希望这会有所帮助。

蒂米。

https://github.com/robsonj/log4net.appenders

用法:&lt; appender name =; eventlogappender;

最新更新