예제 #1
0
        /// <summary>
        /// Return a new logger instance named as the first parameter using
        /// <paramref name="factory"/>.
        /// </summary>
        /// <param name="name">The name of the logger to retrieve</param>
        /// <param name="factory">The factory that will make the new logger instance</param>
        /// <returns>The logger object with the name specified</returns>
        /// <remarks>
        /// <para>
        /// If a logger of that name already exists, then it will be
        /// returned. Otherwise, a new logger will be instantiated by the
        /// <paramref name="factory"/> parameter and linked with its existing
        /// ancestors as well as children.
        /// </para>
        /// </remarks>
        public Logger GetLogger(string name, ILoggerFactory factory)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }
            if (factory == null)
            {
                throw new ArgumentNullException("factory");
            }

            LoggerKey key = new LoggerKey(name);

            // Synchronize to prevent write conflicts. Read conflicts (in
            // GetEffectiveLevel() method) are possible only if variable
            // assignments are non-atomic.

            lock (m_ht) {
                Logger logger = null;

                Object node = m_ht[key];
                if (node == null)
                {
                    logger           = factory.CreateLogger(this, name);
                    logger.Hierarchy = this;
                    m_ht[key]        = logger;
                    UpdateParents(logger);
                    OnLoggerCreationEvent(logger);
                    return(logger);
                }

                Logger nodeLogger = node as Logger;
                if (nodeLogger != null)
                {
                    return(nodeLogger);
                }

                ProvisionNode nodeProvisionNode = node as ProvisionNode;
                if (nodeProvisionNode != null)
                {
                    logger           = factory.CreateLogger(this, name);
                    logger.Hierarchy = this;
                    m_ht[key]        = logger;
                    UpdateChildren(nodeProvisionNode, logger);
                    UpdateParents(logger);
                    OnLoggerCreationEvent(logger);
                    return(logger);
                }

                // It should be impossible to arrive here but let's keep the compiler happy.
                return(null);
            }
        }
예제 #2
0
        /// <summary>
        /// Updates all the parents of the specified logger
        /// </summary>
        /// <param name="log">The logger to update the parents for</param>
        /// <remarks>
        /// <para>
        /// This method loops through all the <i>potential</i> parents of
        /// <paramref name="log"/>. There 3 possible cases:
        /// </para>
        /// <list type="number">
        ///		<item>
        ///			<term>No entry for the potential parent of <paramref name="log"/> exists</term>
        ///			<description>
        ///			We create a ProvisionNode for this potential
        ///			parent and insert <paramref name="log"/> in that provision node.
        ///			</description>
        ///		</item>
        ///		<item>
        ///			<term>The entry is of type Logger for the potential parent.</term>
        ///			<description>
        ///			The entry is <paramref name="log"/>'s nearest existing parent. We
        ///			update <paramref name="log"/>'s parent field with this entry. We also break from
        ///			he loop because updating our parent's parent is our parent's
        ///			responsibility.
        ///			</description>
        ///		</item>
        ///		<item>
        ///			<term>The entry is of type ProvisionNode for this potential parent.</term>
        ///			<description>
        ///			We add <paramref name="log"/> to the list of children for this
        ///			potential parent.
        ///			</description>
        ///		</item>
        /// </list>
        /// </remarks>
        private void UpdateParents(Logger log)
        {
            string name        = log.Name;
            int    length      = name.Length;
            bool   parentFound = false;

            // if name = "w.x.y.z", loop through "w.x.y", "w.x" and "w", but not "w.x.y.z"
            for (int i = name.LastIndexOf('.', length - 1); i >= 0; i = name.LastIndexOf('.', i - 1))
            {
                string substr = name.Substring(0, i);

                LoggerKey key  = new LoggerKey(substr);                // simple constructor
                Object    node = m_ht[key];
                // Create a provision node for a future parent.
                if (node == null)
                {
                    ProvisionNode pn = new ProvisionNode(log);
                    m_ht[key] = pn;
                }
                else
                {
                    Logger nodeLogger = node as Logger;
                    if (nodeLogger != null)
                    {
                        parentFound = true;
                        log.Parent  = nodeLogger;
                        break;                         // no need to update the ancestors of the closest ancestor
                    }
                    else
                    {
                        ProvisionNode nodeProvisionNode = node as ProvisionNode;
                        if (nodeProvisionNode != null)
                        {
                            nodeProvisionNode.Add(log);
                        }
                        else
                        {
                            LogLog.Error(declaringType, "Unexpected object type [" + node.GetType() + "] in ht.", new LogException());
                        }
                    }
                }
            }

            // If we could not find any existing parents, then link with root.
            if (!parentFound)
            {
                log.Parent = this.Root;
            }
        }
