📄 xmlhierarchyconfigurator.cs
字号:
// Create a new log4net.Logger object from the <logger> element.
string loggerName = loggerElement.GetAttribute(NAME_ATTR);
LogLog.Debug("XmlHierarchyConfigurator: Retrieving an instance of log4net.Repository.Logger for logger [" + loggerName + "].");
Logger log = m_hierarchy.GetLogger(loggerName) as Logger;
// Setting up a logger needs to be an atomic operation, in order
// to protect potential log operations while logger
// configuration is in progress.
lock(log)
{
bool additivity = OptionConverter.ToBoolean(loggerElement.GetAttribute(ADDITIVITY_ATTR), true);
LogLog.Debug("XmlHierarchyConfigurator: Setting [" + log.Name + "] additivity to [" + additivity + "].");
log.Additivity = additivity;
ParseChildrenOfLoggerElement(loggerElement, log, false);
}
}
/// <summary>
/// Parses the root logger element.
/// </summary>
/// <param name="rootElement">The root element.</param>
/// <remarks>
/// <para>
/// Parse an XML element that represents the root logger.
/// </para>
/// </remarks>
protected void ParseRoot(XmlElement rootElement)
{
Logger root = m_hierarchy.Root;
// logger configuration needs to be atomic
lock(root)
{
ParseChildrenOfLoggerElement(rootElement, root, true);
}
}
/// <summary>
/// Parses the children of a logger element.
/// </summary>
/// <param name="catElement">The category element.</param>
/// <param name="log">The logger instance.</param>
/// <param name="isRoot">Flag to indicate if the logger is the root logger.</param>
/// <remarks>
/// <para>
/// Parse the child elements of a <logger> element.
/// </para>
/// </remarks>
protected void ParseChildrenOfLoggerElement(XmlElement catElement, Logger log, bool isRoot)
{
// Remove all existing appenders from log. They will be
// reconstructed if need be.
log.RemoveAllAppenders();
foreach (XmlNode currentNode in catElement.ChildNodes)
{
if (currentNode.NodeType == XmlNodeType.Element)
{
XmlElement currentElement = (XmlElement) currentNode;
if (currentElement.LocalName == APPENDER_REF_TAG)
{
IAppender appender = FindAppenderByReference(currentElement);
string refName = currentElement.GetAttribute(REF_ATTR);
if (appender != null)
{
LogLog.Debug("XmlHierarchyConfigurator: Adding appender named [" + refName + "] to logger [" + log.Name + "].");
log.AddAppender(appender);
}
else
{
LogLog.Error("XmlHierarchyConfigurator: Appender named [" + refName + "] not found.");
}
}
else if (currentElement.LocalName == LEVEL_TAG || currentElement.LocalName == PRIORITY_TAG)
{
ParseLevel(currentElement, log, isRoot);
}
else
{
SetParameter(currentElement, log);
}
}
}
IOptionHandler optionHandler = log as IOptionHandler;
if (optionHandler != null)
{
optionHandler.ActivateOptions();
}
}
/// <summary>
/// Parses an object renderer.
/// </summary>
/// <param name="element">The renderer element.</param>
/// <remarks>
/// <para>
/// Parse an XML element that represents a renderer.
/// </para>
/// </remarks>
protected void ParseRenderer(XmlElement element)
{
string renderingClassName = element.GetAttribute(RENDERING_TYPE_ATTR);
string renderedClassName = element.GetAttribute(RENDERED_TYPE_ATTR);
LogLog.Debug("XmlHierarchyConfigurator: Rendering class [" + renderingClassName + "], Rendered class [" + renderedClassName + "].");
IObjectRenderer renderer = (IObjectRenderer)OptionConverter.InstantiateByClassName(renderingClassName, typeof(IObjectRenderer), null);
if (renderer == null)
{
LogLog.Error("XmlHierarchyConfigurator: Could not instantiate renderer [" + renderingClassName + "].");
return;
}
else
{
try
{
m_hierarchy.RendererMap.Put(SystemInfo.GetTypeFromString(renderedClassName, true, true), renderer);
}
catch(Exception e)
{
LogLog.Error("XmlHierarchyConfigurator: Could not find class [" + renderedClassName + "].", e);
}
}
}
/// <summary>
/// Parses a level element.
/// </summary>
/// <param name="element">The level element.</param>
/// <param name="log">The logger object to set the level on.</param>
/// <param name="isRoot">Flag to indicate if the logger is the root logger.</param>
/// <remarks>
/// <para>
/// Parse an XML element that represents a level.
/// </para>
/// </remarks>
protected void ParseLevel(XmlElement element, Logger log, bool isRoot)
{
string loggerName = log.Name;
if (isRoot)
{
loggerName = "root";
}
string levelStr = element.GetAttribute(VALUE_ATTR);
LogLog.Debug("XmlHierarchyConfigurator: Logger [" + loggerName + "] Level string is [" + levelStr + "].");
if (INHERITED == levelStr)
{
if (isRoot)
{
LogLog.Error("XmlHierarchyConfigurator: Root level cannot be inherited. Ignoring directive.");
}
else
{
LogLog.Debug("XmlHierarchyConfigurator: Logger [" + loggerName + "] level set to inherit from parent.");
log.Level = null;
}
}
else
{
log.Level = log.Hierarchy.LevelMap[levelStr];
if (log.Level == null)
{
LogLog.Error("XmlHierarchyConfigurator: Undefined level [" + levelStr + "] on Logger [" + loggerName + "].");
}
else
{
LogLog.Debug("XmlHierarchyConfigurator: Logger [" + loggerName + "] level set to [name=\"" + log.Level.Name + "\",value=" + log.Level.Value + "].");
}
}
}
/// <summary>
/// Sets a parameter on an object.
/// </summary>
/// <param name="element">The parameter element.</param>
/// <param name="target">The object to set the parameter on.</param>
/// <remarks>
/// The parameter name must correspond to a writable property
/// on the object. The value of the parameter is a string,
/// therefore this function will attempt to set a string
/// property first. If unable to set a string property it
/// will inspect the property and its argument type. It will
/// attempt to call a static method called <c>Parse</c> on the
/// type of the property. This method will take a single
/// string argument and return a value that can be used to
/// set the property.
/// </remarks>
protected void SetParameter(XmlElement element, object target)
{
// Get the property name
string name = element.GetAttribute(NAME_ATTR);
// If the name attribute does not exist then use the name of the element
if (element.LocalName != PARAM_TAG || name == null || name.Length == 0)
{
name = element.LocalName;
}
// Look for the property on the target object
Type targetType = target.GetType();
Type propertyType = null;
PropertyInfo propInfo = null;
MethodInfo methInfo = null;
// Try to find a writable property
propInfo = targetType.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
if (propInfo != null && propInfo.CanWrite)
{
// found a property
propertyType = propInfo.PropertyType;
}
else
{
propInfo = null;
// look for a method with the signature Add<property>(type)
methInfo = FindMethodInfo(targetType, name);
if (methInfo != null)
{
propertyType = methInfo.GetParameters()[0].ParameterType;
}
}
if (propertyType == null)
{
LogLog.Error("XmlHierarchyConfigurator: Cannot find Property [" + name + "] to set object on [" + target.ToString() + "]");
}
else
{
string propertyValue = null;
if (element.GetAttributeNode(VALUE_ATTR) != null)
{
propertyValue = element.GetAttribute(VALUE_ATTR);
}
else if (element.HasChildNodes)
{
// Concatenate the CDATA and Text nodes together
foreach(XmlNode childNode in element.ChildNodes)
{
if (childNode.NodeType == XmlNodeType.CDATA || childNode.NodeType == XmlNodeType.Text)
{
if (propertyValue == null)
{
propertyValue = childNode.InnerText;
}
else
{
propertyValue += childNode.InnerText;
}
}
}
}
if(propertyValue != null)
{
#if !NETCF
try
{
// Expand environment variables in the string.
propertyValue = OptionConverter.SubstituteVariables(propertyValue, Environment.GetEnvironmentVariables());
}
catch(System.Security.SecurityException)
{
// This security exception will occur if the caller does not have
// unrestricted environment permission. If this occurs the expansion
// will be skipped with the following warning message.
LogLog.Debug("XmlHierarchyConfigurator: Security exception while trying to expand environment variables. Error Ignored. No Expansion.");
}
#endif
Type parsedObjectConversionTargetType = null;
// Check if a specific subtype is specified on the element using the 'type' attribute
string subTypeString = element.GetAttribute(TYPE_ATTR);
if (subTypeString != null && subTypeString.Length > 0)
{
// Read the explicit subtype
try
{
Type subType = SystemInfo.GetTypeFromString(subTypeString, true, true);
LogLog.Debug("XmlHierarchyConfigurator: Parameter ["+name+"] specified subtype ["+subType.FullName+"]");
if (!propertyType.IsAssignableFrom(subType))
{
// Check if there is an appropriate type converter
if (OptionConverter.CanConvertTypeTo(subType, propertyType))
{
// Must re-convert to the real property type
parsedObjectConversionTargetType = propertyType;
// Use sub type as intermediary type
propertyType = subType;
}
else
{
LogLog.Error("XmlHierarchyConfigurator: Subtype ["+subType.FullName+"] set on ["+name+"] is not a subclass of property type ["+propertyType.FullName+"] and there are no acceptable type conversions.");
}
}
else
{
// The subtype specified is found and is actually a subtype of the property
// type, therefore we can switch to using this type.
propertyType = subType;
}
}
catch(Exception ex)
{
LogLog.Error("XmlHierarchyConfigurator: Failed to find type ["+subTypeString+"] set on ["+name+"]", ex);
}
}
// Now try to convert the string value to an acceptable type
// to pass to this property.
object convertedValue = ConvertStringTo(propertyType, propertyValue);
// Check if we need to do an additional conversion
if (convertedValue != null && parsedObjectConversionTargetType != null)
{
LogLog.Debug("XmlHierarchyConfigurator: Performing additional conversion of value from [" + convertedValue.GetType().Name + "] to [" + parsedObjectConversionTargetType.Name + "]");
convertedValue = OptionConverter.ConvertTypeTo(convertedValue, parsedObjectConversionTargetType);
}
if (convertedValue != null)
{
if (propInfo != null)
{
// Got a converted result
LogLog.Debug("XmlHierarchyConfigurator: Setting Property [" + propInfo.Name + "] to " + convertedValue.GetType().Name + " value [" + convertedValue.ToString() + "]");
try
{
// Pass to the property
propInfo.SetValue(target, convertedValue, BindingFlags.SetProperty, null, null, CultureInfo.InvariantCulture);
}
catch(TargetInvocationException targetInvocationEx)
{
LogLog.Error("XmlHierarchyConfigurator: Failed to set parameter [" + propInfo.Name + "] on object [" + target + "] using value [" + convertedValue + "]", targetInvocationEx.InnerException);
}
}
else if (methInfo != null)
{
// Got a converted result
LogLog.Debug("XmlHierarchyConfigurator: Setting Collection Property [" + methInfo.Name + "] to " + convertedValue.GetType().Name + " value [" + convertedValue.ToString() + "]");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -