Я написал эту реализацию, чтобы изменить уровень журнала во время выполнения и сохранить новый порог обратно в app.config (фактически это Application.exe.config).
Интерфейс:
internal interface ILoggingConfiguration
{
void SetLogLevel(string level);
string GetLogLevel();
}
Реализация:
internal sealed class LoggingConfigurationImpl : ILoggingConfiguration
{
#region Members
private static readonly ILog _logger =
ObjectManager.Common.Logger.GetLogger();
private const string DEFAULT_NAME_SPACE = "Default.Name.Space";
#endregion
#region Implementation of ILoggingConfiguration
public void SetLogLevel(string level)
{
Level threshold = Log4NetUtils.ConvertToLevel(level);
ILoggerRepository[] repositories = LogManager.GetAllRepositories();
foreach (ILoggerRepository repository in repositories)
{
try
{
SetLogLevelOnRepository(repository, threshold);
}
catch (Exception ex)
{
_logger.ErrorFormat("Exception while changing log-level: {0}", ex);
}
}
PersistLogLevel(level);
}
public string GetLogLevel()
{
ILoggerRepository repository = LogManager.GetRepository();
Hierarchy hierarchy = (Hierarchy) repository;
ILogger logger = hierarchy.GetLogger(DEFAULT_NAME_SPACE);
return ((Logger) logger).Level.DisplayName;
}
private void SetLogLevelOnRepository(ILoggerRepository repository,
Level threshold)
{
repository.Threshold = threshold;
Hierarchy hierarchy = (Hierarchy)repository;
ILogger[] loggers = hierarchy.GetCurrentLoggers();
foreach (ILogger logger in loggers)
{
try
{
SetLogLevelOnLogger(threshold, logger);
}
catch (Exception ex)
{
_logger.ErrorFormat("Exception while changing log-level for
logger: {0}{1}{2}", logger, Environment.NewLine, ex);
}
}
}
private void SetLogLevelOnLogger(Level threshold, ILogger logger)
{
((Logger)logger).Level = threshold;
}
private void PersistLogLevel(string level)
{
XmlDocument config = new XmlDocument();
config.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
string xpath =
String.Format("configuration/log4net/logger[@name='{0}']/level",
DEFAULT_NAME_SPACE);
XmlNode rootLoggerNode = config.SelectSingleNode(xpath);
try
{
rootLoggerNode.Attributes["value"].Value = level;
config.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
ConfigurationManager.RefreshSection("log4net");
}
catch(Exception ex)
{
_logger.ErrorFormat("error while persisting new log-level: {0}", ex);
}
}
#endregion
}
Вспомогательный класс Log4NetUtils:
public sealed class Log4NetUtils
{
private static readonly ILoggerRepository _loggerRepository =
LoggerManager.GetAllRepositories().First();
public static Level ConvertToLevel(string level)
{
return _loggerRepository.LevelMap[level];
}
}
Код XAML:
<ComboBox Name="cbxLogLevel" Text="{Binding LogLevel}">
<ComboBoxItem Content="DEBUG" />
<ComboBoxItem Content="INFO" />
<ComboBoxItem Content="WARN" />
<ComboBoxItem Content="ERROR" />
</ComboBox>
<Button Name="btnChangeLogLevel"
Command="{Binding SetLogLevelCommand}"
CommandParameter="{Binding ElementName=cbxLogLevel, Path=Text}" >
Change log level
</Button>