如何为两个独立DLL的不同命名空间配置同一log4net Appender
为不同命名空间的类配置同一个log4net Appender的简便方案
针对你遇到的问题,这里有两种高效的解决方案,无需重复配置Logger、无需硬编码相同的日志名称,同时能统一控制日志阈值:
方案一:利用log4net的Logger层级继承(推荐)
因为你的两个类都隶属于WPF开头的命名空间,log4net的Logger会按照命名空间层级自动继承配置。你只需要在配置文件中定义一个顶层的WPF Logger,将Appender和统一的阈值配置在这里,所有WPF子命名空间下的类都会自动继承该配置。
配置文件示例
<log4net> <!-- 定义共享的Appender --> <appender name="SharedFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="shared_app.log" /> <appendToFile value="true" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="5" /> <maximumFileSize value="10MB" /> <staticLogFileName value="true" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" /> </layout> </appender> <!-- 配置顶层WPF Logger,所有WPF.*命名空间的类都会继承 --> <logger name="WPF"> <appender-ref ref="SharedFileAppender" /> <!-- 统一设置日志级别,后续只需修改这里即可 --> <level value="Info" /> <!-- 关闭Root Logger的继承,避免日志重复输出 --> <additivity value="false" /> </logger> </log4net>
代码实现
两个类中保持默认的Logger初始化方式即可,无需硬编码相同的字符串:
// WPF.Client.Foo类中 private static readonly ILog log = LogManager.GetLogger(typeof(Foo)); // WPF.Server.Foo类中 private static readonly ILog log = LogManager.GetLogger(typeof(Foo));
这种方式的优势:
- 后续新增
WPF开头的命名空间类时,无需修改配置文件,自动继承共享Appender - 日志阈值只需在
WPFLogger中配置一次,统一生效 - 代码保持原有结构,无需额外修改
方案二:使用Logger匹配Filter(适用于无共同命名空间前缀的场景)
如果后续新增的类不属于WPF命名空间,你可以在Appender中配置LoggerMatchFilter,指定需要匹配的Logger名称(即类的全名),只有匹配的Logger才会输出到该Appender。
配置文件示例
<log4net> <appender name="SharedFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="shared_app.log" /> <appendToFile value="true" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="5" /> <maximumFileSize value="10MB" /> <staticLogFileName value="true" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" /> </layout> <!-- 匹配指定的Logger --> <filter type="log4net.Filter.LoggerMatchFilter"> <loggerToMatch value="WPF.Client.Foo" /> <acceptOnMatch value="true" /> </filter> <filter type="log4net.Filter.LoggerMatchFilter"> <loggerToMatch value="WPF.Server.Foo" /> <acceptOnMatch value="true" /> </filter> <!-- 拒绝其他所有Logger的输出 --> <filter type="log4net.Filter.DenyAllFilter" /> </appender> <!-- 让Root Logger引用该Appender,或者直接配置单个Logger引用 --> <root> <appender-ref ref="SharedFileAppender" /> <level value="Info" /> </root> </log4net>
这种方式需要新增类时更新Filter列表,但好处是不受命名空间限制,适合零散的类需要共享Appender的场景。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

