log4net:ERROR ConfigureFromXml called with null 'element' parameter - asp.net-core

We are using log4net library with .NET Core for writing logs in file. But we are getting this error when executing the application "log4net:ERROR ConfigureFromXml called with null 'element' parameter".
Here is our Program.cs file:
public class Program
{
public static void Main(string[] args)
{
XmlDocument log4netConfig = new XmlDocument();
log4netConfig.Load(File.OpenRead("log4net.config"));
var repo = log4net.LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));
log4net.Config.XmlConfigurator.Configure(repo, log4netConfig["log4net"]);
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
Here is Configure method in Startup.cs file:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
loggerFactory.AddConsole(LogLevel.Trace);
loggerFactory.AddLog4Net();
app.UseIdentityServer();
}
Here is log4net.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821" />
</configSections>
<!-- Log4net Logging Setup -->
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender,log4net">
<file value="c:\LogFiles\Applications\IdentityServer\log.txt" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="FATAL" />
</filter>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="FileAppender"/>
</root>
</log4net>
</configuration>

Replace your log4net.config with below code :
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<file value="C:\Temp\" />
<datePattern value="yyyy-MM-dd.'txt'"/>
<staticLogFileName value="false"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<maxSizeRollBackups value="100"/>
<maximumFileSize value="15MB"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level App %newline %message %newline %newline"/>
</layout>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="RollingLogFileAppender"/>
</root>
</log4net>

In fact, the accepted response is not accurate, the problem with the XML is the .NET configuration on top of log4net configuration. The original configuration file is a .NET configuration file instead of a log4net one, and it's rooted with a configuration node instead of with a log4net node.
The second configuration XML on the other hand is correct, but it's replacing the original configuration (maybe with a better one, for sure), not only fixing the problem but replacing the original configuration with a new one.
The a better response for the change would be:
Remove the configuration root node from the original xml file together with the configSections node and leave the log4net node as root of the XML resulting in:
<?xml version="1.0" encoding="utf-8" ?>
<!-- Log4net Logging Setup -->
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender,log4net">
<file value="c:\LogFiles\Applications\IdentityServer\log.txt" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="FATAL" />
</filter>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="FileAppender"/>
</root>
</log4net>
Reconfigure your appender with a Rolling appender if needed...

Related

Log4Net Output File Directory - ASP.NET Core 3.1

