log4net doesn't log in Windows Event Viewer - c#

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,

Related

How to configure log4net with VS 2015 for an Integration Test?

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.

Creating logs in c#

I am creating logs in C# by using object of ILog in log4net. I am passing two parameters 1) repository where it will create log file 2)name of log file but it is showing exception that directory is not defined and if I do it by just passing name of log file ,program runs successfully but I am unable to find the log file.
Here is my code :-
private void createLogger(string Logdirectory)
{
if (Directory.Exists(Logdirectory))
{
Log = LogManager.GetLogger( Logdirectory , LogFilename);
}
else
{
Log = LogManager.GetLogger(LogFilename);
}
}
Here is console output :-
Help me find suitable way of getting logger by Ilog or by any other method except filestream
Read the documentation, log4net is very configurable and well documented.
Documentation: https://logging.apache.org/log4net/release/manual/configuration.html
using Com.Foo; // Import log4net classes.
using log4net;
using log4net.Config;
public class MyApp
{ // Define a static logger variable so that it references the // Logger instance named "MyApp".
private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
static void Main(string[] args)
{ // Set up a simple configuration that logs on the console.
BasicConfigurator.Configure();
log.Info("Entering application.");
Bar bar = new Bar();
bar.DoIt();
log.Info("Exiting application.");
}
}
Take note the difference in the method for getting to log instance.
You're asking for an ILog for the current Type not an explicitly a filename
You're telling log4net to read configuration settings from the app.config/web.config
Depending on your config you may need to use the XmlConfigurator
An example of the .config file is:
<log4net> <!-- A1 is set to be a ConsoleAppender -->
<appender name="A1" type="log4net.Appender.ConsoleAppender"> <!-- A1 uses PatternLayout -->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-4timestamp [%thread] %-5level %logger %ndc - %message%newline" />
</layout>
</appender>
<!-- Set root logger level to DEBUG and its only appender to A1 -->
<root>
<level value="DEBUG" />
<appender-ref ref="A1" />
</root>
</log4net>
There are lots of Appenders, above is a ConsoleAppender, but a DatabaseAppender exists and other types that might fit with you're need.

Log4Net doesn’t write log in release mode - Console Application

I have a console application and have a class library which wraps the Log4Net methods. Now when run the application in debug mode it writes log but when it is built in release mode it doesn’t write log file. What would be the solution for this? The sample code and config file is given below
My development environment is
Visual Studio 2013 and .NET Framework 4.5
Console Application
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
log4net.GlobalContext.Properties["LogFileName"] = "TestLogin.txt";
Logger log = new Logger(typeof(Program));
log.Info("Logging is enabled!!");
}
}
}
App.config in Console Application
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value ="%property{LogFileName}"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level - %message%newline%exception" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
</configuration>
Class Library
using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace Logging
{
public class Logger
{
private readonly ILog log = null;
public Logger(Type type)
{
log = LogManager.GetLogger(type);
}
public void Info(object message)
{
log.Info(message);
}
}
}
I have followed the post and it didn’t help me to figure out why Log4Net doesn’t write in log file in release mode?
log4net doesn't log when running a .Net 4.0 Windows application built in Release mode
There are a few workarounds for this.
You could add the [MethodImpl(MethodImplOptions.NoInlining)]
attribute to your Logger constructor methods in your class library.
You could add [assembly: log4net.Config.XmlConfigurator(Watch =
true)] to AssemblyInfo.cs in your Console Project (not the class library project)
You can add log4net.Config.XmlConfigurator.Configure(); at the
start of your Logger constructor.
I think the reason this is happening is that in release mode, your class library is inlined and so when log4net attempts to find the attribute, it thinks the calling assembly is your exe which does not contain the attribute.
PS.
I presume you are aware that your Logger class will mean that you lose the ability to filter by method names, as log4net will only see the Logger.Info method name.
The line [assembly: log4net.Config.XmlConfigurator(Watch = true)] should be added to your AssemblyInfo.cs file in the Properties folder.
For users with an MVC app that already have the lines [assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)] in AssemblyInfo.cs and log4net.Config.XmlConfigurator.Configure(); in Global.asax.cs, but it's still not writing, make sure that the Application Pool user has permissions to write to the location where you're writing the log.
To get around this, I simply created a log directory on the IIS server NOT inside inetpub, gave it adequate permissions (I suppose it can be "Everyone", "Full Control" if it's just a child log directory and you're feeling lazy), and wrote the full path in the log4net.config (or Web.config, if you didn't isolate it).
Here's my config file:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<root>
<level value="ALL"/>
<appender-ref ref="RollingFileAppender"/>
</root>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:/absolute/path/to/logfile.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maximumFileSize value="10MB"/>
<datePattern value="yyyyMMdd'-FULL.log'" />
<maxSizeRollBackups value="-1"/>
<staticLogFileName value="false"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
</log4net>
</configuration>
Make sure that the log4net.config file is added in your final release binary and corresponds to the path mentioned in ConfigFile = "log4Net.config".
I had the same problem, then I realized that I was simply missing out this config file in my release binary.
I have this in my Logging.dll and my Program.exe assembly.cs. Then it works in both debug and release mode. My program is a windows service.
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]

log4net log being created but remaining empty

I'm attempting to use log4net. When I fire up the app it creates the log file, but no matter how many times I call Log.Info("Application Started"); it remains empty. I've researched the first two pages that google returns and my code seems to match all examples.
Code:
[assembly: XmlConfigurator(Watch = true)]
namespace Generator
{
public class Run
{
private static readonly log4net.ILog Log =
log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public List<BILL_RUN> PerformBillRun()
{
XmlConfigurator.Configure();
Log.Info("Application Started");
var enabled = Log.IsInfoEnabled; //This is true
}
}
}
app.config
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log-files.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<root>
<level value="All" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
Any pointers as to what may be wrong?
This always happens to me...as soon as I post the question.
It turns out my <configSections></configSections> tags weren't directly a child to <configuration> meaning that the config wouldn't be picked up (I assume), and because log4net swallows all exceptions this only manifested itself further into my app.
Logging is working fine now.

Log4Net issue while using RollingFileAppender

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.

Categories

Resources