Comment désactiver la création d’un fichier journal vide au démarrage de l’application?

J’ai bien configuré log4net dans mon application, mais une chose est un peu gênante pour moi.

Le fichier journal est créé (vide) après le démarrage de mon application, même si aucune erreur ne survient. Je voudrais que le fichier journal soit créé seulement après une erreur.

J’ai en fait trouvé un moyen de faire cela dans ce fil:

http://www.l4ndash.com/Log4NetMailArchive/tabid/70/forumid/1/postid/18271/view/topic/Default.aspx

J’ai testé la première méthode et ça marche. Juste au cas où ce lien ne serait plus bon, je reproduirai le code ici. En gros, l’auteur affirme qu’il y a deux façons de procéder.

Première manière:

Créez un nouveau modèle de locking qui n’acquiert un verrou (et crée le fichier) que si le seuil approprié pour cet enregistreur fonctionne.

public class MyLock : log4net.Appender.FileAppender.MinimalLock { public override Stream AcquireLock() { if (CurrentAppender.Threshold == log4net.Core.Level.Off) return null; return base.AcquireLock(); } } 

Maintenant, dans le fichier de configuration, définissez le seuil de départ comme suit:

  

et assurez-vous de définir ce nouveau LockingModel lors de la modélisation:

  

J’utilise ceci avec un appender de fichier roulant.

La seconde méthode est listée sur le lien. Je n’ai pas essayé cette technique mais elle semble être techniquement solide.

Je sais que c’est une vieille question mais je pense que cela peut être utile à quelqu’un d’autre.

Nous avons rencontré une situation similaire dans laquelle il était nécessaire que l’application ne laisse pas de fichier journal vide en l’absence d’erreur.

Nous l’avons résolu en créant la classe LockingModel personnalisée suivante:

 public class MinimalLockDeleteEmpty : FileAppender.MinimalLock { public override void ReleaseLock() { base.ReleaseLock(); var logFile = new FileInfo(CurrentAppender.File); if (logFile.Exists && logFile.Length <= 0) { logFile.Delete(); } } } 

Il est dérivé de la classe FileAppender.MinimalLock qui libère le verrou sur le fichier journal après l'écriture de chaque message du journal.

Nous avons ajouté une fonctionnalité supplémentaire qui supprimera le fichier journal s'il est toujours vide après la libération du verrou. Il empêche l'application de laisser des fichiers journaux d'erreurs vides si les applications s'exécutent et se terminent sans erreur.

Avantages

  • Il créera toujours un fichier journal vide pendant la phase de configuration de Log4Net, garantissant ainsi que la journalisation fonctionne avant le démarrage du rest de l'application. Cependant, le fichier journal est supprimé immédiatement.
  • Il n'est pas nécessaire que vous désactiviez la journalisation dans votre fichier de configuration en définissant la valeur de seuil sur "OFF" et que, plus tard, activez la journalisation par programme avant d'écrire votre premier événement de journal.

Les inconvénients

  • Il s'agit probablement d'une méthode lente de gestion de vos fichiers journaux, car la méthode ReleaseLock et la vérification de la longueur du fichier seront appelées après chaque événement de journal écrit dans le fichier journal. Ne l'utilisez que lorsque vous vous attendez à avoir très peu d'erreurs et que le fichier journal ne doit pas exister s'il n'y a pas d'erreurs.
  • Les fichiers journaux sont créés et supprimés lorsqu'ils sont vides. Cela peut poser problème si d'autres outils surveillent le répertoire des journaux pour détecter les modifications apscopes au système de fichiers. Cependant, ce n'était pas un problème dans notre situation.

Le problème avec cette approche est que si le fichier existe mais est en lecture seule, ou se trouve dans un répertoire qui n’existe pas, etc., vous ne le saurez pas avant qu’une autre erreur ne soit déjà à l’origine des problèmes. Vous voulez vraiment avoir la certitude que la journalisation fonctionne avant que le rest de l’application ne démarre.

Il y a peut- être un moyen de le faire de toute façon, mais sinon je soupçonne que c’est la raison.

Ce qui suit a fonctionné pour moi. Le premier appel à OpenFile () se produit lorsque le consignateur est configuré. Les appels suivants se produisent lorsque le message de journal réel est généré.

 class CustomFileAppender : RollingFileAppender { private bool isFirstTime = true; protected override void OpenFile(ssortingng fileName, bool append) { if (isFirstTime) { isFirstTime = false; return; } base.OpenFile(fileName, append); } 

}

Et dans le fichier de configuration, changez l’appender

   ...  

La séquence de la source log4Net est la suivante:


  • Le premier appel à OpenFile () est dû à ActivateOptions () appelé à partir du constructeur de FileAppender.
  • Lorsque le message de journal est généré, DoAppend () de AppenderSkeleton appelle PreAppendCheck ().
  • PreAppendCheck () est substitué dans TextWriterAppender, la base de FileAppender.
  • PreAppendCheck () annulé appelle virtual PrepareWriter si le fichier n’est pas encore ouvert.
  • PrepareWriter () de FileAppender appelle SafeOpenFile () qui appelle ensuite OpenFile ()

Une autre méthode assez simple est décrite dans ce message de l’archive de la liste de diffusion

Fondamentalement, avec log4net, le fichier journal est créé lors de la configuration du consignateur. Le configurer pour faire autrement est un peu hacky. La solution consiste à différer l’exécution de la configuration. Le message ci-dessus suggère de procéder comme suit lors de la configuration de l’enregistreur:

 private static ILog _log = LogManager.GetLogger(typeof(Program)); public static ILog Log { get { if(!log4net.LogManager.GetRepository().Configured) log4net.Config.XmlConfigurator.Configure(new FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)); return _log; } } 

En règle générale, je configure log4net avec l’atsortingbut assembly , qui configure automatiquement le consignateur (créant ainsi le fichier journal), ainsi qu’un simple getter pour le journal:

 [assembly: log4net.Config.XmlConfigurator(Watch = true)] ... public static log4net.ILog Log { get { return _log; } } private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

Mais supprimer cela et append le getter ci-dessus avec la logique supplémentaire résolut le problème pour moi.

Remarque: en général, je conviens que dans la plupart des cas, il serait préférable de configurer le consignateur et de créer le fichier (et même d’y écrire) au démarrage de l’application.

Les méthodes AcquireLock et ReleaseLock ont ​​fonctionné pour moi, mais le fait que le fichier ait été créé / supprimé m’a souvent gêné. Voici une autre option similaire qui ferme le consignateur et supprime le fichier journal vide à la fin du programme. Appelez simplement RemoveEmptyLogFile lorsque vous avez fini de vous connecter.

 ///  /// Sets the logging level for log4net. ///  private static void RemoveEmptyLogFile() { //Get the logfilename before we shut it down log4net.Appender.FileAppender rootAppender = (log4net.Appender.FileAppender)((log4net.Repository.Hierarchy.Hierarchy)log4net.LogManager.GetRepository()).Root.Appenders[0]; ssortingng filename = rootAppender.File; //Shut down all of the repositories to release lock on logfile log4net.Repository.ILoggerRepository[] repositories = log4net.LogManager.GetAllRepositories(); foreach (log4net.Repository.ILoggerRepository repository in repositories) { repository.Shutdown(); } //Delete log file if it's empty var f = new FileInfo(filename); if (f.Exists && f.Length <= 0) { f.Delete(); } } // RemoveEmptyLogFile 
 private static ILog _log = LogManager.GetLogger(typeof(Program)); public static ILog Log { get { if(!log4net.LogManager.GetRepository().Configured) log4net.Config.XmlConfigurator.Configure(new FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)); return _log; } }