Log4Net section in Web.Config generates Error - c#-4.0

So I am trying to set up Log4Net in my Web .NET 4.0 application. I have added the correct .dll to my project and have appended the following to my Web.Config file as starters:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLogFileAppender" />
</root>
</configSections>
<log4net debug="true">
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\\TestProj\\TestLog.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n" />
</layout>
</appender>
However, if I append the "log4net" section to Web.Config, I will receive the error message
Unable to start debugging on the web server. See help for common
configuration problems.....
Make sure the server is running correctly. Verify there are no syntax
errors in the web.config........
NOTE
I can remove all the internals of this section and leave only the declaration:
<log4net></log4net>
and I will still get the same error.
Can someone give me some pointers on how to track down this error?

For developers who are not sure exactly how to get started following might be a help
ConfigSections in app.config
Remember to tell your application that a library is introducing a custom configuration section are you are intended to utilize, I am not perfectly sure if it is mandatory or not but I always use it as first section within root <configuration> tag.
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
log4net config in app.config
There are quite a variety of different appenders available in log4net but I usually use RollingFileAppender so I am using the same one in this sample, you can find rest of those here.
<log4net>
<!-- file appender -->
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:/logs/my_log_file.log"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<maxSizeRollBackups value="30"/>
<datePattern value=".yyyy-MM-dd"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
</layout>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="RollingFileAppender"/>
</root>
</log4net>
Update AssemblyInfo.cs file
I always miss this step whenever I have to create a new project. So remember you have to tell your application to watch for XMLConfigurator to perform configuration of log4net, so following line goes at the end of AssemblyInfo.cs file:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
Get Started
Remember to include the reference of log4net.dll then use following line of code to initialize logger within a class
private static ILog log = LogManager.GetLogger(typeof(MyClass));
And at the end lets use it like following
log.Info("Hello log4net");
Happy Logging :)

Take a look at a sample configurations at log4net documentation homepage.
Chances are you've misplaced required tags.

Related

Log4Net does not log from a class library

I am working on .NET Framework 4.0 using C# in Windows 7, and trying to log from a class library but it's not working. I'm running my application without errors, but also nothing happens to my log file, neither to my console.
So, here is my code:
This is my App.config file:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<add key="log4net.config" value="config.log4net"/>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{ABSOLUTE} [%thread] %level %logger - %message%newlineExtra Info: %property{testProperty}%newline%exception"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG"/>
<levelMax value="FATAL"/>
</filter>
</appender>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="MyLogFile.txt"/>
<appendToFile value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="5"/>
<maximumFileSize value="10MB"/>
<staticLogFileName value="true"/>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="debug"/>
</filter>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="error"/>
</filter>
<filter type="log4net.Filter.DenyAllFilter"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline%exception"/>
</layout>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="RollingFileAppender"/>
</root>
<logger name="MyApplication">
<level value="DEBUG"/>
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="RollingFileAppender"/>
</logger>
</log4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
This is what I put into my AssemblyInfo.cs:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
This what is at the file i'm trying to log:
private static readonly ILog log = LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
log.Debug("Testing");
When i run my program nothing happens. Someone knows why?
Similar to this answer, both the app.config, log4net configuration and the AssemblyInfo.cs configurator needs to be placed in the host application.
Lets say I have project Console as a console project that I will run, and Library as a Library project. Console will need to have an app.config file with the above log4net configuration, and the AssemblyInfo.cs will need the XmlConfigurator code inside of it. Library does not need either of these, and will work by using the LogManager call.
Console > This is the project that you will run.
Properties
AssemblyInfo.cs > Place [assembly: log4net.Config.XmlConfigurator(Watch = true)] here.
app.config > Place log4net XML configuration here.
Program.cs > Start of application.
Library
Properties
AssemblyInfo.cs > Leave this file alone.
Foo.cs > Create the private readonly property.
SomeMethod() > log.Debug("Test");
Incase anyone is still looking at this and to add to the previous answers, you need to have instantiated a logger in your host application before you can log from the class library.
If you look at the log4net documentation for assembly attributes it says this:
"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."
When the assembly attributes are defined in a class library - i.e. an external assembly - it gets tricky. Can you use log4net.Config.XmlConfigurator.Configure(path) instead?

Log4net C#4.0 [(null)] in output

When I use log4net for logging in .NET4.0 I use the following code
LogManager declaration:
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
And when used in code:
log.Info("My info text");
This outputs the following to the log-file:
2013-10-01 14:41:11,010 [3] INFO MyNamespace.MyClass [(null)] - My info text
I am wondering what the [(null)] means and how I can remove/change it?
This is my config-file:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="log-file.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
</log4net>
</configuration>
Fix
To stop it appearing in the log remove [%property{NDC}] from the config file.
This happens because log4net automatically populates a context of information that might be useful for logging - in some cases this might result in a null value.
log4net NDC
This post explains how to use NDC: When to use 'nested diagnostic context' (NDC)?
In short log4net calls the static method log4net.NDC.Push to set the context of the the code.
You could for example set the NDC manually by running the following:
log4net.NDC.Push("context")
From that point forward outputting a log message will supply %property{NDC} as the string context.
UPDATE:
NDC.Push has been deprecated. Alternatively, you can use ThreadContext.Stacks["NDC"].Push("context")
if you just want the (null) to disappear you can also set log4net.Util.SystemInfo.NullText to some other value like "" or string.Empty, it will use that instead.

log4net - no log file produced

I have this as my config file:
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="c:\\logging\\EwsSearch.log" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="-1" />
<maximumFileSize value="100KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
</log4net>
<root>
<level value="ERROR" />
<appender-ref ref="RollingFileAppender" />
</root>
</configuration>
I then have in my C# code:
public class VsiEWSSearch
{
private static readonly ILog logger = LogManager.GetLogger(typeof(VsiEWSSearch));
public EWSResponse PdeProcessInquiry(int BusinessLineCode, int ClientCaseId, string callingApp)
{
XmlConfigurator.Configure(new System.IO.FileInfo("VSI.EWSSearch.config"));
logger.Error("This is an error");
No log file is produced even though I have adjusted permissions for the directory. What's wrong?
The root node has to be inside the log4net node. Depending on the type of configuration file you need to make some further adjustments:
If you have a standalone config file for log4net then you need to remove the configuration and configSections node. I also think that log4net is not going to find you configuration file unless you specify the full path (you can of course do that without hard-coding any path in your application).
If you are simply using app.config then you do not need further modifications, but you need to call the XmlConfigurator.Configure() method without any argument.
Note: You should call the XmlConfigurator.Configure() method only once in your application.

log4net doesn't watch my app.config

I configured my log4net to watch on changes made to the app.config file.
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
When I run my app and change things in the config file, these changes only take effect when I restart my app. Why could this be?
Is there also a way to tell log4net to watch on changes in the app.config? Like:
<appender name="FileAppender" type="log4net.Appender.FileAppender" >
<watch value="true" />
</appender>
------------- EDIT -------------
I tried now to use a separate config-file: log4net.config.
It looks like this:
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="c:\log.txt" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %c (line %L) -- %m%n" />
</layout>
</appender>
<root>
<appender-ref ref="FileAppender" />
</root>
</log4net>
In my assemblyInfo.cs I wrote the following:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
The class that logs to the file looks like this:
ILog myLogger = LogManager.GetLogger(typeof(Form1));
myLogger.Debug("test");
This works like the old version. logfile entries are made, but when I change my log4net.config during runtime, these changes are not applied.... "Watch=true" should enable that feature, right?
HA!, I was just encountering the same problem, running unit tests that require logging.
Adding this line fixed it:
log4net.Config.XmlConfigurator.Configure();
My App.config:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100KB" />
<staticLogFileName 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="RollingFileAppender" />
</root>
</log4net>
I also do have this:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
According to log4net documentation, the Watch feature does not work for application configuration files (app.config, web.config):
Because the System.Configuration API does not support reloading of the config file
the configuration settings cannot be watched using the
log4net.Config.XmlConfigurator.ConfigureAndWatch methods.
So if you need the log4net configuration to be re-configurable, you will need to place it in a separate XML file and your application needs to have sufficient permissions to read the file:
The file to read the configuration from can be specified using any of the log4net.Config.XmlConfigurator methods that accept a System.IO.FileInfo object. Because the file system can be monitored for file change notifications the ConfigureAndWatch methods can be used to monitor the configuration file for modifications and automatically reconfigure log4net.
Even though I'm terribly late to the party - here's, what helped me: a simple call to log4net.LogManager.GetLogger("DUMMY"); at the very beginning of my program. I put it in the very first line of program.cs's Main() method. No need to assign the logger to any object, merely a polite request to log4net to read the assembly's attributes as stated here.
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.

log4net does not roll over the log file sometimes when rollingstyle set to date

I have a Windows C# application which uses log4net for logging. This is how the loggers are configured:
<log4net>
<appender name="DebugFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Local\logs\ApplnTrace.log" />
<threshold value="INFO" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%5p] - (%file:%line) %m%n" />
</layout>
</appender>
<appender name="MSGFileAppender" type="log4net.Appender.RollingFileAppender">
<file value=".\local\logs\MsgTrace.log" />
<threshold value="INFO" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d %n%m%n" />
</layout>
</appender>
<logger name="ApplnLogger">
<appender-ref ref="DebugFileAppender" />
</logger>
<logger name="MsgLogger">
<appender-ref ref="MSGFileAppender" />
</logger>
</log4net>
The files are rolled over based on date sometimes and sometimes does not and when files are not rolled over, the logging also stops. Can anybody help me find out why?
log4Net is designed to fail quietly. When things stop working, there's usually a problem (most often, it's a config issue or a filesystem security issue).
You might want to try enabling internal log4net debugging. Park this key in the <appSettings> element of your app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
</configuration>
then start your app. Log4net will spew a bunch of debugging info. It gets written to System.Console and to the System.Diagnostics.Trace system. You can catch the trace messages from an attached debugger or by adding a trace listener in the app.config file. If the trace listener writes to a file, make sure that your process has write access, otherwise you'll see nothing:
<configuration>
...
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt"
/>
</listeners>
</trace>
</system.diagnostics>
...
</configuration>
There are a number of different trace listeners you can wire up here, including ones that write to the windows event system.
More here:
http://haacked.com/archive/2006/09/27/Log4Net_Troubleshooting.aspx
http://logging.apache.org/log4net/release/sdk/log4net.Util.LogLog.InternalDebugging.html
Without source, it's hard to tell. Does the application also stop working? If yes, find the fatal flaw in your application.
If not, judging from the log4net JIRA, there's plenty of issues with the RollingFileAppender(see: log4net JIRA) :
"RollingFileAppender stops logging intermittently when it tries to roll over the log file"
"RollingFileAppender with rollingStyle="Date" and maximumFileSize both are not working Simultaneously."
Maybe it's one of those issues that's hurting you.

Resources