log4net doesn't watch my app.config - log4net

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.

Related

Log4Net - Output not showing up at file

I have an Log4Net configuration that produces output as expected in a console application.
I have the exact same config, and invokation code (all done at the earliest point possible in the execution flow), but in the context of NUnit tests.
I know the configuration is loaded correctly. Additionally, I have turned the system diagnostics for Log4Net, and the debug prints are the exact same in both cases.
In the console application the text gets written. Otherwise, the file is empty.
The configuration code:
<log4net>
<!--APPENDERS-->
<!--Endpoint File Appender-->
<appender name="EndpointFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\Temp\Endpoint.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="10" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</appender>
<!--LOGGERS-->
<logger name="EndpointLog">
<level value="ALL" />
<appender-ref ref="EndpointFileAppender" />
</logger>
The Invocation code (first thing at application boot):
log4net.Config.XmlConfigurator.Configure();
ILog log = LogManager.GetLogger("EndpointLog");
log.Info("Hello World.");
Any ideas? Thanks
Is it that you need a root section? Try adding this:
<root>
<level value="All" />
<appender-ref ref="EndpointFileAppender" />
</root>
When you are running in an unittest context, you need to copy the log4net config into the bin folder with your unittest dlls. You can do this by setting copy tot output folder on the log4net config.

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 not logging from Autocad Plugin on deployment

I am developing an AutoCAD 2012 plugin using .net API"s of autocad. The Autocad plugin's are dll which are loaded into the Autocad runtime when the Autocad is started. I have been able to successfully log from log4net using Visual Studio developement environment. However, when I run the plugin outside of Visual Studio, that is when I deploy my plugin, the log4net does not log any messages or even create a log file. Here is the logging related code and the configuration file.
log4net_autocad.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/>
</configSections>
<log4net>
<appender name="AutocadRollingFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="${NIRVANA_SOFTWARE_INSTALL_PATH}Relay_Manager_Autocad.log"/>
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="0" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p [%C.%M] %m%n"/>
</layout>
</appender>
<logger name="AutocadFile">
<level value="All"/>
<appender-ref ref="AutocadRollingFileAppender"/>
</logger>
</log4net>
</configuration>
myPlugin.cs: Code to congifure logging
public class MyPlugin : IExtensionApplication {
private static log4net.ILog log;
void IExtensionApplication.Initialize() {
...
log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("log4net_autocad.config"));
log = log4net.LogManager.GetLogger("AutocadFile");
}
void IExtensionApplication.Initialize() will execute when the Autocad is started. Couple of things that I have checked:
Checked that the Autocad Plugin is properly loaded in Autocad, which
means that log4net initialization code has run.
Checked that log4net config file (log4net_autocad.config) is copied
in the bin directory of the deployed application
The strange thing is that when I load the plugin in developement environment(VS 2010), the plugin logs properly. So why is the log4net not logging (or even creating a log file) in deployment.
EDIT:
I checked some additional stuff
In the plugin just before I log, I checked following through alert dialogs.
The log.Logger.Name properly returns the name of the logger that I am using.
log.Logger.IsEnabledFor(log4net.Core.Level.All) returns false, even though I have configured Level Value=All in the config file.
EDIT-2
I tried to define config file as explained in the referring url of the answer. I am quoting the approach as outlined in the document.
2.] Application Configuration File: [AppName].exe.config, [AppName].dll.config
The application-level configuration, [AppName].exe.config or [AppName].dll.config, is where
most of this document will spend its time. This configuration file will contain all applicationlevel settings and can even be used to define the use of and default values for settings
associated with the Roaming-User and Local-User configuration files. These files are
typically stored in the same directory as the application executable, but can be placed
elsewhere if necessary. There will be much more discussion on this to come.
The above approach suits my application, but I still can't get the logger to log anything at all.I defined a log4net config file with name RelayAnalysis_Autocad.dll.config and supplied it to the log4net for configuration. I think there is something else to it that I am not able to understand. I have started doubting whether we can log using log4net from autocad plugin?
I also removed the environment path and hardcoded it so as to eliminate any issues regarding the reading of environment variable. Still no luck.
On deploy, you should store the plugin configuration in one of the default config files:
User.config
acad.exe.config
machine.config
Probably, the User.config is the best file to carefully change during setup. Moreover you should design and code the changes so that they can be reverted on uninstall.
Doublecheck that you have properly replaced the ${NIRVANA_SOFTWARE_INSTALL_PATH} during setup and that the folder has proper permissions.
Furthermore, I would try to either add to the AssemblyInfo.cs the following line
[assembly: log4net.Config.XmlConfigurator(ConfigFile="AbsolutePathToTheConfig")]
(in which case you shouldn't call XmlConfigurator.Configure) or use an absolute path in the call to
log4net.Config.XmlConfigurator.Configure(new FileInfo("AbsolutePathToTheConfig"));
Finally, note that the log4net documentation about XmlConfigurator.Configure states that the configuration file used can be a XML not matching the .NET config rules.
The configuration file must be valid XML. It must contain at least one element called log4net that holds the log4net configuration data.
Thus, in the log4net_autocad.config file you can skip the <configuration> element:
<log4net>
<appender name="AutocadRollingFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="Absolute\Path\To\Relay_Manager_Autocad.log"/>
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="0" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p [%C.%M] %m%n"/>
</layout>
</appender>
<logger name="AutocadFile">
<level value="All"/>
<appender-ref ref="AutocadRollingFileAppender"/>
</logger>
</log4net>

Need to modify this log4net to write to a file, with ability to write to many files

So I already have nhibernate working which uses log4net, and my web.config currently looks like:
<log4net debug="false">
<appender name="console" type="log4net.Appender.ConsoleAppender, log4net">
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default priority -->
<root>
<priority value="INFO"/>
<appender-ref ref="console"/>
</root>
</log4net>
Now my current requirement is the ability to create a seperate log file for each major module that I have in my application.
Right now it seems to be just writing to console, but I need to add the ability to write to files.
What do I have to modify in my configuration to be able to do this?
I want to be able to, in my code, say I want to write to logfile "logfile_1", and if it doesn't exist, create it, otherwise just append to it.
Really simple, rinse and repeat as required for number of files you want, you can also associate namespaces with different files if you want them separated out that way but I find it easier just to use Log2Console to view the file all together.
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="k:\temp\log2console.log" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.XmlLayoutSchemaLog4j" />
</appender>
Don't forget to add the appender-ref to your root section.

Log4Net section in Web.Config generates Error

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.

Resources