blob: 7ea86025ea550ac5147adf06cfeab88262e47f59 [file] [log] [blame]
#region Apache License
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion
using System;
using System.Globalization;
using log4net.Repository;
using log4net.Util;
namespace log4net.Core;
/// <summary>
/// Implementation of <see cref="ILog"/> wrapper interface.
/// </summary>
/// <remarks>
/// <para>
/// This implementation of the <see cref="ILog"/> interface
/// forwards to the <see cref="ILogger"/> held by the base class.
/// </para>
/// <para>
/// This logger has methods to allow the caller to log at the following
/// levels:
/// </para>
/// <list type="definition">
/// <item>
/// <term>DEBUG</term>
/// <description>
/// The <see cref="Debug(object)"/> and <see cref="DebugFormat(string, object[])"/> methods log messages
/// at the <c>DEBUG</c> level. That is the level with that name defined in the
/// repositories <see cref="ILoggerRepository.LevelMap"/>. The default value
/// for this level is <see cref="Level.Debug"/>. The <see cref="IsDebugEnabled"/>
/// property tests if this level is enabled for logging.
/// </description>
/// </item>
/// <item>
/// <term>INFO</term>
/// <description>
/// The <see cref="Info(object)"/> and <see cref="InfoFormat(string, object[])"/> methods log messages
/// at the <c>INFO</c> level. That is the level with that name defined in the
/// repositories <see cref="ILoggerRepository.LevelMap"/>. The default value
/// for this level is <see cref="Level.Info"/>. The <see cref="IsInfoEnabled"/>
/// property tests if this level is enabled for logging.
/// </description>
/// </item>
/// <item>
/// <term>WARN</term>
/// <description>
/// The <see cref="Warn(object)"/> and <see cref="WarnFormat(string, object[])"/> methods log messages
/// at the <c>WARN</c> level. That is the level with that name defined in the
/// repositories <see cref="ILoggerRepository.LevelMap"/>. The default value
/// for this level is <see cref="Level.Warn"/>. The <see cref="IsWarnEnabled"/>
/// property tests if this level is enabled for logging.
/// </description>
/// </item>
/// <item>
/// <term>ERROR</term>
/// <description>
/// The <see cref="Error(object)"/> and <see cref="ErrorFormat(string, object[])"/> methods log messages
/// at the <c>ERROR</c> level. That is the level with that name defined in the
/// repositories <see cref="ILoggerRepository.LevelMap"/>. The default value
/// for this level is <see cref="Level.Error"/>. The <see cref="IsErrorEnabled"/>
/// property tests if this level is enabled for logging.
/// </description>
/// </item>
/// <item>
/// <term>FATAL</term>
/// <description>
/// The <see cref="Fatal(object)"/> and <see cref="FatalFormat(string, object[])"/> methods log messages
/// at the <c>FATAL</c> level. That is the level with that name defined in the
/// repositories <see cref="ILoggerRepository.LevelMap"/>. The default value
/// for this level is <see cref="Level.Fatal"/>. The <see cref="IsFatalEnabled"/>
/// property tests if this level is enabled for logging.
/// </description>
/// </item>
/// </list>
/// <para>
/// The values for these levels and their semantic meanings can be changed by
/// configuring the <see cref="ILoggerRepository.LevelMap"/> for the repository.
/// </para>
/// </remarks>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix")]
public class LogImpl : LoggerWrapperImpl, ILog
{
/// <summary>
/// Construct a new wrapper for the specified logger.
/// </summary>
/// <param name="logger">The logger to wrap.</param>
/// <remarks>
/// <para>
/// Construct a new wrapper for the specified logger.
/// </para>
/// </remarks>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors")]
public LogImpl(ILogger logger)
: base(logger)
{
if (logger.EnsureNotNull().Repository is ILoggerRepository repository)
{
// Listen for changes to the repository
repository.ConfigurationChanged += LoggerRepositoryConfigurationChanged;
// load the current levels
ReloadLevels(repository);
}
}
/// <summary>
/// Virtual method called when the configuration of the repository changes
/// </summary>
/// <param name="repository">the repository holding the levels</param>
/// <remarks>
/// <para>
/// Virtual method called when the configuration of the repository changes
/// </para>
/// </remarks>
protected virtual void ReloadLevels(ILoggerRepository repository)
{
LevelMap levelMap = repository.EnsureNotNull().LevelMap;
_levelDebug = levelMap.LookupWithDefault(Level.Debug);
_levelInfo = levelMap.LookupWithDefault(Level.Info);
_levelWarn = levelMap.LookupWithDefault(Level.Warn);
_levelError = levelMap.LookupWithDefault(Level.Error);
_levelFatal = levelMap.LookupWithDefault(Level.Fatal);
}
/// <summary>
/// Logs a message object with the <c>DEBUG</c> level.
/// </summary>
/// <param name="message">The message object to log.</param>
/// <remarks>
/// <para>
/// This method first checks if this logger is <c>DEBUG</c>
/// enabled by comparing the level of this logger with the
/// <c>DEBUG</c> level. If this logger is
/// <c>DEBUG</c> enabled, then it converts the message object
/// (passed as parameter) to a string by invoking the appropriate
/// <see cref="ObjectRenderer.IObjectRenderer"/>. It then
/// proceeds to call all the registered appenders in this logger
/// and also higher in the hierarchy depending on the value of the
/// additivity flag.
/// </para>
/// <para>
/// <b>WARNING</b> Note that passing an <see cref="Exception"/>
/// to this method will print the name of the <see cref="Exception"/>
/// but no stack trace. To print a stack trace use the
/// <see cref="Debug(object,Exception)"/> form instead.
/// </para>
/// </remarks>
public virtual void Debug(object? message)
=> Logger.Log(_thisDeclaringType, _levelDebug, message, null);
/// <summary>
/// Logs a message object with the <c>DEBUG</c> level
/// </summary>
/// <param name="message">The message object to log.</param>
/// <param name="exception">The exception to log, including its stack trace.</param>
/// <remarks>
/// <para>
/// Logs a message object with the <c>DEBUG</c> level including
/// the stack trace of the <see cref="Exception"/> <paramref name="exception"/> passed
/// as a parameter.
/// </para>
/// <para>
/// See the <see cref="Debug(object)"/> form for more detailed information.
/// </para>
/// </remarks>
/// <seealso cref="Debug(object)"/>
public virtual void Debug(object? message, Exception? exception)
=> Logger.Log(_thisDeclaringType, _levelDebug, message, exception);
/// <summary>
/// Logs a formatted message string with the <c>DEBUG</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="args">An Object array containing zero or more objects to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="DebugFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Debug(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void DebugFormat(string format, params object?[]? args)
{
if (IsDebugEnabled)
{
Logger.Log(_thisDeclaringType, _levelDebug,
new SystemStringFormat(CultureInfo.InvariantCulture, format, args ?? _oneNullArgs), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>DEBUG</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="DebugFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Debug(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void DebugFormat(string format, object? arg0)
{
if (IsDebugEnabled)
{
Logger.Log(_thisDeclaringType, _levelDebug,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>DEBUG</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <param name="arg1">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="DebugFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Debug(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void DebugFormat(string format, object? arg0, object? arg1)
{
if (IsDebugEnabled)
{
Logger.Log(_thisDeclaringType, _levelDebug,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0, arg1]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>DEBUG</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <param name="arg1">An Object to format</param>
/// <param name="arg2">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="DebugFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Debug(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void DebugFormat(string format, object? arg0, object? arg1, object? arg2)
{
if (IsDebugEnabled)
{
Logger.Log(_thisDeclaringType, _levelDebug,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0, arg1, arg2]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>DEBUG</c> level.
/// </summary>
/// <param name="provider">An <see cref="IFormatProvider"/> that supplies culture-specific formatting information</param>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="args">An Object array containing zero or more objects to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Debug(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void DebugFormat(IFormatProvider? provider, string format, params object?[]? args)
{
if (IsDebugEnabled)
{
Logger.Log(_thisDeclaringType, _levelDebug,
new SystemStringFormat(provider, format, args ?? _oneNullArgs), null);
}
}
/// <summary>
/// Logs a message object with the <c>INFO</c> level.
/// </summary>
/// <param name="message">The message object to log.</param>
/// <remarks>
/// <para>
/// This method first checks if this logger is <c>INFO</c>
/// enabled by comparing the level of this logger with the
/// <c>INFO</c> level. If this logger is
/// <c>INFO</c> enabled, then it converts the message object
/// (passed as parameter) to a string by invoking the appropriate
/// <see cref="ObjectRenderer.IObjectRenderer"/>. It then
/// proceeds to call all the registered appenders in this logger
/// and also higher in the hierarchy depending on the value of
/// the additivity flag.
/// </para>
/// <para>
/// <b>WARNING</b> Note that passing an <see cref="Exception"/>
/// to this method will print the name of the <see cref="Exception"/>
/// but no stack trace. To print a stack trace use the
/// <see cref="Info(object,Exception)"/> form instead.
/// </para>
/// </remarks>
public virtual void Info(object? message)
=> Logger.Log(_thisDeclaringType, _levelInfo, message, null);
/// <summary>
/// Logs a message object with the <c>INFO</c> level.
/// </summary>
/// <param name="message">The message object to log.</param>
/// <param name="exception">The exception to log, including its stack trace.</param>
/// <remarks>
/// <para>
/// Logs a message object with the <c>INFO</c> level including
/// the stack trace of the <see cref="Exception"/> <paramref name="exception"/>
/// passed as a parameter.
/// </para>
/// <para>
/// See the <see cref="Info(object)"/> form for more detailed information.
/// </para>
/// </remarks>
/// <seealso cref="Info(object)"/>
public virtual void Info(object? message, Exception? exception)
=> Logger.Log(_thisDeclaringType, _levelInfo, message, exception);
/// <summary>
/// Logs a formatted message string with the <c>INFO</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="args">An Object array containing zero or more objects to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="InfoFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Info(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void InfoFormat(string format, params object?[]? args)
{
if (IsInfoEnabled)
{
Logger.Log(_thisDeclaringType, _levelInfo,
new SystemStringFormat(CultureInfo.InvariantCulture, format, args ?? _oneNullArgs), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>INFO</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="InfoFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Info(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void InfoFormat(string format, object? arg0)
{
if (IsInfoEnabled)
{
Logger.Log(_thisDeclaringType, _levelInfo,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>INFO</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <param name="arg1">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="InfoFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Info(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void InfoFormat(string format, object? arg0, object? arg1)
{
if (IsInfoEnabled)
{
Logger.Log(_thisDeclaringType, _levelInfo,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0, arg1]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>INFO</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <param name="arg1">An Object to format</param>
/// <param name="arg2">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="InfoFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Info(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void InfoFormat(string format, object? arg0, object? arg1, object? arg2)
{
if (IsInfoEnabled)
{
Logger.Log(_thisDeclaringType, _levelInfo,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0, arg1, arg2]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>INFO</c> level.
/// </summary>
/// <param name="provider">An <see cref="IFormatProvider"/> that supplies culture-specific formatting information</param>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="args">An Object array containing zero or more objects to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Info(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void InfoFormat(IFormatProvider? provider, string format, params object?[]? args)
{
if (IsInfoEnabled)
{
Logger.Log(_thisDeclaringType, _levelInfo,
new SystemStringFormat(provider, format, args ?? _oneNullArgs), null);
}
}
/// <summary>
/// Logs a message object with the <c>WARN</c> level.
/// </summary>
/// <param name="message">the message object to log</param>
/// <remarks>
/// <para>
/// This method first checks if this logger is <c>WARN</c>
/// enabled by comparing the level of this logger with the
/// <c>WARN</c> level. If this logger is
/// <c>WARN</c> enabled, then it converts the message object
/// (passed as parameter) to a string by invoking the appropriate
/// <see cref="ObjectRenderer.IObjectRenderer"/>. It then
/// proceeds to call all the registered appenders in this logger and
/// also higher in the hierarchy depending on the value of the
/// additivity flag.
/// </para>
/// <para>
/// <b>WARNING</b> Note that passing an <see cref="Exception"/> to this
/// method will print the name of the <see cref="Exception"/> but no
/// stack trace. To print a stack trace use the
/// <see cref="Warn(object,Exception)"/> form instead.
/// </para>
/// </remarks>
public virtual void Warn(object? message)
=> Logger.Log(_thisDeclaringType, _levelWarn, message, null);
/// <summary>
/// Logs a message object with the <c>WARN</c> level
/// </summary>
/// <param name="message">The message object to log.</param>
/// <param name="exception">The exception to log, including its stack trace.</param>
/// <remarks>
/// <para>
/// Logs a message object with the <c>WARN</c> level including
/// the stack trace of the <see cref="Exception"/> <paramref name="exception"/>
/// passed as a parameter.
/// </para>
/// <para>
/// See the <see cref="Warn(object)"/> form for more detailed information.
/// </para>
/// </remarks>
/// <seealso cref="Warn(object)"/>
public virtual void Warn(object? message, Exception? exception)
=> Logger.Log(_thisDeclaringType, _levelWarn, message, exception);
/// <summary>
/// Logs a formatted message string with the <c>WARN</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="args">An Object array containing zero or more objects to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="WarnFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Warn(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void WarnFormat(string format, params object?[]? args)
{
if (IsWarnEnabled)
{
Logger.Log(_thisDeclaringType, _levelWarn,
new SystemStringFormat(CultureInfo.InvariantCulture, format, args ?? _oneNullArgs), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>WARN</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="WarnFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Warn(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void WarnFormat(string format, object? arg0)
{
if (IsWarnEnabled)
{
Logger.Log(_thisDeclaringType, _levelWarn,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>WARN</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <param name="arg1">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="WarnFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Warn(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void WarnFormat(string format, object? arg0, object? arg1)
{
if (IsWarnEnabled)
{
Logger.Log(_thisDeclaringType, _levelWarn,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0, arg1]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>WARN</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <param name="arg1">An Object to format</param>
/// <param name="arg2">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="WarnFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Warn(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void WarnFormat(string format, object? arg0, object? arg1, object? arg2)
{
if (IsWarnEnabled)
{
Logger.Log(_thisDeclaringType, _levelWarn,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0, arg1, arg2]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>WARN</c> level.
/// </summary>
/// <param name="provider">An <see cref="IFormatProvider"/> that supplies culture-specific formatting information</param>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="args">An Object array containing zero or more objects to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Warn(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void WarnFormat(IFormatProvider? provider, string format, params object?[]? args)
{
if (IsWarnEnabled)
{
Logger.Log(_thisDeclaringType, _levelWarn,
new SystemStringFormat(provider, format, args ?? _oneNullArgs), null);
}
}
/// <summary>
/// Logs a message object with the <c>ERROR</c> level.
/// </summary>
/// <param name="message">The message object to log.</param>
/// <remarks>
/// <para>
/// This method first checks if this logger is <c>ERROR</c>
/// enabled by comparing the level of this logger with the
/// <c>ERROR</c> level. If this logger is
/// <c>ERROR</c> enabled, then it converts the message object
/// (passed as parameter) to a string by invoking the appropriate
/// <see cref="ObjectRenderer.IObjectRenderer"/>. It then
/// proceeds to call all the registered appenders in this logger and
/// also higher in the hierarchy depending on the value of the
/// additivity flag.
/// </para>
/// <para>
/// <b>WARNING</b> Note that passing an <see cref="Exception"/> to this
/// method will print the name of the <see cref="Exception"/> but no
/// stack trace. To print a stack trace use the
/// <see cref="Error(object,Exception)"/> form instead.
/// </para>
/// </remarks>
public virtual void Error(object? message)
=> Logger.Log(_thisDeclaringType, _levelError, message, null);
/// <summary>
/// Logs a message object with the <c>ERROR</c> level
/// </summary>
/// <param name="message">The message object to log.</param>
/// <param name="exception">The exception to log, including its stack trace.</param>
/// <remarks>
/// <para>
/// Logs a message object with the <c>ERROR</c> level including
/// the stack trace of the <see cref="Exception"/> <paramref name="exception"/>
/// passed as a parameter.
/// </para>
/// <para>
/// See the <see cref="Error(object)"/> form for more detailed information.
/// </para>
/// </remarks>
/// <seealso cref="Error(object)"/>
public virtual void Error(object? message, Exception? exception)
=> Logger.Log(_thisDeclaringType, _levelError, message, exception);
/// <summary>
/// Logs a formatted message string with the <c>ERROR</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="args">An Object array containing zero or more objects to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="ErrorFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Error(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void ErrorFormat(string format, params object?[]? args)
{
if (IsErrorEnabled)
{
Logger.Log(_thisDeclaringType, _levelError,
new SystemStringFormat(CultureInfo.InvariantCulture, format, args ?? _oneNullArgs), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>ERROR</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="ErrorFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Error(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void ErrorFormat(string format, object? arg0)
{
if (IsErrorEnabled)
{
Logger.Log(_thisDeclaringType, _levelError,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>ERROR</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <param name="arg1">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="ErrorFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Error(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void ErrorFormat(string format, object? arg0, object? arg1)
{
if (IsErrorEnabled)
{
Logger.Log(_thisDeclaringType, _levelError,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0, arg1]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>ERROR</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <param name="arg1">An Object to format</param>
/// <param name="arg2">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="ErrorFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Error(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void ErrorFormat(string format, object? arg0, object? arg1, object? arg2)
{
if (IsErrorEnabled)
{
Logger.Log(_thisDeclaringType, _levelError,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0, arg1, arg2]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>ERROR</c> level.
/// </summary>
/// <param name="provider">An <see cref="IFormatProvider"/> that supplies culture-specific formatting information</param>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="args">An Object array containing zero or more objects to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Error(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void ErrorFormat(IFormatProvider? provider, string format, params object?[]? args)
{
if (IsErrorEnabled)
{
Logger.Log(_thisDeclaringType, _levelError,
new SystemStringFormat(provider, format, args ?? _oneNullArgs), null);
}
}
/// <summary>
/// Logs a message object with the <c>FATAL</c> level.
/// </summary>
/// <param name="message">The message object to log.</param>
/// <remarks>
/// <para>
/// This method first checks if this logger is <c>FATAL</c>
/// enabled by comparing the level of this logger with the
/// <c>FATAL</c> level. If this logger is
/// <c>FATAL</c> enabled, then it converts the message object
/// (passed as parameter) to a string by invoking the appropriate
/// <see cref="ObjectRenderer.IObjectRenderer"/>. It then
/// proceeds to call all the registered appenders in this logger and
/// also higher in the hierarchy depending on the value of the
/// additivity flag.
/// </para>
/// <para>
/// <b>WARNING</b> Note that passing an <see cref="Exception"/> to this
/// method will print the name of the <see cref="Exception"/> but no
/// stack trace. To print a stack trace use the
/// <see cref="Fatal(object,Exception)"/> form instead.
/// </para>
/// </remarks>
public virtual void Fatal(object? message)
=> Logger.Log(_thisDeclaringType, _levelFatal, message, null);
/// <summary>
/// Logs a message object with the <c>FATAL</c> level
/// </summary>
/// <param name="message">The message object to log.</param>
/// <param name="exception">The exception to log, including its stack trace.</param>
/// <remarks>
/// <para>
/// Logs a message object with the <c>FATAL</c> level including
/// the stack trace of the <see cref="Exception"/> <paramref name="exception"/>
/// passed as a parameter.
/// </para>
/// <para>
/// See the <see cref="Fatal(object)"/> form for more detailed information.
/// </para>
/// </remarks>
/// <seealso cref="Fatal(object)"/>
public virtual void Fatal(object? message, Exception? exception)
=> Logger.Log(_thisDeclaringType, _levelFatal, message, exception);
/// <summary>
/// Logs a formatted message string with the <c>FATAL</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="args">An Object array containing zero or more objects to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="FatalFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Fatal(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void FatalFormat(string format, params object?[]? args)
{
if (IsFatalEnabled)
{
Logger.Log(_thisDeclaringType, _levelFatal,
new SystemStringFormat(CultureInfo.InvariantCulture, format, args ?? _oneNullArgs), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>FATAL</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="FatalFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Fatal(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void FatalFormat(string format, object? arg0)
{
if (IsFatalEnabled)
{
Logger.Log(_thisDeclaringType, _levelFatal,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>FATAL</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <param name="arg1">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="FatalFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Fatal(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void FatalFormat(string format, object? arg0, object? arg1)
{
if (IsFatalEnabled)
{
Logger.Log(_thisDeclaringType, _levelFatal,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0, arg1]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>FATAL</c> level.
/// </summary>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="arg0">An Object to format</param>
/// <param name="arg1">An Object to format</param>
/// <param name="arg2">An Object to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// The string is formatted using the <see cref="CultureInfo.InvariantCulture"/>
/// format provider. To specify a localized provider use the
/// <see cref="FatalFormat(IFormatProvider,string,object[])"/> method.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Fatal(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void FatalFormat(string format, object? arg0, object? arg1, object? arg2)
{
if (IsFatalEnabled)
{
Logger.Log(_thisDeclaringType, _levelFatal,
new SystemStringFormat(CultureInfo.InvariantCulture, format, [arg0, arg1, arg2]), null);
}
}
/// <summary>
/// Logs a formatted message string with the <c>FATAL</c> level.
/// </summary>
/// <param name="provider">An <see cref="IFormatProvider"/> that supplies culture-specific formatting information</param>
/// <param name="format">A String containing zero or more format items</param>
/// <param name="args">An Object array containing zero or more objects to format</param>
/// <remarks>
/// <para>
/// The message is formatted using the <see cref="String.Format(IFormatProvider, string, object[])"/> method. See
/// <c>String.Format</c> for details of the syntax of the format string and the behavior
/// of the formatting.
/// </para>
/// <para>
/// This method does not take an <see cref="Exception"/> object to include in the
/// log event. To pass an <see cref="Exception"/> use one of the <see cref="Fatal(object)"/>
/// methods instead.
/// </para>
/// </remarks>
public virtual void FatalFormat(IFormatProvider? provider, string format, params object?[]? args)
{
if (IsFatalEnabled)
{
Logger.Log(_thisDeclaringType, _levelFatal,
new SystemStringFormat(provider, format, args ?? _oneNullArgs), null);
}
}
/// <summary>
/// Checks if this logger is enabled for the <c>DEBUG</c>
/// level.
/// </summary>
/// <value>
/// <see langword="true"/> if this logger is enabled for <c>DEBUG</c> events,
/// <see langword="false"/> otherwise.
/// </value>
/// <remarks>
/// <para>
/// This function is intended to lessen the computational cost of
/// disabled log debug statements.
/// </para>
/// <para>
/// For some <c>log</c> Logger object, when you write:
/// </para>
/// <code lang="C#">
/// log.Debug("This is entry number: " + i );
/// </code>
/// <para>
/// You incur the cost constructing the message, concatenation in
/// this case, regardless of whether the message is logged or not.
/// </para>
/// <para>
/// If you are worried about speed, then you should write:
/// </para>
/// <code lang="C#">
/// if (log.IsDebugEnabled())
/// {
/// log.Debug("This is entry number: " + i );
/// }
/// </code>
/// <para>
/// This way you will not incur the cost of parameter
/// construction if debugging is disabled for <c>log</c>. On
/// the other hand, if the <c>log</c> is debug enabled, you
/// will incur the cost of evaluating whether the logger is debug
/// enabled twice. Once in <see cref="IsDebugEnabled"/> and once in
/// the <see cref="Debug(object?)"/>. This is an insignificant overhead
/// since evaluating a logger takes about 1% of the time it
/// takes to actually log.
/// </para>
/// </remarks>
public virtual bool IsDebugEnabled => Logger.IsEnabledFor(_levelDebug);
/// <summary>
/// Checks if this logger is enabled for the <c>INFO</c> level.
/// </summary>
/// <value>
/// <see langword="true"/> if this logger is enabled for <c>INFO</c> events,
/// <see langword="false"/> otherwise.
/// </value>
/// <remarks>
/// <para>
/// See <see cref="IsDebugEnabled"/> for more information and examples
/// of using this method.
/// </para>
/// </remarks>
/// <seealso cref="IsDebugEnabled"/>
public virtual bool IsInfoEnabled => Logger.IsEnabledFor(_levelInfo);
/// <summary>
/// Checks if this logger is enabled for the <c>WARN</c> level.
/// </summary>
/// <value>
/// <see langword="true"/> if this logger is enabled for <c>WARN</c> events,
/// <see langword="false"/> otherwise.
/// </value>
/// <remarks>
/// <para>
/// See <see cref="IsDebugEnabled"/> for more information and examples
/// of using this method.
/// </para>
/// </remarks>
/// <seealso cref="ILog.IsDebugEnabled"/>
public virtual bool IsWarnEnabled => Logger.IsEnabledFor(_levelWarn);
/// <summary>
/// Checks if this logger is enabled for the <c>ERROR</c> level.
/// </summary>
/// <value>
/// <see langword="true"/> if this logger is enabled for <c>ERROR</c> events,
/// <see langword="false"/> otherwise.
/// </value>
/// <remarks>
/// <para>
/// See <see cref="IsDebugEnabled"/> for more information and examples of using this method.
/// </para>
/// </remarks>
/// <seealso cref="ILog.IsDebugEnabled"/>
public virtual bool IsErrorEnabled => Logger.IsEnabledFor(_levelError);
/// <summary>
/// Checks if this logger is enabled for the <c>FATAL</c> level.
/// </summary>
/// <value>
/// <see langword="true"/> if this logger is enabled for <c>FATAL</c> events,
/// <see langword="false"/> otherwise.
/// </value>
/// <remarks>
/// <para>
/// See <see cref="IsDebugEnabled"/> for more information and examples of using this method.
/// </para>
/// </remarks>
/// <seealso cref="ILog.IsDebugEnabled"/>
public virtual bool IsFatalEnabled => Logger.IsEnabledFor(_levelFatal);
/// <summary>
/// Event handler for the <see cref="ILoggerRepository.ConfigurationChanged"/> event
/// </summary>
/// <param name="sender">the repository</param>
/// <param name="e">Empty</param>
private void LoggerRepositoryConfigurationChanged(object sender, EventArgs e)
{
if (sender is ILoggerRepository repository)
{
ReloadLevels(repository);
}
}
/// <summary>
/// The fully qualified name of this declaring type not the type of any subclass.
/// </summary>
private static readonly Type _thisDeclaringType = typeof(LogImpl);
/// <summary>
/// Used to ensure 'params object?[]?' arguments that receive a null are converted
/// to an array of one null value so that 'XxxFormat("{0}", null)' will work correctly.
/// Overloads like 'XxxFormat(message, object? arg0)' are not matched by the compiler in this case.
/// </summary>
private static readonly object?[] _oneNullArgs = [null];
private Level _levelDebug = Level.Debug;
private Level _levelInfo = Level.Info;
private Level _levelWarn = Level.Warn;
private Level _levelError = Level.Error;
private Level _levelFatal = Level.Fatal;
}