简体   繁体   中英

Configure Log4Net for the full project

I have the following code which Logs everything very nicely. Am I going to have to add this to the constructor of all of my classes?

Is there anyway to configure it for the full project? I suppose I could pass log around to all of the classes but that seams like a messy solution.

class Program
{
    /// <summary>
    /// Application start
    /// <param name="settings"></param>
    /// <returns></returns>
    static int Main(string[] args)
    {
    string logFile = string.Format(@"{0}\Cloud\Cloud.Log", Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
    log4net.GlobalContext.Properties["LogFileName"] = logFile;
    log4net.Config.XmlConfigurator.Configure();
    ILog log = log4net.LogManager.GetLogger(typeof(Program));
    log.Info("Console Applicatin Start");
    }
}

How should can I configure Log4Net for the full solution?

I didn't think it was relevant to the question but here is my my App.config:

<configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net>
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <file type="log4net.Util.PatternString" value="%property{LogFileName}.txt"  />
      <appendToFile value="true" />
      <rollingStyle value="Size" />
      <maxSizeRollBackups value="10" />
      <maximumFileSize value="250KB" />
      <staticLogFileName value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
      </layout>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="RollingFileAppender" />
    </root>
  </log4net>

I usually use a wrapper class. Something like:

public class Logger
{
    private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof(Logger));

    static Logger()
    {
        log4net.Config.XmlConfigurator.Configure();
    }

    public void Error(string format, params object[] args)
    {
        _log.Error(string.Format(format, args));
    }

    //...
}

And then just instantiate that where I need it. Like:

private Logger _log = new Logger();

And the use it like:

_log.Error("Something went wrong, Exception: {0}, More parameters: {1}",
    e.Message, "Another parameter");

The

log4net.Config.XmlConfigurator.Configure();

Should configure log4net according to your app.config.

Edit :

I thought I'd post my log4net config, in case you want to try one that has been confirmed working. It sets up a file logger and a console logger (useful to see logging i development environment):

<log4net>
  <root>
    <level value="ALL" />
    <appender-ref ref="ConsoleAppender" />
    <appender-ref ref="DebugFileLogger" />
  </root>
  <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger: %message%newline" />
    </layout>
  </appender>
  <appender name="DebugFileLogger" type="log4net.Appender.RollingFileAppender">
    <param name="File" value="Logs/DebugLog.log" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="20MB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="%d%t %m%n" />
    </layout>
  </appender>
</log4net>

The solution I see most often, is to create a LogManager class, and a property in each class to fetch an instance of a logger, so this is the only lines of code needed in each class to get a logger:

private ILog _log;

public ILog Log
{
    get { return _log ?? (_log = LogManager.GetLogger(LogName.WebServices)); }
}

The LogName.WebServices is an Enum value, and should be extended with more values, so you are able to filter your logs even more.

One of the great features of log4net is the ability to configure filtering and processing differently depending on the logger name: any solution that wraps the logger in a wrapper, singleton or static object loses that as all logs will use the same logger name - and the useful ability to immediately see what class a log entry came from.

All you need in a class where you want to log is a field, eg:

private static ILog Log =        
             LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

which sets the logger name to the name of the type it's contained in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM