मैं इस कार्यान्वयन रनटाइम पर लॉग स्तर को बदलने और नए treshold 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>
.NET 4.0 का उपयोग करना और VS2013update4 यह मेरे लिए ठीक काम करता है। यानी मैं बस डिस्क पर app.config फ़ाइल को संशोधित करने के बाद ConfigurationManager.RefreshSection ("appSettings") को कॉल कर रहा हूं और यह सेटिंग्स को सही ढंग से पुनः लोड करता है। –
छोटे विवरण गायब हैं: कॉन्फ़िगरेशन मैनेजर के बाद। रीफ्रेशसेक्शन ("ऐपसेटिंग") चीज आपको कॉन्फ़िगरेशन = कॉन्फ़िगरेशन मैनेजर को खोलना है। ओपनएक्स कॉन्फ़िगरेशन (एप्लिकेशन.एक्सटेबलपेथ) –