Write log-file when testing with NUnit - c#

I have a test-assembly (MyTestProject) where I want to write some logging using log4net. Thus I created a config-file with the same name as the assembly where I set up the logging as suggested here:
<?xml version="1.0" encoding="utf-8" ?>
<!-- .NET application configuration file
This file must have the exact same name as your application with
.config appended to it. For example if your application is testApp.exe
then the config file must be testApp.exe.config it must also be in the
same directory as the application. -->
<configuration>
<configSections>
<!-- Register the section handler for the log4net section -->
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
<sectionGroup name="NUnit">
<!-- For .NET 2.0 Beta 2 replace the lines with the following -->
<section name="TestCaseBuilder" type="System.Configuration.NameValueSectionHandler, System, Version=2.0.50215.44, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="TestRunner" type="System.Configuration.NameValueSectionHandler, System, Version=2.0.50215.44, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</sectionGroup>
</configSections>
<NUnit>
<TestCaseBuilder>
<add key="OldStyleTestCases" value="false" />
</TestCaseBuilder>
<TestRunner>
<!-- Valid values are STA,MTA. Others ignored. -->
<add key="ApartmentState" value="STA" />
<!-- See ThreadPriority enum for other valid values -->
<add key="ThreadPriority" value="Normal" />
</TestRunner>
</NUnit>
<appSettings>
<add key="ApartmentState" value="STA" />
<add key="apartment" value="STA" />
</appSettings>
<!-- This section contains the log4net configuration settings -->
<log4net debug="true">
<!-- Define some output appenders -->
<appender name="LogFileAppender" type="log4net.Appender.FileAppender,log4net" >
<param name="File" value="D:/data.log" />
<param name="AppendToFile" value="false" />
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] <%X{auth}> - %m%n" />
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default priority -->
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
</configuration>
Within my code I set up the logging as follows:
[TestFixture]
public class MyTest
{
private readonly ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
[TestFixtureSetUp]
public void Init()
{
log.Info("Something to log");
...
}
}
However when I run my tests no such file D:/data.log is created. Even more suspicious when I debug the code and add a watch to the appenders from log I get an empty collection.

I post this together as it stuck me for hours.
I looked into the directory where the file should stay, there was one (apperently from an earlier test-run as its timestamp was not recent). Trying to delete the file got me a message that it is currently in use from nunit-agent-x86.exe. So I killed the process in TaskManager and re-run my tests. Now everything works correct and I get my logging into the file.

This Could have been solved if you give value for key, AppendToFile as true..
As logger appends logging to the existing file and wont try to delete it.

Related

GetAppenders() returns empty list in log4net

I have the following method that fetches the name of the log file in log4net:
private string GetLogFile()
{
var repo = LogManager.GetRepository();
var fileAppender = repo.GetAppenders()
.OfType<FileAppender>().Single(fa => fa.Name == "LogFileAppender");
var logFile = fileAppender != null ? fileAppender.File : string.Empty;
return logFile;
}
This code works fine when I have this code running in a Windows service. But I was given the task to move logging to the main web app. So I referenced log4net in the web app, moved over the config settings, etc. But now when I run the same code the call to GetAppenders() returns an empty list.
Here is the config I have:
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<param name="File" value="\\MYSERVER\Temp\MYFiles\Log\Log.txt" />
<param name="AppendToFile" 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>
Is there an extra step in the web app version that I need to do?
It turned out to be something missing in the Global.asax.cs file in the Application_Start method. I needed to add the following line:
log4net.Config.XmlConfigurator.Configure();
You are required to also call out the additional config sections at the top of the file, as such:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
As well as the addition of the following above your log4net element:
<common>
<logging>
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net">
<arg key="configType" value="INLINE" />
</factoryAdapter>
</logging>
</common>
This makes the assumption that you're using Common.Logging and that you are not using a standalone config file (meaning the configuration is within the web.config).

logging into DB with log4net

I use log4net for logging errors in my project. I want to log messages into DB (SQL Server) so I added AdoNetAppender but it does not work (other appenders work fine, connection string is correct).
What can be wrong?
I decided to create a bare-bones example project. This works. Perhaps you should try making it work.
Create an empty console application project. Add a reference to log4net.
C# Code:
using log4net;
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace Litter
{
class Program
{
static void Main()
{
LogManager.GetLogger("default").Info("Hello, World!");
}
}
}
Config file:
<?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="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1"/>
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<connectionString value="data source=localhost\sqlexpress;initial catalog=Litter;integrated security=True;"/>
<commandText value="INSERT INTO Logs ([Message]) VALUES (#message)"/>
<parameter>
<parameterName value="#message"/>
<dbType value="String"/>
<size value="2000"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message"/>
</layout>
</parameter>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="AdoNetAppender"/>
</root>
</log4net>
</configuration>
Database table:
CREATE TABLE [dbo].[Logs]([Message] [nvarchar](2000) NOT NULL)
GO
That's about as simple as it gets. If you can make this work, then I'd start looking very closely at your app's AdoNetAppender configuration.
Thank you all. The problem was in DB. I just have to set the RowGuid property as true.