예제 #3
0
        /// <summary>
        /// Determines whether two <see cref="LoggerKey" /> instances
        /// are equal.
        /// </summary>
        /// <param name="obj">The <see cref="object" /> to compare with the current <see cref="LoggerKey" />.</param>
        /// <returns>
        /// <c>true</c> if the specified <see cref="object" /> is equal to the current <see cref="LoggerKey" />; otherwise, <c>false</c>.
        /// </returns>
        /// <remarks>
        /// <para>
        /// Compares the references of the interned strings.
        /// </para>
        /// </remarks>
        override public bool Equals(object obj)
        {
            // Compare reference type of this against argument
            if (((object)this) == obj)
            {
                return(true);
            }

            LoggerKey objKey = obj as LoggerKey;

            if (objKey != null)
            {
#if NETCF
                return(m_name == objKey.m_name);
#else
                // Compare reference types rather than string's overloaded ==
                return(((object)m_name) == ((object)objKey.m_name));
#endif
            }
            return(false);
        }
예제 #4
0
		/// <summary>
		/// Updates all the parents of the specified logger
		/// </summary>
		/// <param name="log">The logger to update the parents for</param>
		/// <remarks>
		/// <para>
		/// This method loops through all the <i>potential</i> parents of
		/// <paramref name="log"/>. There 3 possible cases:
		/// </para>
		/// <list type="number">
		///		<item>
		///			<term>No entry for the potential parent of <paramref name="log"/> exists</term>
		///			<description>
		///			We create a ProvisionNode for this potential 
		///			parent and insert <paramref name="log"/> in that provision node.
		///			</description>
		///		</item>
		///		<item>
		///			<term>The entry is of type Logger for the potential parent.</term>
		///			<description>
		///			The entry is <paramref name="log"/>'s nearest existing parent. We 
		///			update <paramref name="log"/>'s parent field with this entry. We also break from 
		///			he loop because updating our parent's parent is our parent's 
		///			responsibility.
		///			</description>
		///		</item>
		///		<item>
		///			<term>The entry is of type ProvisionNode for this potential parent.</term>
		///			<description>
		///			We add <paramref name="log"/> to the list of children for this 
		///			potential parent.
		///			</description>
		///		</item>
		/// </list>
		/// </remarks>
		private void UpdateParents(Logger log) {
			string name = log.Name;
			int length = name.Length;
			bool parentFound = false;

			// if name = "w.x.y.z", loop through "w.x.y", "w.x" and "w", but not "w.x.y.z" 
			for (int i = name.LastIndexOf('.', length - 1); i >= 0; i = name.LastIndexOf('.', i - 1)) {
				string substr = name.Substring(0, i);

				LoggerKey key = new LoggerKey(substr); // simple constructor
				Object node = m_ht[key];
				// Create a provision node for a future parent.
				if (node == null) {
					ProvisionNode pn = new ProvisionNode(log);
					m_ht[key] = pn;
				} else {
					Logger nodeLogger = node as Logger;
					if (nodeLogger != null) {
						parentFound = true;
						log.Parent = nodeLogger;
						break; // no need to update the ancestors of the closest ancestor
					} else {
						ProvisionNode nodeProvisionNode = node as ProvisionNode;
						if (nodeProvisionNode != null) {
							nodeProvisionNode.Add(log);
						} else {
							LogLog.Error(declaringType, "Unexpected object type [" + node.GetType() + "] in ht.", new LogException());
						}
					}
				}
			}

			// If we could not find any existing parents, then link with root.
			if (!parentFound) {
				log.Parent = this.Root;
			}
		}
예제 #5
0
		/// <summary>
		/// Return a new logger instance named as the first parameter using
		/// <paramref name="factory"/>.
		/// </summary>
		/// <param name="name">The name of the logger to retrieve</param>
		/// <param name="factory">The factory that will make the new logger instance</param>
		/// <returns>The logger object with the name specified</returns>
		/// <remarks>
		/// <para>
		/// If a logger of that name already exists, then it will be
		/// returned. Otherwise, a new logger will be instantiated by the
		/// <paramref name="factory"/> parameter and linked with its existing
		/// ancestors as well as children.
		/// </para>
		/// </remarks>
		public Logger GetLogger(string name, ILoggerFactory factory) {
			if (name == null) {
				throw new ArgumentNullException("name");
			}
			if (factory == null) {
				throw new ArgumentNullException("factory");
			}

			LoggerKey key = new LoggerKey(name);

			// Synchronize to prevent write conflicts. Read conflicts (in
			// GetEffectiveLevel() method) are possible only if variable
			// assignments are non-atomic.

			lock (m_ht) {
				Logger logger = null;

				Object node = m_ht[key];
				if (node == null) {
					logger = factory.CreateLogger(this, name);
					logger.Hierarchy = this;
					m_ht[key] = logger;
					UpdateParents(logger);
					OnLoggerCreationEvent(logger);
					return logger;
				}

				Logger nodeLogger = node as Logger;
				if (nodeLogger != null) {
					return nodeLogger;
				}

				ProvisionNode nodeProvisionNode = node as ProvisionNode;
				if (nodeProvisionNode != null) {
					logger = factory.CreateLogger(this, name);
					logger.Hierarchy = this;
					m_ht[key] = logger;
					UpdateChildren(nodeProvisionNode, logger);
					UpdateParents(logger);
					OnLoggerCreationEvent(logger);
					return logger;
				}

				// It should be impossible to arrive here but let's keep the compiler happy.
				return null;
			}
		}