I am working on an Integration Test for a REST Endpoint that connects to a vendors Rest Api on a hardware device. My software has to be tested on the physical device periodically. I created a test project (VSTest VS 2015) and I want to add logging to my test harness. I realize that there is a tremendous amount of documentation on log4net, but I still can't make it work. My goal is to log to the console and also to a file. The vendor wants a log file to validate that my tests completed.
First, I initialize log4net to read a standalone file.
using log4net.Config;
using log4net;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;
namespace MyProgram
{
[TestClass]
public class AssemblyInitializer
{
private static ILog log = null;
[AssemblyInitialize]
public static void Configure(TestContext Context)
{
Debug.WriteLine("Starting log4net setup and configuration");
XmlConfigurator.Configure(new FileInfo("log4net.properties"));
log = LogManager.GetLogger(typeof(AssemblyInitializer));
log.Debug("log4net initialized for Integration Test");
Debug.WriteLine("Completed log4net setup and configuration");
}
}
}
My log4net.properties file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionpattern value="%date [%thread] %-5level %logger{1} - %message%newline"/>
</layout>
</appender>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="IntegrationTests.log" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG">
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="FileAppender"/>
</level>
</root>
</log4net>
</configuration>
I don't think the Test Explorer reads the Assembly.Info file, but I included a reference just in case.
[assembly: log4net.Config.XmlConfigurator(Watch = false)]
I have tried just about everything I can think of. I am out of ideas. Any help would be appreciated.
The code below works. It is not the same implementation, but I am getting both loggers to work. See my above comments. I believe that the log file was either in an unknown location, or I should have accessed a repository along the way. The following code works great and initializes before my tests are run, and logs my test results as needed.
using log4net;
using log4net.Config;
using log4net.Repository.Hierarchy;
using log4net.Core;
using log4net.Appender;
using log4net.Layout;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyProgram
{
[TestClass]
public class AssemblyInitializer
{
private static ILog log = null;
[AssemblyInitialize]
public static void Configure(TestContext Context)
{
Debug.WriteLine("Starting log4net setup and configuration");
Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
hierarchy.Root.RemoveAllAppenders();
PatternLayout patternLayout = new PatternLayout();
patternLayout.ConversionPattern = "%date [%thread] %-5level %logger - %message%newline";
patternLayout.ActivateOptions();
FileAppender fileAppender = new FileAppender();
fileAppender.Name = "Integration Test FileAppender";
fileAppender.File = #"Logs\IntegrationTest.log";
fileAppender.AppendToFile = false;
fileAppender.Layout = patternLayout;
fileAppender.ActivateOptions();
hierarchy.Root.AddAppender(fileAppender);
ConsoleAppender consoleAppender = new ConsoleAppender();
consoleAppender.Name = "Integration Test ConsoleAppender";
consoleAppender.Target = Console.Out.ToString();
consoleAppender.ActivateOptions();
consoleAppender.Layout = patternLayout;
hierarchy.Root.AddAppender(consoleAppender);
hierarchy.Root.Level = Level.Debug;
hierarchy.Configured = true;
log = LogManager.GetLogger(typeof(AssemblyInitializer));
log.Debug("log4net initialized for Integration Test");
Debug.WriteLine("Completed log4net setup and configuration");
}
}
}
I'm going to expand on my comment. Because Log4Net drove me insane too.
This is all that's in my App.config in my Test project for NLog.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<appSettings>
</appSettings>
<nlog autoReload="true"
throwExceptions="true"
internalLogLevel="Debug" internalLogFile="c:\temp\nlog-test.log" >
<targets>
<target type="Console" name="console" error="true"/>
</targets>
<rules>
<logger name="*" writeTo="console" />
</rules>
</nlog>
</configuration>
You define a target which is a destination for logging and then specify which loggers write to that target.
They want you to use the LoggingManger to create a logger (a source) for every class you want to log from. But I just wrapped a single logger in a static class and created some pass-thru methods. You lose some details that the logger could automatically capture for you (e.g. the exact site of the logging call), but I usually have sufficent detail in the message I'm writing to log.
~
Nlog is on Github https://github.com/NLog/NLog. Log4Net is still svn. That tells me something.
There also some nice Windows forms targets for Nlog available on NuGet.
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.
namespace Com.Foo
{
public class Bar
{
private static readonly ILog log = LogManager.GetLogger(typeof(Bar));
public void DoIt()
{
log.Info("Did it again!");
}
}
}
class Program
{
private static readonly ILog log = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
string sfile = #"C:\development\Framework\Logging\ConsoleApplication1\app.config";
XmlConfigurator.Configure(new System.IO.FileInfo(sfile));
log.Info("Entering application.");
Bar bar = new Bar();
bar.DoIt();
log.Info("Exiting application.");
Console.ReadLine();
}
}
My log4net configuration looks as follows:
<!-- 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>
<!-- Print only messages of level WARN or above in the package Com.Foo -->
<logger name="Com.Foo">
<level value="WARN" />
</logger>
The output of my application still shows log from Com.Foo
67 [10] INFO ConsoleApplication1.Program (null) - Entering application.
100 [10] INFO ConsoleApplication1.Com.Foo.Bar (null) - Did it again!
100 [10] INFO ConsoleApplication1.Program (null) - Exiting application.
How do I configure such that Com.Foo.Bar stops from showing up for WARN level?
What am I missing?
Thanks
Configuration, which you provided should work.
When you create logger Com.Foo.Bar it inherits settings from Com.Foo logger in hierarchy. Com.Foo logger inherits his appenders from root logger, but it has own level, which is set to WARN. So, when you trying to write logging event via Com.Foo.Bar logger, effective level will be retrieved from hierarchy - it's a level of nearest logger up in the hierarchy tree (root logger always has level). In your case it is WARN, so logging event will not be passed to appenders.
I think your configuration differs from what you provided. Maybe you are reading wrong configuration file. Try this code (app configuration file will be used):
XmlConfigurator.Configure();
Or (even better) use configuration via attribute:
[assembly: log4net.Config.XmlConfigurator(Watch=true)]
UPDATE
If changing logger retrieving from typeof(Bar) to "Com.Foo" worked, then you provided us wrong namespace of Bar class. Because log4net behind the scene takes full name of type as name of logger. Thus with namespace Com.Foo all should work.
I just figured it out.. I was not setting the logger properly in Foo.Bar class.
Update the following line
private static readonly ILog log = LogManager.GetLogger(typeof(Bar));
to the following..
private static readonly ILog log = LogManager.GetLogger("Com.Foo");
and it worked.
Try
<levelToMatch value="WARN" />
I would like to log in the Windows Event Viewer using log4net.
I created a Console Application (.NET Framework 4), I added the reference log4net.dll, I put the following code in my App.config:
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<log4net>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
</layout>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="EventLogAppender"/>
</root>
</log4net>
<startup><supportedRuntime version="v2.0.50727"/></startup>
</configuration>
And I put the following code :
class Program
{
static void Main(string[] args)
{
log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));
log.Error("test error", new Exception("error's exception", new Exception("error's innerexception")));
Console.Read();
}
}
It doesn't log, nothing happens, why?
Thanks
You need to call configure.
Change:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "App.config", Watch = true)]
To
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
When you specify ConfigFile = "App.config" its going to look for App.config but your filename would be [FileName].Config.
You need to call XmlConfigurator.Configure from the log4net library to initialize it. (see below)
class Program
{
static void Main(string[] args)
{
// you need this
XmlConfigurator.Configure();
log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));
log.Error("test error", new Exception("error's exception", new Exception("error's innerexception")));
Console.Read();
}
}
Call XmlConfigurator.Configure() at the begining of your App.
You also need to grant the user running the application rights to put data in the eventlog.
A good way to do this is with powershell, admin mode
New-EventLog EventLogName -source ApplicationName
Also, add this two parameters into the appender
<param name="LogName" value="EventLogName " />
<param name="ApplicationName" value="ApplicationName" />
Regards,
I am using log4net to perform logging in my application. I have bound my project to TFS. I have created a wrapper around log4net as below:
public static class TestLogger
{
private static readonly ILog log = LogManager.GetLogger("TestLogger");
static TestLogger()
{
log4net.Config.XmlConfigurator.Configure();
}
public static void LogInfo(string information)
{
log.Info(information);
}
public static void LogError(string erroMessage, Exception ex)
{
log.Error(erroMessage, ex);
}
public static void LogWarnings(string warningText)
{
log.Warn(warningText);
}
}
When I tried to execute the program from VS2010 I found that log file is not being created. I create another project (not bound to TFS) and perform some logging, it succeeded and created the file in bin/debug of application.
Below is my log4net configuration file.
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender, log4net">
<file value="Log.txt" />
<appendToFile value="false" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="3" />
<maximumFileSize value="1GB" />
<layout type="log4net.Layout.PatternLayout, log4net">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<logger name="TestLogger">
<level value="ALL" />
<appender-ref ref="RollingFileAppender" />
</logger>
</log4net>
Can anybody help in this issue?
Some troubleshooting tips:
define an absolute path to the Log file in your config file.
check the current working directory in your code (Environment.CurrentDirectory). If you're running under the VS debugger, and you haven't specified a working directory in the Debug tab of your project properties, it may well default to the current Visual Studio working directory.
I don't think being bound to TFS is relevant.
Just change this part
<appendToFile value="true" />
Maybe your application already uses some declarative configuration, which is somewhere burried in the code. Search for something like this:
[assembly: log4net.Config.XmlConfigurator(Watch=true)]
Otherwise try to get hold of the log4net repository with
log4net.LogManager.GetRepository(). It returns an object of the type ILoggerRepository. You can try to use this object to write some information about the current log4net configuration into the Console or somewhere else.
Try to turn on internal debugging as explained here. This should tell you what the problem is. If there is no output from internal debugging then you probably did not configure log4net.