From c0cffd213083f748dff55a89abba9954be1f3704 Mon Sep 17 00:00:00 2001
From: Jan Friedrich
Date: Fri, 26 Jul 2024 14:30:47 +0200
Subject: [PATCH 2/4] #156 better names for private Hierarchy fields
---
src/log4net/Repository/Hierarchy/Hierarchy.cs | 143 +++++-------------
1 file changed, 40 insertions(+), 103 deletions(-)
diff --git a/src/log4net/Repository/Hierarchy/Hierarchy.cs b/src/log4net/Repository/Hierarchy/Hierarchy.cs
index 72f56612..0a55dbeb 100644
--- a/src/log4net/Repository/Hierarchy/Hierarchy.cs
+++ b/src/log4net/Repository/Hierarchy/Hierarchy.cs
@@ -177,7 +177,7 @@ public Hierarchy(PropertiesDictionary properties, ILoggerFactory loggerFactory)
throw new ArgumentNullException(nameof(loggerFactory));
}
- m_defaultFactory = loggerFactory;
+ defaultFactory = loggerFactory;
}
///
@@ -203,22 +203,22 @@ public Logger Root
{
get
{
- if (m_root is null)
+ if (rootLogger is null)
{
lock (this)
{
- if (m_root is null)
+ if (rootLogger is null)
{
// Create the root logger
- Logger root = m_defaultFactory.CreateLogger(this, null);
+ Logger root = defaultFactory.CreateLogger(this, null);
root.Hierarchy = this;
// Store root
- m_root = root;
+ rootLogger = root;
}
}
}
- return m_root;
+ return rootLogger;
}
}
@@ -232,11 +232,8 @@ public Logger Root
///
public ILoggerFactory LoggerFactory
{
- get => m_defaultFactory;
- set
- {
- m_defaultFactory = value ?? throw new ArgumentNullException(nameof(value));
- }
+ get => defaultFactory;
+ set => defaultFactory = value.EnsureNotNull();
}
///
@@ -252,12 +249,7 @@ public ILoggerFactory LoggerFactory
///
public override ILogger? Exists(string name)
{
- if (name is null)
- {
- throw new ArgumentNullException(nameof(name));
- }
-
- m_ht.TryGetValue(new LoggerKey(name), out object? o);
+ loggers.TryGetValue(new(name.EnsureNotNull()), out object? o);
return o as Logger;
}
@@ -277,10 +269,10 @@ public override 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.
- var loggers = new List(m_ht.Count);
+ var loggers = new List(this.loggers.Count);
// Iterate through m_ht values
- foreach (object node in m_ht.Values)
+ foreach (object node in this.loggers.Values)
{
if (node is Logger logger)
{
@@ -308,14 +300,7 @@ public override ILogger[] GetCurrentLoggers()
/// The name of the logger to retrieve
/// The logger object with the name specified
public override ILogger GetLogger(string name)
- {
- if (name is null)
- {
- throw new ArgumentNullException(nameof(name));
- }
-
- return GetLogger(name, m_defaultFactory);
- }
+ => GetLogger(name.EnsureNotNull(), defaultFactory);
///
/// Shutting down a hierarchy will safely close and remove
@@ -420,14 +405,10 @@ public override void ResetConfiguration()
///
public override void Log(LoggingEvent logEvent)
{
- if (logEvent is null)
- {
- throw new ArgumentNullException(nameof(logEvent));
- }
-
+ logEvent.EnsureNotNull();
if (logEvent.LoggerName is not null)
{
- GetLogger(logEvent.LoggerName, m_defaultFactory).Log(logEvent);
+ GetLogger(logEvent.LoggerName, defaultFactory).Log(logEvent);
}
}
@@ -492,18 +473,14 @@ private static void CollectAppenders(List appenderList, IAppenderAtta
///
/// the appender to use to log all logging events
void IBasicRepositoryConfigurator.Configure(IAppender appender)
- {
- BasicRepositoryConfigure(appender);
- }
+ => BasicRepositoryConfigure(appender);
///
/// Initialize the log4net system using the specified appenders
///
/// the appenders to use to log all logging events
void IBasicRepositoryConfigurator.Configure(params IAppender[] appenders)
- {
- BasicRepositoryConfigure(appenders);
- }
+ => BasicRepositoryConfigure(appenders);
///
/// Initialize the log4net system using the specified appenders
@@ -562,8 +539,7 @@ protected void XmlRepositoryConfigure(System.Xml.XmlElement element)
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
- var config = new XmlHierarchyConfigurator(this);
- config.Configure(element);
+ new XmlHierarchyConfigurator(this).Configure(element);
}
Configured = true;
@@ -597,20 +573,12 @@ protected void XmlRepositoryConfigure(System.Xml.XmlElement element)
///
public bool IsDisabled(Level level)
{
- if (level is null)
- {
- throw new ArgumentNullException(nameof(level));
- }
-
if (Configured)
{
- return Threshold > level;
- }
- else
- {
- // If not configured the hierarchy is effectively disabled
- return true;
+ return Threshold > level.EnsureNotNull();
}
+ // If not configured the hierarchy is effectively disabled
+ return true;
}
///
@@ -627,10 +595,7 @@ public bool IsDisabled(Level level)
/// invoking this method.
///
///
- public void Clear()
- {
- m_ht.Clear();
- }
+ public void Clear() => loggers.Clear();
///
/// Returns a new logger instance named as the first parameter using
@@ -649,14 +614,8 @@ public void Clear()
///
public Logger GetLogger(string name, ILoggerFactory factory)
{
- if (name is null)
- {
- throw new ArgumentNullException(nameof(name));
- }
- if (factory is null)
- {
- throw new ArgumentNullException(nameof(factory));
- }
+ name.EnsureNotNull();
+ factory.EnsureNotNull();
var key = new LoggerKey(name);
@@ -668,16 +627,16 @@ public Logger GetLogger(string name, ILoggerFactory factory)
return result;
}
}
- throw new InvalidOperationException(
+ throw new LogException(
$"GetLogger failed, because possibly too many threads are messing with creating the logger {name}!");
}
private Logger? TryCreateLogger(LoggerKey key, ILoggerFactory factory)
{
- if (!m_ht.TryGetValue(key, out object? node))
+ if (!loggers.TryGetValue(key, out object? node))
{
Logger newLogger = CreateLogger(key.Name);
- node = m_ht.GetOrAdd(key, newLogger);
+ node = loggers.GetOrAdd(key, newLogger);
if (node == newLogger)
{
RegisterLogger(newLogger);
@@ -692,7 +651,7 @@ public Logger GetLogger(string name, ILoggerFactory factory)
if (node is ProvisionNode provisionNode)
{
Logger newLogger = CreateLogger(key.Name);
- if (m_ht.TryUpdate(key, newLogger, node))
+ if (loggers.TryUpdate(key, newLogger, node))
{
UpdateChildren(provisionNode, newLogger);
RegisterLogger(newLogger);
@@ -702,7 +661,7 @@ public Logger GetLogger(string name, ILoggerFactory factory)
}
// It should be impossible to arrive here but let's keep the compiler happy.
- throw new InvalidOperationException("TryCreateLogger failed, because a node is neither a Logger nor a ProvisionNode!");
+ throw new LogException("TryCreateLogger failed, because a node is neither a Logger nor a ProvisionNode!");
Logger CreateLogger(string name)
{
@@ -718,7 +677,6 @@ void RegisterLogger(Logger logger)
}
}
-
///
/// Sends a logger creation event to all registered listeners
///
@@ -727,9 +685,7 @@ void RegisterLogger(Logger logger)
/// Raises the logger creation event.
///
protected virtual void OnLoggerCreationEvent(Logger logger)
- {
- LoggerCreatedEvent?.Invoke(this, new LoggerCreationEventArgs(logger));
- }
+ => LoggerCreatedEvent?.Invoke(this, new(logger));
///
/// Updates all the parents of the specified logger
@@ -778,12 +734,12 @@ private void UpdateParents(Logger log)
string substr = name.Substring(0, i);
var key = new LoggerKey(substr);
- m_ht.TryGetValue(key, out object? node);
+ loggers.TryGetValue(key, out object? node);
// Create a provision node for a future parent.
if (node is null)
{
- m_ht[key] = new ProvisionNode(log);
+ loggers[key] = new ProvisionNode(log);
}
else
{
@@ -800,7 +756,7 @@ private void UpdateParents(Logger log)
}
else
{
- LogLog.Error(declaringType, $"Unexpected object type [{node.GetType()}] in ht.", new LogException());
+ LogLog.Error(declaringType, $"Unexpected object type [{node.GetType()}] in loggers.", new LogException());
}
}
if (i == 0)
@@ -864,14 +820,8 @@ private static void UpdateChildren(ProvisionNode pn, Logger log)
///
internal void AddLevel(LevelEntry levelEntry)
{
- if (levelEntry is null)
- {
- throw new ArgumentNullException(nameof(levelEntry));
- }
- if (levelEntry.Name is null)
- {
- throw new ArgumentNullException("levelEntry.Name");
- }
+ levelEntry.EnsureNotNull();
+ levelEntry.Name.EnsureNotNull();
// Lookup replacement value
if (levelEntry.Value == -1)
@@ -941,9 +891,7 @@ internal sealed class LevelEntry
///
/// string info about this object
public override string ToString()
- {
- return $"LevelEntry(Value={Value}, Name={Name}, DisplayName={DisplayName})";
- }
+ => $"LevelEntry(Value={Value}, Name={Name}, DisplayName={DisplayName})";
}
///
@@ -959,23 +907,12 @@ public override string ToString()
///
///
internal void AddProperty(PropertyEntry propertyEntry)
- {
- if (propertyEntry is null)
- {
- throw new ArgumentNullException(nameof(propertyEntry));
- }
- if (propertyEntry.Key is null)
- {
- throw new ArgumentNullException("propertyEntry.Key");
- }
-
- Properties[propertyEntry.Key] = propertyEntry.Value;
- }
+ => Properties[propertyEntry.Key.EnsureNotNull()] = propertyEntry.EnsureNotNull().Value;
- private ILoggerFactory m_defaultFactory;
+ private ILoggerFactory defaultFactory;
- private readonly ConcurrentDictionary m_ht = new(LoggerKey.ComparerInstance);
- private Logger? m_root;
+ private readonly ConcurrentDictionary loggers = new(LoggerKey.ComparerInstance);
+ private Logger? rootLogger;
///
/// The fully qualified type of the Hierarchy class.
@@ -986,4 +923,4 @@ internal void AddProperty(PropertyEntry propertyEntry)
///
private static readonly Type declaringType = typeof(Hierarchy);
}
-}
+}
\ No newline at end of file
From 998216a50acdae155cd602faba3451ca15732f4f Mon Sep 17 00:00:00 2001
From: Jan Friedrich
Date: Fri, 26 Jul 2024 16:01:17 +0200
Subject: [PATCH 3/4] #156 use Interlocked.CompareExchange instead of
lokc(this) - shortened xml comments - Hierarchy.EmittedNoAppenderWarning is
now internal
---
src/log4net/Repository/Hierarchy/Hierarchy.cs | 235 ++++-------------
src/log4net/Repository/Hierarchy/Logger.cs | 248 ++++++++----------
.../Repository/Hierarchy/ProvisionNode.cs | 9 +-
src/log4net/assembly/bin.xml | 64 -----
src/site/xdoc/release/release-notes.xml | 4 +
5 files changed, 167 insertions(+), 393 deletions(-)
delete mode 100644 src/log4net/assembly/bin.xml
diff --git a/src/log4net/Repository/Hierarchy/Hierarchy.cs b/src/log4net/Repository/Hierarchy/Hierarchy.cs
index 0a55dbeb..8cdae7c9 100644
--- a/src/log4net/Repository/Hierarchy/Hierarchy.cs
+++ b/src/log4net/Repository/Hierarchy/Hierarchy.cs
@@ -20,7 +20,9 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq;
+using System.Threading;
using log4net.Appender;
using log4net.Core;
using log4net.Util;
@@ -32,11 +34,6 @@ namespace log4net.Repository.Hierarchy
///
/// The in which the has been created.
/// The event args that hold the instance that has been created.
- ///
- ///
- /// Delegate used to handle logger creation event notifications.
- ///
- ///
public delegate void LoggerCreationEventHandler(object sender, LoggerCreationEventArgs e);
///
@@ -54,28 +51,11 @@ public class LoggerCreationEventArgs : EventArgs
/// Constructor
///
/// The that has been created.
- ///
- ///
- /// Initializes a new instance of the event argument
- /// class,with the specified .
- ///
- ///
- public LoggerCreationEventArgs(Logger log)
- {
- Logger = log;
- }
+ public LoggerCreationEventArgs(Logger log) => Logger = log;
///
/// Gets the that has been created.
///
- ///
- /// The that has been created.
- ///
- ///
- ///
- /// The that has been created.
- ///
- ///
public Logger Logger { get; }
}
@@ -88,135 +68,91 @@ public LoggerCreationEventArgs(Logger log)
/// directly.
///
///
- /// This class is specialized in retrieving loggers by name and
- /// also maintaining the logger hierarchy. Implements the
- /// interface.
+ /// This class is specialized in retrieving loggers by name and also maintaining the logger
+ /// hierarchy. Implements the interface.
///
///
/// The structure of the logger hierarchy is maintained by the
- /// method. The hierarchy is such that children
+ /// 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.
///
///
- /// 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.
+ /// 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.
///
///
/// Nicko Cadell
/// Gert Driesen
public class Hierarchy : LoggerRepositorySkeleton, IBasicRepositoryConfigurator, IXmlRepositoryConfigurator
{
+ private readonly ConcurrentDictionary loggers = new(LoggerKey.ComparerInstance);
+ private ILoggerFactory defaultFactory;
+ private Logger? rootLogger;
+
///
- /// Event used to notify that a logger has been created.
+ /// The fully qualified type of the Hierarchy class.
///
///
- ///
- /// Event raised when a logger is created.
- ///
+ /// Used by the internal logger to record the type of the log message.
///
+ private static readonly Type declaringType = typeof(Hierarchy);
+
+ ///
+ /// Event used to notify that a logger has been created.
+ ///
public event LoggerCreationEventHandler? LoggerCreatedEvent;
///
/// Default constructor
///
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- ///
public Hierarchy() : this(new DefaultLoggerFactory())
- {
- }
+ { }
///
/// Construct with properties
///
/// The properties to pass to this repository.
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- ///
public Hierarchy(PropertiesDictionary properties) : this(properties, new DefaultLoggerFactory())
- {
- }
+ { }
///
/// Construct with a logger factory
///
/// The factory to use to create new logger instances.
- ///
- ///
- /// Initializes a new instance of the class with
- /// the specified .
- ///
- ///
public Hierarchy(ILoggerFactory loggerFactory) : this(new PropertiesDictionary(), loggerFactory)
- {
- }
+ { }
///
/// Construct with properties and a logger factory
///
/// The properties to pass to this repository.
/// The factory to use to create new logger instances.
- ///
- ///
- /// Initializes a new instance of the class with
- /// the specified .
- ///
- ///
- public Hierarchy(PropertiesDictionary properties, ILoggerFactory loggerFactory) : base(properties)
- {
- if (loggerFactory is null)
- {
- throw new ArgumentNullException(nameof(loggerFactory));
- }
-
- defaultFactory = loggerFactory;
- }
+ public Hierarchy(PropertiesDictionary properties, ILoggerFactory loggerFactory)
+ : base(properties) => defaultFactory = loggerFactory.EnsureNotNull();
///
/// Has no appender warning been emitted
///
///
- ///
- /// Flag to indicate if we have already issued a warning
- /// about not having an appender warning.
- ///
+ /// Flag to indicate if we have already issued a warning about not having an appender warning.
///
- public bool EmittedNoAppenderWarning { get; set; }
+ internal bool EmittedNoAppenderWarning { get; set; }
///
/// Get the root of this hierarchy
///
- ///
- ///
- /// Get the root of this hierarchy.
- ///
- ///
public Logger Root
{
get
{
if (rootLogger is null)
{
- lock (this)
- {
- if (rootLogger is null)
- {
- // Create the root logger
- Logger root = defaultFactory.CreateLogger(this, null);
- root.Hierarchy = this;
-
- // Store root
- rootLogger = root;
- }
- }
+ Logger root = defaultFactory.CreateLogger(this, null);
+ root.Hierarchy = this;
+ Interlocked.CompareExchange(ref rootLogger, root, null);
}
return rootLogger;
}
@@ -244,7 +180,7 @@ public ILoggerFactory LoggerFactory
///
///
/// Check if the named logger exists in the hierarchy. If so return
- /// its reference, otherwise returns null.
+ /// its reference, otherwise returns .
///
///
public override ILogger? Exists(string name)
@@ -267,19 +203,8 @@ public ILoggerFactory LoggerFactory
public override 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.
- var loggers = new List(this.loggers.Count);
-
- // Iterate through m_ht values
- foreach (object node in this.loggers.Values)
- {
- if (node is Logger logger)
- {
- loggers.Add(logger);
- }
- }
- return loggers.ToArray();
+ // loggers are Logger objects as there might be some ProvisionNodes as well.
+ return loggers.Values.OfType().ToArray();
}
///
@@ -287,15 +212,9 @@ public override ILogger[] GetCurrentLoggers()
/// the default factory.
///
///
- ///
- /// Return a new logger instance named as the first parameter using
- /// the default factory.
- ///
- ///
/// 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.
- ///
///
/// The name of the logger to retrieve
/// The logger object with the name specified
@@ -317,7 +236,7 @@ public override ILogger GetLogger(string name)
/// lost.
///
///
- /// The Shutdown method is careful to close nested
+ /// The method is careful to close nested
/// appenders before closing regular appenders. This allows
/// configurations where a regular appender is attached to a logger
/// and again to a nested appender.
@@ -355,8 +274,8 @@ public override void Shutdown()
///
/// 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 null,
- /// sets their additivity flag to true and sets the level
+ /// the level of all non-root loggers to ,
+ /// sets their additivity flag to and sets the level
/// of the root logger to . Moreover,
/// message disabling is set its default "off" value.
///
@@ -399,7 +318,7 @@ public override void ResetConfiguration()
/// using the method.
///
///
- /// The logEvent is delivered to the appropriate logger and
+ /// The is delivered to the appropriate logger and
/// that logger is then responsible for logging the event.
///
///
@@ -428,7 +347,7 @@ public override void Log(LoggingEvent logEvent)
///
public override IAppender[] GetAppenders()
{
- var appenderList = new List();
+ var appenderList = new HashSet();
CollectAppenders(appenderList, Root);
@@ -444,23 +363,18 @@ public override IAppender[] GetAppenders()
/// Collect the appenders from an .
/// The appender may also be a container.
///
- private static void CollectAppender(List appenderList, IAppender appender)
+ private static void CollectAppender(HashSet appenderList, IAppender appender)
{
- if (!appenderList.Contains(appender))
+ if (appenderList.Add(appender) && appender is IAppenderAttachable container)
{
- appenderList.Add(appender);
-
- if (appender is IAppenderAttachable container)
- {
- CollectAppenders(appenderList, container);
- }
+ CollectAppenders(appenderList, container);
}
}
///
/// Collect the appenders from an container
///
- private static void CollectAppenders(List appenderList, IAppenderAttachable container)
+ private static void CollectAppenders(HashSet appenderList, IAppenderAttachable container)
{
foreach (IAppender appender in container.Appenders)
{
@@ -555,21 +469,11 @@ protected void XmlRepositoryConfigure(System.Xml.XmlElement element)
///
/// The level to check against.
///
- /// true if the repository is disabled for the level argument, false otherwise.
+ /// if the repository is disabled for the level argument, otherwise.
///
///
- ///
- /// If this hierarchy has not been configured then this method will
- /// always return true.
- ///
- ///
- /// This method will return true if this repository is
- /// disabled for level object passed as parameter and
- /// false otherwise.
- ///
- ///
+ /// If this hierarchy has not been configured then this method will always return .
/// See also the property.
- ///
///
public bool IsDisabled(Level level)
{
@@ -591,10 +495,10 @@ public bool IsDisabled(Level level)
/// logger hierarchy.
///
///
- /// You should really know what you are doing before
- /// invoking this method.
+ /// You should really know what you are doing before invoking this method.
///
///
+ [EditorBrowsable(EditorBrowsableState.Never)]
public void Clear() => loggers.Clear();
///
@@ -716,8 +620,7 @@ protected virtual void OnLoggerCreationEvent(Logger logger)
///
/// The entry is of type ProvisionNode for this potential parent.
///
- /// We add to the list of children for this
- /// potential parent.
+ /// We add to the list of children for this potential parent.
///
///
///
@@ -814,9 +717,7 @@ private static void UpdateChildren(ProvisionNode pn, Logger log)
///
/// the level values
///
- ///
/// Supports setting levels via the configuration file.
- ///
///
internal void AddLevel(LevelEntry levelEntry)
{
@@ -842,48 +743,25 @@ internal void AddLevel(LevelEntry levelEntry)
///
/// A class to hold the value, name and display name for a level
///
- ///
- ///
- /// A class to hold the value, name and display name for a level
- ///
- ///
internal sealed class LevelEntry
{
///
/// Value of the level
///
///
- ///
/// If the value is not set (defaults to -1) the value will be looked
/// up for the current level with the same name.
- ///
///
public int Value { get; set; } = -1;
///
/// Name of the level
///
- ///
- /// The name of the level
- ///
- ///
- ///
- /// The name of the level.
- ///
- ///
public string? Name { get; set; }
///
/// Display name for the level
///
- ///
- /// The display name of the level
- ///
- ///
- ///
- /// The display name of the level.
- ///
- ///
public string? DisplayName { get; set; }
///
@@ -899,28 +777,9 @@ public override string ToString()
///
/// the property value
///
- ///
- /// Set a Property using the values in the argument.
- ///
- ///
/// Supports setting property values via the configuration file.
- ///
///
internal void AddProperty(PropertyEntry propertyEntry)
=> Properties[propertyEntry.Key.EnsureNotNull()] = propertyEntry.EnsureNotNull().Value;
-
- private ILoggerFactory defaultFactory;
-
- private readonly ConcurrentDictionary loggers = new(LoggerKey.ComparerInstance);
- private Logger? rootLogger;
-
- ///
- /// The fully qualified type of the Hierarchy class.
- ///
- ///
- /// Used by the internal logger to record the Type of the
- /// log message.
- ///
- private static readonly Type declaringType = typeof(Hierarchy);
}
}
\ No newline at end of file
diff --git a/src/log4net/Repository/Hierarchy/Logger.cs b/src/log4net/Repository/Hierarchy/Logger.cs
index c946813d..baa41b27 100644
--- a/src/log4net/Repository/Hierarchy/Logger.cs
+++ b/src/log4net/Repository/Hierarchy/Logger.cs
@@ -52,6 +52,36 @@ namespace log4net.Repository.Hierarchy
/// Douglas de la Torre
public abstract class Logger : IAppenderAttachable, ILogger
{
+ ///
+ /// The fully qualified type of the Logger class.
+ ///
+ private static readonly Type declaringType = typeof(Logger);
+
+ ///
+ /// The parent of this logger.
+ ///
+ ///
+ ///
+ /// All loggers have at least one ancestor which is the root logger.
+ ///
+ ///
+ private Logger? parent;
+
+ ///
+ /// Loggers need to know what Hierarchy they are in.
+ ///
+ private Hierarchy? hierarchy;
+
+ ///
+ /// Helper implementation of the interface
+ ///
+ private AppenderAttachedImpl? appenderAttachedImpl;
+
+ ///
+ /// Lock to protect AppenderAttachedImpl variable m_appenderAttachedImpl
+ ///
+ private readonly ReaderWriterLock appenderLock = new();
+
///
/// This constructor created a new instance and
/// sets its name.
@@ -68,10 +98,8 @@ public abstract class Logger : IAppenderAttachable, ILogger
/// logger creator.
///
///
- protected Logger(string name)
- {
- Name = string.Intern(name);
- }
+ protected Logger(string name)
+ => Name = string.Intern(name);
///
/// Gets or sets the parent logger in the hierarchy.
@@ -87,29 +115,29 @@ protected Logger(string name)
///
public virtual Logger? Parent
{
- get => m_parent;
- set => m_parent = value;
+ get => parent;
+ set => parent = value;
}
///
/// Gets or sets a value indicating if child loggers inherit their parent's appenders.
///
///
- /// true if child loggers inherit their parent's appenders.
+ /// if child loggers inherit their parent's appenders.
///
///
///
- /// Additivity is set to true by default, that is children inherit
+ /// Additivity is set to by default, that is children inherit
/// the appenders of their ancestors by default. If this variable is
- /// set to false then the appenders found in the
+ /// set to then the appenders found in the
/// ancestors of this logger are not used. However, the children
/// of this logger will inherit its appenders, unless the children
- /// have their additivity flag set to false too. See
+ /// have their additivity flag set to too. See
/// the user manual for more details.
///
///
public virtual bool Additivity { get; set; } = true;
-
+
///
/// Gets the effective level for this logger.
///
@@ -125,11 +153,11 @@ public virtual Logger? Parent
///
public virtual Level EffectiveLevel
{
- get
+ get
{
- for (Logger? c = this; c is not null; c = c.m_parent)
+ for (Logger? c = this; c is not null; c = c.parent)
{
- if (c.Level is Level level)
+ if (c.Level is Level level)
{
return level;
}
@@ -139,26 +167,17 @@ public virtual Level EffectiveLevel
}
///
- /// Gets or sets the where this
- /// Logger instance is attached to.
+ /// Gets or sets the where this instance is attached to.
///
- ///
- ///
- /// This logger must be attached to a single .
- ///
- ///
public virtual Hierarchy? Hierarchy
{
- get => m_hierarchy;
- set => m_hierarchy = value;
+ get => hierarchy;
+ set => hierarchy = value;
}
///
- /// Gets or sets the assigned , if any, for this Logger.
+ /// Gets or sets the assigned for this Logger.
///
- ///
- /// The of this logger.
- ///
public virtual Level? Level { get; set; }
///
@@ -172,22 +191,19 @@ public virtual Hierarchy? Hierarchy
/// appenders, then it won't be added again.
///
///
- public virtual void AddAppender(IAppender newAppender)
+ public virtual void AddAppender(IAppender newAppender)
{
- if (newAppender is null)
- {
- throw new ArgumentNullException(nameof(newAppender));
- }
+ newAppender.EnsureNotNull();
- m_appenderLock.AcquireWriterLock();
+ appenderLock.AcquireWriterLock();
try
{
- m_appenderAttachedImpl ??= new AppenderAttachedImpl();
- m_appenderAttachedImpl.AddAppender(newAppender);
+ appenderAttachedImpl ??= new AppenderAttachedImpl();
+ appenderAttachedImpl.AddAppender(newAppender);
}
finally
{
- m_appenderLock.ReleaseWriterLock();
+ appenderLock.ReleaseWriterLock();
}
}
@@ -199,49 +215,46 @@ public virtual void AddAppender(IAppender newAppender)
/// A collection of the appenders in this logger. If no appenders
/// can be found, then a is returned.
///
- public virtual AppenderCollection Appenders
+ public virtual AppenderCollection Appenders
{
get
{
- m_appenderLock.AcquireReaderLock();
+ appenderLock.AcquireReaderLock();
try
{
- if (m_appenderAttachedImpl is null)
+ if (appenderAttachedImpl is null)
{
return AppenderCollection.EmptyCollection;
}
- else
- {
- return m_appenderAttachedImpl.Appenders;
- }
+ return appenderAttachedImpl.Appenders;
}
finally
{
- m_appenderLock.ReleaseReaderLock();
+ appenderLock.ReleaseReaderLock();
}
}
}
///
- /// Look for the appender named as name
+ /// Look for the appender named as
///
/// The name of the appender to lookup
- /// The appender with the name specified, or null.
- public virtual IAppender? GetAppender(string? name)
+ /// The appender with the name specified, or .
+ public virtual IAppender? GetAppender(string? name)
{
- m_appenderLock.AcquireReaderLock();
+ appenderLock.AcquireReaderLock();
try
{
- if (m_appenderAttachedImpl is null || name is null)
+ if (appenderAttachedImpl is null || name is null)
{
return null;
}
- return m_appenderAttachedImpl.GetAppender(name);
+ return appenderAttachedImpl.GetAppender(name);
}
finally
{
- m_appenderLock.ReleaseReaderLock();
+ appenderLock.ReleaseReaderLock();
}
}
@@ -253,20 +266,20 @@ public virtual AppenderCollection Appenders
/// This is useful when re-reading configuration information.
///
///
- public virtual void RemoveAllAppenders()
+ public virtual void RemoveAllAppenders()
{
- m_appenderLock.AcquireWriterLock();
+ appenderLock.AcquireWriterLock();
try
{
- if (m_appenderAttachedImpl is not null)
+ if (appenderAttachedImpl is not null)
{
- m_appenderAttachedImpl.RemoveAllAppenders();
- m_appenderAttachedImpl = null;
+ appenderAttachedImpl.RemoveAllAppenders();
+ appenderAttachedImpl = null;
}
}
finally
{
- m_appenderLock.ReleaseWriterLock();
+ appenderLock.ReleaseWriterLock();
}
}
@@ -282,19 +295,19 @@ public virtual void RemoveAllAppenders()
/// on the appender removed.
///
///
- public virtual IAppender? RemoveAppender(IAppender? appender)
+ public virtual IAppender? RemoveAppender(IAppender? appender)
{
- m_appenderLock.AcquireWriterLock();
+ appenderLock.AcquireWriterLock();
try
{
- if (appender is not null && m_appenderAttachedImpl is not null)
+ if (appender is not null && appenderAttachedImpl is not null)
{
- return m_appenderAttachedImpl.RemoveAppender(appender);
+ return appenderAttachedImpl.RemoveAppender(appender);
}
}
finally
{
- m_appenderLock.ReleaseWriterLock();
+ appenderLock.ReleaseWriterLock();
}
return null;
}
@@ -311,23 +324,23 @@ public virtual void RemoveAllAppenders()
/// on the appender removed.
///
///
- public virtual IAppender? RemoveAppender(string? name)
+ public virtual IAppender? RemoveAppender(string? name)
{
- m_appenderLock.AcquireWriterLock();
+ appenderLock.AcquireWriterLock();
try
{
- if (name is not null && m_appenderAttachedImpl is not null)
+ if (name is not null && appenderAttachedImpl is not null)
{
- return m_appenderAttachedImpl.RemoveAppender(name);
+ return appenderAttachedImpl.RemoveAppender(name);
}
}
finally
{
- m_appenderLock.ReleaseWriterLock();
+ appenderLock.ReleaseWriterLock();
}
return null;
}
-
+
///
/// Gets the logger name.
///
@@ -350,7 +363,7 @@ public virtual void RemoveAllAppenders()
/// This method must not throw any exception to the caller.
///
///
- public virtual void Log(Type? callerStackBoundaryDeclaringType, Level? level, object? message, Exception? exception)
+ public virtual void Log(Type? callerStackBoundaryDeclaringType, Level? level, object? message, Exception? exception)
{
try
{
@@ -401,7 +414,8 @@ public virtual void Log(LoggingEvent? logEvent)
///
/// The level to check.
///
- /// true if this logger is enabled for level, otherwise false.
+ /// if this logger is enabled for ,
+ /// otherwise .
///
///
///
@@ -414,7 +428,7 @@ public virtual bool IsEnabledFor(Level? level)
{
if (level is not null)
{
- if (m_hierarchy is not null && m_hierarchy.IsDisabled(level))
+ if (hierarchy is not null && hierarchy.IsDisabled(level))
{
return false;
}
@@ -430,9 +444,9 @@ public virtual bool IsEnabledFor(Level? level)
///
/// Gets the where this
- /// Logger instance is attached to.
+ /// instance is attached to.
///
- public ILoggerRepository? Repository => m_hierarchy;
+ public ILoggerRepository? Repository => hierarchy;
///
/// Deliver the to the attached appenders.
@@ -440,9 +454,8 @@ public virtual bool IsEnabledFor(Level? level)
/// The event to log.
///
///
- /// Call the appenders in the hierarchy starting at
- /// this. If no appenders could be found, emit a
- /// warning.
+ /// Call the appenders in the hierarchy starting at .
+ /// If no appenders could be found, emit a warning.
///
///
/// This method calls all the appenders inherited from the
@@ -450,40 +463,37 @@ public virtual bool IsEnabledFor(Level? level)
/// to log the particular log request.
///
///
- protected virtual void CallAppenders(LoggingEvent loggingEvent)
+ protected virtual void CallAppenders(LoggingEvent loggingEvent)
{
- if (loggingEvent is null)
- {
- throw new ArgumentNullException(nameof(loggingEvent));
- }
+ loggingEvent.EnsureNotNull();
int writes = 0;
- for(Logger? c = this; c is not null; c = c.m_parent)
+ for (Logger? c = this; c is not null; c = c.parent)
{
- if (c.m_appenderAttachedImpl is not null)
+ if (c.appenderAttachedImpl is not null)
{
// Protected against simultaneous call to addAppender, removeAppender,...
- c.m_appenderLock.AcquireReaderLock();
+ c.appenderLock.AcquireReaderLock();
try
{
- if (c.m_appenderAttachedImpl is not null)
+ if (c.appenderAttachedImpl is not null)
{
- writes += c.m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvent);
+ writes += c.appenderAttachedImpl.AppendLoopOnAppenders(loggingEvent);
}
}
finally
{
- c.m_appenderLock.ReleaseReaderLock();
+ c.appenderLock.ReleaseReaderLock();
}
}
- if (!c.Additivity)
+ if (!c.Additivity)
{
break;
}
}
-
+
// No appenders in hierarchy, warn user only once.
//
// Note that by including the AppDomain values for the currently running
@@ -493,9 +503,9 @@ protected virtual void CallAppenders(LoggingEvent loggingEvent)
// or impossible to determine which .config file is missing appender
// definitions.
//
- if (m_hierarchy is not null && !m_hierarchy.EmittedNoAppenderWarning && writes == 0)
+ if (hierarchy is not null && !hierarchy.EmittedNoAppenderWarning && writes == 0)
{
- m_hierarchy.EmittedNoAppenderWarning = true;
+ hierarchy.EmittedNoAppenderWarning = true;
LogLog.Debug(declaringType, $"No appenders could be found for logger [{Name}] repository [{Repository?.Name}]");
LogLog.Debug(declaringType, "Please initialize the log4net system properly.");
try
@@ -505,7 +515,7 @@ protected virtual void CallAppenders(LoggingEvent loggingEvent)
LogLog.Debug(declaringType, " FriendlyName : " + AppDomain.CurrentDomain.FriendlyName);
LogLog.Debug(declaringType, " DynamicDirectory: " + AppDomain.CurrentDomain.DynamicDirectory);
}
- catch(System.Security.SecurityException)
+ catch (System.Security.SecurityException)
{
// Insufficient permissions to display info from the AppDomain
}
@@ -520,15 +530,15 @@ protected virtual void CallAppenders(LoggingEvent loggingEvent)
/// Used to ensure that the appenders are correctly shutdown.
///
///
- public virtual void CloseNestedAppenders()
+ public virtual void CloseNestedAppenders()
{
- m_appenderLock.AcquireWriterLock();
+ appenderLock.AcquireWriterLock();
try
{
- if (m_appenderAttachedImpl is not null)
+ if (appenderAttachedImpl is not null)
{
- AppenderCollection appenders = m_appenderAttachedImpl.Appenders;
- foreach(IAppender appender in appenders)
+ AppenderCollection appenders = appenderAttachedImpl.Appenders;
+ foreach (IAppender appender in appenders)
{
if (appender is IAppenderAttachable)
{
@@ -539,7 +549,7 @@ public virtual void CloseNestedAppenders()
}
finally
{
- m_appenderLock.ReleaseWriterLock();
+ appenderLock.ReleaseWriterLock();
}
}
@@ -555,7 +565,7 @@ public virtual void CloseNestedAppenders()
/// the .
///
///
- public virtual void Log(Level level, object? message, Exception? exception)
+ public virtual void Log(Level level, object? message, Exception? exception)
{
if (IsEnabledFor(level))
{
@@ -577,9 +587,11 @@ public virtual void Log(Level level, object? message, Exception? exception)
/// appenders.
///
///
- protected virtual void ForcedLog(Type callerStackBoundaryDeclaringType, Level? level, object? message, Exception? exception)
+ protected virtual void ForcedLog(Type callerStackBoundaryDeclaringType, Level? level,
+ object? message, Exception? exception)
{
- CallAppenders(new LoggingEvent(callerStackBoundaryDeclaringType, Hierarchy, Name, level, message, exception));
+ CallAppenders(new LoggingEvent(callerStackBoundaryDeclaringType, Hierarchy, Name, level,
+ message, exception));
}
///
@@ -591,7 +603,7 @@ protected virtual void ForcedLog(Type callerStackBoundaryDeclaringType, Level? l
/// Delivers the logging event to the attached appenders.
///
///
- protected virtual void ForcedLog(LoggingEvent logEvent)
+ protected virtual void ForcedLog(LoggingEvent logEvent)
{
// The logging event may not have been created by this logger
// the Repository may not be correctly set on the event. This
@@ -600,35 +612,5 @@ protected virtual void ForcedLog(LoggingEvent logEvent)
CallAppenders(logEvent);
}
-
- ///
- /// The fully qualified type of the Logger class.
- ///
- private static readonly Type declaringType = typeof(Logger);
-
- ///
- /// The parent of this logger.
- ///
- ///
- ///
- /// All loggers have at least one ancestor which is the root logger.
- ///
- ///
- private Logger? m_parent;
-
- ///
- /// Loggers need to know what Hierarchy they are in.
- ///
- private Hierarchy? m_hierarchy;
-
- ///
- /// Helper implementation of the interface
- ///
- private AppenderAttachedImpl? m_appenderAttachedImpl;
-
- ///
- /// Lock to protect AppenderAttachedImpl variable m_appenderAttachedImpl
- ///
- private readonly ReaderWriterLock m_appenderLock = new();
}
-}
+}
\ No newline at end of file
diff --git a/src/log4net/Repository/Hierarchy/ProvisionNode.cs b/src/log4net/Repository/Hierarchy/ProvisionNode.cs
index 47628519..47b8c59e 100644
--- a/src/log4net/Repository/Hierarchy/ProvisionNode.cs
+++ b/src/log4net/Repository/Hierarchy/ProvisionNode.cs
@@ -31,8 +31,7 @@ namespace log4net.Repository.Hierarchy
/// for that node.
///
///
- /// A provision node holds a list of child loggers on behalf of
- /// a logger that does not exist.
+ /// A provision node holds a list of child loggers on behalf of a logger that does not exist.
///
///
/// Nicko Cadell
@@ -43,12 +42,6 @@ internal sealed class ProvisionNode : List
/// Create a new provision node with child node
///
/// A child logger to add to this node.
- ///
- ///
- /// Initializes a new instance of the class
- /// with the specified child logger.
- ///
- ///
internal ProvisionNode(Logger log)
{
Add(log);
diff --git a/src/log4net/assembly/bin.xml b/src/log4net/assembly/bin.xml
deleted file mode 100644
index c52bf0de..00000000
--- a/src/log4net/assembly/bin.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
- bin
-
- zip
- tar.gz
-
- apache-log4j-${project.version}
- true
-
-
-
- *.txt
- *.sample
- *.xml
- INSTALL
- KEYS
- LICENSE
- NOTICE
- contribs/**
- examples/**
- src/assembly/**
- src/changes/**
- src/main/**
- src/ntdll/**
- src/performance/**
- src/site/**
- tests/README
- tests/*.xml
- tests/*.sample
- tests/*.bat
- tests/input/**
- tests/resources/**
- tests/src/**
- tests/witness/**
-
-
-
-
-
-
-
-
-
- 0755
-
-
-
diff --git a/src/site/xdoc/release/release-notes.xml b/src/site/xdoc/release/release-notes.xml
index 274ecc1c..08eb9b4f 100644
--- a/src/site/xdoc/release/release-notes.xml
+++ b/src/site/xdoc/release/release-notes.xml
@@ -147,6 +147,10 @@ limitations under the License.
log4net.Appender.MemoryAppender.m_eventsList (protected field) is now List<LoggingEvent> (instead of System.Collections.ArrayList before)
The reason is an optimization as part of Add support for nullable annotations
+