我正在做一个 NLog 记录器包装 dll 以在某些项目中使用,我想提供多个选项来加载配置文件。
app.config
设置中指定的 Nlog 配置文件路径。NLog 记录器提供程序类
public NLogLoggerProvider(LoggerProviderOptions options)
{
_options = options;
_logFactory = BuildLogFactory();
}
private LogFactory BuildLogFactory()
{
LogFactory factory = null;
if (LogManager.Configuration != null)
{
factory = LogManager.LogFactory;
}
else
{
factory = new LogFactory();
LoadNLogConfigurationOnFactory(factory);
}
ApplyDefaultConfigurationIfNeeded(factory);
return factory;
}
private void LoadNLogConfigurationOnFactory(LogFactory nlogFactory)
{
try
{
var nlogConfigFilePath = GetNLogConfigurationFilePath();
if (nlogConfigFilePath != null)
{
var loggingConfiguration = new XmlLoggingConfiguration(nlogConfigFilePath);
nlogFactory.Configuration = loggingConfiguration;
}
}
catch (Exception ex)
{
ApplyDefaultConfigurationIfNeeded(nlogFactory);
}
}
/// <summary>
/// Get NLog config file to load in the following order
/// <br /> 1. File Specified in LoggerProvider options
/// <br /> 2. Path specified in App config setting named 'NLogConfigFile'
/// <br /> 3. EntryAssembly path /Configuration/Sedecal.Crosscutting.Logging.NLog.config
/// <br /> 4. Default exe config file path
/// </summary>
/// <returns>Nlog config file to load</returns>
private string GetNLogConfigurationFilePath()
{
var appConfigNLogConfigFile = ConfigurationManager.AppSettings[APP_CONFIG_NLOG_CONFIG_PATH];
var defaultNLogConfigFile = GetDefaultConfigFile();
var exeConfigurationFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath;
if (!_options.LogConfigFilePath.IsEmpty() && File.Exists(_options.LogConfigFilePath))
{
return _options.LogConfigFilePath;
}
else if (!appConfigNLogConfigFile.IsEmpty() && File.Exists(appConfigNLogConfigFile))
{
return appConfigNLogConfigFile;
}
else if (File.Exists(defaultNLogConfigFile))
{
return defaultNLogConfigFile;
}
else if (File.Exists(exeConfigurationFile))
{
return exeConfigurationFile;
}
else
{
return null;
}
}
private string GetDefaultConfigFile()
{
var entryAssemblyLocation = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var configFilePath = Path.Combine(entryAssemblyLocation, CONFIGURATION_DIRECTORY, NLOG_CONFIG_FILE);
return configFilePath;
}
private void ApplyDefaultConfigurationIfNeeded(LogFactory nlogFactory)
{
if(nlogFactory.Configuration == null || !nlogFactory.Configuration.AllTargets.Any())
{
nlogFactory.Configuration = GetDefaultLogConfiguration();
}
}
private LoggingConfiguration GetDefaultLogConfiguration()
{
var config = new LoggingConfiguration();
//Create file target and rule to file target
return config;
}
我的问题是关于配置加载的。我就是这样做的
var configuration = new XmlLoggingConfiguration(filePath);
var logFactory = new LogFactory();
logFactory.Configuration = configuration;
但是我看到还有其他方法在
XmlLoggingConfiguration
构造函数中接收LogFactory。但是调试它们我发现工厂配置没有被修改。创建配置并将其加载到工厂的最佳方法是什么?
有没有比检查是否有目标更好的方法来检查配置是否正确加载?
创建配置并将其加载到工厂的最佳方法是什么?
var logFactory = new LogFactory();
logFactory.LoadConfiguration(filePath);
实际上,此方法与您的代码执行相同的操作,但它还允许为不同的极端情况设置行为。这是 GitHub 上的源代码
有没有比检查是否有目标更好的方法来检查配置是否正确加载?
那是不必要的。如果配置有错误,
XmlLoggingConfiguration
默认抛出异常。您可以再次使用源代码进行检查。这会被您未传递的构造函数参数 ignoreErrors
关闭,就像 logFactory.LoadConfiguration
一样
当使用隔离 LogFactory 实例(而不是
NLog.LogManager
-单例)时,建议通过将隔离 LogFactory 作为输入参数传递来构造 LoggingConfiguration
:
private LoggingConfiguration GetDefaultLogConfiguration(LogFactory logFactory)
{
var config = new LoggingConfiguration(logFactory);
//Create file target and rule to file target
return config;
}
当使用
XmlLoggingConfiguration
从 XML 文件加载 NLog 配置时,还建议通过传递隔离 LogFactory 作为输入参数来构造 XmlLoggingConfiguration
:
var logFactory = new LogFactory();
var configuration = new XmlLoggingConfiguration(filePath, logFactory);
logFactory.Configuration = configuration;
当使用隔离的
LogFactory
时,它会提供更可预测的行为以将其提供为输入参数,因为 XmlLoggingConfiguration
能够更新 LogFactory
属性。
请注意,引用
NLog.LogManager.Configuration
-property 时,它将自动从 NLog 默认路径加载。
private LogFactory BuildLogFactory()
{
LogFactory factory = null;
if (LogManager.Configuration != null)
{
factory = LogManager.LogFactory;
}
else
{
factory = new LogFactory();
LoadNLogConfigurationOnFactory(factory);
}
ApplyDefaultConfigurationIfNeeded(factory);
return factory;
}