我在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帐户
有两个解决方法:
- 使用自定义日志包装器使用C#5.0的呼叫者信息属性,这里有一些很好的示例:
- 使用C#5.0呼叫者信息属性进行改进记录
- 学习如何使用log4net登录.net
- 使用
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;