Not sure how to get Glimpse.Log4Net working

I'm trying to get Glimpse.Log4Net working in an existing ASP.Net MVC v4 project (in VS2010), following the docs here and here, but although the solution compiles and runs Glimpse and log4net seem to be working correctly, I can't see the log4net stuff in the Glimpse window that I'm expecting and as shown near the end of the page in the 2nd link.
I've got dependancy injection going with Autofac using this method, and I don't think it is interfering because I get entries as expected in the log file.
Can anyone point me in the right direction?
In my controller:
public class QuoteController : Controller
{
private readonly PrintCostEntities db;
private readonly ILog logger;
public QuoteController(PrintCostEntities db, ILog logger)
{
if (db == null)
{
throw new ArgumentNullException("db");
}
if (logger == null)
{
throw new ArgumentNullException("logger");
}
this.db = db;
this.logger = logger;
}
public ActionResult Index()
{
this.logger.DebugFormat("Index");
return this.View(this.db.Quotes);
}
}
In global.asax:
public class MvcApplication : System.Web.HttpApplication
{
private readonly ILog logger;
protected MvcApplication()
{
XmlConfigurator.Configure();
this.logger = LogManager.GetLogger(typeof(MvcApplication));
}
protected void Application_Start()
{
this.logger.Debug("Application_Start");
}
}
In web.config:
<configuration>
<configSections>
<section name="glimpse" type="Glimpse.Core.Configuration.Section, Glimpse.Core" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<system.web>
<httpModules>
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" />
</httpModules>
<httpHandlers>
<add path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" />
</httpHandlers>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" preCondition="integratedMode" />
</modules>
<handlers>
<add name="Glimpse" path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" preCondition="integratedMode" />
</handlers>
</system.webServer>
<glimpse defaultRuntimePolicy="On" endpointBaseUri="~/Glimpse.axd" />
<log4net>
<appender name="GlimpseAppender" type="Glimpse.Log4Net.Appender.GlimpseAppender">
<threshold value="ALL" />
</appender>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<threshold value="ALL" />
<file value="log4net.log" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />
<maxSizeRollBackups value="5" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
</layout>
</appender>
<root>
<appender-ref ref="GlimpseAppender" />
<appender-ref ref="RollingLogFileAppender" />
</root>
</log4net>
</configuration>
The package has updated to version 1.0 in May 2013 and this version works fine for me in my asp.net mvc4 application.
The log4net tab stays black/inactive (like you mention in your question) when there are no message appended to a GlimpseAppender. There several possible reasons for this:
there is no GlimpseAppender configured - this happened to me, because I had a custom log4net configuration
There is a redirect being done somewhere in you controller(s), after your message was logged. Your typical RedirectResult will redirect via the client resulting in a new request. The GlimpseAppender only logs message for the current http request, so you will not see any messages from before the redirect. (note: so if you do post-redirect-get, most interesting log message are not in teh glimpse log tab)
And then, of course, there are the "usual" log4net reasons why a message is not logged. But I consider that off-topic for this question.
The log4net Glimpse plugin was created by Jess Chadwick and is not yet up to date with the newest version of Glimpse.
You'll want to be using 1.1 version of Glimpse with MVC4, but the log4net plugin has not been updated yet.
The good news is that Glimpse.Log4Net is open source, so you should be able to easily update it to work with the new interfaces. I might even give it a go at updating it myself next week.
In case anyone is looking for more info on this issue - what worked for me:
VS 2013, MVC4, Glimpse 1.8.5, log4net 1.2.11.0
using a separate log4net.config file
in AssemblyInfo.cs I had [assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)] and in Global.asax Application_Start() I had log4net.Config.XmlConfigurator.Configure();
no log4net output in Glimpse - the tab was visible but it was blacked out
thanks to a tip I found here: https://stackoverflow.com/a/4558906/3590792 I changed the Application_Start() code to:
string l4net = Server.MapPath("~/log4net.config");
log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(l4net));
and Glimpse log4net started working

Configuring/Installing log4net for RavenDB in Visual Studio 2010

I'm trying to configure my C# project to use log4net for RavenDB. I already have log4net working with a FileAppender, but the RavenAppender doesn't seem to be working right now. The following are the steps I have taken so far:
Step 1: Installing log4net.Raven
I installed the log4net.Raven library using the following NuGet Package Manager console instructions (taken from the package website linked to above):
Install-Package log4net.Raven
That command added the log4net.Raven library to my project references.
Step 2: Configuring Web.config
In my Web.config file, I have the following settings, most of which are copy and pasted from the README file for the log4net.Raven project on GitHub (the owner of log4net.Raven also has similar configuration settings published on his blog):
<!-- Example connection string config from blog -->
<configsections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net">
</configsections>
<connectionstrings>
<add connectionstring="Url=http://raven; DefaultDatabase=Log" name="RavenLogs">
<add connectionstring="Url=http://localhost:8080;user=asa;password=asa" name="SecureRaven">
</add>
</add>
</connectionstrings>
<!-- My current config -->
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<connectionStrings>
<add name="RavenDB" connectionString="Url=http://localhost:8080;Database=MyDatabase" />
</connectionStrings>
<!-- Example log4net config from README.
My project uses these settings except for the connectionString value,
which is set to "RavenDB" to match the setting name above.
-->
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<!-- LogFileAppender settings here -->
</appender>
<appender name="RavenAppender" type="log4net.Raven.RavenAppender">
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="FATAL" />
</filter>
<connectionString value="RavenDB"/>
<maxNumberOfRequestsPerSession value="100"/>
<bufferSize value="50" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="ERROR" />
</evaluator>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="LogFileAppender" />
<appender-ref ref="RavenAppender" />
</root>
</log4net>
Step 3: Logging from C# code
In my C# code, I have the following:
public class FooController : Controller
{
private static ILog _log = LogManager.GetLogger(typeof(FooController));
public ActionResult Index()
{
_log.Info("Hello World!");
return View("Index");
}
}
That code will write out to a log file on my workstation, so from that I know that log4net in general is working correctly. But for RavenDB, I've been checking the Documents and Logs for MyDatabase through the Raven studio in a web browser, and I do not see any Info level log with the message "Hello World".
Does anyone have any ideas of what the problem could be and how to fix it?
May be the problem is here:
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
if you don't have class named FileAppender in your project you need to add the library name where FileAppender is, for example:
<appender name="LogFileAppender"
type="log4net.Appender.FileAppender, log4net.Raven">
(the syntax for type is =" Fully qualified class name , assembly file name , version , culture , public key token ")
Try debug log4net as here Log4Net Troubleshooting
If you find this line:
log4net: Adding appender named [RavenAppender] to logger [root].
RavenAppender is working

Spring.Net logging with Log4Net not working

I'm having trouble getting Spring.Net to log, using Log4Net. I'm particulary interested in seeing logging around the Aspects. I'm using a pretty simple log config, similar to that of the MovieFinder example app:
...
<logger name="Spring">
<level value="DEBUG" /> <!-- Have tried INFO as well, no different -->
<appender-ref ref="SpringAppender"/>
</logger>
<appender name="SpringAppender" type="log4net.Appender.RollingFileAppender">
<file value="..\Log\Spring_Log.txt"/>
<appendToFile value="true"/>
<maximumFileSize value="100MB"/>
<maxSizeRollBackups value="2"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level [%thread] %logger - %message%newline"/>
</layout>
</appender>
...
The file "Spring_Log.txt" is created, but nothing is logged to it (i.e. empty file). Log4Net is currently logging correctly for NHibernate and our custom app logging. I'm using Spring.Net v1.2.0.20313 and Log4Net v1.2.10.0.
Has anybody else had this problem that they were able to resolve? Many thanks for any help, cheers.
As Erich said, you need to configure Common.Logging.
Your log4net configuration file is fine. Here is what I’ve got using your configuration file:
2009-05-02 19:08:40,890 DEBUG [10] Spring.Objects.Factory.Support.AbstractObjectDefinitionReader - Loading XML object definitions from config [C:\Documents and Settings\pczapla\My Documents\Visual Studio 2008\Projects\TimeLogger\TimeLogger\bin\Debug\TimeLogger.exe.config#spring/objects]
2009-05-02 19:08:40,905 DEBUG [10] Spring.Objects.Factory.Support.AbstractObjectDefinitionReader - Using the following XmlReader implementation : System.Xml.XsdValidatingReader
2009-05-02 19:08:40,921 DEBUG [10] Spring.Objects.Factory.Xml.DefaultObjectDefinitionDocumentReader - Loading object definitions.
2009-05-02 19:08:40,921 DEBUG [10] Spring.Objects.Factory.Xml.ObjectDefinitionParserHelper - Loading object definitions...
Here is a quick guide how to configure Common.Logging:
Add Common.Logging & Common.Logging.Log4Net assemblies they are shipped with spring in lib folder (C:\Program Files\Spring.NET 1.2.0\lib\Net\2.0\).
Then Add the following configuration to your app.config:
<configuration>
</configSections>
...
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
...
<common>
<logging>
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net">
<!-- Common Logging assumes that log4net is initialized -->
<arg key="configType" value="EXTERNAL"/>
<!-- Or it can configure log4net for you
<arg key="configType" value="FILE-WATCH" />
<arg key="configFile" value="path\to\your\log4net.config" />
-->
</factoryAdapter>
</logging>
</common>
</configuration>
That is it. Now you should get debug messages from spring.
Spring.NET uses Common.Logging. Did you configure Common.Logging to log to log4net? See http://netcommon.sourceforge.net/documentation.html for the documentation
hth,
Erich

Categories