I am new to log4net and I am just trying to get familiar with it in a console line app. Firstly I noticed from the few tutorials that the general configuration differs slightly, so it maybe the case that I have not got things setup properly.
The console printed fine, but the tutorial I was following placed the file in the same directory of the console app. I found with mine I had to give it the explicit path to my project to work.
Here is my Program.cs
static void Main(string[] args)
{
XmlDocument log4netConfig = new XmlDocument();
log4netConfig.Load(File.OpenRead("log4net.config"));
var repo = LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));
XmlConfigurator.Configure(repo, log4netConfig["log4net"]);
var logger = LogManager.GetLogger(typeof(Program));
logger.Error("Hello, World!");
}
Here is my config
<log4net>
<root>
<level value="ALL" />
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>
<appender name="console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level %logger - %message%newline" />
</layout>
</appender>
<appender name="file" type="log4net.Appender.RollingFileAppender">
<file value="c:\users\dpg\developer\TestLogging\TestLog4Net\loggingfun.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="25MB" />
<lockingmodel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
</appender>
</log4net>
you can use relative path for work folder
<file value="ErrorLog.txt"/>
for saving it to windows location such as LOCALAPPDATA
<file type="log4net.Util.PatternString" value="${LOCALAPPDATA}\Temp\Log\App.log" />
if using .NET core, and an environment variable like this:
<file type="log4net.Util.PatternString" value="${LOCALAPPDATA}\Temp\Log\App.log" />
the log file will end in App/bin/debug/${LOCALAPPDATA}\Temp\Log\App.log
I found a way to solve this problem, by using a GlobalContext property.
In code:
log4net.GlobalContext.Properties["LocalAppData"] = Environment.GetEnvironmentVariable("LOCALAPPDATA");
var repository = LogManager.GetRepository(Assembly.GetCallingAssembly());
XmlConfigurator.Configure(repository, new FileInfo("App.config"));
In App.config
<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
<param name="StaticLogFileName" value="true" />
<file type="log4net.Util.PatternString" value="%property{LocalAppData}\Temp\Log\App.log" />
<appendToFile value="true" />
<encoding value="utf-8" />
<rollingStyle value="Date" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%appdomain] [%thread] %-5level %logger - %message%newline%exception%newline" />
</layout>
</appender>
Those who are looking to set the file path to Project root dicrectory Path can refer below code. I have implemented this in .NET 5 API Project
Changes for Log4net.config file. Remember type="log4net.Util.PatternString" this line is very important
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="%property{LoggerFilePath}\Logs\server.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %5level %logger.%method [%line] - MESSAGE: %message%newline %exception" />
</layout>
</appender>
Then, in Program.cs file
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging((context,loggerBuilder) =>
{
log4net.GlobalContext.Properties["LoggerFilePath"] = context.HostingEnvironment.ContentRootPath;
loggerBuilder.ClearProviders();
loggerBuilder.AddLog4Net();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
Cheers !

Filter Asp.netcore logs in Log4Net

I am using ASP.NET Core and have created a Log4net logging provider.
My current log4net.config file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="true">
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs\\" />
<appendToFile value="true" />
<DatePattern value="yyyy\\\\MM\\\\dd'.inf.log'" />
<rollingStyle value="Date" />
<param name="StaticLogFileName" value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%ndc] <%property{auth}> - %message%newline" />
</layout>
</appender>
<appender ref="HangfireLoggerAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs\HangfireLog.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<logger additivity="false" name="Hangfire">
<level value="INFO" />
<appender-ref ref="HangfireLoggerAppender" />
</logger>
</log4net>
The log is showing A LOT of asp.net core junk. SQL Logs ect.
I would like to filter out :
Microsoft.AspNetCore.*
Microsoft.EntityFrameworkCore.*
How do I do this with Log4net?
you need to configure logging on your WebHostBuilder as follows :
[Program.cs -> BuildWebHost(string[] args) ]
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
ConfigureLogging((hostingContext, logging) =>
{ logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddFilter("Microsoft.AspNetCore", LogLevel.Information);
logging.AddFilter(" Microsoft.EntityFrameworkCore", LogLevel.Information);
logging.AddConsole();
logging.AddDebug();
})
.Build();
You call the logging.AddFilter method specifying the namespace as first parameter and LogLevel as the second parameter.
This can be also done using configuration in appsettings.json file if you don't want to do in code. You can read more here

Quartz.Net, logging with Log4Net and Common.Logging throws "unknown log level"

I have an Azure cloud service which uses Quartz.Net (2.3.2) to run scheduled tasks. My main logging engine is Log4Net (2.0.3) , and I am using Common.Logging.Log4Net1213 (3.0.0) to bridge Common.Logging and Log4Net. I am using my own "NinjectJobFactory" to create all the jobs and their dependencies (It implements IJobFactory). My schedule startup code looks like this:
_scheduler = factory.GetScheduler();
_scheduler.JobFactory = new NinjectJobFactory(_kernel);
_scheduler.Start();
Everything works perfectly for normal, everyday logging (Quartz startup and shutdown, NServiceBus startup, tasks starting, exception handling inside jobs, etc). The problem I have is when there is a fatal exception in any of the lines above which prevents Quartz from starting. (Usually, this is because I have failed to properly include or configure a dependency that one of the jobs needs). Under these circumstances, instead of logging the real problem, I get an exception inside Log4NetLogger.cs complaining about an unknown logging level, and the underlying exception is never surfaced or logged. I have to break on caught exceptions in order to see the underlying exception. Can anyone suggest a fix? Thanks in advance!
The stack trace looks like this:
Microsoft.WindowsAzure.ServiceRuntime Critical: 1 : Unhandled
Exception: System.ArgumentOutOfRangeException: unknown log level
Parameter name: logLevel Actual value was Error. at
Common.Logging.Log4Net.Log4NetLogger.GetLevel(LogLevel logLevel) in
c:_oss\common-logging\src\Common.Logging.Log4Net129\Logging\Log4Net\Log4NetLogger.cs:line
180 at Common.Logging.Log4Net.Log4NetLogger.WriteInternal(LogLevel
logLevel, Object message, Exception exception) in
c:_oss\common-logging\src\Common.Logging.Log4Net129\Logging\Log4Net\Log4NetLogger.cs:line
140 at Common.Logging.Factory.AbstractLogger.Error(Object message,
Exception exception) in
c:_oss\common-logging\src\Common.Logging.Portable\Logging\Factory\AbstractLogger.cs:line
806 at Quartz.Simpl.SimpleThreadPool.WorkerThread.Run() in
c:\Program Files
(x86)\Jenkins\workspace\Quartz.NET\src\Quartz\Simpl\SimpleThreadPool.cs:line
492 at
System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx) at
System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx) at
System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state) at
System.Threading.ThreadHelper.ThreadStart()
My common.logging config in the app.config is:
<common>
<logging>
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net1213">
<arg key="configType" value="FILE" />
<arg key="configFile" value="log4net.config" />
</factoryAdapter>
</logging>
</common>
Finally, my log4net.config is:
<log4net>
<appender name="ErrorAppender" type="log4net.Appender.BufferingForwardingAppender">
<bufferSize value="1" />
<lossy value="true" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="INFO" />
</evaluator>
<appender-ref ref="TraceAppender" />
</appender>
<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
<threshold value="INFO" />
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="NServiceBus.Azure.Transports.WindowsAzureServiceBus.AzureServiceBusQueueCreator" />
<acceptOnMatch value="false" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="ErrorAppender" />
</root>
</log4net>
This may sound silly, but I was facing the exact same problem and I overcame it by making sure the versions of common.logging, common.logging.core, and common.logging.log4net1213 were all of the same version (3.3.1). Apparently, there is version dependency between the three libraries, and if one is used with another not the same version, this can result.
Here is the decompiled code for the function from which your exception is originating. It comes from Common.Logging.Log4Net1213 v3.3.1. Previous versions of this code didn't exactly account for Common.Logging.LogLevel.Warn, and so the exception fell out at the bottom of the switch statement:
public static Level GetLevel(Common.Logging.LogLevel logLevel)
{
switch (logLevel)
{
case Common.Logging.LogLevel.All:
return Level.All;
case Common.Logging.LogLevel.Trace:
return Level.Trace;
case Common.Logging.LogLevel.Debug:
return Level.Debug;
case Common.Logging.LogLevel.Info:
return Level.Info;
case Common.Logging.LogLevel.Warn:
return Level.Warn;
case Common.Logging.LogLevel.Error:
return Level.Error;
case Common.Logging.LogLevel.Fatal:
return Level.Fatal;
default:
throw new ArgumentOutOfRangeException("logLevel", (object) logLevel, "unknown log level");
}
}
In my case, common.logging.log4net1213 was one version behind the others (v3.3.0), so I updated the library to the same version as the other two libraries, and the problem evaporated.
Good luck!
Can you show us your log config?
My Servicebus/log4net/quartz implementation logs quartz startup issues successfully. This is the startup code i use; not sure if it will help as not seen your code.
NSB Version 4.6.2
public class MyServer : ServiceControl
{
private readonly ILog logger;
private ISchedulerFactory schedulerFactory;
private IScheduler scheduler;
public static IBus Bus = null;
public MyServer()
{
logger = LogManager.GetLogger(GetType());
}
public virtual void Initialize()
{
try
{
log4net.GlobalContext.Properties["Job"] = "Quartz";
Configure.Serialization.Xml();
Configure.Transactions.Enable();
SetLoggingLibrary.Log4Net();
Bus = Configure.With().DefaultBuilder().UnicastBus().SendOnly();
schedulerFactory = CreateSchedulerFactory();
scheduler = GetScheduler();
}
catch (Exception e)
{
logger.Error("Server initialization failed:" + e.Message, e);
throw;
}
}
}
public class Configuration
{
private static readonly NameValueCollection configuration;
static Configuration()
{
configuration = (NameValueCollection)ConfigurationManager.GetSection("quartz");
}
static public string GetQuartzConfigFileName()
{
return configuration["quartz.plugin.xml.fileNames"] as String;
}
}
And my app config looks like this
<configuration>
<configSections>
<section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net1211">
<arg key="configType" value="INLINE" />
</factoryAdapter>
</logging>
</common>
<log4net debug="false">
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="FATAL" />
<foreColor value="Red, HighIntensity" />
</mapping>
<mapping>
<level value="ERROR" />
<foreColor value="Red, HighIntensity" />
</mapping>
<mapping>
<level value="WARN" />
<foreColor value="Yellow" />
</mapping>
<mapping>
<level value="INFO" />
<foreColor value="Green" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="GrafOI.Scheduler.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10000KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<!-- quartz clutters the logs so turn it off unless an error occurs -->
<logger name="Quartz">
<level value="ERROR" />
</logger>
<root>
<level value="DEBUG" />
<appender-ref ref="AdoNetAppender" />
<appender-ref ref="EventLogAppender" />
<appender-ref ref="ColoredConsoleAppender" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
<quartz>
<add key="quartz.scheduler.instanceName" value="GrafOI Scheduler" />
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="2" />
<add key="quartz.threadPool.threadPriority" value="Normal" />
<add key="quartz.jobStore.misfireThreshold" value="60000" />
<add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
<add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz" />
<add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
<add key="quartz.jobStore.dataSource" value="myDS" />
<add key="quartz.dataSource.myDS.connectionString" value="server=.;database=GrafOI;Integrated Security=true;" />
<add key="quartz.dataSource.myDS.provider" value="SqlServer-20" />
<add key="quartz.plugin.xml.type" value="Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz" />
<add key="quartz.plugin.xml.fileNames" value="~/GrafOI.Scheduler.Jobs.xml" />
<add key="quartz.jobStore.useProperties" value="true" />
</quartz>
<appSettings>
</appSettings>
</configuration>
Maybe there is something in there that helps

