in src/log4net/Core/DefaultRepositorySelector.cs [550:663]
private static void ConfigureRepository(Assembly assembly, ILoggerRepository repository)
{
repository.EnsureNotNull();
// Look for the Configurator attributes (e.g. XmlConfiguratorAttribute) on the assembly
ConfiguratorAttribute[] configAttributes = Attribute.GetCustomAttributes(assembly.EnsureNotNull(), typeof(ConfiguratorAttribute), false)
.EnsureIs<ConfiguratorAttribute[]>();
if (configAttributes.Length > 0)
{
// Sort the ConfiguratorAttributes in priority order
Array.Sort(configAttributes);
// Delegate to the attribute the job of configuring the repository
foreach (ConfiguratorAttribute configAttr in configAttributes)
{
try
{
configAttr.Configure(assembly, repository);
}
catch (Exception e) when (!e.IsFatal())
{
LogLog.Error(_declaringType, $"Exception calling [{configAttr.GetType().FullName}] .Configure method.", e);
}
}
}
if (repository.Name == DefaultRepositoryName)
{
// Try to configure the default repository using an AppSettings specified config file
// Do this even if the repository has been configured (or claims to be), this allows overriding
// of the default config files etc., if that is required.
string? repositoryConfigFile = SystemInfo.GetAppSetting("log4net.Config");
if (repositoryConfigFile is not null && repositoryConfigFile.Length > 0)
{
string? applicationBaseDirectory = null;
try
{
applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory;
}
catch (Exception e) when (!e.IsFatal())
{
LogLog.Warn(_declaringType, $"Exception getting ApplicationBaseDirectory. appSettings log4net.Config path [{repositoryConfigFile}] will be treated as an absolute URI", e);
}
string repositoryConfigFilePath = repositoryConfigFile;
if (applicationBaseDirectory is not null)
{
repositoryConfigFilePath = Path.Combine(applicationBaseDirectory, repositoryConfigFile);
}
// Determine whether to watch the file or not based on an app setting value:
bool.TryParse(SystemInfo.GetAppSetting("log4net.Config.Watch"), out bool watchRepositoryConfigFile);
if (watchRepositoryConfigFile)
{
// As we are going to watch the config file it is required to resolve it as a
// physical file system path pass that in a FileInfo object to the Configurator
FileInfo? repositoryConfigFileInfo = null;
try
{
repositoryConfigFileInfo = new FileInfo(repositoryConfigFilePath);
}
catch (Exception e) when (!e.IsFatal())
{
LogLog.Error(_declaringType, $"DefaultRepositorySelector: Exception while parsing log4net.Config file physical path [{repositoryConfigFilePath}]", e);
}
if (repositoryConfigFileInfo is not null)
{
try
{
LogLog.Debug(_declaringType, $"Loading and watching configuration for default repository from AppSettings specified Config path [{repositoryConfigFilePath}]");
XmlConfigurator.ConfigureAndWatch(repository, repositoryConfigFileInfo);
}
catch (Exception e) when (!e.IsFatal())
{
LogLog.Error(_declaringType, $"DefaultRepositorySelector: Exception calling XmlConfigurator.ConfigureAndWatch method with ConfigFilePath [{repositoryConfigFilePath}]", e);
}
}
}
else
{
// As we are not going to watch the config file it is easiest to just resolve it as a
// URI and pass that to the Configurator
Uri? repositoryConfigUri = null;
try
{
repositoryConfigUri = new Uri(repositoryConfigFilePath);
}
catch (Exception e) when (!e.IsFatal())
{
LogLog.Error(_declaringType, $"Exception while parsing log4net.Config file path [{repositoryConfigFile}]", e);
}
if (repositoryConfigUri is not null)
{
LogLog.Debug(_declaringType, $"Loading configuration for default repository from AppSettings specified Config URI [{repositoryConfigUri}]");
try
{
// TODO: Support other types of configurator
XmlConfigurator.Configure(repository, repositoryConfigUri);
}
catch (Exception e) when (!e.IsFatal())
{
LogLog.Error(_declaringType, $"Exception calling XmlConfigurator.Configure method with ConfigUri [{repositoryConfigUri}]", e);
}
}
}
}
}
}