I am trying to group all configuration and log files of my application in one base folder (C:\MY_PRODUCT\ ) to have the following structure:
C:\MY_PRODUCT\CONFIGURATION\
C:\MY_PRODUCT\LOGS\
...
I am using log4net for logging, and using the environment variables in log4net FileAppender configuration works correctly:
<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>
However, by separating the log4net configuration in new file (C:\MY_PRODUCT\CONFIGURATION\Log4Net.config), the log4net is unable to locate this configuration file when using the environment variable by setting the property ConfigSource:
<log4net configSource="${PRODUCT_BASE}\CONFIGURATION\Log4Net.config" />
Note that the if i replace ${PRODUCT_BASE} environment variable by its value (the path C:\MY_PRODUCT) it works correctly and log4net is able to find the config file.
Log4Net logs :
I enabled the log4net debug mode to see whats happen, and i got the following errors:
log4net:ERROR Failed to parse config file. Is the specified as: System.Configuration.ConfigurationErrorsException: Unable to open configSource file '${PRODUCT_BASE}\config\Log4Net.config'. (Tests\bin\Debug\MY_PRODUCT.Core.Tests.dll.config line 10) at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult) at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSection(String configKey) at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName) at System.Configuration.ConfigurationManager.GetSection(String sectionName) at log4net.Config.XmlConfigurator.InternalConfigure(ILoggerRepository repository)
I don't know if Log4Net is expanding the environment variable of the property ConfigSource, i already posted the issue on Apache Log4Net issues platform, until they answer or solve the issue, is there any way to achieve this approach ?