En tant que développeurs, nous avons souvent besoin d’implémenter une fonctionnalité de log dans nos applications. Il s’agit de garder une trace des différents événements et de suivre leurs fonctionnements.
Les logs peuvent être présentés sous forme de notifications mail ou stockés dans des fichiers texte ou une base de données.
Log4Net est une librairie gratuite qui vous facilite cette tâche.
Présentation
Log4net permet de journaliser tout type d’information vers diverses cibles, Log4Net est un port du Framework log4j vers .NET
Pour plus de détail, consultez le site officiel : http://logging.apache.org/log4net/
L’outil est disponible sous licence Apache 2.0 et disponible sur Nuget http://www.nuget.org/packages/log4net
Contexte
Pour utiliser Log4Net il faut comprendre la notion d’Appender, il permet de spécifier où et comment l’information va être journalisée.
Mon application utilise l’appender RollingFileApprender, il permet journaliser des évènements dans un fichier avec la possibilité de log sur plusieurs fichiers en fonction de la date et de l’heure.
Pour le projet de tests j’ai préféré utilisé le MemoryAppender qui permet de stocker les évènements dans un buffer mémoire, il possède deux méthodes particulières : GetEvents () pour récupérer les événements inscrits et Clear () pour tout effacer.
Le MemoryAppender s’avère alors très pratique pour récupérer les événements dans le cadre d’un projet de tests.
LogChecker
Pour mon besoin, j’ai fait une classe utilitaire qui me permet d’instancier et configurer le MemoryAppender et de définir le niveau d’événements à tracer.
Et voici son code :
public class LogChecker : IDisposable
{
readonly MemoryAppender _appender = new MemoryAppender()
public LogChecker(Level levelToCheck)
{
var root = ((Hierarchy)LogManager.GetRepository()).Root;
root.AddAppender(_appender); root.Repository.Configured = true;
_appender.Threshold = levelToCheck;
}
public List<string> Messages
{
get
{
return new List<LoggingEvent>(_appender.GetEvents())
.ConvertAll(e => e.RenderedMessage);
}
}
public void Dispose()
{
_appender.Clear();
var root = ((Hierarchy)LogManager.GetRepository()).Root;
root.RemoveAppender(_appender);
}
}
Test unitaire
Dans l’exemple qui suit j’ai une classe appelée MyClass avec une méthode CheckForInternetConnection qui me permet de tester la connexion internet, j’enregistre un message d’erreur dans le log dans le cas où une exception se déclenche :
public class MyClass
{
private readonly ILog log = LogManager.GetLogger(typeof(MyClass));
public bool CheckForInternetConnection()
{
try
{
using (var client = new WebClient())
using (var stream = client.OpenRead("http://www.google.com"))
{
return true;
}
}
catch
{
log.Error("Internet is not available");
return false;
}
}
}
Et voici l’utilisation dans le test :
[TestMethod]
public void CheckForInternetConnectionTest()
{
using (LogChecker logCheck = new LogChecker(Level.Error))
{
var myClass = new MyClass();
myClass.CheckForInternetConnection();
Assert.AreEqual<int>(1, logCheck.Messages.Count);
Assert.AreEqual<string>("Internet is not available"
, logCheck.Messages[0]);
}
}
Conclusion
Log4net est un outil simple, puissant, extensible et entièrement configurable, ce qui m’a permis d’avoir deux configurations différentes, une pour mon application et l’autre pour mes tests unitaires, j’ai tenté dans cette article d’apporter une réponse à un problème auquel j’ai été confronté.
Maintenant vous pouvez effectuer des tests sur vos logs Log4Net :)