2009-03-16 20 views
15

¿Hay alguna forma de establecer el nivel de registro en log4net mediante programación? Supuse que habría una propiedad que te permitiría hacer esto, pero parece que no puedo encontrar uno.¿Cambiar el nivel de registro mediante programación en log4net?

Lo que quiero hacer es tener una opción configurable para ingresar al modo de depuración. lo que causaría un registro extra.

Estoy usando un archivo xml de configuración de log4net por separado. Por el momento las soluciones que hemos llegado con son los siguientes:

  1. Editar el archivo de registro usando el DOM y luego llamar XMLConfigurator para configurar el archivo de registro de acuerdo con el archivo.

  2. Tiene dos archivos de configuración de registro, y en la opción que cambia la llamada xml Configurator para usar el archivo de configuración de registro apropiado.

Me estoy inclinando hacia 2, ¿hay alguna razón por la que esto no funcione?

Respuesta

7

Esta es la forma en que estoy configuración de log4net programación:

//declared as a class variable 
private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 

PatternLayout layout = new PatternLayout(@"%date %-5level %message%newline"); 
    RollingFileAppender appender = new RollingFileAppender(); 
    appender.Layout = layout; 
    appender.File = "c:\log.txt"; 
    appender.AppendToFile = true; 
    appender.MaximumFileSize = "1MB"; 
    appender.MaxSizeRollBackups = 0; //no backup files 
    appender.Threshold = Level.Error; 
    appender.ActivateOptions();      
    log4net.Config.BasicConfigurator.Configure(appender); 

creo que la propiedad Umbral del Appender de es lo que busca, controlará qué niveles de registro de la appender es la salida.

El log4net manual tiene muchos buenos ejemplos de configuración.

+0

No he probado que fuera, pero que se ve bastante limpio. –

24

Puede cambiar mediante programación el nivel de registro de un log log lognet, pero no es obvio cómo hacerlo. Tengo un código que hace esto. Dada esta Logger:

private readonly log4net.ILog mylogger; 

Tienes que hacer el siguiente juego de piernas para configurarlo para depurar:

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

Cambiar el nivel del registrador (o del registrador de raíz) es mucho mejor que cambiar el nivel de un appender específico. +1 Hago algo similar, pero resúmalo a RuntimeLoggingHelper.SetLoggerLevel (Tipo (o sobrecarga de nombre de cadena), Nivel). –

+0

@ ThomasG.Mayfield y Eddie, ¿puedes explicar por qué cambiar el registrador es mejor que el appender? Tengo un único registrador con 2 apéndices (Consola, Archivo). Quiero poder cambiar fácilmente lo que se escribe en la consola sin cambiar lo que está escrito en el archivo. Estaba buscando una solución para cambiar el umbral/nivel para el appender. ¿Debería usar 2 registradores? – Basic

+0

Puede agregar o quitar appenders en el futuro, pero su deseo de cambiar el nivel del registrador era afectar la salida de registro. Si solo cambiaba un apéndice especificado programáticamente, otros appenders incluirían el resultado que deseaba incluir/excluir. –

0

Esta es una continuación de sus comentarios sobre la respuesta de Mitch.

Si bien es posible que pueda establecer los niveles programáticamente, ¿por qué no simplemente establecer los niveles de registro para depurar? De esta forma, su usuario no tendrá que preocuparse por configurar los niveles de registro para depurar, lo que, confíe en mí, nunca estará activado cuando lo necesite.

Luego, cuando se produce un error, simplemente haga que el usuario le envíe el archivo de registro completo y use un visor de registro como Apache Chainsaw para ver selectivamente solo los niveles que desea ver.

Otra solución es registrar los diferentes niveles en archivos separados. De esta forma, puede hacer que el usuario le envíe solo los niveles que desea ver.

+1

Los usuarios tienen discos duros finitos. La política de la compañía es que la depuración registre todo (métodos de entrada y salida de eventos). También me dijeron que debía configurar el nivel de registro, así que debo cumplir, la resistencia por así decirlo es inútil. –

+1

Ah, veo de dónde vienes. Mandato divino de seres inferiores. –

0

Puede descargar el proyecto de muestra desde here o copiar y pegar el código de abajo. Al final del código es el DDL de SQL para la tabla que contiene la información de registro ..

