diff --git a/src/log4net.Tests/Core/LevelMapTest.cs b/src/log4net.Tests/Core/LevelMapTest.cs index 234550d7..1b3e5910 100644 --- a/src/log4net.Tests/Core/LevelMapTest.cs +++ b/src/log4net.Tests/Core/LevelMapTest.cs @@ -21,48 +21,47 @@ using NUnit.Framework; -namespace log4net.Tests.Core +namespace log4net.Tests.Core; + +/// +/// Used for internal unit testing the class. +/// +[TestFixture] +public sealed class LevelMapTest { /// - /// Used for internal unit testing the class. + /// Tests the creation of a and calling its method /// - [TestFixture] - public sealed class LevelMapTest + [Test] + public void LevelMapCreateClear() { - /// - /// Tests the creation of a and calling its method - /// - [Test] - public void LevelMapCreateClear() - { - var map = new LevelMap(); - LevelCollection allLevels = map.AllLevels; - Assert.AreEqual(0, allLevels.Count); - Assert.IsNull(map["nonexistent"]); + var map = new LevelMap(); + LevelCollection allLevels = map.AllLevels; + Assert.AreEqual(0, allLevels.Count); + Assert.IsNull(map["nonexistent"]); - map.Add("level1234", 1234, "displayName"); - allLevels = map.AllLevels; - Assert.AreEqual(1, allLevels.Count); - Assert.AreEqual("level1234", allLevels[0].Name); - Assert.AreEqual("displayName", allLevels[0].DisplayName); - Assert.AreEqual(1234, allLevels[0].Value); - Level? level1234 = map["level1234"]; - Assert.IsNotNull(level1234); - Assert.AreSame(level1234, allLevels[0]); + map.Add("level1234", 1234, "displayName"); + allLevels = map.AllLevels; + Assert.AreEqual(1, allLevels.Count); + Assert.AreEqual("level1234", allLevels[0].Name); + Assert.AreEqual("displayName", allLevels[0].DisplayName); + Assert.AreEqual(1234, allLevels[0].Value); + Level? level1234 = map["level1234"]; + Assert.IsNotNull(level1234); + Assert.AreSame(level1234, allLevels[0]); - Level lookupLevel = map.LookupWithDefault(level1234!); - Assert.AreSame(level1234, lookupLevel); + Level lookupLevel = map.LookupWithDefault(level1234!); + Assert.AreSame(level1234, lookupLevel); - var otherLevel = new Level(5678, "level5678", "display"); - lookupLevel = map.LookupWithDefault(otherLevel); - Assert.AreSame(otherLevel, lookupLevel); - Assert.AreSame(otherLevel, map["LEVEL5678"]); + var otherLevel = new Level(5678, "level5678", "display"); + lookupLevel = map.LookupWithDefault(otherLevel); + Assert.AreSame(otherLevel, lookupLevel); + Assert.AreSame(otherLevel, map["LEVEL5678"]); - map.Clear(); - allLevels = map.AllLevels; - Assert.AreEqual(0, allLevels.Count); - Assert.IsNull(map["level1234"]); - Assert.IsNull(map["LEVEL5678"]); - } + map.Clear(); + allLevels = map.AllLevels; + Assert.AreEqual(0, allLevels.Count); + Assert.IsNull(map["level1234"]); + Assert.IsNull(map["LEVEL5678"]); } } \ No newline at end of file diff --git a/src/log4net.Tests/Core/LevelMappingTest.cs b/src/log4net.Tests/Core/LevelMappingTest.cs new file mode 100644 index 00000000..6a6dec62 --- /dev/null +++ b/src/log4net.Tests/Core/LevelMappingTest.cs @@ -0,0 +1,124 @@ +#region Apache License +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to you 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 System.Collections.Generic; +using System.Linq; +using System.Reflection; +using log4net.Core; +using log4net.Util; +using NUnit.Framework; + +namespace log4net.Tests.Core; + +/// +/// Used for internal unit testing the class. +/// +[TestFixture] +public sealed class LevelMappingTest +{ + /// + private sealed class MappingEntry : LevelMappingEntry + { + /// + internal MappingEntry(Level level) => Level = level; + + /// + public override string ToString() => $"{Level?.Value} - {Level?.Name}"; + } + + /// + /// Tests the sorting of the entries + /// + [Test] + public void SortEntriesTest() + { + MappingEntry[] unsorted = [ + new(Level.Info), + new(Level.Off), + new(Level.Emergency), + new(Level.Error), + new(Level.Alert), + new(Level.All), + new(Level.Critical), + new(Level.Debug), + new(Level.Fatal), + new(Level.Fine), + new(Level.Finer), + new(Level.Finest), + new(Level.Log4Net_Debug), + new(Level.Notice), + new(Level.Severe), + new(Level.Trace), + new(Level.Verbose), + new(Level.Warn) + ]; + LevelMapping mapping = new(); + foreach (MappingEntry entry in unsorted) + { + mapping.Add(entry); + } + + List withoutDuplicates = unsorted.GroupBy(entry => entry.Level!.Value) + .Select(group => group.Last()).ToList(); + + List sorted = (List)typeof(LevelMapping) + .GetMethod("SortEntries", BindingFlags.NonPublic | BindingFlags.Instance)! + .Invoke(mapping, Array.Empty())!; + + CollectionAssert.AreEquivalent(withoutDuplicates, sorted); + CollectionAssert.AreNotEqual(withoutDuplicates, sorted); + + int lowestLevelSeen = int.MaxValue; + foreach (LevelMappingEntry entry in sorted) + { + Assert.IsTrue(lowestLevelSeen >= entry.Level!.Value, entry.Level.Name); + lowestLevelSeen = entry.Level!.Value; + } + Assert.AreEqual(Level.All.Value, lowestLevelSeen); + } + + /// + /// Tests the method + /// + [Test] + public void LookupTest() + { + LevelMapping mapping = new(); + mapping.Add(new MappingEntry(Level.Info)); + mapping.Add(new MappingEntry(Level.Off)); + mapping.Add(new MappingEntry(Level.Emergency)); + mapping.Add(new MappingEntry(Level.Warn)); + + Assert.IsNull(mapping.Lookup(Level.Info)?.Level); + + mapping.ActivateOptions(); + + Assert.AreEqual(Level.Info, mapping.Lookup(Level.Info)?.Level); + Assert.AreEqual(Level.Off, mapping.Lookup(Level.Off)?.Level); + Assert.AreEqual(Level.Emergency, mapping.Lookup(Level.Emergency)?.Level); + Assert.AreEqual(Level.Warn, mapping.Lookup(Level.Warn)?.Level); + Assert.AreEqual(Level.Warn, mapping.Lookup(Level.Error)?.Level); + Assert.IsNull(mapping.Lookup(Level.Fine)?.Level); + Assert.AreEqual(Level.Emergency, mapping.Lookup(Level.Log4Net_Debug)?.Level); + Assert.IsNull(mapping.Lookup(Level.Trace)?.Level); + Assert.AreEqual(Level.Warn, mapping.Lookup(Level.Alert)?.Level); + Assert.IsNull(mapping.Lookup(Level.All)?.Level); + } +} \ No newline at end of file diff --git a/src/log4net.Tests/Core/LevelTest.cs b/src/log4net.Tests/Core/LevelTest.cs index 959ec3e1..c56370d1 100644 --- a/src/log4net.Tests/Core/LevelTest.cs +++ b/src/log4net.Tests/Core/LevelTest.cs @@ -23,50 +23,49 @@ using NUnit.Framework; -namespace log4net.Tests.Core +namespace log4net.Tests.Core; + +/// +/// Used for internal unit testing the class. +/// +[TestFixture] +public sealed class LevelTest { /// - /// Used for internal unit testing the class. + /// Tests the comparison between two s /// - [TestFixture] - public sealed class LevelTest + [Test] + public void LevelCompare() { - /// - /// Tests the comparison between two s - /// - [Test] - public void LevelCompare() - { - Level? nullLevel = null; - int? nullInt = null; - Compare(nullInt, nullInt, nullLevel, nullLevel); - Compare(nullInt, Level.Verbose.Value, nullLevel, Level.Verbose); - Compare(Level.Verbose.Value, nullInt, Level.Verbose, nullLevel); - Compare(Level.Verbose.Value, Level.Verbose.Value, Level.Verbose, Level.Verbose); - Compare(Level.Debug.Value, Level.Verbose.Value, Level.Debug, Level.Verbose); - } + Level? nullLevel = null; + int? nullInt = null; + Compare(nullInt, nullInt, nullLevel, nullLevel); + Compare(nullInt, Level.Verbose.Value, nullLevel, Level.Verbose); + Compare(Level.Verbose.Value, nullInt, Level.Verbose, nullLevel); + Compare(Level.Verbose.Value, Level.Verbose.Value, Level.Verbose, Level.Verbose); + Compare(Level.Debug.Value, Level.Verbose.Value, Level.Debug, Level.Verbose); + } - private static void Compare(int? leftInt, int? rightInt, Level? left, Level? right, - [CallerArgumentExpression(nameof(left))] string leftName = "", - [CallerArgumentExpression(nameof(right))] string rightName = "") + private static void Compare(int? leftInt, int? rightInt, Level? left, Level? right, + [CallerArgumentExpression(nameof(left))] string leftName = "", + [CallerArgumentExpression(nameof(right))] string rightName = "") + { + Assert.AreEqual(leftInt < rightInt, left < right, "{0} < {1}", leftName, rightName); + Assert.AreEqual(leftInt > rightInt, left > right, "{0} > {1}", leftName, rightName); + Assert.AreEqual(leftInt <= rightInt, left <= right, "{0} <= {1}", leftName, rightName); + Assert.AreEqual(leftInt >= rightInt, left >= right, "{0} >= {1}", leftName, rightName); + Assert.AreEqual(leftInt == rightInt, left == right, "{0} == {1}", leftName, rightName); + Assert.AreEqual(leftInt != rightInt, left != right, "{0} != {1}", leftName, rightName); + Assert.AreEqual(leftInt?.Equals(rightInt), left?.Equals(right), "{0}?.Equals({1})", leftName, rightName); + if (leftInt is not null) { - Assert.AreEqual(leftInt < rightInt, left < right, "{0} < {1}", leftName, rightName); - Assert.AreEqual(leftInt > rightInt, left > right, "{0} > {1}", leftName, rightName); - Assert.AreEqual(leftInt <= rightInt, left <= right, "{0} <= {1}", leftName, rightName); - Assert.AreEqual(leftInt >= rightInt, left >= right, "{0} >= {1}", leftName, rightName); - Assert.AreEqual(leftInt == rightInt, left == right, "{0} == {1}", leftName, rightName); - Assert.AreEqual(leftInt != rightInt, left != right, "{0} != {1}", leftName, rightName); - Assert.AreEqual(leftInt?.Equals(rightInt), left?.Equals(right), "{0}?.Equals({1})", leftName, rightName); - if (leftInt is not null) + if (rightInt is not null) + { + Assert.AreEqual(leftInt?.CompareTo(rightInt), left?.CompareTo(right!), "{0}?.CompareTo({1})", leftName, rightName); + } + else { - if (rightInt is not null) - { - Assert.AreEqual(leftInt?.CompareTo(rightInt), left?.CompareTo(right!), "{0}?.CompareTo({1})", leftName, rightName); - } - else - { - Assert.Throws(() => left!.CompareTo(right!)); - } + Assert.Throws(() => left!.CompareTo(right!)); } } } diff --git a/src/log4net.Tests/Core/LoggingEventTest.cs b/src/log4net.Tests/Core/LoggingEventTest.cs index e72840df..d5f535b0 100644 --- a/src/log4net.Tests/Core/LoggingEventTest.cs +++ b/src/log4net.Tests/Core/LoggingEventTest.cs @@ -28,89 +28,89 @@ using System.IO; using System.Runtime.Serialization.Formatters.Binary; -namespace log4net.Tests.Core +namespace log4net.Tests.Core; + +[TestFixture] +public sealed class LoggingEventTest { - [TestFixture] - public class LoggingEventTest - { - DateTime localTime = new DateTime(2000, 7, 1, 0, 0, 0, 0, CultureInfo.InvariantCulture.Calendar, DateTimeKind.Local); + private static readonly DateTime localTime + = new DateTime(2000, 7, 1, 0, 0, 0, 0, CultureInfo.InvariantCulture.Calendar, DateTimeKind.Local); - [Test] - public void SerializeDeserialize_BinaryFormatter() + [Test] + public void SerializeDeserialize_BinaryFormatter() + { + var timestamp = localTime.ToUniversalTime(); + var ev = new LoggingEvent(new LoggingEventData { - var timestamp = localTime.ToUniversalTime(); - var ev = new LoggingEvent(new LoggingEventData - { - LoggerName = "aLogger", - Level = Level.Log4Net_Debug, - Message = "aMessage", - ThreadName = "aThread", - TimeStampUtc = timestamp, - LocationInfo = new LocationInfo(GetType()), - UserName = "aUser", - Identity = "anIdentity", - ExceptionString = "anException", - Domain = "aDomain", - Properties = new PropertiesDictionary { ["foo"] = "bar" }, - }); + LoggerName = "aLogger", + Level = Level.Log4Net_Debug, + Message = "aMessage", + ThreadName = "aThread", + TimeStampUtc = timestamp, + LocationInfo = new LocationInfo(GetType()), + UserName = "aUser", + Identity = "anIdentity", + ExceptionString = "anException", + Domain = "aDomain", + Properties = new PropertiesDictionary { ["foo"] = "bar" }, + }); - var formatter = new BinaryFormatter(); - using var stream = new MemoryStream(); - formatter.Serialize(stream, ev); - stream.Position = 0; - var ev2 = (LoggingEvent)formatter.Deserialize(stream); + var formatter = new BinaryFormatter(); + using var stream = new MemoryStream(); + formatter.Serialize(stream, ev); + stream.Position = 0; + var ev2 = (LoggingEvent)formatter.Deserialize(stream); - Assert.AreEqual("aLogger", ev2.LoggerName); - Assert.AreEqual(Level.Log4Net_Debug, ev2.Level); - Assert.IsNull(ev2.MessageObject); - Assert.AreEqual("aMessage", ev2.RenderedMessage); - Assert.AreEqual("aThread", ev2.ThreadName); - Assert.AreEqual(timestamp, ev2.TimeStampUtc); - Assert.IsNotNull(ev2.LocationInfo); - Assert.AreEqual("System.RuntimeMethodHandle", ev2.LocationInfo!.ClassName); - Assert.AreEqual("InvokeMethod", ev2.LocationInfo!.MethodName); - Assert.IsNull(ev2.LocationInfo!.FileName); - Assert.AreEqual("0", ev2.LocationInfo!.LineNumber); - Assert.AreEqual("aUser", ev2.UserName); - Assert.AreEqual("anIdentity", ev2.Identity); - Assert.IsNull(ev2.ExceptionObject); - Assert.AreEqual("anException", ev2.GetExceptionString()); - Assert.AreEqual("aDomain", ev2.Domain); - Assert.AreEqual(1, ev.Properties.Count); - Assert.AreEqual("bar", ev2.Properties["foo"]); - } + Assert.AreEqual("aLogger", ev2.LoggerName); + Assert.AreEqual(Level.Log4Net_Debug, ev2.Level); + Assert.IsNull(ev2.MessageObject); + Assert.AreEqual("aMessage", ev2.RenderedMessage); + Assert.AreEqual("aThread", ev2.ThreadName); + Assert.AreEqual(timestamp, ev2.TimeStampUtc); + Assert.IsNotNull(ev2.LocationInfo); + Assert.AreEqual("System.RuntimeMethodHandle", ev2.LocationInfo!.ClassName); + Assert.AreEqual("InvokeMethod", ev2.LocationInfo!.MethodName); + Assert.IsNull(ev2.LocationInfo!.FileName); + Assert.AreEqual("0", ev2.LocationInfo!.LineNumber); + Assert.AreEqual("aUser", ev2.UserName); + Assert.AreEqual("anIdentity", ev2.Identity); + Assert.IsNull(ev2.ExceptionObject); + Assert.AreEqual("anException", ev2.GetExceptionString()); + Assert.AreEqual("aDomain", ev2.Domain); + Assert.AreEqual(1, ev.Properties.Count); + Assert.AreEqual("bar", ev2.Properties["foo"]); + } - /// - /// Loads and validates the cached serialized v2 event data from the log4net2-SerializeEvent directory. - /// - [Test] - public void DeserializeV2() - { - const string datPath = @"..\..\..\..\integration-testing\log4net2-SerializeEvent\SerializeV2Event.dat"; - using var stream = File.OpenRead(datPath); - var formatter = new BinaryFormatter(); - LoggingEvent ev = (LoggingEvent)formatter.Deserialize(stream); - Assert.IsNotNull(ev); + /// + /// Loads and validates the cached serialized v2 event data from the log4net2-SerializeEvent directory. + /// + [Test] + public void DeserializeV2() + { + const string datPath = @"..\..\..\..\integration-testing\log4net2-SerializeEvent\SerializeV2Event.dat"; + using var stream = File.OpenRead(datPath); + var formatter = new BinaryFormatter(); + LoggingEvent ev = (LoggingEvent)formatter.Deserialize(stream); + Assert.IsNotNull(ev); - Assert.AreEqual("aLogger", ev!.LoggerName); - Assert.AreEqual(Level.Log4Net_Debug, ev.Level); - Assert.IsNull(ev.MessageObject); - Assert.AreEqual("aMessage", ev.RenderedMessage); - Assert.AreEqual("aThread", ev.ThreadName); - Assert.IsNotNull(ev.LocationInfo); - Assert.AreEqual("?", ev.LocationInfo!.ClassName); - Assert.AreEqual("?", ev.LocationInfo!.MethodName); - Assert.AreEqual("?", ev.LocationInfo!.FileName); - Assert.AreEqual("?", ev.LocationInfo!.LineNumber); - Assert.AreEqual("aUser", ev.UserName); - Assert.AreEqual("anIdentity", ev.Identity); - Assert.IsNull(ev.ExceptionObject); - Assert.AreEqual("anException", ev.GetExceptionString()); - Assert.AreEqual("aDomain", ev.Domain); - Assert.AreEqual(1, ev.Properties.Count); - Assert.AreEqual("bar", ev.Properties["foo"]); - Assert.AreEqual(localTime.ToUniversalTime(), ev.TimeStampUtc); - } + Assert.AreEqual("aLogger", ev!.LoggerName); + Assert.AreEqual(Level.Log4Net_Debug, ev.Level); + Assert.IsNull(ev.MessageObject); + Assert.AreEqual("aMessage", ev.RenderedMessage); + Assert.AreEqual("aThread", ev.ThreadName); + Assert.IsNotNull(ev.LocationInfo); + Assert.AreEqual("?", ev.LocationInfo!.ClassName); + Assert.AreEqual("?", ev.LocationInfo!.MethodName); + Assert.AreEqual("?", ev.LocationInfo!.FileName); + Assert.AreEqual("?", ev.LocationInfo!.LineNumber); + Assert.AreEqual("aUser", ev.UserName); + Assert.AreEqual("anIdentity", ev.Identity); + Assert.IsNull(ev.ExceptionObject); + Assert.AreEqual("anException", ev.GetExceptionString()); + Assert.AreEqual("aDomain", ev.Domain); + Assert.AreEqual(1, ev.Properties.Count); + Assert.AreEqual("bar", ev.Properties["foo"]); + Assert.AreEqual(localTime.ToUniversalTime(), ev.TimeStampUtc); } } #endif // NET462_OR_GREATER \ No newline at end of file diff --git a/src/log4net/Appender/AnsiColorTerminalAppender.cs b/src/log4net/Appender/AnsiColorTerminalAppender.cs index f1d602ab..831be2b7 100644 --- a/src/log4net/Appender/AnsiColorTerminalAppender.cs +++ b/src/log4net/Appender/AnsiColorTerminalAppender.cs @@ -215,18 +215,18 @@ public AnsiColorTerminalAppender() /// public virtual string Target { - get => m_writeToErrorStream ? ConsoleError : ConsoleOut; + get => writeToErrorStream ? ConsoleError : ConsoleOut; set { string trimmedTargetName = value.Trim(); if (SystemInfo.EqualsIgnoringCase(ConsoleError, trimmedTargetName)) { - m_writeToErrorStream = true; + writeToErrorStream = true; } else { - m_writeToErrorStream = false; + writeToErrorStream = false; } } } @@ -237,7 +237,7 @@ public virtual string Target /// The mapping to add public void AddMapping(LevelColors mapping) { - m_levelMapping.Add(mapping); + levelMapping.Add(mapping); } /// @@ -257,7 +257,7 @@ protected override void Append(LoggingEvent loggingEvent) string loggingMessage = RenderLoggingEvent(loggingEvent); // see if there is a specified lookup. - if (m_levelMapping.Lookup(loggingEvent.Level) is LevelColors levelColors) + if (levelMapping.Lookup(loggingEvent.Level) is LevelColors levelColors) { // Prepend the Ansi Color code loggingMessage = levelColors.CombinedColor + loggingMessage; @@ -294,7 +294,7 @@ protected override void Append(LoggingEvent loggingEvent) } } - if (m_writeToErrorStream) + if (writeToErrorStream) { // Write to the error stream Console.Error.Write(loggingMessage); @@ -318,17 +318,17 @@ protected override void Append(LoggingEvent loggingEvent) public override void ActivateOptions() { base.ActivateOptions(); - m_levelMapping.ActivateOptions(); + levelMapping.ActivateOptions(); } /// - /// The to use when writing to the Console + /// The to use when writing to the Console /// standard output stream. /// public const string ConsoleOut = "Console.Out"; /// - /// The to use when writing to the Console + /// The to use when writing to the Console /// standard error output stream. /// public const string ConsoleError = "Console.Error"; @@ -336,12 +336,12 @@ public override void ActivateOptions() /// /// Flag to write output to the error stream rather than the standard output stream /// - private bool m_writeToErrorStream; + private bool writeToErrorStream; /// /// Mapping from level object to color value /// - private readonly LevelMapping m_levelMapping = new(); + private readonly LevelMapping levelMapping = new(); /// /// Ansi code to reset terminal @@ -393,7 +393,7 @@ public override void ActivateOptions() { base.ActivateOptions(); - StringBuilder buf = new StringBuilder(); + StringBuilder buf = new(); // Reset any existing codes buf.Append("\x1b[0;"); @@ -449,4 +449,4 @@ public override void ActivateOptions() internal string CombinedColor { get; private set; } = string.Empty; } } -} +} \ No newline at end of file diff --git a/src/log4net/Core/Level.cs b/src/log4net/Core/Level.cs index 4e852be5..e15078b6 100644 --- a/src/log4net/Core/Level.cs +++ b/src/log4net/Core/Level.cs @@ -383,96 +383,96 @@ public static int Compare(Level? l, Level? r) /// The level designates very severe error events. /// System unusable, emergencies. /// - public static readonly Level Log4Net_Debug = new(120000, "log4net:DEBUG"); + public static readonly Level Log4Net_Debug = new(120_000, "log4net:DEBUG"); /// /// The level designates very severe error events. /// System unusable, emergencies. /// - public static readonly Level Emergency = new(120000, "EMERGENCY"); + public static readonly Level Emergency = new(120_000, "EMERGENCY"); /// /// The level designates very severe error events /// that will presumably lead the application to abort. /// - public static readonly Level Fatal = new(110000, "FATAL"); + public static readonly Level Fatal = new(110_000, "FATAL"); /// /// The level designates very severe error events. /// Take immediate action, alerts. /// - public static readonly Level Alert = new(100000, "ALERT"); + public static readonly Level Alert = new(100_000, "ALERT"); /// /// The level designates very severe error events. /// Critical condition, critical. /// - public static readonly Level Critical = new(90000, "CRITICAL"); + public static readonly Level Critical = new(90_000, "CRITICAL"); /// /// The level designates very severe error events. /// - public static readonly Level Severe = new(80000, "SEVERE"); + public static readonly Level Severe = new(80_000, "SEVERE"); /// /// The level designates error events that might /// still allow the application to continue running. /// - public static readonly Level Error = new(70000, "ERROR"); + public static readonly Level Error = new(70_000, "ERROR"); /// /// The level designates potentially harmful /// situations. /// - public static readonly Level Warn = new(60000, "WARN"); + public static readonly Level Warn = new(60_000, "WARN"); /// /// The level designates informational messages /// that highlight the progress of the application at the highest level. /// - public static readonly Level Notice = new(50000, "NOTICE"); + public static readonly Level Notice = new(50_000, "NOTICE"); /// /// The level designates informational messages that /// highlight the progress of the application at coarse-grained level. /// - public static readonly Level Info = new(40000, "INFO"); + public static readonly Level Info = new(40_000, "INFO"); /// /// The level designates fine-grained informational /// events that are most useful to debug an application. /// - public static readonly Level Debug = new(30000, "DEBUG"); + public static readonly Level Debug = new(30_000, "DEBUG"); /// /// The level designates fine-grained informational /// events that are most useful to debug an application. /// - public static readonly Level Fine = new(30000, "FINE"); + public static readonly Level Fine = new(30_000, "FINE"); /// /// The level designates fine-grained informational /// events that are most useful to debug an application. /// - public static readonly Level Trace = new(20000, "TRACE"); + public static readonly Level Trace = new(20_000, "TRACE"); /// /// The level designates fine-grained informational /// events that are most useful to debug an application. /// - public static readonly Level Finer = new(20000, "FINER"); + public static readonly Level Finer = new(20_000, "FINER"); /// /// The level designates fine-grained informational /// events that are most useful to debug an application. /// - public static readonly Level Verbose = new(10000, "VERBOSE"); + public static readonly Level Verbose = new(10_000, "VERBOSE"); /// /// The level designates fine-grained informational /// events that are most useful to debug an application. /// - public static readonly Level Finest = new(10000, "FINEST"); + public static readonly Level Finest = new(10_000, "FINEST"); /// /// The level designates the lowest level possible. diff --git a/src/log4net/Util/LevelMapping.cs b/src/log4net/Util/LevelMapping.cs index 92e5f37a..6d3aa709 100644 --- a/src/log4net/Util/LevelMapping.cs +++ b/src/log4net/Util/LevelMapping.cs @@ -17,8 +17,8 @@ // #endregion -using System; using System.Collections.Generic; +using System.Linq; using log4net.Core; namespace log4net.Util @@ -30,6 +30,9 @@ namespace log4net.Util /// Nicko Cadell public sealed class LevelMapping : IOptionHandler { + private readonly Dictionary entries = new(); + private List? sortedEntries; + /// /// Add a to this mapping /// @@ -45,7 +48,7 @@ public void Add(LevelMappingEntry entry) { if (entry.Level is not null) { - m_entriesMap[entry.Level] = entry; + entries[entry.Level] = entry; } } @@ -55,22 +58,19 @@ public void Add(LevelMappingEntry entry) /// specified. /// /// the level to look up. - /// The for the level or null if no mapping found + /// The for the level or if no mapping found public LevelMappingEntry? Lookup(Level? level) { - if (level is null) + if (level is null || sortedEntries is null) { return null; } - if (m_entries is not null) + foreach (LevelMappingEntry entry in sortedEntries) { - foreach (LevelMappingEntry entry in m_entries) + if (level >= entry.Level) { - if (entry.Level is not null && level >= entry.Level) - { - return entry; - } + return entry; } } return null; @@ -80,33 +80,15 @@ public void Add(LevelMappingEntry entry) /// Initialize options /// /// - /// - /// Caches the sorted list of in an array - /// + /// Caches the sorted list of /// public void ActivateOptions() { - Level[] sortKeys = new Level[m_entriesMap.Count]; - LevelMappingEntry[] sortValues = new LevelMappingEntry[m_entriesMap.Count]; - - m_entriesMap.Keys.CopyTo(sortKeys, 0); - m_entriesMap.Values.CopyTo(sortValues, 0); - - // Sort in level order - Array.Sort(sortKeys, sortValues, 0, sortKeys.Length, null); - - // Reverse list so that highest level is first - Array.Reverse(sortValues, 0, sortValues.Length); - - foreach (LevelMappingEntry entry in sortValues) - { - entry.ActivateOptions(); - } - - m_entries = sortValues; + sortedEntries = SortEntries(); + sortedEntries.ForEach(entry => entry.ActivateOptions()); } - private readonly Dictionary m_entriesMap = new(); - private LevelMappingEntry[]? m_entries; + private List SortEntries() + => entries.OrderByDescending(entry => entry.Key).Select(entry => entry.Value).ToList(); } -} +} \ No newline at end of file diff --git a/src/log4net/Util/LevelMappingEntry.cs b/src/log4net/Util/LevelMappingEntry.cs index b46cd43e..30ad337c 100644 --- a/src/log4net/Util/LevelMappingEntry.cs +++ b/src/log4net/Util/LevelMappingEntry.cs @@ -17,6 +17,7 @@ // #endregion +using System.Diagnostics; using log4net.Core; namespace log4net.Util @@ -26,14 +27,14 @@ namespace log4net.Util /// object. /// /// Nicko Cadell + [DebuggerDisplay("{Level}")] public abstract class LevelMappingEntry : IOptionHandler { /// /// Default protected constructor /// protected LevelMappingEntry() - { - } + { } /// /// Gets or sets the level that is the key for this mapping. @@ -45,7 +46,7 @@ protected LevelMappingEntry() /// /// /// - /// Should be overridden by any classes that need to initialise based on their options + /// Should be overridden by any classes that need to initialize based on their options /// /// public virtual void ActivateOptions() diff --git a/src/log4net/Util/SystemInfo.cs b/src/log4net/Util/SystemInfo.cs index 75608474..e04dc184 100644 --- a/src/log4net/Util/SystemInfo.cs +++ b/src/log4net/Util/SystemInfo.cs @@ -572,7 +572,6 @@ public static NotSupportedException CreateReadOnlyCollectionNotModifiableExcepti /// public static bool TryParse(string s, out int val) { - // Initialise out param val = 0; try @@ -605,7 +604,6 @@ public static bool TryParse(string s, out int val) /// public static bool TryParse(string s, out long val) { - // Initialise out param val = 0; try @@ -638,7 +636,6 @@ public static bool TryParse(string s, out long val) /// public static bool TryParse(string s, out short val) { - // Initialise out param val = 0; try diff --git a/src/log4net/Util/SystemStringFormat.cs b/src/log4net/Util/SystemStringFormat.cs index 9de9e087..36ba331b 100644 --- a/src/log4net/Util/SystemStringFormat.cs +++ b/src/log4net/Util/SystemStringFormat.cs @@ -41,7 +41,7 @@ public sealed class SystemStringFormat public object?[]? Args { get; set; } /// - /// Initialise the + /// Constructor /// /// An that supplies culture-specific formatting information. /// A containing zero or more format items. @@ -57,10 +57,7 @@ public SystemStringFormat(IFormatProvider? provider, string format, params objec /// Format the string and arguments /// /// the formatted string - public override string? ToString() - { - return StringFormat(m_provider, Format, Args); - } + public override string? ToString() => StringFormat(m_provider, Format, Args); /// /// Replaces the format item in a specified with the text equivalent