#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.Reflection; using log4net.Core; using log4net.Repository; namespace log4net { /// /// This class is used by client applications to request logger instances. /// /// /// /// This class has static methods that are used by a client to request /// a logger instance. The method is /// used to retrieve a logger. /// /// /// See the interface for more details. /// /// /// Simple example of logging messages /// /// ILog log = LogManager.GetLogger("application-log"); /// /// log.Info("Application Start"); /// log.Debug("This is a debug message"); /// /// if (log.IsDebugEnabled) /// { /// log.Debug("This is another debug message"); /// } /// /// /// /// /// Nicko Cadell /// Gert Driesen public sealed class LogManager { #region Private Instance Constructors /// /// Initializes a new instance of the class. /// /// /// Uses a private access modifier to prevent instantiation of this class. /// private LogManager() { } #endregion Private Instance Constructors #region Type Specific Manager Methods #if !NETSTANDARD1_3 // Excluded because GetCallingAssembly() is not available in CoreFX (https://github.com/dotnet/corefx/issues/2221). /// Returns the named logger if it exists. /// /// Returns the named logger if it exists. /// /// /// /// If the named logger exists (in the default repository) then it /// returns a reference to the logger, otherwise it returns null. /// /// /// The fully qualified logger name to look for. /// The logger found, or null if no logger could be found. public static ILog Exists(string name) { return Exists(Assembly.GetCallingAssembly(), name); } /// Get the currently defined loggers. /// /// Returns all the currently defined loggers in the default repository. /// /// /// The root logger is not included in the returned array. /// /// All the defined loggers. public static ILog[] GetCurrentLoggers() { return GetCurrentLoggers(Assembly.GetCallingAssembly()); } /// Get or create a logger. /// /// Retrieves or creates a named logger. /// /// /// /// Retrieves 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 ILog GetLogger(string name) { return GetLogger(Assembly.GetCallingAssembly(), name); } #endif // !NETSTANDARD1_3 /// /// Returns the named logger if it exists. /// /// /// /// If the named logger exists (in the specified repository) then it /// returns a reference to the logger, otherwise it returns /// null. /// /// /// The repository to lookup in. /// The fully qualified logger name to look for. /// /// The logger found, or null if the logger doesn't exist in the specified /// repository. /// public static ILog Exists(string repository, string name) { return WrapLogger(LoggerManager.Exists(repository, name)); } /// /// Returns the named logger if it exists. /// /// /// /// If the named logger exists (in the repository for the specified assembly) then it /// returns a reference to the logger, otherwise it returns /// null. /// /// /// The assembly to use to lookup the repository. /// The fully qualified logger name to look for. /// /// The logger, or null if the logger doesn't exist in the specified /// assembly's repository. /// public static ILog Exists(Assembly repositoryAssembly, string name) { return WrapLogger(LoggerManager.Exists(repositoryAssembly, name)); } /// /// Returns all the currently defined loggers in the specified repository. /// /// The repository to lookup in. /// /// The root logger is not included in the returned array. /// /// All the defined loggers. public static ILog[] GetCurrentLoggers(string repository) { return WrapLoggers(LoggerManager.GetCurrentLoggers(repository)); } /// /// Returns all the currently defined loggers in the specified assembly's repository. /// /// The assembly to use to lookup the repository. /// /// The root logger is not included in the returned array. /// /// All the defined loggers. public static ILog[] GetCurrentLoggers(Assembly repositoryAssembly) { return WrapLoggers(LoggerManager.GetCurrentLoggers(repositoryAssembly)); } /// /// Retrieves or creates 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 repository to lookup in. /// The name of the logger to retrieve. /// The logger with the name specified. public static ILog GetLogger(string repository, string name) { return WrapLogger(LoggerManager.GetLogger(repository, name)); } /// /// Retrieves or creates 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 repository. /// The name of the logger to retrieve. /// The logger with the name specified. public static ILog GetLogger(Assembly repositoryAssembly, string name) { return WrapLogger(LoggerManager.GetLogger(repositoryAssembly, 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 ILog GetLogger(Type type) { #if NETSTANDARD1_3 return GetLogger(type.GetTypeInfo().Assembly, type.FullName); #else return GetLogger(Assembly.GetCallingAssembly(), type.FullName); #endif } /// /// Shorthand for . /// /// /// Gets the logger for the fully qualified name of the type specified. /// /// The repository 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 ILog GetLogger(string repository, Type type) { return WrapLogger(LoggerManager.GetLogger(repository, type)); } /// /// Shorthand for . /// /// /// Gets the logger for the fully qualified name of the type specified. /// /// The assembly to use to lookup the repository. /// The full name of will be used as the name of the logger to retrieve. /// The logger with the name specified. public static ILog GetLogger(Assembly repositoryAssembly, Type type) { return WrapLogger(LoggerManager.GetLogger(repositoryAssembly, type)); } #endregion Type Specific Manager Methods #region Domain & Repository Manager Methods /// /// Shuts down the log4net system. /// /// /// /// Calling this method will safely close and remove all /// appenders in all the loggers including root contained in all the /// default repositories. /// /// /// Some appenders need to be closed before the application exists. /// Otherwise, pending logging events might be lost. /// /// The shutdown method is careful to close nested /// appenders before closing regular appenders. This is allows /// configurations where a regular appender is attached to a logger /// and again to a nested appender. /// /// public static void Shutdown() { LoggerManager.Shutdown(); } #if !NETSTANDARD1_3 /// Shutdown a logger repository. /// /// Shuts down the default repository. /// /// /// /// Calling this method will safely close and remove all /// appenders in all the loggers including root contained in the /// default repository. /// /// Some appenders need to be closed before the application exists. /// Otherwise, pending logging events might be lost. /// /// The shutdown method is careful to close nested /// appenders before closing regular appenders. This is allows /// configurations where a regular appender is attached to a logger /// and again to a nested appender. /// /// public static void ShutdownRepository() { ShutdownRepository(Assembly.GetCallingAssembly()); } #endif /// /// Shuts down the repository for the repository specified. /// /// /// /// Calling this method will safely close and remove all /// appenders in all the loggers including root contained in the /// specified. /// /// /// Some appenders need to be closed before the application exists. /// Otherwise, pending logging events might be lost. /// /// The shutdown method is careful to close nested /// appenders before closing regular appenders. This is allows /// configurations where a regular appender is attached to a logger /// and again to a nested appender. /// /// /// The repository to shutdown. public static void ShutdownRepository(string repository) { LoggerManager.ShutdownRepository(repository); } /// /// Shuts down the repository specified. /// /// /// /// Calling this method will safely close and remove all /// appenders in all the loggers including root contained in the /// repository. The repository is looked up using /// the specified. /// /// /// Some appenders need to be closed before the application exists. /// Otherwise, pending logging events might be lost. /// /// /// The shutdown method is careful to close nested /// appenders before closing regular appenders. This is allows /// configurations where a regular appender is attached to a logger /// and again to a nested appender. /// /// /// The assembly to use to lookup the repository. public static void ShutdownRepository(Assembly repositoryAssembly) { LoggerManager.ShutdownRepository(repositoryAssembly); } #if !NETSTANDARD1_3 /// Reset the configuration of a repository /// /// Resets all values contained in this repository instance to their defaults. /// /// /// /// Resets all values contained in the repository instance to their /// defaults. This removes all appenders from all loggers, sets /// the level of all non-root loggers to null, /// sets their additivity flag to true and sets the level /// of the root logger to . Moreover, /// message disabling is set to its default "off" value. /// /// public static void ResetConfiguration() { ResetConfiguration(Assembly.GetCallingAssembly()); } #endif /// /// Resets all values contained in this repository instance to their defaults. /// /// /// /// Reset all values contained in the repository instance to their /// defaults. This removes all appenders from all loggers, sets /// the level of all non-root loggers to null, /// sets their additivity flag to true and sets the level /// of the root logger to . Moreover, /// message disabling is set to its default "off" value. /// /// /// The repository to reset. public static void ResetConfiguration(string repository) { LoggerManager.ResetConfiguration(repository); } /// /// Resets all values contained in this repository instance to their defaults. /// /// /// /// Reset all values contained in the repository instance to their /// defaults. This removes all appenders from all loggers, sets /// the level of all non-root loggers to null, /// sets their additivity flag to true and sets the level /// of the root logger to . Moreover, /// message disabling is set to its default "off" value. /// /// /// The assembly to use to lookup the repository to reset. public static void ResetConfiguration(Assembly repositoryAssembly) { LoggerManager.ResetConfiguration(repositoryAssembly); } #if !NETSTANDARD1_3 /// Get the logger repository. /// /// Returns the default instance. /// /// /// /// Gets the for the repository specified /// by the callers assembly (). /// /// /// The instance for the default repository. [Obsolete("Use GetRepository instead of GetLoggerRepository")] public static ILoggerRepository GetLoggerRepository() { return GetRepository(Assembly.GetCallingAssembly()); } #endif /// /// Returns the default instance. /// /// The default instance. /// /// /// Gets the for the repository specified /// by the argument. /// /// /// The repository to lookup in. [Obsolete("Use GetRepository instead of GetLoggerRepository")] public static ILoggerRepository GetLoggerRepository(string repository) { return GetRepository(repository); } /// /// Returns the default instance. /// /// The default instance. /// /// /// Gets the for the repository specified /// by the argument. /// /// /// The assembly to use to lookup the repository. [Obsolete("Use GetRepository instead of GetLoggerRepository")] public static ILoggerRepository GetLoggerRepository(Assembly repositoryAssembly) { return GetRepository(repositoryAssembly); } #if !NETSTANDARD1_3 /// Get a logger repository. /// /// Returns the default instance. /// /// /// /// Gets the for the repository specified /// by the callers assembly (). /// /// /// The instance for the default repository. public static ILoggerRepository GetRepository() { return GetRepository(Assembly.GetCallingAssembly()); } #endif /// /// Returns the default instance. /// /// The default instance. /// /// /// Gets the for the repository specified /// by the argument. /// /// /// The repository to lookup in. public static ILoggerRepository GetRepository(string repository) { return LoggerManager.GetRepository(repository); } /// /// Returns the default instance. /// /// The default instance. /// /// /// Gets the for the repository specified /// by the argument. /// /// /// The assembly to use to lookup the repository. public static ILoggerRepository GetRepository(Assembly repositoryAssembly) { return LoggerManager.GetRepository(repositoryAssembly); } #if !NETSTANDARD1_3 /// Create a domain /// /// Creates a repository with the specified repository type. /// /// /// /// CreateDomain is obsolete. Use CreateRepository instead of CreateDomain. /// /// /// The created will be associated with the repository /// specified such that a call to will return /// the same repository instance. /// /// /// A that implements /// and has a no arg constructor. An instance of this type will be created to act /// as the for the repository specified. /// The created for the repository. [Obsolete("Use CreateRepository instead of CreateDomain")] public static ILoggerRepository CreateDomain(Type repositoryType) { return CreateRepository(Assembly.GetCallingAssembly(), repositoryType); } /// Create a logger repository. /// /// Creates a repository with the specified repository type. /// /// A that implements /// and has a no arg constructor. An instance of this type will be created to act /// as the for the repository specified. /// The created for the repository. /// /// /// The created will be associated with the repository /// specified such that a call to will return /// the same repository instance. /// /// public static ILoggerRepository CreateRepository(Type repositoryType) { return CreateRepository(Assembly.GetCallingAssembly(), repositoryType); } #endif /// /// Creates a repository with the specified name. /// /// /// /// CreateDomain is obsolete. Use CreateRepository instead of CreateDomain. /// /// /// Creates the default type of which is a /// object. /// /// /// The name must be unique. Repositories cannot be redefined. /// An will be thrown if the repository already exists. /// /// /// The name of the repository, this must be unique amongst repositories. /// The created for the repository. /// The specified repository already exists. [Obsolete("Use CreateRepository instead of CreateDomain")] public static ILoggerRepository CreateDomain(string repository) { return LoggerManager.CreateRepository(repository); } /// /// Creates a repository with the specified name. /// /// /// /// Creates the default type of which is a /// object. /// /// /// The name must be unique. Repositories cannot be redefined. /// An will be thrown if the repository already exists. /// /// /// The name of the repository, this must be unique amongst repositories. /// The created for the repository. /// The specified repository already exists. public static ILoggerRepository CreateRepository(string repository) { return LoggerManager.CreateRepository(repository); } /// /// Creates a repository with the specified name and repository type. /// /// /// /// CreateDomain is obsolete. Use CreateRepository instead of CreateDomain. /// /// /// The name must be unique. Repositories cannot be redefined. /// An will be thrown if the repository already exists. /// /// /// The name of the repository, this must be unique to the repository. /// A that implements /// and has a no arg constructor. An instance of this type will be created to act /// as the for the repository specified. /// The created for the repository. /// The specified repository already exists. [Obsolete("Use CreateRepository instead of CreateDomain")] public static ILoggerRepository CreateDomain(string repository, Type repositoryType) { return LoggerManager.CreateRepository(repository, repositoryType); } /// /// Creates a repository with the specified name and repository type. /// /// /// /// The name must be unique. Repositories cannot be redefined. /// An will be thrown if the repository already exists. /// /// /// The name of the repository, this must be unique to the repository. /// A that implements /// and has a no arg constructor. An instance of this type will be created to act /// as the for the repository specified. /// The created for the repository. /// The specified repository already exists. public static ILoggerRepository CreateRepository(string repository, Type repositoryType) { return LoggerManager.CreateRepository(repository, repositoryType); } /// /// Creates a repository for the specified assembly and repository type. /// /// /// /// CreateDomain is obsolete. Use CreateRepository instead of CreateDomain. /// /// /// The created will be associated with the repository /// specified such that a call to with the /// same assembly specified will return the same repository instance. /// /// /// The assembly to use to get the name of the repository. /// A that implements /// and has a no arg constructor. An instance of this type will be created to act /// as the for the repository specified. /// The created for the repository. [Obsolete("Use CreateRepository instead of CreateDomain")] public static ILoggerRepository CreateDomain(Assembly repositoryAssembly, Type repositoryType) { return LoggerManager.CreateRepository(repositoryAssembly, repositoryType); } /// /// Creates a repository for the specified assembly and repository type. /// /// /// /// The created will be associated with the repository /// specified such that a call to with the /// same assembly specified will return the same repository instance. /// /// /// The assembly to use to get the name of the repository. /// A that implements /// and has a no arg constructor. An instance of this type will be created to act /// as the for the repository specified. /// The created for the repository. public static ILoggerRepository CreateRepository(Assembly repositoryAssembly, Type repositoryType) { return LoggerManager.CreateRepository(repositoryAssembly, repositoryType); } /// /// Gets the list of currently defined repositories. /// /// /// /// Get an array of all the objects that have been created. /// /// /// An array of all the known objects. public static ILoggerRepository[] GetAllRepositories() { return LoggerManager.GetAllRepositories(); } /// /// Flushes logging events buffered in all configured appenders in the default repository. /// /// The maximum time in milliseconds to wait for logging events from asycnhronous appenders to be flushed. /// True if all logging events were flushed successfully, else false. public static bool Flush(int millisecondsTimeout) { #if !NETSTANDARD1_3 // Excluded because GetCallingAssembly() is not available in CoreFX (https://github.com/dotnet/corefx/issues/2221). Appender.IFlushable flushableRepository = LoggerManager.GetRepository(Assembly.GetCallingAssembly()) as Appender.IFlushable; if (flushableRepository == null) { return false; } else { return flushableRepository.Flush(millisecondsTimeout); } #else return false; #endif } #endregion Domain & Repository Manager Methods #region Extension Handlers /// /// Looks up the wrapper object for the logger specified. /// /// The logger to get the wrapper for. /// The wrapper for the logger specified. private static ILog WrapLogger(ILogger logger) { return (ILog)s_wrapperMap.GetWrapper(logger); } /// /// Looks up the wrapper objects for the loggers specified. /// /// The loggers to get the wrappers for. /// The wrapper objects for the loggers specified. private static ILog[] WrapLoggers(ILogger[] loggers) { ILog[] results = new ILog[loggers.Length]; for(int i=0; i /// Create the objects used by /// this manager. /// /// The logger to wrap. /// The wrapper for the logger specified. private static ILoggerWrapper WrapperCreationHandler(ILogger logger) { return new LogImpl(logger); } #endregion #region Private Static Fields /// /// The wrapper map to use to hold the objects. /// private static readonly WrapperMap s_wrapperMap = new WrapperMap(new WrapperCreationHandler(WrapperCreationHandler)); #endregion Private Static Fields } }