有点晚,但最近才遇到这个问题,原来.NET Standard框架下不支持某些模式。
根据 Apache 的documentation,不支持这些功能:
- ADO.NET 附加程序
- 与 ASP.NET 相关的任何内容(trace appender 和 几个模式转换器)
- .NET 远程处理
- 彩色控制台附加程序
- 事件日志附加器
- NetSendAppender
- SMTP 附加程序
- DOMConfigurator
- 堆栈跟踪模式
- 访问 appSettings(既不使用 log4net 部分本身,也不使用 AppSettingsPatternConverter)
- 使用 EnvironmentFolderPathPatternConverter 访问“特殊路径”
- 模拟 Windows 帐户
有两种解决方法:
- 使用 C# 5.0 的 Caller Info attributes 和自定义日志包装器,这里有一些很好的例子:
- 使用
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!
尚未完全测试,但目前这两种方法都运行良好,
尽管它们之间存在一些差异:
希望这会有所帮助。
提米。