代码之家  ›  专栏  ›  技术社区  ›  to StackOverflow

动态重新配置log4net

  •  15
  • to StackOverflow  · 技术社区  · 15 年前

    我正在寻找有关在我的ASP.NET应用程序中动态重新配置log4net日志级别的最佳方法的提示。我通常使用一个简单的配置,其中根记录器定义默认的日志级别,例如

    <log4net>
        <root>
        <level value="INFO" />
        <appender-ref ref="..." />
        <appender-ref ref="..." />
        ... etc ...     
        </root>
        ... etc
    

    可能有几个附加器,每个附加器都有过滤器来定义它们使用的日志记录级别。

    1. 我想做的第一件事是允许管理员连接到一个管理页面,该页面使他们能够(a)查看根日志程序的当前级别,(b)动态更改它。我不想使用“configureandwatch”并写入磁盘上的配置文件,因为我不希望这些更改在应用程序循环使用时持续存在。

    2. 接下来,我想更进一步,在管理页面上可以显示一个TreeView,其中包含应用程序中存在的所有当前记录器及其当前日志级别。并允许管理员在层次结构的任何级别上有选择地更改日志记录级别。

    其想法是创建一个通用的管理页面,我可以将其放入所有的应用程序中,这样管理员就可以有选择地启用调试级别的日志记录,以便进行故障排除。

    我发现log4netAPI有点令人困惑,是否有人可以指向示例或展示实现这一点的最佳方法。

    更新:

    两个答案都一样好,所以我接受了第一个答案——谢谢。要重新打印,我可以获取所有当前记录器,如下所示:

    foreach (log4net.ILog log in log4net.LogManager.GetCurrentLoggers())
    {
        log4net.Repository.Hierarchy.Logger logger = 
             (log4net.Repository.Hierarchy.Logger)log.Logger;
        Debug.WriteLine(
            String.Format("{0} Parent {1} Level {2} EffectiveLevel {3}<br>",
            logger.Name,
            logger.Parent.Name,
            logger.Level == null ? "<null>" : logger.Level.Name,
            logger.EffectiveLevel
            )
            );
    }
    
    • effectiveLevel是有效级别-如果后者不为空,则与级别相同,否则从父级继承。

    • 上面返回的记录器中至少有一个将根记录器作为父级,这使我能够获取对根记录器的引用。

    通过上面的内容,应该可以重建记录器层次结构。

    更新2

    再次感谢。我实现了一个ASP.NET服务器控件,该控件在带有复选框的TreeView中显示记录器层次结构,并允许用户动态更改层次结构中任何节点的日志级别。工作得很好,我会把它放在我所有的ASP.NET Web和Web服务应用程序的管理页面上!

    3 回复  |  直到 15 年前
        1
  •  8
  •   to StackOverflow    15 年前

    是否要查找类似以下内容(未测试的代码):

    foreach (ILog logger in log4net.LogManager.GetCurrentLoggers())
    {
      ((log4net.Repository.Hierarchy.Logger)logger).Level = 
          log4net.Core.Level.Error;
    }
    

    显然,您可以用相同的方式拉出记录器名称等。

        2
  •  4
  •   to StackOverflow    15 年前

    我已经成功地以编程方式更改了log4net记录器的日志级别,但是如何从公共API进行更改并不明显。给定此记录器:

    private readonly log4net.ILog mylogger;
    

    您必须做以下花哨的步法来设置它进行调试:

    ((log4net.Repository.Hierarchy.Logger)mylogger.Logger).Level =
     log4net.Core.Level.Debug;
    

    在某些情况下——我不知道是什么导致了这个更复杂的需求——您可能需要遵循本文中所示的额外步骤。 log4net and changing the logger levels .

        3
  •  2
  •   Yordan Georgiev    15 年前

    可能并不完全符合您的要求,但是:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using log4net;
    using log4net.Config;
    using NUnit.Framework;
    
    namespace ExampleConsoleApplication
    {
      enum DebugLevel : int
      { 
        Fatal_Msgs = 0 , 
        Fatal_Error_Msgs = 1 , 
        Fatal_Error_Warn_Msgs = 2 , 
        Fatal_Error_Warn_Info_Msgs = 3 ,
        Fatal_Error_Warn_Info_Debug_Msgs = 4 
      }
    
    
        class TestClass
        {
    
            private static readonly ILog logger =
                     LogManager.GetLogger ( typeof ( TestClass ) );
    
    
            static void Main ( string[] args )
            {
          TestClass objTestClass = new TestClass ();
    
                Console.WriteLine ( " START " );
    
          int shouldLog = 4; //CHANGE THIS FROM 0 TO 4 integer to check the functionality of the example
          //0 -- prints only FATAL messages 
          //1 -- prints FATAL and ERROR messages 
          //2 -- prints FATAL , ERROR and WARN messages 
          //3 -- prints FATAL  , ERROR , WARN and INFO messages 
          //4 -- prints FATAL  , ERROR , WARN , INFO and DEBUG messages 
    
          string srtLogLevel = String.Empty ; 
          switch (shouldLog)
          {
            case (int)DebugLevel.Fatal_Msgs :
              srtLogLevel = "FATAL";
              break;
            case (int)DebugLevel.Fatal_Error_Msgs:
              srtLogLevel = "ERROR";
              break;
            case (int)DebugLevel.Fatal_Error_Warn_Msgs :
              srtLogLevel = "WARN";
              break;
            case (int)DebugLevel.Fatal_Error_Warn_Info_Msgs :
              srtLogLevel = "INFO"; 
              break;
            case (int)DebugLevel.Fatal_Error_Warn_Info_Debug_Msgs :
              srtLogLevel = "DEBUG" ;
              break ;
            default:
              srtLogLevel = "FATAL";
              break;
          }
    
            objTestClass.SetLogingLevel ( srtLogLevel );
    
    
          objTestClass.LogSomething ();
    
    
                Console.WriteLine ( " END HIT A KEY TO EXIT " );
                Console.ReadLine ();
                } //eof method 
    
        /// <summary>
        /// Activates debug level 
        /// </summary>
        /// <sourceurl>http://geekswithblogs.net/rakker/archive/2007/08/22/114900.aspx</sourceurl>
        private void SetLogingLevel ( string strLogLevel )
        {
         string strChecker = "WARN_INFO_DEBUG_ERROR_FATAL" ;
    
          if (String.IsNullOrEmpty ( strLogLevel ) == true || strChecker.Contains ( strLogLevel ) == false)
            throw new Exception ( " The strLogLevel should be set to WARN , INFO , DEBUG ," );
    
    
    
          log4net.Repository.ILoggerRepository[] repositories = log4net.LogManager.GetAllRepositories ();
    
          //Configure all loggers to be at the debug level.
          foreach (log4net.Repository.ILoggerRepository repository in repositories)
          {
            repository.Threshold = repository.LevelMap[ strLogLevel ];
            log4net.Repository.Hierarchy.Hierarchy hier = (log4net.Repository.Hierarchy.Hierarchy)repository;
            log4net.Core.ILogger[] loggers = hier.GetCurrentLoggers ();
            foreach (log4net.Core.ILogger logger in loggers)
            {
              ( (log4net.Repository.Hierarchy.Logger)logger ).Level = hier.LevelMap[ strLogLevel ];
            }
          }
    
          //Configure the root logger.
          log4net.Repository.Hierarchy.Hierarchy h = (log4net.Repository.Hierarchy.Hierarchy)log4net.LogManager.GetRepository ();
          log4net.Repository.Hierarchy.Logger rootLogger = h.Root;
          rootLogger.Level = h.LevelMap[ strLogLevel ];
        }
    
        private void LogSomething ()
        {
          #region LoggerUsage
          DOMConfigurator.Configure (); //tis configures the logger 
          logger.Debug ( "Here is a debug log." );
          logger.Info ( "... and an Info log." );
          logger.Warn ( "... and a warning." );
          logger.Error ( "... and an error." );
          logger.Fatal ( "... and a fatal error." );
          #endregion LoggerUsage
    
        }
        } //eof class 
    
    } //eof namespace 
    
    
    
    
    
    
    #region TheAppConfig
    /*
     <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <configSections>
            <section name="log4net"
                     type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
        </configSections>
        <log4net>
            <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
                <param name="File" value="LogTest2.txt" />
                <param name="AppendToFile" value="true" />
                <layout type="log4net.Layout.PatternLayout">
                    <param name="Header" value="[Header] \r\n" />
                    <param name="Footer" value="[Footer] \r\n" />
                    <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
                </layout>
            </appender>
    
            <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
                <mapping>
                    <level value="ERROR" />
                    <foreColor value="White" />
                    <backColor value="Red, HighIntensity" />
                </mapping>
                <layout type="log4net.Layout.PatternLayout">
                    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
                </layout>
            </appender>
    
    
            <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
                <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.2.10.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
                <connectionString value="data source=ysg;initial catalog=DBGA_DEV;integrated security=true;persist security info=True;" />
                <commandText value="INSERT INTO [DBGA_DEV].[ga].[tb_Data_Log] ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" />
    
                <parameter>
                    <parameterName value="@log_date" />
                    <dbType value="DateTime" />
                    <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />
                </parameter>
                <parameter>
                    <parameterName value="@thread" />
                    <dbType value="String" />
                    <size value="255" />
                    <layout type="log4net.Layout.PatternLayout" value="%thread" />
                </parameter>
                <parameter>
                    <parameterName value="@log_level" />
                    <dbType value="String" />
                    <size value="50" />
                    <layout type="log4net.Layout.PatternLayout" value="%level" />
                </parameter>
                <parameter>
                    <parameterName value="@logger" />
                    <dbType value="String" />
                    <size value="255" />
                    <layout type="log4net.Layout.PatternLayout" value="%logger" />
                </parameter>
                <parameter>
                    <parameterName value="@message" />
                    <dbType value="String" />
                    <size value="4000" />
                    <layout type="log4net.Layout.PatternLayout" value="%messag2e" />
                </parameter>
            </appender>
            <root>
                <level value="INFO" />
                <appender-ref ref="LogFileAppender" />
                <appender-ref ref="AdoNetAppender" />
                <appender-ref ref="ColoredConsoleAppender" />
            </root>
        </log4net>
    </configuration>
     */
    #endregion TheAppconfig
    
    //this is the xml added replace here your log4net and Nunit paths
    //<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
            //  <SpecificVersion>False</SpecificVersion>
            //  <HintPath>..\..\..\Log4Net\log4net-1.2.10\bin\net\2.0\release\log4net.dll</HintPath>
            //</Reference>
            //<Reference Include="nunit.framework, Version=2.4.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />