hierarchy.cs
来自「SharpDevelop2.0.0 c#开发免费工具」· CS 代码 · 共 1,003 行 · 第 1/2 页
CS
1,003 行
#region Copyright & License
//
// Copyright 2001-2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion
using System;
using log4net.ObjectRenderer;
using log4net.Core;
using log4net.Util;
namespace log4net.Repository.Hierarchy
{
#region LoggerCreationEvent
/// <summary>
/// Delegate used to handle logger creation event notifications.
/// </summary>
/// <param name="sender">The <see cref="Hierarchy"/> in which the <see cref="Logger"/> has been created.</param>
/// <param name="e">The <see cref="LoggerCreationEventArgs"/> event args that hold the <see cref="Logger"/> instance that has been created.</param>
/// <remarks>
/// <para>
/// Delegate used to handle logger creation event notifications.
/// </para>
/// </remarks>
public delegate void LoggerCreationEventHandler(object sender, LoggerCreationEventArgs e);
/// <summary>
/// Provides data for the <see cref="Hierarchy.LoggerCreatedEvent"/> event.
/// </summary>
/// <remarks>
/// <para>
/// A <see cref="Hierarchy.LoggerCreatedEvent"/> event is raised every time a
/// <see cref="Logger"/> is created.
/// </para>
/// </remarks>
public class LoggerCreationEventArgs : EventArgs
{
/// <summary>
/// The <see cref="Logger"/> created
/// </summary>
private Logger m_log;
/// <summary>
/// Constructor
/// </summary>
/// <param name="log">The <see cref="Logger"/> that has been created.</param>
/// <remarks>
/// <para>
/// Initializes a new instance of the <see cref="LoggerCreationEventArgs" /> event argument
/// class,with the specified <see cref="Logger"/>.
/// </para>
/// </remarks>
public LoggerCreationEventArgs(Logger log)
{
m_log = log;
}
/// <summary>
/// Gets the <see cref="Logger"/> that has been created.
/// </summary>
/// <value>
/// The <see cref="Logger"/> that has been created.
/// </value>
/// <remarks>
/// <para>
/// The <see cref="Logger"/> that has been created.
/// </para>
/// </remarks>
public Logger Logger
{
get { return m_log; }
}
}
#endregion LoggerCreationEvent
/// <summary>
/// Hierarchical organization of loggers
/// </summary>
/// <remarks>
/// <para>
/// <i>The casual user should not have to deal with this class
/// directly.</i>
/// </para>
/// <para>
/// This class is specialized in retrieving loggers by name and
/// also maintaining the logger hierarchy. Implements the
/// <see cref="ILoggerRepository"/> interface.
/// </para>
/// <para>
/// The structure of the logger hierarchy is maintained by the
/// <see cref="GetLogger"/> method. The hierarchy is such that children
/// link to their parent but parents do not have any references to their
/// children. Moreover, loggers can be instantiated in any order, in
/// particular descendant before ancestor.
/// </para>
/// <para>
/// In case a descendant is created before a particular ancestor,
/// then it creates a provision node for the ancestor and adds itself
/// to the provision node. Other descendants of the same ancestor add
/// themselves to the previously created provision node.
/// </para>
/// </remarks>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
public class Hierarchy : LoggerRepositorySkeleton, IBasicRepositoryConfigurator, IXmlRepositoryConfigurator
{
#region Public Events
/// <summary>
/// Event used to notify that a logger has been created.
/// </summary>
/// <remarks>
/// <para>
/// Event raised when a logger is created.
/// </para>
/// </remarks>
public event LoggerCreationEventHandler LoggerCreatedEvent
{
add { m_loggerCreatedEvent += value; }
remove { m_loggerCreatedEvent -= value; }
}
#endregion Public Events
#region Public Instance Constructors
/// <summary>
/// Default constructor
/// </summary>
/// <remarks>
/// <para>
/// Initializes a new instance of the <see cref="Hierarchy" /> class.
/// </para>
/// </remarks>
public Hierarchy() : this(new DefaultLoggerFactory())
{
}
/// <summary>
/// Construct with properties
/// </summary>
/// <param name="properties">The properties to pass to this repository.</param>
/// <remarks>
/// <para>
/// Initializes a new instance of the <see cref="Hierarchy" /> class.
/// </para>
/// </remarks>
public Hierarchy(PropertiesDictionary properties) : this(properties, new DefaultLoggerFactory())
{
}
/// <summary>
/// Construct with a logger factory
/// </summary>
/// <param name="loggerFactory">The factory to use to create new logger instances.</param>
/// <remarks>
/// <para>
/// Initializes a new instance of the <see cref="Hierarchy" /> class with
/// the specified <see cref="ILoggerFactory" />.
/// </para>
/// </remarks>
public Hierarchy(ILoggerFactory loggerFactory) : this(new PropertiesDictionary(), loggerFactory)
{
}
/// <summary>
/// Construct with properties and a logger factory
/// </summary>
/// <param name="properties">The properties to pass to this repository.</param>
/// <param name="loggerFactory">The factory to use to create new logger instances.</param>
/// <remarks>
/// <para>
/// Initializes a new instance of the <see cref="Hierarchy" /> class with
/// the specified <see cref="ILoggerFactory" />.
/// </para>
/// </remarks>
public Hierarchy(PropertiesDictionary properties, ILoggerFactory loggerFactory) : base(properties)
{
if (loggerFactory == null)
{
throw new ArgumentNullException("loggerFactory");
}
m_defaultFactory = loggerFactory;
m_ht = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable());
}
#endregion Public Instance Constructors
#region Public Instance Properties
/// <summary>
/// Has no appender warning been emitted
/// </summary>
/// <remarks>
/// <para>
/// Flag to indicate if we have already issued a warning
/// about not having an appender warning.
/// </para>
/// </remarks>
public bool EmittedNoAppenderWarning
{
get { return m_emittedNoAppenderWarning; }
set { m_emittedNoAppenderWarning = value; }
}
/// <summary>
/// Get the root of this hierarchy
/// </summary>
/// <remarks>
/// <para>
/// Get the root of this hierarchy.
/// </para>
/// </remarks>
public Logger Root
{
get
{
if (m_root == null)
{
lock(this)
{
if (m_root == null)
{
// Create the root logger
Logger root = m_defaultFactory.CreateLogger(null);
root.Hierarchy = this;
// Store root
m_root = root;
}
}
}
return m_root;
}
}
/// <summary>
/// Gets or sets the default <see cref="ILoggerFactory" /> instance.
/// </summary>
/// <value>The default <see cref="ILoggerFactory" /></value>
/// <remarks>
/// <para>
/// The logger factory is used to create logger instances.
/// </para>
/// </remarks>
public ILoggerFactory LoggerFactory
{
get { return m_defaultFactory; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
m_defaultFactory = value;
}
}
#endregion Public Instance Properties
#region Override Implementation of LoggerRepositorySkeleton
/// <summary>
/// Test if a logger exists
/// </summary>
/// <param name="name">The name of the logger to lookup</param>
/// <returns>The Logger object with the name specified</returns>
/// <remarks>
/// <para>
/// Check if the named logger exists in the hierarchy. If so return
/// its reference, otherwise returns <c>null</c>.
/// </para>
/// </remarks>
override public ILogger Exists(string name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
return m_ht[new LoggerKey(name)] as Logger;
}
/// <summary>
/// Returns all the currently defined loggers in the hierarchy as an Array
/// </summary>
/// <returns>All the defined loggers</returns>
/// <remarks>
/// <para>
/// Returns all the currently defined loggers in the hierarchy as an Array.
/// The root logger is <b>not</b> included in the returned
/// enumeration.
/// </para>
/// </remarks>
override public ILogger[] GetCurrentLoggers()
{
// The accumulation in loggers is necessary because not all elements in
// ht are Logger objects as there might be some ProvisionNodes
// as well.
System.Collections.ArrayList loggers = new System.Collections.ArrayList(m_ht.Count);
// Iterate through m_ht values
foreach(object node in m_ht.Values)
{
if (node is Logger)
{
loggers.Add(node);
}
}
return (Logger[])loggers.ToArray(typeof(Logger));
}
/// <summary>
/// Return a new logger instance named as the first parameter using
/// the default factory.
/// </summary>
/// <remarks>
/// <para>
/// Return a new logger instance named as the first parameter using
/// the default factory.
/// </para>
/// <para>
/// If a logger of that name already exists, then it will be
/// returned. Otherwise, a new logger will be instantiated and
/// then linked with its existing ancestors as well as children.
/// </para>
/// </remarks>
/// <param name="name">The name of the logger to retrieve</param>
/// <returns>The logger object with the name specified</returns>
override public ILogger GetLogger(string name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
return GetLogger(name, m_defaultFactory);
}
/// <summary>
/// Shutting down a hierarchy will <i>safely</i> close and remove
/// all appenders in all loggers including the root logger.
/// </summary>
/// <remarks>
/// <para>
/// Shutting down a hierarchy will <i>safely</i> close and remove
/// all appenders in all loggers including the root logger.
/// </para>
/// <para>
/// Some appenders need to be closed before the
/// application exists. Otherwise, pending logging events might be
/// lost.
/// </para>
/// <para>
/// The <c>Shutdown</c> method is careful to close nested
/// appenders before closing regular appenders. This is allows
/// configurations where a regular appender is attached to a logger
/// and again to a nested appender.
/// </para>
/// </remarks>
override public void Shutdown()
{
LogLog.Debug("Hierarchy: Shutdown called on Hierarchy ["+this.Name+"]");
// begin by closing nested appenders
Root.CloseNestedAppenders();
lock(m_ht)
{
ILogger[] currentLoggers = this.GetCurrentLoggers();
foreach(Logger logger in currentLoggers)
{
logger.CloseNestedAppenders();
}
// then, remove all appenders
Root.RemoveAllAppenders();
foreach(Logger logger in currentLoggers)
{
logger.RemoveAllAppenders();
}
}
base.Shutdown();
}
/// <summary>
/// Reset all values contained in this hierarchy instance to their default.
/// </summary>
/// <remarks>
/// <para>
/// Reset all values contained in this hierarchy instance to their
/// default. This removes all appenders from all loggers, sets
/// the level of all non-root loggers to <c>null</c>,
/// sets their additivity flag to <c>true</c> and sets the level
/// of the root logger to <see cref="Level.Debug"/>. Moreover,
/// message disabling is set its default "off" value.
/// </para>
/// <para>
/// Existing loggers are not removed. They are just reset.
/// </para>
/// <para>
/// This method should be used sparingly and with care as it will
/// block all logging until it is completed.
/// </para>
/// </remarks>
override public void ResetConfiguration()
{
Root.Level = Level.Debug;
Threshold = Level.All;
// the synchronization is needed to prevent hashtable surprises
lock(m_ht)
{
Shutdown(); // nested locks are OK
foreach(Logger l in this.GetCurrentLoggers())
{
l.Level = null;
l.Additivity = true;
}
}
base.ResetConfiguration();
// Notify listeners
OnConfigurationChanged(null);
}
/// <summary>
/// Log the logEvent through this hierarchy.
/// </summary>
/// <param name="logEvent">the event to log</param>
/// <remarks>
/// <para>
/// This method should not normally be used to log.
/// The <see cref="ILog"/> interface should be used
/// for routine logging. This interface can be obtained
/// using the <see cref="log4net.LogManager.GetLogger(string)"/> method.
/// </para>
/// <para>
/// The <c>logEvent</c> is delivered to the appropriate logger and
/// that logger is then responsible for logging the event.
/// </para>
/// </remarks>
override public void Log(LoggingEvent logEvent)
{
if (logEvent == null)
{
throw new ArgumentNullException("logEvent");
}
this.GetLogger(logEvent.LoggerName, m_defaultFactory).Log(logEvent);
}
/// <summary>
/// Returns all the Appenders that are currently configured
/// </summary>
/// <returns>An array containing all the currently configured appenders</returns>
/// <remarks>
/// <para>
/// Returns all the <see cref="log4net.Appender.IAppender"/> instances that are currently configured.
/// All the loggers are searched for appenders. The appenders may also be containers
/// for appenders and these are also searched for additional loggers.
/// </para>
/// <para>
/// The list returned is unordered but does not contain duplicates.
/// </para>
/// </remarks>
override public log4net.Appender.IAppender[] GetAppenders()
{
System.Collections.ArrayList appenderList = new System.Collections.ArrayList();
CollectAppenders(appenderList, Root);
foreach(Logger logger in GetCurrentLoggers())
{
CollectAppenders(appenderList, logger);
}
return (log4net.Appender.IAppender[])appenderList.ToArray(typeof(log4net.Appender.IAppender));
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?