using System; 
    using System.Collections.Generic; 
    using System.Text; 
    using log4net; 
    using log4net.Config; 
    using NUnit.Framework; 
    using GenApp.Utils; 

    namespace ExampleConsoleApplication 
    { 


    class TestClass 
    { 

     private static readonly ILog logger = 
       LogManager.GetLogger (typeof (TestClass)); 


     static void Main (string[] args) 
     { 
     TestClass objTestClass = new TestClass(); 
    //log4net.Appender.ColoredConsoleAppender.Colors.HighIntensity 
     GenApp.Bo.UserSettings us = new GenApp.Bo.UserSettings(); 
     GenApp.Bo.User userObj = new GenApp.Bo.User() 
     { 

      UserSettings = us 

     }; 
     userObj.UserSettings.LogLevel = 4; 




     #region SetDynamicallyLogLevel 


     Logger.Debug (userObj, logger, " -- Debug msg -- "); 
     Logger.Info (userObj, logger, " -- Info msg -- "); 
     Logger.Warn (userObj, logger, " -- Warn msg -- "); 
     Logger.Error (userObj, logger, " -- Error msg -- "); 
     Logger.Fatal (userObj, logger, " -- Fatal msg -- "); 
     #endregion SetDynamicallyLogLevel 



     #region RemoveDynamicallyAppenders 
     Logger.SetThreshold ("LogFileAppender", log4net.Core.Level.Off); 

     //and echo again 
     Logger.Debug (userObj, logger, " -- Debug msg -- "); 
     Logger.Info (userObj, logger, " -- Info msg -- "); 
     Logger.Warn (userObj, logger, " -- Warn msg -- "); 
     Logger.Error (userObj, logger, " -- Error msg -- "); 
     Logger.Fatal (userObj, logger, " -- Fatal msg -- "); 



     #endregion RemoveDynamicallyAppenders 

     Console.WriteLine (" END HIT A KEY TO EXIT "); 
      Console.ReadLine(); 
      } //eof method 


    } //eof class 

    } //eof namespace 




    /* App.config CopyPaste 
    <?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="Program.log" /> 
    <param name="AppendToFile" value="true" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <!--<param name="Header" value="======================================" /> 
     <param name="Footer" value="======================================" />--> 
     <param name="ConversionPattern" value="%date{yyyy'.'MM'.'dd --- HH':'mm':'ss'.'fff} [%t] %-5p -- %m%n" /> 
    </layout> 
    </appender> 

    <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender"> 
    <mapping> 
     <level value="ERROR" /> 
     <foreColor value="Red" /> 
    </mapping> 
    <mapping> 
     <level value="DEBUG" /> 
     <foreColor value="HighIntensity" /> 
    </mapping> 
    <mapping> 
     <level value="INFO" /> 
     <foreColor value="Green" /> 
    </mapping> 
    <mapping> 
     <level value="WARN" /> 
     <foreColor value="Yellow" /> 
    </mapping> 
    <mapping> 
     <level value="FATAL" /> 
     <foreColor value="White" /> 
     <backColor value="Red" /> 
    </mapping> 

    <layout type="log4net.Layout.PatternLayout"> 
     <!-- You could change here the date format --> 
     <conversionPattern value="%date{yyyy'.'MM'.'dd --- HH':'mm':'ss'.'fff} [%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="@domainName" /> 
     <dbType value="String" /> 
     <size value="255" /> 
     <layout type="log4net.Layout.PatternLayout" value="%user" /> 
    </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="%message" /> 
    </parameter> 
    </appender> 
    <root> 
    <level value="ALL" /> 
    <appender-ref ref="LogFileAppender" /> 
    <appender-ref ref="AdoNetAppender" /> 
    <appender-ref ref="ColoredConsoleAppender" /> 
    </root> 
</log4net> 
</configuration> 
    */ 
    #region TheReferencesInThecsprojFile 
    //<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" /> 
    #endregion TheReferencesInThecsprojFile 


namespace GenApp.Bo 
{ 
    public class User 
    { 

    public int LogLevel { get; set; } 
    public UserSettings UserSettings { get; set; } 


    } //eof class 

    public class UserSettings 
    { 
    public int LogLevel; 
    } 

} //eof namespace 

namespace GenApp.Utils 
{ 
    ///<version> 1.1 </version> 
    ///<author> Yordan Georgiev </author> 
    ///<summary> Wrapper around log4net with dynamically adjustable verbosity</summary> 
    public class Logger 
    { 

    private static Logger inst = new Logger(); 
    public static Logger Inst() 
    { 
     inst.ConfigureLogging(); 
     return inst; 
    } 


    public 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 
    } 

    public static void Debug (GenApp.Bo.User userObj, ILog logger, string msg) 
    { 
     DebugLevel debugLevel = (DebugLevel)userObj.UserSettings.LogLevel; 
     string strLogLevel = Logger.GetLogTypeString (debugLevel); 
     inst.SetLogingLevel (strLogLevel); 
     logger.Debug (msg); 

    } //eof method 