Can't get NHibernate and Log4Net to generate logging.

I can't get any logging of NHibernate or my application. I tried EVERYTHING that I could think about, but nothing works!
Here is my code:
using System.Reflection;
using NHibernate.Cfg;
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]
namespace NHibernate_Log4Net
{
class Program
{
static void Main(string[] args)
{
var cfg = new Configuration()
.Configure()
.AddAssembly(Assembly.GetCallingAssembly());
}
}
}
namespace NHibernate_Log4Net.Model
{
public class Item
{
public int Id { get; set; }
public int Title { get; set; }
public int Alias { get; set; }
}
}
Item.hbm.xml file:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHibernate_Log4Net.Model.Item" assembly="NHibernate_Log4Net" auto-import="false">
<class name="User" table="Users">
<id name="Id">
<generator class="Native"/>
</id>
<property name="Title" length="255" not-null="true" />
<property name="Alias" length="255" not-null="true" />
</class>
</hibernate-mapping>
Log4Net.config file:
<?xml version="1.0" encoding="utf-8"?>
<log4net debug="false">
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log4netLogger.log" />
<appendToFile value="false" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1000KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<appender name="OutputDebugStringAppender" type="log4net.Appender.OutputDebugStringAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p %m - %c -%n" />
</layout>
</appender>
<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date - %message%newline"/>
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFileAppender" />
<appender-ref ref="OutputDebugStringAppender" />
<appender-ref ref="TraceAppender" />
</root>
<logger name="NHibernate" additivity="false">
<level value="FATAL"/>
<appender-ref ref="RollingFileAppender" />
<appender-ref ref="OutputDebugStringAppender" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="TraceAppender" />
</logger>
<logger name="NHibernate.SQL" additivity="false">
<level value="DEBUG" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="RollingFileAppender" />
</logger>
<!--
NHibernate.Loader.Loader logs diagnostic stuff and SELECTs.
You can use either logger, or both, depending on you needs.
-->
<logger name="NHibernate.Loader.Loader" additivity="false">
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="RollingFileAppender" />
</logger>
</log4net>
NHibernate throws an error that the class Users doesn't exist. This is expected, but why do I not see any logging from this, from NHibernate?
(I can log it myself, but the point that I can't see any log from NHibernate).
The config file needs to match the executable, is your executable named Log4Net.exe?
I have had trouble using the XmlConfigurator attribute in the past. Perhaps you should just call XmlConfigurator explicitly in your main like so:
namespace NHibernate_Log4Net
{
class Program
{
static void Main(string[] args)
{
XmlConfigurator.ConfigureAndWatch(new FileInfo("log4net.config"));
var cfg = new Configuration()
.Configure()
.AddAssembly(Assembly.GetCallingAssembly());
}
}
}
If the logging levels set for the NHibernate loggers are too high (or off), you may not see any log messages from NHibernate. For example, what is the value of
((log4net.Repository.Hierarchy.Logger)LogManager.GetLogger("NHibernate").Logger).Level?
You should have a section in your config file like this:
<log4net>
<appender name="NHLog" type="log4net.Appender.FileAppender">
<file value="logs/nhibernate.log" />
<appendToFile value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n" />
</layout>
</appender>
<logger name="NHibernate" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="NHLog"/>
</logger>
</log4net>
Update: If the log file is always created (when non-existent before a run) but is always empty, this points to an exception during appending. To minimise the possibility of an exception, have a very simple conversionPattern (perhaps just "%m%n") and see if any output is generated. If there is, add back elements of the conversion pattern until you find where the problem is. If no output is generated, log something to the NHibernate logger from your own code (this is perfectly OK) and step through it in the debugger.
ILog log = LogManager.GetLogger("NHibernate");
log.Info("Application starting");
If still no joy, you may have to post some of your code/configuration.
https://web.archive.org/web/20110514164829/http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/07/01/how-to-configure-log4net-for-use-with-nhibernate.aspx
I used the above link to set up logging. Try the following
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]
namespace NHibernate_Log4Net
{
class Program
{
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
var cfg = new Configuration()
.AddAssembly(Assembly.GetCallingAssembly());
.Configure()
}
}
}
The extra is this line
log4net.Config.XmlConfigurator.Configure();
It didnt work for me till I added that. I know this is somewhat similar to what Jeffery suggested, but... just my 2cents.
Also, shouldnt the Configure() call on the Nhibernate configuration object come last? After the Assembly is added?

NHibernate Enabling log4net

I have enabled log4net and run my app which is giving an exception.
But the log file is empty.
Doesn't NHibernate log info about the exception???
Malcolm
You need to configure log4net. Just by adding log4net dll to the project doesn't log anything. You need to create appenders to specify where all the loggin should be directed to. Create a xml file like this one:
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs\Trace.log" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<maxSizeRollBackups value="30" />
<maximumFileSize value="1000KB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level - %message%newline" />
</layout>
<threshold value="DEBUG"/>
</appender>
<root>
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
...and configure it when starting up the application:
public static void Main()
{
var logconfig = new System.IO.FileInfo(PATH_TO_LOG_CONFIG);
if(logconfig.Exists)
{
log4net.Config.XmlConfigurator.ConfigureAndWatch(logconfig);
}
}