https://dotnetthoughts.net/how-to-use-log4net-with-aspnetcore-for-logging/
这篇文章是关于使用 Log4Net 和 ASP.NET Core 来实现日志记录的。Apache log4net 库是帮助程序员将日志语句输出到各种输出目标的工具。log4net 是优秀的 Apache log4j™ 框架到 Microsoft® .NET 运行时的一个端口。我们在利用 .NET 运行时中的新功能的同时,使框架在精神上与原始 log4j 相似。
首先需要在 project.json 文件中添加 log4net 库的引用。我正在使用”log4net”:”2.0.7”. 现在您可以使用 log4net 编写代码。我正在 Program.cs 文件中编写代码。与 ASP.NET 不同,log4net 不支持加载配置的属性,因此需要手动加载配置。这是我正在使用的示例 log4net 配置文件,它将使用FileAppender. 我正在记录所有信息。您可以在 log4net 文档中找到有关日志记录提供程序和级别的更多信息。
<?xml version="1.0" encoding="utf-8" ?><log4net><appender name="RollingFile" type="log4net.Appender.FileAppender"><file value="C:\Temp\app.log" /><layout type="log4net.Layout.PatternLayout"><conversionPattern value="%-5p %d{hh:mm:ss} %message%newline" /></layout></appender><root><level value="ALL" /><appender-ref ref="RollingFile" /></root></log4net>
这是 program.cs 文件,它获取 ILog 对象的实例并手动加载配置。
public class Program{private static readonly log4net.ILog log =log4net.LogManager.GetLogger(typeof(Program));public static void Main(string[] args){XmlDocument log4netConfig = new XmlDocument();log4netConfig.Load(File.OpenRead("log4net.config"));var repo = log4net.LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));log4net.Config.XmlConfigurator.Configure(repo, log4netConfig["log4net"]);log.Info("Application - Main is invoked");//Lines removed for brevity}}
在根文件夹中添加的 log4net.config 文件。现在您可以运行该应用程序,您会看到在 C:\temp 文件夹中创建了一个名为 app.log 的文件。如果您查看它,您只会看到添加了我们记录的信息。但是如果你想要类似于 ASP.NET Core 日志的东西,你需要自己实现提供者和扩展方法。
这是实现,它可以帮助您进行类似于现有 ASP.NET Core 日志记录实现的日志记录。
首先,您需要使用 Log4Net 库实现 ILogger 接口。这是实现。
public class Log4NetLogger : ILogger{private readonly string _name;private readonly XmlElement _xmlElement;private readonly ILog _log;private ILoggerRepository _loggerRepository;public Log4NetLogger(string name, XmlElement xmlElement){_name = name;_xmlElement = xmlElement;_loggerRepository = log4net.LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));_log = LogManager.GetLogger(_loggerRepository.Name, name);log4net.Config.XmlConfigurator.Configure(_loggerRepository, xmlElement);}public IDisposable BeginScope<TState>(TState state){return null;}public bool IsEnabled(LogLevel logLevel){switch (logLevel){case LogLevel.Critical:return _log.IsFatalEnabled;case LogLevel.Debug:case LogLevel.Trace:return _log.IsDebugEnabled;case LogLevel.Error:return _log.IsErrorEnabled;case LogLevel.Information:return _log.IsInfoEnabled;case LogLevel.Warning:return _log.IsWarnEnabled;default:throw new ArgumentOutOfRangeException(nameof(logLevel));}}public void Log<TState>(LogLevel logLevel, EventId eventId, TState state,Exception exception, Func<TState, Exception, string> formatter){if (!IsEnabled(logLevel)){return;}if (formatter == null){throw new ArgumentNullException(nameof(formatter));}string message = null;if (null != formatter){message = formatter(state, exception);}if (!string.IsNullOrEmpty(message) || exception != null){switch (logLevel){case LogLevel.Critical:_log.Fatal(message);break;case LogLevel.Debug:case LogLevel.Trace:_log.Debug(message);break;case LogLevel.Error:_log.Error(message);break;case LogLevel.Information:_log.Info(message);break;case LogLevel.Warning:_log.Warn(message);break;default:_log.Warn($"Encountered unknown log level {logLevel}, writing out as Info.");_log.Info(message, exception);break;}}}}
并且需要使用 ILoggerProvider 实现将此记录器提供给记录器工厂扩展。这是 ILoggerProvider 实现。我从 ASP.NET Core 实现的控制台记录器提供程序实现中获取的大部分代码。配置解析在这个类内部实现。
public class Log4NetProvider : ILoggerProvider{private readonly string _log4NetConfigFile;private readonly ConcurrentDictionary<string, Log4NetLogger> _loggers =new ConcurrentDictionary<string, Log4NetLogger>();public Log4NetProvider(string log4NetConfigFile){_log4NetConfigFile = log4NetConfigFile;}public ILogger CreateLogger(string categoryName){return _loggers.GetOrAdd(categoryName, CreateLoggerImplementation);}public void Dispose(){_loggers.Clear();}private Log4NetLogger CreateLoggerImplementation(string name){return new Log4NetLogger(name, Parselog4NetConfigFile(_log4NetConfigFile));}private static XmlElement Parselog4NetConfigFile(string filename){XmlDocument log4netConfig = new XmlDocument();log4netConfig.Load(File.OpenRead(filename));return log4netConfig["log4net"];}}
最后,您需要 ILoggerFactory 扩展方法,这有助于将 Log4Net 添加到记录器工厂。这是扩展方法的实现。
public static class Log4netExtensions{public static ILoggerFactory AddLog4Net(this ILoggerFactory factory, string log4NetConfigFile){factory.AddProvider(new Log4NetProvider(log4NetConfigFile));return factory;}public static ILoggerFactory AddLog4Net(this ILoggerFactory factory){factory.AddProvider(new Log4NetProvider("log4net.config"));return factory;}}
你可以使用这个内部Configure()方法。
public void Configure(IApplicationBuilder app,IHostingEnvironment env, ILoggerFactory loggerFactory){loggerFactory.AddLog4Net();if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseMvcWithDefaultRoute();}
现在您可以再次运行该应用程序,您可以看到充满大量日志记录详细信息的日志文件。
这是 log4net 创建的日志文件的屏幕截图。