    public static void Info (GenApp.Bo.User userObj, ILog logger, string msg) 
    { 
     DebugLevel debugLevel = (DebugLevel)userObj.UserSettings.LogLevel; 
     string strLogLevel = Logger.GetLogTypeString (debugLevel); 
     inst.SetLogingLevel (strLogLevel); 
     logger.Info (msg); 

    } //eof method 


    public static void Warn (GenApp.Bo.User userObj, ILog logger, string msg) 
    { 
     DebugLevel debugLevel = (DebugLevel)userObj.UserSettings.LogLevel; 
     string strLogLevel = Logger.GetLogTypeString (debugLevel); 
     inst.SetLogingLevel (strLogLevel); 
     logger.Warn (msg); 

    } //eof method 


    public static void Error (GenApp.Bo.User userObj, ILog logger, string msg) 
    { 
     DebugLevel debugLevel = (DebugLevel)userObj.UserSettings.LogLevel; 
     string strLogLevel = Logger.GetLogTypeString (debugLevel); 
     inst.SetLogingLevel (strLogLevel); 
     logger.Error (msg); 
    } //eof method 


    public static void Fatal (GenApp.Bo.User userObj, ILog logger, string msg) 
    { 
     DebugLevel debugLevel = (DebugLevel)userObj.UserSettings.LogLevel; 
     string strLogLevel = Logger.GetLogTypeString (debugLevel); 
     inst.SetLogingLevel (strLogLevel); 
     logger.Fatal (msg); 
    } //eof method 


