From aa9387a86dcc5598b63d5b5b12a9c21a02ede5a5 Mon Sep 17 00:00:00 2001 From: Jan Friedrich Date: Thu, 24 Oct 2024 10:23:15 +0200 Subject: [PATCH] file scoped namespaces and CA warnings fixed in examples --- .../Appender/AsyncAppender.cs | 194 +++--- .../Appender/FireEventAppender.cs | 69 ++- .../Appender/MessageBoxAppender.cs | 97 +-- .../Appender/MessageObjectExpanderAppender.cs | 71 ++- .../Appender/PatternFileAppender.cs | 125 ++-- .../Appender/PatternLayoutAdoNetAppender.cs | 103 ++-- .../PatternLayoutAdoNetAppenderParameter.cs | 11 +- .../SampleAppendersApp/LoggingExample.cs | 132 +++-- .../Appenders/WmiAppender/IWmiBoundEvent.cs | 43 +- examples/Appenders/WmiAppender/WmiAppender.cs | 281 ++++----- .../Appenders/WmiAppender/WmiAppender.csproj | 1 + .../Appenders/WmiAppender/WmiInstaller.cs | 37 +- examples/Appenders/WmiAppender/WmiLayout.cs | 131 ++--- .../Appenders/WmiAppender/WmiLoggingEvent.cs | 53 +- examples/Directory.Build.props | 11 +- .../EventIDLogApp/EventIDLogApp.cs | 33 +- .../Extensibility/TraceLogApp/TraceLogApp.cs | 33 +- .../log4net.Ext.EventID/EventIDLogImpl.cs | 105 ++-- .../log4net.Ext.EventID/EventIDLogManager.cs | 407 +++++++------ .../log4net.Ext.EventID/IEventIDLog.cs | 77 ++- .../Extensions/log4net.Ext.Trace/ITraceLog.cs | 23 +- .../log4net.Ext.Trace/TraceLogImpl.cs | 93 +-- .../log4net.Ext.Trace/TraceLogManager.cs | 425 +++++++------- .../Layout/ForwardingLayout.cs | 217 +++---- .../Layout/LevelConversionPattern.cs | 15 +- .../Layout/LevelPatternLayout.cs | 36 +- .../Layout/LineWrappingLayout.cs | 97 +-- .../SampleLayoutsApp/LoggingExample.cs | 56 +- examples/Performance/NotLogging/NotLogging.cs | 550 +++++++++--------- .../Tutorials/ConsoleApp/LoggingExample.cs | 116 ++-- 30 files changed, 1879 insertions(+), 1763 deletions(-) diff --git a/examples/Appenders/SampleAppendersApp/Appender/AsyncAppender.cs b/examples/Appenders/SampleAppendersApp/Appender/AsyncAppender.cs index a4ef5c15..e83e7af2 100644 --- a/examples/Appenders/SampleAppendersApp/Appender/AsyncAppender.cs +++ b/examples/Appenders/SampleAppendersApp/Appender/AsyncAppender.cs @@ -23,130 +23,156 @@ using log4net.Core; using log4net.Util; -namespace SampleAppendersApp.Appender +namespace SampleAppendersApp.Appender; + +/// +/// Appender that forwards LoggingEvents asynchronously +/// +/// +/// This appender forwards LoggingEvents to a list of attached appenders. +/// The events are forwarded asynchronously using the ThreadPool. +/// This allows the calling thread to be released quickly, however it does +/// not guarantee the ordering of events delivered to the attached appenders. +/// +public sealed class AsyncAppender : IAppender, IBulkAppender, IOptionHandler, IAppenderAttachable { - /// - /// Appender that forwards LoggingEvents asynchronously - /// - /// - /// This appender forwards LoggingEvents to a list of attached appenders. - /// The events are forwarded asynchronously using the ThreadPool. - /// This allows the calling thread to be released quickly, however it does - /// not guarantee the ordering of events delivered to the attached appenders. - /// - public sealed class AsyncAppender : IAppender, IBulkAppender, IOptionHandler, IAppenderAttachable - { - private readonly object syncRoot = new(); + private readonly object _syncRoot = new(); - /// - public string Name { get; set; } = string.Empty; + /// + public string Name { get; set; } = string.Empty; - /// - public void ActivateOptions() - { } + /// + public void ActivateOptions() + { } - /// - public FixFlags Fix { get; set; } = FixFlags.All; + /// + public FixFlags Fix { get; set; } = FixFlags.All; - /// - public void Close() + /// + public void Close() + { + // Remove all the attached appenders + lock (_syncRoot) { - // Remove all the attached appenders - lock (syncRoot) - appenderAttachedImpl?.RemoveAllAppenders(); + _appenderAttachedImpl?.RemoveAllAppenders(); } + } + + /// + public void DoAppend(LoggingEvent loggingEvent) + { + ArgumentNullException.ThrowIfNull(loggingEvent); + loggingEvent.Fix = Fix; + ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncAppend), loggingEvent); + } - /// - public void DoAppend(LoggingEvent loggingEvent) + /// + public void DoAppend(LoggingEvent[] loggingEvents) + { + ArgumentNullException.ThrowIfNull(loggingEvents); + foreach (LoggingEvent loggingEvent in loggingEvents) { - ArgumentNullException.ThrowIfNull(loggingEvent); loggingEvent.Fix = Fix; - ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncAppend), loggingEvent); } - /// - public void DoAppend(LoggingEvent[] loggingEvents) - { - ArgumentNullException.ThrowIfNull(loggingEvents); - foreach (LoggingEvent loggingEvent in loggingEvents) - loggingEvent.Fix = Fix; - ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncAppend), loggingEvents); - } + ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncAppend), loggingEvents); + } - private void AsyncAppend(object? state) + private void AsyncAppend(object? state) + { + if (_appenderAttachedImpl != null) { - if (appenderAttachedImpl != null) + if (state is LoggingEvent loggingEvent) + { + _appenderAttachedImpl.AppendLoopOnAppenders(loggingEvent); + } + else if (state is LoggingEvent[] loggingEvents) { - if (state is LoggingEvent loggingEvent) - appenderAttachedImpl.AppendLoopOnAppenders(loggingEvent); - else if (state is LoggingEvent[] loggingEvents) - appenderAttachedImpl.AppendLoopOnAppenders(loggingEvents); + _appenderAttachedImpl.AppendLoopOnAppenders(loggingEvents); } } + } - #region IAppenderAttachable Members + #region IAppenderAttachable Members - /// - public void AddAppender(IAppender appender) + /// + public void AddAppender(IAppender appender) + { + ArgumentNullException.ThrowIfNull(appender); + lock (_syncRoot) { - ArgumentNullException.ThrowIfNull(appender); - lock (syncRoot) - (appenderAttachedImpl ??= new()).AddAppender(appender); + (_appenderAttachedImpl ??= new()).AddAppender(appender); } + } - /// - public AppenderCollection Appenders + /// + public AppenderCollection Appenders + { + get { - get + lock (_syncRoot) { - lock (syncRoot) - return appenderAttachedImpl?.Appenders ?? AppenderCollection.EmptyCollection; + return _appenderAttachedImpl?.Appenders ?? AppenderCollection.EmptyCollection; } } + } - /// - public IAppender? GetAppender(string name) + /// + public IAppender? GetAppender(string? name) + { + lock (_syncRoot) { - lock (syncRoot) + if (_appenderAttachedImpl is null || name is null) { - if (appenderAttachedImpl is null || name is null) - return null; - - return appenderAttachedImpl.GetAppender(name); + return null; } + + return _appenderAttachedImpl.GetAppender(name); } + } - /// - public void RemoveAllAppenders() + /// + public void RemoveAllAppenders() + { + lock (_syncRoot) { - lock (syncRoot) - if (appenderAttachedImpl is not null) - { - appenderAttachedImpl.RemoveAllAppenders(); - appenderAttachedImpl = null; - } + if (_appenderAttachedImpl is not null) + { + _appenderAttachedImpl.RemoveAllAppenders(); + _appenderAttachedImpl = null; + } } + } - /// - public IAppender? RemoveAppender(IAppender appender) + /// + public IAppender? RemoveAppender(IAppender appender) + { + lock (_syncRoot) { - lock (syncRoot) - if (appender is not null && appenderAttachedImpl is not null) - return appenderAttachedImpl.RemoveAppender(appender); - return null; + if (appender is not null && _appenderAttachedImpl is not null) + { + return _appenderAttachedImpl.RemoveAppender(appender); + } } - /// - public IAppender? RemoveAppender(string name) + return null; + } + + /// + public IAppender? RemoveAppender(string name) + { + lock (_syncRoot) { - lock (syncRoot) - if (name is not null && appenderAttachedImpl is not null) - return appenderAttachedImpl.RemoveAppender(name); - return null; + if (name is not null && _appenderAttachedImpl is not null) + { + return _appenderAttachedImpl.RemoveAppender(name); + } } - #endregion - - private AppenderAttachedImpl? appenderAttachedImpl; + return null; } + + #endregion + + private AppenderAttachedImpl? _appenderAttachedImpl; } diff --git a/examples/Appenders/SampleAppendersApp/Appender/FireEventAppender.cs b/examples/Appenders/SampleAppendersApp/Appender/FireEventAppender.cs index 4fbe1d7d..f3e0a849 100644 --- a/examples/Appenders/SampleAppendersApp/Appender/FireEventAppender.cs +++ b/examples/Appenders/SampleAppendersApp/Appender/FireEventAppender.cs @@ -21,50 +21,49 @@ using log4net.Core; -namespace SampleAppendersApp.Appender +namespace SampleAppendersApp.Appender; + +/// +public sealed class MessageLoggedEventArgs(LoggingEvent loggingEvent) : EventArgs { /// - public sealed class MessageLoggedEventArgs(LoggingEvent loggingEvent) : EventArgs - { - /// - public LoggingEvent LoggingEvent { get; } = loggingEvent; - } + public LoggingEvent LoggingEvent { get; } = loggingEvent; +} +/// +/// Appender that raises an event for each LoggingEvent received +/// +/// +/// Raises a MessageLoggedEvent for each LoggingEvent object received +/// by this appender. +/// +public class FireEventAppender : log4net.Appender.AppenderSkeleton +{ /// - /// Appender that raises an event for each LoggingEvent received + /// Event handler /// - /// - /// Raises a MessageLoggedEvent for each LoggingEvent object received - /// by this appender. - /// - public class FireEventAppender : log4net.Appender.AppenderSkeleton - { - /// - /// Event handler - /// - public event EventHandler? MessageLoggedEvent; + public event EventHandler? MessageLoggedEvent; - /// - /// Easy singleton, gets the last instance created - /// - public static FireEventAppender? Instance { get; private set; } + /// + /// Easy singleton, gets the last instance created + /// + public static FireEventAppender? Instance { get; private set; } - /// - public FireEventAppender() => Instance = this; // Store the instance created + /// + public FireEventAppender() => Instance = this; // Store the instance created - /// - public virtual FixFlags Fix { get; set; } = FixFlags.All; + /// + public virtual FixFlags Fix { get; set; } = FixFlags.All; - /// - protected override void Append(LoggingEvent loggingEvent) - { - ArgumentNullException.ThrowIfNull(loggingEvent); - // Because we the LoggingEvent may be used beyond the lifetime - // of the Append() method we must fix any volatile data in the event - loggingEvent.Fix = Fix; + /// + protected override void Append(LoggingEvent loggingEvent) + { + ArgumentNullException.ThrowIfNull(loggingEvent); + // Because we the LoggingEvent may be used beyond the lifetime + // of the Append() method we must fix any volatile data in the event + loggingEvent.Fix = Fix; - // Raise the event - MessageLoggedEvent?.Invoke(this, new MessageLoggedEventArgs(loggingEvent)); - } + // Raise the event + MessageLoggedEvent?.Invoke(this, new MessageLoggedEventArgs(loggingEvent)); } } \ No newline at end of file diff --git a/examples/Appenders/SampleAppendersApp/Appender/MessageBoxAppender.cs b/examples/Appenders/SampleAppendersApp/Appender/MessageBoxAppender.cs index b9cae738..ca722c3e 100644 --- a/examples/Appenders/SampleAppendersApp/Appender/MessageBoxAppender.cs +++ b/examples/Appenders/SampleAppendersApp/Appender/MessageBoxAppender.cs @@ -26,66 +26,67 @@ using log4net.Layout; using log4net.Util; -namespace SampleAppendersApp.Appender +namespace SampleAppendersApp.Appender; + +/// +/// Displays messages as message boxes +/// +/// +/// Displays each LoggingEvent as a MessageBox. The message box is UI modal +/// and will block the calling thread until it is dismissed by the user. +/// +public sealed class MessageBoxAppender : AppenderSkeleton { - /// - /// Displays messages as message boxes - /// - /// - /// Displays each LoggingEvent as a MessageBox. The message box is UI modal - /// and will block the calling thread until it is dismissed by the user. - /// - public sealed class MessageBoxAppender : AppenderSkeleton - { - private LevelMapping levelMapping = new(); + private readonly LevelMapping _levelMapping = new(); - /// - public void AddMapping(LevelIcon mapping) => levelMapping.Add(mapping); + /// + public void AddMapping(LevelIcon mapping) => _levelMapping.Add(mapping); - /// - public PatternLayout? TitleLayout { get; set; } + /// + public PatternLayout? TitleLayout { get; set; } - /// - protected override void Append(LoggingEvent loggingEvent) - { - ArgumentNullException.ThrowIfNull(loggingEvent); - - MessageBoxIcon messageBoxIcon = MessageBoxIcon.Information; + /// + protected override void Append(LoggingEvent loggingEvent) + { + ArgumentNullException.ThrowIfNull(loggingEvent); - if (levelMapping.Lookup(loggingEvent.Level) is LevelIcon levelIcon) - // Prepend the Ansi Color code - messageBoxIcon = levelIcon.Icon; + MessageBoxIcon messageBoxIcon = MessageBoxIcon.Information; - string message = RenderLoggingEvent(loggingEvent); + if (_levelMapping.Lookup(loggingEvent.Level) is LevelIcon levelIcon) + { + // Prepend the Ansi Color code + messageBoxIcon = levelIcon.Icon; + } - string? title = null; - if (TitleLayout is null) - { - title = "LoggingEvent: " + loggingEvent.Level.Name; - } - else - { - using StringWriter titleWriter = new(System.Globalization.CultureInfo.InvariantCulture); - TitleLayout.Format(titleWriter, loggingEvent); - title = titleWriter.ToString(); - } + string message = RenderLoggingEvent(loggingEvent); - MessageBox.Show(message, title, MessageBoxButtons.OK, messageBoxIcon); + string? title = null; + if (TitleLayout is null) + { + title = "LoggingEvent: " + loggingEvent.Level?.Name; } - - /// - public override void ActivateOptions() + else { - base.ActivateOptions(); - levelMapping.ActivateOptions(); + using StringWriter titleWriter = new(System.Globalization.CultureInfo.InvariantCulture); + TitleLayout.Format(titleWriter, loggingEvent); + title = titleWriter.ToString(); } + MessageBox.Show(message, title, MessageBoxButtons.OK, messageBoxIcon); + } + + /// + public override void ActivateOptions() + { + base.ActivateOptions(); + _levelMapping.ActivateOptions(); + } + + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible")] + public sealed class LevelIcon : LevelMappingEntry + { /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible")] - public sealed class LevelIcon : LevelMappingEntry - { - /// - public MessageBoxIcon Icon { get; set; } - } + public MessageBoxIcon Icon { get; set; } } } diff --git a/examples/Appenders/SampleAppendersApp/Appender/MessageObjectExpanderAppender.cs b/examples/Appenders/SampleAppendersApp/Appender/MessageObjectExpanderAppender.cs index 616fcea7..874962b2 100644 --- a/examples/Appenders/SampleAppendersApp/Appender/MessageObjectExpanderAppender.cs +++ b/examples/Appenders/SampleAppendersApp/Appender/MessageObjectExpanderAppender.cs @@ -22,45 +22,54 @@ using log4net.Core; -namespace SampleAppendersApp.Appender +namespace SampleAppendersApp.Appender; + +/// +/// Forwarding Appender that introspects the +/// and extracts all public properties and fields and stores them in the +/// +/// +public sealed class MessageObjectExpanderAppender : log4net.Appender.ForwardingAppender { - /// - /// Forwarding Appender that introspects the - /// and extracts all public properties and fields and stores them in the - /// - /// - public sealed class MessageObjectExpanderAppender : log4net.Appender.ForwardingAppender + /// + protected override void Append(LoggingEvent loggingEvent) { - /// - protected override void Append(LoggingEvent loggingEvent) + ArgumentNullException.ThrowIfNull(loggingEvent); + object? messageObject = loggingEvent.MessageObject; + + if (messageObject is not null and not string) { - ArgumentNullException.ThrowIfNull(loggingEvent); - object messageObject = loggingEvent.MessageObject; + Type messageType = messageObject.GetType(); - if (messageObject != null && !(messageObject is string)) + // Get all public instance properties + if (ExpandProperties) { - Type messageType = messageObject.GetType(); - - // Get all public instance properties - if (ExpandProperties) - foreach (PropertyInfo propertyInfo in messageType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) - if (propertyInfo.CanRead) - loggingEvent.Properties[propertyInfo.Name] = propertyInfo.GetValue(messageObject, null); - - // Get all public instance fields - if (ExpandFields) - foreach (FieldInfo fieldInfo in messageType.GetFields(BindingFlags.Instance | BindingFlags.Public)) - loggingEvent.Properties[fieldInfo.Name] = fieldInfo.GetValue(messageObject); + foreach (PropertyInfo propertyInfo in messageType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) + { + if (propertyInfo.CanRead) + { + loggingEvent.Properties[propertyInfo.Name] = propertyInfo.GetValue(messageObject, null); + } + } } - // Delegate to base class which will forward - base.Append(loggingEvent); + // Get all public instance fields + if (ExpandFields) + { + foreach (FieldInfo fieldInfo in messageType.GetFields(BindingFlags.Instance | BindingFlags.Public)) + { + loggingEvent.Properties[fieldInfo.Name] = fieldInfo.GetValue(messageObject); + } + } } - /// - public bool ExpandProperties { get; set; } = true; - - /// - public bool ExpandFields { get; set; } = true; + // Delegate to base class which will forward + base.Append(loggingEvent); } + + /// + public bool ExpandProperties { get; set; } = true; + + /// + public bool ExpandFields { get; set; } = true; } \ No newline at end of file diff --git a/examples/Appenders/SampleAppendersApp/Appender/PatternFileAppender.cs b/examples/Appenders/SampleAppendersApp/Appender/PatternFileAppender.cs index 88088200..1d7ca355 100644 --- a/examples/Appenders/SampleAppendersApp/Appender/PatternFileAppender.cs +++ b/examples/Appenders/SampleAppendersApp/Appender/PatternFileAppender.cs @@ -25,82 +25,85 @@ using log4net.Layout; using log4net.Core; -namespace SampleAppendersApp.Appender +namespace SampleAppendersApp.Appender; + +/// +/// Appender that writes to a file named using a pattern +/// +/// +/// The file to write to is selected for each event using a +/// PatternLayout specified in the File property. This allows +/// each LoggingEvent to be written to a file based on properties +/// of the event. +/// The output file is opened to write each LoggingEvent as it arrives +/// and closed afterwards. +/// +public sealed class PatternFileAppender : AppenderSkeleton { - /// - /// Appender that writes to a file named using a pattern - /// - /// - /// The file to write to is selected for each event using a - /// PatternLayout specified in the File property. This allows - /// each LoggingEvent to be written to a file based on properties - /// of the event. - /// The output file is opened to write each LoggingEvent as it arrives - /// and closed afterwards. - /// - public sealed class PatternFileAppender : AppenderSkeleton - { - /// - public PatternLayout? File { get; set; } + /// + public PatternLayout? File { get; set; } - /// - public Encoding Encoding { get; set; } = Encoding.Default; + /// + public Encoding Encoding { get; set; } = Encoding.Default; - /// - public SecurityContext? SecurityContext { get; set; } + /// + public SecurityContext? SecurityContext { get; set; } - /// - public override void ActivateOptions() - { - base.ActivateOptions(); - SecurityContext ??= SecurityContextProvider.DefaultProvider.CreateSecurityContext(this); - } + /// + public override void ActivateOptions() + { + base.ActivateOptions(); + SecurityContext ??= SecurityContextProvider.DefaultProvider.CreateSecurityContext(this); + } - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")] - protected override void Append(LoggingEvent loggingEvent) + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")] + protected override void Append(LoggingEvent loggingEvent) + { + try { - try - { - // Render the file name - using StringWriter stringWriter = new(); - ArgumentNullException.ThrowIfNull(File); - File.Format(stringWriter, loggingEvent); - string fileName = stringWriter.ToString(); - - fileName = SystemInfo.ConvertToFullPath(fileName); + // Render the file name + using StringWriter stringWriter = new(); + ArgumentNullException.ThrowIfNull(File); + File.Format(stringWriter, loggingEvent); + string fileName = stringWriter.ToString(); - FileStream? fileStream = null; - - ArgumentNullException.ThrowIfNull(SecurityContext); - using (SecurityContext.Impersonate(this)) - { - // Ensure that the directory structure exists - string? directoryFullName = Path.GetDirectoryName(fileName); - ArgumentNullException.ThrowIfNull(directoryFullName); + fileName = SystemInfo.ConvertToFullPath(fileName); - // Only create the directory if it does not exist - // doing this check here resolves some permissions failures - if (!Directory.Exists(directoryFullName)) - Directory.CreateDirectory(directoryFullName); + FileStream? fileStream = null; - // Open file stream while impersonating - fileStream = new(fileName, FileMode.Append, FileAccess.Write, FileShare.Read); - } + ArgumentNullException.ThrowIfNull(SecurityContext); + using (SecurityContext.Impersonate(this)) + { + // Ensure that the directory structure exists + string? directoryFullName = Path.GetDirectoryName(fileName); + ArgumentNullException.ThrowIfNull(directoryFullName); - if (fileStream is not null) + // Only create the directory if it does not exist + // doing this check here resolves some permissions failures + if (!Directory.Exists(directoryFullName)) { - using (StreamWriter streamWriter = new(fileStream, Encoding)) - RenderLoggingEvent(streamWriter, loggingEvent); - - fileStream.Close(); + Directory.CreateDirectory(directoryFullName); } + + // Open file stream while impersonating + fileStream = new(fileName, FileMode.Append, FileAccess.Write, FileShare.Read); } - catch (Exception ex) + + if (fileStream is not null) { - ErrorHandler.Error("Failed to append to file", ex); + using (StreamWriter streamWriter = new(fileStream, Encoding)) + { + RenderLoggingEvent(streamWriter, loggingEvent); + } + + fileStream.Close(); } } + catch (Exception ex) + { + ErrorHandler.Error("Failed to append to file", ex); + } } } \ No newline at end of file diff --git a/examples/Appenders/SampleAppendersApp/Appender/PatternLayoutAdoNetAppender.cs b/examples/Appenders/SampleAppendersApp/Appender/PatternLayoutAdoNetAppender.cs index db1219ca..12ed547f 100644 --- a/examples/Appenders/SampleAppendersApp/Appender/PatternLayoutAdoNetAppender.cs +++ b/examples/Appenders/SampleAppendersApp/Appender/PatternLayoutAdoNetAppender.cs @@ -23,63 +23,64 @@ using log4net.Layout; using log4net.Util; -namespace SampleAppendersApp.Appender +namespace SampleAppendersApp.Appender; + +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// ]]> +/// +/// +public sealed class PatternLayoutAdoNetAppender : AdoNetAppender { - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// ]]> - /// - /// - public sealed class PatternLayoutAdoNetAppender : AdoNetAppender - { - private readonly ArrayList converters = []; + private readonly ArrayList _converters = []; - /// - public void AddConverter(ConverterInfo converterInfo) => converters.Add(converterInfo); + /// + public void AddConverter(ConverterInfo converterInfo) => _converters.Add(converterInfo); - /// - public void AddPatternLayoutParameter(PatternLayoutAdoNetAppenderParameter parameter) - { - ArgumentNullException.ThrowIfNull(parameter); - PatternLayout patternLayout = new(parameter.ConversionPattern); - AddConveters(patternLayout); - patternLayout.ActivateOptions(); + /// + public void AddPatternLayoutParameter(PatternLayoutAdoNetAppenderParameter parameter) + { + ArgumentNullException.ThrowIfNull(parameter); + PatternLayout patternLayout = new(parameter.ConversionPattern); + AddConveters(patternLayout); + patternLayout.ActivateOptions(); - parameter.Layout = new Layout2RawLayoutAdapter(patternLayout); - m_parameters.Add(parameter); - } + parameter.Layout = new Layout2RawLayoutAdapter(patternLayout); + m_parameters.Add(parameter); + } - private void AddConveters(PatternLayout patternLayout) + private void AddConveters(PatternLayout patternLayout) + { + foreach (ConverterInfo conveterInfo in _converters) { - foreach (ConverterInfo conveterInfo in converters) - patternLayout.AddConverter(conveterInfo); + patternLayout.AddConverter(conveterInfo); } } } \ No newline at end of file diff --git a/examples/Appenders/SampleAppendersApp/Appender/PatternLayoutAdoNetAppenderParameter.cs b/examples/Appenders/SampleAppendersApp/Appender/PatternLayoutAdoNetAppenderParameter.cs index 4e42e0d7..22a22bc2 100644 --- a/examples/Appenders/SampleAppendersApp/Appender/PatternLayoutAdoNetAppenderParameter.cs +++ b/examples/Appenders/SampleAppendersApp/Appender/PatternLayoutAdoNetAppenderParameter.cs @@ -19,12 +19,11 @@ using log4net.Appender; -namespace SampleAppendersApp.Appender +namespace SampleAppendersApp.Appender; + +/// +public sealed class PatternLayoutAdoNetAppenderParameter : AdoNetAppenderParameter { /// - public sealed class PatternLayoutAdoNetAppenderParameter : AdoNetAppenderParameter - { - /// - public string? ConversionPattern { get; set; } - } + public string? ConversionPattern { get; set; } } \ No newline at end of file diff --git a/examples/Appenders/SampleAppendersApp/LoggingExample.cs b/examples/Appenders/SampleAppendersApp/LoggingExample.cs index 88a18757..bd978f12 100644 --- a/examples/Appenders/SampleAppendersApp/LoggingExample.cs +++ b/examples/Appenders/SampleAppendersApp/LoggingExample.cs @@ -27,88 +27,98 @@ // called ConsoleApp.exe.config in the application base // directory (i.e. the directory containing SampleAppendersApp.exe) -namespace SampleAppendersApp +namespace SampleAppendersApp; + +/// +/// Example of how to simply configure and use log4net +/// +public static class LoggingExample { + // Create a logger for use in this class + private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof(LoggingExample)); + /// - /// Example of how to simply configure and use log4net + /// Application entry point /// - public static class LoggingExample + [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")] + public static void Main() { - // Create a logger for use in this class - private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(LoggingExample)); - - /// - /// Application entry point - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")] - public static void Main() - { - log4net.ThreadContext.Properties["session"] = 21; - - // Hookup the FireEventAppender event - if (FireEventAppender.Instance is not null) - FireEventAppender.Instance.MessageLoggedEvent += FireEventAppender_MessageLoggedEventHandler; + log4net.ThreadContext.Properties["session"] = 21; - // Log an info level message - if (log.IsInfoEnabled) log.Info("Application [ConsoleApp] Start"); + // Hookup the FireEventAppender event + if (FireEventAppender.Instance is not null) + { + FireEventAppender.Instance.MessageLoggedEvent += FireEventAppender_MessageLoggedEventHandler; + } - // Log a debug message. Test if debug is enabled before - // attempting to log the message. This is not required but - // can make running without logging faster. - if (log.IsDebugEnabled) log.Debug("This is a debug message"); + // Log an info level message + if (_log.IsInfoEnabled) + { + _log.Info("Application [ConsoleApp] Start"); + } - // Log a custom object as the log message - log.Warn(new MsgObj(42, "So long and thanks for all the fish")); + // Log a debug message. Test if debug is enabled before + // attempting to log the message. This is not required but + // can make running without logging faster. + if (_log.IsDebugEnabled) + { + _log.Debug("This is a debug message"); + } - try - { - Bar(); - } - catch (ArithmeticException ex) - { - // Log an error with an exception - log.Error("Exception thrown from method Bar", ex); - } + // Log a custom object as the log message + _log.Warn(new MsgObj(42, "So long and thanks for all the fish")); - log.Error("Hey this is an error!"); + try + { + Bar(); + } + catch (ArithmeticException ex) + { + // Log an error with an exception + _log.Error("Exception thrown from method Bar", ex); + } - // Log an info level message - if (log.IsInfoEnabled) log.Info("Application [ConsoleApp] End"); + _log.Error("Hey this is an error!"); - Console.Write("Press Enter to exit..."); - Console.ReadLine(); + // Log an info level message + if (_log.IsInfoEnabled) + { + _log.Info("Application [ConsoleApp] End"); } - // Helper methods to demonstrate location information and nested exceptions + Console.Write("Press Enter to exit..."); + Console.ReadLine(); + } + + // Helper methods to demonstrate location information and nested exceptions - private static void Bar() => Goo(); + private static void Bar() => Goo(); - private static void Foo() => throw new InvalidTimeZoneException("This is an Exception"); + private static void Foo() => throw new InvalidTimeZoneException("This is an Exception"); - private static void Goo() + private static void Goo() + { + try + { + Foo(); + } + catch (Exception ex) { - try - { - Foo(); - } - catch (Exception ex) - { - throw new ArithmeticException("Failed in Goo. Calling Foo. Inner Exception provided", ex); - } + throw new ArithmeticException("Failed in Goo. Calling Foo. Inner Exception provided", ex); } + } - private static void FireEventAppender_MessageLoggedEventHandler(object? sender, MessageLoggedEventArgs e) - => System.Diagnostics.Trace.WriteLine("EVENT ****" + e.LoggingEvent.RenderedMessage + "****"); + private static void FireEventAppender_MessageLoggedEventHandler(object? sender, MessageLoggedEventArgs e) + => System.Diagnostics.Trace.WriteLine("EVENT ****" + e.LoggingEvent.RenderedMessage + "****"); + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible")] + public sealed class MsgObj(int type, string error) + { /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible")] - public sealed class MsgObj(int type, string error) - { - /// - public int MessageType { get; } = type; + public int MessageType { get; } = type; - /// - public string ErrorText { get; } = error; - } + /// + public string ErrorText { get; } = error; } } diff --git a/examples/Appenders/WmiAppender/IWmiBoundEvent.cs b/examples/Appenders/WmiAppender/IWmiBoundEvent.cs index 68785054..5892ed06 100644 --- a/examples/Appenders/WmiAppender/IWmiBoundEvent.cs +++ b/examples/Appenders/WmiAppender/IWmiBoundEvent.cs @@ -20,33 +20,32 @@ using log4net.Core; using System.Management.Instrumentation; -namespace log4net.Appender +namespace log4net.Appender; + +/// +/// Subclass of for events that need to bind to a +/// +/// +/// +/// If the . is +/// a then the default behavior of the +/// is to call the method passing the . +/// This allows the event object to capture additional data from the +/// before it is fired. +/// +/// +public interface IWmiBoundEvent : IEvent { /// - /// Subclass of for events that need to bind to a + /// This method is called before this instance is fired /// + /// the containing the data /// /// - /// If the . is - /// a then the default behavior of the - /// is to call the method passing the . - /// This allows the event object to capture additional data from the - /// before it is fired. + /// The calls this method passing the + /// object. Implementors should capture any required data from the + /// and store it in their instance prior to firing to WMI. /// /// - public interface IWmiBoundEvent : IEvent - { - /// - /// This method is called before this instance is fired - /// - /// the containing the data - /// - /// - /// The calls this method passing the - /// object. Implementors should capture any required data from the - /// and store it in their instance prior to firing to WMI. - /// - /// - void Bind(LoggingEvent loggingEvent); - } + void Bind(LoggingEvent loggingEvent); } \ No newline at end of file diff --git a/examples/Appenders/WmiAppender/WmiAppender.cs b/examples/Appenders/WmiAppender/WmiAppender.cs index a3c00e63..9259c1f9 100644 --- a/examples/Appenders/WmiAppender/WmiAppender.cs +++ b/examples/Appenders/WmiAppender/WmiAppender.cs @@ -25,166 +25,169 @@ // This is the WMI namespace for event objects in this assembly [assembly: Instrumented("root/log4net")] -namespace log4net.Appender +namespace log4net.Appender; + +/// +/// fires instrumented events for each +/// +/// +/// +/// This appender fires Windows Management Instrumentation (WMI) events for +/// each . +/// +/// +/// By default this appender fires objects, however +/// this can be overridden by specifying a custom or by setting +/// the . to an +/// instance. +/// +/// +/// This assembly must be registered with WMI. Use the InstallUtil tool +/// shipped with the .NET framework to install this assembly. This will register +/// the root/log4net WMI namespace. +/// +/// +public sealed class WmiAppender : IAppender, IOptionHandler { + #region Private Instance Fields + + /// + /// It is assumed and enforced that errorHandler is never null. + /// + /// + /// + /// It is assumed and enforced that errorHandler is never null. + /// + /// + /// See for more information. + /// + /// + private IErrorHandler _errorHandler = new OnlyOnceErrorHandler("WmiAppender"); + + #endregion + + #region Public Instance Properties + + /// + /// Gets or sets the name of this appender. + /// + /// The name of the appender. + /// + /// + /// The name uniquely identifies the appender. + /// + /// + public string Name { get; set; } = default!; + /// - /// fires instrumented events for each + /// Gets or sets the threshold of this appender. /// + /// + /// The threshold of the appender. + /// /// /// - /// This appender fires Windows Management Instrumentation (WMI) events for - /// each . + /// All log events with lower level than the threshold level are ignored + /// by the appender. + /// + /// + /// In configuration files this option is specified by setting the + /// value of the option to a level + /// string, such as "DEBUG", "INFO" and so on. /// + /// + public Level? Threshold { get; set; } + + /// + /// Gets or sets the for this appender. + /// + /// The layout of the appender. + /// /// - /// By default this appender fires objects, however - /// this can be overridden by specifying a custom or by setting - /// the . to an - /// instance. + /// The to use to format the + /// as an . /// + /// + public WmiLayout? Layout { get; set; } + + /// + /// Gets or sets the for this appender. + /// + /// The of the appender + /// /// - /// This assembly must be registered with WMI. Use the InstallUtil tool - /// shipped with the .NET framework to install this assembly. This will register - /// the root/log4net WMI namespace. + /// The default value is a . /// /// - public sealed class WmiAppender : IAppender, IOptionHandler + public IErrorHandler ErrorHandler { - #region Private Instance Fields - - /// - /// It is assumed and enforced that errorHandler is never null. - /// - /// - /// - /// It is assumed and enforced that errorHandler is never null. - /// - /// - /// See for more information. - /// - /// - private IErrorHandler errorHandler = new OnlyOnceErrorHandler("WmiAppender"); - - #endregion - - #region Public Instance Properties - - /// - /// Gets or sets the name of this appender. - /// - /// The name of the appender. - /// - /// - /// The name uniquely identifies the appender. - /// - /// - public string Name { get; set; } = default!; - - /// - /// Gets or sets the threshold of this appender. - /// - /// - /// The threshold of the appender. - /// - /// - /// - /// All log events with lower level than the threshold level are ignored - /// by the appender. - /// - /// - /// In configuration files this option is specified by setting the - /// value of the option to a level - /// string, such as "DEBUG", "INFO" and so on. - /// - /// - public Level? Threshold { get; set; } - - /// - /// Gets or sets the for this appender. - /// - /// The layout of the appender. - /// - /// - /// The to use to format the - /// as an . - /// - /// - public WmiLayout? Layout { get; set; } - - /// - /// Gets or sets the for this appender. - /// - /// The of the appender - /// - /// - /// The default value is a . - /// - /// - public IErrorHandler ErrorHandler + get => _errorHandler; + set { - get => errorHandler; - set + if (value is null) + { + // We do not throw exception here since the cause is probably a bad config file. + LogLog.Warn(GetType(), "WmiAppender: You have tried to set a null error-handler."); + } + else { - if (value is null) - // We do not throw exception here since the cause is probably a bad config file. - LogLog.Warn(GetType(), "WmiAppender: You have tried to set a null error-handler."); - else - errorHandler = value; + _errorHandler = value; } } + } + + #endregion Public Instance Properties + + /// + /// Activate this appender + /// + /// + /// + /// If a has not been specified then this + /// method will create a default instance. + /// + /// + public void ActivateOptions() => Layout ??= new WmiLayout(); + + /// + /// Close this appender + /// + public void Close() + { } - #endregion Public Instance Properties - - /// - /// Activate this appender - /// - /// - /// - /// If a has not been specified then this - /// method will create a default instance. - /// - /// - public void ActivateOptions() => Layout ??= new WmiLayout(); - - /// - /// Close this appender - /// - public void Close() - { } - - /// - /// Process a - /// - /// the containing the data - /// - /// - /// Uses the to format the - /// as an . This is then fired. - /// - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types")] - public void DoAppend(LoggingEvent loggingEvent) + /// + /// Process a + /// + /// the containing the data + /// + /// + /// Uses the to format the + /// as an . This is then fired. + /// + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types")] + public void DoAppend(LoggingEvent loggingEvent) + { + if (loggingEvent is null) { - if (loggingEvent is null) - { - throw new ArgumentNullException(nameof(loggingEvent)); - } + throw new ArgumentNullException(nameof(loggingEvent)); + } - try - { - if (IsAsSevereAsThreshold(loggingEvent.Level)) - { - (Layout?.Format(loggingEvent))?.Fire(); - } - } - catch (Exception ex) + try + { + if (IsAsSevereAsThreshold(loggingEvent.Level)) { - ErrorHandler.Error("Failed in DoAppend", ex); + (Layout?.Format(loggingEvent))?.Fire(); } } - - /// - /// Checks if the message level is below this appenders threshold. - /// - private bool IsAsSevereAsThreshold(Level? level) => ((Threshold is null) || level >= Threshold); + catch (Exception ex) + { + ErrorHandler.Error("Failed in DoAppend", ex); + } } + + /// + /// Checks if the message level is below this appenders threshold. + /// + private bool IsAsSevereAsThreshold(Level? level) => Threshold is null || level >= Threshold; } \ No newline at end of file diff --git a/examples/Appenders/WmiAppender/WmiAppender.csproj b/examples/Appenders/WmiAppender/WmiAppender.csproj index bb743867..f334a71d 100644 --- a/examples/Appenders/WmiAppender/WmiAppender.csproj +++ b/examples/Appenders/WmiAppender/WmiAppender.csproj @@ -2,6 +2,7 @@ net462 enable + log4net.Appender diff --git a/examples/Appenders/WmiAppender/WmiInstaller.cs b/examples/Appenders/WmiAppender/WmiInstaller.cs index 77e3a485..03c86c2e 100644 --- a/examples/Appenders/WmiAppender/WmiInstaller.cs +++ b/examples/Appenders/WmiAppender/WmiInstaller.cs @@ -17,14 +17,33 @@ // #endregion + +#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.Management.Instrumentation; -namespace log4net.Appender -{ - /// - /// Register this assembly with WMI - /// - [System.ComponentModel.RunInstaller(true)] - public sealed class WmiInstaller : DefaultManagementProjectInstaller - { } -} \ No newline at end of file +namespace log4net.Appender; + +/// +/// Register this assembly with WMI +/// +[System.ComponentModel.RunInstaller(true)] +public sealed class WmiInstaller : DefaultManagementProjectInstaller +{ } \ No newline at end of file diff --git a/examples/Appenders/WmiAppender/WmiLayout.cs b/examples/Appenders/WmiAppender/WmiLayout.cs index 011fb748..c9aa051c 100644 --- a/examples/Appenders/WmiAppender/WmiLayout.cs +++ b/examples/Appenders/WmiAppender/WmiLayout.cs @@ -21,78 +21,79 @@ using System; using System.Management.Instrumentation; -namespace log4net.Appender +namespace log4net.Appender; + +/// +public class WmiLayout { - /// - public class WmiLayout + /// + /// Formats a for instrumentation + /// + /// the containing the data + /// an instrumentation event that can be fired + /// + /// + /// If the of the + /// is an then + /// that instance is returned. If the instance also implements the + /// interface then the + /// method will be called on the instance with the + /// parameter. + /// + /// + /// If the of the + /// is not an + /// then the method will be called + /// to create an appropriate instrumentation event object. + /// + /// + public virtual IEvent Format(LoggingEvent loggingEvent) { - /// - /// Formats a for instrumentation - /// - /// the containing the data - /// an instrumentation event that can be fired - /// - /// - /// If the of the - /// is an then - /// that instance is returned. If the instance also implements the - /// interface then the - /// method will be called on the instance with the - /// parameter. - /// - /// - /// If the of the - /// is not an - /// then the method will be called - /// to create an appropriate instrumentation event object. - /// - /// - public virtual IEvent Format(LoggingEvent loggingEvent) + // See if the caller gave us an Instrumentation Event + if (loggingEvent?.MessageObject is IEvent instrumentationEvent) { - // See if the caller gave us an Instrumentation Event - if (loggingEvent?.MessageObject is IEvent instrumentationEvent) - { - // See if the caller gave us a Bound Instrumentation Event - // Attach the logging event to the bound instrumentation event - (instrumentationEvent as IWmiBoundEvent)?.Bind(loggingEvent); - - return instrumentationEvent; - } + // See if the caller gave us a Bound Instrumentation Event + // Attach the logging event to the bound instrumentation event + (instrumentationEvent as IWmiBoundEvent)?.Bind(loggingEvent); - // We must create our own IEvent - return CreateEvent(loggingEvent!); + return instrumentationEvent; } - /// - /// Create the instance that should be fired - /// - /// the containing the data - /// an instrumentation event that can be fired - /// - /// - /// The default implementation of this method creates a - /// instance using the data from the . - /// - /// - /// Subclasses should override this method to return their own custom - /// instrumentation event object. - /// - /// - protected virtual IEvent CreateEvent(LoggingEvent loggingEvent) - { - if (loggingEvent is null) - throw new ArgumentNullException(nameof(loggingEvent)); + // We must create our own IEvent + return CreateEvent(loggingEvent!); + } - return new WmiLoggingEvent - { - TimeStamp = loggingEvent.TimeStamp, - LoggerName = loggingEvent.LoggerName, - Level = (loggingEvent.Level ??Level.Debug).DisplayName, - Message = loggingEvent.RenderedMessage, - ThreadName = loggingEvent.ThreadName, - ExceptionString = loggingEvent.GetExceptionString(), - Domain = loggingEvent.Domain - }; + /// + /// Create the instance that should be fired + /// + /// the containing the data + /// an instrumentation event that can be fired + /// + /// + /// The default implementation of this method creates a + /// instance using the data from the . + /// + /// + /// Subclasses should override this method to return their own custom + /// instrumentation event object. + /// + /// + protected virtual IEvent CreateEvent(LoggingEvent loggingEvent) + { + if (loggingEvent is null) + { + throw new ArgumentNullException(nameof(loggingEvent)); } + + return new WmiLoggingEvent + { + TimeStamp = loggingEvent.TimeStamp, + LoggerName = loggingEvent.LoggerName, + Level = (loggingEvent.Level ?? Level.Debug).DisplayName, + Message = loggingEvent.RenderedMessage, + ThreadName = loggingEvent.ThreadName, + ExceptionString = loggingEvent.GetExceptionString(), + Domain = loggingEvent.Domain + }; } } \ No newline at end of file diff --git a/examples/Appenders/WmiAppender/WmiLoggingEvent.cs b/examples/Appenders/WmiAppender/WmiLoggingEvent.cs index 6acca6b3..b16e82cf 100644 --- a/examples/Appenders/WmiAppender/WmiLoggingEvent.cs +++ b/examples/Appenders/WmiAppender/WmiLoggingEvent.cs @@ -20,32 +20,31 @@ using System; using System.Management.Instrumentation; -namespace log4net.Appender +namespace log4net.Appender; + +/// +/// The default instrumented event raised by the +/// +/// +/// This is the default event fired by the . +/// To fire a custom event set the to a +/// subclass of that overrides the +/// method. +/// +public sealed class WmiLoggingEvent : BaseEvent { - /// - /// The default instrumented event raised by the - /// - /// - /// This is the default event fired by the . - /// To fire a custom event set the to a - /// subclass of that overrides the - /// method. - /// - public sealed class WmiLoggingEvent : BaseEvent - { - /// - public DateTime TimeStamp { get; set; } - /// - public string? LoggerName { get; set; } - /// - public string? Level { get; set; } - /// - public string? Message { get; set; } - /// - public string? ThreadName { get; set; } - /// - public string? ExceptionString { get; set; } - /// - public string? Domain { get; set; } - } + /// + public DateTime TimeStamp { get; set; } + /// + public string? LoggerName { get; set; } + /// + public string? Level { get; set; } + /// + public string? Message { get; set; } + /// + public string? ThreadName { get; set; } + /// + public string? ExceptionString { get; set; } + /// + public string? Domain { get; set; } } \ No newline at end of file diff --git a/examples/Directory.Build.props b/examples/Directory.Build.props index f5d61728..42cd2572 100644 --- a/examples/Directory.Build.props +++ b/examples/Directory.Build.props @@ -1,6 +1,6 @@ - 3.0.2 + 3.0.3 $(Version) true latest @@ -14,6 +14,9 @@ true false + + + full false @@ -23,7 +26,8 @@ true - 3.0.2 + 3.0.3-preview.1 + 8.0.0 true @@ -37,4 +41,7 @@ git https://github.com/apache/logging-log4net + + + \ No newline at end of file diff --git a/examples/Extensibility/EventIDLogApp/EventIDLogApp.cs b/examples/Extensibility/EventIDLogApp/EventIDLogApp.cs index dfbf49a3..80bc6cfe 100644 --- a/examples/Extensibility/EventIDLogApp/EventIDLogApp.cs +++ b/examples/Extensibility/EventIDLogApp/EventIDLogApp.cs @@ -23,28 +23,27 @@ // Configure this assembly using the 'EventIDLogApp.exe.config' config file [assembly: log4net.Config.XmlConfigurator(Watch = true)] -namespace EventIDLogApp +namespace EventIDLogApp; + +/// +/// EventIDLogApp +/// +internal static class EventIDLogApp { + // Create a logger for use in this class + private static readonly IEventIDLog _log = EventIDLogManager.GetLogger(typeof(EventIDLogApp)) + ?? throw new ArgumentNullException(nameof(EventIDLogManager.GetLogger)); + /// - /// EventIDLogApp + /// The main entry point for the application. /// - internal static class EventIDLogApp + [STAThread] + static void Main() { - // Create a logger for use in this class - private static readonly IEventIDLog log = EventIDLogManager.GetLogger(typeof(EventIDLogApp)) - ?? throw new ArgumentNullException(nameof(EventIDLogManager.GetLogger)); - - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - log.Info(1, "Application [" + typeof(EventIDLogApp).Assembly.GetName().Name + "] Start"); + _log.Info(1, "Application [" + typeof(EventIDLogApp).Assembly.GetName().Name + "] Start"); - log.Warn(40, "This is a warn message "); + _log.Warn(40, "This is a warn message "); - log.Info(2, "Application [" + typeof(EventIDLogApp).Assembly.GetName().Name + "] Stop"); - } + _log.Info(2, "Application [" + typeof(EventIDLogApp).Assembly.GetName().Name + "] Stop"); } } \ No newline at end of file diff --git a/examples/Extensibility/TraceLogApp/TraceLogApp.cs b/examples/Extensibility/TraceLogApp/TraceLogApp.cs index 6e534920..ab78b522 100644 --- a/examples/Extensibility/TraceLogApp/TraceLogApp.cs +++ b/examples/Extensibility/TraceLogApp/TraceLogApp.cs @@ -24,26 +24,25 @@ // Configure this assembly using the 'TraceLogApp.exe.log4net' config file [assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "log4net", Watch = true)] -namespace TraceLogApp +namespace TraceLogApp; + +/// +internal static class TraceLogApp { - /// - internal static class TraceLogApp - { - // Create a logger for use in this class - private static readonly ITraceLog log = TraceLogManager.GetLogger(typeof(TraceLogApp)) - ?? throw new ArgumentNullException(nameof(TraceLogManager.GetLogger)); + // Create a logger for use in this class + private static readonly ITraceLog _log = TraceLogManager.GetLogger(typeof(TraceLogApp)) + ?? throw new ArgumentNullException(nameof(TraceLogManager.GetLogger)); - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + for (int i = 0; i < 10; i++) { - for (int i = 0; i < 10; i++) - { - log.Trace("This is a trace message " + i); - System.Threading.Thread.Sleep(new TimeSpan(0, 0, 2)); - } + _log.Trace("This is a trace message " + i); + System.Threading.Thread.Sleep(new TimeSpan(0, 0, 2)); } } } \ No newline at end of file diff --git a/examples/Extensions/log4net.Ext.EventID/EventIDLogImpl.cs b/examples/Extensions/log4net.Ext.EventID/EventIDLogImpl.cs index d48cb99f..be73d736 100644 --- a/examples/Extensions/log4net.Ext.EventID/EventIDLogImpl.cs +++ b/examples/Extensions/log4net.Ext.EventID/EventIDLogImpl.cs @@ -21,78 +21,77 @@ using log4net.Core; -namespace log4net.Ext.EventID +namespace log4net.Ext.EventID; + +/// +/// Implementation for +/// +/// +[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix")] +public sealed class EventIDLogImpl(ILogger logger) : LogImpl(logger), IEventIDLog { /// - /// Implementation for + /// The fully qualified name of this declaring type not the type of any subclass. /// - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix")] - public sealed class EventIDLogImpl(ILogger logger) : LogImpl(logger), IEventIDLog - { - /// - /// The fully qualified name of this declaring type not the type of any subclass. - /// - private readonly static Type ThisDeclaringType = typeof(EventIDLogImpl); + private static readonly Type _thisDeclaringType = typeof(EventIDLogImpl); - #region Implementation of IEventIDLog + #region Implementation of IEventIDLog - /// - public void Info(int eventId, object message) => Info(eventId, message, null); + /// + public void Info(int eventId, object message) => Info(eventId, message, null); - /// - public void Info(int eventId, object message, Exception? t) + /// + public void Info(int eventId, object message, Exception? t) + { + if (IsInfoEnabled) { - if (IsInfoEnabled) - { - LoggingEvent loggingEvent = new(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t); - loggingEvent.Properties["EventID"] = eventId; - Logger.Log(loggingEvent); - } + LoggingEvent loggingEvent = new(_thisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t); + loggingEvent.Properties["EventID"] = eventId; + Logger.Log(loggingEvent); } + } - /// - public void Warn(int eventId, object message) => Warn(eventId, message, null); + /// + public void Warn(int eventId, object message) => Warn(eventId, message, null); - /// - public void Warn(int eventId, object message, Exception? t) + /// + public void Warn(int eventId, object message, Exception? t) + { + if (IsWarnEnabled) { - if (IsWarnEnabled) - { - LoggingEvent loggingEvent = new(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Warn, message, t); - loggingEvent.Properties["EventID"] = eventId; - Logger.Log(loggingEvent); - } + LoggingEvent loggingEvent = new(_thisDeclaringType, Logger.Repository, Logger.Name, Level.Warn, message, t); + loggingEvent.Properties["EventID"] = eventId; + Logger.Log(loggingEvent); } + } - /// - public void Error(int eventId, object message) => Error(eventId, message, null); + /// + public void Error(int eventId, object message) => Error(eventId, message, null); - /// - public void Error(int eventId, object message, Exception? t) + /// + public void Error(int eventId, object message, Exception? t) + { + if (IsErrorEnabled) { - if (IsErrorEnabled) - { - LoggingEvent loggingEvent = new(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Error, message, t); - loggingEvent.Properties["EventID"] = eventId; - Logger.Log(loggingEvent); - } + LoggingEvent loggingEvent = new(_thisDeclaringType, Logger.Repository, Logger.Name, Level.Error, message, t); + loggingEvent.Properties["EventID"] = eventId; + Logger.Log(loggingEvent); } + } - /// - public void Fatal(int eventId, object message) => Fatal(eventId, message, null); + /// + public void Fatal(int eventId, object message) => Fatal(eventId, message, null); - /// - public void Fatal(int eventId, object message, Exception? t) + /// + public void Fatal(int eventId, object message, Exception? t) + { + if (IsFatalEnabled) { - if (IsFatalEnabled) - { - LoggingEvent loggingEvent = new(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Fatal, message, t); - loggingEvent.Properties["EventID"] = eventId; - Logger.Log(loggingEvent); - } + LoggingEvent loggingEvent = new(_thisDeclaringType, Logger.Repository, Logger.Name, Level.Fatal, message, t); + loggingEvent.Properties["EventID"] = eventId; + Logger.Log(loggingEvent); } - - #endregion Implementation of IEventIDLog } + + #endregion Implementation of IEventIDLog } diff --git a/examples/Extensions/log4net.Ext.EventID/EventIDLogManager.cs b/examples/Extensions/log4net.Ext.EventID/EventIDLogManager.cs index 6c866714..35244f6e 100644 --- a/examples/Extensions/log4net.Ext.EventID/EventIDLogManager.cs +++ b/examples/Extensions/log4net.Ext.EventID/EventIDLogManager.cs @@ -22,236 +22,235 @@ using System.Reflection; using log4net.Core; -namespace log4net.Ext.EventID +namespace log4net.Ext.EventID; + +/// +/// Custom Logging Class to support Event IDs. +/// +public sealed class EventIDLogManager { + #region Static Member Variables + /// - /// Custom Logging Class to support Event IDs. + /// The wrapper map to use to hold the objects /// - public sealed class EventIDLogManager - { - #region Static Member Variables + private static readonly WrapperMap _wrapperMap = new(new(WrapperCreationHandler)); - /// - /// The wrapper map to use to hold the objects - /// - private static readonly WrapperMap wrapperMap = new(new(WrapperCreationHandler)); + #endregion - #endregion + #region Constructor - #region Constructor - - /// - /// Private constructor to prevent object creation - /// - private EventIDLogManager() { } + /// + /// Private constructor to prevent object creation + /// + private EventIDLogManager() { } - #endregion + #endregion - #region Type Specific Manager Methods + #region Type Specific Manager Methods - /// - /// Returns the named logger if it exists - /// - /// - /// If the named logger exists (in the default hierarchy) then it - /// returns a reference to the logger, otherwise it returns - /// . - /// - /// The fully qualified logger name to look for - /// The logger found, or null - public static IEventIDLog? Exists(string name) => Exists(Assembly.GetCallingAssembly(), name); + /// + /// Returns the named logger if it exists + /// + /// + /// If the named logger exists (in the default hierarchy) then it + /// returns a reference to the logger, otherwise it returns + /// . + /// + /// The fully qualified logger name to look for + /// The logger found, or null + public static IEventIDLog? Exists(string name) => Exists(Assembly.GetCallingAssembly(), name); - /// - /// Returns the named logger if it exists - /// - /// - /// If the named logger exists (in the specified domain) then it - /// returns a reference to the logger, otherwise it returns - /// . - /// - /// the domain to lookup in - /// The fully qualified logger name to look for - /// The logger found, or null - public static IEventIDLog? Exists(string domain, string name) - => WrapLogger(LoggerManager.Exists(domain, name)); + /// + /// Returns the named logger if it exists + /// + /// + /// If the named logger exists (in the specified domain) then it + /// returns a reference to the logger, otherwise it returns + /// . + /// + /// the domain to lookup in + /// The fully qualified logger name to look for + /// The logger found, or null + public static IEventIDLog? Exists(string domain, string name) + => WrapLogger(LoggerManager.Exists(domain, name)); - /// - /// Returns the named logger if it exists - /// - /// - /// If the named logger exists (in the specified assembly's domain) then it - /// returns a reference to the logger, otherwise it returns - /// . - /// - /// the assembly to use to lookup the domain - /// The fully qualified logger name to look for - /// The logger found, or null - public static IEventIDLog? Exists(Assembly assembly, string name) - => WrapLogger(LoggerManager.Exists(assembly, name)); + /// + /// Returns the named logger if it exists + /// + /// + /// If the named logger exists (in the specified assembly's domain) then it + /// returns a reference to the logger, otherwise it returns + /// . + /// + /// the assembly to use to lookup the domain + /// The fully qualified logger name to look for + /// The logger found, or null + public static IEventIDLog? Exists(Assembly assembly, string name) + => WrapLogger(LoggerManager.Exists(assembly, name)); - /// - /// Returns all the currently defined loggers in the default domain. - /// - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers - public static IEventIDLog[] GetCurrentLoggers() - => GetCurrentLoggers(Assembly.GetCallingAssembly()); + /// + /// Returns all the currently defined loggers in the default domain. + /// + /// + /// The root logger is not included in the returned array. + /// + /// All the defined loggers + public static IEventIDLog[] GetCurrentLoggers() + => GetCurrentLoggers(Assembly.GetCallingAssembly()); - /// - /// Returns all the currently defined loggers in the specified domain. - /// - /// the domain to lookup in - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers - public static IEventIDLog[] GetCurrentLoggers(string domain) - => WrapLoggers(LoggerManager.GetCurrentLoggers(domain)); + /// + /// Returns all the currently defined loggers in the specified domain. + /// + /// the domain to lookup in + /// + /// The root logger is not included in the returned array. + /// + /// All the defined loggers + public static IEventIDLog[] GetCurrentLoggers(string domain) + => WrapLoggers(LoggerManager.GetCurrentLoggers(domain)); - /// - /// Returns all the currently defined loggers in the specified assembly's domain. - /// - /// the assembly to use to lookup the domain - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers - public static IEventIDLog[] GetCurrentLoggers(Assembly assembly) - => WrapLoggers(LoggerManager.GetCurrentLoggers(assembly)); + /// + /// Returns all the currently defined loggers in the specified assembly's domain. + /// + /// the assembly to use to lookup the domain + /// + /// The root logger is not included in the returned array. + /// + /// All the defined loggers + public static IEventIDLog[] GetCurrentLoggers(Assembly assembly) + => WrapLoggers(LoggerManager.GetCurrentLoggers(assembly)); - /// - /// Retrieve or create a named logger. - /// - /// - /// Retrieve a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// The name of the logger to retrieve. - /// the logger with the name specified - public static IEventIDLog? GetLogger(string name) - => GetLogger(Assembly.GetCallingAssembly(), name); + /// + /// Retrieve or create a named logger. + /// + /// + /// Retrieve a logger named as the + /// parameter. If the named logger already exists, then the + /// existing instance will be returned. Otherwise, a new instance is + /// created. + /// + /// By default, loggers do not have a set level but inherit + /// it from the hierarchy. This is one of the central features of + /// log4net. + /// + /// The name of the logger to retrieve. + /// the logger with the name specified + public static IEventIDLog? GetLogger(string name) + => GetLogger(Assembly.GetCallingAssembly(), name); - /// - /// Retrieve or create a named logger. - /// - /// - /// Retrieve a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// the domain to lookup in - /// The name of the logger to retrieve. - /// the logger with the name specified - public static IEventIDLog? GetLogger(string domain, string name) - => WrapLogger(LoggerManager.GetLogger(domain, name)); + /// + /// Retrieve or create a named logger. + /// + /// + /// Retrieve a logger named as the + /// parameter. If the named logger already exists, then the + /// existing instance will be returned. Otherwise, a new instance is + /// created. + /// + /// By default, loggers do not have a set level but inherit + /// it from the hierarchy. This is one of the central features of + /// log4net. + /// + /// the domain to lookup in + /// The name of the logger to retrieve. + /// the logger with the name specified + public static IEventIDLog? GetLogger(string domain, string name) + => WrapLogger(LoggerManager.GetLogger(domain, name)); - /// - /// Retrieve or create a named logger. - /// - /// - /// Retrieve a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// the assembly to use to lookup the domain - /// The name of the logger to retrieve. - /// the logger with the name specified - public static IEventIDLog? GetLogger(Assembly assembly, string name) - => WrapLogger(LoggerManager.GetLogger(assembly, name)); + /// + /// Retrieve or create a named logger. + /// + /// + /// Retrieve a logger named as the + /// parameter. If the named logger already exists, then the + /// existing instance will be returned. Otherwise, a new instance is + /// created. + /// + /// By default, loggers do not have a set level but inherit + /// it from the hierarchy. This is one of the central features of + /// log4net. + /// + /// the assembly to use to lookup the domain + /// The name of the logger to retrieve. + /// the logger with the name specified + public static IEventIDLog? GetLogger(Assembly assembly, string name) + => WrapLogger(LoggerManager.GetLogger(assembly, name)); - /// - /// Shorthand for . - /// - /// - /// Get the logger for the fully qualified name of the type specified. - /// - /// The full name of will - /// be used as the name of the logger to retrieve. - /// the logger with the name specified - public static IEventIDLog? GetLogger(Type type) - { - ArgumentNullException.ThrowIfNull(type); - return GetLogger(Assembly.GetCallingAssembly(), type.FullName ?? string.Empty); - } + /// + /// Shorthand for . + /// + /// + /// Get the logger for the fully qualified name of the type specified. + /// + /// The full name of will + /// be used as the name of the logger to retrieve. + /// the logger with the name specified + public static IEventIDLog? GetLogger(Type type) + { + ArgumentNullException.ThrowIfNull(type); + return GetLogger(Assembly.GetCallingAssembly(), type.FullName ?? string.Empty); + } - /// - /// Shorthand for . - /// - /// - /// Get the logger for the fully qualified name of the type specified. - /// - /// the domain to lookup in - /// The full name of will - /// be used as the name of the logger to retrieve. - /// the logger with the name specified - public static IEventIDLog? GetLogger(string domain, Type type) - => WrapLogger(LoggerManager.GetLogger(domain, type)); + /// + /// Shorthand for . + /// + /// + /// Get the logger for the fully qualified name of the type specified. + /// + /// the domain to lookup in + /// The full name of will + /// be used as the name of the logger to retrieve. + /// the logger with the name specified + public static IEventIDLog? GetLogger(string domain, Type type) + => WrapLogger(LoggerManager.GetLogger(domain, type)); - /// - /// Shorthand for . - /// - /// - /// Get the logger for the fully qualified name of the type specified. - /// - /// the assembly to use to lookup the domain - /// The full name of will - /// be used as the name of the logger to retrieve. - /// the logger with the name specified - public static IEventIDLog? GetLogger(Assembly assembly, Type type) - => WrapLogger(LoggerManager.GetLogger(assembly, type)); + /// + /// Shorthand for . + /// + /// + /// Get the logger for the fully qualified name of the type specified. + /// + /// the assembly to use to lookup the domain + /// The full name of will + /// be used as the name of the logger to retrieve. + /// the logger with the name specified + public static IEventIDLog? GetLogger(Assembly assembly, Type type) + => WrapLogger(LoggerManager.GetLogger(assembly, type)); - #endregion + #endregion - #region Extension Handlers + #region Extension Handlers - /// - /// Lookup the wrapper object for the logger specified - /// - /// the logger to get the wrapper for - /// the wrapper for the logger specified - private static IEventIDLog? WrapLogger(ILogger? logger) => (IEventIDLog?)wrapperMap.GetWrapper(logger); + /// + /// Lookup the wrapper object for the logger specified + /// + /// the logger to get the wrapper for + /// the wrapper for the logger specified + private static IEventIDLog? WrapLogger(ILogger? logger) => (IEventIDLog?)_wrapperMap.GetWrapper(logger); - /// - /// Lookup the wrapper objects for the loggers specified - /// - /// the loggers to get the wrappers for - /// Lookup the wrapper objects for the loggers specified - private static IEventIDLog[] WrapLoggers(IReadOnlyList loggers) + /// + /// Lookup the wrapper objects for the loggers specified + /// + /// the loggers to get the wrappers for + /// Lookup the wrapper objects for the loggers specified + private static IEventIDLog[] WrapLoggers(IReadOnlyList loggers) + { + IEventIDLog[] results = new IEventIDLog[loggers.Count]; + for (int i = 0; i < loggers.Count; i++) { - IEventIDLog[] results = new IEventIDLog[loggers.Count]; - for (int i = 0; i < loggers.Count; i++) - { - results[i] = WrapLogger(loggers[i]) ?? throw new ArgumentNullException(nameof(loggers)); - } - return results; + results[i] = WrapLogger(loggers[i]) ?? throw new ArgumentNullException(nameof(loggers)); } + return results; + } - /// - /// Method to create the objects used by - /// this manager. - /// - /// The logger to wrap - /// The wrapper for the logger specified - private static EventIDLogImpl WrapperCreationHandler(ILogger logger) => new(logger); + /// + /// Method to create the objects used by + /// this manager. + /// + /// The logger to wrap + /// The wrapper for the logger specified + private static EventIDLogImpl WrapperCreationHandler(ILogger logger) => new(logger); - #endregion - } + #endregion } diff --git a/examples/Extensions/log4net.Ext.EventID/IEventIDLog.cs b/examples/Extensions/log4net.Ext.EventID/IEventIDLog.cs index 063a1f8b..63027165 100644 --- a/examples/Extensions/log4net.Ext.EventID/IEventIDLog.cs +++ b/examples/Extensions/log4net.Ext.EventID/IEventIDLog.cs @@ -25,53 +25,52 @@ using log4net; -namespace log4net.Ext.EventID +namespace log4net.Ext.EventID; + +/// +/// ILog-Extension +/// +public interface IEventIDLog : ILog { /// - /// ILog-Extension + /// Info /// - public interface IEventIDLog : ILog - { - /// - /// Info - /// - void Info(int eventId, object message); + void Info(int eventId, object message); - /// - /// Info - /// - void Info(int eventId, object message, Exception t); + /// + /// Info + /// + void Info(int eventId, object message, Exception t); - /// - /// Warn - /// - void Warn(int eventId, object message); + /// + /// Warn + /// + void Warn(int eventId, object message); - /// - /// Warn - /// - void Warn(int eventId, object message, Exception t); + /// + /// Warn + /// + void Warn(int eventId, object message, Exception t); - /// - /// Error - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords")] - void Error(int eventId, object message); + /// + /// Error + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords")] + void Error(int eventId, object message); - /// - /// Error - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords")] - void Error(int eventId, object message, Exception t); + /// + /// Error + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords")] + void Error(int eventId, object message, Exception t); - /// - /// Fatal - /// - void Fatal(int eventId, object message); + /// + /// Fatal + /// + void Fatal(int eventId, object message); - /// - /// Fatal - /// - void Fatal(int eventId, object message, Exception t); - } + /// + /// Fatal + /// + void Fatal(int eventId, object message, Exception t); } \ No newline at end of file diff --git a/examples/Extensions/log4net.Ext.Trace/ITraceLog.cs b/examples/Extensions/log4net.Ext.Trace/ITraceLog.cs index 2296928a..67a22d94 100644 --- a/examples/Extensions/log4net.Ext.Trace/ITraceLog.cs +++ b/examples/Extensions/log4net.Ext.Trace/ITraceLog.cs @@ -19,18 +19,17 @@ using System; -namespace log4net.Ext.Trace +namespace log4net.Ext.Trace; + +/// +public interface ITraceLog : ILog { /// - public interface ITraceLog : ILog - { - /// - void Trace(object message); - /// - void Trace(object message, Exception t); - /// - void TraceFormat(string format, params object[] args); - /// - bool IsTraceEnabled { get; } - } + void Trace(object message); + /// + void Trace(object message, Exception t); + /// + void TraceFormat(string format, params object[] args); + /// + bool IsTraceEnabled { get; } } \ No newline at end of file diff --git a/examples/Extensions/log4net.Ext.Trace/TraceLogImpl.cs b/examples/Extensions/log4net.Ext.Trace/TraceLogImpl.cs index 33331bf6..2355995b 100644 --- a/examples/Extensions/log4net.Ext.Trace/TraceLogImpl.cs +++ b/examples/Extensions/log4net.Ext.Trace/TraceLogImpl.cs @@ -22,64 +22,67 @@ using log4net.Core; using log4net.Util; -namespace log4net.Ext.Trace +namespace log4net.Ext.Trace; + +/// +[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix")] +public sealed class TraceLogImpl(ILogger logger) : LogImpl(logger), ITraceLog { - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix")] - public sealed class TraceLogImpl(ILogger logger) : LogImpl(logger), ITraceLog - { - /// - /// The fully qualified name of this declaring type not the type of any subclass. - /// - private readonly static Type ThisDeclaringType = typeof(TraceLogImpl); + /// + /// The fully qualified name of this declaring type not the type of any subclass. + /// + private static readonly Type _thisDeclaringType = typeof(TraceLogImpl); - /// - /// The default value for the TRACE level - /// - private readonly static Level s_defaultLevelTrace = new(20000, "TRACE"); + /// + /// The default value for the TRACE level + /// + private static readonly Level _defaultLevelTrace = new(20000, "TRACE"); - /// - /// The current value for the TRACE level - /// - private Level? levelTrace; + /// + /// The current value for the TRACE level + /// + private Level? _levelTrace; - /// - /// Lookup the current value of the TRACE level - /// - protected override void ReloadLevels(Repository.ILoggerRepository repository) - { - base.ReloadLevels(repository); - ArgumentNullException.ThrowIfNull(repository); - levelTrace = repository.LevelMap.LookupWithDefault(s_defaultLevelTrace); - } + /// + /// Lookup the current value of the TRACE level + /// + protected override void ReloadLevels(Repository.ILoggerRepository repository) + { + base.ReloadLevels(repository); + ArgumentNullException.ThrowIfNull(repository); + _levelTrace = repository.LevelMap.LookupWithDefault(_defaultLevelTrace); + } - #region Implementation of ITraceLog + #region Implementation of ITraceLog - /// - public void Trace(object message) - => Logger.Log(ThisDeclaringType, levelTrace, message, null); + /// + public void Trace(object message) + => Logger.Log(_thisDeclaringType, _levelTrace, message, null); - /// - public void Trace(object message, Exception t) - => Logger.Log(ThisDeclaringType, levelTrace, message, t); + /// + public void Trace(object message, Exception t) + => Logger.Log(_thisDeclaringType, _levelTrace, message, t); - /// - public void TraceFormat(string format, params object[] args) + /// + public void TraceFormat(string format, params object[] args) + { + if (IsTraceEnabled) { - if (IsTraceEnabled) - Logger.Log(ThisDeclaringType, levelTrace, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); + Logger.Log(_thisDeclaringType, _levelTrace, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null); } + } - /// - public void TraceFormat(IFormatProvider provider, string format, params object[] args) + /// + public void TraceFormat(IFormatProvider provider, string format, params object[] args) + { + if (IsTraceEnabled) { - if (IsTraceEnabled) - Logger.Log(ThisDeclaringType, levelTrace, new SystemStringFormat(provider, format, args), null); + Logger.Log(_thisDeclaringType, _levelTrace, new SystemStringFormat(provider, format, args), null); } + } - /// - public bool IsTraceEnabled => Logger.IsEnabledFor(levelTrace); + /// + public bool IsTraceEnabled => Logger.IsEnabledFor(_levelTrace); - #endregion Implementation of ITraceLog - } + #endregion Implementation of ITraceLog } \ No newline at end of file diff --git a/examples/Extensions/log4net.Ext.Trace/TraceLogManager.cs b/examples/Extensions/log4net.Ext.Trace/TraceLogManager.cs index df9635c0..3946e598 100644 --- a/examples/Extensions/log4net.Ext.Trace/TraceLogManager.cs +++ b/examples/Extensions/log4net.Ext.Trace/TraceLogManager.cs @@ -21,226 +21,225 @@ using System.Reflection; using log4net.Core; -namespace log4net.Ext.Trace +namespace log4net.Ext.Trace; + +/// +/// Custom Logging Class to support additional logging levels +/// +public static class TraceLogManager { + #region Static Member Variables + + /// + /// The wrapper map to use to hold the objects + /// + private static readonly WrapperMap _wrapperMap = new(new WrapperCreationHandler(WrapperCreationHandler)); + + #endregion + + #region Type Specific Manager Methods + /// - /// Custom Logging Class to support additional logging levels + /// Returns the named logger if it exists /// - public static class TraceLogManager + /// + /// If the named logger exists (in the default hierarchy) then it + /// returns a reference to the logger, otherwise it returns + /// . + /// + /// The fully qualified logger name to look for + /// The logger found, or null + public static ITraceLog? Exists(string name) => Exists(Assembly.GetCallingAssembly(), name); + + /// + /// Returns the named logger if it exists + /// + /// + /// If the named logger exists (in the specified domain) then it + /// returns a reference to the logger, otherwise it returns + /// . + /// + /// the domain to lookup in + /// The fully qualified logger name to look for + /// The logger found, or null + public static ITraceLog? Exists(string domain, string name) + => WrapLogger(LoggerManager.Exists(domain, name)); + + /// + /// Returns the named logger if it exists + /// + /// + /// If the named logger exists (in the specified assembly's domain) then it + /// returns a reference to the logger, otherwise it returns + /// . + /// + /// the assembly to use to lookup the domain + /// The fully qualified logger name to look for + /// The logger found, or null + public static ITraceLog? Exists(Assembly assembly, string name) + => WrapLogger(LoggerManager.Exists(assembly, name)); + + /// + /// Returns all the currently defined loggers in the default domain. + /// + /// + /// The root logger is not included in the returned array. + /// + /// All the defined loggers + public static ITraceLog[] GetCurrentLoggers() => GetCurrentLoggers(Assembly.GetCallingAssembly()); + + /// + /// Returns all the currently defined loggers in the specified domain. + /// + /// the domain to lookup in + /// + /// The root logger is not included in the returned array. + /// + /// All the defined loggers + public static ITraceLog[] GetCurrentLoggers(string domain) + => WrapLoggers(LoggerManager.GetCurrentLoggers(domain)); + + /// + /// Returns all the currently defined loggers in the specified assembly's domain. + /// + /// the assembly to use to lookup the domain + /// + /// The root logger is not included in the returned array. + /// + /// All the defined loggers + public static ITraceLog[] GetCurrentLoggers(Assembly assembly) + => WrapLoggers(LoggerManager.GetCurrentLoggers(assembly)); + + /// + /// Retrieve or create a named logger. + /// + /// + /// Retrieve a logger named as the + /// parameter. If the named logger already exists, then the + /// existing instance will be returned. Otherwise, a new instance is + /// created. + /// + /// By default, loggers do not have a set level but inherit + /// it from the hierarchy. This is one of the central features of + /// log4net. + /// + /// The name of the logger to retrieve. + /// the logger with the name specified + public static ITraceLog? GetLogger(string name) => GetLogger(Assembly.GetCallingAssembly(), name); + + /// + /// Retrieve or create a named logger. + /// + /// + /// Retrieve a logger named as the + /// parameter. If the named logger already exists, then the + /// existing instance will be returned. Otherwise, a new instance is + /// created. + /// + /// By default, loggers do not have a set level but inherit + /// it from the hierarchy. This is one of the central features of + /// log4net. + /// + /// the domain to lookup in + /// The name of the logger to retrieve. + /// the logger with the name specified + public static ITraceLog? GetLogger(string domain, string name) + => WrapLogger(LoggerManager.GetLogger(domain, name)); + + /// + /// Retrieve or create a named logger. + /// + /// + /// Retrieve a logger named as the + /// parameter. If the named logger already exists, then the + /// existing instance will be returned. Otherwise, a new instance is + /// created. + /// + /// By default, loggers do not have a set level but inherit + /// it from the hierarchy. This is one of the central features of + /// log4net. + /// + /// the assembly to use to lookup the domain + /// The name of the logger to retrieve. + /// the logger with the name specified + public static ITraceLog? GetLogger(Assembly assembly, string name) + => WrapLogger(LoggerManager.GetLogger(assembly, name)); + + /// + /// Shorthand for . + /// + /// + /// Get the logger for the fully qualified name of the type specified. + /// + /// The full name of will + /// be used as the name of the logger to retrieve. + /// the logger with the name specified + public static ITraceLog? GetLogger(Type type) { - #region Static Member Variables - - /// - /// The wrapper map to use to hold the objects - /// - private static readonly WrapperMap s_wrapperMap = new(new WrapperCreationHandler(WrapperCreationHandler)); - - #endregion - - #region Type Specific Manager Methods - - /// - /// Returns the named logger if it exists - /// - /// - /// If the named logger exists (in the default hierarchy) then it - /// returns a reference to the logger, otherwise it returns - /// . - /// - /// The fully qualified logger name to look for - /// The logger found, or null - public static ITraceLog? Exists(string name) => Exists(Assembly.GetCallingAssembly(), name); - - /// - /// Returns the named logger if it exists - /// - /// - /// If the named logger exists (in the specified domain) then it - /// returns a reference to the logger, otherwise it returns - /// . - /// - /// the domain to lookup in - /// The fully qualified logger name to look for - /// The logger found, or null - public static ITraceLog? Exists(string domain, string name) - => WrapLogger(LoggerManager.Exists(domain, name)); - - /// - /// Returns the named logger if it exists - /// - /// - /// If the named logger exists (in the specified assembly's domain) then it - /// returns a reference to the logger, otherwise it returns - /// . - /// - /// the assembly to use to lookup the domain - /// The fully qualified logger name to look for - /// The logger found, or null - public static ITraceLog? Exists(Assembly assembly, string name) - => WrapLogger(LoggerManager.Exists(assembly, name)); - - /// - /// Returns all the currently defined loggers in the default domain. - /// - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers - public static ITraceLog[] GetCurrentLoggers() => GetCurrentLoggers(Assembly.GetCallingAssembly()); - - /// - /// Returns all the currently defined loggers in the specified domain. - /// - /// the domain to lookup in - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers - public static ITraceLog[] GetCurrentLoggers(string domain) - => WrapLoggers(LoggerManager.GetCurrentLoggers(domain)); - - /// - /// Returns all the currently defined loggers in the specified assembly's domain. - /// - /// the assembly to use to lookup the domain - /// - /// The root logger is not included in the returned array. - /// - /// All the defined loggers - public static ITraceLog[] GetCurrentLoggers(Assembly assembly) - => WrapLoggers(LoggerManager.GetCurrentLoggers(assembly)); - - /// - /// Retrieve or create a named logger. - /// - /// - /// Retrieve a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// The name of the logger to retrieve. - /// the logger with the name specified - public static ITraceLog? GetLogger(string name) => GetLogger(Assembly.GetCallingAssembly(), name); - - /// - /// Retrieve or create a named logger. - /// - /// - /// Retrieve a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// the domain to lookup in - /// The name of the logger to retrieve. - /// the logger with the name specified - public static ITraceLog? GetLogger(string domain, string name) - => WrapLogger(LoggerManager.GetLogger(domain, name)); - - /// - /// Retrieve or create a named logger. - /// - /// - /// Retrieve a logger named as the - /// parameter. If the named logger already exists, then the - /// existing instance will be returned. Otherwise, a new instance is - /// created. - /// - /// By default, loggers do not have a set level but inherit - /// it from the hierarchy. This is one of the central features of - /// log4net. - /// - /// the assembly to use to lookup the domain - /// The name of the logger to retrieve. - /// the logger with the name specified - public static ITraceLog? GetLogger(Assembly assembly, string name) - => WrapLogger(LoggerManager.GetLogger(assembly, name)); - - /// - /// Shorthand for . - /// - /// - /// Get the logger for the fully qualified name of the type specified. - /// - /// The full name of will - /// be used as the name of the logger to retrieve. - /// the logger with the name specified - public static ITraceLog? GetLogger(Type type) - { - ArgumentNullException.ThrowIfNull(type?.FullName); - return GetLogger(Assembly.GetCallingAssembly(), type.FullName); - } + ArgumentNullException.ThrowIfNull(type?.FullName); + return GetLogger(Assembly.GetCallingAssembly(), type.FullName); + } - /// - /// Shorthand for . - /// - /// - /// Get the logger for the fully qualified name of the type specified. - /// - /// the domain to lookup in - /// The full name of will - /// be used as the name of the logger to retrieve. - /// the logger with the name specified - public static ITraceLog? GetLogger(string domain, Type type) - => WrapLogger(LoggerManager.GetLogger(domain, type)); - - /// - /// Shorthand for . - /// - /// - /// Get the logger for the fully qualified name of the type specified. - /// - /// the assembly to use to lookup the domain - /// The full name of will - /// be used as the name of the logger to retrieve. - /// the logger with the name specified - public static ITraceLog? GetLogger(Assembly assembly, Type type) - => WrapLogger(LoggerManager.GetLogger(assembly, type)); - - #endregion - - #region Extension Handlers - - /// - /// Lookup the wrapper object for the logger specified - /// - /// the logger to get the wrapper for - /// the wrapper for the logger specified - private static ITraceLog? WrapLogger(ILogger? logger) => (ITraceLog?)s_wrapperMap.GetWrapper(logger); - - /// - /// Lookup the wrapper objects for the loggers specified - /// - /// the loggers to get the wrappers for - /// Lookup the wrapper objects for the loggers specified - private static ITraceLog[] WrapLoggers(ILogger[] loggers) - { - ITraceLog[] results = new ITraceLog[loggers.Length]; - for (int i = 0; i < loggers.Length; i++) - { - results[i] = WrapLogger(loggers[i]) ?? throw new ArgumentNullException(nameof(loggers)); - } + /// + /// Shorthand for . + /// + /// + /// Get the logger for the fully qualified name of the type specified. + /// + /// the domain to lookup in + /// The full name of will + /// be used as the name of the logger to retrieve. + /// the logger with the name specified + public static ITraceLog? GetLogger(string domain, Type type) + => WrapLogger(LoggerManager.GetLogger(domain, type)); - return results; - } + /// + /// Shorthand for . + /// + /// + /// Get the logger for the fully qualified name of the type specified. + /// + /// the assembly to use to lookup the domain + /// The full name of will + /// be used as the name of the logger to retrieve. + /// the logger with the name specified + public static ITraceLog? GetLogger(Assembly assembly, Type type) + => WrapLogger(LoggerManager.GetLogger(assembly, type)); - /// - /// Method to create the objects used by - /// this manager. - /// - /// The logger to wrap - /// The wrapper for the logger specified - private static TraceLogImpl WrapperCreationHandler(ILogger logger) => new(logger); + #endregion - #endregion + #region Extension Handlers + + /// + /// Lookup the wrapper object for the logger specified + /// + /// the logger to get the wrapper for + /// the wrapper for the logger specified + private static ITraceLog? WrapLogger(ILogger? logger) => (ITraceLog?)_wrapperMap.GetWrapper(logger); + + /// + /// Lookup the wrapper objects for the loggers specified + /// + /// the loggers to get the wrappers for + /// Lookup the wrapper objects for the loggers specified + private static ITraceLog[] WrapLoggers(ILogger[] loggers) + { + ITraceLog[] results = new ITraceLog[loggers.Length]; + for (int i = 0; i < loggers.Length; i++) + { + results[i] = WrapLogger(loggers[i]) ?? throw new ArgumentNullException(nameof(loggers)); + } + + return results; } + + /// + /// Method to create the objects used by + /// this manager. + /// + /// The logger to wrap + /// The wrapper for the logger specified + private static TraceLogImpl WrapperCreationHandler(ILogger logger) => new(logger); + + #endregion } \ No newline at end of file diff --git a/examples/Layouts/SampleLayoutsApp/Layout/ForwardingLayout.cs b/examples/Layouts/SampleLayoutsApp/Layout/ForwardingLayout.cs index 341feb5e..8b2af5f0 100644 --- a/examples/Layouts/SampleLayoutsApp/Layout/ForwardingLayout.cs +++ b/examples/Layouts/SampleLayoutsApp/Layout/ForwardingLayout.cs @@ -21,128 +21,129 @@ using log4net.Core; using log4net.Layout; -namespace SampleLayoutsApp.Layout +namespace SampleLayoutsApp.Layout; + +/// +/// The ForwardingLayout forwards to a nested +/// +/// +/// The ForwardingLayout base class is used by layouts that want +/// to decorate other objects. +/// +public abstract class ForwardingLayout : ILayout, IOptionHandler { + /// + protected ForwardingLayout() + { + } + + /// + public ILayout? Layout { get; set; } + + #region Implementation of IOptionHandler + /// - /// The ForwardingLayout forwards to a nested + /// Activate component options /// /// - /// The ForwardingLayout base class is used by layouts that want - /// to decorate other objects. + /// + /// This is part of the delayed object + /// activation scheme. The method must + /// be called on this object after the configuration properties have + /// been set. Until is called this + /// object is in an undefined state and must not be used. + /// + /// + /// If any of the configuration properties are modified then + /// must be called again. + /// + /// + /// This method must be implemented by the subclass. + /// /// - public abstract class ForwardingLayout : ILayout, IOptionHandler + public virtual void ActivateOptions() { - /// - protected ForwardingLayout() + if (Layout is IOptionHandler optionHandler) { + optionHandler.ActivateOptions(); } + } - /// - public ILayout? Layout { get; set; } - - #region Implementation of IOptionHandler - - /// - /// Activate component options - /// - /// - /// - /// This is part of the delayed object - /// activation scheme. The method must - /// be called on this object after the configuration properties have - /// been set. Until is called this - /// object is in an undefined state and must not be used. - /// - /// - /// If any of the configuration properties are modified then - /// must be called again. - /// - /// - /// This method must be implemented by the subclass. - /// - /// - public virtual void ActivateOptions() - { - if (Layout is IOptionHandler optionHandler) - optionHandler.ActivateOptions(); - } - - #endregion + #endregion - #region Implementation of ILayout + #region Implementation of ILayout - /// - /// Implement this method to create your own layout format. - /// - /// The TextWriter to write the formatted event to - /// The event to format - /// - /// - /// This method is called by an appender to format - /// the as text. - /// - /// - virtual public void Format(TextWriter writer, LoggingEvent loggingEvent) - => Layout?.Format(writer, loggingEvent); + /// + /// Implement this method to create your own layout format. + /// + /// The TextWriter to write the formatted event to + /// The event to format + /// + /// + /// This method is called by an appender to format + /// the as text. + /// + /// + virtual public void Format(TextWriter writer, LoggingEvent loggingEvent) + => Layout?.Format(writer, loggingEvent); - /// - /// The content type output by this layout. - /// - /// The content type is "text/plain" - /// - /// - /// The content type output by this layout. - /// - /// - /// This base class uses the value "text/plain". - /// To change this value a subclass must override this - /// property. - /// - /// - public virtual string ContentType => Layout?.ContentType ?? "text/plain"; + /// + /// The content type output by this layout. + /// + /// The content type is "text/plain" + /// + /// + /// The content type output by this layout. + /// + /// + /// This base class uses the value "text/plain". + /// To change this value a subclass must override this + /// property. + /// + /// + public virtual string ContentType => Layout?.ContentType ?? "text/plain"; - /// - /// The header for the layout format. - /// - /// the layout header - /// - /// - /// The Header text will be appended before any logging events - /// are formatted and appended. - /// - /// - public virtual string? Header => Layout?.Header; + /// + /// The header for the layout format. + /// + /// the layout header + /// + /// + /// The Header text will be appended before any logging events + /// are formatted and appended. + /// + /// + public virtual string? Header => Layout?.Header; - /// - /// The footer for the layout format. - /// - /// the layout footer - /// - /// - /// The Footer text will be appended after all the logging events - /// have been formatted and appended. - /// - /// - public virtual string? Footer => Layout?.Footer; + /// + /// The footer for the layout format. + /// + /// the layout footer + /// + /// + /// The Footer text will be appended after all the logging events + /// have been formatted and appended. + /// + /// + public virtual string? Footer => Layout?.Footer; - /// - /// Flag indicating if this layout handles exceptions - /// - /// false if this layout handles exceptions - /// - /// - /// If this layout handles the exception object contained within - /// , then the layout should return - /// false. Otherwise, if the layout ignores the exception - /// object, then the layout should return true. - /// - /// - /// Set this value to override a this default setting. The default - /// value is true, this layout does not handle the exception. - /// - /// - public virtual bool IgnoresException => Layout?.IgnoresException ?? true; + /// + /// Flag indicating if this layout handles exceptions + /// + /// false if this layout handles exceptions + /// + /// + /// If this layout handles the exception object contained within + /// , then the layout should return + /// false. Otherwise, if the layout ignores the exception + /// object, then the layout should return true. + /// + /// + /// Set this value to override a this default setting. The default + /// value is true, this layout does not handle the exception. + /// + /// + public virtual bool IgnoresException => Layout?.IgnoresException ?? true; - #endregion - } + #endregion } \ No newline at end of file diff --git a/examples/Layouts/SampleLayoutsApp/Layout/LevelConversionPattern.cs b/examples/Layouts/SampleLayoutsApp/Layout/LevelConversionPattern.cs index 63651016..dae7637d 100644 --- a/examples/Layouts/SampleLayoutsApp/Layout/LevelConversionPattern.cs +++ b/examples/Layouts/SampleLayoutsApp/Layout/LevelConversionPattern.cs @@ -19,15 +19,14 @@ using log4net.Core; -namespace SampleLayoutsApp.Layout +namespace SampleLayoutsApp.Layout; + +/// +public sealed class LevelConversionPattern { /// - public sealed class LevelConversionPattern - { - /// - public required Level Level { get; init; } + public required Level Level { get; init; } - /// - public required string ConversionPattern { get; init; } - } + /// + public required string ConversionPattern { get; init; } } \ No newline at end of file diff --git a/examples/Layouts/SampleLayoutsApp/Layout/LevelPatternLayout.cs b/examples/Layouts/SampleLayoutsApp/Layout/LevelPatternLayout.cs index bc9f081e..7a810692 100644 --- a/examples/Layouts/SampleLayoutsApp/Layout/LevelPatternLayout.cs +++ b/examples/Layouts/SampleLayoutsApp/Layout/LevelPatternLayout.cs @@ -23,28 +23,32 @@ using log4net.Core; using log4net.Layout; -namespace SampleLayoutsApp.Layout +namespace SampleLayoutsApp.Layout; + +/// +public sealed class LevelPatternLayout : PatternLayout { + private readonly Hashtable _levelToPatternLayout = []; + /// - public sealed class LevelPatternLayout : PatternLayout + public override void Format(TextWriter writer, LoggingEvent loggingEvent) { - private readonly Hashtable levelToPatternLayout = []; - - /// - public override void Format(TextWriter writer, LoggingEvent loggingEvent) + ArgumentNullException.ThrowIfNull(loggingEvent); + if (loggingEvent.Level is null + || _levelToPatternLayout[loggingEvent.Level] is not PatternLayout patternLayout) { - ArgumentNullException.ThrowIfNull(loggingEvent); - if (levelToPatternLayout[loggingEvent.Level] is not PatternLayout patternLayout) - base.Format(writer, loggingEvent); - else - patternLayout.Format(writer, loggingEvent); + base.Format(writer, loggingEvent); } - - /// - public void AddLevelConversionPattern(LevelConversionPattern levelLayout) + else { - ArgumentNullException.ThrowIfNull(levelLayout); - levelToPatternLayout[levelLayout.Level] = new PatternLayout(levelLayout.ConversionPattern); + patternLayout.Format(writer, loggingEvent); } } + + /// + public void AddLevelConversionPattern(LevelConversionPattern levelLayout) + { + ArgumentNullException.ThrowIfNull(levelLayout); + _levelToPatternLayout[levelLayout.Level] = new PatternLayout(levelLayout.ConversionPattern); + } } \ No newline at end of file diff --git a/examples/Layouts/SampleLayoutsApp/Layout/LineWrappingLayout.cs b/examples/Layouts/SampleLayoutsApp/Layout/LineWrappingLayout.cs index b8ee4a9f..7e1b57e1 100644 --- a/examples/Layouts/SampleLayoutsApp/Layout/LineWrappingLayout.cs +++ b/examples/Layouts/SampleLayoutsApp/Layout/LineWrappingLayout.cs @@ -21,65 +21,66 @@ using System.IO; using log4net.Core; -namespace SampleLayoutsApp.Layout +namespace SampleLayoutsApp.Layout; + +/// +/// The LineWrappingLayout wraps the output of a nested layout +/// +/// +/// The output of the nested layout is wrapped at +/// . Each of the continuation lines +/// is prefixed with a number of spaces specified by . +/// +public sealed class LineWrappingLayout : ForwardingLayout { - /// - /// The LineWrappingLayout wraps the output of a nested layout - /// - /// - /// The output of the nested layout is wrapped at - /// . Each of the continuation lines - /// is prefixed with a number of spaces specified by . - /// - public sealed class LineWrappingLayout : ForwardingLayout - { - /// - public int LineWidth { get; set; } = 76; + /// + public int LineWidth { get; set; } = 76; - /// - public int Indent { get; set; } = 4; + /// + public int Indent { get; set; } = 4; - /// - public override void Format(TextWriter writer, LoggingEvent loggingEvent) - { - ArgumentNullException.ThrowIfNull(writer); - using StringWriter stringWriter = new(); + /// + public override void Format(TextWriter writer, LoggingEvent loggingEvent) + { + ArgumentNullException.ThrowIfNull(writer); + using StringWriter stringWriter = new(); - base.Format(stringWriter, loggingEvent); + base.Format(stringWriter, loggingEvent); - string formattedString = stringWriter.ToString(); + string formattedString = stringWriter.ToString(); - WrapText(writer, formattedString); - } + WrapText(writer, formattedString); + } - private void WrapText(TextWriter writer, string text) + private void WrapText(TextWriter writer, string text) + { + if (text.Length <= LineWidth) { - if (text.Length <= LineWidth) - writer.Write(text); - else - { - // Do the first line - writer.WriteLine(text.AsSpan(0, LineWidth)); - string rest = text[LineWidth..]; + writer.Write(text); + } + else + { + // Do the first line + writer.WriteLine(text.AsSpan(0, LineWidth)); + string rest = text[LineWidth..]; - string indentString = new(' ', Indent); - int continuationLineWidth = LineWidth - Indent; + string indentString = new(' ', Indent); + int continuationLineWidth = LineWidth - Indent; - // Do the continuation lines - while (true) - { - writer.Write(indentString); + // Do the continuation lines + while (true) + { + writer.Write(indentString); - if (rest.Length > continuationLineWidth) - { - writer.WriteLine(rest[..continuationLineWidth]); - rest = rest[continuationLineWidth..]; - } - else - { - writer.Write(rest); - break; - } + if (rest.Length > continuationLineWidth) + { + writer.WriteLine(rest[..continuationLineWidth]); + rest = rest[continuationLineWidth..]; + } + else + { + writer.Write(rest); + break; } } } diff --git a/examples/Layouts/SampleLayoutsApp/LoggingExample.cs b/examples/Layouts/SampleLayoutsApp/LoggingExample.cs index 7597397a..7b26f036 100644 --- a/examples/Layouts/SampleLayoutsApp/LoggingExample.cs +++ b/examples/Layouts/SampleLayoutsApp/LoggingExample.cs @@ -25,39 +25,47 @@ // called ConsoleApp.exe.config in the application base // directory (i.e. the directory containing SampleAppendersApp.exe) -namespace SampleLayoutsApp +namespace SampleLayoutsApp; + +/// +/// Example of how to simply configure and use log4net +/// +public static class LoggingExample { + // Create a logger for use in this class + private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof(LoggingExample)); + /// - /// Example of how to simply configure and use log4net + /// Application entry point /// - public static class LoggingExample + [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")] + public static void Main() { - // Create a logger for use in this class - private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(LoggingExample)); - - /// - /// Application entry point - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")] - public static void Main() + // Log an info level message + if (_log.IsInfoEnabled) { - // Log an info level message - if (log.IsInfoEnabled) log.Info("Application [SampleLayoutsApp] Start"); - - // Log a debug message. Test if debug is enabled before - // attempting to log the message. This is not required but - // can make running without logging faster. - if (log.IsDebugEnabled) log.Debug("This is a debug message"); + _log.Info("Application [SampleLayoutsApp] Start"); + } - log.Info("This is a long line of logging text. This should test if the LineWrappingLayout works. This text should be wrapped over multiple lines of output. Could you get a log message longer than this?"); + // Log a debug message. Test if debug is enabled before + // attempting to log the message. This is not required but + // can make running without logging faster. + if (_log.IsDebugEnabled) + { + _log.Debug("This is a debug message"); + } - log.Error("Hey this is an error!"); + _log.Info("This is a long line of logging text. This should test if the LineWrappingLayout works. This text should be wrapped over multiple lines of output. Could you get a log message longer than this?"); - // Log an info level message - if (log.IsInfoEnabled) log.Info("Application [SampleLayoutsApp] End"); + _log.Error("Hey this is an error!"); - Console.Write("Press Enter to exit..."); - Console.ReadLine(); + // Log an info level message + if (_log.IsInfoEnabled) + { + _log.Info("Application [SampleLayoutsApp] End"); } + + Console.Write("Press Enter to exit..."); + Console.ReadLine(); } } \ No newline at end of file diff --git a/examples/Performance/NotLogging/NotLogging.cs b/examples/Performance/NotLogging/NotLogging.cs index 8c05e80b..93ca5355 100644 --- a/examples/Performance/NotLogging/NotLogging.cs +++ b/examples/Performance/NotLogging/NotLogging.cs @@ -25,374 +25,396 @@ using log4net.Layout; using log4net.Repository.Hierarchy; -namespace NotLogging +namespace NotLogging; + +/// +/// NotLogging +/// +[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider")] +[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")] +internal static class NotLogging { + #region Init Code + + private static int _warmupCycles = 10000; + private static readonly ILog _shortLog = LogManager.GetLogger("A0123456789"); + private static readonly ILog _mediumLog = LogManager.GetLogger("A0123456789.B0123456789"); + private static readonly ILog _longLog = LogManager.GetLogger("A0123456789.B0123456789.C0123456789"); + private static readonly ILog _inexistentShortLog = LogManager.GetLogger("I0123456789"); + private static readonly ILog _inexistentMediumLog = LogManager.GetLogger("I0123456789.B0123456789"); + private static readonly ILog _inexistentLongLog = LogManager.GetLogger("I0123456789.B0123456789.C0123456789"); + private static readonly ILog[] _logArray = + [ + _shortLog, + _mediumLog, + _longLog, + _inexistentShortLog, + _inexistentMediumLog, + _inexistentLongLog + ]; + private static readonly TimedTest[] _timedTests = + [ + new SimpleMessage_Bare(), + new SimpleMessage_Array(), + new SimpleMessage_MethodGuard_Bare(), + new SimpleMessage_LocalGuard_Bare(), + new ComplexMessage_Bare(), + new ComplexMessage_Array(), + new ComplexMessage_MethodGuard_Bare(), + new ComplexMessage_MethodGuard_Array(), + new ComplexMessage_MemberGuard_Bare(), + new ComplexMessage_LocalGuard_Bare() + ]; + + private static void Usage() + { + Console.WriteLine( + "Usage: NotLogging " + Environment.NewLine + + "\t true indicates shipped code" + Environment.NewLine + + "\t false indicates code in development" + Environment.NewLine + + "\t runLength is an int representing the run length of loops" + Environment.NewLine + + "\t We suggest that runLength be at least 1000000 (1 million)."); + Environment.Exit(1); + } + /// - /// NotLogging + /// Program wide initialization method /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider")] + /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")] - internal static class NotLogging + private static int ProgramInit(string[] args) { - #region Init Code - - private static int warmupCycles = 10000; - private static readonly ILog SHORT_LOG = LogManager.GetLogger("A0123456789"); - private static readonly ILog MEDIUM_LOG = LogManager.GetLogger("A0123456789.B0123456789"); - private static readonly ILog LONG_LOG = LogManager.GetLogger("A0123456789.B0123456789.C0123456789"); - private static readonly ILog INEXISTENT_SHORT_LOG = LogManager.GetLogger("I0123456789"); - private static readonly ILog INEXISTENT_MEDIUM_LOG = LogManager.GetLogger("I0123456789.B0123456789"); - private static readonly ILog INEXISTENT_LONG_LOG = LogManager.GetLogger("I0123456789.B0123456789.C0123456789"); - private static readonly ILog[] LOG_ARRAY = [ - SHORT_LOG, - MEDIUM_LOG, - LONG_LOG, - INEXISTENT_SHORT_LOG, - INEXISTENT_MEDIUM_LOG, - INEXISTENT_LONG_LOG]; - private static readonly TimedTest[] TIMED_TESTS = [ - new SimpleMessage_Bare(), - new SimpleMessage_Array(), - new SimpleMessage_MethodGuard_Bare(), - new SimpleMessage_LocalGuard_Bare(), - new ComplexMessage_Bare(), - new ComplexMessage_Array(), - new ComplexMessage_MethodGuard_Bare(), - new ComplexMessage_MethodGuard_Array(), - new ComplexMessage_MemberGuard_Bare(), - new ComplexMessage_LocalGuard_Bare()]; - - private static void Usage() + if (args is not string[] { Length: 2 }) { - Console.WriteLine( - "Usage: NotLogging " + Environment.NewLine + - "\t true indicates shipped code" + Environment.NewLine + - "\t false indicates code in development" + Environment.NewLine + - "\t runLength is an int representing the run length of loops" + Environment.NewLine + - "\t We suggest that runLength be at least 1000000 (1 million)."); - Environment.Exit(1); + Usage(); + return 0; } + if (!int.TryParse(args[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out int runLength)) + { + Usage(); + return 0; + } + + ConsoleAppender appender = new() { Layout = new SimpleLayout() }; + ((SimpleLayout)appender.Layout).ActivateOptions(); + appender.ActivateOptions(); - /// - /// Program wide initialization method - /// - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")] - private static int ProgramInit(string[] args) + if ("false" == args[0]) { - if (args is not string[] { Length: 2 }) - { - Usage(); - return 0; - } - if (!int.TryParse(args[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out int runLength)) - { - Usage(); - return 0; - } + // nothing to do + } + else if ("true" == args[0]) + { + Console.WriteLine("Flagging as shipped code."); + ((Hierarchy)LogManager.GetRepository()).Threshold = log4net.Core.Level.Warn; + } + else + { + Usage(); + } - ConsoleAppender appender = new() { Layout = new SimpleLayout() }; - ((SimpleLayout)appender.Layout).ActivateOptions(); - appender.ActivateOptions(); + ((Logger)_shortLog.Logger).Level = log4net.Core.Level.Info; + ((Hierarchy)LogManager.GetRepository()).Root.Level = log4net.Core.Level.Info; + ((Hierarchy)LogManager.GetRepository()).Root.AddAppender(appender); - if ("false" == args[0]) - { - // nothing to do - } - else if ("true" == args[0]) - { - Console.WriteLine("Flagging as shipped code."); - ((Hierarchy)LogManager.GetRepository()).Threshold = log4net.Core.Level.Warn; - } - else - { - Usage(); - } + return runLength; + } - ((Logger)SHORT_LOG.Logger).Level = log4net.Core.Level.Info; - ((Hierarchy)LogManager.GetRepository()).Root.Level = log4net.Core.Level.Info; - ((Hierarchy)LogManager.GetRepository()).Root.AddAppender(appender); + #endregion - return runLength; + /// + /// The main entry point for the application. + /// + [STAThread] + private static void Main(string[] argv) + { + if (System.Diagnostics.Debugger.IsAttached) + { + _warmupCycles = 0; + argv = ["false", "2"]; + } + if (argv.Length != 2) + { + Usage(); } - #endregion + int runLength = ProgramInit(argv); - /// - /// The main entry point for the application. - /// - [STAThread] - private static void Main(string[] argv) + Console.WriteLine(); + Console.Write("Warming Up..."); + + if (_warmupCycles > 0) { - if (System.Diagnostics.Debugger.IsAttached) + foreach (ILog logger in _logArray) { - warmupCycles = 0; - argv = ["false", "2"]; + foreach (TimedTest timedTest in _timedTests) + { + timedTest.Run(logger, _warmupCycles); + } } - if (argv.Length != 2) - Usage(); - - int runLength = ProgramInit(argv); - - Console.WriteLine(); - Console.Write("Warming Up..."); + } - if (warmupCycles > 0) - foreach (ILog logger in LOG_ARRAY) - foreach (TimedTest timedTest in TIMED_TESTS) - timedTest.Run(logger, warmupCycles); + Console.WriteLine("Done"); + Console.WriteLine(); - Console.WriteLine("Done"); - Console.WriteLine(); - - // Calculate maximum description length - int maxDescLen = 0; - foreach (TimedTest timedTest in TIMED_TESTS) - maxDescLen = Math.Max(maxDescLen, timedTest.Description.Length); + // Calculate maximum description length + int maxDescLen = 0; + foreach (TimedTest timedTest in _timedTests) + { + maxDescLen = Math.Max(maxDescLen, timedTest.Description.Length); + } - string formatString = "{0,-" + (maxDescLen + 1) + "} {1,9:G} ticks. Log: {2}"; - double delta; + string formatString = "{0,-" + (maxDescLen + 1) + "} {1,9:G} ticks. Log: {2}"; + double delta; - ArrayList averageData = []; + ArrayList averageData = []; - foreach (TimedTest timedTest in TIMED_TESTS) + foreach (TimedTest timedTest in _timedTests) + { + double total = 0; + foreach (ILog logger in _logArray) { - double total = 0; - foreach (ILog logger in LOG_ARRAY) - { - delta = timedTest.Run(logger, runLength); - Console.WriteLine(string.Format(formatString, timedTest.Description, delta, ((Logger)logger.Logger).Name)); - - total += delta; - } - Console.WriteLine(); + delta = timedTest.Run(logger, runLength); + Console.WriteLine(string.Format(formatString, timedTest.Description, delta, ((Logger)logger.Logger).Name)); - averageData.Add(new object[] { timedTest, total / ((double)LOG_ARRAY.Length) }); + total += delta; } Console.WriteLine(); - Console.WriteLine("Averages:"); - Console.WriteLine(); - foreach (object[] pair in averageData) - { - string avgFormatString = "{0,-" + (maxDescLen + 1) + "} {1,9:G} ticks."; - Console.WriteLine(string.Format(avgFormatString, ((TimedTest)pair[0]).Description, ((double)pair[1]))); - } + averageData.Add(new object[] { timedTest, total / ((double)_logArray.Length) }); } + Console.WriteLine(); + Console.WriteLine("Averages:"); + Console.WriteLine(); - internal abstract class TimedTest + foreach (object[] pair in averageData) { - public abstract double Run(ILog log, long runLength); - public abstract string Description { get; } + string avgFormatString = "{0,-" + (maxDescLen + 1) + "} {1,9:G} ticks."; + Console.WriteLine(string.Format(avgFormatString, ((TimedTest)pair[0]).Description, ((double)pair[1]))); } + } - #region Tests calling Debug(string) + internal abstract class TimedTest + { + public abstract double Run(ILog log, long runLength); + public abstract string Description { get; } + } - internal sealed class SimpleMessage_Bare : TimedTest + #region Tests calling Debug(string) + + internal sealed class SimpleMessage_Bare : TimedTest + { + public override double Run(ILog log, long runLength) { - public override double Run(ILog log, long runLength) + DateTime before = DateTime.Now; + for (int i = 0; i < runLength; i++) { - DateTime before = DateTime.Now; - for (int i = 0; i < runLength; i++) - { - log.Debug("msg"); - } - DateTime after = DateTime.Now; - TimeSpan diff = after - before; - return ((double)diff.Ticks) / ((double)runLength); + log.Debug("msg"); } - - public override string Description => "log.Debug(\"msg\");"; + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks) / ((double)runLength); } - internal sealed class ComplexMessage_MethodGuard_Bare : TimedTest + public override string Description => "log.Debug(\"msg\");"; + } + + internal sealed class ComplexMessage_MethodGuard_Bare : TimedTest + { + public override double Run(ILog log, long runLength) { - public override double Run(ILog log, long runLength) + DateTime before = DateTime.Now; + for (int i = 0; i < runLength; i++) { - DateTime before = DateTime.Now; - for (int i = 0; i < runLength; i++) + if (log.IsDebugEnabled) { - if (log.IsDebugEnabled) - { - log.Debug("msg" + i + "msg"); - } + log.Debug("msg" + i + "msg"); } - DateTime after = DateTime.Now; - TimeSpan diff = after - before; - return ((double)diff.Ticks) / ((double)runLength); } - - public override string Description => "if(log.IsDebugEnabled) log.Debug(\"msg\" + i + \"msg\");"; + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks) / ((double)runLength); } - internal sealed class ComplexMessage_Bare : TimedTest + public override string Description => "if(log.IsDebugEnabled) log.Debug(\"msg\" + i + \"msg\");"; + } + + internal sealed class ComplexMessage_Bare : TimedTest + { + public override double Run(ILog log, long runLength) { - public override double Run(ILog log, long runLength) + DateTime before = DateTime.Now; + for (int i = 0; i < runLength; i++) { - DateTime before = DateTime.Now; - for (int i = 0; i < runLength; i++) - { - log.Debug("msg" + i + "msg"); - } - DateTime after = DateTime.Now; - TimeSpan diff = after - before; - return ((double)diff.Ticks) / ((double)runLength); + log.Debug("msg" + i + "msg"); } - - public override string Description => "log.Debug(\"msg\" + i + \"msg\");"; + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks) / ((double)runLength); } - #endregion + public override string Description => "log.Debug(\"msg\" + i + \"msg\");"; + } - #region Tests calling Debug(new object[] { ... }) + #endregion - internal sealed class SimpleMessage_Array : TimedTest + #region Tests calling Debug(new object[] { ... }) + + internal sealed class SimpleMessage_Array : TimedTest + { + public override double Run(ILog log, long runLength) { - public override double Run(ILog log, long runLength) + DateTime before = DateTime.Now; + for (int i = 0; i < runLength; i++) { - DateTime before = DateTime.Now; - for (int i = 0; i < runLength; i++) - { - log.Debug(new object[] { "msg" }); - } - DateTime after = DateTime.Now; - TimeSpan diff = after - before; - return ((double)diff.Ticks) / ((double)runLength); + log.Debug(new object[] { "msg" }); } - - public override string Description => "log.Debug(new object[] { \"msg\" });"; + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks) / ((double)runLength); } - internal sealed class ComplexMessage_MethodGuard_Array : TimedTest + public override string Description => "log.Debug(new object[] { \"msg\" });"; + } + + internal sealed class ComplexMessage_MethodGuard_Array : TimedTest + { + public override double Run(ILog log, long runLength) { - public override double Run(ILog log, long runLength) + DateTime before = DateTime.Now; + for (int i = 0; i < runLength; i++) { - DateTime before = DateTime.Now; - for (int i = 0; i < runLength; i++) + if (log.IsDebugEnabled) { - if (log.IsDebugEnabled) - { - log.Debug(new object[] { "msg", i, "msg" }); - } + log.Debug(new object[] { "msg", i, "msg" }); } - DateTime after = DateTime.Now; - TimeSpan diff = after - before; - return ((double)diff.Ticks) / ((double)runLength); } - - public override string Description => "if(log.IsDebugEnabled) log.Debug(new object[] { \"msg\" , i , \"msg\" });"; + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks) / ((double)runLength); } - internal sealed class ComplexMessage_Array : TimedTest + public override string Description => "if(log.IsDebugEnabled) log.Debug(new object[] { \"msg\" , i , \"msg\" });"; + } + + internal sealed class ComplexMessage_Array : TimedTest + { + public override double Run(ILog log, long runLength) { - public override double Run(ILog log, long runLength) + DateTime before = DateTime.Now; + for (int i = 0; i < runLength; i++) { - DateTime before = DateTime.Now; - for (int i = 0; i < runLength; i++) - { - log.Debug(new object[] { "msg", i, "msg" }); - } - DateTime after = DateTime.Now; - TimeSpan diff = after - before; - return ((double)diff.Ticks) / ((double)runLength); + log.Debug(new object[] { "msg", i, "msg" }); } - - public override string Description => "log.Debug(new object[] { \"msg\" , i , \"msg\" });"; + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks) / ((double)runLength); } - #endregion - - #region Tests calling Debug(string) (using class members) + public override string Description => "log.Debug(new object[] { \"msg\" , i , \"msg\" });"; + } - internal sealed class ComplexMessage_MemberGuard_Bare : TimedTest - { - public override double Run(ILog log, long runLength) => new Impl(log).Run(runLength); + #endregion - public override string Description => "if (m_isEnabled) log.Debug(\"msg\" + i + \"msg\");"; + #region Tests calling Debug(string) (using class members) - private sealed class Impl - { - private readonly ILog log; - private readonly bool isEnabled; + internal sealed class ComplexMessage_MemberGuard_Bare : TimedTest + { + public override double Run(ILog log, long runLength) => new Impl(log).Run(runLength); - public Impl(ILog log) - { - this.log = log; - isEnabled = this.log.IsDebugEnabled; - } + public override string Description => "if (m_isEnabled) log.Debug(\"msg\" + i + \"msg\");"; - public double Run(long runLength) - { + private sealed class Impl + { + private readonly ILog _log; + private readonly bool _isEnabled; - DateTime before = DateTime.Now; - for (int i = 0; i < runLength; i++) - { - if (isEnabled) - { - log.Debug("msg" + i + "msg"); - } - } - DateTime after = DateTime.Now; - TimeSpan diff = after - before; - return ((double)diff.Ticks) / ((double)runLength); - } + public Impl(ILog log) + { + this._log = log; + _isEnabled = this._log.IsDebugEnabled; } - } - internal sealed class SimpleMessage_LocalGuard_Bare : TimedTest - { - public override double Run(ILog log, long runLength) + public double Run(long runLength) { - bool isEnabled = log.IsDebugEnabled; DateTime before = DateTime.Now; for (int i = 0; i < runLength; i++) { - if (isEnabled) log.Debug("msg"); + if (_isEnabled) + { + _log.Debug("msg" + i + "msg"); + } } DateTime after = DateTime.Now; TimeSpan diff = after - before; return ((double)diff.Ticks) / ((double)runLength); } - - public override string Description => "if (isEnabled) log.Debug(\"msg\");"; } + } - internal sealed class SimpleMessage_MethodGuard_Bare : TimedTest + internal sealed class SimpleMessage_LocalGuard_Bare : TimedTest + { + public override double Run(ILog log, long runLength) { - public override double Run(ILog log, long runLength) + bool isEnabled = log.IsDebugEnabled; + + DateTime before = DateTime.Now; + for (int i = 0; i < runLength; i++) { - DateTime before = DateTime.Now; - for (int i = 0; i < runLength; i++) + if (isEnabled) { - if (log.IsDebugEnabled) log.Debug("msg"); + log.Debug("msg"); } - DateTime after = DateTime.Now; - TimeSpan diff = after - before; - return ((double)diff.Ticks) / ((double)runLength); } - - public override string Description => "if (log.IsDebugEnabled) log.Debug(\"msg\");"; + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks) / ((double)runLength); } - internal sealed class ComplexMessage_LocalGuard_Bare : TimedTest + public override string Description => "if (isEnabled) log.Debug(\"msg\");"; + } + + internal sealed class SimpleMessage_MethodGuard_Bare : TimedTest + { + public override double Run(ILog log, long runLength) { - public override double Run(ILog log, long runLength) + DateTime before = DateTime.Now; + for (int i = 0; i < runLength; i++) { - bool isEnabled = log.IsDebugEnabled; - - DateTime before = DateTime.Now; - for (int i = 0; i < runLength; i++) + if (log.IsDebugEnabled) { - if (isEnabled) log.Debug("msg" + i + "msg"); + log.Debug("msg"); } - DateTime after = DateTime.Now; - TimeSpan diff = after - before; - return ((double)diff.Ticks) / ((double)runLength); } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks) / ((double)runLength); + } - public override string Description => "if (isEnabled) log.Debug(\"msg\" + i + \"msg\");"; + public override string Description => "if (log.IsDebugEnabled) log.Debug(\"msg\");"; + } + + internal sealed class ComplexMessage_LocalGuard_Bare : TimedTest + { + public override double Run(ILog log, long runLength) + { + bool isEnabled = log.IsDebugEnabled; + + DateTime before = DateTime.Now; + for (int i = 0; i < runLength; i++) + { + if (isEnabled) + { + log.Debug("msg" + i + "msg"); + } + } + DateTime after = DateTime.Now; + TimeSpan diff = after - before; + return ((double)diff.Ticks) / ((double)runLength); } - #endregion + + public override string Description => "if (isEnabled) log.Debug(\"msg\" + i + \"msg\");"; } + #endregion } \ No newline at end of file diff --git a/examples/Tutorials/ConsoleApp/LoggingExample.cs b/examples/Tutorials/ConsoleApp/LoggingExample.cs index 61e9c9d8..8a4b0f7a 100644 --- a/examples/Tutorials/ConsoleApp/LoggingExample.cs +++ b/examples/Tutorials/ConsoleApp/LoggingExample.cs @@ -23,80 +23,88 @@ // called ConsoleApp.exe.config in the application base // directory (i.e. the directory containing ConsoleApp.exe) -namespace ConsoleApp +namespace ConsoleApp; + +using System; + +/// +/// Example of how to simply configure and use log4net +/// +public static class LoggingExample { - using System; + // Create a logger for use in this class + private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof(LoggingExample)); /// - /// Example of how to simply configure and use log4net + /// Application entry point /// - public static class LoggingExample + [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")] + public static void Main() { - // Create a logger for use in this class - private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(LoggingExample)); - - /// - /// Application entry point - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")] - public static void Main() + // Log an info level message + if (_log.IsInfoEnabled) { - // Log an info level message - if (log.IsInfoEnabled) log.Info("Application [ConsoleApp] Start"); - - // Log a debug message. Test if debug is enabled before - // attempting to log the message. This is not required but - // can make running without logging faster. - if (log.IsDebugEnabled) log.Debug("This is a debug message"); + _log.Info("Application [ConsoleApp] Start"); + } - try - { - Bar(); - } - catch (InvalidOperationException ex) - { - // Log an error with an exception - log.Error("Exception thrown from method Bar", ex); - } + // Log a debug message. Test if debug is enabled before + // attempting to log the message. This is not required but + // can make running without logging faster. + if (_log.IsDebugEnabled) + { + _log.Debug("This is a debug message"); + } - log.Error("Hey this is an error!"); + try + { + Bar(); + } + catch (InvalidOperationException ex) + { + // Log an error with an exception + _log.Error("Exception thrown from method Bar", ex); + } - // Push a message on to the Nested Diagnostic Context stack - using (log4net.NDC.Push("NDC_Message")) - { - log.Warn("This should have an NDC message"); + _log.Error("Hey this is an error!"); - // Set a Mapped Diagnostic Context value - log4net.MDC.Set("auth", "auth-none"); - log.Warn("This should have an MDC message for the key 'auth'"); + // Push a message on to the Nested Diagnostic Context stack + using (log4net.NDC.Push("NDC_Message")) + { + _log.Warn("This should have an NDC message"); - } // The NDC message is popped off the stack at the end of the using {} block + // Set a Mapped Diagnostic Context value + log4net.MDC.Set("auth", "auth-none"); + _log.Warn("This should have an MDC message for the key 'auth'"); - log.Warn("See the NDC has been popped of! The MDC 'auth' key is still with us."); + } // The NDC message is popped off the stack at the end of the using {} block - // Log an info level message - if (log.IsInfoEnabled) log.Info("Application [ConsoleApp] End"); + _log.Warn("See the NDC has been popped of! The MDC 'auth' key is still with us."); - Console.Write("Press Enter to exit..."); - Console.ReadLine(); + // Log an info level message + if (_log.IsInfoEnabled) + { + _log.Info("Application [ConsoleApp] End"); } - // Helper methods to demonstrate location information and nested exceptions + Console.Write("Press Enter to exit..."); + Console.ReadLine(); + } + + // Helper methods to demonstrate location information and nested exceptions - private static void Bar() => Goo(); + private static void Bar() => Goo(); - private static void Foo() => throw new InvalidOperationException("This is an Exception"); + private static void Foo() => throw new InvalidOperationException("This is an Exception"); - private static void Goo() + private static void Goo() + { + try + { + Foo(); + } + catch (Exception ex) { - try - { - Foo(); - } - catch (Exception ex) - { - throw new ArithmeticException("Failed in Goo. Calling Foo. Inner Exception provided", ex); - } + throw new ArithmeticException("Failed in Goo. Calling Foo. Inner Exception provided", ex); } } } \ No newline at end of file