📄 xmlconfigurator.cs
字号:
// load the data into the document
doc.Load(xmlReader);
}
catch(Exception ex)
{
LogLog.Error("XmlConfigurator: Error while loading XML configuration", ex);
// The document is invalid
doc = null;
}
if (doc != null)
{
LogLog.Debug("XmlConfigurator: loading XML configuration");
// Configure using the 'log4net' element
XmlNodeList configNodeList = doc.GetElementsByTagName("log4net");
if (configNodeList.Count == 0)
{
LogLog.Debug("XmlConfigurator: XML configuration does not contain a <log4net> element. Configuration Aborted.");
}
else if (configNodeList.Count > 1)
{
LogLog.Error("XmlConfigurator: XML configuration contains [" + configNodeList.Count + "] <log4net> elements. Only one is allowed. Configuration Aborted.");
}
else
{
ConfigureFromXml(repository, configNodeList[0] as XmlElement);
}
}
}
}
#endregion Configure static methods
#region ConfigureAndWatch static methods
#if (!NETCF && !SSCLI)
/// <summary>
/// Configures log4net using the file specified, monitors the file for changes
/// and reloads the configuration if a change is detected.
/// </summary>
/// <param name="configFile">The XML file to load the configuration from.</param>
/// <remarks>
/// <para>
/// The configuration file must be valid XML. It must contain
/// at least one element called <c>log4net</c> that holds
/// the configuration data.
/// </para>
/// <para>
/// The configuration file will be monitored using a <see cref="FileSystemWatcher"/>
/// and depends on the behavior of that class.
/// </para>
/// <para>
/// For more information on how to configure log4net using
/// a separate configuration file, see <see cref="Configure(FileInfo)"/>.
/// </para>
/// </remarks>
/// <seealso cref="Configure(FileInfo)"/>
static public void ConfigureAndWatch(FileInfo configFile)
{
ConfigureAndWatch(LogManager.GetRepository(Assembly.GetCallingAssembly()), configFile);
}
/// <summary>
/// Configures the <see cref="ILoggerRepository"/> using the file specified,
/// monitors the file for changes and reloads the configuration if a change
/// is detected.
/// </summary>
/// <param name="repository">The repository to configure.</param>
/// <param name="configFile">The XML file to load the configuration from.</param>
/// <remarks>
/// <para>
/// The configuration file must be valid XML. It must contain
/// at least one element called <c>log4net</c> that holds
/// the configuration data.
/// </para>
/// <para>
/// The configuration file will be monitored using a <see cref="FileSystemWatcher"/>
/// and depends on the behavior of that class.
/// </para>
/// <para>
/// For more information on how to configure log4net using
/// a separate configuration file, see <see cref="Configure(FileInfo)"/>.
/// </para>
/// </remarks>
/// <seealso cref="Configure(FileInfo)"/>
static public void ConfigureAndWatch(ILoggerRepository repository, FileInfo configFile)
{
LogLog.Debug("XmlConfigurator: configuring repository [" + repository.Name + "] using file [" + configFile + "] watching for file updates");
if (configFile == null)
{
LogLog.Error("XmlConfigurator: ConfigureAndWatch called with null 'configFile' parameter");
}
else
{
// Configure log4net now
Configure(repository, configFile);
try
{
// Create a watch handler that will reload the
// configuration whenever the config file is modified.
ConfigureAndWatchHandler.StartWatching(repository, configFile);
}
catch(Exception ex)
{
LogLog.Error("XmlConfigurator: Failed to initialize configuration file watcher for file ["+configFile.FullName+"]", ex);
}
}
}
#endif
#endregion ConfigureAndWatch static methods
#region ConfigureAndWatchHandler
#if (!NETCF && !SSCLI)
/// <summary>
/// Class used to watch config files.
/// </summary>
/// <remarks>
/// <para>
/// Uses the <see cref="FileSystemWatcher"/> to monitor
/// changes to a specified file. Because multiple change notifications
/// may be raised when the file is modified, a timer is used to
/// compress the notifications into a single event. The timer
/// waits for <see cref="TimeoutMillis"/> time before delivering
/// the event notification. If any further <see cref="FileSystemWatcher"/>
/// change notifications arrive while the timer is waiting it
/// is reset and waits again for <see cref="TimeoutMillis"/> to
/// elapse.
/// </para>
/// </remarks>
private sealed class ConfigureAndWatchHandler
{
/// <summary>
/// Watch a specified config file used to configure a repository
/// </summary>
/// <param name="repository">The repository to configure.</param>
/// <param name="configFile">The configuration file to watch.</param>
/// <remarks>
/// <para>
/// Watch a specified config file used to configure a repository
/// </para>
/// </remarks>
internal static void StartWatching(ILoggerRepository repository, FileInfo configFile)
{
new ConfigureAndWatchHandler(repository, configFile);
}
/// <summary>
/// Holds the FileInfo used to configure the XmlConfigurator
/// </summary>
private FileInfo m_configFile;
/// <summary>
/// Holds the repository being configured.
/// </summary>
private ILoggerRepository m_repository;
/// <summary>
/// The timer used to compress the notification events.
/// </summary>
private Timer m_timer;
/// <summary>
/// The default amount of time to wait after receiving notification
/// before reloading the config file.
/// </summary>
private const int TimeoutMillis = 500;
/// <summary>
/// Initializes a new instance of the <see cref="ConfigureAndWatchHandler" /> class.
/// </summary>
/// <param name="repository">The repository to configure.</param>
/// <param name="configFile">The configuration file to watch.</param>
/// <remarks>
/// <para>
/// Initializes a new instance of the <see cref="ConfigureAndWatchHandler" /> class.
/// </para>
/// </remarks>
private ConfigureAndWatchHandler(ILoggerRepository repository, FileInfo configFile)
{
m_repository = repository;
m_configFile = configFile;
// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = m_configFile.DirectoryName;
watcher.Filter = m_configFile.Name;
// Set the notification filters
watcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.FileName;
// Add event handlers. OnChanged will do for all event handlers that fire a FileSystemEventArgs
watcher.Changed += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
watcher.Created += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
watcher.Deleted += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
watcher.Renamed += new RenamedEventHandler(ConfigureAndWatchHandler_OnRenamed);
// Begin watching.
watcher.EnableRaisingEvents = true;
// Create the timer that will be used to deliver events. Set as disabled
m_timer = new Timer(new TimerCallback(OnWatchedFileChange), null, Timeout.Infinite, Timeout.Infinite);
}
/// <summary>
/// Event handler used by <see cref="ConfigureAndWatchHandler"/>.
/// </summary>
/// <param name="source">The <see cref="FileSystemWatcher"/> firing the event.</param>
/// <param name="e">The argument indicates the file that caused the event to be fired.</param>
/// <remarks>
/// <para>
/// This handler reloads the configuration from the file when the event is fired.
/// </para>
/// </remarks>
private void ConfigureAndWatchHandler_OnChanged(object source, FileSystemEventArgs e)
{
LogLog.Debug("ConfigureAndWatchHandler: "+e.ChangeType+" [" + m_configFile.FullName + "]");
// Deliver the event in TimeoutMillis time
// timer will fire only once
m_timer.Change(TimeoutMillis, Timeout.Infinite);
}
/// <summary>
/// Event handler used by <see cref="ConfigureAndWatchHandler"/>.
/// </summary>
/// <param name="source">The <see cref="FileSystemWatcher"/> firing the event.</param>
/// <param name="e">The argument indicates the file that caused the event to be fired.</param>
/// <remarks>
/// <para>
/// This handler reloads the configuration from the file when the event is fired.
/// </para>
/// </remarks>
private void ConfigureAndWatchHandler_OnRenamed(object source, RenamedEventArgs e)
{
LogLog.Debug("ConfigureAndWatchHandler: " + e.ChangeType + " [" + m_configFile.FullName + "]");
// Deliver the event in TimeoutMillis time
// timer will fire only once
m_timer.Change(TimeoutMillis, Timeout.Infinite);
}
/// <summary>
/// Called by the timer when the configuration has been updated.
/// </summary>
/// <param name="state">null</param>
private void OnWatchedFileChange(object state)
{
XmlConfigurator.Configure(m_repository, m_configFile);
}
}
#endif
#endregion ConfigureAndWatchHandler
#region Private Static Methods
/// <summary>
/// Configures the specified repository using a <c>log4net</c> element.
/// </summary>
/// <param name="repository">The hierarchy to configure.</param>
/// <param name="element">The element to parse.</param>
/// <remarks>
/// <para>
/// Loads the log4net configuration from the XML element
/// supplied as <paramref name="element"/>.
/// </para>
/// <para>
/// This method is ultimately called by one of the Configure methods
/// to load the configuration from an <see cref="XmlElement"/>.
/// </para>
/// </remarks>
static private void ConfigureFromXml(ILoggerRepository repository, XmlElement element)
{
if (element == null)
{
LogLog.Error("XmlConfigurator: ConfigureFromXml called with null 'element' parameter");
}
else if (repository == null)
{
LogLog.Error("XmlConfigurator: ConfigureFromXml called with null 'repository' parameter");
}
else
{
LogLog.Debug("XmlConfigurator: Configuring Repository [" + repository.Name + "]");
IXmlRepositoryConfigurator configurableRepository = repository as IXmlRepositoryConfigurator;
if (configurableRepository == null)
{
LogLog.Warn("XmlConfigurator: Repository [" + repository + "] does not support the XmlConfigurator");
}
else
{
// Copy the xml data into the root of a new document
// this isolates the xml config data from the rest of
// the document
XmlDocument newDoc = new XmlDocument();
XmlElement newElement = (XmlElement)newDoc.AppendChild(newDoc.ImportNode(element, true));
// Pass the configurator the config element
configurableRepository.Configure(newElement);
}
}
}
#endregion Private Static Methods
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -