1

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>
Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449

3 Answers3

2

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>
FishySwede
  • 1,563
  • 1
  • 17
  • 24
  • I am playing with this now. My app.config does work. I am using because I need it to store the logfile in %programdata% directory for my application. – Linda Lawton - DaImTo Mar 24 '15 at 09:42
  • That makes sense. Make sure you have permissions to write to that directory. This should be very helpful in these situations: http://stackoverflow.com/questions/756125/how-to-track-down-log4net-problems – FishySwede Mar 24 '15 at 09:45
  • what is , params object[] args for? – Linda Lawton - DaImTo Mar 24 '15 at 09:47
  • Ah, sorry, I didn't explain the call. I'll add it to the answer. It's basically to be able to use formatting like the String.Format(...) method – FishySwede Mar 24 '15 at 09:50
2

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.

stuartd
  • 70,509
  • 14
  • 132
  • 163
1

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.

Lars Kristensen
  • 1,410
  • 19
  • 29