使用Microsoft.Extensions.Logging.Abstractions结合Log4Net实现多日志文件输出
解决Microsoft.Extensions.Logging结合Log4Net分文件输出日志的方案
方案1:通过命名Logger+Log4Net配置映射实现
原生Log4Net的命名Logger可以绑定特定Appender,在Microsoft.Extensions.Logging中,我们可以通过创建带分类名称的ILogger,配合Log4Net配置文件里的分类Logger节点,实现日志分文件输出。
操作步骤:
- 修改Log4Net配置文件,定义多个RollingFileAppender,同时创建对应分类的Logger节点并绑定专属Appender:
<log4net> <!-- 业务日志Appender --> <appender name="BusinessAppender" type="log4net.Appender.RollingFileAppender"> <file value="Logs/Business.log" /> <appendToFile value="true" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="10" /> <maximumFileSize value="10MB" /> <staticLogFileName value="true" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" /> </layout> </appender> <!-- 系统日志Appender --> <appender name="SystemAppender" type="log4net.Appender.RollingFileAppender"> <file value="Logs/System.log" /> <appendToFile value="true" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="10" /> <maximumFileSize value="10MB" /> <staticLogFileName value="true" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" /> </layout> </appender> <!-- 业务分类Logger:仅输出到BusinessAppender --> <logger name="BusinessLogger" additivity="false"> <level value="INFO" /> <appender-ref ref="BusinessAppender" /> </logger> <!-- 系统分类Logger:仅输出到SystemAppender --> <logger name="SystemLogger" additivity="false"> <level value="DEBUG" /> <appender-ref ref="SystemAppender" /> </logger> <!-- 根Logger:处理未匹配分类的日志(可选) --> <root> <level value="ERROR" /> <appender-ref ref="BusinessAppender" /> </root> </log4net>
- 代码中通过
ILoggerFactory创建指定分类的ILogger:
- 代码中通过
// 初始化LoggerFactory并加载Log4Net配置 var loggerFactory = LoggerFactory.Create(builder => { builder.AddLog4Net("log4net.config"); }); // 创建业务日志实例 var businessLogger = loggerFactory.CreateLogger("BusinessLogger"); businessLogger.LogInformation("用户提交订单成功"); // 创建系统日志实例 var systemLogger = loggerFactory.CreateLogger("SystemLogger"); systemLogger.LogDebug("配置文件加载完成");
注:additivity="false"用于避免日志重复输出到根Logger的Appender。
方案2:自定义Log4NetProvider扩展Appender指定逻辑
如果需要动态指定Appender,可以自定义扩展方法,直接将Logger绑定到目标Appender。
操作步骤:
- 编写扩展方法实现动态绑定:
public static class Log4NetExtensions { public static ILogger CreateLoggerWithAppender(this ILoggerFactory factory, string appenderName) { var repo = log4net.LogManager.GetRepository(); var loggerName = $"Appender_{appenderName}"; // 若Logger不存在则动态创建并绑定Appender if (!repo.Exists(loggerName)) { var logger = repo.LoggerFactory.CreateLogger(loggerName); var targetAppender = repo.GetAppender(appenderName); if (targetAppender != null) { logger.AddAppender(targetAppender); logger.Level = log4net.Core.Level.All; logger.Repository.Configured = true; } } return factory.CreateLogger(loggerName); } }
- 使用扩展方法创建指定Appender的Logger:
var businessLogger = loggerFactory.CreateLoggerWithAppender("BusinessAppender"); businessLogger.LogInformation("业务日志直接输出到Business.log"); var systemLogger = loggerFactory.CreateLoggerWithAppender("SystemAppender"); systemLogger.LogDebug("系统日志直接输出到System.log");
方案3:通过Log4Net过滤器实现日志路由
无需创建多个命名Logger,利用Log4Net的过滤器,根据日志分类、级别等属性自动路由到对应Appender。
操作步骤:
- 在Log4Net配置中给每个Appender添加过滤器:
<appender name="BusinessAppender" type="log4net.Appender.RollingFileAppender"> <!-- 基础配置省略 --> <filter type="log4net.Filter.LoggerMatchFilter"> <loggerToMatch value="Business*" /> <!-- 匹配所有以Business开头的分类 --> <acceptOnMatch value="true" /> </filter> <filter type="log4net.Filter.DenyAllFilter" /> <!-- 拒绝其他日志 --> </appender> <appender name="SystemAppender" type="log4net.Appender.RollingFileAppender"> <!-- 基础配置省略 --> <filter type="log4net.Filter.LoggerMatchFilter"> <loggerToMatch value="System*" /> <!-- 匹配所有以System开头的分类 --> <acceptOnMatch value="true" /> </filter> <filter type="log4net.Filter.DenyAllFilter" /> </appender> <!-- 根Logger同时引用两个Appender,由过滤器路由 --> <root> <level value="ALL" /> <appender-ref ref="BusinessAppender" /> <appender-ref ref="SystemAppender" /> </root>
- 代码中创建对应分类的Logger:
var orderLogger = loggerFactory.CreateLogger("Business.OrderService"); orderLogger.LogInformation("订单ID:12345 已支付"); var configLogger = loggerFactory.CreateLogger("System.Configuration"); configLogger.LogDebug("数据库连接字符串加载完成");
内容的提问来源于stack exchange,提问作者Ron
相关产品推荐
相关产品推荐