    /// <summary> 
    /// Activates debug level 
    /// </summary> 
    /// <sourceurl>http://geekswithblogs.net/rakker/archive/2007/08/22/114900.aspx</sourceurl> 
    private void SetLogingLevel (string strLogLevel) 
    { 

     this.ConfigureLogging(); 
     string strChecker = "WARN_INFO_DEBUG_ERROR_FATAL"; 

     if (String.IsNullOrEmpty (strLogLevel) == true || strChecker.Contains (strLogLevel) == false) 
     throw new ArgumentOutOfRangeException (" 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]; 
    } 

    ///<summary> 
    ///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 
    ///</summary> 
    private static string GetLogTypeString (DebugLevel debugLevel) 
    { 

     string srtLogLevel = String.Empty; 
     switch (debugLevel) 
     { 
     case DebugLevel.Fatal_Msgs: 
      srtLogLevel = "FATAL"; 
      break; 
     case DebugLevel.Fatal_Error_Msgs: 
      srtLogLevel = "ERROR"; 
      break; 
     case DebugLevel.Fatal_Error_Warn_Msgs: 
      srtLogLevel = "WARN"; 
      break; 
     case DebugLevel.Fatal_Error_Warn_Info_Msgs: 
      srtLogLevel = "INFO"; 
      break; 
     case DebugLevel.Fatal_Error_Warn_Info_Debug_Msgs: 
      srtLogLevel = "DEBUG"; 
      break; 
     default: 
      srtLogLevel = "FATAL"; 
      break; 
     } //eof switch 
     return srtLogLevel; 

    } //eof GetLogTypeString 


    /// <summary> 
    /// The path where the configuration is read from. 
    /// This value is set upon a call to ConfigureLogging(). 
    /// </summary> 
    private string configurationFilePath; 
    public void ConfigureLogging() 
    { 
     lock (this) 
     { 
     bool configured = false; 


     #region ConfigureByThePathOfTheEntryAssembly 
     // Tells the logging system the correct path. 
     Assembly a = Assembly.GetEntryAssembly(); 

     if (a != null && a.Location != null) 
     { 
      string path = a.Location + ".config"; 

      if (File.Exists (path)) 
      { 
      log4net.Config.DOMConfigurator.Configure (
       new FileInfo (path)); 
      configurationFilePath = path; 
      configured = true; 
      } 
      else 
      { 
      path = FindConfigInPath (Path.GetDirectoryName (a.Location)); 
      if (File.Exists (path)) 
      { 
       log4net.Config.DOMConfigurator.Configure (
       new FileInfo (path)); 
       configurationFilePath = path; 
       configured = true; 
      } 
      } 
     } 
     #endregion ConfigureByThePathOfTheEntryAssembly 


     #region ConfigureByWeb.config 
     //// Also, try web.config. 
     //if (!configured) 
     //{ 
     // if (HttpContext.Current != null && 
     // HttpContext.Current.Server != null && 
     // HttpContext.Current.Request != null) 
     // { 
     // string path = HttpContext.Current.Server.MapPath (
     //  HttpContext.Current.Request.ApplicationPath); 

     // path = path.TrimEnd ('\\') + "\\Web.config"; 

     // if (File.Exists (path)) 
     // { 
     //  log4net.Config.DOMConfigurator.Configure (
     //  new FileInfo (path)); 
     //  configurationFilePath = path; 
     //  configured = true; 
     // } 
     // } 
     //} 
     #endregion ConfigureByWeb.config 


     #region ConfigureByThePathOfTheExecutingAssembly 
     if (!configured) 
     { 
      // Tells the logging system the correct path. 
      a = Assembly.GetExecutingAssembly(); 

      if (a != null && a.Location != null) 
      { 
      string path = a.Location + ".config"; 

      if (File.Exists (path)) 
      { 
       log4net.Config.DOMConfigurator.Configure (
       new FileInfo (path)); 
       configurationFilePath = path; 
       configured = true; 
      } 
      else 
      { 
       path = FindConfigInPath (Path.GetDirectoryName (a.Location)); 
       if (File.Exists (path)) 
       { 
       log4net.Config.DOMConfigurator.Configure (
        new FileInfo (path)); 
       configurationFilePath = path; 
       configured = true; 
       } 
      } 
      } 
     } 
     #endregion ConfigureByThePathOfTheExecutingAssembly 


     #region ConfigureByThePathOfTheCallingAssembly 
     if (!configured) 
     { 
      // Tells the logging system the correct path. 
      a = Assembly.GetCallingAssembly(); 

      if (a != null && a.Location != null) 
      { 
      string path = a.Location + ".config"; 

      if (File.Exists (path)) 
      { 
       log4net.Config.DOMConfigurator.Configure (
       new FileInfo (path)); 
       configurationFilePath = path; 
       configured = true; 
      } 
      else 
      { 
       path = FindConfigInPath (Path.GetDirectoryName (a.Location)); 
       if (File.Exists (path)) 
       { 
       log4net.Config.DOMConfigurator.Configure (
        new FileInfo (path)); 
       configurationFilePath = path; 
       configured = true; 
       } 
      } 
      } 
     } 
     #endregion ConfigureByThePathOfTheCallingAssembly 


     #region ConfigureByThePathOfTheLibIsStored 
     if (!configured) 
     { 
      // Look in the path where this library is stored. 
      a = Assembly.GetAssembly (typeof (Logger)); 

      if (a != null && a.Location != null) 
      { 
      string path = FindConfigInPath (Path.GetDirectoryName (a.Location)); 
      if (File.Exists (path)) 
      { 
       log4net.Config.DOMConfigurator.Configure (
       new FileInfo (path)); 
       configurationFilePath = path; 
       configured = true; 
      } 
      } 
     } 
     #endregion ConfigureByThePathOfTheLibIsStored 



     } //eof lock 
    } //eof method 



    /// <summary> 
    /// Searches for a configuration file in the given path. 
    /// </summary> 
    private string FindConfigInPath (
     string path) 
    { 
     string[] files = Directory.GetFiles (path); 

     if (files != null && files.Length > 0) 
     { 
     foreach (string file in files) 
     { 
      if (Path.GetExtension (file).Trim ('.').ToLower (
      CultureInfo.CurrentCulture) == "config") 
      { 
      return file; 
      } 
     } 
     } 

     // Not found. 
     return string.Empty; 
    } //eof method 



    /// <summary> 
    /// Remove dynamically appenders 
    /// </summary> 
    /// <param name="appenderName"></param> 
    /// <param name="threshold"></param> 
    public static void SetThreshold (string appenderName, Level threshold) 
    { 
     foreach (AppenderSkeleton appender in LogManager.GetRepository().GetAppenders()) 
     { 
     if (appender.Name == appenderName) 
     { 
      appender.Threshold = threshold; 
      appender.ActivateOptions(); 

      break; 
     } 
     } 
    } //eof method 



    } //eof class 


} //eof namespace 

USE [DBGA_DEV] 
GO 

/****** Object: Table [ga].[tb_Data_Log] Script Date: 05/20/2009 12:16:01 ******/ 
SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

SET ANSI_PADDING ON 
GO 

CREATE TABLE [ga].[tb_Data_Log](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [Date] [datetime] NOT NULL, 
    [Thread] [varchar](255) NOT NULL, 
    [Level] [varchar](20) NOT NULL, 
    [Logger] [varchar](255) NOT NULL, 
    [Message] [varchar](4000) NOT NULL 
) ON [PRIMARY] 

GO 

SET ANSI_PADDING ON 
GO 
Cuestiones relacionadas