使用带有环境变量的外部 log4net 配置文件

Use external log4net configuration file with environment variables

我正在尝试将我的应用程序的所有配置和日志文件分组到一个基本文件夹 (C:\MY_PRODUCT\ ) 中以具有以下结构:

C:\MY_PRODUCT\CONFIGURATION\
C:\MY_PRODUCT\LOGS\
...

我正在使用 log4net 进行日志记录,并且在 log4net FileAppender 配置中使用环境变量工作正常:

<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
<file value="${PRODUCT_BASE}\LOGS\file.log" />
<threshold value="ALL" />
<appendToFile value="true" />
<maximumFileSize value="10MB" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="200" />
<layout type="log4net.Layout.PatternLayout">
  <conversionPattern value="[%date{O}] [%-5level] [%-3thread] [%logger] [%method] %message%newline" />
</layout>

但是,通过在新文件(C:\MY_PRODUCT\CONFIGURATION\Log4Net.config)中分离 log4net 配置,通过设置 属性 配置源:

<log4net configSource="${PRODUCT_BASE}\CONFIGURATION\Log4Net.config" />

请注意,如果我用它的值(路径 C:\MY_PRODUCT)替换 ${PRODUCT_BASE} 环境变量,它会正常工作并且 log4net 能够找到配置文件。

Log4Net 日志:

我启用了 log4net 调试模式以查看发生了什么,我收到以下错误:

log4net:错误无法解析配置文件。是否指定为: System.Configuration.ConfigurationErrorsException: 无法打开配置源文件“${PRODUCT_BASE}\config\Log4Net.config”。 (Tests\bin\Debug\MY_PRODUCT.Core.Tests.dll.config 第 10 行) 在 System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] 键,SectionInput 输入,Boolean isTrusted,FactoryRecord factoryRecord,SectionRecord sectionRecord,Object parentResult) 在 System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject) 在 System.Configuration.BaseConfigurationRecord.GetSectionRecursive(字符串 configKey、布尔值 getLkg、布尔值 checkPermission、布尔值 getRuntimeObject、布尔值 requestIsHere、对象和结果、对象和结果运行时对象) 在 System.Configuration.BaseConfigurationRecord.GetSectionRecursive(字符串 configKey、布尔值 getLkg、布尔值 checkPermission、布尔值 getRuntimeObject、布尔值 requestIsHere、对象和结果、对象和结果运行时对象) 在 System.Configuration.BaseConfigurationRecord.GetSectionRecursive(字符串 configKey、布尔值 getLkg、布尔值 checkPermission、布尔值 getRuntimeObject、布尔值 requestIsHere、对象和结果、对象和结果运行时对象) 在 System.Configuration.BaseConfigurationRecord.GetSection(字符串配置键) 在 System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(字符串部分名称) 在 System.Configuration.ConfigurationManager.GetSection(字符串部分名称) 在 log4net.Config.XmlConfigurator.InternalConfigure(ILoggerRepository 存储库)

我不知道Log4Net是否扩展了属性 ConfigSource的环境变量,我已经在Apache Log4Net问题平台上发布了这个问题,直到他们回答或解决问题,有没有办法实现这种方法?

谷歌搜索后,这似乎不是 Log4Net 问题,正如他们在 msdn post 上所说:

No, that can't be done natively.

我最后在 app.config 中添加了一个新的应用程序设置:

<add key="log4net.config" value="%PRODUCT_BASE%\config\Log4Net.config"/>

并且在启动时配置 log4net 时:

string log4NetConfigFile = ConfigurationManager.AppSettings["log4net.config"];
        var fileInfo = new FileInfo(Environment.ExpandEnvironmentVariables(log4NetConfigFile));
        XmlConfigurator.Configure(fileInfo);

希望这对遇到同样问题的其他人有所帮助。