Reputation: 116868
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>
Upvotes: 1
Views: 5306
Reputation: 73243
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.
Upvotes: 2
Reputation: 1583
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>
Upvotes: 2
Reputation: 1495
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.
Upvotes: 1