I have a windows service with an app.config and a log4net.config.
app.config:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net configSource="log4net.config" />
log4net.config:
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="D:\Projects\Integration\Interface Module\bin\Logs\MyFirstLogger.log"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="2" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
I have added this in AssemblyInfo.cs too:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
And in one of my classes, I have:
private readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
and
_log.Info(content);
I have given all users full permissions to my Logs folder.
My bin folder (which the service is running from) has both my app.config and log4net.config.
But no logging file got generated. What settings did I miss?
Updated on 4-March-2014
If you are using a separate config file like I did (log4net.config), do remember to set the Copy to output directory setting to Copy always in the Solution Explorer
Please note that when the process is run as Windows Service, Environment.CurrentDirectory will be "C:\Windows\system32"
So if you put the log4net configuration file (log4net.config) next to your *.exe, you can use the following code to configure log4net.
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
XmlConfigurator.Configure(new FileInfo(Path.Combine(assemblyFolder, "log4net.config")));
By Design Log4Net is
fail-stop, we mean that log4net will not throw unexpected exceptions
at run-time potentially causing your application to crash
So it is very difficult to figure out what is causing the issue .
How do I enable log4net internal debugging?
FROM FAQ - http://logging.apache.org/log4net/release/faq.html
Internal debugging can also be enabled by setting a value in the
application's configuration file (not the log4net configuration file,
unless the log4net config data is embedded in the application's
config file). The log4net.Internal.Debug application setting must be
set to the value true. For example:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
</configuration>
This setting is read immediately on startup an will cause all internal debugging messages to be emitted.
. To enable log4net's internal debug programmatically you need to set
the log4net.Util.LogLog.InternalDebugging property to true.
Obviously the sooner this is set the more debug will be produced.
So here is a custom class i created for log4Net - because config file
was very confusing I created this helper class
you can initiate as many appender you need across the applications
so if one dll call other dll both can initiate appenders and both
appends will work.
also you can close the appender and ( as in case of file appender)
then send it as a email
Log4NetFileHelper log = new Log4NetFileHelper();
log.Init(); //Initialize
log.AddConsoleLogging(); //Add Console Logging
log.AddFileLogging(Path.Combine(AssemblyDirectory, "BatchConsole.log"));
log.AddFileLogging(Path.Combine(AssemblyDirectory,"BatchConsole_error.log"),log4net.Core.Level.Error);
Do set this Property to True log4net.Util.LogLog.InternalDebugging=true;
public class Log4NetFileHelper
{
private string DEFAULT_LOG_FILENAME=string.Format("application_log_{0}.log",DateTime.Now.ToString("yyyyMMMdd_hhmm"));
Logger root;
public Log4NetFileHelper()
{
}
public virtual void Init()
{
root = ((Hierarchy)LogManager.GetRepository()).Root;
//root.AddAppender(GetConsoleAppender());
//root.AddAppender(GetFileAppender(sFileName));
root.Repository.Configured = true;
}
#region Public Helper Methods
#region Console Logging
public virtual void AddConsoleLogging()
{
ConsoleAppender C = GetConsoleAppender();
AddConsoleLogging(C);
}
public virtual void AddConsoleLogging(ConsoleAppender C)
{
root.AddAppender(C);
}
#endregion
#region File Logging
public virtual FileAppender AddFileLogging()
{
return AddFileLogging(DEFAULT_LOG_FILENAME);
}
public virtual FileAppender AddFileLogging(string sFileFullPath)
{
return AddFileLogging(sFileFullPath, log4net.Core.Level.All);
}
public virtual FileAppender AddFileLogging(string sFileFullPath, log4net.Core.Level threshold)
{
return AddFileLogging(sFileFullPath, threshold,true);
}
public virtual FileAppender AddFileLogging(string sFileFullPath, log4net.Core.Level threshold, bool bAppendfile)
{
FileAppender appender = GetFileAppender(sFileFullPath, threshold , bAppendfile);
root.AddAppender(appender);
return appender;
}
public virtual SmtpAppender AddSMTPLogging(string smtpHost, string From, string To, string CC, string subject, log4net.Core.Level threshhold)
{
SmtpAppender appender = GetSMTPAppender(smtpHost, From, To, CC, subject, threshhold);
root.AddAppender(appender);
return appender;
}
#endregion
public log4net.Appender.IAppender GetLogAppender(string AppenderName)
{
AppenderCollection ac = ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root.Appenders;
foreach(log4net.Appender.IAppender appender in ac){
if (appender.Name == AppenderName)
{
return appender;
}
}
return null;
}
public void CloseAppender(string AppenderName)
{
log4net.Appender.IAppender appender = GetLogAppender(AppenderName);
CloseAppender(appender);
}
private void CloseAppender(log4net.Appender.IAppender appender)
{
appender.Close();
}
#endregion
#region Private Methods
private SmtpAppender GetSMTPAppender(string smtpHost, string From, string To, string CC, string subject, log4net.Core.Level threshhold)
{
SmtpAppender lAppender = new SmtpAppender();
lAppender.Cc = CC;
lAppender.To = To;
lAppender.From = From;
lAppender.SmtpHost = smtpHost;
lAppender.Subject = subject;
lAppender.BufferSize = 512;
lAppender.Lossy = false;
lAppender.Layout = new
log4net.Layout.PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %message (%logger{1}:%line)%n");
lAppender.Threshold = threshhold;
lAppender.ActivateOptions();
return lAppender;
}
private ConsoleAppender GetConsoleAppender()
{
ConsoleAppender lAppender = new ConsoleAppender();
lAppender.Name = "Console";
lAppender.Layout = new
log4net.Layout.PatternLayout(" %message %n");
lAppender.Threshold = log4net.Core.Level.All;
lAppender.ActivateOptions();
return lAppender;
}
/// <summary>
/// DETAILED Logging
/// log4net.Layout.PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %message (%logger{1}:%line)%n");
///
/// </summary>
/// <param name="sFileName"></param>
/// <param name="threshhold"></param>
/// <returns></returns>
private FileAppender GetFileAppender(string sFileName , log4net.Core.Level threshhold ,bool bFileAppend)
{
FileAppender lAppender = new FileAppender();
lAppender.Name = sFileName;
lAppender.AppendToFile = bFileAppend;
lAppender.File = sFileName;
lAppender.Layout = new
log4net.Layout.PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %message (%logger{1}:%line)%n");
lAppender.Threshold = threshhold;
lAppender.ActivateOptions();
return lAppender;
}
//private FileAppender GetFileAppender(string sFileName)
//{
// return GetFileAppender(sFileName, log4net.Core.Level.All,true);
//}
#endregion
private void ConfigureLog(string sFileName)
{
}
}
Here is the config that works for me.
AssemblyInfo.cs
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4net.config", Watch = true)]
Log4net.Config
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
<param name="File" value="C:\TEMP\Logs.txt"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock,log4net" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="2" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
C# Code
private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(typeof(class_name));
I have this setup in C# Class library project and all other project uses this project reference to log the exceptions.
After checking and recheck... :-)
All you need is to call XmlConfigurator.Configure(); before you create the logger (only once).
Glad to help you,
Ofir
If you will make a different configuration file and put log4net related things in it, then you will need to use
[assembly: log4net.Config.XmlConfigurator(ConfigFile = #"...\log4net.config", Watch = true)]
inside AssemblyInfo.cs instead of just
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
Otherwise, you have to put
<log4net>
...
</log4net> part of the configuration inside your App.config
Sorry if some of these seem obvious, but these are what I would check:
Make sure you have your log4net.config file properties Copy to Output set to Copy Always, verify by checking for the file in your bin directory
Also note from the log4net docs related to AssemblyInfo.cs properties:
Using attributes can be a clearer method for defining where the application's configuration will be loaded from. However it is worth
noting that attributes are purely passive. They are information only.
Therefore if you use configuration attributes you must invoke log4net
to allow it to read the attributes. A simple call to
LogManager.GetLogger will cause the attributes on the calling assembly
to be read and processed. Therefore it is imperative to make a
logging call as early as possible during the application start-up, and
certainly before any external assemblies have been loaded and
invoked.
To troubleshoot you might try switching from the assembly level property to an explicit configuration call
XmlConfigurator.Configure();
should be sufficient.
I always make log4net.config a full config file, starting with
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
...
</log4net>
</configuration>
You should not need anything in app.config related to log4net as long as your config file is log4net.config
When you say 'All Users' have full permissions to the log directory, does this include the service accounts?
Check that LocalService, NetworkService, LocalSystem etc have permissions (depending on what context the service is running).
Also, assuming you have a harness to run the service as an application, does logging work when running as your user?
If it doesn't run okay as an application, you've got a problem with the log4net config (which other answers have tried to address).
log4net runs under the privileges of the active user. Make sure that the active user has rights to create/modify/delete the specified text file.
Could you please upload you application so that i could debug it myself?
a few i recommend to check:
replace all the "\" in your file path to "\"
put all the log4net config embedded in the application's config file.
enable log4net debugging
(see here)
try a different configuration. just get a sample config for somewhere on the internet.
just to be sure, i'd give maximum permissions for all users to your logging directory
try to uninstall the service and reinstall it.
In continuation of comment from Yanting Chen in above thread -
With below code, you can find what all config messages are logged by log4net when running the app under Windows Scheduler. It may help someone to get insight of log4net especially when running under services or scheduler where you can't see the command screen.
private static void InstanceLogger()
{
if (logger == null)
logger = LogManager.GetLogger(typeof(Utility));
// Code to troubleshoot Log4Net issues through Event log viewer
StringBuilder sb = new StringBuilder();
foreach (log4net.Util.LogLog m in logger.Logger.Repository.ConfigurationMessages)
{
sb.AppendLine(m.Message);
}
throw new Exception("String messages: " + sb.ToString());
}
if you have a separate file for log4net.config. Have you set following property:
Copy to the output directory = Copy always
I saw your code has a minor issue in AssemblyInfo.cs.
replace your code by :
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "{{folder_path}}\log4net.config")]
where {{folder_path}} is the path of your log4net.config
Windows Service with system login does not have access to all the directories present.
So try logging in the "C:\Users\Public\AppData".
This worked for me
Running Dbgview.exe from Microsoft SysinternalsSuite as admin --> Capture Global Win32 --> start your service, showed me that my log4net.config was simply not in the same directory as the windows service executable. Left click log4net.config in VS and in Properties --> Advanced --> set Copy to Output Directory: Copy if newer. That way Build will include the file in bin as it necessary to run the service.
See How do I enable log4net internal debugging? from log4net's
FAQ.
I followed this tutorial to add logging to my service.
Related
I currently use a class library to store a class that handles logging using log4net. This class is used in other projects.
I've read a lot of other questions and answers, but I haven't been able to fix it yet...
I enabled internal debugging of log4net because it would not write to a file, and this is the error I get:
log4net:ERROR Failed to find configuration section 'log4net' in the application's .config file. Check your .config file for the <log4net> and <configSections> elements. The configuration section should look like: <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
These are my files:
log4net.config
<log4net debug="true">
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<param name="File" value="Logs/log4net.log" />
<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>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
<parameter>
<parameterName value="#BlogId" />
<dbType value="Int32" />
<layout type="log4net.Layout.RawPropertyLayout">
<key value="BlogId" />
</layout>
</parameter>
</configuration>
AssemblyInfo.cs (just last line)
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
Logger.cs
public class Logger : ILogger
{
private static ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public Logger()
{
XmlConfigurator.Configure();
logger.Info("NEW LOGGER INSTANCE CREATED");
}
}
UPDATE
I fixed it by letting the class that uses my Logger.cs give its own .config file for log4net. Now log4net reads the given .config files and it works.
You have defined that the log4net section is in your app.config with:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
that means you should add the content of the log4net.config to the app.config file.
If you're trying to implement a wrapper over log4net where the log4net lives in its own class library and not in the main executable of your application, try something like this in a static constructor of your wrapper class:
static Logger()
{
log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo
(System.IO.Path.GetDirectoryName
(System.Reflection.Assembly.GetExecutingAssembly().Location)));
}
The static constructor solution ensures that if you load the class library, the configuration code will run.
You will also need to do something to copy the log4net.config file from that class library project into the same folder as the executable. You can do this by hand when deploying the application; however, to do it automatically when debugging a post-build step with something like this (from the class library project) will put the config file into the right folder:
XCOPY "$(TargetDir)*.config" ".\..\..\..\..\bin\Debug" /S /Y /I
XCOPY "$(TargetDir)*.config" ".\..\..\..\..\bin\Release" /S /Y /I
// Where those paths point to the main executable /bin folders
// and build configuration target dirs
A good reason to use this approach is that if you're leveraging something like MEF, you can bring in your logger wrapper class as an interface and you don't need to reference log4net in more than one project in your solution. You can interface with the logger with an abstract interface of your own choosing, and use log4net as the Impl. (Bridge pattern)
Good luck!
I am creating logs in C# by using object of ILog in log4net. I am passing two parameters 1) repository where it will create log file 2)name of log file but it is showing exception that directory is not defined and if I do it by just passing name of log file ,program runs successfully but I am unable to find the log file.
Here is my code :-
private void createLogger(string Logdirectory)
{
if (Directory.Exists(Logdirectory))
{
Log = LogManager.GetLogger( Logdirectory , LogFilename);
}
else
{
Log = LogManager.GetLogger(LogFilename);
}
}
Here is console output :-
Help me find suitable way of getting logger by Ilog or by any other method except filestream
Read the documentation, log4net is very configurable and well documented.
Documentation: https://logging.apache.org/log4net/release/manual/configuration.html
using Com.Foo; // Import log4net classes.
using log4net;
using log4net.Config;
public class MyApp
{ // Define a static logger variable so that it references the // Logger instance named "MyApp".
private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
static void Main(string[] args)
{ // Set up a simple configuration that logs on the console.
BasicConfigurator.Configure();
log.Info("Entering application.");
Bar bar = new Bar();
bar.DoIt();
log.Info("Exiting application.");
}
}
Take note the difference in the method for getting to log instance.
You're asking for an ILog for the current Type not an explicitly a filename
You're telling log4net to read configuration settings from the app.config/web.config
Depending on your config you may need to use the XmlConfigurator
An example of the .config file is:
<log4net> <!-- A1 is set to be a ConsoleAppender -->
<appender name="A1" type="log4net.Appender.ConsoleAppender"> <!-- A1 uses PatternLayout -->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-4timestamp [%thread] %-5level %logger %ndc - %message%newline" />
</layout>
</appender>
<!-- Set root logger level to DEBUG and its only appender to A1 -->
<root>
<level value="DEBUG" />
<appender-ref ref="A1" />
</root>
</log4net>
There are lots of Appenders, above is a ConsoleAppender, but a DatabaseAppender exists and other types that might fit with you're need.
I have a console application and have a class library which wraps the Log4Net methods. Now when run the application in debug mode it writes log but when it is built in release mode it doesn’t write log file. What would be the solution for this? The sample code and config file is given below
My development environment is
Visual Studio 2013 and .NET Framework 4.5
Console Application
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
log4net.GlobalContext.Properties["LogFileName"] = "TestLogin.txt";
Logger log = new Logger(typeof(Program));
log.Info("Logging is enabled!!");
}
}
}
App.config in Console Application
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value ="%property{LogFileName}"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level - %message%newline%exception" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
</configuration>
Class Library
using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace Logging
{
public class Logger
{
private readonly ILog log = null;
public Logger(Type type)
{
log = LogManager.GetLogger(type);
}
public void Info(object message)
{
log.Info(message);
}
}
}
I have followed the post and it didn’t help me to figure out why Log4Net doesn’t write in log file in release mode?
log4net doesn't log when running a .Net 4.0 Windows application built in Release mode
There are a few workarounds for this.
You could add the [MethodImpl(MethodImplOptions.NoInlining)]
attribute to your Logger constructor methods in your class library.
You could add [assembly: log4net.Config.XmlConfigurator(Watch =
true)] to AssemblyInfo.cs in your Console Project (not the class library project)
You can add log4net.Config.XmlConfigurator.Configure(); at the
start of your Logger constructor.
I think the reason this is happening is that in release mode, your class library is inlined and so when log4net attempts to find the attribute, it thinks the calling assembly is your exe which does not contain the attribute.
PS.
I presume you are aware that your Logger class will mean that you lose the ability to filter by method names, as log4net will only see the Logger.Info method name.
The line [assembly: log4net.Config.XmlConfigurator(Watch = true)] should be added to your AssemblyInfo.cs file in the Properties folder.
For users with an MVC app that already have the lines [assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)] in AssemblyInfo.cs and log4net.Config.XmlConfigurator.Configure(); in Global.asax.cs, but it's still not writing, make sure that the Application Pool user has permissions to write to the location where you're writing the log.
To get around this, I simply created a log directory on the IIS server NOT inside inetpub, gave it adequate permissions (I suppose it can be "Everyone", "Full Control" if it's just a child log directory and you're feeling lazy), and wrote the full path in the log4net.config (or Web.config, if you didn't isolate it).
Here's my config file:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<root>
<level value="ALL"/>
<appender-ref ref="RollingFileAppender"/>
</root>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:/absolute/path/to/logfile.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maximumFileSize value="10MB"/>
<datePattern value="yyyyMMdd'-FULL.log'" />
<maxSizeRollBackups value="-1"/>
<staticLogFileName value="false"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
</log4net>
</configuration>
Make sure that the log4net.config file is added in your final release binary and corresponds to the path mentioned in ConfigFile = "log4Net.config".
I had the same problem, then I realized that I was simply missing out this config file in my release binary.
I have this in my Logging.dll and my Program.exe assembly.cs. Then it works in both debug and release mode. My program is a windows service.
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
I have a configuration file for my project that includes the configuration for the log4net logger.
It is as it follows:
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<file value="MyLogFile.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<header value ="Start file processing..."/>
<conversionPattern value="%newline%date - %message%exception" />
<footer type="log4net.Util.PatternString" value="File processing finished.%newline%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
I am wondering if it is possible dynamicaly to change the value of my :
<file value="MyLogFile.txt" />
Simplest way to dynamically change log4net configuration, is setting xml configurator to watch changes of config file:
[assembly: XmlConfigurator(Watch = true)]
When you will do some changes to application config file (one which lives near exe) log4net will automatically reconfigure itself and further output will go to other file.
If you for some reason want to do this programatically then you need to get instance of file appender from logger repository (aka Hierarchy):
var fileAppender = LogManager.GetLoggerRepository()
.GetAppenders()
.OfType<FileAppender>()
.FirstOrDefault(fa => fa.Name == "LogFileAppender");
And change it's settings:
if (fileAppender != null)
{
fileAppender.File = Path.Combine(Environment.CurrentDirectory, "foo.txt");
fileAppender.ActivateOptions();
}
Keep in mind, that simple setting File property will not open new file - it just sets file name which should be opened during appender activation. So, you need to activate it manually just after changing file path.
Yup, you can access the appender at runtime and change the properties of it. Just make sure you call ActivateOptions after changing anything.
Here's an example that changes the connection string for an ADO appender. You should be able to adapt that easily enough for what you are trying to do:
http://blog.gfader.com/2010/05/log4net-how-to-change-settings-of.html
You can read the log4net file, parse it with a xml parser in your application and change the file value attribute. Then save the log4net file. If you have watch=true, the new configuration will be picked up as the new configuration.
You can do some thing like this also
<file type="log4net.Util.PatternString" value="%property{LogFileName}.log" />
ILog logger = LogManager.GetLogger("SampleAppender");
log4net.GlobalContext.Properties["LogFileName"] = "MyLog";
XmlConfigurator.Configure();
I'm not sure if this is the right forum to post this question. But I'm just hoping someone here might have used log4net in the past, so hoping to get some help.
I'm using log4net to log my exceptions. The configuration settings look like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net debug="false">
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\Logs\sample.log" />
<appendToFile value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="10MB"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date %logger.%method[line %line] - %message%newline"/>
</layout>
</appender>
<root>
<level value="INFO"/>
<appender-ref ref="RollingLogFileAppender"/>
</root>
</log4net>
</configuration>
I started out by adding this configuration to web.config, but I got an error (VS studio could not find a schema for log4net-"Could not find schema information for the element log4net"). So I followed this link (Log4Net "Could not find schema information" messages) and configured my settings in a separate xml file and added the following line of code in my AssemblyInfo.cs:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "xmlfile.xml", Watch = true)]
And in the actual code, I placed this line:
public void CreateUser(String username, String password)
{
try
{
log.Info("Inside createuser");
//code for creating user
}
catch(exception e)
{
log.Info("something happened in create user", e);
}
}
The problem is that the log file is not being created. I can't see anything inside C:\Logs. Can anybody tell me what I'm doing wrong here?
Any suggestions/inputs will be very helpful.
Thank you all in advance.
I could not get the setting in Asembly.cs to work without adding this to Application_Start in my Global.asax:
log4net.Config.XmlConfigurator.Configure();
Your log file is not being created probably because the ASPNET user does not have permission to write to the C:\Logs\ directory. Make sure you give full rights to ASPNET to wherever your applicaton wants to create the log file.
So you are loading the configuration file but are you then setting the log variable like so
private static readonly ILog log = LogManager.GetLogger(typeof(Program));
Unless you specify a full path for the separate config file log4net expects the file to be in the path returned by:
System.AppDomain.CurrentDomain.BaseDirectory
If you have a simple console application, this usually means the directory containing the assembly but this is not necessarily true in other cases. There are many ways to solve this problem (c.f. my answer here as well).
To start it might be easier to put the log4net configuration back to the app/web.config and ignore the schema warning. If logging works then you can be sure you have no permission issues and can move to the next step to have the configuration in an external file.
What kind of application are you writing? Maybe I could be a bit more specific with my answer...