.NET Core引入日志(Log4Net篇)
Demo版本信息如下:
VS:2019
框架:.Net Core 3.1
Log4Net:2.0.12
思维导图:

【1】添加依赖项
通过nuget添加Log4Net
【2】创建公共类
添加公共类Log4NetLogger,实现ILogger, ILoggerProvider,扩展方法Log4netExtensions
////// ILogger /// public class Log4NetLogger : ILogger { private readonly ILog _log; private ILoggerRepository _loggerRepository; public Log4NetLogger(string 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 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 (LogLevel logLevel, EventId eventId, TState state, Exception exception, Func 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 /// 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"]; } } /// /// 扩展方法 Log4netExtensions /// 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; } }
【3】Startup
在Startup中注册log4net

【5】配置文件
添加log4Net.config配置文件,需要注意,log4Net.config文件一定要放在项目的根目录,其次,“属性”—“复制到输出目录”要设置为“始终复制”
<?xml version="1.0" encoding="utf-8" ?>"ErrorRollingFileAppender" type="log4net.Appender.RollingFileAppender"> "D://log//Error//" /> "true" /> "Date"/> "yyyy-MM-dd'.log'"/> "100" /> "false" /> "utf-8" /> "log4net.Layout.PatternLayout"> "%newline%date [%thread %-5level] %n -- %m%n" /> "log4net.Filter.LevelRangeFilter"> "ERROR" /> "FATAL" /> "WarnRollingFileAppender" type="log4net.Appender.RollingFileAppender"> "D://log//Warn//" /> "true" /> "Date"/> "yyyy-MM-dd'.log'"/> "100" /> "false" /> "utf-8" /> "log4net.Layout.PatternLayout"> "%newline%date [%thread %-5level] %n -- %m%n" /> "log4net.Filter.LevelRangeFilter"> "WARN" /> "WARN" /> "InfoRollingFileAppender" type="log4net.Appender.RollingFileAppender"> "D://log//Info//" /> "true" /> "Date"/> "yyyy-MM-dd'.log'"/> "100" /> "false" /> "utf-8" /> "log4net.Layout.PatternLayout"> "%newline%date [%thread %-5level] %n -- %m%n" /> "log4net.Filter.LevelRangeFilter"> "TRACE " /> "INFO" /> "All" /> ref ref="ErrorRollingFileAppender" /> ref ref="WarnRollingFileAppender" /> ref ref="InfoRollingFileAppender" />
【6】测试
此Demo通过MVC实现测试,所以需要添加控制器与视图。
1、同时在Startup中注册MVC相关服务,services.AddControllersWithViews();

2、更改Configure中的UseEndpoints请求为MVC路由配置

app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}" ); });
3、控制器中获取对象
private readonly ILogger _logger; ////// **************通过构造方法获取注册的Log4Net服务 /// /// public HomeController(ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger (); }
4、调用
public IActionResult Index() { //************** 日志对象的引用 _logger.LogInformation($"这是一个一般的日志消息"); _logger.LogWarning($"这是一个警告的日志消息"); _logger.LogError($"这是一个错误的日志消息"); return View(); }