2016-08-12 5 views
1

J'ai un service Windows qui accepte les requêtes Web pour déclencher une tâche asynchrone de longue durée. Je souhaite que chaque tâche génère les journaux dans des répertoires différents (dont le nom est déterminé par l'ID de demande et l'utilisateur qui a déclenché le travail). Dans chaque répertoire, j'ai plusieurs fichiers journaux. J'utilise Common.Logging et log4net. Cependant, je dois réinitialiser la configuration de log4net afin de changer le répertoire (comme indiqué ci-dessous), et cela ne fonctionne pas bien si une tâche est déclenchée alors qu'une autre est toujours en cours d'exécution. Les journaux des deux tâches changent pour le dernier répertoire créé.Connexion à plusieurs dossiers

protected ILog CreateLoggerInstance(string loggerName, string logFolder) 
    { 
     logFolder += "/"; 
     // This is a hack to avoid creation of a folder called (null), because of limitation in log4net. 
     // More details: https://github.com/net-commons/common-logging/issues/81 
     log4net.GlobalContext.Properties["LogsDirectory"] = logFolder; 

     this.LogInstance = LogManager.GetLogger(loggerName); 
     this.LogInstance.GlobalVariablesContext.Set("LogsDirectory", logFolder); 
     LogManager.Reset(); 
     this.LogInstance = LogManager.GetLogger(loggerName); 

     this.LogFolder = logFolder; 
     return this.LogInstance; 
    } 

Existe-t-il un moyen de définir le journal uniquement pour un enregistreur spécifique? Ou puis-je éviter Reset() en quelque sorte? En outre, ce morceau de code est le seul endroit où je me réfère à log4net. Je vais donc passer à NLog si je peux créer plusieurs dossiers pour chaque ensemble de journaux.

Edit: J'ai trouvé cette fonctionnalité dans NLog - https://github.com/NLog/NLog/wiki/Configure-component-logging

Mais il ne ressemble pas à Common.Logging supporte.

+0

Si vous voulez écrire à plusieurs endroits en même temps, vous aurez besoin d'un appender pour chaque emplacement. La seule autre alternative consiste à utiliser le verrouillage autour de la création de l'enregistreur, ce qui serait préjudiciable aux performances. – stuartd

Répondre

1

La solution est assez simple dans NLog,

utiliser uniquement le requestId et user dans l'attribut fileName.

<targets> 
    <target name="file" xsi:type="File" 
     layout="${longdate} ${logger} ${message}" 
     fileName="${basedir}/${var:requestid}_${var:user}.log" /> 
</targets> 

<rules> 
    <logger name="*" minlevel="Debug" writeTo="file" /> 
</rules> 

Vous pouvez définir le nom d'utilisateur RequestID & dans les différents contextes: les variables globales, GDC/MDC etc. Voir https://github.com/NLog/NLog/wiki/Gdc-layout-renderer

+0

Brillant, cela a fonctionné. J'ai été capable de créer un enregistreur avec MDC, puis d'utiliser Common.Logging partout. Dans un seul fichier, j'ai dû utiliser NLog.MappedDiagnosticsContext. Question rapide, MDC devrait bien fonctionner avec les tâches TPL non? Mes tests jusqu'à présent suggèrent qu'ils fonctionnent, mais y aura-t-il des problèmes avec ThreadPool? – Narayana

+1

pour TPL (tâches) vous avez besoin du MDLC: https://github.com/NLog/NLog/wiki/MDLC-Layout-Renderer – Julian